Как правильно обработать UPDATE_COMMAND_UI
От: Ashen_Angel  
Дата: 29.04.04 15:34
Оценка:
Есть пункт меню, при клике на котором вызывается:

void CServerShellDlg::OnUpdateStatus(CCmdUI *pCmdUI)
{
if (ServerStarted)
{
pCmdUI->SetText("Close server");
} else {
pCmdUI->SetText("Start server");
}
}

Проблема видимо связана с моим незнанием, т.к. данный код не
работает. Мне естественно приходилось писать подобное, но
раньше всё было нормально. Есть подозрения на VC++ .NET 2003,
а точнее на не полное понимание того как это теперь функционирует.
Может, кто-нибудь знает как правильно написать?
Re: Как правильно обработать UPDATE_COMMAND_UI
От: Ashen_Angel  
Дата: 30.04.04 19:19
Оценка:
Странно, на 2-ом форуме спрашиваю и опять гробовое молчание. Вопрос вроде тривиальный.
Re: Как правильно обработать UPDATE_COMMAND_UI
От: Lone Беларусь  
Дата: 01.05.04 19:06
Оценка:
Здравствуйте, Ashen_Angel, Вы писали:

A_A>Есть пункт меню, при клике на котором вызывается:


A_A>void CServerShellDlg::OnUpdateStatus(CCmdUI *pCmdUI)

A_A>{
A_A> if (ServerStarted)
A_A> {
A_A> pCmdUI->SetText("Close server");
A_A> } else {
A_A> pCmdUI->SetText("Start server");
A_A> }
A_A>}

A_A>Проблема видимо связана с моим незнанием, т.к. данный код не

A_A>работает. Мне естественно приходилось писать подобное, но
A_A>раньше всё было нормально. Есть подозрения на VC++ .NET 2003,
A_A>а точнее на не полное понимание того как это теперь функционирует.
A_A>Может, кто-нибудь знает как правильно написать?

Насколько я понял, приложение диалоговое? Если да, то поищи ответы на свой вопрос в выпуске №21 рассылки этого сайта (там, кстати, ещё очень много интересного ). Если лень скачивать, то позволю себе процитировать ответ Александра Шаргина:

Когда Windows собирается отобразить всплывающее меню, она посылает сообщение WM_INITMENUPOPUP, чтобы программа могла на лету кое-что поменять: отключить некоторые пункты, расставить галочки и т. п. Поэтому базовый способ модификации всплывающих меню состоит в перехвате этого сообщения с последующим использованием функций EnableMenuItem, CheckMenuItem и т. п.

MFC предлагает альтернативный подход. С классе CFrameWnd есть готовый обработчик WM_INITMENUPOPUP, который инициализирует структуру CCmdUI для каждого пункта меню, после чего отправляет сообщение CN_UPDATE_COMMAND_UI, определённое в MFC, сперва классу представления, затем классу документа, затем классу главного окна и, наконец, классу приложения. Каждый из этих классов может внести свою лепту в инициализацию всплывающего меню. Можно инициировать этот процесс, вообще ничего не зная о CN_UPDATE_COMMAND_UI: достаточно вызвать CCmdUI::DoUpdate, и сообщеине дойдёт до написанных программистом обработчиков ON_UPDATE_COMMAND_UI.

Теперь внимание: класс диалога (CDialog) не имеет предопределённого обработчика WM_INITMENUPOPUP. Поэтому сообщения CN_UPDATE_COMMAND_UI никто не посылает, и обработчики ON_UPDATE_COMMAND_UI не вызываются. Необходимо вручную написать обработчик OnInitMenuPopup, воспроизведя в нём часть функциональности класса CFrameWnd. В простейшем случае он может выглядеть так:

void CMyDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
{ 
   if (!bSysMenu) 
   {
    CCmdUI state; 

    state.m_pMenu = pPopupMenu; 
    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); 
       state.m_pSubMenu = NULL; 
       state.DoUpdate(this, state.m_nID < 0xF000); 
      }
  } 
}

В случае когда всплывающее меню имеет подменю обработчик будет более сложным. За примером такого обработчика можно обратиться к исходным текстам программы DLGCBR32, которые находятся в MSDN.


A_A>Странно, на 2-ом форуме спрашиваю и опять гробовое молчание. Вопрос вроде тривиальный.


Так выходные ж
... << RSDN@Home 1.1.2 stable >>
Re[2]: Как правильно обработать UPDATE_COMMAND_UI
От: Ashen_Angel  
Дата: 01.05.04 19:23
Оценка:
Здравствуйте, Lone

Great thanks!!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.