How to add a menu to the dialog box:
1) use function loading
2) create a menu resource idr_mainframe and add the menu idr_mainframe item to the Panel resource in the dialog box.
Problem: the menu can be implemented by using the following methods, but the menu status cannot be updated.
Source: http://vcer.net/showTip.jsp? Tipid = 1, 2521
Http://hi.baidu.com/hypkb/blog/item/5c7e61613bdf24d78db10db4.html
Symptom
From the command UI handler interface, changing the menu status (enable/disable, select/unselect, and change the text) does not work properly in the dialog box.
Void ctestdlg: onupdatefileexit (ccmdui * pcmdui)
{
Pcmdui-> enable (false); // not calling the command handler, but does not show as disabled.
Pcmdui-> setcheck (true); // does not show check mark before the text.
Pcmdui-> setradio (true); // does not show dot before the text.
Pcmdui-> settext ("close"); // does not change the text.
}
Cause
When the drop-down menu is displayed, the wm_initmenupopup message is sent first to display the menu items. The MFC cframewnd: oninitmenupopup function traverses menu items and calls the update command processing function (if any) for each menu item ). the menu appearance is updated to reflect its status (enable/disable, select/unselect). The user interface update mechanism cannot work in dialog box-based applications, because cdialog does not have the oninitmenupopup processing function, and uses the cwnd's default processing function, this function does not call the update command processing function for the menu item.
Solution
Follow these steps to solve this problem by adding the on_wm_initmenupopup item to message ing:
Begin_message_map (ctestdlg, cdialog)
// {Afx_msg_map (ctestdlg)
........................
........................
//} Afx_msg_map
On_wm_initmenupopup ()
End_message_map ()
Add the oninitmenupopup member function in your dialog box class and copy the following code to the function (note: the code
Basically, it is copied from cframewnd: oninitmenupopup (in winfrm. cpp ):
Void ctestdlg: oninitmenupopup (cmenu * ppopupmenu, uint nindex, bool bsysmenu)
{
Assert (ppopupmenu! = NULL );
// Check the Enabled state of various menu items.
Ccmdui state;
State. m_pmenu = ppopupmenu;
Assert (State. m_pother = NULL );
Assert (State. m_pparentmenu = NULL );
// Determine If menu is popup in top-level menu and set m_pother
// It If so (m_pparentmenu = NULL indicates that it is secondary popup ).
Hmenu hparentmenu;
If (afxgetthreadstate ()-> m_htrackingmenu = ppopupmenu-> m_hmenu)
State. m_pparentmenu = ppopupmenu; // parent = Child for tracking Popup.
Else if (hparentmenu =: getmenu (m_hwnd ))! = NULL)
{
Cwnd * pparent = this;
// Child windows don't have menus -- need to go to the top!
If (pparent! = NULL &&
(Hparentmenu =: getmenu (pparent-> m_hwnd ))! = NULL)
{
Int nindexmax =: getmenuitemcount (hparentmenu );
For (INT nindex = 0; nindex <nindexmax; nindex ++)
{
If (: getsubmenu (hparentmenu, nindex) = ppopupmenu-> m_hmenu)
{
// When popup is found, m_pparentmenu is containing menu.
State. m_pparentmenu = cmenu: fromhandle (hparentmenu );
Break;
}
}
}
}
State. m_nindexmax = ppopupmenu-> getmenuitemcount ();
For (State. m_nindex = 0; State. m_nindex <state. m_nindexmax;
State. m_nindex ++)
{
State. m_nid = ppopupmenu-> getmenuitemid (State. m_nindex );
If (State. m_nid = 0)
Continue; // menu separator or invalid cmd-Ignore it.
Assert (State. m_pother = NULL );
Assert (State. m_pmenu! = NULL );
If (State. m_nid = (uint)-1)
{
// Possibly a popup menu, route to first item of that Popup.
State. m_psubmenu = ppopupmenu-> getsubmenu (State. m_nindex );
If (State. m_psubmenu = NULL |
(State. m_nid = state. m_psubmenu-> getmenuitemid (0) = 0 |
State. m_nid = (uint)-1)
{
Continue; // first item of popup can't be routed.
}
State. doupdate (this, true); // popups are never auto disabled.
}
Else
{
// Normal menu item.
// Auto enable/disable if frame window has m_bautomenuenable
// Set and command is _ not _ A system command.
State. m_psubmenu = NULL;
State. doupdate (this, false );
}
// Adjust for menu deletions and additions.
Uint ncount = ppopupmenu-> getmenuitemcount ();
If (ncount <state. m_nindexmax)
{
State. m_nindex-= (State. m_nindexmax-ncount );
While (State. m_nindex <ncount &&
Ppopupmenu-> getmenuitemid (State. m_nindex) = state. m_nid)
{
State. m_nindex ++;
}
}
State. m_nindexmax = ncount;
}
}
This is the behavior in the status design.
In addition, you need to write a declaration in the. h file. The Code is as follows:
Afx_msg void oninitmenupopup (cmenu * ppopupmenu, uint nindex, bool bsysmenu );
More information
The command user interface processing function is also called by cwnd: oncommand to confirm that the command is not disabled before it is passed.
This is why the command for the disabled menu item is not called (although not displayed in gray (unavailable )).
In this case, the menu item is not re-painted to reflect the status of the menu item. This is the code in the wincore. cpp file:
// Before passing the command, make sure the command is not disabled (Note: The following code is not required in general, and I don't know where to put it, huh, huh)
// Make sure command has not become disabled before routing.
Ctestcmdui state;
State. m_nid = NID;
On1_msg (NID, cn_update_command_ui, & state, null );
If (! State. m_benabled)
{
Trace1 ("Warning: not executing disabled command % d/N", NID );
Return true;
}
Steps to reproduce this behavior
Use the Application Wizard to create a dialog box-based application to create a new menu resource and add files and files/exit menu items to it. In the properties of the dialog box, set the menu of the dialog box to the above menu.
Use the Class Wizard to add an update_command_ui handler for the file/exit menu item and add one of the following statements to the handler function.
Pcmdui-> enable (false); // not calling the handler, but does not show as Disabled
Pcmdui-> setcheck (true); // does not show check mark before the text.
Pcmdui-> setradio (true); // does not show dot before the text.
Pcmdui-> settext ("close"); // does not change the text.