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



Copyright 2015 QuinStreet Inc. All Rights Reserved.