實作剪貼板監視功能(如迅雷自動偵測下載連結)僅需兩步:註冊監視視窗、處理 WM_CLIPBOARDUPDATE 訊息。本文提供 C# 完整範例(可移植至 C++)。
BOOL AddClipboardFormatListener(HWND hwnd); // 註冊視窗接收剪貼板變更通知
// 對應訊息:WM_CLIPBOARDUPDATE (0x031D)
取消監視:RemoveClipboardFormatListener(hwnd)。
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public partial class Form1 : Form {
[DllImport("User32.dll", SetLastError = true)]
private static extern bool AddClipboardFormatListener(IntPtr hwnd);
[DllImport("User32.dll", SetLastError = true)]
private static extern bool RemoveClipboardFormatListener(IntPtr hwnd);
private const int WM_CLIPBOARDUPDATE = 0x031D;
public Form1() {
InitializeComponent();
// 視窗建立後註冊
AddClipboardFormatListener(this.Handle);
}
protected override void WndProc(ref Message m) {
if (m.Msg == WM_CLIPBOARDUPDATE) {
if (Clipboard.ContainsText()) {
string text = Clipboard.GetText();
// 偵測 URI 格式
if (text.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ||
text.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) {
txtOutput.AppendText(
$"[{DateTime.Now:HH:mm:ss}] 剪貼板變更,偵測到 URI:\r\n{text}\r\n" +
new string('-', 50) + "\r\n");
}
}
m.Result = IntPtr.Zero; // 標記已處理
} else {
base.WndProc(ref m);
}
}
protected override void OnFormClosing(FormClosingEventArgs e) {
RemoveClipboardFormatListener(this.Handle); // 釋放註冊
base.OnFormClosing(e);
}
}
// 標頭檔
#define WM_CLIPBOARDUPDATE 0x031D
// 視窗建立時
AddClipboardFormatListener(hWnd);
// 訊息迴圈處理
case WM_CLIPBOARDUPDATE: {
if (OpenClipboard(hWnd)) {
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
HGLOBAL hGlobal = GetClipboardData(CF_UNICODETEXT);
if (hGlobal) {
wchar_t* pszText = (wchar_t*)GlobalLock(hGlobal);
if (pszText) {
std::wstring text(pszText);
GlobalUnlock(hGlobal);
// 檢查 URI 前綴...
}
}
}
CloseClipboard();
}
return 0;
}

複製含 https:// 或 https:// 的文字即觸發偵測,顯示於介面。
CreateWindowEx + GetMessage 迴圈)。AddClipboardFormatListener / RemoveClipboardFormatListener 必須成對,否則資源洩漏。OpenClipboard 失敗時重試(其他進程持有鎖定)。CF_UNICODETEXT,次 CF_TEXT,再 CF_HTML 等富文本格式。SetClipboardViewer 鏈結機制(已淘汰)。