void CGfxPopupMenu::EnableMenuItems(CMenu * pMenu, CWnd * pParent) { ASSERT(pMenu); ASSERT(pParent); int nItem = pMenu->GetMenuItemCount(); CCmdUI state; state.m_pMenu = pMenu; state.m_nIndex = nItem-1; state.m_nIndexMax = nItem; while ((--nItem)>=0) { UINT itemId = pMenu->GetMenuItemID(nItem); if (itemId == (UINT) -1) { CMenu *pops = pMenu->GetSubMenu(nItem); if (pops) EnableMenuItems(pops, pParent); } else { if (itemId != 0) { state.m_nID = itemId; pParent->OnCmdMsg(itemId, CN_UPDATE_COMMAND_UI, &state, NULL); state.DoUpdate(pParent, true); } } state.m_nIndex = nItem-1; } }
// 参看:http://www.cnblogs.com/hcfalan/archive/2010/11/24/1886139.html BOOL CDlgImageViewer::ContinueModal() { if(m_ToolBar.IsWindowVisible()) { CFrameWnd* pParent = (CFrameWnd*)m_ToolBar.GetParent(); if(pParent) m_ToolBar.OnUpdateCmdUI(pParent, (WPARAM)TRUE); } CMenu* pMainMenu = GetMenu(); CCmdUI cmdUI; if (pMainMenu != NULL) { for (int n = 0; n < pMainMenu->GetMenuItemCount(); ++n) { CMenu* pSubMenu = pMainMenu->GetSubMenu(n); cmdUI.m_nIndexMax = pSubMenu->GetMenuItemCount(); for (int i = 0; i < cmdUI.m_nIndexMax; ++i) { cmdUI.m_nIndex = i; cmdUI.m_nID = pSubMenu->GetMenuItemID(i); cmdUI.m_pMenu = pSubMenu; cmdUI.DoUpdate(this, FALSE); } } } return CDialogEx::ContinueModal(); }
BOOL CPopupFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { if (m_pMenu != NULL && pHandlerInfo == NULL) { if (nCode == CN_COMMAND) { if (m_pMenu->SelectItem(nID) == S_OK) return TRUE; } else if (nCode == CN_UPDATE_COMMAND_UI) { CCmdUI* pCmdUI = (CCmdUI*)pExtra; long lState; if (m_pMenu->GetItemState(pCmdUI->m_nID, &lState) == S_OK) { pCmdUI->Enable((lState & MenuStateDisable) == 0); pCmdUI->SetCheck((lState & MenuStateCheck) != 0); return TRUE; } } } return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); }
LRESULT CPIMDIFrameWndEx::OnUICheckEvent(WPARAM wParam, LPARAM lParam) { CCmdUI* pCmdUI = (CCmdUI*)wParam; ASSERT(pCmdUI != NULL); BOOL bCheck = (BOOL)lParam; pCmdUI->SetCheck(bCheck); return 0; }
LRESULT CPIMDIFrameWndEx::OnUIEnableEvent(WPARAM wParam, LPARAM lParam) { CCmdUI* pCmdUI = (CCmdUI*)wParam; ASSERT(pCmdUI != NULL); BOOL bEnable = (BOOL)lParam; pCmdUI->Enable(bEnable); return 0; }
void CDocSelector::OnUpdateCmdUI( CFrameWnd* pTarget, BOOL bDisableIfNoHndler ) { CCmdUI state; state.m_pOther = this; state.m_nIndexMax = 1; // there's only one thing to update state.m_nID = AFX_IDW_STATUS_BAR; // allow the statusbar itself to have update handlers if ( CControlBar::OnCmdMsg( state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL ) ) return; // allow target (owner) to handle the remaining updates state.DoUpdate( pTarget, FALSE ); }
void CProgressBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) // I'm not entirely sure how much of this is necessary, but it doesn't seem to // do any harm, and things didn't work properly until I put it in... { CCmdUI state; state.m_pOther = this; state.m_nIndexMax = (UINT32)m_nCount; for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++) { state.m_nID = 0; state.DoUpdate(pTarget, bDisableIfNoHndler); } // update the dialog controls added to the status bar (of which there are none) UpdateDialogControls(pTarget, bDisableIfNoHndler); }
void CModelessMain::OnInitMenuPopup(CMenu* pPopupMenu, UINT /*nIndex*/, BOOL bSysMenu) { if (!bSysMenu) { ENSURE(pPopupMenu != NULL); // check the enabled state of various menu items CCmdUI state; state.m_pMenu = pPopupMenu; ASSERT(state.m_pOther == NULL); 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, FALSE); // popups are never auto disabled } else { // normal menu item // Auto enable/disable if command is _not_ a system command state.m_pSubMenu = NULL; state.DoUpdate(this, state.m_nID < 0xF000); } } } }
//Стандартный вызов ON_UPDATE_COMMAND_UI запрещает элементы меню, но не делает их grayed. //Чтобы все таки запрещенные элементы меню выглядели как grayed, нужно вызывать эту функцию //Note: эта функция не перерисовывает меню. //Возвращает true - если произошли изменения и нужно перерисовать меню, иначе false bool CMainFrame::_UpdateTopLevelMainMenu(void) { CMenu* pMenu = this->GetMenu(); std::vector<UINT> old_menu_state; //remember old states of all menu items { int menu_items_count = pMenu->GetMenuItemCount(); for(int i = 0; i < menu_items_count; ++i) old_menu_state.push_back(pMenu->GetMenuState(pMenu->GetMenuItemID(i),MF_BYCOMMAND)); } //Perform update CCmdUI ui; ui.m_nIndexMax = pMenu->GetMenuItemCount(); ui.m_pMenu = pMenu; for (ui.m_nIndex = 0; ui.m_nIndex < ui.m_nIndexMax; ui.m_nIndex++) { ui.m_nID = pMenu->GetMenuItemID(ui.m_nIndex); ui.DoUpdate(this, m_bAutoMenuEnable); } //Check: do we need to redraw menu? { int menu_items_count = pMenu->GetMenuItemCount(); for(int i = 0; i < menu_items_count; ++i) { UINT old_s = old_menu_state[i]; UINT new_s = pMenu->GetMenuState(pMenu->GetMenuItemID(i),MF_BYCOMMAND); if (old_s!=new_s) return true; //caller should redraw main menu } } //nothing changed: redraw is not needed return false; }
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { // TODO: 在此添加专用代码和/或调用基类 #ifndef __USING_INTER_RESOURCE // 2011/08/22-8201-gxx: // 指定版本的文字资源来自于grc // if (nCode == CN_UPDATE_COMMAND_UI) { if (CBCGPFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo) == TRUE) { if (nID == ID_VIEW_TOOLBAR) { ASSERT(FALSE); } CCmdUI *pCmdUI = (CCmdUI*)pExtra; if (pCmdUI->m_pOther != NULL && pCmdUI->m_pOther == &m_wndToolBar) { // 不对工具栏做处理 } else { pCmdUI->SetText(LOAD_STRING(nID)); } return TRUE; } return FALSE; } #endif return CBCGPFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); }
void CIMoteTerminal::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) { 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. state.m_pParentMenu = CMenu::FromHandle(hParentMenu); 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; } }
BOOL CPageToolbars::OnCmdMsg(UINT nID, INT nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { if( !m_bInitComplete ){ return CPageBase::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); } if( nCode == CN_UPDATE_COMMAND_UI || nCode == CN_COMMAND ) { if( nID == ID_MYEXTBTN_SLIDER || nID == ID_MYEXTBTN_SCROLLER ) { if( nCode == CN_UPDATE_COMMAND_UI ){ CCmdUI * pCmdUI = (CCmdUI *)pExtra; ASSERT( pCmdUI != NULL ); pCmdUI->Enable(); } return TRUE; } if( nID == ID_COMBOBOX_IN_TOOLBAR || nID == ID_COMBOBOX_IN_MENUBAR || nID == ID_EDIT_IN_TOOLBAR || nID == ID_EDIT_IN_MENUBAR || nID == ID_CHECKBOX_IN_TOOLBAR || nID == ID_CHECKBOX_IN_MENUBAR || nID == ID_LINE_WIDTH_0 || nID == ID_LINE_WIDTH_1 || nID == ID_LINE_WIDTH_2 || nID == ID_LINE_WIDTH_3 || nID == ID_LINE_WIDTH_4 || nID == ID_LINE_WIDTH_5 || nID == ID_LINE_WIDTH_6 || nID == ID_LINE_WIDTH_7 || nID == ID_LINE_WIDTH_8 || nID == ID_LINE_WIDTH_9 || nID == ID_LINE_WIDTH_10 || nID == ID_LINE_WIDTH_OTHER ) { if( nCode == CN_UPDATE_COMMAND_UI ){ CCmdUI * pCmdUI = (CCmdUI *)pExtra; ASSERT( pCmdUI != NULL ); pCmdUI->Enable(); } return TRUE; } if( nID == IDC_CHECK_SHOW_GRIPPER ) { if( nCode == CN_COMMAND ){ bool bDlgButtonChecked = ( IsDlgButtonChecked( nID ) == BST_CHECKED ); m_wndToolBarColor.SetBarStyle( bDlgButtonChecked ? m_wndToolBarColor.GetBarStyle() | CBRS_GRIPPER : m_wndToolBarColor.GetBarStyle() & ~CBRS_GRIPPER ); m_wndToolBarPalette.SetBarStyle( bDlgButtonChecked ? m_wndToolBarPalette.GetBarStyle() | CBRS_GRIPPER : m_wndToolBarPalette.GetBarStyle() & ~CBRS_GRIPPER ); m_wndToolBar.SetBarStyle( bDlgButtonChecked ? m_wndToolBar.GetBarStyle() | CBRS_GRIPPER : m_wndToolBar.GetBarStyle() & ~CBRS_GRIPPER ); m_wndMenuBar.SetBarStyle( bDlgButtonChecked ? m_wndMenuBar.GetBarStyle() | CBRS_GRIPPER : m_wndMenuBar.GetBarStyle() & ~CBRS_GRIPPER ); m_wndToolBarControls1.SetBarStyle( bDlgButtonChecked ? m_wndToolBarControls1.GetBarStyle() | CBRS_GRIPPER : m_wndToolBarControls1.GetBarStyle() & ~CBRS_GRIPPER ); m_wndToolBarControls2.SetBarStyle( bDlgButtonChecked ? m_wndToolBarControls2.GetBarStyle() | CBRS_GRIPPER : m_wndToolBarControls2.GetBarStyle() & ~CBRS_GRIPPER ); _Update(); } } if( m_wndToolBarColor.GetSafeHwnd() != NULL ) { INT nBtnHeight = 0; switch( nID ) { case ID_HEIGHT_8PX: nBtnHeight = 8; break; case ID_HEIGHT_10PX: nBtnHeight = 10; break; case ID_HEIGHT_12PX: nBtnHeight = 12; break; case ID_HEIGHT_14PX: nBtnHeight = 14; break; case ID_HEIGHT_16PX: nBtnHeight = 16; break; case ID_HEIGHT_18PX: nBtnHeight = 18; break; case ID_HEIGHT_20PX: nBtnHeight = 20; break; case ID_HEIGHT_22PX: nBtnHeight = 22; break; case ID_HEIGHT_24PX: nBtnHeight = 24; break; case ID_HEIGHT_26PX: nBtnHeight = 26; break; case ID_HEIGHT_28PX: nBtnHeight = 28; break; case ID_HEIGHT_30PX: nBtnHeight = 30; break; } // switch( nID ) if( nBtnHeight != 0 ) { if( nCode == CN_UPDATE_COMMAND_UI ) { CCmdUI * pCmdUI = (CCmdUI *)pExtra; ASSERT( pCmdUI != NULL ); pCmdUI->Enable(); pCmdUI->SetRadio( (m_nThinColorBtnHeight == nBtnHeight) ? TRUE : FALSE ); } else { if( m_nThinColorBtnHeight != nBtnHeight ) { m_nThinColorBtnHeight = nBtnHeight; CWnd::RepositionBars(0,0xFFFF,0); m_wndToolBarColor.RedrawWindow(); } } return TRUE; } INT nColorCmdIndex = m_wndToolBarColor.CommandToIndex( nID ); if( nColorCmdIndex >= 0 ) { if( nCode == CN_UPDATE_COMMAND_UI ) { CCmdUI * pCmdUI = (CCmdUI *)pExtra; ASSERT( pCmdUI != NULL ); pCmdUI->Enable(); } else { CWinApp * pApp = ::AfxGetApp(); ASSERT( pApp != NULL ); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( _T("PageToolbars"), nID ); ASSERT( pCmdItem != NULL ); CString sMsg; sMsg.Format( _T("Command from the color toolbar:\n\n%s"), pCmdItem->m_sMenuText ); ::AfxMessageBox( LPCTSTR(sMsg) ); } return TRUE; } } } return CPageBase::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); }
//This method should be called when a pop-up menu is about to become active void CDiagnostContextMenuManager::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu) { ASSERT(m_pWnd); if (bSysMenu) return; // don't support system menu ASSERT(pMenu != NULL); // check the enabled state of various menu items CCmdUI state; state.m_pMenu = pMenu; 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 == pMenu->m_hMenu) state.m_pParentMenu = pMenu; // parent == child for tracking popup else if ((hParentMenu = ::GetMenu(m_pWnd->m_hWnd)) != NULL) { CWnd* pParent = m_pWnd->GetTopLevelParent(); // 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) == pMenu->m_hMenu) { // when popup is found, m_pParentMenu is containing menu state.m_pParentMenu = CMenu::FromHandle(hParentMenu); break; } } } } state.m_nIndexMax = pMenu->GetMenuItemCount(); for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++) { state.m_nID = pMenu->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 = pMenu->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(m_pWnd, FALSE); // 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(m_pWnd, TRUE); } // adjust for menu deletions and additions UINT nCount = pMenu->GetMenuItemCount(); if (nCount < state.m_nIndexMax) { state.m_nIndex -= (state.m_nIndexMax - nCount); while (state.m_nIndex < nCount && pMenu->GetMenuItemID(state.m_nIndex) == state.m_nID) { state.m_nIndex++; } } state.m_nIndexMax = nCount; }//for }
/** * Show context menu and handle user selection. */ void CLocationView::OnContextMenu(CWnd* pWnd, CPoint point) { if (point.x == -1 && point.y == -1) { //keystroke invocation CRect rect; GetClientRect(rect); ClientToScreen(rect); point = rect.TopLeft(); point.Offset(5, 5); } CRect rc; CPoint pt = point; GetClientRect(rc); ScreenToClient(&pt); BCMenu menu; VERIFY(menu.LoadMenu(IDR_POPUP_LOCATIONBAR)); theApp.TranslateMenu(menu.m_hMenu); BCMenu* pPopup = (BCMenu *) menu.GetSubMenu(0); ASSERT(pPopup != NULL); CCmdUI cmdUI; cmdUI.m_pMenu = pPopup; cmdUI.m_nIndexMax = cmdUI.m_pMenu->GetMenuItemCount(); for (cmdUI.m_nIndex = 0 ; cmdUI.m_nIndex < cmdUI.m_nIndexMax ; ++cmdUI.m_nIndex) { cmdUI.m_nID = cmdUI.m_pMenu->GetMenuItemID(cmdUI.m_nIndex); switch (cmdUI.m_nID) { case ID_DISPLAY_MOVED_NONE: cmdUI.SetRadio(m_displayMovedBlocks == DISPLAY_MOVED_NONE); break; case ID_DISPLAY_MOVED_ALL: cmdUI.SetRadio(m_displayMovedBlocks == DISPLAY_MOVED_ALL); break; case ID_DISPLAY_MOVED_FOLLOW_DIFF: cmdUI.SetRadio(m_displayMovedBlocks == DISPLAY_MOVED_FOLLOW_DIFF); break; } } CString strItem; CString strNum; int nLine = -1; int bar = IsInsideBar(rc, pt); // If cursor over bar, format string with linenumber, else disable item if (bar != BAR_NONE) { // If outside bar area use left bar if (bar == BAR_YAREA) bar = BAR_LEFT; nLine = GetLineFromYPos(pt.y, bar); strNum.Format(_T("%d"), nLine + 1); // Show linenumber not lineindex } else pPopup->EnableMenuItem(ID_LOCBAR_GOTODIFF, MF_GRAYED); LangFormatString1(strItem, ID_LOCBAR_GOTOLINE_FMT, strNum); pPopup->SetMenuText(ID_LOCBAR_GOTODIFF, strItem, MF_BYCOMMAND); // invoke context menu // we don't want to use the main application handlers, so we use flags TPM_NONOTIFY | TPM_RETURNCMD // and handle the command after TrackPopupMenu int command = pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, point.x, point.y, AfxGetMainWnd()); CMergeDoc* pDoc = GetDocument(); switch (command) { case ID_LOCBAR_GOTODIFF: m_view[MERGE_VIEW_LEFT]->GotoLine(nLine, true, bar); if (bar == BAR_LEFT || bar == BAR_RIGHT) m_view[bar]->SetFocus(); break; case ID_EDIT_WMGOTO: m_view[MERGE_VIEW_LEFT]->WMGoto(); break; case ID_DISPLAY_MOVED_NONE: SetConnectMovedBlocks(DISPLAY_MOVED_NONE); pDoc->SetDetectMovedBlocks(FALSE); break; case ID_DISPLAY_MOVED_ALL: SetConnectMovedBlocks(DISPLAY_MOVED_ALL); pDoc->SetDetectMovedBlocks(TRUE); break; case ID_DISPLAY_MOVED_FOLLOW_DIFF: SetConnectMovedBlocks(DISPLAY_MOVED_FOLLOW_DIFF); pDoc->SetDetectMovedBlocks(TRUE); break; } }
void CISenTekAssistantDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) { ASSERT(pPopupMenu != NULL); CCmdUI state; state.m_pMenu = pPopupMenu; ASSERT(state.m_pOther == NULL); ASSERT(state.m_pParentMenu == NULL); HMENU hParentMenu; if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu) state.m_pParentMenu = pPopupMenu; else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL) { CWnd* pParent = this; 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) { state.m_pParentMenu = CMenu::FromHandle(hParentMenu); 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; ASSERT(state.m_pOther == NULL); ASSERT(state.m_pMenu != NULL); if (state.m_nID == (UINT)-1) { 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; } state.DoUpdate(this, TRUE); } else { state.m_pSubMenu = NULL; state.DoUpdate(this, FALSE); } 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; } }
void FileScrapDropDlg::OnInitMenuPopup(CMenu* pPopupMenu, xpr_uint_t nIndex, xpr_bool_t bSysMenu) { ASSERT(pPopupMenu != XPR_NULL); //super::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); // for multi-language BCMenu *pBCPopupMenu = dynamic_cast<BCMenu *>(pPopupMenu); if (pBCPopupMenu != XPR_NULL) { xpr_uint_t sId; xpr_sint_t sCount = pBCPopupMenu->GetMenuItemCount(); const xpr_tchar_t *sStringId; const xpr_tchar_t *sString; xpr::string sMenuText; CommandStringTable &sCommandStringTable = CommandStringTable::instance(); xpr_sint_t i; for (i = 0; i < sCount; ++i) { sId = pBCPopupMenu->GetMenuItemID(i); // apply string table if (sId != 0) // if sId is 0, it's separator. { if (sId == -1) { // if sId(xpr_uint_t) is -1, it's sub-menu. pBCPopupMenu->GetMenuText(i, sMenuText, MF_BYPOSITION); sString = gApp.loadString(sMenuText); pBCPopupMenu->SetMenuText(i, (xpr_tchar_t *)sString, MF_BYPOSITION); } else { sStringId = sCommandStringTable.loadString(sId); if (sStringId != XPR_NULL) { sString = gApp.loadString(sStringId); pBCPopupMenu->SetMenuText(sId, (xpr_tchar_t *)sString, MF_BYCOMMAND); } } } } } // Check the enabled state of various menu items. CCmdUI sState; sState.m_pMenu = pPopupMenu; ASSERT(sState.m_pOther == XPR_NULL); ASSERT(sState.m_pParentMenu == XPR_NULL); // Determine if menu is popup in top-level menu and set m_pOther to // it if so (m_pParentMenu == XPR_NULL indicates that it is secondary popup). HMENU sParentMenu; if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu) sState.m_pParentMenu = pPopupMenu; // Parent == child for tracking popup. else if ((sParentMenu = ::GetMenu(m_hWnd)) != XPR_NULL) { CWnd *sParentWnd = this; // Child windows don't have menus--need to go to the top! if (sParentWnd != XPR_NULL && (sParentMenu = ::GetMenu(sParentWnd->m_hWnd)) != XPR_NULL) { xpr_sint_t sIndex; xpr_sint_t sIndexMax = ::GetMenuItemCount(sParentMenu); for (sIndex = 0; sIndex < sIndexMax; ++sIndex) { if (::GetSubMenu(sParentMenu, sIndex) == pPopupMenu->m_hMenu) { // When popup is found, m_pParentMenu is containing menu. sState.m_pParentMenu = CMenu::FromHandle(sParentMenu); break; } } } } sState.m_nIndexMax = pPopupMenu->GetMenuItemCount(); for (sState.m_nIndex = 0; sState.m_nIndex < sState.m_nIndexMax; ++sState.m_nIndex) { sState.m_nID = pPopupMenu->GetMenuItemID(sState.m_nIndex); if (sState.m_nID == 0) continue; // Menu separator or invalid cmd - ignore it. ASSERT(sState.m_pOther == XPR_NULL); ASSERT(sState.m_pMenu != XPR_NULL); if (sState.m_nID == (xpr_uint_t)-1) { // Possibly a popup menu, route to first item of that popup. sState.m_pSubMenu = pPopupMenu->GetSubMenu(sState.m_nIndex); if (sState.m_pSubMenu == XPR_NULL || (sState.m_nID = sState.m_pSubMenu->GetMenuItemID(0)) == 0 || sState.m_nID == (xpr_uint_t)-1) { continue; // First item of popup can't be routed to. } sState.DoUpdate(this, XPR_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. sState.m_pSubMenu = XPR_NULL; sState.DoUpdate(this, XPR_FALSE); } // Adjust for menu deletions and additions. xpr_uint_t sCount = pPopupMenu->GetMenuItemCount(); if (sCount < sState.m_nIndexMax) { sState.m_nIndex -= (sState.m_nIndexMax - sCount); while (sState.m_nIndex < sCount && pPopupMenu->GetMenuItemID(sState.m_nIndex) == sState.m_nID) { sState.m_nIndex++; } } sState.m_nIndexMax = sCount; } }