OpenClipboard API有什么意义?

时间:2017-04-03 22:18:16

标签: c# .net winapi

在尝试使用剪贴板时读取了相当多的剪贴板后,我尝试直接使用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'类型的第一次机会异常
  附加信息:请求的剪贴板操作未成功。

所以,问题:

  1. OpenClipboard()确实有用吗?

  2. OpenClipboard()的论据是什么? API的其余部分不需要任何窗口的句柄,为什么OpenClipboard()?换句话说,剪贴板应该在PROCESSES之间共享,而不是在WINDOWS之间共享 - 但我没有办法为我当前的进程锁定它。

  3. 我可以致电OpenClipboard(IntPtr.Zero),MSDN说:

      

    如果此参数为NULL,则打开的剪贴板与当前任务相关联。

    什么是'任务'应该是什么意思?

1 个答案:

答案 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()有一个功能。

enter image description here

然后该功能被GetCurrentProcess()GetCurrentThread()替换。

enter image description here

因为更有意义的是一次只有一个线程可以访问共享资源,我会说''任务'实际上意味着'线程'。

  

API的其余部分不需要任何窗口的句柄,那么为什么OpenClipboard()?

如果我的上述假设是正确的,也就是说,一次只有一个线程可以访问剪贴板,那么很可能,Windows将使用您之前使用OpenClipboard()指定的线程/窗口,直到您调用{{1或者线程/窗口变得无效。这就是您不需要一直指定CloseClipboard()的原因。

  

换句话说,剪贴板应该在PROCESSES之间共享,而不是在WINDOWS之间共享 - 但是我没有看到为当前进程锁定它的方法。

虽然我对C#P / Invoke不确定,但它锁定了。如果您有权访问Win32 / C开发工具包,请编译并运行以下代码:

HWND

看看如果你在其他程序中使用剪贴板会发生什么。 :)关闭控制台窗口以进行恢复。