Vc mfc menu bar (cmenu) controls () classification:
C ++
Menu Bar
Display the menu bar in the dialog box
Like the toolbar, the menu bar does not have the corresponding options in the push panel, but there is a menu control class cmenu, so if you want to display the menu bar in the dialog box, just like the toolbar, on the resourceview tab, create a menu bar resource. The procedure is the same as creating a toolbar resource, except that the resource type is menu. The menu resource design is as follows:
If you want to change the text of a menu item, right-click the menu item to be changed, select properties, and a dialog box will pop up:
The ID item above is the ID corresponding to this menu item. It is used when you add a menu item and click the message processing function. The content in the marked item is the text to be displayed.
Note that the "pop-up" option indicates that the corresponding menu item has a lower-level menu, such:
The menu item "go to" above has a pop-up attribute and a sub-menu.
After the menu resources are designed, We can display the menu bar in the dialog box by entering the dialog box editing area, right-clicking the dialog box interface, selecting properties, and selecting the menu resource ID in the menu item, press enter to compile and run the program. The effect is as follows:
Of course, there is another way to display the menu in the dialog box: Call the setmenu function to associate the menu with the dialog box. The first parameter of the function is the window handle, and the second parameter is the menu handle. Add the following statement to the oninitdialog function:
Cmenu menu; // defines a menu class variable.
Menu. loadmenu (idr_menu1); // load the idr_menu1 menu resource
Setmenu (& menu); // associate with the current window
Menu. Detach (); // separate
If you want to process a menu item and click a message, you can click a message in the same way as you do in the toolbar. In the Class Wizard, find the corresponding menu item ID and add the Command Message Processing Function for it.
Set the display bitmap and background bitmap on the left of the menu
Functions to be understood in the cmenu class
Setmenuitembitmaps // sets the bitmap on the left of the menu item.
Function Definition: bool setmenuitembitmaps (uint nposition, uint nflags, const cbitmap * pbmpunchecked, const cbitmap * pbmpchecked );
Npostion indicates the menu item to be set. It can be a menu item index and a menu item ID, which is specified by the nflags parameter. If it is mf_byposition, it is specified by the menu item index,
If it is mf_bycommand, the first parameter nposition is the menu item ID. The bitmap displayed when pbmpunchecked is not detected (normal) and the image displayed when pbmpchecked is detected (that is, the image displayed when the menu item is checked, which is associated with the checkmenuitem function)
An API function setmenuinfo. This function can be used to set the fill brush type selected during menu re-painting. This function has two parameters. The first one is the menu handle to be set, the second is a menuinfo structure pointer. We only need to know that there is a member hbrback in this structure. hbrback is a paint brush handle, the menu background bitmap is implemented by creating a bitmap image brush.
Well, the above project is used as an example to introduce three bitmaps. the ID number remains unchanged by default, and then a bitmap (menu background bitmap, ID: idb_menuback) is introduced ), then, add the following statement to the oninitdialog function of the dialog box class:
Cmenu * pmenu = getmenu (); // obtain the context menu of the dialog box
Cmenu * psubmenu = pmenu-> getsubmenu (0); // obtain the sub menu (if any). 0 indicates the index, corresponding to the "file" menu.
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); // creates a bitmap image brush.
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 ();
The running effect is as follows:
(PS: I don't know if you have encountered this problem. The menuinfo structure is undefined. The solution is to go to the file tab (FileView) and go to the stdafx under the source file. add the statement at the beginning of the CPP file: # define winver 0x0501)
Design pop-up menu
Functions to be understood in the cmenu class:
Trackpopupmenu (uint nflags, int X, int y, cwnd * pwnd, lpcrect lprect = NULL );
This function is used to display menus on the interface. The nflags parameter specifies the menu display flag. X and Y are used to determine the coordinate points based on which the menu is displayed. pwnd is the window for single-phase association of dishes.
The nflags parameter is described as follows:
|
Specifies the screen position or mouse key. The screen position flag can be one of the following values:
· |
Tpm_centeralign |
Center the pop-up menu in the horizontal direction relative to the coordinates specified by X. |
· |
Tpm_leftalign |
Place the pop-up menu to align it left at the position specified by X. |
· |
Tpm_rightalign |
Place the pop-up menu to align it right at the position specified by X. |
The mouse key flag can be one of the following values:
· |
Tpm_leftbutton |
As a result, the left mouse button is displayed. |
· |
Tpm_rightbutton |
In this case, right-click the menu trace. |
|
Take the preceding project as an example. In the dialog box, right-click the message processing function (wm_rbuttonup) and add the following code to the function:
Void cseventhdlg: onrbuttonup (uint nflags, cpoint point)
{
// Todo: add your message handler code here and/or call default
Cmenu * menu = getmenu ();
Clienttoscreen (& Point); // convert the window coordinates into screen coordinates
Menu-> getsubmenu (0)-> trackpopupmenu (
Tpm_leftbutton | tpm_vertical, point. X, point. Y, this );
Menu-> detach ();
Cdialog: onrbuttonup (nflags, point );
}
Note that the menu to be displayed on the interface must be a pop-up menu. Although menu-> trackpopupmenu can also be displayed, it is obviously not the desired result.
Running effect:
Dynamic (Code-only) create a menu
In the preceding example, menus created using menu resources are used. This time, we use code to create menus. In essence, this is the same as creating a control using the create function of the control class. The "CREATE" function here is the createmenu and createpopupmenu functions.
Functions to be understood in the cmenu class:
Createmenu // create a main menu with no parameters
Createpopupmenu // create a menu with a pop-up property. The function has no parameters.
Appendmenu // Add a menu item or pop-up menu to a menu
The appendmenu function is defined as follows:
Bool appendmenu (uint nflags, uint nidnewitem = 0, lpctstr lpsznewitem = NULL );
Common Values of nflags are as follows:
Mf_string indicates that a menu item does not have a pop-up attribute.
A pop-up menu item added by mf_popup
Mf_separator adds a menu separator.
Mf_ownerdraw indicates that the corresponding menu has a self-painted attribute.
Nidnewitem parameter. if you add a menu item that does not have a pop-up attribute, the value is the menu item ID. Otherwise, it is a pop-up menu handle, and lpsznewitem is the menu item name (menu text content)
Now let's create a menu dynamically. First, add a button control to the dialog box. When you click this button, create a menu and respond to the click message of this button control, add the following code to the message processing function:
Cmenu menu;
Menu. createmenu (); // create a Main Menu
Cmenu popmenu;
Popmenu. createpopupmenu (); // create a pop-up menu
Popmenu. appendmenu (mf_string, 1001, "new"); // Add a menu item
Popmenu. appendmenu (mf_string, 1002, "open ");
Popmenu. appendmenu (mf_string, 1003, "save ");
Menu. appendmenu (mf_popup, (uint) popmenu. m_hmenu, "file"); // Add a pop-up menu item
Setmenu (& menu); // associate it with the window
Menu. Detach ();
Popmenu. Detach ();
Change the menu item size (width and height) and set the font size of the menu text.
Because the cmenu class does not provide a function to set the menu item size and font size, we can only use the self-painting method to implement the above function.
If you do not know some functions of the cmenu class, you can refer to the "MFC class Daquan ".
First, a subclass cnewmenu (the class type is generic class) is derived from cmenu, and then three member functions are added to this class, measureitem (Set Menu width and height ),
Drawitem (custom menu), changemenuitem (modify menu item type)
The three functions are defined as follows:
Void cnewmenu: measureitem (lpmeasureitemstruct)
Void cnewmenu: drawitem (lpdrawitemstruct)
Void cnewmenu: changemenuitem (cmenu * pmenu)
Here, measureitem and drawitem are virtual functions of the cmenu class.
The code for each function is as follows:
Void cnewmenu: measureitem (lpmeasureitemstruct)
{
Lpmeasureitemstruct-> itemheight = 25; // item height
Lpmeasureitemstruct-> itemwidth = 120; // item width
}
Void cnewmenu: drawitem (lpdrawitemstruct)
{
Crect rect = lpdrawitemstruct-> rcitem;
Cdc dc;
DC. Attach (lpdrawitemstruct-> HDC );
DC. fillsolidrect (rect, RGB (0,166,170 ));
Cfont font;
Font. createpointfont (125, ""); // create a font
DC. SelectObject (& font );
Cstring * ptext = (cstring *) lpdrawitemstruct-> itemdata;
If (lpdrawitemstruct-> itemstate & ods_selected)
DC. fillsolidrect (rect, RGB (202,); // The menu is selected.
DC. settextcolor (RGB (10, 0, 181); // set the text color
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); // obtain the menu item ID
Pmenu-> getmenustring (I, * ptext, mf_byposition); // obtain the menu text
// The last parameter of the modifymenu function corresponds to the itemdata variable in the drawitemstruct structure.
Pmenu-> modifymenu (I, mf_ownerdraw | mf_byposition | mf_string, Itemid, (lpstr) ptext );
If (Itemid =-1) // if it is a pop-up menu
{
Changemenuitem (pmenu-> getsubmenu (I ));
}
}
}
Each menu item must have the mf_ownerdraw attribute. Otherwise, the wm_measureitem and wm_drawitem messages cannot be received, and the menu item does not have the mf_ownerdraw attribute. Even if a message is received, it cannot be automatically painted, therefore, the changemenuitem function above is used to modify menu item attributes.
Wm_measureitem and wm_drawitem messages are not directly sent to the menu window and will be received by the parent window. Therefore, you must process the wm_measureitem and wm_drawitem messages in the parent window and add these two message processing functions to the context class, the code in the two functions is as follows:
Void cfirstdlg: onmeasureitem (INT nidctl, lpmeasureitemstruct)
{
// Todo: add your message handler code here and/or call default
If (lpmeasureitemstruct-> ctltype = odt_menu) // if the type is menu
Newmenu. measureitem (lpmeasureitemstruct); // call the measureitem member function of the cnewmenu class
Else
Cdialog: onmeasureitem (nidctl, lpmeasureitemstruct );
}
Void cfirstdlg: ondrawitem (INT nidctl, 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 );
}
Then we add a member variable in the dialog class:
Cnewmenu newmenu; (remember to include the header file: "newmenu. H"), and then add the following code in the oninitdialog function of the dialog box class:
Newmenu. loadmenu (idr_menu1 );
Setmenu (& newmenu );
// Only change the first item in the main menu. Change all: newmenu. changemenuitem (& newmenu );
Newmenu. changemenuitem (newmenu. getsubmenu (0 ));
Idr_menu1 is the ID of the menu resource. You can create it by yourself. Now, the major achievements have been completed. Click compile and run. The effect is as follows:
Like the self-painted button control, it still does not process all menu statuses, such as getting focus, checking, and associating images. Does not process menu separators ..
If you want to process these statuses. We recommend that you check the itemstate variable of the drawitemstruct structure. This Member specifies the status of the menu item,
Associate the image to view the functions of the cmenu class...
(For the allocated memory corresponding to the menu item data (itemdata), release it by yourself)