MFC---上下文菜单(快捷菜单)管理器
在MFC中的app類的InitInstance函數(shù)中,我們會(huì)看到這樣一個(gè)函數(shù),InitContextMenuManager,從它的字面意義可以看出是“初始化上下文菜單管理器”。像這樣,在初始化函數(shù)中調(diào)用了這個(gè)函數(shù),那么MFC框架就會(huì)為你創(chuàng)建一個(gè)類型為CContextMenuManager的對(duì)象,另外我們也可以手動(dòng)創(chuàng)建這個(gè)對(duì)象,但是如果手動(dòng)創(chuàng)建,那么就不要在使用這個(gè)函數(shù)了,否則會(huì)出錯(cuò),MFC中由這個(gè)對(duì)象來(lái)管理程序中的快捷菜單,當(dāng)然,我們也可以使用win32的那種方法來(lái)實(shí)現(xiàn)快捷菜單的功能。那么MFC的一個(gè)優(yōu)勢(shì)就是使用面向?qū)ο蟮姆椒▉?lái)管理程序中的各個(gè)對(duì)象,對(duì)于菜單,MFC也提供了一個(gè)對(duì)象來(lái)專門管理快捷菜單,首先來(lái)看看在由MFC向?qū)傻膯挝臋n程序中,對(duì)菜單管理器的使用。
當(dāng)我們使用MFC向?qū)梢粋€(gè)單文檔程序之后,我們?cè)诳蛻魠^(qū)點(diǎn)擊右鍵,就有一個(gè)快捷菜單,如下:
由于我們沒(méi)有添加命令響應(yīng),因此菜單上面的項(xiàng)目都是灰色的。現(xiàn)在來(lái)看看它是如何做到的,首先在app類的PreLoadState函數(shù)中有如下語(yǔ)句:
void CcontextmenuApp::PreLoadState()
{
BOOL bNameValid;
CString strName;
bNameValid = strName.LoadString(IDS_EDIT_MENU);
ASSERT(bNameValid);
GetContextMenuManager()->AddMenu(strName, IDR_POPUP_EDIT);
}
在這里GetContextMenuManager是app類的一個(gè)方法,但是這里要注意的是這個(gè)函數(shù)是CWinAppEx函數(shù),在CWinApp類中沒(méi)有,這個(gè)我們可以修改我們自己的app類的基類就可以了,但是使用VS2010這不是什么問(wèn)題。GetContextMenuManager函數(shù)會(huì)返回CContextMenuManager類型的對(duì)象指針,然后調(diào)用AddMenu方法,就將一個(gè)菜單資源添加到了這個(gè)對(duì)象當(dāng)中,那么這個(gè)對(duì)象指針由框架保存,為了我們方便使用,我們可以在我們的類中聲明一個(gè)CContextMenuManager類型的對(duì)象指針,來(lái)保存對(duì)象的地址,這樣我們?cè)谑褂玫臅r(shí)候比較方便。
在這里已經(jīng)將菜單資源添加到了快捷菜單管理器中,現(xiàn)在我們就可以使用了,那么在什么時(shí)候應(yīng)該彈出快捷菜單呢,有的人使用的鼠標(biāo)右鍵按下或是右鍵彈起的時(shí)候,進(jìn)行彈出響應(yīng)。這樣做也是可以達(dá)到效果的,但是在windows中,有一個(gè)消息,是專門用來(lái)處理快捷菜單的,那就是WM_CONTEXTMENU,那么這個(gè)消息也是在當(dāng)?WM_RBUTTONUP 或是WM_NCRBUTTONUP(非客戶區(qū)鼠標(biāo)右鍵彈起)傳遞給默認(rèn)窗口過(guò)程函數(shù)DefWindowProc時(shí)由默認(rèn)窗口過(guò)程處理生成的。因此,這里我們就要注意,當(dāng)我們自己處理了WM_RBUTTONUP之后,應(yīng)該繼續(xù)調(diào)用基類處理。否則,不會(huì)有WM_CONTEXTMENU消息生成,另外,還需要注意的一個(gè)是WM_RBUTTONUP的消息參數(shù)中傳遞的坐標(biāo)是客戶區(qū)坐標(biāo),而我們要使用的,應(yīng)該是屏幕坐標(biāo),因此,需要做一個(gè)轉(zhuǎn)換或是使用GetCursorPos來(lái)獲取光標(biāo)的位置。現(xiàn)在看由MFC框架生成的對(duì)快捷菜單的調(diào)用,它是在View類中處理的WM_CONTEXTMENU消息中處理的,如下:
oid CcontextmenuView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
這樣,當(dāng)我們點(diǎn)擊鼠標(biāo)右鍵的時(shí)候,就會(huì)生成一個(gè)WM_CONTEXTMENU消息,這時(shí)候,我們響應(yīng)快捷菜單彈出的消息,這里它就是是用快捷菜單管理器來(lái)彈出的快捷菜單,ShowPopuMenu就是CContextMenuManager類的成員函數(shù)。如果我們是使用win32的方法來(lái)實(shí)現(xiàn)快捷菜單,也可以在這里做出相應(yīng)的處理,而不使用MFC提供的快捷菜單管理器。下面我們做一個(gè)自己的快捷菜單,來(lái)看看快捷菜單管理器的使用。
首先我們?cè)谫Y源編輯器中,插入自定義的菜單,如下:
現(xiàn)在回到App類的PreLoadState函數(shù)做,做出修改,加載我們自己定義的菜單,修改后如下:
void CcontextmenuApp::PreLoadState()
{
/*BOOL bNameValid;
CString strName;
bNameValid = strName.LoadString(IDS_EDIT_MENU);
ASSERT(bNameValid);*/
GetContextMenuManager()->AddMenu(L"MYMENU"/*strName*/, IDR_MYMENU);
}
接著,我在View類的WM_CONTEXTMENU消息響應(yīng)函數(shù)下,也做出修改,修改后如下:
void CcontextmenuView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_MYMENU, point.x, point.y, this, TRUE);
#endif
}
現(xiàn)在可以運(yùn)行一下,看看效果:
這樣就實(shí)現(xiàn)了我們功能,我們看見(jiàn)菜單項(xiàng)目仍然是灰色,當(dāng)我們?yōu)樗鼈兲砑用铐憫?yīng)之后,那么就不會(huì)是灰色狀態(tài),以第一個(gè)菜單項(xiàng)目為例:
我在View類中做響應(yīng),如下:
void CcontextmenuView::OnMymenu32771()
{
// TODO: 在此添加命令處理程序代碼
this->MessageBox(L"菜單項(xiàng)目一");
}
下面再次運(yùn)行:
現(xiàn)在我們看見(jiàn)“菜單項(xiàng)目一”,由于添加了命令響應(yīng),現(xiàn)在已經(jīng)不再是灰色了,我們點(diǎn)擊響應(yīng)一次:
在快捷菜單管理器其中,我們可以使用AddMenu添加多個(gè)菜單,但是同一個(gè)菜單不應(yīng)多次添加。另外,如果是自己手動(dòng)創(chuàng)建的快捷菜單管理器對(duì)象,那么在使用的時(shí)候,需要多點(diǎn)注意事項(xiàng),例如,新菜單彈出來(lái)之后,是否應(yīng)該自動(dòng)關(guān)閉原來(lái)的那個(gè)快捷菜單,如果遇到問(wèn)題,可以查閱msdn,獲得解決方法。推薦使用由MFC的這個(gè)快捷菜單管理器來(lái)管理我們的快捷菜單,省去了使用win32彈出快捷菜單的很多步驟和資源回收的工作。更加安全可靠。
更多信息,參考MSDN,推薦大家用好MSDN,是我不懈的努力!^_^
推薦編程者訪問(wèn)網(wǎng)站:http://www.panshy.com 獲取更多知識(shí)。
本文代碼:http://download.csdn.net/detail/xinzhiyounizhiyouni/6793861
總結(jié)
以上是生活随笔為你收集整理的MFC---上下文菜单(快捷菜单)管理器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2018软件测试从业者精进指南 。
- 下一篇: dbms_metadata.get_dd