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

📄 dwautohide.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 3 页
字号:
	LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM/* lParam*/, BOOL& bHandled)
	{
		T* pThis=reinterpret_cast<T*>(this);
		bHandled=pThis->OnClosing();
		return 0;
	}

	LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		// Note: We can depend on CDWSettings already being updated
		//  since we will always be a descendant of the main frame

		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 1;
//	}

protected:
	CCaption		m_caption;
	CSplitterBar	m_splitter;
	CSide			m_side;
};

template<class TAutoHidePaneTraits>
class CAutoHideManager
	: public CAutoHidePaneImpl<CAutoHideManager<TAutoHidePaneTraits>,CWindow,TAutoHidePaneTraits>
{
	typedef CAutoHidePaneImpl<CAutoHideManager<TAutoHidePaneTraits>,CWindow,TAutoHidePaneTraits>	baseClass;
	typedef CAutoHideManager																		thisClass;
protected:
	typedef typename CAutoHideBar::CSide		CSide;
	enum{ tmID=1,tmTimeout=1300};
	enum{ animateTimeout=100};
	enum{ hoverTimeout=50/*HOVER_DEFAULT*/};
	enum{ barsCount=4 };

	class CSizeTrackerFull : public IDDTracker
	{
	protected:
		typedef ssec::bounds_type<long> CBounds;
	public:
		bool IsHorizontal() const
		{
			return m_side.IsHorizontal();
		}
		bool IsTop() const
		{
			return m_side.IsTop();
		}
		CSizeTrackerFull(HWND hWnd,CPoint pt,const CSide& side,long minSize,const CRect& rcBound)
			: m_wnd(hWnd),m_side(side)
		{
			m_wnd.GetWindowRect(&m_rc);
			CWindow wndParent=m_wnd.GetParent();
			wndParent.ScreenToClient(&m_rc);
			wndParent.ScreenToClient(&pt);
			if(IsHorizontal())
			{
				if(IsTop())
					m_ppos=&m_rc.bottom;
				else
					m_ppos=&m_rc.top;
				m_bounds.low=rcBound.top;
				m_bounds.hi=rcBound.bottom;
				m_offset=pt.y-*m_ppos;
			}
			else
			{
				if(IsTop())
					m_ppos=&m_rc.right;
				else
					m_ppos=&m_rc.left;
				m_bounds.low=rcBound.left;
				m_bounds.hi=rcBound.right;
				m_offset=pt.x-*m_ppos;
			}
			m_bounds.low+=minSize;
			m_bounds.hi-=minSize;
		}
        void OnMove(long x, long y)
        {
			long pos = IsHorizontal() ? y : x;
			pos-=m_offset;
			pos=m_bounds.bind(pos);
			if(*m_ppos!=pos)
			{
				*m_ppos=pos;
				Move();
			}
		}
		void SetPosition()
		{
			m_wnd.SetWindowPos(NULL,&m_rc,SWP_NOZORDER | SWP_NOACTIVATE);
		}
		virtual void Move()
		{
			SetPosition();
		}
		bool ProcessWindowMessage(MSG* pMsg)
		{
		   return (pMsg->message==WM_TIMER);
		}

	protected:
		CWindow		m_wnd;
		CBounds		m_bounds;
		CRect		m_rc;
		const CSide	m_side;
		long*		m_ppos;
		long		m_offset;
	};
	class CSizeTrackerGhost : public CSizeTrackerFull
	{
        typedef CSimpleSplitterBarSlider<CSplitterBar> CSlider;
	public:
		CSizeTrackerGhost(HWND hWnd,CPoint pt,const CSide& side,CSplitterBar& splitter,const CRect& rcBound)
			: CSizeTrackerFull(hWnd,pt,side,splitter.GetThickness(),rcBound),m_dc(::GetWindowDC(NULL))
			,m_splitter(splitter),m_slider(splitter)
		{
			m_spOffset=m_slider-*m_ppos;
		}
        void BeginDrag()
        {
            m_splitter.DrawGhostBar(m_dc);
        }
        void EndDrag(bool bCanceled)
        {
            m_splitter.CleanGhostBar(m_dc);
            if(!bCanceled)
                SetPosition();
        }
		virtual void Move()
		{
			m_splitter.CleanGhostBar(m_dc);
			m_slider=*m_ppos+m_spOffset;
			m_splitter.DrawGhostBar(m_dc);
		}
	protected:
		CDC				m_dc;
		CSplitterBar&	m_splitter;
		CSlider			m_slider;
		long			m_spOffset;
	};
public:
	CAutoHideManager()
		: m_pActive(0)
	{
		m_side=0;
	}
	bool Initialize(HWND hWnd)
	{
		ApplySystemSettings(hWnd);
		m_bars[CSide::sTop].Initialize(CSide(CSide::sTop));
		m_bars[CSide::sBottom].Initialize(CSide(CSide::sBottom));
		m_bars[CSide::sLeft].Initialize(CSide(CSide::sLeft));
		m_bars[CSide::sRight].Initialize(CSide(CSide::sRight));
		RECT rc={0,0,0,0};
		return (Create(hWnd,rc)!=NULL);
	}
	void ApplySystemSettings(HWND hWnd)
	{
		CClientDC dc(hWnd);
		CDWSettings settings;
		HFONT hOldFont=dc.SelectFont(settings.VSysFont());
		TEXTMETRIC tm;
		dc.GetTextMetrics(&tm);
		m_barThickness=tm.tmHeight;

		dc.SelectFont(settings.HSysFont());
		dc.GetTextMetrics(&tm);
		if(m_barThickness<tm.tmHeight)
			m_barThickness=tm.tmHeight;
		dc.SelectFont(hOldFont);
		int widthIcon=settings.CXMinIcon();
		assert(widthIcon==settings.CYMinIcon()); //if it throw let me know ;)
		if(widthIcon>m_barThickness)
			m_barThickness=widthIcon;
		m_barThickness+=2*IPinnedLabel::captionPadding+IPinnedLabel::labelEdge;
	}

	void UpdateLayout(CDC& dc,CRect& rc)
	{
		long leftPadding= ( m_bars[CSide::sLeft].IsVisible() ) ? m_barThickness : 0;
		long rightPadding=( m_bars[CSide::sRight].IsVisible() ) ? m_barThickness : 0;
		m_bars[CSide::sTop].CalculateRect( dc,rc,m_barThickness,leftPadding,rightPadding);
		m_bars[CSide::sBottom].CalculateRect( dc,rc,m_barThickness,leftPadding,rightPadding);

		leftPadding=0;
		rightPadding=0;

		m_bars[CSide::sLeft].CalculateRect( dc,rc,m_barThickness,leftPadding,rightPadding);
		m_bars[CSide::sRight].CalculateRect( dc,rc,m_barThickness,leftPadding,rightPadding);

		m_rcBound.CopyRect(&rc);
		if(m_pActive)
			FitPane();
	}
	long Width() const
	{
		long width=0;
		if(m_bars[CSide::sLeft].IsVisible())
			width+=m_barThickness;
		if(m_bars[CSide::sRight].IsVisible())
			width+=m_barThickness;
		return width;
	}
	long Height() const
	{
		long height=0;
		if(m_bars[CSide::sTop].IsVisible())
			height+=m_barThickness;
		if(m_bars[CSide::sBottom].IsVisible())
			height+=m_barThickness;
		return height;
	}
	bool FitPane()
	{
		CRect rc(m_rcBound);
		long spliterWidth=m_splitter.GetThickness();
		long width=m_pActive->Width()+spliterWidth;
		if(IsHorizontal())
		{
			long maxWidth=rc.Height();
			maxWidth=(maxWidth<spliterWidth) ? spliterWidth : maxWidth-spliterWidth;
			if(IsTop())
				rc.bottom=rc.top+( (maxWidth>width) ? width : maxWidth );
			else
				rc.top=rc.bottom-( (maxWidth>width) ? width : maxWidth );
		}
		else
		{
			long maxWidth=rc.Width();
			maxWidth=(maxWidth<spliterWidth) ? spliterWidth : maxWidth-spliterWidth;
			if(IsTop())
				rc.right=rc.left+( (maxWidth>width) ? width : maxWidth );
			else
				rc.left=rc.right-( (maxWidth>width) ? width : maxWidth );
		}
		return (SetWindowPos(HWND_TOP,rc,SWP_NOACTIVATE)!=FALSE);
	}

	IPinnedLabel::CPinnedWindow* LocatePinnedWindow(const CPoint& pt) const
	{
		IPinnedLabel::CPinnedWindow* ptr=0;
		for(int i=0;i<barsCount;i++)
		{
			ptr=m_bars[i].MouseEnter(pt);
			if(ptr!=0)
				break;
		}
		return ptr;
	}
	bool IsPtIn(const CPoint& pt) const
	{
		bool bRes;
		for(int i=0;i<barsCount;i++)
		{
			bRes=m_bars[i].IsPtIn(pt);
			if(bRes)
				break;
		}
		return bRes;
	}
	bool MouseEnter(HWND hWnd,const CPoint& pt)
	{
		IPinnedLabel::CPinnedWindow* ptr=0;
		for(int i=0;i<barsCount;i++)
		{
			CAutoHideBar* pbar=m_bars+i;
			ptr=pbar->MouseEnter(pt);
			if((ptr!=0)
				&& IsVisualizationNeeded(ptr))
			{
				m_pTracked=ptr;
				TRACKMOUSEEVENT tme = { 0 };
				tme.cbSize = sizeof(tme);
				tme.hwndTrack = hWnd;
				tme.dwFlags = TME_HOVER;
				tme.dwHoverTime = hoverTimeout;
				::_TrackMouseEvent(&tme);
				break;
			}
		}
		return (ptr!=0);
	}

	bool MouseHover(HWND hWnd,const CPoint& pt)
	{
		IPinnedLabel::CPinnedWindow* ptr=0;
		for(int i=0;i<barsCount;i++)
		{
			CAutoHideBar* pbar=m_bars+i;
			ptr=pbar->MouseEnter(pt,true);
			if((ptr!=0)
				&& (ptr==m_pTracked)
					&&IsVisualizationNeeded(ptr))
			{
				CClientDC dc(hWnd);
				pbar->Draw(dc);
				Visualize(ptr,i,true);
				break;
			}
		}
		return (ptr!=0);
	}

	void Draw(CDC& dc)
	{
		EraseBackground(dc);
		for(int i=0;i<barsCount;i++)
			m_bars[i].Draw(dc,false);
	}
	void EraseBackground(CDC& dc)
	{
		CDWSettings settings;
		CBrush bgrBrush;
		bgrBrush.CreateSolidBrush(settings.CoolCtrlBackgroundColor());
		HBRUSH hOldBrush=dc.SelectBrush(bgrBrush);
		CRect rcTop(m_bars[CSide::sTop].operator const CRect&());
		CRect rcBottom(m_bars[CSide::sBottom].operator const CRect&());

		if(m_bars[CSide::sLeft].IsVisible())
		{
			const CRect& rc=m_bars[CSide::sLeft].operator const CRect&();
			rcTop.left-=rc.Height();
			rcBottom.left-=rc.Height();
			dc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY);
		}
		if(m_bars[CSide::sRight].IsVisible())
		{
			const CRect& rc=m_bars[CSide::sRight].operator const CRect&();
			rcTop.right+=rc.Height();
			rcBottom.right+=rc.Height();
			dc.PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY);
		}

		if(m_bars[CSide::sTop].IsVisible())
			dc.PatBlt(rcTop.left, rcTop.top, rcTop.Width(), rcTop.Height(), PATCOPY);
		if(m_bars[CSide::sBottom].IsVisible())
			dc.PatBlt(rcBottom.left, rcBottom.top, rcBottom.Width(), rcBottom.Height(), PATCOPY);

		dc.SelectBrush(hOldBrush);
	}

	bool PinUp(HWND hWnd,DFPINUP* pHdr,bool& bUpdate)
	{
		pHdr->hdr.hBar=m_hWnd;
		CSide side(pHdr->dwDockSide);
		assert(side.IsValid());
		CAutoHideBar* pbar=m_bars+side.Side();
		bUpdate=!pbar->IsVisible();
		IPinnedLabel* pLabel=pbar->Insert(pHdr);
		bool bRes=(pLabel!=0);
		if(bRes&& ((pHdr->dwFlags&DFPU_VISUALIZE)!=0))
			Visualize(pLabel->ActivePinnedWindow(),side);
		if(!bUpdate)
		{
			CClientDC dc(hWnd);
			pbar->UpdateLayout(dc);
			pbar->Draw(dc);
		}
		return bRes;
	}

	bool Remove(HWND hWnd,bool bUnpin=false)
	{
		if(m_pActive!=0 && (m_pActive->Wnd()==hWnd ) )
												Vanish();

		HDOCKBAR hBar=GetParent();
		assert(::IsWindow(hBar));
		DFDOCKPOS* pHdr=0;
		DFDOCKPOS dockHdr;
		if(bUnpin)
		{
//			dockHdr.hdr.code=DC_SETDOCKPOSITION;
			dockHdr.hdr.hWnd=hWnd;
			dockHdr.hdr.hBar=hBar;
			pHdr=&dockHdr;
		}
		bool bRes=false;
		for(int i=0;i<barsCount;i++)
		{
			CAutoHideBar* pbar=m_bars+i;
			bRes=pbar->Remove(hWnd,m_hWnd,pHdr);
			if(bRes)
			{
				if(pbar->IsVisible())
				{
					CClientDC dc(hBar);
					pbar->UpdateLayout(dc);
					pbar->Draw(dc);
				}
				else
				{
					::SendMessage(hBar, WM_SIZE, 0, 0);
					::RedrawWindow(hBar,NULL,NULL,
										RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
				}
				break;
			}
		}
		return bRes;
	}

	bool GetDockingPosition(DFDOCKPOS* pHdr) const
	{
		bool bRes=false;
		for(int i=0;i<barsCount;i++)
		{
			bRes=m_bars[i].GetDockingPosition(pHdr);
			if(bRes)
				break;
		}
		return bRes;
	}
///////////////////////////////////////////////////////////
	bool IsVisualizationNeeded(const IPinnedLabel::CPinnedWindow* ptr) const
	{
		return (ptr!=m_pActive);
	}

	bool Visualize(IPinnedLabel::CPinnedWindow* ptr,const CSide& side,bool bAnimate=false)
	{
		assert(ptr);
		assert(IsVisualizationNeeded(ptr));
		Vanish();
		Orientation(side);
		assert(m_pActive==0);
		m_pActive=ptr;
		bool bRes=(::SetWindowPos(m_pActive->Wnd(),HWND_TOP,0,0,0,0,
							SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW)!=FALSE);
		if(bRes)
		{
			bRes=FitPane();
			if(bRes)
			{
				SetWindowText(m_pActive->Text());
				CDWSettings setting;
				if(bAnimate && setting.IsAnimationEnabled())
					AnimateWindow(animateTimeout,true);
				else
					bRes=(SetWindowPos(HWND_TOP,0,0,0,0,
											SWP_NOMOVE | SWP_NOSIZE |
											SWP_SHOWWINDOW | SWP_FRAMECHANGED )!=FALSE);
				if(bRes)
				{
					BOOL dummy;
					OnSize(0,0,0,dummy);
					bRes=(SetTimer(tmID,tmTimeout)==tmID);
				}
			}
		}
		assert(bRes);
		return bRes;
	}

	bool Vanish(bool bAnimate=false)
	{
		bool bRes=(m_pActive==0);
		if(!bRes)
		{
			KillTimer(tmID);
			::ShowWindow(m_pActive->Wnd(),SW_HIDE);
			m_pActive=0;
			CDWSettings setting;
			if(bAnimate && setting.IsAnimationEnabled())
				AnimateWindow(animateTimeout,false);
			bRes=ShowWindow(SW_HIDE)!=FALSE;
		}
		return bRes;
	}
///////////////////////////////////////////////////////////
	void StartResizing(const CPoint& pt)
	{
		std::auto_ptr<CSizeTrackerFull> pTracker;
		CDWSettings settings;
		if(settings.GhostDrag())
		{
			CRect rc;
			GetWindowRect(&rc);
			CSplitterBar splitter(IsHorizontal());
			splitter.CalculateRect(rc,m_side.Side());
			pTracker=std::auto_ptr<CSizeTrackerFull>(
								new CSizeTrackerGhost(m_hWnd,pt,Orientation(),splitter,m_rcBound));
		}
		else
			pTracker=std::auto_ptr<CSizeTrackerFull>(
								new CSizeTrackerFull(m_hWnd,pt,Orientation(),m_splitter.GetThickness(),m_rcBound));

		HWND hWndParent=GetParent();
		assert(hWndParent);
		TrackDragAndDrop(*pTracker,hWndParent);
	}

	bool PinBtnPress()
	{
		assert(m_pActive);
		return Remove(m_pActive->Wnd(),true);
	}

	bool OnClosing()
	{
		assert(m_pActive);
		::PostMessage(m_pActive->Wnd(),WM_CLOSE,NULL,NULL);
		return true;
	}

	DECLARE_WND_CLASS(_T("CAutoHideManager"))
protected:
	BEGIN_MSG_MAP(thisClass)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_TIMER,OnTimer)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
/////////////////
		MESSAGE_HANDLER(WMDF_DOCK,OnDock)
		CHAIN_MSG_MAP(baseClass)
	END_MSG_MAP()

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = false;
		Vanish(false);
		return 0;
	}

	LRESULT OnTimer(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		POINT pt;
		CRect rc;
		GetCursorPos(&pt);
		GetWindowRect(&rc);
		if(!rc.PtInRect(pt))
		{
			CWindow wndParent (GetParent());
			wndParent.ScreenToClient(&pt);

			IPinnedLabel::CPinnedWindow* ptr=LocatePinnedWindow(pt);
			if(ptr==0 || IsVisualizationNeeded(ptr))
			{
				HWND hWnd=GetFocus();
				while( hWnd!=m_hWnd )
				{
					if(hWnd==NULL)
					{
						Vanish(true);
							break;
					}
					hWnd=::GetParent(hWnd);
				}
			}
		}
		return 0;
	}

    LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
    {
        if(wParam != SIZE_MINIMIZED && (m_pActive!=0))
        {
			CRect rc;
			GetClientRect(&rc);
			::SetWindowPos(m_pActive->Wnd(),NULL,
							 rc.left,rc.top,
							 rc.Width(),rc.Height(),
							 SWP_NOZORDER | SWP_NOACTIVATE);
			GetWindowRect(&rc);
			long width = (IsHorizontal())	? rc.Height() : rc.Width();
			width -= m_splitter.GetThickness();
			if(width>m_caption.GetThickness()/*0*/)
				m_pActive->Width(width);
        }
        bHandled = FALSE;
        return 1;
    }
    LRESULT OnDock(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
    {
		LRESULT lRes=FALSE;
		DFMHDR* pHdr=reinterpret_cast<DFMHDR*>(lParam);
		switch(pHdr->code)
		{
			case DC_UNDOCK:
				assert(::IsWindow(pHdr->hWnd));
				lRes=Remove(pHdr->hWnd);
				break;
		}
		return lRes;
	}
protected:
	long							m_barThickness;
	IPinnedLabel::CPinnedWindow*	m_pActive;
	IPinnedLabel::CPinnedWindow*	m_pTracked;
	CRect							m_rcBound;
	CAutoHideBar					m_bars[barsCount];
};

}//namespace dockwins
#endif // __WTL_DW__DWAUTOHIDE_H__

⌨️ 快捷键说明

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