1. 程式人生 > >VC++動態加入和刪除選單的方法

VC++動態加入和刪除選單的方法

在應用程式中,往往要根據當前的操作來增加相應的選單。動態增加選單的方法有多 
種,本文只講述利用資源編輯器預建立選單資源,然後在程式執行中動態加入(或刪 
除)到主選單中去的方法。 
一、用AppWizard建立一個單文件工程,預設一切選項。在WorkSpace(工作空間)的 
ResourecView頁中右擊Menu資源,加入一個新的選單,其ID為:IDR_MENU1。為 
IDR_MENU1加入一個選單項和相應的子選單。如(圖一)所示。 
二、編輯IDR_MAINFRAME選單(ID為IDR_MAINFRAME的選單一般均為主選單),在【檢視 
(V)】選單項下面增加二個子選單項。如(圖二)所示。其屬性如下: 
ID 
Caption 
IDC_ADD 
加入選單 
IDC_DELETE 
刪除選單 
三、要訪問要選單,可使用CWnd類的GetMenu()成員函式、或使用全域性函式 
AfxGetMainWnd()―>GetMenu(),它們都返回一個CMenu物件的指標。一旦得到Cmenu指 
針,就可以對選單進行各種操作(裝入、增加、插入,刪除,更新等等)。通過Cmenu 
指標對選單進行操作後,應使用Cmenu類的Detach()成員函式從Cmenu物件中分離出菜 
單,避免發生衝突。之後呼叫CWnd::DrawMenuBar()重畫選單。 
四、為實現加入、刪除操作,我們用“ClassWizard”嚮導為IDC_ADD和IDC_DELETE增加 
兩個COMMAND訊息對映函式,它們分別為CMainFrame::OnAdd() 和 
CMainFrame::OnDelete()。接著我們為其編寫程式碼如下: 
void CMainFrame::OnAdd() //加入選單操作。 
CMenu addmenu,*mainmenu; 
if(!addmenu.LoadMenu(IDR_MENU1)) //裝入選單資源。 
MessageBox("選單裝入失敗!","錯誤",MB_OK|MB_ICONERROR); 
return; //如裝入失敗,顯示訊息框,且返回。 
CString str="顏色(&C)"; //要增加的選單項的標籤。 
mainmenu=AfxGetMainWnd()->GetMenu(); 
//取得指向視窗選單的Cmenu物件的指標。 
mainmenu->InsertMenu (1,MF_POPUP|MF_BYPOSITION|MF_STRING, 
(UINT)addmenu.GetSubMenu(0)-> m_hMenu,str); 
//將彈出式選單插入到第2項選單之前(選單項從0開始計算)。 
// addmenu.GetSubMenu(0)-> m_hMenu是被裝入選單的第一個選單項的彈出式選單的選單控制代碼。 
mainmenu->Detach(); //將視窗選單與Cmenu物件分離。 
addmenu.Detach(); //將資源選單(IDR_MENU1)與Cmenu物件分離。 
DrawMenuBar(); //重畫選單。 
Cmenu::InsertMenu的函式原形如下: 
BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ); 
引數 nPosition:指定在那個選單項前插入新選單項。被引數nFlags用於以下列方式解釋nPosition
NFlags引數 
NPosition引數的解釋 
MF_BYCOMMAND 
指定引數給出巳存在的選單項的命令ID號。此為預設值。 
MF_BYPOSITION 
指定引數給出巳存在的選單項的位置。第一項位於位置0。如果Nposition為-1,新選單將新增到選單尾。 
引數 nFlags:指定Nposition、nIDNewItem、lpszNewItem值如何被解釋。 
引數 nIDNewItem:指定新選單項的命令ID號,或者,若nFlags被設定為MF_POPUP,則指定為彈出選單的選單控制代碼(HMENU)。若nFlags被設定為MF_SEPARATOR,那麼引數nIDNewItem將被忽略。 
引數 lpszNewItem:指定新選單項的文字。被nFlags以下列方式解釋 
NFlags引數 
LpszNewItem的解釋 
MF_STRING 
包含指向以空格位終止符的字串指標。它為預設解釋。 
MF_SEPARATOR 
引數將被忽略。 
void CMainFrame::OnDelete() //刪除選單操作。 
CMenu *m 
ainmenu; 
CString str; 
mainmenu=GetMenu(); //取得指向視窗選單的Cmenu物件的指標。 
for(int i=mainmenu->GetMenuItemCount()-1;i>=0;i--) //取得選單的項數。 
mainmenu->GetMenuString(i,str,MF_BYPOSITION); 
//將指定選單項的標籤拷貝到指定的緩衝區。MF_BYPOSITION的解釋見上。 
if(str=="顏色(&C)") //如果是剛才我們增加的選單項,則刪除。 
mainmenu->DeleteMenu(i,MF_BYPOSITION); 
break; 
mainmenu->Detach(); //將視窗選單與Cmenu物件分離。 
DrawMenuBar(); //重畫選單。 
五、編譯,執行程式,看看到底是怎樣的!用這種方法動態增加選單有它的好處:即我們可以事先為選單ID編寫好COMMAND、UPDATE_COMMAND_UI訊息對映入口,在程式需要時動態的裝入選單即可。