How to dynamically add menus/menu items, submenus, and right-click menus
Menu-related operations mainly use the cmenu class. Of course, the corresponding API functions are also available. The cmenu class is only the encapsulation of the function of the Operation menu in the API by MFC. However, if you can use a class, try to use the class. The class is well organized and the code looks comfortable. For SDK programming, use the API.
Cmenu menumain, menu1; // define the cmenu object first
I. There are two ways to create a menu:
1. Use the loadmenu function to load Resources
Menumain. loadmenu (idr_mainframe); // load from the resource. Here the main menu resource of SDI is used.
2. Create with the createmenu Function
Menu1.createmenu (); // create a menu. No menu item exists.
2. Add menu items. appendmenu () can be added at the end of the menu, and insertmenu () can be added at the specified position.
// Id_test1 is defined in resource. H. Just give an integer. Do not repeat it with the existing one.
Menu1.appendmenu (Mf_string, Id_test1, "test1"); // The first menu item
Menu1.appendmenu (Mf_string, Id_test2, "Test2"); // The second menu item
Menu1.insertmenu (1, mf_byposition | mf_string,
(Uint) id_test1, "id_test1"); // Add a new menu item before the second menu item
3. Add sub-menu
Appendmenu () and insertmenu () functions are also used. However, pay attention to parameter settings.
Menu1.appendmenu (mf_byposition |Mf_popup| Mf_string,
(Uint) menumain. getsubmenu (0)-> m_hmenu, "Sub-menu ");
// The second parameter is the menu handle hmenu.
Iv. Delete menus
Use the deletemenu () and removemenu () functions to delete menu/menu items at the specified position.
Difference between the two: If the menu item is a pop-up menu, the difference between deletemenu and removemenu is very important. Deletemenu clears the pop-up menu, but removemenu does not clear it. One is a thorough deletion, and the other is a removal.
Msdn: 1.The deletemenu function destroys the handle to the menu or submenu and frees the memory used by the menu or submenu. It invalidates the handle of the menu or sub-menu (destroys ).
2. removemenu does not destroy the menu or its handle, allowing the menu to be reused. It can be reused and will not be deleted from the memory.
5. Add a shortcut menu
Cmenu menu1;
Menu1.createpopupmenu (); // dynamically create a pop-up menu object
Menu1.appendmenu (mf_string, id_test1, "menu item 1 ");
Menu1.appendmenu (mf_string, id_test2, "menu item 2 ");
Menu1.insertmenu (2, mf_byposition | mf_popup | mf_string,
(Uint) menumain. m_hmenu, "sub menu"); // Add sub menu
Cpoint pt;
Getcursorpos (& pt );
Menu1.trackpopupmenu (tpm_rightbutton, Pt. X, Pt. Y, this );
Menu1.destroymenu ();
6. Respond to menu events
1. If a menu is added to a resource, use Class Wizard to add a menu RESPONSE event.
2. If the menu is created by code, you need to manually Implement Message ing of the menu. This example is in the cmainframe class. Of course, it can also be in the View class and Doc class. It can also be based on the dialog box.
1) In the. h file
// Generated message map Functions
Protected:
// {Afx_msg (cmainframe)
Afx_msg int oncreate (maid );
Afx_msg void onchangmenuitem (); // Add the menu command here to process the declaration of the Function
//} Afx_msg
Declare_message_map ()
2) In the. cpp file,
Begin_message_map (cmainframe, cframewnd)
// {Afx_msg_map (cmainframe)
On_wm_create ()
On_command (idm_changmenuitem, onchangmenuitem) // Add it here. Note that ';' does not exist ';'
//} Afx_msg_map
End_message_map ()
Void cmainframe: onchangmenuitem ()
{
// Write the code to be processed here
......
}
Other methods:
If the menu id value is continuous, it is best to use on_command_range to map the message processing function. You can process all messages within a range in a function.
When you press a menu item, a wm_command message is sent, and the idnumber of the menu item is included in the low position of the wparam parameter.
Bool cyourview: oncommand (wparam, lparam)
{
// Todo: add your specialized code here and/or call the base class
Uint m_nitemid = loword (wparam );
If (m_nitemid = id_youritem) // id_youritem ID specified when you add a menu item
{
// Put the response code here
}
Return cscrollview: oncommand (wparam, lparam );
}
You can use the trackpopupmenu return value to process the context menu. Set TPM _ returncmd in the uflags parameter. In this way, the returned value is the ID of the menu item you selected and can be processed according to the ID.
Trackpopupmenu (TPM _ returncmd, Pt. X, Pt. Y, this );
Msdn:If you specify tpm_returncmd in the uflags parameter, the return value is the menu-item identifier of the item that the user selected.
VII. Others
Drawmenubar (); // when you change a menu, you need to re-paint the menu to display the changes.
Getsystemmenu (); // get the window control window
Getmenu () // obtain the menu used by the current program
Getsubmenu () // obtain the submenu
The detach () member function of the cmenu class should be used to separate the menu handle from the cmenu object to avoid program errors after the object fails.
For example:
Cmenu menu;
Menu. createpopupmenu (); // dynamically create a pop-up menu object
Menu. appendmenu (0, id_test1, "test1 ");
Menu. appendmenu (0, id_test2, "Test2 ");
Cmenu * menumain = getmenu (); // The main menu of the program must be in the cmainframe class.
Menumain-> appendmenu (mf_byposition | mf_popup | mf_string, (uint) menu. m_hmenu, "sub menu 1 ");
Menu. Detach (); // An error occurred while directly using menu. m_hmenu. The menu object is destroyed after the event ends.
Drawmenubar ();