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

📄 tabbedmdi.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 5 页
字号:
					}
					if((pWinPos->flags & SWP_NOSIZE) == 0)
					{
						pWinPos->cy -= nTabAreaHeight;
					}
				}
			}
		}

		// "base::OnWindowPosChanging()"
		LRESULT lRet = this->DefWindowProc(uMsg, wParam, lParam);
		bHandled = TRUE;

		return lRet;
	}

	LRESULT OnNcPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{

		if(m_bDrawFlat &&
			WS_EX_CLIENTEDGE == (this->GetExStyle() & WS_EX_CLIENTEDGE))
		{
			// When we have WS_EX_CLIENTEDGE and drawing "flat",
			// we'll paint the non-client edges ourself with a more flat look.
			// NOTE: If WS_EX_CLIENTEDGE ever takes up more than 2 pixels
			// on each edge, update the drawing code.

			WTL::CWindowDC dc(this->m_hWnd);
			if(dc)
			{
				RECT rcWindow;
				this->GetWindowRect(&rcWindow);
				::OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
				dc.DrawEdge(&rcWindow, EDGE_ETCHED, BF_FLAT|BF_RECT);
			}

			/*
			// Note: The documentation says the flags should be
			// DCX_WINDOW|DCX_INTERSECTRGN
			// but that wasn't working.
			// On http://freespace.virgin.net/james.brown7/tutorials/tips.htm
			// they mention you also need to OR in the flag "0x10000".
			CDCHandle dc = this->GetDCEx((HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN | 0x10000));
			if(!dc.IsNull())
			{
				RECT rcWindow;
				this->GetWindowRect(&rcWindow);
				::OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
				dc.DrawEdge(&rcWindow, EDGE_ETCHED, BF_FLAT|BF_RECT);

				::ReleaseDC(dc);
			}
			*/
			bHandled = TRUE;
		}
		else
		{
			bHandled = FALSE;
		}

		return 0;
	}

	LRESULT OnMDIDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		// NOTE: For symmetry, we could try to handle WM_MDICREATE
		//  for tab creation.  There are 2 reasons we don't:
		//   1. With WTL, the implementation doesn't use WM_MDICREATE,
		//      so it wouldn't be reliable to rely on it
		//   2. We don't need to.  Handling the change in child
		//      activation to display the tab, if its not there,
		//      creates, DisplayTab will create the corresponding tab. 

		// Remove the tab for the child being destroyed.
		//  Before removing the tab, we want the default happen,
		//  so that the MDI Client figures out who to activate next.
		//  If we removed the tab first, the "DeleteItem" on
		//  the tab wouldn't know the next best tab to select,
		//  and so if it's removing the tab that's currently selected,
		//  it changes the selection to 0.
		//  But by having the MDI client activate the child
		//  "next in line" (Z-Order), that child will be activated,
		//  and its tab will be selected, so that by the time we remove
		//  the tab for this child, the tab won't be selected.
		LRESULT lRet = this->DefWindowProc(uMsg, wParam, lParam);
		bHandled = TRUE;

		if(wParam != NULL)
		{
			m_MdiTabOwner.RemoveTab((HWND)wParam);
		}

		return lRet;
	}

	LRESULT OnChildActivationChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// NOTE: We'd like to just handle WM_MDIACTIVATE when sent to
		//  the MDI client to know when the active MDI child has changed.
		//  Unfortunately, you don't HAVE to send WM_MDIACTIVATE to the
		//  MDI Client to change the active child (such as clicking
		//  a different MDI child to activate it).
		//  However, the MDI *child* will *always* receive WM_MDIACTIVATE.
		//  In fact, the child losing focus gets WM_MDIACTIVATE, 
		//  and then the child gaining focus gets WM_MDIACTIVATE
		//  (the "deactivating" and "activating" windows are sent as
		//  the WPARAM and LPARAM both times).
		//  So we'll make the "activating" child window responsible for
		//  sending us a message (UWM_MDICHILDACTIVATIONCHANGE)
		//  when it gets a WM_MDIACTIVATE message.  We'll use this
		//  to display the tab (switching the selected tab to the
		//  corresponding tab, or creating a tab for the child and
		//  setting it as selected)

		if(wParam != NULL)
		{
			m_MdiTabOwner.DisplayTab((HWND)wParam, TRUE, m_bUseMDIChildIcon);
		}

		return 0;
	}

	LRESULT OnChildTabTextChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		// NOTE: Our direct children are Frame windows.
		//  We make the MDI child responsible for sending us a
		//  message (UWM_MDICHILDTABTEXTCHANGE) if they want to
		//  update the text of the corresponding tab.

		if(wParam != NULL)
		{
			m_MdiTabOwner.UpdateTabText((HWND)wParam, (LPCTSTR)lParam);
		}

		return 0;
	}

	LRESULT OnChildTabToolTipChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		//  We make the MDI child responsible for sending us a
		//  message (UWM_MDICHILDTABTOOLTIPCHANGE) with the tooltip
		//  if that tooltip is something different than the tab text.

		if(wParam != NULL)
		{
			m_MdiTabOwner.UpdateTabToolTip((HWND)wParam, (LPCTSTR)lParam);
		}

		return 0;
	}

	LRESULT OnChildMaximized(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		HWND hWndMaximized = (HWND)wParam;
		HWND hWndActiveChild = (HWND)this->SendMessage(WM_MDIGETACTIVE, 0, 0);
		if(hWndMaximized == hWndActiveChild)
		{
			m_MdiTabOwner.ShowTabControlIfChildMaximized();
		}
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnChildUnMaximized(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		HWND hWndUnMaximized = (HWND)wParam;
		HWND hWndActiveChild = (HWND)this->SendMessage(WM_MDIGETACTIVE, 0, 0);
		if(hWndUnMaximized == hWndActiveChild)
		{
			m_MdiTabOwner.HideTabControlIfChildNotMaximized();
		}
		bHandled = FALSE;
		return 0;
	}
};


template <class T, class TBase = CCommandBarCtrlBase, class TWinTraits = ATL::CControlWinTraits>
class ATL_NO_VTABLE CTabbedMDICommandBarCtrlImpl : public WTL::CMDICommandBarCtrlImpl<T, TBase, TWinTraits>
{
protected:
	typedef CTabbedMDICommandBarCtrlImpl thisClass;
	typedef CMDICommandBarCtrlImpl<T, TBase, TWinTraits> baseClass;
	typedef CCommandBarCtrlImpl<T, TBase, TWinTraits> grandparentClass;

// Extended data
protected:
	bool m_bUseMaxChildDocIconAndFrameCaptionButtons:1;

// Constructors
public:
	CTabbedMDICommandBarCtrlImpl() :
		m_bUseMaxChildDocIconAndFrameCaptionButtons(true)
	{
	}

// Public methods
public:
	void UseMaxChildDocIconAndFrameCaptionButtons(bool bUseMaxChildDocIconAndFrameCaptionButtons = true)
	{
		m_bUseMaxChildDocIconAndFrameCaptionButtons = bUseMaxChildDocIconAndFrameCaptionButtons;
	}

// Overrides
public:
	void GetSystemSettings()
	{
		baseClass::GetSystemSettings();
		m_cxLeft += 4;
	}

// Message Handling
public:
	BEGIN_MSG_MAP(thisClass)

		if(m_bUseMaxChildDocIconAndFrameCaptionButtons)
		{
			CHAIN_MSG_MAP(baseClass)
		}
		else
		{
			CHAIN_MSG_MAP(grandparentClass)
		}

	ALT_MSG_MAP(1)		// Parent window messages

		if(m_bUseMaxChildDocIconAndFrameCaptionButtons)
		{
			CHAIN_MSG_MAP_ALT(baseClass, 1)
		}
		else
		{
			CHAIN_MSG_MAP_ALT(grandparentClass, 1)
		}

	ALT_MSG_MAP(2)		// MDI client window messages

		MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu)

		if(m_bUseMaxChildDocIconAndFrameCaptionButtons)
		{
			MESSAGE_HANDLER(WM_MDIDESTROY, OnMDIDestroy)
			MESSAGE_HANDLER(UWM_MDICHILDMAXIMIZED, OnChildMaximized)
			MESSAGE_HANDLER(UWM_MDICHILDUNMAXIMIZED, OnChildUnMaximized)
		}
		// NOTE: If future implementations of CMDICommandBarCtrlImpl
		//  add MDI client related handlers for ALT_MSG_MAP(2),
		//  either add them here or chain to the base
	ALT_MSG_MAP(3)		// Message hook messages

		// NOTE: We don't want to depend on the command bar's
		//  hooked messages for telling us about maximization
		//  changes.  We can do the job with the normal
		//  MDI messages and our special MDI messages
		//MESSAGE_RANGE_HANDLER(0, 0xFFFF, OnAllHookMessages)
		CHAIN_MSG_MAP_ALT(grandparentClass, 3)

	END_MSG_MAP()

// MDI client window message handlers
	LRESULT OnMDISetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		m_wndMDIClient.DefWindowProc(uMsg, NULL, lParam);
		HMENU hOldMenu = GetMenu();
		BOOL bRet = AttachMenu((HMENU)wParam);
		bRet;   // avoid level 4 warning
		ATLASSERT(bRet);

#if (_WTL_VER >= 0x0710) && (_WIN32_IE >= 0x0400)
		T* pT = static_cast<T*>(this);
		pT->UpdateRebarBandIdealSize();
#endif //(_WTL_VER >= 0x0710) && (_WIN32_IE >= 0x0400)

		return (LRESULT)hOldMenu;
	}

	LRESULT OnMDIDestroy(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		HWND hWndChild = (HWND)wParam;

		if(m_hWndChildMaximized == hWndChild)
		{
			bool bMaxOld = m_bChildMaximized;
			HICON hIconOld = m_hIconChildMaximized;

			m_bChildMaximized = false;
			m_hWndChildMaximized = NULL;
			m_hIconChildMaximized = NULL;

			T* pT = static_cast<T*>(this);
			pT->RefreshMaximizedState((bMaxOld != m_bChildMaximized), (hIconOld != m_hIconChildMaximized));
		}

		bHandled = FALSE;
		return 0;
	}

	LRESULT OnChildMaximized(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		HWND hWndChild = (HWND)wParam;

		bool bMaxOld = m_bChildMaximized;
		HICON hIconOld = m_hIconChildMaximized;

		m_bChildMaximized = true;

		if(m_hWndChildMaximized != hWndChild)
		{
			ATL::CWindow wnd = m_hWndChildMaximized = hWndChild;
			m_hIconChildMaximized = wnd.GetIcon(FALSE);
			if(m_hIconChildMaximized == NULL)	// no icon set with WM_SETICON, get the class one
			{
// need conditional code because types don't match in winuser.h
#ifdef _WIN64
				m_hIconChildMaximized = (HICON)::GetClassLongPtr(wnd, GCLP_HICONSM);
				if(m_hIconChildMaximized == NULL)
				{
					m_hIconChildMaximized = (HICON) ::GetClassLongPtr(wnd, GCLP_HICON);
				}
#else
				m_hIconChildMaximized = (HICON)LongToHandle(::GetClassLongPtr(wnd, GCLP_HICONSM));
				if(m_hIconChildMaximized == NULL)
				{
					m_hIconChildMaximized = (HICON) LongToHandle(::GetClassLongPtr(wnd, GCLP_HICON));
				}
#endif
			}
		}

		T* pT = static_cast<T*>(this);
		pT->RefreshMaximizedState((bMaxOld != m_bChildMaximized), (hIconOld != m_hIconChildMaximized));

		bHandled = FALSE;
		return 0;
	}

	LRESULT OnChildUnMaximized(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		HWND hWndChild = (HWND)wParam;

		if(m_hWndChildMaximized == hWndChild)
		{
			bool bMaxOld = m_bChildMaximized;
			HICON hIconOld = m_hIconChildMaximized;

			m_bChildMaximized = false;
			m_hWndChildMaximized = NULL;
			m_hIconChildMaximized = NULL;

			T* pT = static_cast<T*>(this);
			pT->RefreshMaximizedState((bMaxOld != m_bChildMaximized), (hIconOld != m_hIconChildMaximized));
		}

		bHandled = FALSE;
		return 0;
	}

	void RefreshMaximizedState(bool bMaximizeChanged, bool bIconChanged)
	{
		// NOTE: This code comes out of CMDICommandBarCtrlImpl::OnAllHookMessages.
		//  If the base implementation changes, reflect those changes here.
		if(bMaximizeChanged)
		{
#ifdef _CMDBAR_EXTRA_TRACE
			ATLTRACE2(atlTraceUI, 0, "MDI CmdBar - All messages hook change: m_bChildMaximized = %s\n", m_bChildMaximized ? "true" : "false");
#endif
			// assuming we are in a rebar, change our size to accomodate new state
			// we hope that if we are not in a rebar, nCount will be 0
			int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L);
			int cxDiff = (m_bChildMaximized ? 1 : -1) * (m_cxLeft + m_cxRight);
			for(int i = 0; i < nCount; i++)
			{ 
#if (_WIN32_IE >= 0x0500)
				REBARBANDINFO rbi = { sizeof(REBARBANDINFO), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_STYLE };
				::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
				if(rbi.hwndChild == m_hWnd)
				{
					if((rbi.fStyle & RBBS_USECHEVRON) != 0)
					{
						rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
						rbi.cxMinChild += cxDiff;
						rbi.cxIdeal += cxDiff;
						::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
					}
					break;
				}
#elif (_WIN32_IE >= 0x0400)
				REBARBANDINFO rbi = { sizeof(REBARBANDINFO), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE };
				::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
				if(rbi.hwndChild == m_hWnd)
				{
					rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
					rbi.cxMinChild += cxDiff;
					rbi.cxIdeal += cxDiff;
					::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi);
					break;
				}
#else //(_WIN32_IE < 0x0400)
				REBARBANDINFO rbi = { sizeof(REBARBANDINFO), RBBIM_CHILD | RBBIM_CHILDSIZE };
				::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi);
				if(rbi.hwndChild == m_hWnd)
				{
					rbi.fMask = RBBIM_CHILDSIZE;
					rbi.cxMinChild += cxDiff;
					::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPAR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -