http://www.debuglab.com/knowledge/dlgupdateui.html
Dialog Base俊 UpdateCommandUI Handler甫 崔磊.
1.夸距
MFC俊辑 Frame 扁馆狼 扩档绰 Menu, Toolbar殿捞 UpdateCammandUI Handler俊 悼累俊 蝶扼 Enable/Disable, Check惑怕啊 啊瓷茄单, Dialog 扁馆狼 扩档绰 捞繁 悼累捞 冈龙 臼嚼聪促. 恐衬搁 CFrameWnd俊绰 捞繁 扁瓷甸捞 备泅登绢 乐瘤父 CDialog俊绰 绝扁 锭巩涝聪促. 荤角 捞繁 扁瓷阑 持扁绰 奖瘤绰 臼嚼聪促. 历档 CFrameWnd狼 家胶甫 蝶扼啊焊搁辑 败快 舅酒陈嚼聪促. 捞 规过阑 荤侩窍搁 Dialog俊 乐绰 牧飘费鳖瘤 CmdUpdateUI Handler甫 悼累 矫懦 荐 乐嚼聪促.
2.夯巩
琴缴篮 WM_KICKIDLE捞扼绰 皋技瘤甫 贸府窍绰单 乐嚼聪促. 捞 皋技瘤绰 MSDN俊 UNDOCUMENT荤亲捞骨肺 茫酒毫档 绝阑 疤聪促. 捞抚栏肺焊搁 Idle惑怕俊 惯积登绰 皋技瘤涝聪促. 捞 何盒俊辑 Menu客 ToolBar 弊府绊 Control甸狼 惑怕甫 力绢窍搁邓聪促. Modal Dialog俊辑父 犬牢秦好瘤父 Modeless俊辑绰 酒流 犬牢 给秦好嚼聪促. 梅何茄 CDialogEx 努贰胶甫 惑加罐酒 荤侩窍搁 邓聪促.
3.抗力
//////////////4.曼绊
// DialogEx.H
// Implementation
protected:
virtual void OnUpdateCmdUI_Menu(CCmdTarget* pTarget,
BOOL bDisableIfNoHndler); // 眠啊
virtual void OnUpdateCmdUI_ToolBar(CCmdTarget* pTarget,
BOOL bDisableIfNoHndler); // 眠啊
// Generated message map functions
//{{AFX_MSG(CDialogEx)
//}}AFX_MSG
afx_msg LRESULT OnKickIdle(WPARAM , LPARAM ); // 眠啊
DECLARE_MESSAGE_MAP()
///////////////
// DialogEx.CPP
BEGIN_MESSAGE_MAP(CDialogEx, CDialog)
//{{AFX_MSG_MAP(CDialogEx)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
END_MESSAGE_MAP()
class CToolCmdUI : public CCmdUI // class private to this file !
{
public: // re-implementations only
virtual void Enable(BOOL bOn);
virtual void SetCheck(int nCheck);
virtual void SetText(LPCTSTR lpszText);
};
void CToolCmdUI::Enable(BOOL bOn)
{
m_bEnableChanged = TRUE;
CToolBar* pToolBar = (CToolBar*)m_pOther;
ASSERT(pToolBar != NULL);
ASSERT_KINDOF(CToolBar, pToolBar);
ASSERT(m_nIndex < m_nIndexMax);
UINT nNewStyle = pToolBar->GetButtonStyle(m_nIndex) & ~TBBS_DISABLED;
if (!bOn)
{
nNewStyle |= TBBS_DISABLED;
// WINBUG: If a button is currently pressed and then is disabled
// COMCTL32.DLL does not unpress the button, even after the mouse
// button goes up! We work around this bug by forcing TBBS_PRESSED
// off when a button is disabled.
nNewStyle &= ~TBBS_PRESSED;
}
ASSERT(!(nNewStyle & TBBS_SEPARATOR));
pToolBar->SetButtonStyle(m_nIndex, nNewStyle);
}
void CToolCmdUI::SetCheck(int nCheck)
{
ASSERT(nCheck >= 0 && nCheck <= 2); // 0=>off, 1=>on, 2=>indeterminate
CToolBar* pToolBar = (CToolBar*)m_pOther;
ASSERT(pToolBar != NULL);
ASSERT_KINDOF(CToolBar, pToolBar);
ASSERT(m_nIndex < m_nIndexMax);
UINT nNewStyle = pToolBar->GetButtonStyle(m_nIndex) &
~(TBBS_CHECKED | TBBS_INDETERMINATE);
if (nCheck == 1)
nNewStyle |= TBBS_CHECKED;
else if (nCheck == 2)
nNewStyle |= TBBS_INDETERMINATE;
ASSERT(!(nNewStyle & TBBS_SEPARATOR));
pToolBar->SetButtonStyle(m_nIndex, nNewStyle | TBBS_CHECKBOX);
}
void CToolCmdUI::SetText(LPCTSTR)
{
// ignore it
}
LRESULT CDialogEx::OnKickIdle(WPARAM wParam, LPARAM lParam)
{
OnUpdateCmdUI_Menu(this, TRUE);
OnUpdateCmdUI_ToolBar(this, TRUE);
UpdateDialogControls(this, FALSE);
return 0;
}
void CDialogEx::OnUpdateCmdUI_Menu(CCmdTarget* pTarget,
BOOL bDisableIfNoHndler)
{
CMenu* pMenu = GetMenu();
if (!pMenu)
return;
CCmdUI state;
for (UINT nIndex = 0; nIndex < pMenu->GetMenuItemCount(); nIndex++)
{
CMenu* pSubMenu = pMenu->GetSubMenu(nIndex);
state.m_nIndexMax = pSubMenu->GetMenuItemCount();
for (UINT i = 0; i < state.m_nIndexMax; i++)
{
state.m_nIndex = i;
state.m_nID = pSubMenu->GetMenuItemID(i);
state.m_pMenu = pSubMenu;
state.DoUpdate(pTarget, bDisableIfNoHndler);
}
}
}
void CDialogEx::OnUpdateCmdUI_ToolBar(CCmdTarget* pTarget,
BOOL bDisableIfNoHndler)
{
CToolBar *pToolBar = (CToolBar*)GetDlgItem(AFX_IDW_TOOLBAR);
if (!pToolBar)
return;
CToolCmdUI state;
state.m_pOther = pToolBar;
state.m_nIndexMax = pToolBar->GetToolBarCtrl().GetButtonCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++)
{
// get buttons state
TBBUTTON button;
pToolBar->GetToolBarCtrl().GetButton(state.m_nIndex, &button);
state.m_nID = button.idCommand;
// ignore separators
if (!(button.fsStyle & TBSTYLE_SEP))
{
// allow reflections
if (pToolBar->OnCmdMsg(0,
MAKELONG((int)CN_UPDATE_COMMAND_UI,
WM_COMMAND+WM_REFLECT_BASE), &state, NULL))
continue;
// allow the toolbar itself to have update handlers
if (pToolBar->OnCmdMsg(state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL))
continue;
// allow the owner to process the update
state.DoUpdate(this, TRUE);
}
}
}
Coduguru, MFC 家胶