剪貼板是進程間資料交換的核心通道。本文詳細講解如何在 C++ Builder 中實現剪貼板變更監視,並示範變更時自動彈出右鍵選單的完整技術路徑。
Windows 維護一個剪貼板檢視器鏈,每個監視視窗透過 SetClipboardViewer 加入鏈頭,ChangeClipboardChain 移除。收到 WM_DRAWCLIPBOARD 訊息表示剪貼板內容變更,必須呼叫 SendMessage 轉發給鏈中下一個視窗。
private:
void __fastcall ClipboardChanged(TMessage& Msg);
public:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DRAWCLIPBOARD, TMessage, ClipboardChanged)
END_MESSAGE_MAP(TForm)
MESSAGE_HANDLER 將特定訊息導向自定處理函數,避免巨大的 WndProc switch-case。
void __fastcall TForm1::ClipboardChanged(TMessage& Msg) {
POINT MousePos;
GetCursorPos(&MousePos);
PopupMenu4->PopupComponent = Form1;
PopupMenu4->Popup(MousePos.x, MousePos.y);
// 關鍵:必須轉發訊息給鏈中下一個視窗
SendMessage(NextViewer, Msg.Msg, Msg.WParam, Msg.LParam);
}
此範例在滑鼠位置彈出選單,實際應用可改為記錄變更歷史、同步遠端剪貼板等。
void __fastcall TForm1::ToolButton9Click(TObject *Sender) {
static HWND LastHandle;
static bool clip = false;
if (clip) {
ToolButton9->Down = false;
ChangeClipboardChain(Form1->Handle, LastHandle);
} else {
ToolButton9->Down = true;
Clipboard()->Clear(); // 可選:清空剪貼板
Application->Minimize(); // 可選:最小化視窗
LastHandle = SetClipboardViewer(Form1->Handle);
}
clip = !clip;
}
按鈕切換監視狀態,LastHandle 保存鏈中原本的下一個視窗,停止時正確移除自身。
Clipboard()->HasFormat(CF_TEXT) 判斷是否有文字格式Clipboard()->AsText 直接取得文字內容EnumClipboardFormats 列舉所有可用格式AddClipboardFormatListener 替代舊鏈機制本技術結合 OnIdle 事件(見相關文章)可構建專業級剪貼板增強工具。