Win32的菜單編程

來源:互聯網
上載者:User

 

  WIN32使用者介面設計基礎之Menus篇 2003-3-29 13:05:28   YESKY   陳孝強   閱讀次數: 4835  一個菜單條總是屬於一個視窗,當使用者選定一個功能表項目後,系統向菜單的父視窗發出訊息,如果是普通菜單發送WM_COMMAND訊息,如果是系統功能表發送WM_SYSCOMMAND訊息。當滑鼠懸浮在一個有下級菜單的功能表項目上時,系統首先向菜單的父視窗發送WM_INITMENUPOPUP訊息,然後展開子功能表。每一個菜單條由一個唯一的控制代碼指向,類型為HMENU。獲得一個菜單的控制代碼使用GetMenu()函數,獲得子功能表用GetSubMenu()、GetMenuItemInfo()。獲得視窗的系統功能表控制代碼應當使用GetSystemMenu()。菜單除了控制代碼,還有ID,類似於按鈕的ID,當菜單觸發事件時,菜單ID被包含在WM_COMMAND或WM_SYSCOMMAND中一同發送。可以通過GetMenuItemID()擷取一個功能表項目的ID。訪問功能表項目時如果使用ID的方式會比較麻煩,一種變通的方法就是按照功能表項目的以0為基數的索引進行訪問,最左邊的為0,向右逐次遞增,最上邊的為0,向下逐次遞增。   一、 菜單的建立   1、 使用菜單資源   首先設計好菜單,然後用LoadMenu()載入,再用SetMenu()設定,例如,在視窗的WM_CREATE訊息中: HMENU hMenu;hMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1));SetMenu(hWNd,hMenu);    2、 記憶體菜單模板建立菜單   有的應用程式允許使用者自訂菜單,這就要求使用記憶體菜單模板來定義菜單,然後用LoadMenuIndirect()函數載入這個記憶體菜單模板獲得菜單控制代碼,記憶體菜單模板由兩部分組成:一個MENUITEMTEMPLATEHEADER(或者MENUEX_TEMPLATE_HEADER)結構和若干個MENUITEMTEMPLATE(或者MENUEX_TEMPLATE_ITEM)結構   3、 CreateMenu()函數   CreateMenu()函數返回一個指向空菜單的HMENU指標,利用這個指標向其中添加功能表項目InsertMenuItem()。 動態菜單建立後必須調用SetMenu()函數   二、 菜單的顯示   1、 對於已經通過在WNDCLASSEX視窗類別註冊時指定hMenu成員或者調用SetMenu()函數為其設定了父視窗的菜單,視窗顯示,菜單自動顯示   2、 顯示快顯功能表應使用TrackPopmenuEx()函數,例如 HMENU hpMemu;hpMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_POPMENU);TrackePopmenuEx(hpMenu,//菜單的控制代碼TPM_LEFTALIGN,//菜單和彈出點座標的對齊x,//彈出點X座標y,//彈出點Y座標hWnd,//父視窗控制代碼NULL);    3、 菜單顯示過程中的訊息   使用者單擊功能表列上的一項,父視窗接收到WM_INITITEM訊息(在這個訊息中可以繪製菜單),然後快顯功能表。當滑鼠指向一個可以彈出子功能表的功能表項目時,父視窗接收到WM_INITMENUPOPUP(可捕獲此訊息繪製子功能表),然後彈出子功能表。當滑鼠在菜單上移動時,父視窗接收到WM_MENUSELECT訊息,該訊息中包含有當前的功能表項目的索引號,可以對其進行引用。單擊一個功能表項目,產生WM_COMMAND訊息,單擊一個風格為MNS_NOTIFYBYPOS的功能表項目,產生WM_MENUCOMMAND訊息,該訊息除了提供WM_COMMAND訊息提供的資料外還額外添加了一個MENUINFO結構。右鍵快顯功能表發送WM_CONTEXTMENU訊息。使用者在一個功能表項目上右擊滑鼠將產生WM_MENURBUTTONUP訊息(例如在IE的收藏菜單的功能表項目上右擊快顯功能表的效果就可以通過捕獲該訊息實現)三、 菜單的動態更改   1、 插入新的功能表項目InsertMenuItem()   首先填寫MENUINFO結構 typedef struct tagMENUITEMINFO {UINT cbSize; 結構的大小,sizeof(MENUINFO)NT fMask; 將要獲得或者設定的項目,後面的哪些參數發揮作用受該參數的設定的影響。MIIM_BITMAP,hbmpItem將用來設定或返回按鈕的位元影像,MIIM_ID,wID設定或返回功能表項目的IDUINT fType; 設定或返回功能表項目的類型,MFT_BITMAP位元影像;MFT_STRING字串;MFT_OWNERDRAW,發送WM_DRAWITEM和WM_MEASUREITEM訊息用於繪製功能表項目UINT fState; 功能表項目的狀態:MFS_DEFAULT,預設;MFS_GRAYED,不可用;UINT wID; 功能表項目的ID,要求fMask中有MIIM_IDHMENU hSubMenu; 下一級菜單的控制代碼,要求fMask中有MIIM_SUBMENUHBITMAP hbmpChecked; HBITMAP hbmpUnchecked; ULONG_PTR dwItemData; LPTSTR dwTypeData; UINT cch; HBITMAP hbmpItem;} MENUITEMINFO, *LPMENUITEMINFO;然後調用InsertMenu()函數InsertMenu(HMENU hMenu;UINT nItems;BOOL isPisition;//設為TRUE,nItems為功能表項目的索引號,設為FALSE,nItems為功能表項目的IDLPCMENUITEMINFO lpmiinfo;)    2、 修改功能表項目屬性使用SetMenuItemInfo()函數   3、 刪除功能表項目     DeleteMenu()和RemoveMenu(),功能表項目刪除後用DrawMenuBar()重繪菜單顯示更新   四、 菜單特效    1、 捷徑功能表   捕獲父視窗的WM_CONTEXTMENU(使用者在視窗中右擊滑鼠將啟用該事件),調用函數TrackPopupMenuEx();TrackPopupMenuEx(hm,0,GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam),hWnd,NULL);hm為菜單控制代碼,GET_X_LPARAM(不知怎麼不能用)宏獲得事件發生時滑鼠的X座標,hWnd為父視窗控制代碼   2、 位元影像菜單     MENUITEMINFO結構的fMask中添加MIIM_BITMAP標誌,為期hbmItem指定一個指向位元影像的指標   五、 自繪製菜單   1、 指定標誌   要實現自繪製必須使功能表項目的風格符合要求,有兩種方法可以做到,其一是用InsertMenuItem()函數插入,其二是用SetMenuItemInfo()函數修改,不論使用哪一個都必須填寫一個MENUITEMINFO結構,為其fMask添加MIIM_FTYPE,為其fType添加MFT_OWNERDRAW。和列表框一樣,對功能表項目進行自繪製是設計到較多的資料傳遞,可以存放在MENUITEMINFO結構中,設定fMask為MIIM_DATA,然後給dwItemData成員賦值。WM_DRAWITEM(LPDRAWITEMSTRUCT)和WM_MEASUREITEM(LPMEASUREITEMSTRUCT)的參數中都含有itemData成語用於取出預先存放的資料。   例如: MENUITEMINFO mi;HMENU hmn;mi.fMask=MIIM_FTYPE;milfType=MFT_OWNERDRAW;hmn=GetMenu(hWnd);SetMenuItemInfo(hmn,0,TRUE,&mi);    2、 處理WM_MEASUREITEM訊息   使用者單擊,菜單即將顯示時,菜單的父視窗接收到WM_MEASUREITEM訊息,捕獲此訊息可以設定功能表項目的尺寸,例如: LPMEASUREITEMSTRUCT lpmis;lpmis=(LPMEASUREITEMSTRUCT)lParam;lpmis->itemHeight=48lpmis->itemWidth=144;    3、 處理WM_DRAWITEM訊息   WM_DRAWITEM訊息的LPARAM參數為一個LPDRAWITEMSTRUCT指標,其中含有指向被繪製的功能表項目的裝置情境指標、菜單ID和狀態等資訊,根據這些資訊進行繪製,例如: LPDRAWITEMSTRUCT lpdis;HDC hMem;HBITMAP hbm;hMem=CreateCompatibleDC(lpdis->hDC);hbm=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_MENUMAP));SelectObject(hMem,hbm);BitBlt(lpdis->hDC,0,0,lpids->rcItem.right,lpdis->rcItem.bottom,hMem,0,0,SRCCOPY);     

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.