编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

使用C#调用WINDOWS系统API监控剪切板变化就提醒

wxchong 2024-07-16 10:46:52 开源技术 9 ℃ 0 评论

大家新年好!今天是除夕夜,写篇文章润润手。

今天学习一下WINDOWS中的一个API方法“AddClipboardFormatListener”,用于实时监控剪切板的变化,虽然.NET中有剪切板类,但想达到实时监控的效果还得配合上Timer定期如50毫秒检查一次,我觉得设计上就不是很合理,WINDOWS上其实调用“AddClipboardFormatListener”API就能够满足我们,并且不是用Timer这种蠢办法。

话不多说,上干货。

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class ClipboardMonitor : Control
{
    public event EventHandler ClipboardUpdate;

    public ClipboardMonitor()
    {
        ClipboardUpdate += (sender, args) => { };
        NativeMethods.SetParent(Handle, NativeMethods.HWND_MESSAGE);
        NativeMethods.AddClipboardFormatListener(Handle);
    }

    protected override void WndProc(ref Message m)
    {
        const int WM_CLIPBOARDUPDATE = 0x031D;
        if (m.Msg == WM_CLIPBOARDUPDATE)
        {
            OnClipboardUpdate(EventArgs.Empty);
        }
        base.WndProc(ref m);
    }

    protected virtual void OnClipboardUpdate(EventArgs e)
    {
        ClipboardUpdate?.Invoke(this, e);
    }

    protected override void Dispose(bool disposing)
    {
        NativeMethods.RemoveClipboardFormatListener(Handle);
        base.Dispose(disposing);
    }

    private static class NativeMethods
    {
        public static readonly IntPtr HWND_MESSAGE = new IntPtr(-3);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AddClipboardFormatListener(IntPtr hwnd);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool RemoveClipboardFormatListener(IntPtr hwnd);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
    }
}

接下来讲解一下这段代码,在这个自定义Control中,我们创建了一个隐藏的Control,并使用AddClipboardFormatListener函数将其注册为剪切板的监听器。当剪切板的内容发生变化时,Windows会发送一个WM_CLIPBOARDUPDATE消息到这个Control,我们可以在WndProc方法中捕获这个消息,并触发ClipboardUpdate事件。

这段代码有个小技巧,AddClipboardFormatListener函数需要一个顶级窗口的句柄作为参数。在这个例子中,我们使用SetParent函数将Control的父窗口设置为HWND_MESSAGE,值为-3,这个值代表是一个特殊的窗口,用于接收没有父窗口的消息。

另外,由于AddClipboardFormatListener函数会增加对窗口的引用计数,所以在Control被销毁时,我们需要使用RemoveClipboardFormatListener函数来取消监听,否则可能会导致内存泄漏。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表