patterncsharpMinor
Monitoring the clipboard
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
To achieve this a message-only window (a term that comes from the Win32 API) is created using an instance of
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
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
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
-
an event based method
-
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.