我想了解更多有关此系统如何工作的信息,特别是框架实际决定更新UI元素的时间和方式。
我的应用程序有一个“工具”系统,一次只能激活一个工具。我使用“ON_UPDATE_COMMAND_UI”消息来“检查”UI中工具的图标/按钮,这会影响应用程序菜单和工具栏。无论如何,在工作栏图标停止正确突出显示的最后几天,这一切都很有效。
我调查了一下,发现只有在实际点击图标时才会收到更新命令。奇怪的是,这只会影响工具栏,而不是菜单,它仍然可以正常工作。即使菜单中的按钮更新,工具栏图标也保持不变。
显然我已经做了一些事情来打破它 - 任何想法?
修改
没关系。我覆盖了应用程序的OnIdle()
方法,并且没有调用原始的基类方法 - 即CWinApp::OnIdle()
- 我猜这是大多数时候调用更新的地方。来自https://msdn.microsoft.com/en-us/library/3e077sxt.aspx的代码段说明了:
BOOL CMyApp::OnIdle(LONG lCount)
{
// CWinApp's original method is involved in the update message handling!
// Removing this call will break things
BOOL bMore = CWinApp::OnIdle(lCount);
if (lCount == 0)
{
TRACE(_T("App idle for short period of time\n"));
bMore = TRUE;
}
// ... do work
return bMore;
// return TRUE as long as there are any more idle tasks
}
答案 0 :(得分:3)
这是一个good article,它解释了如何做到这一点。不要将他的代码示例与WM_KICKIDLE一起使用,而是向下滚动到评论部分。有两个代码示例可以解释如何更好地完成它。我引用:
//Override WM_INITMENUPOPUP
void CDialog::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
// TODO: Add your message handler code here
if(pPopupMenu &&
!bSysMenu)
{
CCmdUI CmdUI;
CmdUI.m_nIndexMax = pPopupMenu->GetMenuItemCount();
for(UINT i = 0; i < CmdUI.m_nIndexMax; i++)
{
CmdUI.m_nIndex = i;
CmdUI.m_nID = pPopupMenu->GetMenuItemID(i);
CmdUI.m_pMenu = pPopupMenu;
// There are two options:
// Option 1. All handlers are in dialog
CmdUI.DoUpdate(this, FALSE);
// Option 2. There are handlers in dialog and controls
/*
CmdUI.DoUpdate( this, FALSE );
// If dialog handler doesn't change state route update
// request to child controls. The last DoUpdate will
// disable menu item with no handler
if( FALSE == CmdUI.m_bEnableChanged )
CmdUI.DoUpdate( m_pControl_1, FALSE );
...
if( FALSE == CmdUI.m_bEnableChanged )
CmdUI.DoUpdate( m_pControl_Last, TRUE );
*/
}
}
}
答案 1 :(得分:0)