Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中监视剪贴板内容的更改?_C#_.net_Clipboard - Fatal编程技术网

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

如何在C#中监视剪贴板内容的更改?,c#,.net,clipboard,C#,.net,Clipboard,我希望在我的C#程序中具有此功能:当用户执行Ctrl+C或复制任意位置(即剪贴板内容更改时),我的程序将收到通知,并检查内容是否符合某些标准,如果符合,则成为活动程序,并处理内容,等等 我可以从System.Windows.Forms.Clipboard中获取内容,但是,我不知道如何监视剪贴板中的内容更改 如果使用WindowsVista或更高版本,请使用约翰·克诺勒的答案中的AddClipboardFormatListener,对于WindowsXP,我必须使用旧的、更脆弱的SetClipbo

我希望在我的C#程序中具有此功能:当用户执行Ctrl+C或复制任意位置(即剪贴板内容更改时),我的程序将收到通知,并检查内容是否符合某些标准,如果符合,则成为活动程序,并处理内容,等等

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


如果使用WindowsVista或更高版本,请使用约翰·克诺勒的答案中的
AddClipboardFormatListener
,对于WindowsXP,我必须使用旧的、更脆弱的
SetClipboardViewer
API,就像在接受的答案中一样。

您可以使用Win32 API的pinvoke来实现这一点

侦听器是一个窗口句柄(Form.handle),表单将通过 通知

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

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


下面是一个页面,其中包含在C#中设置的代码:

Win32 API包含一个函数SetClipboardViewer


我编写了一个小的实用程序类,它使用带有窗口的函数来实现这一点

/// <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);
}
//
///更新剪贴板内容时提供通知。
/// 
公共密封类剪贴簿通知
{
/// 
///在更新剪贴板的内容时发生。
/// 
公共静态事件处理程序剪贴簿更新;
私有静态NotificationForm_form=新NotificationForm();
/// 
///引发事件。
/// 
///事件的事件参数。
私有静态void OnClipboardUpdate(EventArgs e)
{
var handler=clipboadupdate;
if(处理程序!=null)
{
handler(null,e);
}
}
/// 
///隐藏表单以接收WM_剪贴簿更新消息。
/// 
私有类通知表单:表单
{
公共通知表()
{
SetParent(句柄,NativeMethods.HWND_消息);
AddClipboardFormatListener(句柄);
}
受保护的覆盖无效WndProc(参考消息m)
{
if(m.Msg==NativeMethods.WM_剪贴簿更新)
{
OnClipboardUpdate(空);
}
基准WndProc(参考m);
}
}
}
内部静态类NativeMethods
{
//看http://msdn.microsoft.com/en-us/library/ms649021%28v=vs.85%29.aspx
public const int WM_clipboadupdate=0x031D;
公共静态IntPtr HWND_消息=新IntPtr(-3);
//看http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only
[DllImport(“user32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
公共静态外部bool AddClipboardFormatListener(IntPtr hwnd);
//看http://msdn.microsoft.com/en-us/library/ms633541%28v=vs.85%29.aspx
//看http://msdn.microsoft.com/en-us/library/ms649033%28VS.85%29.aspx
[DllImport(“user32.dll”,SetLastError=true)]
公共静态外部IntPtr SetParent(IntPtr hWndChild、IntPtr hwndnnewparent);
}

此类假设在应用程序的生命周期内始终需要通知,但是可以对其进行修改,以便在需要时通过取消订阅。

SetClipboardViewer是一个脆弱的旧API,您不应该在新代码中使用它。改用AddClipboardFormatListener。同样,您也可以尝试。它提供了一个
ClipboardChanged
事件,允许您在剪切/复制各种数据格式并获取剪贴板内容时对其进行筛选。第二个链接已断开。谢谢。但在msdn页面上,此API的最低操作系统要求是Vista。这是真的吗?(但我仍然在使用XP。事实上,我的用户也将使用XP。)是的,最低要求是Vista。如果您使用的是XP,那么除了使用SetClipboarViewer,您别无选择。请注意SetClipboardViewer是脆弱的,尽管如果您的代码是正确的,并且您是唯一的查看器,您应该不会有任何问题。好的,我会非常小心。否则你的答案是最好的。谢谢这也是一个很好的例子。谢谢美好的你有没有更新过这个来合并XP?@tofutim没有,我不确定XP机器上有什么API可以实现同样的功能,你也可以试试。它提供了一个
ClipboardChanged
事件,允许您在剪切/复制各种数据格式并获取剪贴板内容时对其进行过滤。在WPF中如何做到这一点:作为一个库,由于它将相同的功能封装到一个精细的组件库中,因此它可能会带来更大的好处。然后,您可以访问其
ClipboardChanged
事件,并在剪切/复制时检测各种数据格式。