中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

中山百度網(wǎng)站排名網(wǎng)頁百度網(wǎng)盤

中山百度網(wǎng)站排名,網(wǎng)頁百度網(wǎng)盤,內(nèi)蒙古兩學(xué)一做網(wǎng)站,福州網(wǎng)站建設(shè)招商6.1 菜 單 設(shè)計(jì) 菜單是可視化編程的重要組成部分,是一種方便地給命令分組并訪問這些命令的方法。菜單通常用來顯示程序的各項(xiàng)功能,以方便用戶選擇執(zhí)行,通過對菜單命令進(jìn)行編程可以調(diào)用程序中相應(yīng)的功能。 6.1.1 菜單類CMenu 在MFC中&#x…

6.1??菜 單 設(shè)計(jì)

菜單是可視化編程的重要組成部分,是一種方便地給命令分組并訪問這些命令的方法。菜單通常用來顯示程序的各項(xiàng)功能,以方便用戶選擇執(zhí)行,通過對菜單命令進(jìn)行編程可以調(diào)用程序中相應(yīng)的功能。

?

6.1.1??菜單類CMenu

在MFC中,CMenu類封裝了Windows的菜單功能,它提供了多個(gè)方法用于創(chuàng)建、修改、合并菜單。CMenu類的主要方法如下。

(1)Attach方法:該方法用于將句柄關(guān)聯(lián)到菜單對象上。語法如下:

BOOL Attach( HMENU hMenu );

參數(shù)說明

?????hMenu:標(biāo)識菜單句柄。

返回值:為非零,表示執(zhí)行成功,否則執(zhí)行失敗。

(2)Detach方法:該方法從菜單對象上分離菜單句柄。語法如下:

HMENU Detach( );

返回值:分離的菜單句柄。

(3)FromHandle方法:該方法根據(jù)菜單句柄返回一個(gè)菜單對象指針,如果句柄沒有關(guān)聯(lián)的菜單對象,則一個(gè)臨時(shí)的菜單對象指針將要被創(chuàng)建。語法如下:

static CMenu* PASCAL FromHandle( HMENU hMenu );

參數(shù)說明

?????hMenu:標(biāo)識菜單句柄。

返回值:菜單對象指針。

(4)CreateMenu方法:該方法用于創(chuàng)建一個(gè)菜單窗口,并將其關(guān)聯(lián)到菜單對象上。語法如下:

?????BOOL CreateMenu( );

返回值:執(zhí)行成功,返回值為非零,否則為零。

(5)CreatePopupMenu方法:該方法用于創(chuàng)建一個(gè)彈出式菜單窗口,并將其關(guān)聯(lián)到菜單對象上。語法如下:

BOOL CreatePopupMenu( );

返回值:執(zhí)行成功,返回值為非零,否則為零。對于彈出式菜單,如果菜單窗口被釋放,菜單對象將要被自動釋放。

(6)LoadMenu方法:該方法從應(yīng)用程序的可執(zhí)行文件中加載一個(gè)菜單資源,將其關(guān)聯(lián)到菜單對象上。語法如下:

BOOL LoadMenu( LPCTSTR lpszResourceName );

BOOL LoadMenu( UINT nIDResource );

參數(shù)說明

?????lpszResourceName:標(biāo)識資源名稱。

?????nIDResource:標(biāo)識資源ID。

返回值:執(zhí)行成功,返回值為非零,否則為零。

(7)DestroyMenu方法:該方法用于釋放菜單窗口,當(dāng)菜單窗口被釋放前,它將從菜單對象上分離出來。語法如下:

BOOL DestroyMenu( );

???說明:當(dāng)菜單對象的析構(gòu)函數(shù)被調(diào)用時(shí),將自動調(diào)用DestroyMenu方法釋放菜單窗口。

(8)DeleteMenu方法:該方法用于從菜單中刪除一個(gè)菜單項(xiàng)。語法如下:

BOOL DeleteMenu( UINT nPosition, UINT nFlags );

參數(shù)說明

?????nPosition:標(biāo)識某一個(gè)菜單項(xiàng)。

?????nFlags:表示如何刪除菜單項(xiàng),可選值如下。

????????????MF_BYCOMMAND:根據(jù)nPosition標(biāo)識的菜單ID刪除菜單項(xiàng)。

????????????MF_BYPOSITION:根據(jù)nPosition標(biāo)識的菜單位置刪除菜單項(xiàng)。

(9)TrackPopupMenu方法:該方法用于顯示一個(gè)彈出式菜單。語法如下:

BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL );

參數(shù)說明

?????nFlags:表示屏幕位置標(biāo)記和鼠標(biāo)按鈕標(biāo)記??蛇x值如下。

????????????TPM_CENTERALIGN:在x水平位置居中顯示菜單。

????????????TPM_LEFTALIGN:在x水平位置左方顯示菜單。

????????????TPM_RIGHTALIGN:在x水平位置右方顯示菜單。

????????????TPM_LEFTBUTTON:單擊鼠標(biāo)左鍵顯示彈出式菜單。

????????????TPM_RIGHTBUTTON?:單擊鼠標(biāo)右鍵顯示彈出式菜單。

?????x:以屏幕坐標(biāo)標(biāo)識彈出式菜單的水平坐標(biāo)。

?????y:以屏幕坐標(biāo)標(biāo)識彈出式菜單的垂直坐標(biāo)。

?????pWnd:標(biāo)識彈出式菜單的所有者。

?????lpRect:以屏幕坐標(biāo)表示用戶在菜單中的單擊區(qū)域,如果為NULL,當(dāng)用戶單擊彈出式菜單之外的區(qū)域,將釋放菜單窗口。

(10)AppendMenu方法:該方法用于在菜單項(xiàng)的末尾添加一個(gè)新菜單。語法如下:

BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );

BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

參數(shù)說明

?????nFlags:標(biāo)識菜單項(xiàng)的狀態(tài)信息。

?????nIDNewItem:標(biāo)識菜單項(xiàng)的ID。

?????lpszNewItem:標(biāo)識菜單項(xiàng)的內(nèi)容。

?????pBmp:標(biāo)識關(guān)聯(lián)菜單項(xiàng)的位圖對象指針。

(11)CheckMenuItem方法:該方法用于在彈出的菜單項(xiàng)中放置或刪除標(biāo)記。語法如下:

UINT CheckMenuItem( UINT nIDCheckItem, UINT nCheck );

參數(shù)說明

?????nIDCheckItem:指定由nCheck確定的將要檢測的菜單項(xiàng)。

?????nCheck:指定如何檢測菜單項(xiàng),并如何決定菜單中子菜單的位置??蛇x值如下。

????????????MF_BYCOMMAND:指定參數(shù)給出已存在菜單項(xiàng)的命令I(lǐng)D號,為默認(rèn)值。

????????????MF_BYPOSITION:指定參數(shù)給出已存在菜單項(xiàng)的位置,第一項(xiàng)位置為0。

????????????MF_CHECKED:與MF_UNCHECKED一起用作開關(guān),在菜單項(xiàng)之前放置默認(rèn)的檢測標(biāo)記。

????????????MF_UNCHECKED:與MF_CHECKED一起用作開關(guān),刪除菜單項(xiàng)之前的檢測標(biāo)記。

(12)CheckMenuRadioItem方法:該方法用于將單選按鈕放置在菜單項(xiàng)之前,或從組中所有的其他菜單項(xiàng)中刪除單選按鈕。語法如下:

BOOL CheckMenuRadioItem( UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags );

參數(shù)說明

?????nIDFirst:指定單選按鈕組中的第一個(gè)菜單項(xiàng)的值。

?????nIDLast:指定單選按鈕組中的最后一個(gè)菜單項(xiàng)的值。

?????nIDItem:指定單選按鈕組中被選中的菜單項(xiàng)的值。

?????nFlags:對nIDFirst、nIDLast和nIDItem的解釋,可選值如下:

????????????MF_BYCOMMAND:指定參數(shù)給出已存在菜單項(xiàng)的命令I(lǐng)D號,若沒有設(shè)置MF_ BYCOMMAND和MF_BYPOSITION,該值為默認(rèn)值。

????????????MF_BYPOSITION:指定參數(shù)給出已存在菜單項(xiàng)的位置,第一項(xiàng)位置為0。

(13)EnableMenuItem方法:該方法用于設(shè)置菜單項(xiàng)有效、無效或變灰。語法如下:

UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable );

參數(shù)說明

?????nIDEnableItem:指定nEnable決定的將要有效的菜單項(xiàng),該參數(shù)既可以指定彈出式菜單,也可以指定標(biāo)準(zhǔn)菜單項(xiàng)。

?????nEnable:指定了將要進(jìn)行的動作,可選值如下。

????????????MF_BYCOMMAND:指定參數(shù)給出已存在的菜單項(xiàng)的命令I(lǐng)D號,此值為默認(rèn)值。

????????????MF_BYPOSITION:指定參數(shù)給出已存在菜單項(xiàng)的位置,第一項(xiàng)位置為0。

????????????MF_DISABLED:使菜單項(xiàng)無效,但不變灰。

????????????MF_ENABLED:使菜單項(xiàng)有效。

????????????MF_GRAYED:使菜單項(xiàng)變灰。

(14)GetMenuItemCount方法:該方法用于返回彈出式菜單或頂層菜單的菜單數(shù)。語法如下:

UINT GetMenuItemCount( ) const;

返回值:如果菜單項(xiàng)沒有子菜單,函數(shù)返回值為-1,否則返回子菜單數(shù)。

(15)GetMenuItemID方法:該方法根據(jù)菜單項(xiàng)的位置返回菜單ID,如果菜單項(xiàng)是一個(gè)彈出式菜單,返回值為-1;如果菜單項(xiàng)是一個(gè)分隔條,返回值為0。語法如下:

UINT GetMenuItemID( int nPos ) const;

參數(shù)說明

?????nPos:標(biāo)識菜單項(xiàng)的位置。

(16)GetMenuState方法:該方法用于返回指定菜單項(xiàng)的狀態(tài)或彈出菜單的項(xiàng)數(shù)。語法如下:

UINT GetMenuState( UINT nID, UINT nFlags ) const;

參數(shù)說明

?????nID:指定由nFlags決定的菜單項(xiàng)ID。

?????nFlags:指定nID的特性,值為MF_BYCOMMAND和MF_BYPOSITION之一。

(17)GetMenuString方法:該方法用于設(shè)置菜單項(xiàng)的文本。語法如下:

int GetMenuString( UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags ) const;

int GetMenuString( UINT nIDItem, CString& rString, UINT nFlags ) const;

參數(shù)說明

?????nIDItem:標(biāo)識菜單項(xiàng)位置或菜單項(xiàng)命令I(lǐng)D,具體含義依賴于nFlags參數(shù)。

?????lpString:標(biāo)識一個(gè)字符緩沖區(qū)。

?????nMaxCount:標(biāo)識向字符緩沖區(qū)中復(fù)制的最大字符數(shù)。

?????rString:標(biāo)識一個(gè)字符串。

?????nFlags:表示如何解釋nIDItem。如果為MF_BYCOMMAND,nIDItem標(biāo)識菜單項(xiàng)命令I(lǐng)D;如果為MF_BYPOSITION,nIDItem標(biāo)識菜單項(xiàng)位置。

返回值:實(shí)際復(fù)制到緩沖區(qū)中的字符數(shù)。

(18)GetSubMenu方法:該方法用于獲取彈出式菜單中的一個(gè)菜單項(xiàng)。語法如下:

CMenu* GetSubMenu( int nPos ) const;

參數(shù)說明

?????nPos:標(biāo)識菜單項(xiàng)位置,第一個(gè)菜單項(xiàng)對應(yīng)的位置是0,第二個(gè)菜單項(xiàng)對應(yīng)的位置是1,依次類推。

(19)InsertMenu方法:該方法用于向菜單中指定位置插入菜單項(xiàng)。語法如下:

BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem

= NULL );

BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

參數(shù)說明

?????nPosition:標(biāo)識某一個(gè)菜單項(xiàng)。

?????nFlags:表示如何解釋nPosition,可選值如下:

????????????MF_BYCOMMAND:根據(jù)nPosition標(biāo)識的菜單ID插入菜單項(xiàng)。

????????????MF_BYPOSITION:根據(jù)nPosition標(biāo)識的菜單位置插入菜單項(xiàng)。

?????nIDNewItem:標(biāo)識菜單項(xiàng)的ID。

?????lpszNewItem:標(biāo)識菜單項(xiàng)的內(nèi)容。

?????pBmp:標(biāo)識關(guān)聯(lián)菜單項(xiàng)的位圖對象指針。

(20)ModifyMenu方法:該方法用于修改菜單項(xiàng)信息。語法如下:

BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem

= NULL );

BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

參數(shù)說明

?????nPosition:標(biāo)識某一個(gè)菜單項(xiàng)。

?????nFlags:表示如何解釋nPosition,可選值如下。

????????????MF_BYCOMMAND:根據(jù)nPosition標(biāo)識的菜單ID修改菜單項(xiàng)。

????????????MF_BYPOSITION:根據(jù)nPosition標(biāo)識的菜單位置修改菜單項(xiàng)。

?????nIDNewItem:標(biāo)識菜單項(xiàng)的ID。

?????lpszNewItem:標(biāo)識菜單項(xiàng)的內(nèi)容。

?????pBmp:標(biāo)識關(guān)聯(lián)菜單項(xiàng)的位圖對象指針。

(21)RemoveMenu方法:該方法用于移除一個(gè)菜單項(xiàng)。語法如下:

BOOL RemoveMenu( UINT nPosition, UINT nFlags );

參數(shù)說明

?????nPosition:標(biāo)識某一個(gè)菜單項(xiàng)。

?????nFlags:表示如何刪除菜單項(xiàng),可選值如下:

????????????MF_BYCOMMAND:根據(jù)nPosition標(biāo)識的菜單ID刪除菜單項(xiàng)。

????????????MF_BYPOSITION:根據(jù)nPosition標(biāo)識的菜單位置刪除菜單項(xiàng)。

(22)DrawItem方法:該方法是一個(gè)虛方法,用戶可以改寫該方法實(shí)現(xiàn)菜單的繪制。語法如下:

virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );

參數(shù)說明

?????lpDrawItemStruct:是一個(gè)DRAWITEMSTRUCT結(jié)構(gòu)指針,該結(jié)構(gòu)包含了菜單項(xiàng)的ID、類型、畫布、句柄等詳細(xì)信息。

?

6.1.2??菜單資源設(shè)計(jì)

下面來介紹如何設(shè)計(jì)菜單資源,步驟如下。

(1)在工作區(qū)窗口中選擇資源視圖(ResourceView),鼠標(biāo)右鍵單擊一個(gè)節(jié)點(diǎn),在彈出的快捷菜單中選擇“Insert”菜單項(xiàng),將打開“Insert Resource”對話框,如圖6.1所示。

?

圖6.1 “Insert Resource”對話框

(2)在資源類型列表中選擇“Menu”節(jié)點(diǎn),單擊“New”按鈕,將創(chuàng)建一個(gè)菜單,如圖6.2所示。

?

圖6.2??菜單設(shè)計(jì)窗口

(3)在菜單設(shè)計(jì)窗口中按<Enter>鍵打開“Menu Item Properties”窗口,在“Caption”編輯框中設(shè)計(jì)菜單標(biāo)題,如圖6.3所示。

?

圖6.3 “Menu Item Properties”窗口

(4)關(guān)閉“Menu Item Properties”窗口,返回到菜單設(shè)計(jì)窗口中,如圖6.4所示。

?

圖6.4??菜單設(shè)計(jì)窗口

(5)在新建菜單下的虛線框上按<Enter>鍵打開“Menu Item Properties”窗口可以添加子菜單,在“Menu Item Properties”窗口中設(shè)置子菜單ID和菜單的標(biāo)題,如圖6.5所示。

?

圖6.5??“Menu Item Properties”窗口

如果用戶不設(shè)置菜單ID,系統(tǒng)將會自動生成一個(gè)ID。

(6)關(guān)閉菜單屬性窗口,返回到菜單設(shè)計(jì)窗口中,如圖6.6所示。

???說明:如果要插入一個(gè)分隔線,可以選擇Separator屬性,并且菜單資源設(shè)計(jì)窗口支持鼠標(biāo)拖曳功能,可以在選中菜單項(xiàng)后將其拖曳至適當(dāng)位置,從而調(diào)整各個(gè)菜單的位置。

(7)如果想要設(shè)計(jì)一個(gè)級聯(lián)菜單,可以在菜單項(xiàng)的屬性窗口中選中Pop-up復(fù)選框,這樣,在菜單項(xiàng)的右側(cè)將顯示一個(gè)箭頭,效果如圖6.7所示。

?????????????????????

??????????????????圖6.6??菜單設(shè)計(jì)窗口??????????????????????????????圖6.7??菜單設(shè)計(jì)窗口

???說明:如果為菜單項(xiàng)選中Pop-up屬性,則該菜單項(xiàng)的ID將不能編輯。

(8)打開級聯(lián)子菜單的屬性窗口,設(shè)置菜單ID和菜單標(biāo)題。重復(fù)以上的步驟就可以設(shè)置需要的菜單。

???說明:在設(shè)計(jì)菜單項(xiàng)信息時(shí),可以為菜單項(xiàng)設(shè)置加速鍵來簡化用戶操作。在菜單標(biāo)題的后面加“&+字母”即可實(shí)現(xiàn)加速鍵的設(shè)置,程序運(yùn)行時(shí),用戶按下〈Alt〉鍵加上該字母鍵,便可激活并操作該菜單。如果設(shè)置加速鍵的菜單項(xiàng)是子菜單,還需要為該菜單的上級菜單設(shè)置加速鍵,否則上級菜單沒有加速鍵就不能運(yùn)行子菜單的加速鍵。

?

6.1.3??菜單的顯示與命令處理

在編輯了菜單資源之后運(yùn)行程序并不能顯示菜單,要顯示菜單,還需要將菜單和對話框資源進(jìn)行關(guān)聯(lián),打開“Dialog Properties”窗口,在“General”選項(xiàng)卡的“Menu”列表框中選擇要進(jìn)行關(guān)聯(lián)的菜單ID,如圖6.8所示。

?

圖6.8??“Dialog Properties”窗口

現(xiàn)在運(yùn)行程序就包含菜單了。但是想要用菜單進(jìn)行對程序的操作還需要設(shè)置菜單的命令處理。打開類向?qū)?#xff0c;選擇“Message Maps”選項(xiàng)卡,在“Class name”列表框選擇關(guān)聯(lián)菜單的對話框類,在“Object Ids”列表中選擇菜單項(xiàng)ID,在“Messages”列表中選擇“COMMAND”項(xiàng),如圖6.9所示。

?

圖6.9??類向?qū)?/p>

單擊“Add Function…”按鈕,彈出“Add Member Function”對話框,并給出默認(rèn)時(shí)的命令處理函數(shù)名,如圖6.10所示。

?

圖6.10 “Add Member Function”對話框

單擊“OK”按鈕,就添加了菜單項(xiàng)的命令處理函數(shù)。再單擊“Edit Code”按鈕可以打開添加的OnMenumessage命令處理函數(shù),在這里可以編輯菜單項(xiàng)的功能,代碼如下:

void CMenuDlg::OnMenumessage()

{

????MessageBox("菜單消息處理函數(shù)");

????return;

}

?

6.1.4??動態(tài)創(chuàng)建菜單

在前面已經(jīng)介紹了如何編輯菜單資源以及通過類向?qū)Ь帉懖藛蔚拿钐幚砗瘮?shù)。本節(jié)將通過CMenu類實(shí)現(xiàn)動態(tài)創(chuàng)建菜單。

(1)創(chuàng)建一個(gè)基于對話框的應(yīng)用程序。

(2)向?qū)υ捒蛑刑砑右粋€(gè)按鈕控件。

(3)在主窗口的頭文件中聲明一個(gè)CMenu類對象,代碼如下:

CMenu m_Menu;

(4)在資源頭文件(Resource.h)中定義命令I(lǐng)D,如圖6.11所示。

?

圖6.11??Resource.h文件

(5)在主窗口的頭文件中添加消息處理函數(shù),如圖6.12所示。

?

圖6.12??DynamicMenuDlg.h文件

(6)在主窗口的源文件中添加消息映射宏,將命令I(lǐng)D關(guān)聯(lián)到消息處理函數(shù)中,如圖6.13所示。

(7)在主窗口的源文件中添加消息處理函數(shù)的實(shí)現(xiàn)代碼,代碼如下:

?

圖6.13??DynamicMenuDlg.cpp文件

void CDynamicMenuDlg::OnMenured()

{

???MessageBox("打開菜單被按下");

}

void CDynamicMenuDlg::OnMenublue()

{

???MessageBox("保存菜單被按下");

}

void CDynamicMenuDlg::OnMenugreen()

{

????MessageBox("另存為菜單被按下");

}

MessageBox函數(shù)用來彈出一個(gè)消息框,該函數(shù)有3個(gè)參數(shù),第一個(gè)參數(shù)表示消息框顯示的文本,第二個(gè)參數(shù)表示消息框的標(biāo)題,默認(rèn)為可執(zhí)行文件名,第3個(gè)參數(shù)表示消息框顯示的按鈕風(fēng)格和圖標(biāo)風(fēng)格的組合。

(8)處理“創(chuàng)建”按鈕的消息響應(yīng)事件,用代碼創(chuàng)建菜單,代碼如下:

void CDynamicMenuDlg::OnButton1()

{

???m_Menu.CreateMenu();

???CMenu popmenu;

???popmenu.CreatePopupMenu();

???m_Menu.AppendMenu(MF_POPUP,(UINT)popmenu.m_hMenu,"系統(tǒng)");

???popmenu.AppendMenu(MF_STRING,ID_MENURED,"打開");

???popmenu.AppendMenu(MF_STRING,ID_MENUBLUE,"保存");

???popmenu.AppendMenu(MF_STRING,ID_MENUGREEN,"另存為");

???popmenu.Detach();

???SetMenu(&m_Menu);

}

SetMenu函數(shù)用于分配一個(gè)菜單到指定窗口。

程序運(yùn)行結(jié)果如圖6.14所示。

?

圖6.14??動態(tài)創(chuàng)建菜單

6.1.5??菜單項(xiàng)的更新機(jī)制

在使用類向?qū)椴藛翁砑用钐幚砗瘮?shù)時(shí),發(fā)現(xiàn)菜單除了COMMAND消息外,還有一個(gè)UPDATE_COMMAND_UI消息,該消息是“更新命令用戶接口消息”。菜單項(xiàng)的狀態(tài)維護(hù)就依賴于UPDATE_COMMAND_UI消息。下面就來看看如何使用這個(gè)消息。

打開一個(gè)基于單文檔的應(yīng)用程序,運(yùn)行程序后發(fā)現(xiàn)“編輯”菜單下的菜單項(xiàng)都不可用,如圖6.15所示。

如果想要使“編輯”菜單下的菜單項(xiàng)都可用,就要為相應(yīng)的菜單項(xiàng)處理UPDATE_ COMMAND_UI消息。以“撤銷”菜單項(xiàng)為例,打開類向?qū)?#xff0c;選擇“Message Maps”選項(xiàng)卡,在“Class name”列表框中選擇“CmainFrame”類,在“Object Ids”列表中選擇“撤銷”菜單項(xiàng)“ID_EDIT_UNDO”,在“Messages”列表中選擇“UPDATE_COMMAND_UI”項(xiàng),單擊“Add Function…”按鈕,創(chuàng)建該消息的處理函數(shù),如圖6.16所示。

?

圖6.16??類向?qū)?/p>

單擊“Edit Code”按鈕,定位到新建的消息處理函數(shù),在函數(shù)中添加代碼使“撤銷”菜單項(xiàng)可用,代碼如下:

void CMainFrame::OnUpdateEditUndo(CCmdUI* pCmdUI)

{

???pCmdUI->Enable(); //使菜單項(xiàng)可用

}

???說明:參數(shù)pCmdUI可以設(shè)置菜單項(xiàng)是否可用、是否具有標(biāo)記和改變菜單項(xiàng)標(biāo)題。

程序運(yùn)行結(jié)果如圖6.17所示。

?

圖6.17??菜單項(xiàng)的更新機(jī)制

通過上面的運(yùn)行結(jié)果發(fā)現(xiàn)“撤銷”菜單項(xiàng)已經(jīng)可用,這是因?yàn)镸FC菜單項(xiàng)的命令更新機(jī)制,當(dāng)要顯示菜單時(shí),系統(tǒng)發(fā)出WM_INITMENUPOPUP消息,該消息被程序窗口的基類接管后會創(chuàng)建一個(gè)CCmdUI對象,CCmdUI對象會與程序的第一個(gè)菜單項(xiàng)相關(guān)聯(lián),并調(diào)用CCmdUI對象的DoUpdate方法發(fā)送UPDATE_COMMAND_UI消息,系統(tǒng)會查找是否有捕獲這個(gè)消息的宏,如果找到就調(diào)用相應(yīng)的函數(shù)進(jìn)行處理。當(dāng)這個(gè)菜單項(xiàng)更新后,CCmdUI對象會繼續(xù)對下一個(gè)菜單項(xiàng)進(jìn)行關(guān)聯(lián),直到完成所有菜單項(xiàng)的處理。

6.1.6??自繪彈出式菜單

在Windows操作系統(tǒng)中單擊鼠標(biāo)右鍵彈出的菜單稱為彈出式菜單。彈出式菜單可以方便用戶的操作,下面來介紹一下如何創(chuàng)建彈出式菜單。

(1)創(chuàng)建一個(gè)基于對話框的程序。

(2)向工程中導(dǎo)入兩個(gè)位圖,將資源ID改為IDB_LEFTBITMAP和IDB_ITEMBITMAP。

(3)以CMenu類為基類派生一個(gè)CCustomMenu類,定義一個(gè)記錄菜單項(xiàng)信息的數(shù)據(jù)結(jié)構(gòu)CMenuItemInfo,代碼如下:

struct CMenuItemInfo

{

???CString m_ItemText;??//菜單項(xiàng)文本

???int?????m_ItemIndex; //菜單項(xiàng)索引

???int?????m_ItemID;?????//菜單標(biāo)記0分隔條,其他普通菜單

};

(4)在CCustomMenu類的頭文件中聲明如下變量:

CMenuItemInfo m_ItemLists[10]; //菜單項(xiàng)信息

int????????????????????m_ImageIndex;??//圖像索引

CFont?????????????????m_TitleFont;???//標(biāo)題字體

(5)在CCustomMenu類中添加DrawMenuTitle方法,用于繪制菜單左側(cè)標(biāo)題,代碼如下:

void CCustomMenu::DrawMenuTitle(CDC *pDC, CRect rect, CString title)

{

???CBitmap m_bitmap;

???m_bitmap.LoadBitmap(IDB_LEFTBITMAP);

???BITMAP m_size;

???m_bitmap.GetBitmap(&m_size);

???CDC m_memdc;

???m_memdc.CreateCompatibleDC(pDC);

???CGdiObject* m_oldobject;

???m_oldobject = m_memdc.SelectObject(&m_bitmap);

???pDC->StretchBlt(0,0,28,rect.bottom,&m_memdc,0,0,m_size.bmWidth,m_size.bmHeight,SRCCOPY);

???m_bitmap.DeleteObject();

???CFont* m_oldfont = pDC->SelectObject(&m_TitleFont);

???pDC->TextOut(rect.left+5,rect.Height()+130,title);

???pDC->SelectObject(m_oldfont);

}

通過LoadBitmap方法裝載位圖IDB_LEFTBITMAP,再使用StretchBlt方法將位圖繪制成標(biāo)題大小。

(6)在CCustomMenu類中添加DrawItemText方法,用于繪制菜單項(xiàng)文本,代碼如下:

void CCustomMenu::DrawItemText(CDC *pDC, LPSTR str, CRect rect)

{

???rect.DeflateRect(40,0,0,0);

???pDC->DrawText(str,rect,DT_SINGLELINE|DT_VCENTER|DT_LEFT);

}

(7)在CCustomMenu類中添加DrawSeparater方法,用于繪制分隔條,代碼如下:

void CCustomMenu::DrawSeparater(CDC *pDC, CRect rect)

{

???if(pDC != NULL)

???{

??????rect.DeflateRect(29,0,0,0);

??????pDC->Draw3dRect(rect,RGB(0,0,255),RGB(0,0,255));

???}

}

(8)在CCustomMenu類中添加ChangeMenuItem方法,用于修改菜單項(xiàng)信息,代碼如下:

BOOL CCustomMenu::ChangeMenuItem(CMenu *menu)

{

????int m_index=0;

????if(menu != NULL)

????{

???????int m_itemcount = menu->GetMenuItemCount(); //獲得菜單項(xiàng)個(gè)數(shù)

???????for(int i=0;i<m_itemcount;i++)

???????{

????????????//獲得菜單項(xiàng)文本

????????????menu->GetMenuString(i,m_ItemLists[m_index].m_ItemText,MF_BYPOSITION);

????????????int m_itemID = menu->GetMenuItemID(i); //獲得菜單項(xiàng)ID

????????????m_ItemLists[m_index].m_ItemID = m_itemID;

????????????if(m_itemID>0)

????????????{

????????????????m_ItemLists[m_index].m_ItemIndex= m_ImageIndex;

????????????????m_ImageIndex++;

????????????}

????????????//修改菜單項(xiàng)信息

????????????menu->ModifyMenu(i,MF_OWNERDRAW | MF_BYPOSITION | MF_STRING,

????????????????m_ItemLists[m_index].m_ItemID,(LPSTR)&(m_ItemLists[m_index]));

????????????m_index++;

????????????CMenu* m_subMenu = menu->GetSubMenu(i);

????????????if(m_subMenu)

????????????{

????????????????ChangeMenuItem(m_subMenu);

????????????}

????????}

????}

????return TRUE;

}

(9)改寫CMenu類的MeasureItem方法,設(shè)置菜單項(xiàng)大小,代碼如下:

void CCustomMenu::MeasureItem(LPMEASUREITEMSTRUCT lpStruct)

{

????if(lpStruct->CtlType=?=ODT_MENU)

????{

???????lpStruct->itemHeight = 22; //設(shè)置菜單項(xiàng)的高

???????lpStruct->itemWidth = 100; //設(shè)置菜單項(xiàng)的寬

???????CMenuItemInfo* m_iteminfo;

???????m_iteminfo = (CMenuItemInfo*)lpStruct->itemData;

???????if(m_iteminfo->m_ItemID =?= 0)

???????{

?????????????lpStruct->itemHeight = 1; //設(shè)置分隔條

???????}

????}

}

(10)改寫CMenu類的DrawItem方法,重繪菜單項(xiàng),代碼如下:

void CCustomMenu::DrawItem(LPDRAWITEMSTRUCT lpStruct)

{

????if(lpStruct->CtlType=?=ODT_MENU)

????{

???????if(lpStruct->itemData =?= NULL)????return;

???????unsigned int m_state = lpStruct->itemState; //獲得菜單項(xiàng)狀態(tài)

???????CDC* pDC = CDC::FromHandle(lpStruct->hDC);

???????CString str = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemText;

???????LPSTR m_str = str.GetBuffer(str.GetLength());

???????int m_itemID = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemID;?????

???????int m_itemicon = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemIndex;

???????CRect m_rect = lpStruct->rcItem;??????

???????pDC->SetBkMode(TRANSPARENT); //設(shè)置菜單項(xiàng)文本背景透明????????

???????switch(m_itemID)

???????{

???????case 0:?????//繪制分隔條

?????????????????DrawSeparater(pDC,m_rect);

?????????????????break;

????????default:???//繪制菜單項(xiàng)和左側(cè)標(biāo)題

?????????????????DrawComMenu(pDC,m_rect,m_state&ODS_SELECTED);

?????????????????DrawItemText(pDC,m_str,m_rect);

?????????????????DrawMenuTitle(pDC,m_rect,"明日科技有限公司");?????????????

?????????????????break;

????????}

????}

}

(11)在主窗口的頭文件中聲明一個(gè)CCustomMenu類對象m_Menu,在主窗口的OnInit Dialog函數(shù)中添加如下代碼,裝載菜單資源。

m_Menu.LoadMenu(IDR_MENU1); //裝載菜單資源

m_Menu.ChangeMenuItem(&m_Menu);

(12)處理主窗口的WM_CONTEXTMENU消息,彈出菜單,代碼如下:

void CPopMenuDlg::OnContextMenu(CWnd* pWnd, CPoint point)

{

???CMenu* m_tempmenu = m_Menu.GetSubMenu(0);

???m_tempmenu->TrackPopupMenu(TPM_LEFTBUTTON|TPM_LEFTALIGN,point.x,point.y,this);

}

當(dāng)鼠標(biāo)右鍵單擊程序窗口的客戶區(qū)時(shí),程序會收到一條WM_CONTEXTMENU消息,在該消息的處理函數(shù)中使用TrackPopupMenu方法彈出菜單。

(13)在主窗口中添加消息WM_DRAWITEM和WM_MEASUREITEM,并分別在這兩個(gè)消息的處理函數(shù)中調(diào)用m_Menu對象的DrawItem方法和MeasureItem方法。

菜單欄

在對話框窗口里顯示菜單欄

像工具欄一樣,菜單欄在按件面板里沒有對應(yīng)的選項(xiàng),但有一個(gè)菜單控件類CMenu,所以如果想要在對話框里顯示菜單欄,就得像工具欄那樣,到ResourceView選項(xiàng)卡里新建一個(gè)菜單欄資源,步驟跟新建工具欄資源一樣,只是資源類型是:Menu,菜單資源設(shè)計(jì)如下圖:

如果想改菜單項(xiàng)文本內(nèi)容的話,方法是右擊要更改的菜單項(xiàng),選擇屬性,接著會彈出這樣一個(gè)對話框:


上面那個(gè)ID項(xiàng)就是該菜單項(xiàng)對應(yīng)的ID號了,添加菜單項(xiàng)單擊消息處理函數(shù)時(shí)會用到,而標(biāo)明項(xiàng)里的內(nèi)容就是菜單項(xiàng)要顯示的文本了。

這里還得注意一下“彈出”這個(gè)選項(xiàng),勾上這個(gè)選項(xiàng)表明對應(yīng)的菜單項(xiàng)還有下級菜單,如:


上面“轉(zhuǎn)到”這個(gè)菜單項(xiàng)具有彈出屬性,有下級菜單

設(shè)計(jì)好了菜單資源,接著我們就來在對話框顯示菜單欄吧,方法是進(jìn)入對話框編輯區(qū),右擊對話框界面,選擇屬性,然后在菜單項(xiàng)里選擇菜單資源ID號,回車,編譯,運(yùn)行,效果如下圖:

當(dāng)然還有第二種在對話框顯示菜單的方法:調(diào)用SetMenu函數(shù)把菜單跟對話框關(guān)聯(lián)起來,函數(shù)第一個(gè)參數(shù)是窗口句柄,第二個(gè)參數(shù)是菜單句柄。在OnInitDialog函數(shù)里添加如下語句:
?CMenu menu;//定義一個(gè)菜單類變量
?menu.LoadMenu(IDR_MENU1);//裝載IDR_MENU1菜單資源
?SetMenu(&menu);//和當(dāng)前窗口關(guān)聯(lián)起來
?menu.Detach();//分離

如果要處理菜單項(xiàng)單擊消息的話,方法跟處理工具欄項(xiàng)單擊消息一樣,進(jìn)入類向?qū)?#xff0c;找到對應(yīng)的菜單項(xiàng)ID,為它添加COMMAND消息處理函數(shù)。
?設(shè)置菜單左邊顯示位圖和背景位圖

CMenu類里要了解的函數(shù)

SetMenuItemBitmaps//設(shè)置菜單項(xiàng)左邊的位圖

函數(shù)定義:BOOL SetMenuItemBitmaps( UINT nPosition, UINT nFlags, const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked );
nPostion指明具體要設(shè)置的菜單項(xiàng),可以是菜單項(xiàng)索引,菜單項(xiàng)ID,具體由nFlags參數(shù)指明,為MF_BYPOSITION,則以菜單項(xiàng)索引指明,

為MF_BYCOMMAND則第一個(gè)參數(shù)nPosition是菜單項(xiàng)ID號。pBmpUnchecked未被檢測時(shí)顯示的位圖(正常時(shí)),pBmpChecked檢測時(shí)顯示的圖片(就是菜單項(xiàng)被打上勾時(shí)所顯示的圖片,跟CheckMenuItem函數(shù)有關(guān)聯(lián))

一個(gè)API函數(shù)SetMenuInfo,這個(gè)函數(shù)可以設(shè)置菜單重繪時(shí)選擇的填充畫刷類型,該函數(shù)有兩個(gè)參數(shù),第一個(gè)是要設(shè)置的菜單句柄,第二個(gè)是一個(gè)MENUINFO結(jié)構(gòu)指針,我們只要了解這結(jié)構(gòu)里有一個(gè)成員hbrBack就行了,hbrBack是一個(gè)畫刷句柄,而菜單背景位圖就通過創(chuàng)建位圖畫刷來實(shí)現(xiàn)的。

好了,以上面的工程為例,引入三張位圖,ID號默認(rèn)不變,然后再引入一張位圖(菜單背景位圖,ID:IDB_MENUBACK),接著在對話框類的OnInitDialog函數(shù)里添加如下語句:

CMenu *pMenu=GetMenu();//獲取對話框關(guān)聯(lián)菜單
?CMenu *pSubMenu=pMenu->GetSubMenu(0);//獲得子菜單(如果有)0表示索引,對應(yīng)“文件”菜單
?for(int i=0;i<3;i++)
?{
???? CBitmap bmp;
???? bmp.LoadBitmap(IDB_BITMAP1+i);
? pSubMenu->SetMenuItemBitmaps(i,MF_BYPOSITION,&bmp,&bmp);
??bmp.Detach();
?}
?CBitmap bmp;
?CBrush m_BKBrush;
?bmp.LoadBitmap(IDB_MENUBACK);
?m_BKBrush.CreatePatternBrush(&bmp);//創(chuàng)建位圖畫刷
?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();

運(yùn)行效果如下圖:


(PS:不知道大家有沒有碰到過這個(gè)問題,MENUINFO結(jié)構(gòu)未定義,解決的方法是進(jìn)入文件選項(xiàng)卡(FileView),在Source? File文件下的StdAfx.cpp文件里的最前面部分添加這個(gè)語句:#define? WINVER 0x0501)

設(shè)計(jì)彈出式菜單

?CMenu類里要了解的函數(shù):

TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd,LPCRECT lpRect = NULL );
該函數(shù)用于在界面顯示菜單,nFlags參數(shù)指明菜單顯示標(biāo)志,x,y用于確定菜單顯示基于的坐標(biāo)點(diǎn),pWnd是菜單相關(guān)聯(lián)的窗口。

在“MFC類庫詳解”中有關(guān)參數(shù)nFlags的解釋如下:

?指定屏幕位置標(biāo)志或鼠標(biāo)鍵標(biāo)志。
屏幕位置標(biāo)志可以為下列值之一:
·TPM_CENTERALIGN使彈出菜單在水平方向相對于x指定的坐標(biāo)居中。
·TPM_LEFTALIGN放置彈出菜單,以便彈出菜單在由坐標(biāo)值x指定的位置左對齊。
·TPM_RIGHTALIGN放置彈出菜單,以便彈出菜單在由坐標(biāo)值x指定的位置右對齊。

鼠標(biāo)鍵標(biāo)志可以為下列值之一:
·TPM_LEFTBUTTON導(dǎo)致彈出菜單追蹤鼠標(biāo)左鍵。
·TPM_RIGHTBUTTON導(dǎo)致彈出菜單追蹤鼠標(biāo)右鍵。

以上面工程為例,給對話框添加鼠標(biāo)右鍵抬起(WM_RBUTTONUP)消息處理函數(shù),在函數(shù)里添加如下代碼:
void CSeventhDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
?// TODO: Add your message handler code here and/or call default
?CMenu *Menu=GetMenu();
?ClientToScreen(&point);//將窗口坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo)
?Menu->GetSubMenu(0)->TrackPopupMenu(
??TPM_LEFTBUTTON|TPM_VERTICAL,point.x,point.y,this);
?Menu->Detach();
?CDialog::OnRButtonUp(nFlags, point);
}
要注意的是,要在界面顯示的菜單,必須是一個(gè)彈出菜單,雖然Menu->TrackPopupMenu也可以顯示,但顯然不是想要的結(jié)果。

運(yùn)行效果:


動態(tài)(純代碼)創(chuàng)建一個(gè)菜單
上面的例子,都是使用了菜單資源創(chuàng)建的菜單,這一次我們用代碼來創(chuàng)建菜單,其實(shí)本質(zhì)跟前面的用控件類的Create函數(shù)創(chuàng)建一個(gè)控件一樣。只不過這里的“Create”函數(shù)是CreateMenu和CreatePopupMenu函數(shù)。

CMenu類里要了解的函數(shù):

CreateMenu //創(chuàng)建一個(gè)主菜單,函數(shù)沒有參數(shù)

CreatePopupMenu//創(chuàng)建一個(gè)具有彈出屬性的菜單,函數(shù)沒有參數(shù)

AppendMenu//往一個(gè)菜單里添加菜單項(xiàng),或彈出式菜單

AppendMenu函數(shù)定義如下:

BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );
nFlags參數(shù)常用取值如下:

?MF_STRING 表明添加的是一個(gè)不具有彈出屬性的菜單項(xiàng)。

MF_POPUP 添加的一個(gè)彈出菜單項(xiàng)

MF_SEPARATOR 添加的是一個(gè)菜單分隔條

MF_OWNERDRAW? 表明對應(yīng)菜單具有自繪屬性

nIDNewItem參數(shù),如果添加的是一個(gè)不具有彈出屬性的菜單項(xiàng),那么該值就是菜單項(xiàng)ID號,否則是彈出式菜單句柄,lpszNewItem是菜單項(xiàng)名稱(菜單文本內(nèi)容)

好了,接著我們來動態(tài)創(chuàng)建一個(gè)菜單,首先往對話框里添加一個(gè)按鈕控件,當(dāng)單擊這個(gè)按鈕時(shí),就創(chuàng)建菜單,響應(yīng)這個(gè)按鈕控件的單擊消息,消息處理函數(shù)里添加如下代碼:

CMenu Menu;
? Menu.CreateMenu();//創(chuàng)建一個(gè)主菜單
? CMenu popMenu;
? popMenu.CreatePopupMenu();//創(chuàng)建一個(gè)彈出式菜單
? popMenu.AppendMenu(MF_STRING,1001,"新建");//添加菜單項(xiàng)
? popMenu.AppendMenu(MF_STRING,1002,"打開");
? popMenu.AppendMenu(MF_STRING,1003,"保存");
? Menu.AppendMenu(MF_POPUP,(UINT)popMenu.m_hMenu,"文件");//添加彈出菜單項(xiàng)
? SetMenu(&Menu);//關(guān)聯(lián)到窗口中
? Menu.Detach();
? popMenu.Detach();

更改菜單項(xiàng)大小(寬高),設(shè)置菜單文本字體大小

由于CMenu類里并沒有提供設(shè)置菜單項(xiàng)大小以及字體大小的函數(shù),所以我們?nèi)绻獙?shí)現(xiàn)上述功能的話,只能采取自繪的方法。

如果對CMenu類的某些函數(shù)不了解的話,可以參考"MFC 類大全",這里就不講述了

首先從CMenu派生出一個(gè)子類CNewMenu(類的類型為Generic Class),然后往這個(gè)類添加三個(gè)成員函數(shù),MeasureItem(設(shè)置菜單寬高),

DrawItem(自繪菜單),ChangeMenuItem(修改菜單項(xiàng)類型)

三個(gè)函數(shù)分別定義如下:

void CNewMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)

void CNewMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

void CNewMenu::ChangeMenuItem(CMenu *pMenu)

其中MeasureItem和DrawItem是CMenu類的虛函數(shù)。

各函數(shù)的代碼如下:

void CNewMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
?lpMeasureItemStruct->itemHeight=25;//項(xiàng)高
?lpMeasureItemStruct->itemWidth=120;//項(xiàng)寬
}

void CNewMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
?CRect rect=lpDrawItemStruct->rcItem;
?CDC dc;
?dc.Attach(lpDrawItemStruct->hDC);
?dc.FillSolidRect(rect,RGB(0,166,170));
?CFont Font;
?Font.CreatePointFont(125,"宋體");//創(chuàng)建字體
?dc.SelectObject(&Font);
?CString *pText=(CString *)lpDrawItemStruct->itemData;
?if(lpDrawItemStruct->itemState&ODS_SELECTED)
?? dc.FillSolidRect(rect,RGB(80,89,202));//菜單被選中
?dc.SetTextColor(RGB(10,0,181));//設(shè)置文本顏色
?dc.DrawText(*pText,rect,DT_VCENTER|DT_LEFT|DT_SINGLELINE);
?dc.Detach();

}

void CNewMenu::ChangeMenuItem(CMenu *pMenu)
{
int itemCount=pMenu->GetMenuItemCount();
for(int i=0;i<itemCount;i++)
{
??? CString *pText=new CString;
?UINT itemID=pMenu->GetMenuItemID(i);//獲取菜單項(xiàng)ID號
?pMenu->GetMenuString(i,*pText,MF_BYPOSITION);//獲取菜單文本

//ModifyMenu函數(shù)最后一個(gè)參數(shù)對應(yīng)DRAWITEMSTRUCT結(jié)構(gòu)里的itemData變量
?pMenu->ModifyMenu(i,MF_OWNERDRAW|MF_BYPOSITION|MF_STRING,itemID,(LPSTR)pText);
? if(itemID==-1)//如果是一個(gè)彈出式菜單
?{
??ChangeMenuItem(pMenu->GetSubMenu(i));
?}
}??
}
必須讓每個(gè)菜單項(xiàng)具有MF_OWNERDRAW屬性,不然接不到WM_MEASUREITEM和WM_DRAWITEM消息,而且菜單項(xiàng)不具有MF_OWNERDRAW屬性, 即使接到消息,也無法自繪,所以上面的ChangeMenuItem函數(shù)就是用于修改菜單項(xiàng)屬性
WM_MEASUREITEM和WM_DRAWITEM消息不是直接發(fā)給菜單窗口的,會被父窗口給收到,所以得處理父窗口的WM_MEASUREITEM和WM_DRAWITEM消息,給話框類添加這兩個(gè)消息處理函數(shù),兩個(gè)函數(shù)里的代碼分別如下:

void CFirstDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
?// TODO: Add your message handler code here and/or call default
???? if(lpMeasureItemStruct->CtlType==ODT_MENU)//如果類型是菜單
?????? newMenu.MeasureItem(lpMeasureItemStruct);//調(diào)用CNewMenu類的MeasureItem成員函數(shù)
?????? else
??? CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
??
}

void CFirstDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
?// TODO: Add your message handler code here and/or call default
?if(lpDrawItemStruct->CtlType==ODT_MENU)
? newMenu.DrawItem(lpDrawItemStruct);
?else
?CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

接著我們在對話類添加一個(gè)成員變量:

CNewMenu newMenu; (記得要包含頭文件:"NewMenu.h"),然后在對話框類的OnInitDialog函數(shù)添加如下代碼:

?newMenu.LoadMenu(IDR_MENU1);
?SetMenu(&newMenu);
?//只更改下主菜單下的第一項(xiàng),更改全部:newMenu.ChangeMenuItem(&newMenu);
?newMenu.ChangeMenuItem(newMenu.GetSubMenu(0));

IDR_MENU1是菜單資源的ID號,可自行創(chuàng)建。好了,到了這里大功已經(jīng)告成了,點(diǎn)編譯運(yùn)行,效果如下:


跟自繪按鈕控件一樣,上面依然沒處理菜單的所有狀態(tài),如獲得焦點(diǎn),被核記,有無關(guān)聯(lián)圖片。也不處理菜單分隔條。。
如果想處理這些狀態(tài)的話。建議查看DRAWITEMSTRUCT結(jié)構(gòu)的itemState變量,這個(gè)成員指明菜單項(xiàng)的狀態(tài),
關(guān)聯(lián)圖片,就查看CMenu類的函數(shù)。。。

(菜單項(xiàng)數(shù)據(jù)(itemData)對應(yīng)的分配內(nèi)存,就自己釋放吧)


http://www.risenshineclean.com/news/11562.html

相關(guān)文章:

  • 機(jī)械類外貿(mào)網(wǎng)站建設(shè)站長之家工具
  • 社交網(wǎng)站上的商城怎么做淘寶店鋪如何推廣
  • eclipse 網(wǎng)站開發(fā)教程臺州關(guān)鍵詞優(yōu)化平臺
  • 網(wǎng)站頁面一般以多大標(biāo)準(zhǔn)做合適百度站長收錄提交入口
  • 海宏集團(tuán)網(wǎng)站建設(shè)朋友圈網(wǎng)絡(luò)營銷
  • 中國航發(fā)網(wǎng)上商城客服電話快手seo
  • WordPress批量掃描谷歌seo代運(yùn)營
  • 重慶網(wǎng)站推百度網(wǎng)盤seo優(yōu)化
  • 小程序免費(fèi)制作網(wǎng)站2021年10月新聞?wù)?/a>
  • 風(fēng)鈴做的網(wǎng)站能否推廣seo搜索引擎優(yōu)化的內(nèi)容
  • 中山做網(wǎng)站哪個(gè)公司好如何優(yōu)化搜索引擎
  • 用vs做網(wǎng)站的登錄百度關(guān)鍵詞搜索量統(tǒng)計(jì)
  • 做網(wǎng)站的工作流程成都網(wǎng)站seo設(shè)計(jì)
  • 成都定制網(wǎng)站建設(shè)網(wǎng)站如何做seo排名
  • 網(wǎng)站技術(shù)的解決方案鄭州網(wǎng)絡(luò)營銷哪個(gè)好
  • 做京東網(wǎng)站需要哪些手續(xù)強(qiáng)強(qiáng)seo博客
  • app設(shè)計(jì)素材網(wǎng)站鄭州怎么優(yōu)化網(wǎng)站排名靠前
  • 常州網(wǎng)站制作報(bào)價(jià)php視頻轉(zhuǎn)碼
  • 做簡歷網(wǎng)站成人營銷管理培訓(xùn)班
  • 關(guān)注網(wǎng)站制作廣州各區(qū)最新動態(tài)
  • 制作釣魚網(wǎng)站移動網(wǎng)站推廣如何優(yōu)化
  • 企業(yè)做網(wǎng)頁還是網(wǎng)站網(wǎng)站優(yōu)化資源
  • cdn網(wǎng)絡(luò)對網(wǎng)站開發(fā)有影響嗎全網(wǎng)推廣代理
  • 中國建筑總公司官網(wǎng)首頁windows優(yōu)化大師怎么下載
  • 網(wǎng)站app下載平臺怎么做的代運(yùn)營公司是怎么運(yùn)營的
  • 南海佛山網(wǎng)站建設(shè)百度廣告代理公司
  • 網(wǎng)站平臺由什么搭建百度推廣登錄平臺登錄
  • 新建網(wǎng)站百度怎么收錄怎么做seo
  • 農(nóng)村服務(wù)建設(shè)有限公司網(wǎng)站google推廣工具
  • 南通網(wǎng)站建設(shè)報(bào)價(jià)專業(yè)培訓(xùn)seo的機(jī)構(gòu)