Problem: Under normal circumstances we use Update_Command_UI to modify the status of the menu (Enable / Disable, CHECK / Uncheck, Change Text), but this method is in a dialog-based menu, but there is no effect.
Void ctestdlg :: onupdatefileexit (ccmdui * pcmdui)
{
PCMDUI-> Enable (false);
PCMDUI-> SetCheck (TRUE);
PCMDUI-> setradio (TRUE);
PCMDUI-> SetText ("close");
// The above method can work in the MDI and SDI program. There is no effect in the dialog box, and this function is not called.
}
Cause Analysis: When a drop-down menu is displayed, a WM_INITMENUPOPUP message will be sent before the menu is displayed. The cframeWnd :: OnInitMenup function refreshes this menu item, and if there is an Update_command_UI response function, call it. Use it to update the appearance effect of each menu (Enabled / Disabled, Checked / Unchecked).
In a dialog-based program, because there is no OnInitMenupopup function, the Update_command_UI response function is not called, but the default processing of the CWND class is used, which does not call the Update_command_UI response function.
The solution is as follows:
first step:
Add a ON_WM_INITMENUPOPUP entry to a message map in the dialog box class.
Begin_MESSAGE_MAP (Ctestdlg, cdialog)
//}} AFX_MSG_MAP
ON_WM_INITMENUPOPUP ()
END_MESSAGE_MAP ()
Step 2:
Add a message function declaration in the .h file of the dialog box.
// generated message map functions
// {{AFX_MSG (CDISABLEDLGMENUDLG)
AFX_MSG Void OninitMenupopup (CMenu * Ppopupmenu, Uint NINDEX, BOOL BSYSMENU);
//}} AFX_MSG
Declare_message_map ()
third step:
Add the following function code in the dialog class class (most code is taken from the winFrm.cpp file "CFRAMEWND :: OnInitMenupopup):
Void C ****** DLG :: OnNitMenupopup (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 to
// 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 { 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 (); State.m_nIndex = 0; state.m_nindex State.m_nIndex ) { State.m_nid = ppopupmenu-> getMenuItemId (state.m_nindex); IF (state.m_nid == 0) Continue; // Menu Separetor 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 what 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 to. } State.doupdate (this, true); // Popups Are Never Auto Disabled. } Else { // Normal Menu Item. // Auto Enable / Disable if Frame Window Has M_Bautomenuenable // set and common is _not_ a system command. State.m_psubmenu = null; State.doupdate (this, false); } // adjust for menu delections and additions.uint ncount = ppopupmenu-> getMenuItemcount (); IF (ncount { State.m_NINDEX - = (state.m_nindexmax - ncount); While (state.m_nindex PpopupMenu-> getMenuitemid (state.m_nindex) == State.m_nid) { State.m_nIndex ; } } State.m_nindexmax = ncount; } }