FAQ:WinAPI VCPP:OnUpdate для пунктов меню

Материал из Весельчак У
Версия от 15:35, 3 октября 2009; RXL (обсуждение | вклад) (Новая: ===Почему не вызывается OnUpdate для пунктов меню (не получается ни затенить, ни отметку поставить)?=== В диа...)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Почему не вызывается OnUpdate для пунктов меню (не получается ни затенить, ни отметку поставить)?

В диалоге (CDialog) у меню апдейт не происходит сам, в отличие от мейнфрейма (CFrameWnd). Для этого нужно сделать апдейт самим, в обработчике сообщения WM_KICKIDLE.

Визардом этот обработчик не добавляется, поэтому можно переопределить виртуальную DefWindowProc() и там обработать:

// этот файл надо включить, там определёна WM_KICKIDLE
#include <afxpriv.h>
 
LRESULT CMyDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	if (message == WM_KICKIDLE)
	{
		// делаем апдейт для всех пунктов меню
		CMenu* pMainMenu = GetMenu();
		if (pMainMenu)
		{
			CCmdUI cmdUI;
			for (UINT n = 0; n < pMainMenu->GetMenuItemCount(); n++)
			{
				CMenu* pSubMenu=pMainMenu->GetSubMenu(n);
				if (!pSubMenu)
					continue;
 
				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 CDialog::DefWindowProc(message, wParam, lParam);
}