clipboard Listener event is being called twice

末鹿安然 提交于 2020-01-01 14:38:31

问题


i want to save the changes in my clipboard. so i registered my application to get all the changes that happens to the Clipboard.

Using

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

and then

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());
        }
}

The Problem is: When copying text from an application like visual studio or firefox, the OnClipboardChanged() function will be called twice or 3 times sometimes.

I think that those application will write the Data to the clipboard with different formats, this is why the function is called more than once. But how would i prevent saving the same data because OnClipboardChanged() is being called more than once ?


回答1:


Because they're opening/closing the clipboard multiple times. I've seen such madness before. Excel used to perform 24 separate operations when copying a chart.
Instead of this (pseudocode):

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

they're probably doing this:

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

Update: The usual mitigation strategy is to avoid reacting to every update, and react to the LAST update after a reasonable "settle time" has elapsed with no further clipboard notifications. 500ms will usually be more than adequate.




回答2:


Prevent multiple calls to the clipboard

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;
}


来源:https://stackoverflow.com/questions/10373713/clipboard-listener-event-is-being-called-twice

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!