1.設定選單左邊顯示點陣圖和背景位圖
cmenu類裡要了解的函式
setmenuitembitmaps//設定選單項左邊的點陣圖
函式定義:bool setmenuitembitmaps( uint nposition, uint nflags, const cbitmap* pbmpunchecked, const cbitmap* pbmpchecked );
npostion指明具體要設定的選單項,可以是選單項索引,選單項id,具體由nflags引數指明,為mf_byposition,則以選單項索引指明,
為mf_bycommand則第乙個引數nposition是選單項id號。pbmpunchecked未被檢測時顯示的點陣圖(正常時),pbmpchecked檢測時顯示的(就是選單項被打上勾時所顯示的,跟checkmenuitem函式有關聯)
乙個api函式setmenuinfo,這個函式可以設定選單重繪時選擇的填充畫刷型別,該函式有兩個引數,第乙個是要設定的選單控制代碼,第二個是乙個menuinfo結構指標,我們只要了解這結構裡有乙個成員hbrback就行了,hbrback是乙個畫刷控制代碼,而選單背景點陣圖就通過建立位圖畫刷來實現的。
好了,以上面的工程為例,引入三張位圖,id號預設不變,然後再引入一張位圖(選單背景位圖,id:idb_menuback),接著在對話方塊類的oninitdialog函式裡新增如下語句:
cmenu *pmenu=getmenu();//獲取對話方塊關聯選單
cmenu *psubmenu=pmenu->getsubmenu(0);//獲得子選單(如果有)0表示索引,對應「檔案」選單
for(int i=0;i<3;i++)
cbitmap bmp;
cbrush m_bkbrush;
bmp.loadbitmap(idb_menuback);
m_bkbrush.createpatternbrush(&bmp);//建立位圖畫刷
menuinfo mninfo;
memset(&mninfo,0,sizeof(menuinfo));
mninfo.cbsize=sizeof(menuinfo);
mninfo.fmask=mim_background;
mninfo.hbrback=m_bkbrush;
::setmenuinfo(psubmenu->m_hmenu,&mninfo);
m_bkbrush.detach();
執行效果如下圖:
(ps:不知道大家有沒有碰到過這個問題,menuinfo結構未定義,解決的方法是進入檔案選項卡(fileview),在source file檔案下的stdafx.cpp檔案裡的最前面部分新增這個語句:#define winver 0x0501)
2.設計彈出式選單
cmenu類裡要了解的函式:
trackpopupmenu( uint nflags, int x, int y, cwnd* pwnd,lpcrect lprect = null );
該函式用於在介面顯示選單,nflags引數指明選單顯示標誌,x,y用於確定選單顯示基於的座標點,pwnd是選單相關聯的視窗。
在「mfc類庫詳解」中有關引數nflags的解釋如下:
指定螢幕位置標誌或滑鼠鍵標誌。
螢幕位置標誌可以為下列值之一: · tpm_centeralign 使彈出選單在水平方向相對於x指定的座標居中。 · tpm_leftalign 放置彈出選單,以便彈出選單在由座標值x指定的位置左對齊。 · tpm_rightalign 放置彈出選單,以便彈出選單在由座標值x指定的位置右對齊。
滑鼠鍵標誌可以為下列值之一: · tpm_leftbutton 導致彈出選單追蹤滑鼠左鍵。 · tpm_rightbutton 導致彈出選單追蹤滑鼠右鍵。
以上面工程為例,給對話方塊新增滑鼠右鍵抬起(wm_rbuttonup)訊息處理函式,在函式裡新增如下**:
void cseventhdlg::onrbuttonup(uint nflags, cpoint point)
要注意的是,要在介面顯示的選單,必須是乙個彈出選單,雖然menu->trackpopupmenu也可以顯示,但顯然不是想要的結果。
執行效果:
3.動態(純**)建立乙個選單
上面的例子,都是使用了選單資源建立的選單,這一次我們用**來建立選單,其實本質跟前面的用控制項類的create函式建立乙個控制項一樣。只不過這裡的「create」函式是createmenu和createpopupmenu函式。
cmenu類裡要了解的函式:
createmenu //建立乙個主選單,函式沒有引數
createpopupmenu//建立乙個具有彈出屬性的選單,函式沒有引數
mf_string 表明新增的是乙個不具有彈出屬性的選單項。
mf_popup 新增的乙個彈出選單項
mf_separator 新增的是乙個選單分隔條
mf_ownerdraw 表明對應選單具有自繪屬性
nidnewitem引數,如果新增的是乙個不具有彈出屬性的選單項,那麼該值就是選單項id號,否則是彈出式選單控制代碼,lpsznewitem是選單項名稱(選單文字內容)
好了,接著我們來動態建立乙個選單,首先往對話方塊裡新增乙個按鈕控制項,當單擊這個按鈕時,就建立選單,響應這個按鈕控制項的單擊訊息,訊息處理函式裡新增如下**:
4.更改選單項大小(寬高),設定選單文字字型大小
由於cmenu類裡並沒有提供設定選單項大小以及字型大小的函式,所以我們如果要實現上述功能的話,只能採取自繪的方法。
如果對cmenu類的某些函式不了解的話,可以參考"mfc 類大全",這裡就不講述了
首先從cmenu派生出乙個子類cnewmenu(類的型別為generic class),然後往這個類新增三個成員函式,measureitem(設定選單寬高),
drawitem(自繪選單),changemenuitem(修改選單項型別)
三個函式分別定義如下:
void cnewmenu::measureitem(lpmeasureitemstruct lpmeasureitemstruct)
void cnewmenu::drawitem(lpdrawitemstruct lpdrawitemstruct)
void cnewmenu::changemenuitem(cmenu *pmenu)
其中measureitem和drawitem是cmenu類的虛函式。
各函式的**如下:
void cnewmenu::measureitem(lpmeasureitemstruct lpmeasureitemstruct)
void cnewmenu::drawitem(lpdrawitemstruct lpdrawitemstruct)
} }
必須讓每個選單項具有mf_ownerdraw屬性,不然接不到wm_measureitem和wm_drawitem訊息,而且選單項不具有mf_ownerdraw屬性, 即使接到訊息,也無法自繪,所以上面的changemenuitem函式就是用於修改選單項屬性
wm_measureitem和wm_drawitem訊息不是直接發給選單視窗的,會被父視窗給收到,所以得處理父視窗的wm_measureitem和wm_drawitem訊息,給話框類新增這兩個訊息處理函式,兩個函式裡的**分別如下:
void cfirstdlg::onmeasureitem(int nidctl, lpmeasureitemstruct lpmeasureitemstruct)
void cfirstdlg::ondrawitem(int nidctl, lpdrawitemstruct lpdrawitemstruct)
接著我們在對話類新增乙個成員變數:
cnewmenu newmenu; (記得要包含標頭檔案:"newmenu.h"),然後在對話方塊類的oninitdialog函式新增如下**:
newmenu.loadmenu(idr_menu1);
setmenu(&newmenu);
//只更改下主選單下的第一項,更改全部:newmenu.changemenuitem(&newmenu);
newmenu.changemenuitem(newmenu.getsubmenu(0));
idr_menu1是選單資源的id號,可自行建立。好了,到了這裡大功已經告成了,點編譯執行,效果如下:
跟自繪按鈕控制項一樣,上面依然沒處理選單的所有狀態,如獲得焦點,被核記,有無關聯。也不處理選單分隔條。。
如果想處理這些狀態的話。建議檢視drawitemstruct結構的itemstate變數,這個成員指明選單項的狀態,
關聯,就檢視cmenu類的函式。。。
原文:
MFC 選單欄顯示隱藏
首先獲取程式視窗大小 在cmainframe 定義變數crect clientrect 在oncreate裡獲取客戶區大小,並隱藏選單欄 m wndcommandbar.showwindow sw hide getclientrect clientrect bool cmainframe pretr...
MFC獲取選單欄的高度
在一些情況下,我們可能會需要獲取乙個視窗選單欄的高度。一般情況下使用下面一行 可以獲取到選單欄的高度 int height getsystemmetrics sm cymenu 但是有乙個問題,就是當視窗寬度變小時,選單欄可能會變成兩行,如圖所示 此時,如果使用getsystemmetrics獲取到...
MFC選單欄及工具欄實現
mfc選單欄實現 在資源檢視中,右鍵工程名.rc 新增資源,選擇menu。對menu設定id,並對menu選單進行設定 即新增選單欄的名字 在c dlg.h中,新增cmenu m menu 在c dlg.c的初始化中,新增m menu.loadmenu idr menu1 idr menu1 set...