# # Personalized menu with icon # #今天把程序托到xp虚拟机, plan to look at the performance of XP, find the Small icon of the menu*16 Display 3/about 4, very ugly, then have this article # # implementation Method # #有点像Listview的item重绘 (self-painting) implementation. 3 Pips1. Set menu for Mf_ownerdraw style, (self-painted style)2. Handling Wm_measureitem messages to set the height of the menu item3. Process Wm_drawitem messages to draw chart text ... is not the same as the ListView item redraw! (Free to share the next ListView Redraw) # # # Setting menu for Mf_ownerdraw Style # # #1looping through the menu each item setting stylevoidModifymenuowndraw (HMENU hmen) {HMENU Hsubmenu=NULL; intImenuidx =0 ; WCHAR Wszstring[max_path]; intImenuitemcount =0; while((Hsubmenu =GetSubMenu (HMEN,IMENUIDX))) {Imenuitemcount=Getmenuitemcount (Hsubmenu); for(intI=0; I < imenuitemcount;i++) {Modifymenu (hsubmenu,i,mf_byposition|mf_ownerdraw,null,null); } imenuidx++; } }2The call timing I called in wm_create message processing.3. Effects each menu item becomes a small white box with # # # processing Wm_measureitem messages to set the height of the menu item # # #1. Adding Wm_measureitem processing functionsvoidOnMeasureItem (HWND hwnd, MEASUREITEMSTRUCT *Lpmeasureitem) { if(Lpmeasureitem->ctltype = =Odt_menu) { //have ID is normal item, no ID is split line if(lpmeasureitem->ItemID) {Lpmeasureitem->itemheight = -;//GetSystemMetrics (sm_cymenu); } Else { //Split line is low.Lpmeasureitem->itemheight =3; } Lpmeasureitem->itemwidth = - ; } }2. Effect each menu item becomes a long white box # # #处理WM_DRAWITEM消息来绘制图表文字 # # #1. Adding Wm_drawitem handler functionsvoidOnDrawItem (HWND hwnd,ConstDrawitemstruct *Lpdrawitem) {HDC HDC= lpdrawitem->HDC; Menuiteminfo Miinfo={0} ; WCHAR Wszstring[max_path]; Rect rect; memcpy (&rect,& (Lpdrawitem->rcitem),sizeof(RECT)); //here to judge the self-painted button, ListView, MENU and so on, you can see the definition of Odt_menu, you can find out how many kinds of if(Lpdrawitem->ctltype = =Odt_menu) {Hbrush hbrush; //menu item has ID is the normal option, no ID is the split line, separate treatment if(lpdrawitem->ItemID) { //for the selected item, we're going to draw a big red box. if(Lpdrawitem->itemstate &ods_selected) {Hbrush=createsolidbrush (RGB (255, -,147)); } Else { //not selected to draw back to the primary colorHbrush =CreateSolidBrush (GetSysColor (Color_menu)); } framerect (HDc,&Rect,hbrush); Deletebrush (Hbrush); }Else { //Split Line, we just draw a big lever .SetDCBrushColor (Hdc,getsyscolor (Color_menutext)); Rect.top+=1; Rect.bottom-=1; Rectangle (Hdc,rect.left,rect.top,rect.right,rect.bottom); } if(lpdrawitem->ItemID) { //draw img intIalign = (Rect.bottom-rect.top- -)/2 ; intx = Rect.left +ialign; inty = rect.top +ialign; BITMAP bmp; HDC Hdcmem=CreateCompatibleDC (HDC); Hbitmap hbmp= LoadBitmap (Hinst,makeintresource (Lpdrawitem->itemid-id_file_listener +Idb_bmp_listener)); //hbitmap hbmp = (hbitmap) loadimage (NULL, "1.bmp", Image_bitmap, 0, 0, lr_loadfromfile| Lr_createdibsection); GetObject (Hbmp,sizeof(BITMAP), &BMP); SelectObject (Hdcmem, hbmp); BitBlt (hDc, x, Y, -, -, Hdcmem,0,0, srccopy); DeleteDC (HDCMEM); DeleteObject (hbmp); //Draw Text//to draw a word first get the next heightTextmetric TM; GetTextMetrics (HDc,&TM); //calculates the rect where the word is located. If the font is centered above intIaligntop = (rect.bottom-rect.top-tm.tmheight)/2 ; Ialigntop= ialigntop >0? Ialigntop:-Ialigntop; Rect.top+=Ialigntop; Rect.bottom-=Ialigntop; //leave out the drawing icon position torect.left+= -; //Get string FirstGetmenustring ((HMENU) lpdrawitem->hwnditem,lpdrawitem->Itemid,wszstring,max_path,mf_bycommand); //and you have to decide if you have \ t some words to write separately.wchar* lpfind = WCSCHR (wszstring,l'\ t'); if(lpfind) {*lpfind = L' /'; Lpfind+=1 ; } Drawtextex (Hdc,wszstring,wcslen (wszstring), (LPRECT)&(rect), dt_left,null); //with \ t. if(lpfind) {Rect.left+= - ; Rect.right-=Ten; Drawtextex (Hdc,lpfind,wcslen (Lpfind), (LPRECT)&(rect), dt_right,null); } } } }2. The above code has been changed, there is no test, if the discrepancy also please self-restructuring
-Really want to lazy, or set small icons, size 12*12 in XP will not not adapt.
Hbitmap hbmpshow = LoadBitmap (Hinst,makeintresource (idb_bmp_show));
SetMenuItemBitmaps (Htraymenu, Id_notify_showxman, Mf_bycommand, hbmpshow,hbmpshow);
Self-drawing menu with icon