在研讀《VC6.0 技術內幕》時,發現書中關於自訂使用者訊息的說明較為分散,故整理此筆記供日後查閱。自訂訊息機制是 MFC 程式設計中實現物件間解耦通訊的核心技能之一。
實作前須明確兩個角色:
SendMessage 或 PostMessage 的物件。以物件 A 傳送訊息給物件 B(或 A 自己)為例說明完整流程。
在發送者的標頭檔(或共用標頭檔)中定義訊息 ID,所有自訂訊息皆以 WM_USER 為基底加上正整數:
#define WM_USERMESSAGE (WM_USER + 30)
建議集中管理於專案共用的 CustomMessages.h,避免 ID 衝突。
在發送者 A 的某個成員函式中,取得接收者 B 的視窗指標或句柄,呼叫:
// 同步發送,阻塞直到處理完成
B->SendMessage(WM_USERMESSAGE, wParam, lParam);
// 非同步發送,立即返回
B->PostMessage(WM_USERMESSAGE, wParam, lParam);
wParam、lParam 為自訂資料承載,Win32 慣用做法。
接收者 B 需完成三個部分:
在 DECLARE_MESSAGE_MAP() 宏之前,於 AFX_MSG 區塊加入:
afx_msg LRESULT OnMyCustomMsg(WPARAM wParam, LPARAM lParam);
在 BEGIN_MESSAGE_MAP 之後、AFX_MSG_MAP 區塊加入(無分號結尾):
ON_MESSAGE(WM_USERMESSAGE, OnMyCustomMsg)
LRESULT CMyClass::OnMyCustomMsg(WPARAM wParam, LPARAM lParam)
{
// 解析 wParam、lParam 執行對應邏輯
return 0; // 返回值視需求而定
}
PostMessage 或 PostThreadMessage,避免死結。WM_USER~0x7FFF 為視窗類別私有,WM_APP~0xBFFF 為應用程式全域,建議大型專案使用 WM_APP 基底。完整專案範例可參考 GitHub 範例庫 VC6-CustomMessage-Demo,包含發送端/接收端雙專案與跨執行緒示範。