【.net 深呼吸】监听剪贴板更新(针对Vista之后系统)
2021-06-21 15:04
标签:cte das nbsp 技术分享 封装 rdl use void .com 针对 XP 及以前的监视剪贴板更改的方法就不讲了,因为 XP 已严重过时。本篇老周介绍的方法面向 Vista 以上的系统。 在托管应用程序中监听剪贴板更新行为必须用到 Win 32 API ,具体做法,我先简单说一下。 首先,调用 AddClipboardFormatListener 函数来向窗口注册监听行为,它需要一个窗口句柄作为传入参数,该句柄所指的窗口即是监听剪贴板更新的窗口。 然后,当剪贴板的内容被更新,处理程序会收到一条 WM_CLIPBOARDUPDATE 消息。我们在应用程序中,只要收到这条消息,就说明剪贴板的内容已被更新。 WM_CLIPBOARDUPDATE 消息的宏定义如下: 这个消息的 wParam 和 lParam 参数都不曾使用,所以我们不必理会这两个参数值。如果用户已处理该消息,应当返回 0。 AddClipboardFormatListener 函数的原型如下: 在托管代码中调用它,要先进行导入。 好,基本理论说完了,下面我们来看看如何在WPF程序中监听剪贴板更新。 由于此功能实为WPF与 Win32 的交互操作,因此,要用到 HwndSource 类,这个类公开了一个 AddHook 方法,调用这个方法可以添加一个 HwndSourceHook 委托实例,当窗口接收到消息时,就会调用这个委托。 该委托的定义如下。 你一定会猛然发现,这个委托很像 WinProc 函数指针。msg 参数就是被拦截到的消息。在与该委托绑定的方法中,我们可以对收到的消息进行筛选,因为我们这里只关心 WM_CLIPBOARDUPDATE 消息,其他的咱们不管。 ClipboardUpdated 事件是我封装时定义的,这是为了方便引发。 还有一件事,各位会发现,HwndSource 实例创建时需要与一个窗口的句柄绑定,那么,如何获取到 Window 实例的句柄呢,这就要用到一个帮助类—— WindowInteropHelper。有了它,想得到窗口的句柄就很简单了。 在添加 hook 处理之前,一定要记得调用 AddClipboardFormatListener 函数为窗口注册监听行为。 要是监听行为注册成功,就可以添加 hook 了。 那么,咱们封装的这些代码如何用到窗口代码中呢。Window 有一个 SourceInitialized 事件,当句柄初始化完成就会发生。我们可以重写 OnSourceInitialized 方法,然后在方法中使用我们上面封装的代码。 只要监听到剪贴板被更新,那么要获取剪贴板上的数据就很容易了,因为System.Windows下面已经有一个 Clipboard 类,它有一堆静态方法,可以直接读写剪贴板上的内容。 运行程序后,随便复制点东东到剪贴板中,就会看到程序有反应了。如下面高清无码截图所示。 好了,本文就扯到这里了。 本文示例源代码下载 【.net 深呼吸】监听剪贴板更新(针对Vista之后系统) 标签:cte das nbsp 技术分享 封装 rdl use void .com 原文地址:http://www.cnblogs.com/tcjiaan/p/7182279.html#define WM_CLIPBOARDUPDATE 0x031D
BOOL WINAPI AddClipboardFormatListener(
_In_ HWND hwnd
);
[DllImport("User32.dll")]
static extern bool AddClipboardFormatListener(IntPtr hwnd);
delegate IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled);
private IntPtr OnHooked(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_CLIPBOARDUPDATE)
{
ClipboardUpdated?.Invoke(this, EventArgs.Empty);
return IntPtr.Zero;
}
return IntPtr.Zero;
}
public event EventHandler ClipboardUpdated;
WindowInteropHelper helper = new WindowInteropHelper(window);
_hwndSource = HwndSource.FromHwnd(helper.Handle);
bool r = AddClipboardFormatListener(_hwndSource.Handle);
if (r)
{
_hwndSource.AddHook(new HwndSourceHook(OnHooked));
}
ClipboardHooker m_clipboardHooker;
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
m_clipboardHooker = new ClipboardHooker(this);
m_clipboardHooker.ClipboardUpdated += OnClipboardUpdated;
}
private void OnClipboardUpdated(object sender, EventArgs e)
{
tb.Text = "老板,有人修改了剪贴板。";
IDataObject data = Clipboard.GetDataObject();
string[] fs = data.GetFormats();
tb.Text += $"\n数据格式:{string.Join("、", fs)}";
}
文章标题:【.net 深呼吸】监听剪贴板更新(针对Vista之后系统)
文章链接:http://soscw.com/index.php/essay/96949.html