MFC選單欄 CMenu 控制項

2021-09-25 01:22:25 字數 4230 閱讀 9232

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...