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