问题
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