如何监控C#中的剪贴板内容更改?

Wei*_*ing 41 .net c# clipboard

我想在我的C#程序中使用此功能:当用户在任何地方执行Ctrl+ C或复制时(即当剪贴板内容发生更改时),我的程序将收到通知,并检查内容是否符合某些条件,如果是,则成为活动程序,处理内容等

我可以从中获取内容System.Windows.Forms.Clipboard,但是,我不知道如何从剪贴板监视内容更改.

如果使用Windows Vista或更高版本,请使用AddClipboardFormatListenerJohn Knoeller的答案,对于Windows XP,我必须使用较旧的,更脆弱的SetClipboardViewerAPI,如接受的答案.

Jus*_*tin 51

我写了一个小实用程序类,它使用AddClipboardFormatListener函数函数和一个Message-only窗口来做这件事.

/// <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);
}
Run Code Online (Sandbox Code Playgroud)

此类假定在应用程序生存期内始终需要通知,但是可以修改它以提供通过RemoveClipboardFormatListener函数取消订阅的功能(如果需要).


Joh*_*ler 16

您可以通过pinvoke到Win32 API AddClipboardFormatListener来执行此操作

监听器是一个窗口句柄(Form.Handle),表单将通过WM_CLIPBOARDUPDATE通知通知更改

它是旧SetClipboardViewerAPI 的更强大的替代品.

  • 是的,最低要求是Vista.如果你在XP上,那么你别无选择,只能使用SetClipboarViewer.请注意,SetClipboardViewer很脆弱,但如果_your_代码正确并且您是_only_ viewer,则应该没有问题. (2认同)

小智 13

您可以使用win32 API提供的SetClipboardViewer(通过p/invoke).

这是一个包含在C#中设置一个代码的页面:http://www.codeguru.com/csharp/.net/net_general/tipstricks/article.php/c7315/

  • SetClipboardViewer是一个脆弱的旧API,你不应该在新代码中使用它.请改用AddClipboardFormatListener. (9认同)
  • 第二个链接断开。 (2认同)