Article title: The original author: querw Original: www.vczx.com Sending: querw Published Type: Original release date: 2004-08-02 Download this article
Program run effects shots: Implementation of painting from the menu: querw (North China University 2000 Computer 4 classes) E-mail: querw@sina.com read << A beautiful painting from the menu >> (http on VCKBASE: // www.vckbase.com/document/viewdoc/?id=537) author: Zheng Heng (lbird) after applied to my own projects found: the article mentioned can be well implemented, but is inconvenient: You need to map WM_DRAWITEM and WM_MEASUREITEM messages to achieve self-drawing. This is an inconvenient for a dialog-based project, or only need to pop-up menu. There is a very famous self-painted menu on the Internet: bcmenu (http: // Www.rocscience.com/~corkum/bcmenu.html) (there is also bcmenu in the attached engineering), you can implement your own effects when you use it, you don't need to map the above two messages. This problem makes me feel very confused. MSDN also explains: MeasureItem () and DrawItem () two virtual functions are called by the framework without manual mapping. However, if the above two messages are not mapped, it is not normal. (I got a lot of information until now Still don't understand, huh, huh :)) Since BCMENU can implement self-drawing function without mapping WM_DRAWITEM and WM_MEASUREITEM, then it will definitely be dealt with. Sure enough, bcmenu :: loadmenu () has handled the entire menu. I noticed, If the menu is a pop-up, you don't need to map WM_DRAWITEM and WM_MEASUREITEM to achieve self-drawing. So I re-build the entire menu in cmenuex :: loading, put all submenus as pop-up menu use API functions :: createPopupnu (), code as follows: BOOL CMENUEX :: LoadMenu (uint umenu) {// Re-read the menu, create as a Popup menu, can self-draw (MesureItem () and drawItem () hmenu hmenu = :: CreateMenu (); this-> attach (hmenu); cMenu Menu; // Temporary menu (using cmenu's loadMenu () function reads into the menu, and constructs a new menu for Blue Pen; Menu.LoadMenu (Umenu); For (int i = 0; i <(int) menu.getmen UItemcount (); i ) {uid = menu.getMenuItemId (i); if (uid == 0) // Separator {:: appendmenu (HMENU, MF_SEPARATOR, 0, NULL);} else if (int) UID = = -1) // Pop-up menu (ie menu) {cmenu * psubmenu = menu.getsubmenu (i); // Create submenu HMENU HSUBMENU = :: createPopUpMenu (); cstring strpopup; menu.getMenustring (I, StrPopup, MF_BYPOSITION); :: InsertMenu (hMenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT) hSubMenu, strPopup); // sub-menu called recursively ChangeMenuStyle (), the sub-menu instead MF_OWNERDRAW style ChangeMenuStyle (pSubMenu, hSubMenu); } Else // Normal menu item {CString Strtext; menu.getMenustring (UID, STRTEXT, MF_BYCOMMAND); appendmenu (mf_string, uid, strtext);}} menu.destroyMenu (); // Destroy Temporary menu Return True;
} void cmenuex :: ChangeMenuStyle (cmenu HNEWMENU) {// Association is CMenuex (CMENU package) (CMENU package results?) cmenuex * pnewmex; pnewmenu = new cmenuex; pnewmenu = new cmenenuex; pnewMenu -> attach (hnewmenu); m_submerruarr.add (pnewmenu); uint uid; int nitemcount = pmenu-> getMenuItemCount (); for (int i = 0; i