首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Win32 開發入門(25):監視剪貼板變更 - AddClipboardFormatListener 實作

     編輯:關於C++

實作剪貼板監視功能(如迅雷自動偵測下載連結)僅需兩步:註冊監視視窗、處理 WM_CLIPBOARDUPDATE 訊息。本文提供 C# 完整範例(可移植至 C++)。

核心 API

BOOL AddClipboardFormatListener(HWND hwnd);  // 註冊視窗接收剪貼板變更通知
// 對應訊息:WM_CLIPBOARDUPDATE (0x031D)

取消監視:RemoveClipboardFormatListener(hwnd)。

C# 完整實作

P/Invoke 宣告

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);
    }
}

C++ 對應實作要點

// 標頭檔
#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:// 的文字即觸發偵測,顯示於介面。

關鍵注意事項

  1. 視窗必須為訊息迴圈擁有者:Console 應用需建立隱藏視窗 (CreateWindowEx + GetMessage 迴圈)。
  2. 配對呼叫:AddClipboardFormatListener / RemoveClipboardFormatListener 必須成對,否則資源洩漏。
  3. 剪貼板存取序列化:OpenClipboard 失敗時重試(其他進程持有鎖定)。
  4. 格式優先序:優先 CF_UNICODETEXT,次 CF_TEXT,再 CF_HTML 等富文本格式。
  5. 效能考量:頻繁變更時避免在訊息處理中執行耗時操作,改用佇列交由背景執行緒處理。

適用版本

  • Windows Vista / Windows Server 2008 及更新版本。
  • XP 需使用舊式 SetClipboardViewer 鏈結機制(已淘汰)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved