5

我想将更改保存在剪贴板中。所以我注册了我的应用程序以获取剪贴板发生的所有更改。

使用

    [DllImport("User32.dll")]
    protected static extern bool AddClipboardFormatListener(int hwnd);

进而

protected override void WndProc(ref Message m)
    {
switch (m.Msg)
        {
            case WM_CLIPBOARDUPDATE:
                OnClipboardChanged();
                break;
             ...
        }
     }

private void OnClipboardChanged()
{
    if (Clipboard.ContainsText())
        {
         MessageBox.Show(Clipboard.GetText().ToString());
        }
}

问题是:从 Visual Studio 或 firefox 等应用程序复制文本时,有时会调用 OnClipboardChanged() 函数两次或 3 次。

我认为那些应用程序会将数据以不同的格式写入剪贴板,这就是该函数被多次调用的原因。但是我将如何防止保存相同的数据,因为 OnClipboardChanged() 被多次调用?

4

2 回答 2

8

因为他们多次打开/关闭剪贴板。我以前见过这样的疯狂。Excel 用于在复制图表时执行 24 种单独的操作。
而不是这个(伪代码):

openClipboard
for each format {
  place data on clipboard(format)
}
closeClipboard

他们可能正在这样做:

for each format {
  openClipboard
  place data on clipboard(format)
  closeClipboard
}

更新:通常的缓解策略是避免对每次更新做出反应,并在合理的“稳定时间”过去后对最后一次更新做出反应,并且没有进一步的剪贴板通知。500 毫秒通常绰绰有余。

于 2012-04-29T21:40:26.173 回答
0

防止多次调用剪贴板

private int _i = 0;
private int i
{
    get
    {
        async void setI()
        {
            await Task.Run(() =>
            {
                Thread.Sleep(20);
                i = 0;
            }
            );
        }
        setI();
        return _i;
    }
    set
    {
        _i = value;
    }
}
private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
{
    if (msg == WM_CLIPBOARDUPDATE)
    {
        if(i<1)
        {
            this.ClipboardUpdate?.Invoke(this, new EventArgs());
            i++;
        }
    }
    handled = false;
    return IntPtr.Zero;
}
于 2019-04-13T00:49:27.777 回答