Windows Programming _ sun Xin C ++ lesson6 menu operations
Highlights of this section
1. Message response sequence
2. Message Classification
3. menu structure and features
4. Static menu operations
5. dynamically create menu operations
6. Implementation of the telephone book
//************************************** **************************************** ********************************
1. Message response sequence
At the same time, add the test class response function menu item response sequence to the four classes: View class Doc class cmainframe class app class
2. Message Classification
Standard Message: Except wm_command, all messages starting with WM _. Classes derived from cwnd can accept such messages, such as wm_char, command messages, and advertised messages.
Command message: the class derived from ccmdtarget, such as cwinapp, can accept command messages, but cannot accept standard messages.
Notification message: a message (such as a single button) generated by the control notifies the occurrence of an event in its Contact window. The notification message is also displayed in the form of wm_command. Classes derived from cve-target can accept such messages.
In short, the classes derived from cve-target can accept command messages and announcement messages. The classes derived from cwnd can accept standard messages, and of course can also accept command messages and announcement messages.
For more information about message classification, see:
3. menu structure and features
(1) Sub-menu: the entire building corresponds to the entire menu bar, and each floor corresponds to a sub-menu (file, edit, view, etc.) on the menu bar, and the room corresponds to the menu items of each sub-menu.
Menu item: Find the entire building --> Find a floor ---> find a room
Corresponding to finding the entire menu bar ---> finding a sub menu ---> finding a menu item
For the comparison between menus and buildings, see:
(2) The Menu separator cannot be ignored in the index access menu. It is also a value in the index.
(3) command update mechanism:
The maintenance of menu items depends on cn_update_command_ui Creek. When the cn_update_command_ui message is captured, MFC creates a ccmdui object (ccmdui is a class without a base class ).
This object is associated with the menu item and calls the member function doupdate () of this object (). note that the update command UI handler can only be applied to projects in pop-up menu items, and cannot be applied to permanently displayed top-level menu items.
(4) The index in the menu and the index on the toolbar may be inconsistent, resulting in an enable error.
4. Static menu operations
(1) create a bitmap menu to obtain the size of the menu bitmap in the system, and then set the size of the new bitmap to the appropriate size.
//************************************** **************************************** ****
Cstring strmenuinfo;
Strmenuinfo. Format ("x = % d, y = % d", getsystemmetrics (sm_cxmenucheck), getsystemmetrics (sm_cymenucheck ));
MessageBox (strmenuinfo );
M_bitchecked.loadbitmap (idb_bitmap1 );
M_bitunchecked.loadbitmap (idb_bitmap2 );
Psumenu-> setmenuitembitmaps (2, mf_byposition, & m_bitchecked, & m_bitunchecked );
//************************************** **************************************** ****
(2) mark the menu
//************************************** **************************************** ****
// Obtain the entire menu or sub-menu pointer
Cmenu * pmenu = getmenu ();
Cmenu * psumenu = pmenu-> getsubmenu (0 );
// Mark the menu
// Psumenu-> checkmenuitem (0, mf_byposition | mf_checked); // Location index
// Psumenu-> checkmenuitem (id_file_new, mf_bycommand | mf_checked); // ID Index
//************************************** **************************************** ****
(3) only one default menu can be selected by default.
//************************************** **************************************** ****
// Psumenu-> setdefaultitem (1, true); // set the default menu item to calculate by position
// Psumenu-> setdefaultitem (id_file_open); // you can specify the default menu item ID.
//************************************** **************************************** ****
(4) menu unavailable: Set m_bautomenuenable to false to block automatic updates.
Run m_bautomenuenable = false. The system no longer determines which menus are available or unavailable, and the cut copy menu is no longer grayed out.
(5) cancel the menu setmenu (null );
(6) load the menu
Setmenu (null );
Cmenu menu;
Menu. loadmenu (idr_mainframe );
Setmenu (& menu );
Menu. Detach (); // disconnects a local menu from an object. The menu object is parsed only when the window is destroyed.
(5) Right-click the menu
Add the pop-up menu to the View class instead of the mainframe class.
You can use the add control method or use the trackpopupmenu function to write your own code.
When writing the code, note that the display position of the menu is the screen coordinate, and the current click is based on the view coordinate. Then, the screen coordinate and customer area coordinate should be converted. Use the clienttoscreen () function for coordinate assembly ();
The owner of the pop-up menu is the view class, so it can only be the command for the View class to respond to the pop-up menu item; to get the framework pointer for the Framework response, use getparent. When the getparent () function is used, the view class still responds first, indicating that the subwindow responds.
The priority is higher than the parent window.
//************************************** **************************************** ***************
Void cmenuview: onrbuttondown (uint nflags, cpoint point)
{
// Todo: add your message handler code here and/or call default
Cmenu menu;
Menu. loadmenu (idr_menu_popup );
Cmenu * pmenu = menu. getsubmenu (0 );
// Crect myrect;
// Getclientrect (& myrect );
Clienttoscreen (& Point); // Coordinate Transformation
Pmenu-> trackpopupmenu (tpm_rightalign, point. X, point. Y, this, null );
Cview: onrbuttondown (nflags, point );
}
//************************************** **************************************** ***************
5. dynamically create menu operations
1. append, insert, and delete sub-menus or menu items
//************************************** *******************
Cmenu menu;
Menu. createpopupmenu (); // create popupmenu
// Getmenu ()-> appendmenu (mf_popup | mf_enabled | mf_string, uint (menu. m_hmenu), "appendmenu"); // Add the pop-up menu to the main menu
Getmenu ()-> insertmenu (2, mf_byposition | mf_popup | mf_string, uint (menu. m_hmenu), "appendmenu ");
Menu. appendmenu (mf_string, idm_menutest, "Item1 ");
Menu. appendmenu (mf_string, 112, "item2 ");
Menu. appendmenu (mf_string, 113, "item3"); // Add a menu item to the pop-up menu
Menu. Detach (); // do not forget to be separated from the menu object
Getmenu ()-> getsubmenu (0)-> appendmenu (mf_string, 114, "itemappend"); // append a menu item to the end
Getmenu ()-> getsubmenu (0)-> insertmenu (1, mf_byposition | mf_string, 115, "iteminsert"); // insert a menu item at a specified position
Getmenu ()-> deletemenu (1, mf_byposition); // delete a submenu
Getmenu ()-> getsubmenu (0)-> deletemenu (2, mf_byposition); // delete a menu item
//************************************** *******************
(2) dynamically added menus and Command Message responses
Add ID
Add Command Message response prototype
Add message ing macro
Add message Response Function
6. Implementation of the telephone book
(1) Train of Thought: Add a menu and redraw the menu bar to call drawmenubar () and use the cmainframe pointer.
Add character input to process wm_char messages
Redraw window invalidate ()
Cstringarray saves input (cobarray uses the same class ).
(2) Error c2501: 'cmenu2doc ': Missing storage-class or type specifiers solution: Contains menu2doc. h to menu2view. h
(3) command message routing:
Cwnd: windowproc ---> onwndmsg ---> when determining a standard message, the message is processed through message ing. If a command message is sent to oncommand, The advertised message is handled by ony y, and oncmdmsg. This program
Cmainframe --> subwindow View class ---> Doc class --> View message ing in the document class. If no message is displayed, return the message to view --> View class to view message ing, if no message is returned, the message is returned to the cmainframe class. ---> the cmainframe class is used to check whether a message is sent.
The message should be sent to cmenuapp if no message is sent;
For the command message routing process, see:
For more understanding, see the following code:
//************************************** *******************
// Wincore. cpp
Virtual lresult cwnd: windowproc (uint message, wparam, lparam );
Virtual bool cwnd: onwndmsg (uint message, wparam, lparam, lresult * presult );
Virtual bool cwnd: oncommand (wparam, lparam );
Virtual bool cwnd: onnotify (wparam, lparam, lresult * presult );
Lresult cwnd: windowproc (uint message, wparam, lparam)
{
// Onwndmsg does most of the work, response t for defwindowproc call
Lresult = 0;
If (! Onwndmsg (message, wparam, lparam, & lresult ))
Lresult = defwindowproc (message, wparam, lparam );
Return lresult;
}
Bool cwnd: onwndmsg (uint message, wparam, lparam, lresult * presult)
{
Lresult = 0;
// Special case for commands
If (Message = wm_command)
{
If (oncommand (wparam, lparam ))
{
Lresult = 1;
Goto lreturntrue;
}
Return false;
}
// Special case for notifies
If (Message = wm_policy)
{
Nmhdr * pnmhdr = (nmhdr *) lparam;
If (pnmhdr-> hwndfrom! = NULL & onnotify (wparam, lparam, & lresult ))
Goto lreturntrue;
Return false;
}
// *** Unspecified ****
}
//************************************** *******************
Virtual bool cframewnd: oncommand (wparam, lparam );
Therefore, when the virtual bool oncommand () function is added to cmainframe, MFC first calls the oncommand function of mainframe,
Then, call the oncommand () function of the base class. In this process, it seems that the mainframe intercepts the command message first, while the View class cannot be captured.
(4) telephone book Implementation
Member variables:
Cmenu2view class
Public:
Cstringarray m_strarray; // Save the input
PRIVATE:
Int m_nindex;
Cmenu m_menu;
Cstring m_strphone;
//************************************** *******************
// Input implementation
Void cmenu2view: onchar (uint nchar, uint nrepcnt, uint nflags)
{
// Todo: add your message handler code here and/or call default
Cclientdc DC (this );
If (0x0d = nchar)
{
If (0 = m_nindex)
{
M_menu.createpopupmenu ();
Getparent ()-> getmenu ()-> appendmenu (mf_popup | mf_enabled | mf_string, uint (m_menu.m_hmenu), "Phonebook ");
Getparent ()-> drawmenubar (); // The re-painting menu bar is updated now.
}
// Dynamically add menu items using input information
M_menu.appendmenu (mf_string, idm_phone1 + m_nindex, m_strphone.left (m_strphone.find ('')));
Invalidate ();
M_strarray.add (m_strphone );
M_nindex ++;
M_strphone.empty ();
}
Else
{
M_strphone + = nchar;
DC. textout (0, 0, m_strphone );
}
Cview: onchar (nchar, nrepcnt, nflags );
}
//************************************** *******************
// Output implementation
Bool cmainframe: oncommand (wparam, lparam)
{
// Todo: add your specialized code here and/or call the base class
// Message interception in the main framework (using the message routing mechanism)
Int menuid = loword (wparam );
Cmenu2view * pview = (cmenu2view *) getactiveview ();
If (menuid> = idm_phone1 & menuid <(idm_phone1 + pview-> m_strarray.getsize ()))
{
Cclientdc DC (pview );
DC. textout (, pview-> m_strarray.getat (MenuID-IDM_PHONE1 ));
MessageBox ("mainframe responsed! ");
Return true;
}
Return cframewnd: oncommand (wparam, lparam );
}
//************************************** *******************
The program running effect is as follows:
Summary:
1. Message Classification
2. message routing
3. Static menus and dynamic menu creation operations