クリップボードからコピーされたファイルのリストを取得しようとしています。WPF にはこのためのメソッドが組み込まれていることはよく知っていますが、Web 上の多くの場所で説明されているように、WPF のクリップボードの実装にはバグがあるため、API を使用することが重要です。
これまでのところGetClipboardData
、メモリ内で必要なデータへのポインタを返す関数を使用しています。さて、このデータを列挙するにはDragQueryFile
、Windows で API を使用する必要があることがわかりました。
私のDragQueryFile
APIは次のように宣言されています。
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int DragQueryFile(IntPtr hDrop, int iFile, StringBuilder lpszFile, int cch);
そして、私のGetClipboardData
APIは次のように宣言されています。
[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) が実際にクリップボードにあるかどうかも確認しました。