Monitor for clipboard changes using AddClipboardFormatListener
Microsoft has added a new windows function to help monitor when the data in the clipboard has been changed. The new function is called AddClipboardFormatListener but sadly it is only available for Windows Vista and higher. If you are looking for a method that will work for earlier versions of Windows take a look at Monitor clipboard in C#.
The principle is the same with the older method. We need to add our window to the clipboard format listener list so it can receive the WM_CLIPBOARDUPDATE message.
In order to do that we need to pinvoke the AddClipboardFormatListener
and RemoveClipboardFormatListener
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /// <summary> /// Places the given window in the system-maintained clipboard format listener list. /// </summary> [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool AddClipboardFormatListener(IntPtr hwnd); /// <summary> /// Removes the given window from the system-maintained clipboard format listener list. /// </summary> [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool RemoveClipboardFormatListener(IntPtr hwnd); /// <summary> /// Sent when the contents of the clipboard have changed. /// </summary> private const int WM_CLIPBOARDUPDATE = 0x031D; |
Then we need to add our window to the clipboard format listener list by calling the AddClipboardFormatListener method with our window’s handle as a parameter. Place the following code in your main window form constructor or any of its load events.
1 | AddClipboardFormatListener(this.Handle); // Add our window to the clipboard's format listener list. |
Override the WndProc
method so we can catch when the WM_CLIPBOARDUPDATE is send.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == WM_CLIPBOARDUPDATE) { IDataObject iData = Clipboard.GetDataObject(); // Clipboard's data. /* Depending on the clipboard's current data format we can process the data differently. * Feel free to add more checks if you want to process more formats. */ if (iData.GetDataPresent(DataFormats.Text)) { string text = (string)iData.GetData(DataFormats.Text); // do something with it } else if (iData.GetDataPresent(DataFormats.Bitmap)) { Bitmap image = (Bitmap)iData.GetData(DataFormats.Bitmap); // do something with it } } } |
And finally make sure to remove your main window from the clipboard format listener list before closing your form.
1 2 3 4 | private void Form1_FormClosing(object sender, FormClosingEventArgs e) { RemoveClipboardFormatListener(this.Handle); // Remove our window from the clipboard's format listener list. } |
It would be possible to also have the code version for C++ ?
Thanks in advance
Thanks, but I’m using Unicode and WinForm ……….
My changes:
And:
Thanks for sharing your solution to the problem.
If DataFormats.StringFormat can contain both Unicode and ASCII strings then it is a better solution than using DataFormats.Text, depending on your needs of course.
Alternatively, if you have two different logics and want to handle them separately, you can use DataFormats.UnicodeText for Unicode.
It works perfect. Thanks and greetings from Poland :)