能否将加速器条目与已注册的窗口消息直接关联?
关于已注册窗口消息关联加速器表的问题
没有直接在加速器表中关联RegisterWindowMessage返回的动态消息值的方法,原因如下:
- 加速器表是编译阶段就固定的资源文件,其中的条目只能使用预定义的静态整数ID(比如资源中定义的
ID_*常量)。 RegisterWindowMessage的返回值是程序运行时由系统动态分配的(范围在0xC000到0xFFFF之间),无法提前写入静态的加速器资源脚本里。
不过你可以优化间接调用的实现,让代码更简洁:
- 统一转发逻辑:在主窗口的命令消息处理中集中转发,避免为每个注册消息单独写处理函数:
void CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { if (nCode == CN_COMMAND) { switch(nID) { case ID_SEARCH_FIND_NEXT: PostMessage(theApp.UWM_FIND_NEXT_MSG); return; // 标记为已处理,终止后续传递 // 可在此添加更多加速器ID与注册消息的映射 } } // 未处理的命令交给基类处理 CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); }
- 复用转发函数:通过消息映射将多个加速器ID绑定到同一个转发函数,在函数内根据ID匹配对应的注册消息:
// 消息映射 ON_COMMAND(ID_SEARCH_FIND_NEXT, &CMainFrame::ForwardRegisteredMsg) ON_COMMAND(ID_SEARCH_FIND_PREV, &CMainFrame::ForwardRegisteredMsg) void CMainFrame::ForwardRegisteredMsg() { UINT msg = 0; switch(GetCurrentMessage()->wParam) { case ID_SEARCH_FIND_NEXT: msg = theApp.UWM_FIND_NEXT_MSG; break; case ID_SEARCH_FIND_PREV: msg = theApp.UWM_FIND_PREV_MSG; break; } if (msg != 0) { PostMessage(msg); } }
另外需要注意:注册窗口消息主要用于跨进程通信,而加速器表是进程内的快捷方式定义,间接转发的方式本身就符合两者的使用场景,是合理的实现方案。
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

