HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Monitoring the clipboard

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
clipboardthemonitoring

Problem

The following class monitors the clipboard and raises an event whenever the contents change. The monitoring starts when the class is created and ends when Dispose is called.

To achieve this a message-only window (a term that comes from the Win32 API) is created using an instance of HwndSource class (since I am using WPF). The window's handle is then registered via AddClipboardFormatListener to receive a message whenever the clipboard changes. The window's messages are processed by WndProc which raises the event when the WM_CLIPBOARDUPDATE message comes.

In other solutions for monitoring the clipboard I saw this was done on the actual main window of the application, but I wanted to separate the logic of monitoring the clipboard form the View and keep a clean MVVM. In an application I would instantiate the ClipboardMonitor in the ViewModel.

I am interested if there may be any hidden pitfalls where this approach may go wrong.

```
public sealed class ClipboardMonitor : IDisposable
{
private static class NativeMethods
{
///
/// Places the given window in the system-maintained clipboard format listener list.
///
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AddClipboardFormatListener(IntPtr hwnd);

///
/// Removes the given window from the system-maintained clipboard format listener list.
///
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool RemoveClipboardFormatListener(IntPtr hwnd);

///
/// Sent when the contents of the clipboard have changed.
///
public const int WM_CLIPBOARDUPDATE = 0x031D;

///
/// To find message-only windows, specify HWND_MESSAGE in the hwndParent parameter of the FindWindowEx function.
///
public static IntPtr HWND_MESSAGE = new I

Solution

Your code looks fine except for two points:

-
a Dispose() method should never throw an exception but yours will likely throw one if it is called twice. This can be avoided by having a private bool disposed variable which is checked by an if condition.

-
an event based method OnXXX is usually either private or protected and used to actually raise the event. A simple rename to ClipboardChanged will be sufficient to handle that issue.

Context

StackExchange Code Review Q#115417, answer score: 6

Revisions (0)

No revisions yet.