1

クリップボードからコピーされたファイルのリストを取得しようとしています。WPF にはこのためのメソッドが組み込まれていることはよく知っていますが、Web 上の多くの場所で説明されているように、WPF のクリップボードの実装にはバグがあるため、API を使用することが重要です。

これまでのところGetClipboardData、メモリ内で必要なデータへのポインタを返す関数を使用しています。さて、このデータを列挙するにはDragQueryFile、Windows で API を使用する必要があることがわかりました。

私のDragQueryFileAPIは次のように宣言されています。

[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int DragQueryFile(IntPtr hDrop, int iFile, StringBuilder lpszFile, int cch);

そして、私のGetClipboardDataAPIは次のように宣言されています。

[DllImport("user32.dll")]
static extern IntPtr GetClipboardData(uint uFormat);

ここで、DragQueryFile API のドキュメントを見ると、関数の引数について次のように明確に記載されています。

iFile: クエリするファイルのインデックス。このパラメータの値が 0xFFFFFFFF の場合、DragQueryFile は削除されたファイルの数を返します。このパラメーターの値が 0 から削除されたファイルの総数までの範囲にある場合、DragQueryFile はファイル名と対応する値を lpszFile パラメーターが指すバッファーにコピーします。

私はこの情報を使用して、このコードを作成しました (コピーして貼り付けることができ、あなたの側でも実行する必要があります)。

var dummyFiles = new StringCollection();
dummyFiles.Add(Path.GetTempFileName());
dummyFiles.Add(Path.GetTempFileName());

Clipboard.Clear();
Clipboard.SetFileDropList(dummyFiles);

var dataPointer = GetClipboardData(15); //15 is for CF_HDROP datatype - this does in fact return a pointer, so it's working fine
var fileCount = DragQueryFile(dataPointer, -1, null, 0);

上記の例では、fileCountは常に0ですが、クリップボードに 2 つのファイルを追加したClipboard.GetFileDropListだけで、WPF の関数を使用してそれらを正常に取得できます。また、フォーマット 15 (CF_HDROP) が実際にクリップボードにあるかどうかも確認しました。

4

1 に答える 1

1

win7 x64 で GetclipboardData から戻り値を取得するために、OpenClipboard を呼び出す必要がありました (したがって、CloseClipboard も呼び出しました)。

追加した

[DllImport("user32.dll", SetLastError = true)]
static extern bool OpenClipboard(IntPtr hWndNewOwner);

[DllImport("user32.dll", SetLastError = true)]
static extern bool CloseClipboard();

そして、pinvoke.net で見つけたものと一致するように DragQueryFile を変更しました (int ではなく uint)。

[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int DragQueryFile(IntPtr hDrop, uint iFile, StringBuilder lpszFile, int cch);

と使用

    var dummyFiles = new StringCollection();
    dummyFiles.Add(Path.GetTempFileName());
    dummyFiles.Add(Path.GetTempFileName());

    Clipboard.Clear();
    Clipboard.SetFileDropList(dummyFiles);   

    OpenClipboard(IntPtr.Zero);

    IntPtr hDrop = GetClipboardData(15);

    var count = DragQueryFile(hDrop, uint.MaxValue, null, 0);

    // etc.

    CloseClipboard();

私のために働いた(カウント= 2)。

于 2012-07-25T23:27:49.317 に答える