Create a Windows Clipboard Monitor in C# using SetClipboardViewer
2012-11-19 09:40
1956 查看
Introduction
Applications such as GetRight and ClipMate seemto magically know when something is copied to the Clipboard. How is it done? This example shows you how to use the Win32 API function
SetClipboardViewerto create a Clipboard
Viewer application.
Using SetClipboardViewer
The Win32 API contains a function SetClipboardViewerwhich allows an application to register itself as a viewer of Clipboard events. When an item is copied to the Clipboard,
windows notifies the Clipboard Viewer by sending the WM_DRAWCLIPBOARD message. The application can then use the appropriate function to get the contents of the Clipboard and perform processing.
Example Application
I had a great idea one day (after copying and pasting internet links a few hundred times) to create a small application that would read the Clipboard when something was copied to it and extract any Internet URLs, UNC paths or filenames that it found and putthem on a menu in the system tray.
I spent a little time on it and it is in a working state but it is not finished. One day I will get around to finishing it off but for the moment it is a good sample to learn how
SetClipboardViewerworks.
C# Source Code: RAD_ClipboardMonitorExampleSrc.zip (~50 KB) | |
VB.NET Example: ClipboardMonitor_VB.txt |
The SetClipboardViewer Function
The SetClipboardViewerfunction adds the specified window to the chain of Clipboard Viewers. Clipboard Viewer windows receive a
WM_DRAWCLIPBOARDmessage whenever the content
of the Clipboard changes.
The
SetClipboardViewerAPI declaration has the following syntax in C#
[DllImport("User32.dll", CharSet=CharSet.Auto)] public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
The
hWndNewViewerparameter is the handle to the window to be added to the Clipboard chain.
When
SetClipboardVieweris successful, the return value identifies the next window in the Clipboard Viewer chain. This is important as a Clipboard Viewer is required to pass Clipboard messages to the next window
in the Clipboard chain.
Setting up the Clipboard Viewer
I need to override the WndProcmethod of the underlying Form so that the main form can respond to window messages from the operating system. Normally .NET applications
do not need to use
WndProcas the .NET Framework takes care of these events.
protected override void WndProc(ref Message m) {
Next, call
SetClipboardViewerto register the application as a Clipboard Viewer. The window will now receive the
WM_DRAWCLIPBOARDmessage.
Applications do not normally receive the
WM_DRAWCLIPBOARDmessage, only those that call
SetClipboardViewer.
_ClipboardViewerNext = SetClipboardViewer(this.Handle);
Responding to the WM_DRAWCLIPBOARD message
After calling SetWindowLong the WindowProc method will receive the WM_DRAWCLIPBOARDmessage when something is copied to the Clipboard.
protected override void WndProc(ref Message m) {switch ((Win32.Msgs)m.Msg)
{
case Win32.Msgs.WM_DRAWCLIPBOARD:
This is the place that I do my processing of the Clipboard data. The .NET Framework has theClipboard, DataObject and DataFormats classes
for working with the Clipboard.Clipboard.GetDataObject gets the current contents of the Clipboard as an IDataObject.
IDataObject iData = new DataObject(); iData = Clipboard.GetDataObject();
As the Clipboard can contain different types of data, use the DataObject.GetDataPresentmethod to check for a certain type of data. It returns true if the contents of the Clipboard can be converted to the specified
type. The DataFormats class contains constants that define the names of some of the more common Clipboard formats.
if (iData.GetDataPresent(DataFormats.Rtf)) { // ...
Once I have determined that the format is available then the DataObject.GetData method can be used to get the Clipboard content in the required format. The following example gets the contents in Rich Text Format
(RTF).
ctlClipboardText.Rtf = (string)iData.GetData(DataFormats.Rtf);
After performing any processing that the application requires the next window in the Clipboard Viewer chain must be notified of the Clipboard change. This is done by calling the Windows API function
SendMessage.
The same parameters that were passed to the
WndProcmethod are passed to
SendMessageto be used by the next Clipboard Viewer in the chain.
SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);
When overriding
WndProcI must pass any unhandled messages to the base class by calling
base.WndProc
protected override void WndProc(ref Message m) {switch ((Win32.Msgs)m.Msg)
{
case Win32.Msgs.WM_DRAWCLIPBOARD:
// ... process Clipboard
default:
// unhandled window message
base.WndProc(ref m);
break;
The WM_CHANGECBCHAIN Message
The WM_CHANGECBCHAINmessage is sent when a window is being removed from the chain of Clipboard Viewers. Note that the message is only sent to the first window in the Clipboard Viewer chain. The first window and
subsequent windows in the chain must use
SendMessageto pass the message along the chain.
If
wParamis equal to the handle of the next Clipboard Viewer then the next Clipboard Viewer is being removed and I need to update the pointer that refers to the next window in the chain.
m.LParamis
a pointer to the Clipboard Viewer in the chain after the one being removed.
if (m.WParam == _ClipboardViewerNext) { _ClipboardViewerNext = m.LParam; } else { SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam); }
This message can be seen by starting multiple copies of the Clipboard Viewer and watching the Debug output.
Unregistering the Application as a Clipboard Viewer
When the application closes I make sure I call ChangeClipboardChain to remove the application from the Clipboard chain.ChangeClipboardChain(this.Handle, _ClipboardViewerNext);
And Finally...
There are a few tricks to using the SetClipboardViewerfunction but it allows your application to be notified of Clipboard events.
If you have any comments or feedback please send them via email: Ross Donald (ross @ radsoftware.com.au)
转自:http://www.radsoftware.com.au/articles/clipboardmonitor.aspx
相关文章推荐
- create Context Menu in Windows Forms application using C# z
- Using the ReportViewer ASP.NET Control in Windows Azure
- HOW TO: Set a Windows Hook in Visual C# .NET
- SQLite Practice Using C# in Windows
- Create Native iOS, Android, Mac and Windows apps in C#
- 【Python错误】windows下使用pip/easy_install提示Fatal error in launcher: Unable to create process using...
- Using SiteMap and MasterPages to set META Tags in ASP.NET and C#
- How to Create a Automated Task that Runs at a Set Time in Windows 7
- Using ZipLib to create a Zip File in C#
- Create windows service using c#
- HOW TO: Set a Windows Hook in Visual C# .NET
- How to create (and deploy) a windows service in C# ?
- 【Python错误】windows下使用pip/easy_install提示Fatal error in launcher: Unable to create process using...
- SQLite Practice Using C# in Windows
- Hands-on Labs for Windows® Workflow Foundation in C# and VB.NET
- pip install 出现 Fatal error in launcher: Unable to create process using '"'
- Using Eclipse + beyond compare + remotecmd in windows XP for Embedded developement
- Fatal error in launcher: Unable to create process using 错误解决 以及python3安装scrapy
- pip报错解决方法--Fatal error in launcher: Unable to create process using
- 如何用th:attr标签在thymeleaf模板中设置属性-原标题:How To Set Attributes in Thymeleaf Template using th:attr?