从命令用户界面处理函数(Command UIhandler)改变菜单状态(启用/禁用,选择/取消选择,更改文字)在由对话框处理时没有正常工作。
void CTestDlg::OnUpdateFileExit(CCmdUI* pCmdUI { pCmdUI->Enable(FALSE); //没有显示为禁用. pCmdUI->SetCheck(TRUE); // 没有文字前显示选定标记. pCmdUI->SetRadio(TRUE); // 没有在文字前显示点. pCmdUI->SetText("Close"); //没有更改菜单文字. }
以上菜单预处理函数在处理对话框的菜单时,并不会正常工作,这是就需要另找一个可行的办法来代替。
在下拉菜单显示的时候,WM_INITMENUPOPUP消息被先发送执行以显示菜单项,在有框架的视图/文档模式下,CFrameWnd::OnInitMenuPopup函数便利菜单项以响应。在对话框中,基类CDialog中没有相应的处理函数OnInitMenuPopup来处理,所以消息得不到执行。
BEGIN_MESSAGE_MAP(CTestDlg,CDialog) //{.............. ON_WM_INITMENUPOPUP() END_MESSAGE_MAP()
然后在对话框类头文件中,添加OnInitMenuPopUp成员函数并复制一下代码到该函数(基本上都是从CFrameWnd::OnInitMenuPopUp中复制过来的)
void CTestDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) { CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); // TODO: 在此处添加消息处理程序代码 ASSERT(pPopupMenu != NULL); // Check the enabled state of various menu items. CCmdUI state; state.m_pMenu = pPopupMenu; ASSERT(state.m_pOther == NULL); ASSERT(state.m_pParentMenu == NULL); // Determine if menu is popup in top-level menu and set m_pOther to // it if so (m_pParentMenu == NULL indicates that it is secondary popup). HMENU hParentMenu; if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu) state.m_pParentMenu = pPopupMenu; // Parent == child for tracking popup. else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL) { CWnd* pParent = this; // Child Windows don't have menus--need to go to the top! if (pParent != NULL && (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL) { int nIndexMax = ::GetMenuItemCount(hParentMenu); for (int nIndex = 0; nIndex < nIndexMax; nIndex++) { if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu) { // When popup is found, m_pParentMenu is containing menu. break; } } } } state.m_nIndexMax = pPopupMenu->GetMenuItemCount(); for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++) { state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex); if (state.m_nID == 0) continue; // Menu separator or invalid cmd - ignore it. ASSERT(state.m_pOther == NULL); ASSERT(state.m_pMenu != NULL); if (state.m_nID == (UINT)-1) { // Possibly a popup menu, route to first item of that popup. state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex); if (state.m_pSubMenu == NULL || (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 || state.m_nID == (UINT)-1) { continue; // First item of popup can't be routed to. } state.DoUpdate(this, TRUE); // Popups are never auto disabled. } else { // Normal menu item. // Auto enable/disable if frame window has m_bAutoMenuEnable // set and command is _not_ a system command. state.m_pSubMenu = NULL; state.DoUpdate(this, FALSE); } // Adjust for menu deletions and additions. UINT nCount = pPopupMenu->GetMenuItemCount(); if (nCount < state.m_nIndexMax) { state.m_nIndex -= (state.m_nIndexMax - nCount); while (state.m_nIndex < nCount && pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID) { state.m_nIndex++; } } state.m_nIndexMax = nCount; } }