MFC 消息映射機制預設一條消息對應一個處理函數。若需實現「一條消息觸發多個類的處理邏輯」(如插件系統、模組解耦),可採用函數指針陣列 + 動態註冊模式,實現輕量級觀察者模式。
// MsgHandler.h
#pragma once
#include
#include
#include
// 統一處理器簽名:WPARAM, LPARAM 為標準消息參數
using MsgHandlerFunc = std::function;
class CMsgDispatcher {
public:
static CMsgDispatcher& Instance() {
static CMsgDispatcher inst;
return inst;
}
// 註冊處理器,返回唯一 ID 供後續註銷
UINT RegisterHandler(MsgHandlerFunc handler) {
std::lock_guard lock(m_mutex);
m_handlers.push_back(handler);
return (UINT)m_handlers.size(); // 簡易 ID
}
// 註銷處理器
void UnregisterHandler(UINT id) {
std::lock_guard lock(m_mutex);
if (id > 0 && id <= m_handlers.size()) {
m_handlers[id - 1] = nullptr; // 標記失效
}
}
// 分發消息
void Dispatch(WPARAM wParam, LPARAM lParam) {
std::lock_guard lock(m_mutex);
for (auto& handler : m_handlers) {
if (handler) handler(wParam, lParam);
}
}
private:
std::vector m_handlers;
std::mutex m_mutex;
};
// ModuleA.cpp
class CModuleA {
public:
CModuleA() {
// 構造時註冊,使用 Lambda 捕獲 this
m_handlerId = CMsgDispatcher::Instance().RegisterHandler(
[this](WPARAM w, LPARAM l) { OnCustomMsg(w, l); }
);
}
~CModuleA() {
CMsgDispatcher::Instance().UnregisterHandler(m_handlerId);
}
void OnCustomMsg(WPARAM w, LPARAM l) {
// 模組 A 的具體處理邏輯
TRACE(_T("ModuleA received: %d, %d\n"), w, l);
}
private:
UINT m_handlerId = 0;
};
// MainFrame.cpp 或 View.cpp
LRESULT CMainFrame::OnCustomMessage(WPARAM wParam, LPARAM lParam) {
// 核心:一條消息分發給所有註冊處理器
CMsgDispatcher::Instance().Dispatch(wParam, lParam);
return 0;
}
// 發送消息觸發
PostMessage(WM_USER_CUSTOM, param1, param2);
std::map> 按優先級排序調用CCmdTarget 派生類重寫 OnCmdMsg 實現命令路由鏈此模式打破 MFC 單一消息映射限制,以現代 C++ 風格實現靈活的多播機制,且零侵入原有消息循環。