【问题标题】:How do I monitor clipboard content changes in C#? [duplicate]如何在 C# 中监视剪贴板内容更改? [复制]
【发布时间】:2011-01-14 16:15:00
【问题描述】:

我想在我的 C# 程序中有这个功能:当用户执行 Ctrl + C 或复制任何地方(即剪贴板内容更改时),我的程序将得到通知,检查内容是否满足一定的条件,如果满足,成为活动程序,处理内容等。

我可以从System.Windows.Forms.Clipboard获取内容,但是,我不知道如何监控剪贴板中的内容变化。

如果使用 Windows Vista 或更高版本,请使用 John Knoeller 的答案中的 AddClipboardFormatListener,对于 Windows XP,我必须使用旧的、更脆弱的 SetClipboardViewer API,如已接受的答案中。

【问题讨论】:

  • 如何在 WPF 中执行此操作在这里:stackoverflow.com/a/33018459/2122718
  • SharpClipboard 作为一个库可能会更有好处,因为它将相同的功能封装到一个精细的组件库中。然后,您可以访问其ClipboardChanged 事件并在剪切/复制时检测各种数据格式。

标签: c# .net clipboard


【解决方案1】:

您可以通过 pinvoke 到 Win32 API AddClipboardFormatListener 来做到这一点

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

它是旧的SetClipboardViewer API 的更强大的替代品。

【讨论】:

  • 谢谢。但在 msdn 页面上,此 API 的最低操作系统要求是 Vista。真的吗? (不过我还在 XP 下。事实上,我的用户也会使用 XP。)
  • 是的,最低要求是 Vista。如果您使用的是 XP,那么您别无选择,只能使用 SetClipboarViewer。请注意,SetClipboardViewer 是脆弱的,但如果 您的 代码是正确的并且您是 唯一的查看器,则应该没有问题。
  • 好的,我会很小心的。否则,您的答案将是最好的。谢谢!
【解决方案2】:

您可以使用 Win32 API 提供的SetClipboardViewer(通过 P/Invoke)。

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

【讨论】:

  • SetClipboardViewer 是一个脆弱的旧 API,您不应该在新代码中使用它。请改用 AddClipboardFormatListener。
  • 同样,你也可以试试SharpClipboard。它提供了一个ClipboardChanged 事件,允许您在剪切/复制各种数据格式时过滤它们并获取剪贴板内容。
  • 第二个链接坏了。
【解决方案3】:

Win32 API 包含一个函数 SetClipboardViewer。

Here is a pretty good (from a quick glance) write up.

【讨论】:

  • 这也是一个很好的例子。谢谢!
【解决方案4】:

我编写了一个小型实用程序类,它使用 AddClipboardFormatListener function 函数和 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);
}

此类假定在应用程序生命周期内始终需要通知,但是可以对其进行修改以提供通过 RemoveClipboardFormatListener function 取消订阅的功能(如果需要)。

【讨论】:

  • 不错。你有没有更新这个以包含 XP?
  • @tofutim 不,我不确定 XP 机器上有哪些 API 可以做到这一点
  • 同样,你也可以试试SharpClipboard。它提供了一个ClipboardChanged 事件,允许您在剪切/复制各种数据格式时过滤它们并获取剪贴板内容。
猜你喜欢
  • 2010-10-11
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
相关资源
最近更新 更多