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

📄 wndfrmpkg.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 3 页
字号:
								new CSplitterMoveTrackerGhost(hWnd,*this,pt,rc));
		else
			pTracker=std::auto_ptr<CSplitterMoveTrackerBase>(
								new CSplitterMoveTrackerFull(*this,pt,rc));

		bool bRes=false;
		if(const_iterator(*pTracker)!=m_frames.end())
			 bRes=TrackDragAndDrop(*pTracker,hWnd);
		return bRes;
	}
*/
	bool StartSliding(HWND hWnd,const CPoint& pt,const CRect& rc,bool bGhostMove)
	{
		bool bRes=false;
		position pos=IsHorizontal() ?pt.x :pt.y;
		const_iterator i=m_frames.locate(pos);
		if(i!=m_frames.end())
		{
			CEmbeddedSplitterBar splitter(!IsHorizontal(),(*i),rc);
			if(splitter.IsPtIn(pt))
			{
				std::auto_ptr<CSplitterMoveTrackerBase> pTracker;

				if(bGhostMove)
					pTracker=std::auto_ptr<CSplitterMoveTrackerBase>(
										new CSplitterMoveTrackerGhost(hWnd,*this,pt,rc));
				else
					pTracker=std::auto_ptr<CSplitterMoveTrackerBase>(
										new CSplitterMoveTrackerFull(hWnd,*this,pt,rc));

				if(const_iterator(*pTracker)!=m_frames.end())
					 bRes=TrackDragAndDrop(*pTracker,hWnd);
			}
		}
		return bRes;
	}

	bool UpdateLayout(const CRect& rc)
	{
		CBounds bounds;
        if(IsHorizontal())
        {
                bounds.low=rc.left;
                bounds.hi=rc.right;
        }
        else
        {
                bounds.low=rc.top;
                bounds.hi=rc.bottom;
        }
		bounds.low-=splitterSize;

		CBounds::distance_t limit=m_frames.distance_limit();
        if(bounds.distance()<limit)
                        bounds.hi=bounds.low+limit;
        m_frames.set_bounds(bounds);
		return Arrange(rc);
	}

	void GetMinFrameSize(const DFMHDR* pHdr,CSize& sz) const
	{
		MINMAXINFO mmInfo;
		ZeroMemory(&mmInfo,sizeof(MINMAXINFO));
		::SendMessage(pHdr->hWnd,WM_GETMINMAXINFO,NULL,reinterpret_cast<LPARAM>(&mmInfo));
		sz.cx=mmInfo.ptMinTrackSize.x;
		sz.cy=mmInfo.ptMinTrackSize.y;
	}
	LRESULT GetMinFrameDist(const DFMHDR* pHdr) const
	{
		CSize sz;
		GetMinFrameSize(pHdr,sz);
		return (IsHorizontal()) ? sz.cx : sz.cy;
	}

	void GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
	{
		if(m_frames.size()!=0)
		{
			pMinMaxInfo=std::accumulate(m_frames.begin(),m_frames.end(),
											pMinMaxInfo,CMinMaxInfoAccumulator<splitterSize>(IsHorizontal()));
			if(IsHorizontal())
				pMinMaxInfo->ptMinTrackSize.x-=splitterSize;
			else
				pMinMaxInfo->ptMinTrackSize.y-=splitterSize;
		}
	}
	void Draw(CDC& dc,const CRect& rc) const
	{
        if(m_frames.begin()!=m_frames.end())
			std::for_each(++m_frames.begin(),m_frames.end(),CEmbeddedSplitterBarPainter(dc,!IsHorizontal(),rc));
	}

	bool AcceptDock(DFDOCKRECT* pHdr,const CRect& rc)
	{
		bool bRes=false;
		CSize sz;
		GetMinFrameSize(&(pHdr->hdr),sz);
		if(rc.PtInRect(CPoint(pHdr->rect.left,pHdr->rect.top))
			&& (sz.cx<=rc.Width())
				&& (sz.cy<=rc.Height())
					&& ((( (IsHorizontal()) ? sz.cx : sz.cy)+m_frames.distance_limit())<(m_frames.hi()-m_frames.low())))
		{
			if(IsHorizontal())
			{
				pHdr->rect.top=rc.top;
				pHdr->rect.bottom=rc.bottom;
			}
			else
			{
				pHdr->rect.left=rc.left;
				pHdr->rect.right=rc.right;
			}
			bRes=true;
		}
		return bRes;
	}
	bool Dock(CFrame& frame,const DFDOCKRECT* pHdr,const CRect& rc)
	{
		position		  pos;
		CFrames::distance len;

		if(IsHorizontal())
		{
			pos=pHdr->rect.left;
			len=pHdr->rect.right-pHdr->rect.left;
		}
		else
		{
			pos=pHdr->rect.top;
			len=pHdr->rect.bottom-pHdr->rect.top;
		}

		iterator i=m_frames.locate(pos);
		if(i!=m_frames.end())
		{
			iterator inext=i;
			++inext;
			CBounds fbounds((*i),(inext!=m_frames.end())?(*inext):m_frames.hi());
			if((fbounds.low+(fbounds.hi-fbounds.low)/3)<pos)
				i=inext;
		}
		frame=pos;
		m_frames.insert(i,frame,len);

		return Arrange(rc);
	}
	bool Undock(const DFMHDR* pHdr,const CRect& rc)
	{
		iterator i=std::find_if(m_frames.begin(),m_frames.end(),CFrame::CCmp(pHdr->hWnd));
		assert(i!=m_frames.end());
		m_frames.erase(i);
		return Arrange(rc);
	}
	bool Replace(const DFDOCKREPLACE* pHdr,const CRect& rc)
	{
		iterator i=std::find_if(m_frames.begin(),m_frames.end(),CFrame::CCmp(pHdr->hdr.hWnd));
		assert(i!=m_frames.end());
		m_frames.replace(i,CFrame(0,pHdr->hWnd));
		return Arrange(rc);
	}

protected:
	bool	m_bHorizontal;
	CFrames	m_frames;
};

template< class TTraits = CDockingFrameTraits >
class CWndFramesPackage : public CWndFramesPackageBase<CWndFrame,TTraits >
{
	typedef CWndFrame CFrame;
	typedef TTraits CTraits;
	typedef typename CTraits::CSplitterBar			CSplitterBar;
	typedef CWndFramesPackage<TTraits>				thisClass;
	typedef CWndFramesPackageBase<CFrame,TTraits >	baseClass;
public:
	CWndFramesPackage(bool bHorizontal):baseClass(bHorizontal)
	{
	}
	void PrepareForDocking(CWindow wnd,HDOCKBAR bar)
	{
		wnd.ShowWindow(SW_HIDE);
		DWORD style = wnd.GetWindowLong(GWL_STYLE);
		DWORD newStyle = style&(~WS_POPUP)|WS_CHILD;
		wnd.SetWindowLong( GWL_STYLE, newStyle);
		wnd.SetParent(bar);
		wnd.SendMessage(WM_NCACTIVATE,TRUE);
		wnd.SendMessage(WMDF_NDOCKSTATECHANGED,
					MAKEWPARAM(TRUE,IsHorizontal()),
					reinterpret_cast<LPARAM>(bar));
	}
	void PrepareForUndocking(CWindow wnd,HDOCKBAR bar)
	{
		wnd.ShowWindow(SW_HIDE);
		DWORD style = wnd.GetWindowLong(GWL_STYLE);
		DWORD newStyle = style&(~WS_CHILD)|WS_POPUP;
		wnd.SetWindowLong( GWL_STYLE, newStyle);
		wnd.SetParent(NULL);

		wnd.SendMessage(WMDF_NDOCKSTATECHANGED,
			FALSE,
			reinterpret_cast<LPARAM>(bar));
	}

	bool SetDockingPosition(const DFDOCKPOS* pHdr,const CRect& rc)
	{
		assert(::IsWindow(pHdr->hdr.hWnd));
		CWindow wnd(pHdr->hdr.hWnd);
		PrepareForDocking(wnd,pHdr->hdr.hBar);
		position pos=m_frames.low()+position((m_frames.hi()-m_frames.low())*pHdr->fPctPos);
		m_frames.insert(CFrame(pos,pHdr->hdr.hWnd),pHdr->nHeight);
//		wnd.ShowWindow(SW_SHOWNA);
		bool bRes=Arrange(rc);
		wnd.SetWindowPos(NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
		return bRes;
	}

	bool GetDockingPosition(DFDOCKPOS* pHdr,const CRect& /*rc*/) const
	{
		assert(::IsWindow(pHdr->hdr.hWnd));
		const_iterator i=std::find_if(m_frames.begin(),m_frames.end(),CFrame::CCmp(pHdr->hdr.hWnd));
		bool bRes=(i!=m_frames.end());
		if(bRes)
		{
			position pos=*i-m_frames.low();
			pHdr->fPctPos=float(pos)/(m_frames.hi()-m_frames.low());
			pHdr->nHeight=m_frames.get_frame_size(i)-CSplitterBar::GetThickness();
//			pHdr->nWidth=IsHorizontal() ? rc.Height() : rc.Width();
//			pHdr->nWidth-=CSplitterBar::GetThickness();
			if(m_frames.size()==1)
				pHdr->dwDockSide|=CDockingSide::sSingle;
		}
		return bRes;
	}

	bool AcceptDock(DFDOCKRECT* pHdr,const CRect& rc)
	{
		return (!((m_frames.size()==1)
					&&(m_frames.begin()->hwnd()==pHdr->hdr.hWnd)))
						  &&baseClass::AcceptDock(pHdr,rc);
	}
	bool Dock(DFDOCKRECT* pHdr,const CRect& rc)
	{
		assert(::IsWindow(pHdr->hdr.hWnd));
		CWindow wnd(pHdr->hdr.hWnd);
		PrepareForDocking(wnd,pHdr->hdr.hBar);
		CFrame frame(0,pHdr->hdr.hWnd);
		bool bRes=baseClass::Dock(frame,pHdr,rc);
		wnd.SetWindowPos(NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
//		wnd.ShowWindow(SW_SHOWNA);
		return bRes;

	}
	bool Undock(DFMHDR* pHdr,const CRect& rc)
	{
		bool bRes=baseClass::Undock(pHdr,rc);
		assert(bRes);
		PrepareForUndocking(pHdr->hWnd,pHdr->hBar);
		if(m_frames.size()==0)
		{
			DFMHDR dockHdr;
			dockHdr.hWnd = pHdr->hBar;
			dockHdr.hBar = ::GetParent(pHdr->hBar);
			assert(::IsWindow(dockHdr.hBar));
			dockHdr.code=DC_UNDOCK;
			::SendMessage(dockHdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(&dockHdr));
            ::PostMessage(dockHdr.hWnd,WM_CLOSE,NULL,NULL);
		}
		return bRes;
	}

	bool Replace(const DFDOCKREPLACE* pHdr,const CRect& rc)
	{
		PrepareForUndocking(pHdr->hdr.hWnd,pHdr->hdr.hBar);
		PrepareForDocking(pHdr->hWnd,pHdr->hdr.hBar);
		bool bRes=baseClass::Replace(pHdr,rc);
		assert(bRes);
		::SetWindowPos(pHdr->hWnd,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
//		::ShowWindow(pHdr->hWnd,SW_SHOWNA);
		return bRes;
	}

};

template<class T>
class CPtrFrame
{
	typedef CPtrFrame<T> thisClass;
public:
	typedef typename T::position position;
	typedef typename T::distance distance;

	class CCmp
	{
	public:
		CCmp(HWND hWnd)	:m_hWnd(hWnd)
		{
		}
		bool operator ()(const thisClass& frame) const
		{
			return (frame.hwnd() == m_hWnd);
		}
	protected:
		HWND m_hWnd;
	};

	CPtrFrame(const CPtrFrame& x):m_pos(x.m_pos),m_ptr(x.m_ptr)
	{
	}
	CPtrFrame(position pos, T* ptr)
		:m_pos(pos),m_ptr(ptr)
	{
	}
	HWND hwnd() const
	{
		return m_ptr->operator HWND();
	}

	operator position() const
	{
		return m_pos;
	}

	thisClass& operator += (position val)
	{
		m_pos+=val;
		return *this;
	}
	thisClass& operator -= (position val)
	{
		m_pos-=val;
		return *this;
	}

	thisClass& operator = (position pos)
	{
		m_pos=pos;
		return *this;
	}

	HDWP DeferFramePos(HDWP hdwp,long x1,long y1,long x2,long y2) const
	{
		return m_ptr->DeferFramePos(hdwp,x1,y1,x2,y2);
	}
	T* operator ->() const
	{
		return m_ptr.get();
	}
	void GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
	{
		m_ptr->GetMinMaxInfo(pMinMaxInfo);
	}
	distance MinDistance() const
	{
		return m_ptr->MinDistance();
	}
protected:
	position m_pos;
#ifdef USE_BOOST
	mutable boost::shared_ptr<T> m_ptr;
#else
	mutable std::auto_ptr<T> m_ptr;
#endif
};


struct IFrame
{
	typedef long position;
	typedef long distance;

	virtual  ~IFrame(){};
	virtual  HWND hwnd() const=0;
	operator HWND() const
	{
		return hwnd();
	}
	virtual bool AcceptDock(DFDOCKRECT* pHdr) const=0;
	virtual distance MinDistance() const=0;
	virtual void GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const=0;

	virtual HDWP DeferFramePos(HDWP hdwp,long x1,long y1,long x2,long y2) const
	{
		return ::DeferWindowPos(hdwp,hwnd(),
								NULL,
								x1,y1,
								x2-x1,y2-y1,
								SWP_NOZORDER | SWP_NOACTIVATE);
	}
};


class CWindowPtrWrapper : public IFrame
{
public:
	CWindowPtrWrapper(HWND* phWnd):m_phWnd(phWnd)
	{
	}
	virtual HWND hwnd() const
	{
		return (*m_phWnd);
	}
	virtual bool AcceptDock(DFDOCKRECT* /*pHdr*/) const
	{
		return false;
	}
	virtual HDWP DeferFramePos(HDWP hdwp,long x1,long y1,long x2,long y2) const
	{
		if(*m_phWnd!=NULL)
			hdwp=::DeferWindowPos(hdwp,hwnd(),
									NULL,
									x1,y1,
									x2-x1,y2-y1,
									SWP_NOZORDER | SWP_NOACTIVATE);
		return hdwp;
	}
	void GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
	{
		if(*m_phWnd!=NULL)
		 ::SendMessage(hwnd(),WM_GETMINMAXINFO,NULL,reinterpret_cast<LPARAM>(pMinMaxInfo));
	}
	virtual distance MinDistance() const
	{
		MINMAXINFO mmInfo;
		ZeroMemory(&mmInfo,sizeof(MINMAXINFO));
		GetMinMaxInfo(&mmInfo);
		return mmInfo.ptMinTrackSize.x;;
	}
protected:
	HWND* m_phWnd;
};

//TImbeddedPackegeWnd
template<class TPackageFrame,class TTraits = CDockingWindowTraits >
class CSubWndFramesPackage :
		public CRect,
		public CWndFramesPackageBase<CPtrFrame<IFrame>,TTraits >
{
	typedef CPtrFrame<IFrame> CFrame;
	typedef TTraits CTraits;
	typedef typename CTraits::CSplitterBar	CSplitterBar;
	typedef CSubWndFramesPackage<TPackageFrame,TTraits> thisClass;
	typedef CWndFramesPackageBase<CFrame,TTraits >		baseClass;
	typedef TPackageFrame	CPackageFrame;
	enum {controlledLen=(15+CSplitterBar::sbThickness)};
	struct  CDockOrientationFlag
	{
		enum{low=0,high=1};
		static void SetHigh(DWORD& flag)
		{

⌨️ 快捷键说明

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