Use on_update_command_ui to update the menu in the MFC dialog box.

Source: Internet
Author: User
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); // disabled if not displayed.
Pcmdui-> setcheck (true); // The selected tag is displayed before no text is displayed.
Pcmdui-> setradio (true); // The vertex is not displayed before the text.
Pcmdui-> settext ("close"); // The Menu text is not changed.
}

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 update user interface mechanism does not work in dialog box-based applications, because cdialog does not have the oninitmenupopup processing function, and cwnd's default processing function is used, this function does not call the update command handler function for the menu item.

Solution

Follow these steps to resolve this issue

Add the on_wm_initmenupopup entry 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 is basically from cframewnd: oninitmenupopup (in winfrm. in CPP) Copied ):

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;
}
}

Status

Design behavior.

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:

// Make sure the command is not disabled before the command is passed
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

Create a new menu resource and add a file and a file/exit menu item 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); // disabled if not displayed.
Pcmdui-> setcheck (true); // The selected tag is displayed before no text is displayed.
Pcmdui-> setradio (true); // The vertex is not displayed before the text.
Pcmdui-> settext ("close"); // The Menu text is not changed.

 

 

From: http://beauty.hit.edu.cn/myStudy/folder.2007-02-10.3253989707/document.2008-06-27.0224224197

 

Http://support.microsoft.com/kb/242577/zh-cn

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.