我正在尝试从剪贴板中获取复制文件的列表。我很清楚WPF有内置的方法,但是对我来说使用API很重要,因为WPF的剪贴板实现很麻烦,正如网上很多地方所描述的那样。
到目前为止,我正在使用GetClipboardData
函数,该函数返回指向内存中所需数据的指针。现在,为了枚举这些数据,我发现我需要在Windows中使用DragQueryFile
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);
现在,如果您查看documentation for the DragQueryFile API,它会清楚地说明函数中的参数:
iFile:要查询的文件的索引。 如果此参数的值为0xFFFFFFFF,则DragQueryFile返回已删除文件的计数。如果此参数的值介于零和丢弃的文件总数之间,则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个文件添加到剪贴板,我可以通过WPF中的Clipboard.GetFileDropList
函数获取它们就好了。我还检查了格式15(CF_HDROP)是否确实在剪贴板中,它是。
答案 0 :(得分:1)
我不得不调用OpenClipboard(因此我也称为CloseClipboard),以便在win7 x64上从GetclipboardData获取返回值。
我添加了
[DllImport("user32.dll", SetLastError = true)]
static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll", SetLastError = true)]
static extern bool CloseClipboard();
并更改了DragQueryFile以匹配我在pinvoke.net上找到的内容(uint而不是int)
[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)。