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

📄 dwautohide.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 3 页
字号:
// Copyright (c) 2002

// Sergey Klimov (kidd@ukr.net)
// WTL Docking windows
//
// This code is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included. If
// the source code in  this file is used in any commercial application
// then a simple email woulod be nice.

#ifndef __WTL_DW__DWAUTOHIDE_H__
#define __WTL_DW__DWAUTOHIDE_H__

#define DF_AUTO_HIDE_FEATURES

#include <queue>
#include <deque>
#include "ssec.h"
#include "DockMisc.h"
#include "ExtDockingWindow.h"


namespace dockwins{

typedef CDockingWindowTraits<COutlookLikeCaption,
								WS_CAPTION | WS_CHILD |
								WS_CLIPCHILDREN | WS_CLIPSIBLINGS,WS_EX_TOOLWINDOW>
								COutlookLikeAutoHidePaneTraits;


template <class TAutoHidePaneTraits,class TSplitterBar,/* DWORD TDockFrameStyle=0,*/
			DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0>
struct CDockingFrameTraitsT : CWinTraits <t_dwStyle,t_dwExStyle>
{
	typedef TSplitterBar		CSplitterBar;
	typedef TAutoHidePaneTraits CAutoHidePaneTraits;
};

typedef CDockingFrameTraitsT< COutlookLikeAutoHidePaneTraits,CSimpleSplitterBar<5>,
		WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
		WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> CDockingFrameTraits;

typedef CDockingFrameTraitsT<COutlookLikeAutoHidePaneTraits, CSimpleSplitterBarEx<6>,
		WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,0> CDockingSiteTraits;

struct IPinnedLabel
{
	typedef CDockingSide	CSide;
	enum
	{
		leftBorder=3,
		rightBorder=3,
		labelEdge=2,
		labelPadding=5,			// padding between the labels
		captionPadding=3		// padding between border of the label and the lable caption
	};

	class CPinnedWindow
	{
	public:
		CPinnedWindow()
			:m_hWnd(NULL),m_icon(0),m_txt(0),m_width(0)
		{
		}
		CPinnedWindow(const CPinnedWindow& ref)
		{
			this->operator=(ref);
		}
		~CPinnedWindow()
		{
			delete [] m_txt;
		}
		CPinnedWindow& operator = (const CPinnedWindow& ref)
		{
			m_hWnd=ref.m_hWnd;
			m_icon=ref.m_icon;
			m_width=ref.m_width;
			m_txt=ref.m_txt;
			ref.m_txt=0;
			return *this;
		}
		int Assign(HWND hWnd,unsigned long width)
		{
			assert(::IsWindow(hWnd));
			m_hWnd=hWnd;
			m_width=width;
			m_icon=reinterpret_cast<HICON>(::SendMessage(hWnd, WM_GETICON, FALSE, 0));
			if(m_icon == NULL)
				m_icon = reinterpret_cast<HICON>(::GetClassLong(hWnd, GCL_HICONSM));
			delete [] m_txt;
			int len=0;
			try
			{
				len=::GetWindowTextLength(hWnd)+1;
				m_txt=new TCHAR[len];
				::GetWindowText(hWnd,m_txt,len);
			} catch(std::bad_alloc& /*e*/)
			{
				m_txt=0;
			}
			return len;

		}
		HWND Wnd() const
		{
			return m_hWnd;
		}
		HICON Icon() const
		{
			return m_icon;
		}
		LPCTSTR Text() const
		{
			return m_txt;
		}
		unsigned long Width() const
		{
			return m_width;
		}
		void Width(unsigned long width)
		{
			m_width=width;
		}
		void PrepareForDock(HDOCKBAR hBar,bool bHorizontal)
		{
			::ShowWindow(m_hWnd,SW_HIDE);
			DWORD style = ::GetWindowLong(m_hWnd,GWL_STYLE);
			DWORD newStyle = style&(~(WS_POPUP | WS_CAPTION))|WS_CHILD;
			::SetWindowLong(m_hWnd, GWL_STYLE, newStyle);
			::SetParent(m_hWnd,hBar);
			::SendMessage(m_hWnd,WM_NCACTIVATE,TRUE,NULL);
			::SendMessage(m_hWnd,WMDF_NDOCKSTATECHANGED,
									MAKEWPARAM(TRUE,bHorizontal),
									reinterpret_cast<LPARAM>(hBar));
		}
		void PrepareForUndock(HDOCKBAR	hBar)
		{
			::ShowWindow(m_hWnd,SW_HIDE);
			DWORD style = ::GetWindowLong(m_hWnd,GWL_STYLE);
			DWORD newStyle = style&(~WS_CHILD) | WS_POPUP | WS_CAPTION;
			::SetWindowLong(m_hWnd, GWL_STYLE, newStyle);
			::SetParent(m_hWnd,NULL);
			::SendMessage(m_hWnd,WMDF_NDOCKSTATECHANGED,
					FALSE,
					reinterpret_cast<LPARAM>(hBar));
		}
		void DrawLabel(CDC& dc,const CRect& rc,const CSide& side) const
		{
			CRect rcOutput(rc);
			rcOutput.DeflateRect(captionPadding,captionPadding);
			if(m_icon!=NULL)
			{
				CDWSettings settings;
				CSize  szIcon(settings.CXMinIcon(),settings.CYMinIcon());
				if(side.IsHorizontal())
				{
					if(rc.Width()>szIcon.cx+2*captionPadding)
					{
						POINT pt={rcOutput.left,rc.top+(rc.Height()-szIcon.cx)/2};
						rcOutput.left+=szIcon.cx+captionPadding;
						dc.DrawIconEx(pt,m_icon,szIcon);
					}
				}
				else
				{
					if(rc.Height()>szIcon.cy+2*captionPadding)
					{
						POINT pt={rc.left+(rc.Width()-szIcon.cy)/2,rcOutput.top};
						rcOutput.top+=szIcon.cy+captionPadding;
						dc.DrawIconEx(pt,m_icon,szIcon);
					}
				}
			}
			DrawEllipsisText(dc,m_txt,_tcslen(m_txt),&rcOutput,side.IsHorizontal());
		}
	protected:
		unsigned long	m_width;
		HWND			m_hWnd;
		HICON			m_icon;
		mutable LPTSTR	m_txt;
	};

	class CCmp
	{
	public:
		CCmp(HWND hWnd):m_hWnd(hWnd)
		{
		}
		bool operator() (const IPinnedLabel* ptr) const
		{
			return ptr->IsOwner(m_hWnd);
		}
	protected:
		HWND m_hWnd;
	};

	virtual ~IPinnedLabel(){}

	virtual IPinnedLabel* Remove(HWND hWnd,HDOCKBAR hBar)=0;
	virtual bool UnPin(HWND hWnd,HDOCKBAR hBar,DFDOCKPOS* pHdr)=0;

	virtual long Width() const=0;
	virtual void Width(long width)=0;
	virtual long DesiredWidth(CDC& dc) const=0;

	virtual bool GetDockingPosition(DFDOCKPOS* pHdr) const=0;

	virtual CPinnedWindow* ActivePinnedWindow()=0;
	virtual CPinnedWindow* FromPoint(long x,bool bActivate)=0;
	virtual bool IsOwner(HWND hWnd) const=0;
	virtual void Draw(CDC& dc,const CRect& rc,const CSide& side) const=0;

};

class CSinglePinnedLabel : public IPinnedLabel
{
public:
	CSinglePinnedLabel(DFPINUP* pHdr,bool bHorizontal)
		:m_width(0)
	{
		assert( (pHdr->n==0) || (pHdr->n==1) );
		m_wnd.Assign(pHdr->hdr.hWnd,pHdr->nWidth);
		m_wnd.PrepareForDock(pHdr->hdr.hBar,bHorizontal);
	}
	CSinglePinnedLabel(const CPinnedWindow& wnd)
		:m_wnd(wnd),m_width(0)
	{
	}

	virtual IPinnedLabel* Remove(HWND hWnd,HDOCKBAR hBar)
	{
		assert(IsOwner(hWnd));
		m_wnd.PrepareForUndock(hBar);
		return 0;
	}
	virtual bool UnPin(HWND hWnd,HDOCKBAR hBar,DFDOCKPOS* pHdr)
	{
		GetDockingPosition(pHdr);
		bool bRes=(Remove(hWnd,hBar)==0);
		if(bRes)
		{
			pHdr->hdr.code=DC_SETDOCKPOSITION;
			::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr));
		}
		return bRes;
	}
	virtual long Width() const
	{
		return m_width;
	}

	virtual void Width(long width)
	{
		m_width=width;
	}

	virtual long DesiredWidth(CDC& dc) const
	{
		SIZE sz;
		LPCTSTR text=m_wnd.Text();
		bool bRes=(GetTextExtentPoint32(dc, text,_tcslen(text),&sz)!=FALSE);
		assert(bRes);
		unsigned long width=sz.cx+2*captionPadding;
		if(m_wnd.Icon()!=NULL)
		{
			CDWSettings settings;
			width+=settings.CXMinIcon()+captionPadding;
		}
		bRes;
		return width;
	}

	virtual CPinnedWindow* ActivePinnedWindow()
	{
		return &m_wnd;
	}
	virtual CPinnedWindow* FromPoint(long x,bool /*bActivate*/)
	{
		assert(x>=0 && x<Width() );
		return ActivePinnedWindow();
	}

	virtual void Draw(CDC& dc,const CRect& rc,const CSide& side) const
	{
		dc.Rectangle(&rc);
		m_wnd.DrawLabel(dc,rc,side);
	}

	virtual bool IsOwner(HWND hWnd) const
	{
		return m_wnd.Wnd()==hWnd;
	}
	virtual bool GetDockingPosition(DFDOCKPOS* pHdr) const
	{
		assert(pHdr->hdr.hWnd==m_wnd.Wnd());
		pHdr->nBar=0;
		pHdr->nWidth=m_wnd.Width();
		pHdr->nHeight=1;
		pHdr->nIndex=0;
		pHdr->fPctPos=0;
		return true;
	}
protected:
	CPinnedWindow	m_wnd;
	long			m_width;
};

class CMultyPinnedLabel : public IPinnedLabel
{
	enum {npos=ULONG_MAX/*std::numeric_limits<unsigned long>::max()*/};
public:
	CMultyPinnedLabel(DFPINUP* pHdr,bool bHorizontal)
		:m_width(0)
	{
		assert(pHdr->n>1);
		m_n=pHdr->n;
		m_tabs=new CPinnedWindow[m_n];
		int maxLen=0;
		for(unsigned long i=0;i<m_n;i++)
		{
			int len=m_tabs[i].Assign(pHdr->phWnds[i],pHdr->nWidth);
			m_tabs[i].PrepareForDock(pHdr->hdr.hBar,bHorizontal);
			if(len>maxLen)
			{
				maxLen=len;
				m_longestTextTab=i;
			}
			if(pHdr->phWnds[i]==pHdr->hdr.hWnd)
				m_activeTab=i;
		}
	}
	~CMultyPinnedLabel()
	{
		delete [] m_tabs;
	}

	virtual bool UnPin(HWND hWnd,HDOCKBAR hBar,DFDOCKPOS* pHdr)
	{
		assert(pHdr->hdr.hWnd==hWnd);
		GetDockingPosition(pHdr);
		pHdr->hdr.hWnd=m_tabs[0].Wnd();
		pHdr->hdr.code=DC_SETDOCKPOSITION;
		m_tabs[0].PrepareForUndock(hBar);
		::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr));

		pHdr->hdr.hBar=pHdr->hdr.hWnd;
		for(unsigned long i=1;i<m_n;i++)
		{
			pHdr->nIndex=i;
			pHdr->hdr.hWnd=m_tabs[i].Wnd();
			m_tabs[i].PrepareForUndock(hBar);
			::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr));
		}
		pHdr->hdr.code=DC_ACTIVATE;
		pHdr->hdr.hWnd=m_tabs[m_activeTab].Wnd();
		::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(&(pHdr->hdr)));
		return true;
	}
	virtual IPinnedLabel* Remove(HWND hWnd,HDOCKBAR hBar)
	{
		assert(IsOwner(hWnd));
		IPinnedLabel* ptr=this;
		try
		{
			if(m_n==2)
			{
				unsigned long i=(m_tabs[0].Wnd()!=hWnd);
				ptr=new CSinglePinnedLabel(m_tabs[i]);
				m_tabs[!i].PrepareForUndock(hBar);
			}
			else
			{
				CPinnedWindow* ptr=m_tabs;
				m_tabs=new CPinnedWindow[m_n-1];
				unsigned long j=0;
				unsigned int maxLen=0;
				for(unsigned long i=0;i<m_n;i++)
				{
					if(ptr[i].Wnd()!=hWnd)
					{
						if(maxLen<_tcslen(ptr[i].Text()))
							m_longestTextTab=j;
						m_tabs[j++]=ptr[i];
					}
					else
						ptr[i].PrepareForUndock(hBar);
				}
				if(m_activeTab==--m_n)
							--m_activeTab;
				delete [] ptr;
			}
		}
		catch(std::bad_alloc& /*e*/)
		{
		}
		return ptr;
	}
	unsigned long Locate(HWND hWnd) const
	{
		for(unsigned long i=0;i<m_n;i++)
			if(m_tabs[i].Wnd()==hWnd)
				return i;
			return (unsigned long)npos;
	}
	virtual bool IsOwner(HWND hWnd) const
	{
		return (Locate(hWnd)!=npos);
	}

	virtual long Width() const
	{
		return m_width;
	}
	virtual void Width(long width)
	{
		m_width=width;
		if(m_width<m_passiveTabWidth*long(m_n))
		{
			if(m_width<long(m_n))
				m_passiveTabWidth=0;
			else
				m_passiveTabWidth=m_width/m_n;
		}
	}
	virtual long DesiredWidth(CDC& dc) const
	{
		SIZE sz;
		LPCTSTR text=m_tabs[m_longestTextTab].Text();
		bool bRes=(GetTextExtentPoint32(dc, text,_tcslen(text),&sz)!=FALSE);
		assert(bRes);
		bRes;
		long width=sz.cx+2*captionPadding;
		CDWSettings settings;
		width+=settings.CXMinIcon()+captionPadding;
		m_passiveTabWidth=settings.CXMinIcon()+2*captionPadding;
		width+=m_passiveTabWidth*(m_n-1);
		return width;
	}

	virtual CPinnedWindow* ActivePinnedWindow()
	{
		return m_tabs+m_activeTab;
	}
	virtual CPinnedWindow* FromPoint(long x,bool bActivate)
	{
		assert(x>=0 && x<Width() );
		unsigned long i=m_activeTab;
		if(x<long(m_activeTab)*m_passiveTabWidth)
			i=x/m_passiveTabWidth;
		else
		{
			long width=Width()-(m_n-m_activeTab-1)*m_passiveTabWidth;
			if( width<x )
				i+=(x-width)/m_passiveTabWidth+1;
		}
		assert(m_activeTab<m_n);
		if(bActivate)
			m_activeTab=i;
		return m_tabs+i;
	}

	void DrawPassiveTab(unsigned long i,CDC& dc,const CRect& rc,const CSide& side) const
	{
		CRect rcOutput(rc);
		rcOutput.DeflateRect(captionPadding,captionPadding);
		HICON icon=m_tabs[i].Icon();
		CDWSettings settings;
		CSize  sz(settings.CXMinIcon(),settings.CYMinIcon());
		if( icon!=0
			&& (sz.cx<=(rc.Width()-2*captionPadding))
			&& (sz.cy<=(rc.Height()-2*captionPadding)) )
		{
			POINT pt={rcOutput.left,rcOutput.top};
			dc.DrawIconEx(pt,icon,sz);
		}
		else
		{
			LPCTSTR text=m_tabs[i].Text();
			DrawEllipsisText(dc,text,_tcslen(text),&rcOutput,side.IsHorizontal());
		}
	}
	void DrawActiveTab(unsigned long i,CDC& dc,const CRect& rc,const CSide& side) const
	{
		m_tabs[i].DrawLabel(dc,rc,side.IsHorizontal());
	}
	virtual void Draw(CDC& dc,const CRect& rc,const CSide& side) const
	{
		CRect rcOutput(rc);
		dc.Rectangle(&rcOutput);
		long* pLeft;
		long* pRight;
		long* px;
		long* py;
		if(side.IsHorizontal())
		{
			pLeft=&rcOutput.left;
			pRight=&rcOutput.right;

			px=&rcOutput.left;
			py=&rcOutput.bottom;
		}
		else
		{
			pLeft=&rcOutput.top;
			pRight=&rcOutput.bottom;

			px=&rcOutput.right;
			py=&rcOutput.top;
		}
		for(unsigned long i=0;i<m_n;i++)
		{
			if(i==m_activeTab)
			{
				*pRight=*pLeft+m_width-m_passiveTabWidth*(m_n-1);
				assert(*pRight<=(side.IsHorizontal() ? rcOutput.right : rcOutput.bottom));
				DrawActiveTab(i,dc,rcOutput,side.IsHorizontal());
			}
			else
			{
				*pRight=*pLeft+m_passiveTabWidth;
				assert(*pRight<=(side.IsHorizontal() ? rcOutput.right : rcOutput.bottom));
				DrawPassiveTab(i,dc,rcOutput,side);
			}
			dc.MoveTo(rcOutput.left, rcOutput.top);
			dc.LineTo(*px,*py);
			*pLeft=*pRight;
		}
	}

	virtual bool GetDockingPosition(DFDOCKPOS* pHdr) const
	{
		unsigned long i=Locate(pHdr->hdr.hWnd);
		bool bRes=(i!=npos);
		if(bRes)
		{
			if(m_activeTab==i)
				pHdr->dwDockSide|=CDockingSide::sActive;
			pHdr->nBar=0;
			pHdr->nWidth=m_tabs[i].Width();
			pHdr->nHeight=1;
			pHdr->nIndex=i;
			pHdr->fPctPos=0;
		}
		return bRes;
	}
protected:
	unsigned long	m_n;
	CPinnedWindow*	m_tabs;
	long			m_width;

	mutable  long   m_passiveTabWidth;
	unsigned long	m_activeTab;
	unsigned long	m_longestTextTab;
};

class CAutoHideBar: protected CRect
{
	typedef CRect	baseClass;
protected:
	typedef IPinnedLabel*					CPinnedLabelPtr;
	typedef std::deque<CPinnedLabelPtr>		CBunch;
	typedef CBunch::const_iterator			const_iterator;
public:
	typedef IPinnedLabel::CSide	CSide;

	CAutoHideBar()
	{
		SetRectEmpty();
	}

	// Bug fix, refer to
	// <http://www.codeproject.com/wtl/wtldockingwindows.asp?mode=all&userid=36446&select=1377220&df=100&forumid=3244&mpp=50&msg=1377220>
	static void DestroyPinnedLabel(CPinnedLabelPtr ptr)	
	{
		delete ptr;
	}	

	~CAutoHideBar()	
	{		
		void (*pDelete)(CPinnedLabelPtr)=&DestroyPinnedLabel;		
		std::for_each(m_bunch.begin(),m_bunch.end(),pDelete);	
	}

	operator const CRect& () const
	{
		return *this;
	}
	bool IsPtIn(const CPoint& pt) const
	{
		return (PtInRect(pt)!=FALSE);
	}
	const CSide& Orientation() const
	{
		return m_side;
	}
	bool IsVisible() const
	{
		return !m_bunch.empty();
	}
	bool IsHorizontal() const
	{
		return Orientation().IsHorizontal();
	}
	bool IsTop() const

⌨️ 快捷键说明

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