Windows 是訊息驅動架構。每個執行緒擁有訊息佇列,訊息結構 MSG 包含:hwnd (目標視窗)、message (訊息 ID)、wParam/lParam (參數)、time、pt (滑鼠座標)。
訊息迴圈核心:GetMessage → TranslateMessage → DispatchMessage。
#define WM_USER_COMMAND (WM_USER + 100) // 避免與系統訊息衝突
單一文件專案,選單項目「命令一/二/三」對應處理函數:
void CMainFrame::OnSendCmd1() { SendCommand(0, 0); }
void CMainFrame::OnSendCmd2() { SendCommand(0, 1); }
void CMainFrame::OnSendCmd3() { SendCommand(1, 0); }
void CMainFrame::SendCommand(WPARAM wp, LPARAM lp) {
CWnd* pWnd = CWnd::FindWindow(NULL, _T("Receiver")); // 依視窗標題尋找
if (pWnd) pWnd->SendMessage(WM_USER_COMMAND, wp, lp);
}
BOOL CWorkerApp::InitInstance() {
// ... 框架初始化 ...
m_pMainWnd->SetWindowText(_T("Receiver")); // 關鍵:讓主控端 FindWindow 找到
return TRUE;
}
// MainFrm.h
#define WM_USER_COMMAND (WM_USER + 100)
class CMainFrame : public CFrameWnd {
// ...
afx_msg void OnUserCommand(WPARAM wp, LPARAM lp);
DECLARE_MESSAGE_MAP()
};
// MainFrm.cpp
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_MESSAGE(WM_USER_COMMAND, OnUserCommand)
END_MESSAGE_MAP()
void CMainFrame::OnUserCommand(WPARAM wp, LPARAM lp) {
if (wp == 0 && lp == 0) AfxMessageBox(_T("收到命令一"));
else if (wp == 0 && lp == 1) AfxMessageBox(_T("收到命令二"));
else if (wp == 1 && lp == 0) AfxMessageBox(_T("收到命令三"));
}
SendMessage:主控程式發送後**阻塞**,直到受控程式彈出的 AfxMessageBox 被關閉。PostMessage:主控程式**不阻塞**,適合高頻非同步通知。| 優點 | 缺點 | 適用場景 |
|---|---|---|
| 實作簡單、無需共用記憶體/管道 | 資料承載量小 (僅兩個參數) | 上層控制下層工作流、簡單命令觸發 |
| 視窗句柄即天然連接點 | 需目標視窗存在、單機限制 | GUI 應用程式間鬆耦合協作 |
WM_COPYDATA 結構體傳遞緩衝區指標。