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");
}
參考資料:

