我正在尝试在基于CFrameWndEx主框架窗口的VS2008(和VS2010)SDI项目中处理WM_MENUSELECT消息。
我从VS2008向导创build一个简单的项目(单个文档,“MFC标准”,“使用经典菜单”选项),导致类似(添加WM_MENUSELECT消息后):
class CMainFrame : public CFrameWnd { ///... public: afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu); };
和
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() ON_WM_MENUSELECT() END_MESSAGE_MAP() ///... void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu) { CFrameWnd::OnMenuSelect(nItemID, nFlags, hSysMenu); }
这是有效的,当在CMainFrame :: OnMenuSelect中放置一个断点时,它会在菜单被使用时触发(在这种情况下每次都会)
用CFrameWndEx代替CFrameWnd(或者通过向导创build一个带有单个文档,“MFC标准”,“使用菜单栏和工具栏”选项的新项目)
class CMainFrame : public CFrameWndEx { ///.... public: afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu); };
和
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWndEx) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx) ON_WM_CREATE() ON_WM_MENUSELECT() END_MESSAGE_MAP() ///.... void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu) { CFrameWndEx::OnMenuSelect(nItemID, nFlags, hSysMenu); }
该消息将永远不会被触发。
我甚至把使用CFrameWndEx的项目剥离到了最低限度,我仍然无法得到这个消息。
任何想法为什么? 提示,总是欢迎提示。 谢谢。 最大。
Aaah,单步进入MFC源代码的好时光! 这一直是关键;-)
CMFCPopupMenu :: SetSendMenuSelectMsg()是你的新朋友。
只要在你的CMainFrame::OnCreate()
添加这行:
CMFCPopupMenu::SetSendMenuSelectMsg(TRUE);
底线是MFC菜单和工具栏不是常用的标准Windows对象的包装。 他们用不同的模式来执行不同的事情。
现在,为了向后兼容,可以让这些类作为它们的前辈,并发送一个WM_MENUSELECT
,它们不是默认的。
注意:操作这些对象可能有新的机制或最佳实践。 这可能是值得研究的,而不是强制兼容性设置。
消息映射开始处的宏中的基类必须是正确的(在ON_WM_MENUSELECT
)。 我的猜测是,当您更改基类时,您没有将其更改为CFrameWndEx
。