I want to have this feature in my C# program: When the user do Ctrl + C or Copy anywhere (i.e. when the clipboard content changes), my program will get notified, and check whether the content met certain criteria, if so, become the active program, and process the content, etc.
I can get the contents out from System.Windows.Forms.Clipboard
, however, I don't know how to monitor the content changes from the clipboard.
If using Windows Vista or later, use AddClipboardFormatListener
as in John Knoeller's answer, for Windows XP, I have to use the older, more fragile SetClipboardViewer
API, as in the accepted answer.
I've written up a small utility class that uses the AddClipboardFormatListener function function with a Message-only window to do just this.
/// <summary>
/// Provides notifications when the contents of the clipboard is updated.
/// </summary>
public sealed class ClipboardNotification
{
/// <summary>
/// Occurs when the contents of the clipboard is updated.
/// </summary>
public static event EventHandler ClipboardUpdate;
private static NotificationForm _form = new NotificationForm();
/// <summary>
/// Raises the <see cref="ClipboardUpdate"/> event.
/// </summary>
/// <param name="e">Event arguments for the event.</param>
private static void OnClipboardUpdate(EventArgs e)
{
var handler = ClipboardUpdate;
if (handler != null)
{
handler(null, e);
}
}
/// <summary>
/// Hidden form to recieve the WM_CLIPBOARDUPDATE message.
/// </summary>
private class NotificationForm : Form
{
public NotificationForm()
{
NativeMethods.SetParent(Handle, NativeMethods.HWND_MESSAGE);
NativeMethods.AddClipboardFormatListener(Handle);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == NativeMethods.WM_CLIPBOARDUPDATE)
{
OnClipboardUpdate(null);
}
base.WndProc(ref m);
}
}
}
internal static class NativeMethods
{
// See http://msdn.microsoft.com/en-us/library/ms649021%28v=vs.85%29.aspx
public const int WM_CLIPBOARDUPDATE = 0x031D;
public static IntPtr HWND_MESSAGE = new IntPtr(-3);
// See http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AddClipboardFormatListener(IntPtr hwnd);
// See http://msdn.microsoft.com/en-us/library/ms633541%28v=vs.85%29.aspx
// See http://msdn.microsoft.com/en-us/library/ms649033%28VS.85%29.aspx
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
}
This class assumes that the notifications are always needed for the duration of the applications lifetime, however it could be modified to provide the ability to unsubscribe via the RemoveClipboardFormatListener function if required.