Using ON_UPDATE_COMMAND_UI with menu items and controls (2) | CodeGuru

Using ON_UPDATE_COMMAND_UI with menu items and controls (2)

–>  If you have a dialog-based application, to which you have added a menu, any OnUpdate handlers that you included in the dialog’s message map will never be called.  (Note that the corresponding OnCommand handlers work fine). By handling the dialog’s WM_KICKIDLE message, and mimicking MFC’s routing of its UPDATE_UI messages, you can implement this […]

Written By
CodeGuru Staff
CodeGuru Staff
Nov 11, 1998
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

–>

 If you have a dialog-based application, to which you have added a menu, any OnUpdate
handlers that you included in the dialog’s message map will never be called.  (Note that
the corresponding OnCommand handlers work fine).

By handling the dialog’s WM_KICKIDLE message, and mimicking MFC’s routing of its
UPDATE_UI messages, you can implement this with a little work.

The first step is to handle WM_KICKIDLE, which is #defined in afxpriv.h, by declaring
OnKickIdle(), and adding it to the message map.

//[in TESTDLG.H]
class CTestDlg : public CDialog
{
 . . .
 // Generated message map functions
 //{{AFX_MSG(CTestDlg)
 . . .
 //}}AFX_MSG
 afx_msg LRESULT OnKickIdle(WPARAM, LPARAM);
 DECLARE_MESSAGE_MAP()
 . . .
};
#include "stdafx.h"
#include "TestDlg.h"
#include <afxpriv.h>
. . . 
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
 //{{AFX_MSG_MAP(CTestDlg)
 . . .
 //}}AFX_MSG_MAP
 ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
END_MESSAGE_MAP()

The real work comes in defining OnKickIdle(). You need to
iterate over each item that might have an OnUpdate handler, set up a CCmdUI instance for
that item, and call CCmdUI::DoUpdate().  The OnKickIdle() I have written will update
the menu items in each of the first-level dropdown menus (e.g. the "File" menu,
the "Edit" menu, etc. from a normal app).  You will need to modify it if you
have further levels of submenus.  You will need a similar loop if you want to have
OnUpdate handlers for a status bar, toolbar, or specific dialog controls.

LRESULT CTestDlg::OnKickIdle(WPARAM, LPARAM)
{
 CMenu* pMainMenu = GetMenu();
 CCmdUI cmdUI;
 for (UINT n = 0; n < pMainMenu->GetMenuItemCount(); ++n)
 {
  CMenu* pSubMenu = pMainMenu->GetSubMenu(n);
  cmdUI.m_nIndexMax = pSubMenu->GetMenuItemCount();
  for (UINT i = 0; i < cmdUI.m_nIndexMax;++i)
  {
   cmdUI.m_nIndex = i;
   cmdUI.m_nID = pSubMenu->GetMenuItemID(i);
   cmdUI.m_pMenu = pSubMenu;
   cmdUI.DoUpdate(this, FALSE);
  }
 }
 return TRUE;
}

Download demo project – 10 KB

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.