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).
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; }
Comments
Handling OnUpdate() processing for menu items
Posted by Legacy on 10/16/2001 12:00amOriginally posted by: Anonymous
How to do this for a CPropertyPage derived class ?????
Please help...
ReplySmaller, faster and efficient (I hope) K.I.S.S. in other word.
Posted by Legacy on 06/14/2001 12:00amOriginally posted by: Leonid Prokopovich
Avoid KickIdle,A simple way toUpdate!!
Posted by Legacy on 11/30/2000 12:00amOriginally posted by: Sreedharan
Re : Code hoards CPU time
Posted by Legacy on 11/02/2000 12:00amOriginally posted by: Yair Konfino
It`s true that the CPU is working hard in this case !!!
ReplySpy++ shows why .
WM_KICKIDLE is passed to the window thousands of times
repeatedly .
The solution is to use :
void OnKickIdle() and ON_MESSAGE_VOID(ID_XXXX,WM_KICKIDLE).
It`s working for me .
Updating popup menus
Posted by Legacy on 07/25/2000 12:00amOriginally posted by: Damian Biollo
Code hoards CPU time
Posted by Legacy on 03/02/2000 12:00amOriginally posted by: Clinton Morell
I found that the OnKickIdle() code tended to hoard CPU time on my computer and it was keeping other programs from getting enough CPU cycles.
Adding "Sleep(1)" at the beginning of the OnKickIdle() function fixed the problem for me, your mileage may vary.
ReplyHow to implement this for a toolbar control.
Posted by Legacy on 04/19/1999 12:00amOriginally posted by: Brandon Jackson
How to implement this for toolbar control?
Posted by Legacy on 04/15/1999 12:00amOriginally posted by: Andrey
I have a Tabbed Property sheet application.
The first Property page has a toolbar control and a list control. The list control has a popup menu with commands applied to it. It has ON_UPDATE_COMMAND_UI for these commands as it knows when to disable items.
I need that toolbar control that belongs to list's parent to duplicate the commands in the menu (including auto disabling).
Do you know how to implement this?
Thanks a lot!
Reply