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

📄 dockingwindow.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 2 页
字号:
		virtual void Release(HWND /*hWnd*/){};
		virtual void Hot(HWND /*hWnd*/){}
	};

	class CBtnClickTracker : public CDDTrackerBaseT<CBtnClickTracker>
	{
	public:
		CBtnClickTracker(HWND hWnd,CButton& btn)
			:m_hWnd(hWnd),m_btn(btn)
		{
		}
		void BeginDrag()
		{
			m_btn.Press(m_hWnd);
		}
		void EndDrag(bool /*bCanceled*/)
		{
			m_btn.Release(m_hWnd);
		}
	protected:
		HWND		m_hWnd;
		CButton&	m_btn;
	};
protected:
	template<class T>
	class CHotBtnTracker : public CDDTrackerBaseT<CHotBtnTracker<T> >
	{
	public:
		CHotBtnTracker(CButton& btn,T& owner,HWND hWnd,int nHotHitTest)
			:m_btn(btn),m_owner(owner),m_hWnd(hWnd),m_nHotHitTest(nHotHitTest),m_bDoAction(false)
		{
			CRect rc;
			::GetClientRect(m_hWnd,&rc);
			m_offset.x=rc.left;
			m_offset.y=rc.top;
			::ClientToScreen(m_hWnd,&m_offset);
			::GetWindowRect(hWnd,&rc);
			m_offset.x-=rc.left;
			m_offset.y-=rc.top;
		}
		void BeginDrag()
		{
			m_btn.Hot(m_hWnd);
		}
		void EndDrag(bool /*bCanceled*/)
		{
			m_btn.Release(m_hWnd);
		}

		void OnDropLeftButton(long x, long y)
		{
			CPoint pt(x+m_offset.x,y+m_offset.y);
			m_bDoAction=(m_owner.HitTest(pt)==m_nHotHitTest);

		}
		void OnMove(long x, long y)
		{
			CPoint pt(x+m_offset.x,y+m_offset.y);
			if(m_owner.HitTest(pt)!=m_nHotHitTest)
				::ReleaseCapture();
		}
		bool ProcessWindowMessage(MSG* pMsg)
		{
			bool bRes=false;
			bRes=(pMsg->message==WM_LBUTTONDOWN);
			if(bRes)
				m_btn.Press(m_hWnd);
			return bRes;
		}

		operator bool () const
		{
			return m_bDoAction;
		}
	protected:
		bool		m_bDoAction;
		CPoint		m_offset;
		T&			m_owner;
		CButton&	m_btn;
		HWND		m_hWnd;
		int			m_nHotHitTest;
	};
public:
	CCaptionBase(bool bHorizontal=true)
		:COrientedRect(bHorizontal,::GetSystemMetrics(SM_CYSMCAPTION))
	{
	}
	CCaptionBase(unsigned long thickness,bool bHorizontal=true)
		:COrientedRect(bHorizontal,thickness)
	{
	}

	bool CalculateRect(CRect& rc,bool bTop)
	{
		return baseClass::CalculateRect(rc,bTop);
	}
	LRESULT HitTest(const CPoint& /*pt*/) const
	{
		return HTNOWHERE;
	}
	void Draw(HWND /*hWnd*/,CDC& dc)
	{
		dc.FillRect(this,(HBRUSH)LongToPtr(COLOR_3DFACE + 1));
	}
	bool OnAction(HWND hWnd,unsigned int nHitTest)
	{
		return HotTrack(hWnd,nHitTest);
	}
	bool HotTrack(HWND /*hWnd*/,unsigned int /*nHitTest*/)
	{
		return false;
	}
	void UpdateMetrics()
	{
		// Override in derived class if it depends on system metrics
	}
};


template <class TCaption,DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0>
struct CDockingWindowTraits : CDockingBarWinTraits<t_dwStyle,t_dwExStyle>
{
	typedef TCaption CCaption;
};

typedef CDockingWindowTraits<CCaptionBase,WS_OVERLAPPEDWINDOW | WS_POPUP/* WS_CHILD*/ | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,WS_EX_TOOLWINDOW/* WS_EX_CLIENTEDGE*/> CEmptyTitleDockingWindowTraits;

template <class T,
          class TBase = CWindow,
          class TDockingWinTraits = CEmptyTitleDockingWindowTraits>
class ATL_NO_VTABLE CTitleDockingWindowBaseImpl :
	public CDockingWindowBaseImpl< T, TBase, TDockingWinTraits >
{
    typedef CDockingWindowBaseImpl< T, TBase, TDockingWinTraits >		baseClass;
    typedef CTitleDockingWindowBaseImpl< T, TBase, TDockingWinTraits >	thisClass;
protected:
	typedef typename TDockingWinTraits::CCaption	CCaption;
public:
	LRESULT NcHitTest(const CPoint& pt)
	{
		LRESULT lRes=m_caption.HitTest(pt);
		if(lRes==HTNOWHERE)
				lRes=HTCLIENT;
		else
		{
			if(GetCapture()==NULL)
				m_caption.HotTrack(m_hWnd,lRes);
		}
		return lRes;
	}

	void GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
	{
		long width=m_caption.GetThickness();
		if(pMinMaxInfo->ptMinTrackSize.y<width)
			pMinMaxInfo->ptMinTrackSize.y=width;
		if(pMinMaxInfo->ptMinTrackSize.x<width)
			pMinMaxInfo->ptMinTrackSize.x=width;
	}

	void NcCalcSize(CRect* pRc)
	{
		DWORD style = GetWindowLong(GWL_STYLE);
		if((style&WS_CAPTION)==0)
			m_caption.SetRectEmpty();
		else
			m_caption.CalculateRect(*pRc,true);
	}
	void NcDraw(CDC& dc)
	{
		DWORD style = GetWindowLong(GWL_STYLE);
		if((style&WS_CAPTION)!=0)
			m_caption.Draw(m_hWnd,dc);
	}
	void OnDocked(HDOCKBAR hBar,bool bHorizontal)
	{
		m_caption.SetOrientation(!bHorizontal);
		baseClass::OnDocked(hBar,bHorizontal);
	}
	void OnUndocked(HDOCKBAR hBar)
	{
		m_caption.SetOrientation(true);
		baseClass::OnUndocked(hBar);
	}
	bool CloseBtnPress()
	{
		PostMessage(WM_CLOSE);
		return false;
	}
#ifdef DF_AUTO_HIDE_FEATURES
	bool PinUp(const CDockingSide& side)
	{
		CRect rc;
		GetWindowRect(&rc);
		T* pThis=static_cast<T*>(this);
		assert(rc.Width()>0);
		assert(rc.Height()>0);
		return pThis->PinUp(side,(side.IsHorizontal() ? rc.Width() : rc.Height()));
	}

	bool PinUp(const CDockingSide& side,unsigned long width,bool bVisualize=false)
	{
		if(IsDocking())
					Undock();
		DFPINUP pinHdr;
		pinHdr.hdr.hWnd=m_hWnd;
		pinHdr.hdr.hBar=GetOwnerDockingBar();
//		pinHdr.hdr.code=DC_PINUP;
		pinHdr.dwDockSide=side;
		pinHdr.nWidth=width;
		pinHdr.dwFlags= bVisualize ? DFPU_VISUALIZE : 0 ;
		pinHdr.n=0;
		return m_docker.PinUp(&pinHdr);
	}

	bool PinBtnPress()
	{
		assert(IsDocking());
		DFDOCKPOS dockHdr;
//		dockHdr.hdr.code=DC_GETDOCKPOSITION;
		dockHdr.hdr.hWnd=m_hWnd;
		dockHdr.hdr.hBar=GetOwnerDockingBar();
		bool bRes=GetDockingPosition(&dockHdr);
		if(bRes)
		{
			bRes=Undock();
			if(bRes)
			{
				T* pThis=static_cast<T*>(this);
				bRes=pThis->PinUp(CDockingSide(dockHdr.dwDockSide),dockHdr.nWidth,true);
			}
		}
		return bRes;
	}
#endif
protected:
	BEGIN_MSG_MAP(thisClass)
		if(IsDocking())
		{
			MESSAGE_HANDLER(WM_WINDOWPOSCHANGING,OnWindowPosChanging)
			MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize)
			MESSAGE_HANDLER(WM_NCACTIVATE, OnNcActivate)
			MESSAGE_HANDLER(WM_NCHITTEST,OnNcHitTest)
			MESSAGE_HANDLER(WM_NCPAINT,OnNcPaint)
			MESSAGE_HANDLER(WM_SETTEXT,OnCaptionChange)
			MESSAGE_HANDLER(WM_SETICON,OnCaptionChange)
			MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown)
			MESSAGE_HANDLER(WM_NCLBUTTONUP,OnNcLButtonUp)
			MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK,OnNcLButtonDblClk)
#ifdef DF_FOCUS_FEATURES
			assert(CDockingFocusHandler::This());
			CHAIN_MSG_MAP_ALT_MEMBER((*CDockingFocusHandler::This()),0)
#endif
		}
		MESSAGE_HANDLER(WM_GETMINMAXINFO,OnGetMinMaxInfo)
		MESSAGE_HANDLER(WM_SETTINGCHANGE,OnSettingChange)
		MESSAGE_HANDLER(WM_SYSCOLORCHANGE,OnSettingChange/*OnSysColorChange*/)
		CHAIN_MSG_MAP(baseClass)
	END_MSG_MAP()

	LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		T* pThis=static_cast<T*>(this);
		LRESULT lRes=pThis->DefWindowProc(uMsg,wParam,lParam);
		pThis->GetMinMaxInfo(reinterpret_cast<LPMINMAXINFO>(lParam));
		return lRes;
	}

	LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		if(!IsDocking())
		{
			// If we're floating, we're a top level window.
			// We might be getting this message before the main frame
			// (which is also a top-level window).
			// The main frame handles this message, and refreshes
			// system settings cached in CDWSettings.  In case we
			// are getting this message before the main frame,
			// update these cached settings (so that when we update
			// our caption's settings that depend on them,
			// its using the latest).
			CDWSettings settings;
			settings.Update();

			// In addition, because we are a top-level window,
			// we should be sure to send this message to all our descendants
			// in case there are common controls and other windows that
			// depend on cached system metrics.
			this->SendMessageToDescendants(uMsg, wParam, lParam, TRUE);
		}

		m_caption.UpdateMetrics();

		T* pThis=static_cast<T*>(this);
		pThis->SetWindowPos(NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

		bHandled = FALSE;
		return 1;
	}
/*
	LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		return 0;
	}
*/
	LRESULT OnWindowPosChanging(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		return NULL;
	}

	LRESULT OnNcActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled=IsWindowEnabled();
		return TRUE;
	}

	LRESULT OnNcCalcSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
        T* pThis=static_cast<T*>(this);
		CRect* pRc=reinterpret_cast<CRect*>(lParam);
		CPoint ptTop(pRc->TopLeft());
		(*pRc)-=ptTop;
		pThis->NcCalcSize(pRc);
		(*pRc)+=ptTop;
		return NULL;
	}

	LRESULT OnNcHitTest(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
        T* pThis=static_cast<T*>(this);
		CRect rcWnd;
		GetWindowRect(&rcWnd);
		pt.x-=rcWnd.TopLeft().x;
		pt.y-=rcWnd.TopLeft().y;
		return pThis->NcHitTest(pt);
	}
//OnSetIcon
//OnSetText
	LRESULT OnCaptionChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
//		LockWindowUpdate();
		DWORD style = ::GetWindowLong(m_hWnd,GWL_STYLE);
		::SetWindowLong(m_hWnd, GWL_STYLE, style&(~WS_CAPTION));
		LRESULT lRes=DefWindowProc(uMsg,wParam,lParam);
		::SetWindowLong(m_hWnd, GWL_STYLE, style);
		T* pThis=static_cast<T*>(this);
		pThis->SetWindowPos(NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
//		CWindowDC dc(m_hWnd);
//		pThis->NcDraw(dc);
//		LockWindowUpdate(FALSE);
		return lRes;
	}
	LRESULT OnNcPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		CWindowDC dc(m_hWnd);
		T* pThis=static_cast<T*>(this);
		pThis->NcDraw(dc);
		return NULL;
	}

	LRESULT OnNcLButtonDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled=m_caption.OnAction(m_hWnd,wParam);
        return !bHandled;
	}

	LRESULT OnNcLButtonUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		T* pThis=static_cast<T*>(this);
		switch(wParam)
		{
			case HTCLOSE:
				bHandled=pThis->CloseBtnPress();
				break;
#ifdef DF_AUTO_HIDE_FEATURES
			case HTPIN:
				bHandled=pThis->PinBtnPress();
				break;
#endif
			default:
				bHandled=FALSE;
		}
        return 0;
	}
	LRESULT OnNcLButtonDblClk(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		return 0;
	}
protected:
	CCaption	m_caption;
};

template <class T,
          class TBase = CWindow,
          class TDockingWinTraits = CEmptyTitleDockingWindowTraits>
class ATL_NO_VTABLE CTitleDockingWindowImpl
			: public CTitleDockingWindowBaseImpl< T, TBase, TDockingWinTraits >
{
    typedef CTitleDockingWindowBaseImpl< T, TBase, TDockingWinTraits >	baseClass;
    typedef CTitleDockingWindowImpl< T, TBase, TDockingWinTraits >		thisClass;
public:
	CTitleDockingWindowImpl()
	{
		m_pos.hdr.hBar=HNONDOCKBAR;
	}
	virtual bool Undock()
	{
		assert(IsDocking());
		GetDockingPosition(&m_pos);
		return baseClass::Undock();
	}
	virtual bool Hide()
	{
		bool bRes=true;
		if(IsDocking())
		{
			bRes=GetDockingPosition(&m_pos);
			assert(bRes);
			if(bRes)
			//	bRes=Undock();
				bRes=Float(&m_rcUndock,SWP_HIDEWINDOW);
			assert(bRes);
		}
		else
			m_pos.hdr.hBar=HNONDOCKBAR;
		return (bRes && ShowWindow(SW_HIDE));
	}
	virtual bool Show()
	{
		bool bRes=true;
		if(m_pos.hdr.hBar!=HNONDOCKBAR)
			bRes=SetDockingPosition(&m_pos);
		else
			ShowWindow(SW_SHOW);
		assert(bRes);
		return bRes;
	}

	bool Toggle()
	{
		bool bRes=(static_cast<T*>(this)->IsWindowVisible()!=FALSE);
		if(bRes)
		{
			Hide();
			::SetFocus(::GetParent (m_hWnd));
		}
		else
			Show();
		return bRes;
	}
	bool GetDockingWindowPlacement(DFDOCKPOSEX* pHdr) const
	{
		bool bRes=baseClass::GetDockingWindowPlacement(pHdr);
		pHdr->bVisible=static_cast<const T*>(this)->IsWindowVisible();
		if( (!pHdr->bDocking
			  || (!pHdr->bVisible) )
			  /*&& (m_pos.hdr.hBar!=HNONDOCKBAR)*/)
			::CopyMemory(&pHdr->dockPos,&m_pos,sizeof(DFDOCKPOS));
		return bRes;
	}
	bool SetDockingWindowPlacement(DFDOCKPOSEX* pHdr)
	{
		bool bRes=true;
		pHdr->dockPos.hdr.hWnd=m_hWnd;
		::CopyMemory(&m_pos,&(pHdr->dockPos),sizeof(DFDOCKPOS));
		if(pHdr->bVisible)
			bRes=baseClass::SetDockingWindowPlacement(pHdr);
		else
		{
			if(IsDocking())
						Undock();
			::CopyRect(&m_rcUndock,&pHdr->rect);
			bRes=(SetWindowPos(NULL,&m_rcUndock,SWP_NOZORDER | SWP_HIDEWINDOW |
													SWP_NOACTIVATE )!=FALSE);
		}
		return bRes;
	}

	bool CanBeClosed(unsigned long /*param*/)
	{
		Hide();
		return false;
	}

	BEGIN_MSG_MAP(thisClass)
		MESSAGE_HANDLER(WM_CLOSE, OnClose)
		MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClk)
		CHAIN_MSG_MAP(baseClass)
	END_MSG_MAP()

	LRESULT OnClose(UINT /*uMsg*/, WPARAM wParam, LPARAM/* lParam*/, BOOL& bHandled)
	{
		bHandled=!(static_cast<T*>(this)->CanBeClosed(wParam));
		return 0;
	}
	LRESULT OnNcLButtonDblClk(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		if(wParam==HTCAPTION)
		{
			if(IsDocking())
				Float();
			else
			{
				if(m_pos.hdr.hBar!=HNONDOCKBAR)
					SetDockingPosition(&m_pos);
			}
		}
		return 0;
	}
protected:
	DFDOCKPOS m_pos;
};

#define COMMAND_TOGGLE_MEMBER_HANDLER(id, member) \
	if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
	{ \
		member.Toggle(); \
	}

//please don't use CStateKeeper class anymore!
//this class is obsolete and provided only for compatibility with previous versions.
//the CTitleDockingWindowImpl class provide all functionality of CStateKeeper
template<class T>
struct CStateKeeper : public T
{
};

//please don't use CTitleExDockingWindowImpl class anymore!
//this class is obsolete and provided only for compatibility with previous versions.
//the CTitleDockingWindowImpl class provide all functionality of CTitleExDockingWindowImpl
template <class T,
          class TBase = CWindow,
          class TDockingWinTraits = CEmptyTitleDockingWindowTraits>
struct ATL_NO_VTABLE CTitleExDockingWindowImpl : CTitleDockingWindowImpl< T, TBase, TDockingWinTraits >
{
};

}//namespace dockwins
#endif // __WTL_DW__DOCKINGWINDOW_H__

⌨️ 快捷键说明

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