打赏

CR TubeGet中有用户需要剪切板监视功能,记录代码以做备忘:

复制代码
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace CRTubeGet
{
    /// <summary>
    /// Provides notifications when the contents of the clipboard is updated.
    /// </summary>
    public sealed class ClipboardNotification
    {
        public const int WM_CLIPBOARDUPDATE = 0x031D;

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool AddClipboardFormatListener(IntPtr hWnd);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RemoveClipboardFormatListener(IntPtr hWnd);

        /// <summary>
        /// Occurs when the contents of the clipboard is updated.
        /// </summary>
        public event MethodInvoker ClipboardUpdate;

        public ClipboardNotification()
        {
            new NotificationForm(OnClipboardUpdate);
        }

        /// <summary>
        /// Raises the <see cref="ClipboardUpdate"/> event.
        /// </summary>
        /// <param name="e">Event arguments for the event.</param>
        private void OnClipboardUpdate()
        {
            var handler = ClipboardUpdate;
            if (handler != null)
                handler();
        }

        /// <summary>
        /// Hidden form to recieve the WM_CLIPBOARDUPDATE message.
        /// </summary>
        private class NotificationForm : Form
        {
            private MethodInvoker onClipboardUpdate;
            private IntPtr hWnd;
            private int lastTickCount;

            public NotificationForm(MethodInvoker onClipboardUpdate)
            {
                this.onClipboardUpdate = onClipboardUpdate;
                this.hWnd = this.Handle;
                AddClipboardFormatListener(this.hWnd);
            }

            ~NotificationForm()
            {
                RemoveClipboardFormatListener(this.hWnd);
            }

            protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_CLIPBOARDUPDATE && this.onClipboardUpdate != null)
                {
                    //列表类解析,会阻止时间,用此法不行,再用lastText方法
                    if (Environment.TickCount - this.lastTickCount >= 200)
                        this.onClipboardUpdate();
                    this.lastTickCount = Environment.TickCount;
                    m.Result = IntPtr.Zero;
                }
                base.WndProc(ref m);
            }
        }
    }
}
复制代码

期间所见问题为有些Copy事件会触发两次甚至更多WM_CLIPBOARDUPDATE消息,比如下载任务之[复制URL]操作。因此,以Environment.TickCount间隔值做为判断条件。

使用方法:

复制代码
        private void StartClipboardWatch()
        {
            var cn = new ClipboardNotification();
            cn.ClipboardUpdate += cn_ClipboardUpdate;
        }

        private void cn_ClipboardUpdate()
        {
            if (!App.WatchClipboard || !Clipboard.ContainsText() || Program.ModalLevel != 0)
                return;

            this.downloadPage.Download(false, true);
            GA.TrackEvent(DataType.Download, "From", "WatchClipboard");
        }
复制代码

 

参考资料:

win10监听剪切板变化 - _York - 博客园

posted on 2019-07-28 08:57  楚人无衣  阅读(3200)  评论(0编辑  收藏  举报