📄 mtlupdatecmdui.h
字号:
m_bEnableChanged = false;
BOOL bResult = pUpdateCmdUI->OnCmdMsg(m_nID, CN_UPDATE_COMMAND_UI, this, NULL);
if (!bResult)
ATLASSERT(!m_bEnableChanged); // not routed
if (bDisableIfNoHndler && !m_bEnableChanged)
{
AFX_CMDHANDLERINFO info;
info.pTarget = NULL;
BOOL bHandler = pTarget->OnCmdMsg(m_nID, CN_COMMAND, this, &info);
// Enable or Disable based on whether there is a handler there
Enable(bHandler);
}
return bResult;
}
*/
};
class CToolCmdUI : public CCmdUI // class private to this file !
{
public: // re-implementations only
virtual void Enable(bool bOn = true)
{
// ATLTRACE2(atlTraceUser, 4, _T("CToolCmdUI::Enable (%d:%d)\n"), m_wndOther.m_hWnd, m_nIndex);
// m_bEnableChanged = true;
CToolBarCtrl toolbar = m_wndOther.m_hWnd;
ATLASSERT(m_nIndex < m_nIndexMax);
UINT nOldState = toolbar.GetState(m_nID);
UINT nNewState = nOldState;
ATLASSERT(nNewState != -1);
if (!bOn)
{
nNewState &= ~TBSTATE_ENABLED;
// 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.
nNewState &= ~TBSTATE_CHECKED;
}
else {
nNewState |= TBSTATE_ENABLED;
}
if (nNewState != nOldState) {
MTLVERIFY(toolbar.SetState(m_nID, nNewState));
}
}
virtual void SetCheck(int nCheck = 1)
{
ATLASSERT(nCheck >= 0 && nCheck <= 2); // 0=>off, 1=>on, 2=>indeterminate
CToolBarCtrl toolbar = m_wndOther.m_hWnd;
ATLASSERT(m_nIndex < m_nIndexMax);
CVersional<TBBUTTONINFO> tbb;
tbb.dwMask = TBIF_STATE | TBIF_STYLE;
MTLVERIFY( toolbar.GetButtonInfo(m_nID, &tbb) != -1 );
BYTE fsNewState = tbb.fsState &
~(TBSTATE_CHECKED | TBSTATE_INDETERMINATE);
if (nCheck == 1)
fsNewState |= TBSTATE_CHECKED;
else if (nCheck == 2)
fsNewState |= TBSTATE_INDETERMINATE;
BYTE fsNewStyle = tbb.fsStyle | TBSTYLE_CHECK;// add a check style
bool bUpdate = false;
if (tbb.fsState != fsNewState) {
bUpdate = true;
tbb.fsState = fsNewState;
}
if (tbb.fsStyle != fsNewStyle) {
bUpdate = true;
tbb.fsStyle = fsNewStyle;
}
else {
tbb.dwMask = TBIF_STATE;// update only state
}
if (bUpdate) {
MTLVERIFY(toolbar.SetButtonInfo(m_nID, &tbb/* | TBBS_CHECKBOX*/));
}
}
virtual void SetText(LPCTSTR lpszText)
{
// ignored it.
}
virtual void SetDefault(bool bOn = true)
{
// ignored it.
}
};
class CUpdateCmdUIBase
{
public:
static bool s_bAutoMenuEnable;// not supported yet
DECLARE_REGISTERED_MESSAGE(Mtl_Update_CmdUI_Message)
static BOOL ProcessCmdUIToWindow(HWND hWnd, UINT nID, CCmdUI* pCmdUI)
{
return (BOOL)::SendMessage(hWnd, GET_REGISTERED_MESSAGE(Mtl_Update_CmdUI_Message),
(WPARAM)nID, (LPARAM)pCmdUI);
}
};
__declspec(selectany) bool CUpdateCmdUIBase::s_bAutoMenuEnable = true;
template <class T>
class CUpdateCmdUIHandler : public CUpdateCmdUIBase
{
public:
BEGIN_MSG_MAP(CUpdateCmdUIHandler)
MESSAGE_HANDLER(GET_REGISTERED_MESSAGE(Mtl_Update_CmdUI_Message), OnUpdateCommandUI)
END_MSG_MAP()
LRESULT OnUpdateCommandUI(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLASSERT(uMsg == GET_REGISTERED_MESSAGE(Mtl_Update_CmdUI_Message));
UINT nID = (UINT)wParam;
CCmdUI* pCmdUI = (CCmdUI*)lParam;
T* pT = static_cast<T*>(this);
return pT->ProcessCmdUIMap(nID, pCmdUI);
}
};
template <class T>
class CUpdateCmdUI : public CUpdateCmdUIBase
{
public:
// Data members
CSimpleArray<HWND> m_arrToolBar;
// Constructor
CUpdateCmdUI()
{
}
// Methods
void CmdUIAddToolBar(HWND hWndToolBar)
{
m_arrToolBar.Add(hWndToolBar);
}
// Message map and handlers
BEGIN_MSG_MAP(CUpdateCmdUI)
MESSAGE_HANDLER(WM_COMMAND, OnCommand)
MSG_WM_INITMENUPOPUP(OnInitMenuPopup)
MESSAGE_HANDLER(GET_REGISTERED_MESSAGE(Mtl_Update_CmdUI_Message), OnUpdateCommandUI)
END_MSG_MAP()
LRESULT OnCommand(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{// a service to avoid a tool bar button's flicker
bHandled = FALSE;
HWND hWndCtl = (HWND)lParam;
if (hWndCtl != NULL && m_arrToolBar.Find(hWndCtl) != -1) {
::UpdateWindow(hWndCtl);
}
return 0;
}
void OnInitMenuPopup(HMENU hmenuPopup, UINT uPos, BOOL fSystemMenu)
{
SetMsgHandled(FALSE);
CmdUIUpdateMenuBar(hmenuPopup);
}
LRESULT OnUpdateCommandUI(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
UINT nID = (UINT)wParam;
CCmdUI* pCmdUI = (CCmdUI*)lParam;
T* pT = static_cast<T*>(this);
return pT->ProcessCmdUIMap(nID, pCmdUI);
}
BOOL _DoUpdate(CCmdUI* pCmdUI, bool bDisableIfNoHndler)
{
if (/*pCmdUI->m_nID == 0 || */LOWORD(pCmdUI->m_nID) == 0xFFFF)
return TRUE; // ignore invalid IDs
// pCmdUI->m_bEnableChanged = false;
T* pT = static_cast<T*>(this);
BOOL bResult = pT->ProcessCmdUIMap(pCmdUI->m_nID, pCmdUI);
// if (!bResult)
// ATLASSERT(!pCmdUI->m_bEnableChanged); // not routed
// if (bDisableIfNoHndler && !pCmdUI->m_bEnableChanged && !bResult)
// {
// Enable or Disable based on whether there is a handler there
// }
return bResult;
}
void CmdUIUpdateMenuBar(CMenuHandle menuPopup)
{
CCmdUI state;
state.m_menu = menuPopup.m_hMenu;
ATLASSERT(state.m_wndOther.m_hWnd == NULL);
state.m_nIndexMax = menuPopup.GetMenuItemCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++)
{
state.m_nID = menuPopup.GetMenuItemID(state.m_nIndex);
if (state.m_nID == 0)
continue; // menu separator or invalid cmd - ignore it
ATLASSERT(state.m_wndOther.m_hWnd == NULL);
ATLASSERT(state.m_menu.m_hMenu != NULL);
if (state.m_nID == (UINT)-1)
{
// possibly a popup menu, route to first item of that popup
state.m_menuSub = menuPopup.GetSubMenu(state.m_nIndex);
if (state.m_menuSub.m_hMenu == NULL ||
(state.m_nID = state.m_menuSub.GetMenuItemID(0)) == 0 ||
state.m_nID == (UINT)-1)
{
continue; // first item of popup can't be routed to
}
_DoUpdate(&state, false); // popups are never auto disabled
}
else
{
// normal menu item
// Auto enable/disable if frame window has 's_bAutoMenuEnable'
// set and command is _not_ a system command.
state.m_menuSub = NULL;
_DoUpdate(&state, s_bAutoMenuEnable && state.m_nID < 0xF000);
}
// adjust for menu deletions and additions
UINT nCount = menuPopup.GetMenuItemCount();
if (nCount < state.m_nIndexMax)
{
state.m_nIndex -= (state.m_nIndexMax - nCount);
while (state.m_nIndex < nCount &&
menuPopup.GetMenuItemID(state.m_nIndex) == state.m_nID)
{
state.m_nIndex++;
}
}
state.m_nIndexMax = nCount;
}// for
}
void CmdUIUpdateToolBars()
{
for (int i = 0; i < m_arrToolBar.GetSize(); ++i) {
_CmdUIUpdateToolBar(m_arrToolBar[i]);
}
}
void _CmdUIUpdateToolBar(HWND hWndToolBar)
{
// ATLTRACE2(atlTraceUser, 4, _T("CUpdateCmdUI::_CmdUIUpdateToolBar\n"));
if (!::IsWindowVisible(hWndToolBar))
return;
CToolBarCtrl toolbar(hWndToolBar);
CToolCmdUI state;
state.m_wndOther = hWndToolBar;
state.m_nIndexMax = toolbar.GetButtonCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++)
{
// get buttons state
TBBUTTON button;
MTLVERIFY(toolbar.GetButton(state.m_nIndex, &button));
state.m_nID = button.idCommand;
// ignore separators
if (!(button.fsStyle & TBSTYLE_SEP))
{
// allow reflections
// if (CWnd::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 (CWnd::OnCmdMsg(state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL))
// continue;
// allow the owner to process the update
_DoUpdate(&state, false);
}
}
// update the dialog controls added to the toolbar
// UpdateDialogControls(pTarget, bDisableIfNoHndler);
}
void CmdUIUpdateChildWindow(HWND hWndContainer, int nID)
{
HWND hWndChild = ::GetDlgItem(hWndContainer, nID);
ATLASSERT(::IsWindow(hWndChild));
CCmdUI state;
state.m_wndOther = hWndChild;
state.m_nID = nID;
state.m_nIndexMax = 1;
_DoUpdate(&state, false);
}
void CmdUIUpdateStatusBar(HWND hWndStatusBar, int nPaneID)
{
CCmdUI state;
state.m_wndOther = hWndStatusBar;
state.m_nIndexMax = 1;
state.m_nID = nPaneID;
_DoUpdate(&state, false);
}
};
// Update Command UI Chaining Macros
#define CHAIN_UPDATE_COMMAND_UI_MEMBER(theChainMember) \
if (theChainMember.ProcessCmdUIMap(nID, pCmdUI)) \
return TRUE;
#define CHAIN_CLIENT_UPDATE_COMMAND_UI() \
if (ProcessCmdUIToWindow(m_hWndClient, nID, pCmdUI)) \
return TRUE;
#define CHAIN_MDI_CHILD_UPDATE_COMMAND_UI() \
{ \
HWND hWndActive = MDIGetActive(); \
if (hWndActive && ProcessCmdUIToWindow(hWndActive, nID, pCmdUI)) \
return TRUE; \
}
////////////////////////////////////////////////////////////////////////////
} //namespace MTL
#endif // __MTLUPDATECMDUI_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -