在尝试使用剪贴板时读取了相当多的剪贴板后,我尝试直接使用OpenClipboard()
来捕获剪贴板并能够从我的窗口中使用它。
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
[DllImport("user32.dll", SetLastError=true)]
private static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll", SetLastError=true)]
private static extern bool CloseClipboard();
private int idx = 0;
private void refresh_Tick(object sender, EventArgs e) {
switch (idx++) {
case 0:
OpenClipboard(Handle);
break;
default:
Clipboard.SetText(" ");
break;
}
}
}
使用SetText
时,我会收到臭名昭着的错误:
System.Windows.Forms.dll中发生'System.Runtime.InteropServices.ExternalException'类型的第一次机会异常
附加信息:请求的剪贴板操作未成功。
所以,问题:
OpenClipboard()
确实有用吗?
OpenClipboard()
的论据是什么? API的其余部分不需要任何窗口的句柄,为什么OpenClipboard()
?换句话说,剪贴板应该在PROCESSES之间共享,而不是在WINDOWS之间共享 - 但我没有办法为我当前的进程锁定它。
我可以致电OpenClipboard(IntPtr.Zero)
,MSDN说:
如果此参数为NULL,则打开的剪贴板与当前任务相关联。
什么是'任务'应该是什么意思?
答案 0 :(得分:1)
Does OpenClipboard() actually work?
OpenClipboard()
works, but definitely not in the way you showed. It is a raw Win32 API. Here is an example of using it to copy string to clipboard (C/C++)。
OpenClipboard()的参数是什么?
说实话,我对此并不确定。通常我们只是通过NULL
aka IntPtr.Zero
并让它与当前任务相关联。我猜它会检索创建指定窗口的线程,然后将其与剪贴板关联。
什么是任务?那么这是我的理解。回到Win16天,而不是'线程'或者'处理',他们使用了术语'任务'。 GetCurrentTask()
有一个功能。
然后该功能被GetCurrentProcess()
和GetCurrentThread()
替换。
因为更有意义的是一次只有一个线程可以访问共享资源,我会说''任务'实际上意味着'线程'。
API的其余部分不需要任何窗口的句柄,那么为什么OpenClipboard()?
如果我的上述假设是正确的,也就是说,一次只有一个线程可以访问剪贴板,那么很可能,Windows将使用您之前使用OpenClipboard()
指定的线程/窗口,直到您调用{{1或者线程/窗口变得无效。这就是您不需要一直指定CloseClipboard()
的原因。
虽然我对C#P / Invoke不确定,但它锁定了。如果您有权访问Win32 / C开发工具包,请编译并运行以下代码:换句话说,剪贴板应该在PROCESSES之间共享,而不是在WINDOWS之间共享 - 但是我没有看到为当前进程锁定它的方法。
HWND
看看如果你在其他程序中使用剪贴板会发生什么。 :)关闭控制台窗口以进行恢复。