Is there a clipboard changed or updated event that i can access through C#?
I think you'll have to use some p/invoke:
[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
See this article on how to set up a clipboard monitor in c#
Basically you register you app as a clipboard viewer using
_ClipboardViewerNext = SetClipboardViewer(this.Handle);
and then you will recieve the WM_DRAWCLIPBOARD
message, which you can handle by overriding WndProc
:
protected override void WndProc(ref Message m)
{
switch ((Win32.Msgs)m.Msg)
{
case Win32.Msgs.WM_DRAWCLIPBOARD:
// Handle clipboard changed
break;
// ...
}
}
(There's more to be done; passing things along the clipboard chain and unregistering your view, but you can get that from the article)
Check out the SetClipboardViewer, ChangeClipboardChain and SendMessage API calls.
Here's a good article that explains how to trap Clipboard change notifications. And another.
For completeness, here's the control I'm using in production code. Just drag from the designer and double click to create the event handler.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
namespace ClipboardAssist {
// Must inherit Control, not Component, in order to have Handle
[DefaultEvent("ClipboardChanged")]
public partial class ClipboardMonitor : Control
{
IntPtr nextClipboardViewer;
public ClipboardMonitor()
{
this.BackColor = Color.Red;
this.Visible = false;
nextClipboardViewer = (IntPtr)SetClipboardViewer((int)this.Handle);
}
/// <summary>
/// Clipboard contents changed.
/// </summary>
public event EventHandler<ClipboardChangedEventArgs> ClipboardChanged;
protected override void Dispose(bool disposing)
{
ChangeClipboardChain(this.Handle, nextClipboardViewer);
}
[DllImport("User32.dll")]
protected static extern int SetClipboardViewer(int hWndNewViewer);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
protected override void WndProc(ref System.Windows.Forms.Message m)
{
// defined in winuser.h
const int WM_DRAWCLIPBOARD = 0x308;
const int WM_CHANGECBCHAIN = 0x030D;
switch (m.Msg)
{
case WM_DRAWCLIPBOARD:
OnClipboardChanged();
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
case WM_CHANGECBCHAIN:
if (m.WParam == nextClipboardViewer)
nextClipboardViewer = m.LParam;
else
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
default:
base.WndProc(ref m);
break;
}
}
void OnClipboardChanged()
{
try
{
IDataObject iData = Clipboard.GetDataObject();
if (ClipboardChanged != null)
{
ClipboardChanged(this, new ClipboardChangedEventArgs(iData));
}
}
catch (Exception e)
{
// Swallow or pop-up, not sure
// Trace.Write(e.ToString());
MessageBox.Show(e.ToString());
}
}
}
public class ClipboardChangedEventArgs : EventArgs
{
public readonly IDataObject DataObject;
public ClipboardChangedEventArgs(IDataObject dataObject)
{
DataObject = dataObject;
}
}
}
Hi .. i know this is a little bit old, but iam working on a small project to catch the Clipboard changes ...
the code works great BUT: if you add a notifyicon and minimize the form to tray and turn the showintaskbar to false, the program wont catch any clipboard changes anymore ... even if you maximize the form back, it wont work again ...you have to restart the program ..
any idea on how to solve this issue !? how can i catch clipboard changes, even if the form is minimized into the tray !?
hi ... i tested the code above, working great.. but on some applications like firefox, the event will fire twice, that means when you copy something from firefox, the clipboardtext (or object) will be set twice in the clipboard ??and the event will be fired 2 times .... i am not sure what`s happening..
any help on this ?
thanks