⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtlupdatecmdui.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 2 页
字号:
		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 + -