MFC選單、子選單、選單項的控制
阿新 • • 發佈:2019-01-25
CMenu::CMenu CMenu( ); CMenu::LoadMenu //載入一個選單 BOOL LoadMenu( LPCTSTR lpszResourceName ); CWnd::GetMenu //獲取選單欄 CMenu* GetMenu( ) const; CMenu::CreatePopupMenu //建立彈出選單(頂層選單) BOOL CreatePopupMenu( ); CMenu::GetSubMenu //獲取子選單 CMenu* GetSubMenu( int nPos ) const; CMenu::CheckMenuItem //該函式取得與指定選單項相聯絡的選單標誌 UINT CheckMenuItem( UINT nIDCheckItem, UINT nCheck ); CMenu::SetDefaultItem //設定預設選單 BOOL SetDefaultItem( UINT uItem, BOOL fByPos = FALSE ); CMenu::SetMenuItemBitmaps //設定圖形標記選單 BOOL SetMenuItemBitmaps( UINT nPosition, UINT nFlags, const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked ); int GetSystemMetrics( int nIndex // system metric or configuration setting ); CMenu::EnableMenuItem //允許、禁止或變灰指定的選單項 UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable ); CWnd::SetMenu //將當前選單設為指定的選單,也可用來清除選單(NULL),但不會銷燬選單 BOOL SetMenu( CMenu* pMenu ); /* CCmdUI沒有基類。 它僅在一個CCmdTarget派生類的ON_UPDATE_COMMAND_UI處理程式中使用。 當用戶在應用的下拉選單時,要確定每個選單項的顯示狀態——允許存取或禁止存取。 選單命令的目標通過實現一個ON_UPDATE_COMMAND_UI處理來提供這些資訊。 可以使用ClassWizard來瀏覽定位應用中的命令使用者介面物件,然後為它建立一個訊息對映入口, 併為每個訊息處理函式提供函式原型。 */ CWnd::ClientToScreen //客戶區座標轉換為螢幕座標 void ClientToScreen( LPPOINT lpPoint ) const; void ClientToScreen( LPRECT lpRect ) const; CMenu::TrackPopupMenu //指定位置顯示快捷選單 BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL ); /*動態選單操作*/ CMenu::InsertMenu BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ); BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp ); CMenu::AppendMenu BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ); BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp ); CMenu::DeleteMenu BOOL DeleteMenu( UINT nPosition, UINT nFlags ); detach()函式 //MFC類裡CMENU類的成員函式。功能是切斷一個CWnd物件和一個有效視窗的聯絡。
/*demo1(為選單項打標記) 在框架類的OnCreate()中新增如下程式碼: */ GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_CHECKED|MF_BYPOSITION );//通過位置索引 GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_OPEN,MF_CHECKED|MF_BYCOMMAND);//通過命令ID索引 /*demo2(設定預設選單) 在框架類的OnCreate()中新增如下程式碼: */ /*GetMenu()->GetSubMenu(0)->SetDefaultItem(2,TRUE);//通過位置索引*/ GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_SAVE_AS,FALSE);//通過命令ID索引 /* demo3(圖形標記選單) 在框架類的OnCreate()中新增如下程式碼: */ CBitmap *bitmap=new CBitmap(); bitmap->LoadBitmap(IDB_BITMAP1); GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,bitmap,bitmap); /* demo4(獲取系統指定選單點陣圖大小) 在框架類的OnCreate()中新增如下程式碼: */ CString str; str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK)); MessageBox(str); /* demo5(允許、禁止或變灰指定的選單項) 建構函式中初始化m_bAutoMenuEnable = FALSE; 在框架類的OnCreate()中新增如下程式碼: */ GetMenu()->GetSubMenu(0)->EnableMenuItem(0, MF_BYPOSITION | MF_DISABLED | MF_GRAYED); CMenu* mmenu = GetMenu(); CMenu* submenu = mmenu->GetSubMenu(0); submenu->EnableMenuItem(ID_FILE_OPEN, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); /* demo6(消除和載入選單) 在框架類的OnCreate()中新增如下程式碼: */ SetMenu(NULL); CMenu menu; menu.LoadMenu(IDR_MAINFRAME); SetMenu(&menu); menu.Detach();//使區域性變數menu不被析構,也可以申請堆記憶體或者把menu設定為成員變數 /* demo7(捕獲ON_UPDATE_COMMAND_UI訊息更新選單) 選擇ClassWizard”選單項,在出現的介面中,選擇Class Name為“CMainFrame”, 增加成員函式,Object Ids、Messages、Member functions分別為: ID_EDIT_CUT、UPDATE_COMMAND_UI、OnUpdateEditCut() EditCode: */ void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI) { // if(2==pCmdUI->m_nIndex)//工具欄不會被關聯 if(ID_EDIT_CUT==pCmdUI->m_nID)//工具欄會被關聯,工具欄和選單欄ID號一致 pCmdUI->Enable(TRUE);//剪下選單項設定為允許 } /* demo8(建立一個非彈出式選單項) 在ResourceView中編輯Menu目錄下的IDR_MAINFRAME,新增一個新的選單項,不選擇彈出。 選擇ClassWizard”選單項,在出現的介面中,選擇Class Name為“CMainFrame”, 增加成員函式,Object Ids、Messages、Member functions分別為: ID_TEST、COMMAND、OnTest() EditCode: */ void CMainFrame::OnTest() { AfxMessageBox("MainFrame Clicked!"); } /* demo9(建立彈出快捷鍵選單) 在ResourceView中編輯Menu目錄下插入一個新的選單資源。 在View類中新增WM_RBUTTONDOWN訊息響應函式 EditCode: */ void CMenuView::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CMenu menu; menu.LoadMenu(IDR_MENU1); CMenu *pPopup = menu.GetSubMenu(0); ClientToScreen(&point);//客戶區座標轉換為螢幕座標 pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this); //用this指標,只能讓view類進行目錄項命令響應,如果要框架類視窗也響應,則用GetParent() CView::OnRButtonDown(nFlags, point); } /* demo10(動態控制選單) 在框架類中的OnCreat()函式中新增如下程式碼。 EditCode: */ CMenu menu; menu.CreatePopupMenu();//建立彈出選單 GetMenu()->AppendMenu(MF_POPUP, (UINT)menu.m_hMenu,"SYAU");//新增子選單(彈出選單MF_POPUP型別對應著子選單的控制代碼) GetMenu()->InsertMenu(2,MF_BYPOSITION|MF_POPUP, (UINT)menu.m_hMenu,"SYAU");//插入子選單 menu.AppendMenu(MF_STRING,111,"MFC1");//新增選單項(選單項MF_STRING型別對應著選單項的ID) menu.AppendMenu(MF_STRING,112,"MFC2"); menu.AppendMenu(MF_STRING,113,"MFC3"); menu.Detach(); GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,114,"welcome");//新增選單項 GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,MF_BYCOMMAND|MF_STRING,115,"MFC");//插入選單項 //GetMenu()->DeleteMenu(1,MF_BYPOSITION);//刪除子選單 //GEtMenu()->GetSubMenu(0)->DeleteMenu(2,MF_BYPOSITION);//刪除選單項 //demo11(在動態新增的選單中進行命令響應) //在檔案檢視的Resource.h中,新增選單項的ID號: #define IDM_MFC1 111 //在MainFrm.h的中新增訊息的原型: protected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnEditCut(); //}}AFX_MSG afx_msg void OnMfc1(); DECLARE_MESSAGE_MAP() //在MainFrm.cpp中新增訊息對映: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_COMMAND(ID_EDIT_CUT, OnEditCut) //}}AFX_MSG_MAP ON_COMMAND(IDM_MFC1, OnMfc1) END_MESSAGE_MAP() //在MainFrm.cpp中新增函式的實現: void CMainFrame::OnMfc1() { MessageBox("MFC1 clicked!"); }
/* demo12(在框架類中截獲本由視類完成的訊息處理) 在框架類中重寫虛擬函式OnCommand() */ BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class int MenuCmdId = LOWORD(wParam);//獲取命令ID /* CString str; str.Format("%d",MenuCmdId); MessageBox(str); */ CMenu3View *pView = (CMenu3View *)GetActiveView();//獲取View類指標 if(MenuCmdId>=IDM_PHONE1 && MenuCmdId<IDM_PHONE1+pView->m_strArray.GetSize()) { CClientDC dc(pView); dc.TextOut(0,0,pView->m_strArray.GetAt(MenuCmdId-IDM_PHONE1)); return TRUE;//執行完後直接返回,View不會再響應 } return CFrameWnd::OnCommand(wParam, lParam);//基類完成訊息路由 }