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

📄 dockingwindow.h

📁 一款最完整的工业组态软源代码
💻 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__DOCKINGWINDOW_H__
#define __WTL_DW__DOCKINGWINDOW_H__

#pragma once

#include "DDTracker.h"

namespace dockwins{

class CDocker : protected CWindow
{
public:
	explicit CDocker(HWND hWnd=NULL) : CWindow(hWnd)
	{
	}
	bool AdjustDragRect(DFDOCKRECT* pHdr) const
	{
		pHdr->hdr.code=DC_ADJUSTDRAGRECT;
		return (::SendMessage(m_hWnd,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
	}
	bool AcceptDock(DFDOCKRECT* pHdr) const
	{
		pHdr->hdr.code=DC_ACCEPT;
		return (::SendMessage(m_hWnd,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
	}
	bool Dock(DFDOCKRECT* pHdr) const
	{
		pHdr->hdr.code=DC_DOCK;
//		return (::SendMessage(m_hWnd,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
		return (::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
	}

	bool Undock(DFMHDR* pHdr) const
	{
		pHdr->code=DC_UNDOCK;
		return (::SendMessage(pHdr->hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
	}

    bool Replace(DFDOCKREPLACE* pHdr) const
    {
        pHdr->hdr.code=DC_REPLACE;
        return (::SendMessage(pHdr->hdr.hBar,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
    }

	bool GetDockingPosition(DFDOCKPOS* pHdr) const
	{
		pHdr->hdr.code=DC_GETDOCKPOSITION;
		return (::SendMessage(m_hWnd,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
	}

	bool SetDockingPosition(DFDOCKPOS* pHdr) const
	{
		pHdr->hdr.hBar=m_hWnd;
		pHdr->hdr.code=DC_SETDOCKPOSITION;
		return (::SendMessage(m_hWnd,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
	}
//#ifdef DF_AUTO_HIDE_FEATURES
	bool PinUp(DFPINUP* pHdr) const
	{
		pHdr->hdr.code=DC_PINUP;
		return (::SendMessage(m_hWnd,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
	}

	bool IsPinned(DFMHDR* pHdr) const
	{
		pHdr->code=DC_ISPINNED;
		return (::SendMessage(m_hWnd,WMDF_DOCK,NULL,reinterpret_cast<LPARAM>(pHdr))!=FALSE);
	}
//#endif
	operator HWND ()
	{
		return m_hWnd;
	}
};

template < DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0>
struct CDockingBarWinTraits : CWinTraits<t_dwStyle,t_dwExStyle>
{
	typedef dockwins::CDocker CDocker;
};

typedef CDockingBarWinTraits<WS_OVERLAPPEDWINDOW| WS_POPUP/* WS_CHILD*/ | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,WS_EX_TOOLWINDOW/* WS_EX_CLIENTEDGE*/>    CSimpleDockingBarWinTraits;

template <class T,
          class TBase = CWindow,
          class TWinTraits = CSimpleDockingBarWinTraits>
class ATL_NO_VTABLE CDockingWindowBaseImpl : public CWindowImpl< T, TBase, TWinTraits >
{
    typedef CWindowImpl< T, TBase, TWinTraits >   baseClass;
    typedef CDockingWindowBaseImpl< T, TBase, TWinTraits >       thisClass;
	typedef typename TWinTraits::CDocker	CDocker;
protected:
	class CGhostMoveTracker : public CDDTrackerBaseT<CGhostMoveTracker>
	{
//probably better use GetSystemMetrics
        enum{GhostRectSideSize=3};
	public:
		CGhostMoveTracker(const CDocker& docker,const POINT& pt,DFDOCKRECT& dockHdr)
			:m_docker(docker),m_dockHdr(dockHdr),m_dc(::GetWindowDC(NULL))
		{
			m_offset.cx=m_dockHdr.rect.left-pt.x;
			m_offset.cy=m_dockHdr.rect.top-pt.y;
			m_size.cx=m_dockHdr.rect.right-m_dockHdr.rect.left;
			m_size.cy=m_dockHdr.rect.bottom-m_dockHdr.rect.top;
		}
		void DrawGhostRect(CDC& dc,RECT* pRect)
		{
			CBrush brush((HBRUSH)CDCHandle::GetHalftoneBrush());
			if(!brush.IsNull())
			{
				HBRUSH hBrushOld = dc.SelectBrush(brush);

				dc.PatBlt(pRect->left, pRect->top,
						  pRect->right-pRect->left,GhostRectSideSize, PATINVERT);
				dc.PatBlt(pRect->left, pRect->bottom-GhostRectSideSize,
						  pRect->right-pRect->left,GhostRectSideSize, PATINVERT);

				dc.PatBlt(pRect->left, pRect->top+GhostRectSideSize,
						  GhostRectSideSize,pRect->bottom-pRect->top-2*GhostRectSideSize, PATINVERT);
				dc.PatBlt(pRect->right-GhostRectSideSize, pRect->top+GhostRectSideSize,
						  GhostRectSideSize,pRect->bottom-pRect->top-2*GhostRectSideSize, PATINVERT);


				dc.SelectBrush(hBrushOld);
			}

		}
		void CleanGhostRect(CDC& dc,RECT* pRect)
		{
			DrawGhostRect(dc,pRect);
		}
		void BeginDrag()
		{
			DrawGhostRect(m_dc,&m_dockHdr.rect);
		}
		void EndDrag(bool /*bCanceled*/)
		{
			CleanGhostRect(m_dc,&m_dockHdr.rect);
		}
		void OnMove(long x, long y)
		{
			CleanGhostRect(m_dc,&m_dockHdr.rect);
			m_dockHdr.rect.left=x;
			m_dockHdr.rect.top=y;
			::ClientToScreen(m_dockHdr.hdr.hWnd,reinterpret_cast<POINT*>(&m_dockHdr.rect));
			m_dockHdr.rect.right=m_dockHdr.rect.left+m_size.cx;
			m_dockHdr.rect.bottom=m_dockHdr.rect.top+m_size.cy;
			m_docker.AdjustDragRect(&m_dockHdr);
			if((GetKeyState(VK_CONTROL) & 0x8000) || !m_docker.AcceptDock(&m_dockHdr))
			{
				m_dockHdr.hdr.hBar=HNONDOCKBAR;
				m_dockHdr.rect.left=x+m_offset.cx;
				m_dockHdr.rect.top=y+m_offset.cy;
				m_dockHdr.rect.right=m_dockHdr.rect.left+m_size.cx;
				m_dockHdr.rect.bottom=m_dockHdr.rect.top+m_size.cy;
			}
			DrawGhostRect(m_dc,&m_dockHdr.rect);
		}
		bool ProcessWindowMessage(MSG* pMsg)
		{
			bool bHandled=false;
			switch(pMsg->message)
			{
				case WM_KEYDOWN:
				case WM_KEYUP:
					if(pMsg->wParam==VK_CONTROL)
					{
						CPoint point(pMsg->pt.x,pMsg->pt.y);
						::ScreenToClient(m_dockHdr.hdr.hWnd,&point);
						OnMove(point.x,point.y);
						bHandled=true;
					}
					break;
			}
		   return bHandled;
		}
	protected:
		const CDocker&	m_docker;
		CDC				m_dc;
		DFDOCKRECT&		m_dockHdr;
		SIZE			m_size;
		SIZE			m_offset;
	};
public:
	CDockingWindowBaseImpl()
		:m_hBarOwner(HNONDOCKBAR)
	{
		m_rcUndock.SetRectEmpty();
	}

	HWND Create(HWND hDockingFrameWnd, RECT& rcPos, LPCTSTR szWindowName = NULL,
		DWORD dwStyle = 0, DWORD dwExStyle = 0,
		UINT nID = 0, LPVOID lpCreateParam = NULL)
	{
		m_docker=CDocker(hDockingFrameWnd);
		return baseClass::Create(hDockingFrameWnd, rcPos, szWindowName ,
									dwStyle , dwExStyle , nID , lpCreateParam);
	}
#ifdef DF_AUTO_HIDE_FEATURES
	BOOL IsWindowVisible() const
	{
		BOOL bRes=IsPinned();
		if(!bRes)
			bRes=baseClass::IsWindowVisible();
		return bRes;
	}
	bool IsPinned() const
	{
		bool bRes=IsDocking();
		if(bRes)
		{
			DFMHDR dockHdr;
//			dockHdr.code=DC_ISPINNED;
			dockHdr.hWnd=m_hWnd;
			dockHdr.hBar=GetOwnerDockingBar();
			bRes=m_docker.IsPinned(&dockHdr);
		}
		return bRes;
	}
#endif
	HDOCKBAR GetOwnerDockingBar() const
	{
		return m_hBarOwner;
	}

	bool GetDockingPosition(DFDOCKPOS* pHdr) const
	{
		assert(::IsWindow(m_hWnd));
		bool bRes=true;
		pHdr->hdr.hBar=GetOwnerDockingBar();
		if(IsDocking())
		{
			pHdr->hdr.hWnd=m_hWnd;
//		    pHdr->hdr.code=DC_GETDOCKPOSITION;
			bRes=m_docker.GetDockingPosition(pHdr);
		}
		return bRes;
	}

	bool GetDockingWindowPlacement(DFDOCKPOSEX* pHdr) const
	{
		bool bRes=true;
		pHdr->bDocking=IsDocking();
		if(pHdr->bDocking)
		{
			::CopyRect(&pHdr->rect,&m_rcUndock);
			bRes=GetDockingPosition(&(pHdr->dockPos));
		}
		else
			GetWindowRect(&pHdr->rect);
		return bRes;
	}
	bool SetDockingPosition(DFDOCKPOS* pHdr)
	{
		assert(::IsWindow(m_hWnd));
		if(IsDocking())
					Undock();
		pHdr->hdr.hWnd=m_hWnd;
//	    pHdr->hdr.code=DC_SETDOCKPOSITION;
		return m_docker.SetDockingPosition(pHdr);
	}

	bool SetDockingWindowPlacement(DFDOCKPOSEX* pHdr)
	{
		bool bRes=true;
		if(pHdr->bDocking)
		{
			bRes=SetDockingPosition(&(pHdr->dockPos));
			::CopyRect(&m_rcUndock,&pHdr->rect);
		}
		else
		{
			if(IsDocking())
						Undock();
			bRes=(SetWindowPos(HWND_TOP,&(pHdr->rect),SWP_SHOWWINDOW | SWP_NOACTIVATE)!=FALSE);
		}
		return bRes;
	}

	bool IsDocking() const
	{
		return GetOwnerDockingBar()!=HNONDOCKBAR;
	}

	bool Float(LPCRECT pRc,UINT flags=SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_FRAMECHANGED,HWND hWndInsertAfter=HWND_TOP)
	{
		bool bRes=IsDocking();
		if(bRes)
		{
			if(Undock())
				bRes=(SetWindowPos(hWndInsertAfter,pRc,flags)!=FALSE);
		}
		return bRes;
	}

	bool Float()
	{
		bool bRes=!m_rcUndock.IsRectEmpty();
		if(bRes)
			bRes=Float(&m_rcUndock);
		return bRes;
	}

	virtual bool Undock()
	{
		assert(IsDocking());
		DFMHDR dockHdr;
//		dockHdr.code=DC_UNDOCK;
		dockHdr.hWnd=m_hWnd;
		dockHdr.hBar=GetOwnerDockingBar();
		return m_docker.Undock(&dockHdr);
	}

	bool OnClosing()
	{
		bool bRes=true;
		if(IsDocking())
			bRes=Undock();
		return bRes;
	}

	virtual bool DockMe(DFDOCKRECT* pHdr)
	{
		return m_docker.Dock(pHdr);
	}

    bool BeginMoving(const POINT& point)
    {
		DFDOCKRECT dockHdr;
//		dockHdr.hdr.code=DC_ACCEPT;
		dockHdr.hdr.hWnd=m_hWnd;
		dockHdr.hdr.hBar=HNONDOCKBAR;//GetOwnerDockingBar();

		if(m_rcUndock.IsRectEmpty())
		{
			GetWindowRect(&dockHdr.rect);
//			dockHdr.hdr.code=DC_ADJUSTDRAGRECT;
			m_docker.AdjustDragRect(&dockHdr);
			m_rcUndock.CopyRect(&dockHdr.rect);
		}
		GetWindowRect(&dockHdr.rect);
		CPoint pt(point);
		ClientToScreen(&pt);

		float ratio=float(pt.x-dockHdr.rect.left)/(dockHdr.rect.right-dockHdr.rect.left);
		dockHdr.rect.left=pt.x-long(ratio*m_rcUndock.Width());
		ratio=float(pt.y-dockHdr.rect.top)/(dockHdr.rect.bottom-dockHdr.rect.top);
		dockHdr.rect.top=pt.y-long(ratio*m_rcUndock.Height());

		dockHdr.rect.right=dockHdr.rect.left+m_rcUndock.Width();
		dockHdr.rect.bottom=dockHdr.rect.top+m_rcUndock.Height();

		CGhostMoveTracker tracker(m_docker,point,dockHdr);
		if(TrackDragAndDrop(tracker,m_hWnd))
		{

			CPoint ptCur;
			::GetCursorPos(&ptCur);
			if((dockHdr.hdr.hBar!=HNONDOCKBAR)
				|| (ptCur.x!=pt.x) || (ptCur.y!=pt.y))
			{
				if(IsDocking())
							Undock();
				if(dockHdr.hdr.hBar!=HNONDOCKBAR)
//						m_docker.Dock(&dockHdr);
					DockMe(&dockHdr);
				else
					SetWindowPos(HWND_TOP,&(dockHdr.rect),SWP_SHOWWINDOW | SWP_FRAMECHANGED);
			}
		}
		return true;
	}
	void OnDocked(HDOCKBAR hBar,bool /*bHorizontal*/)

⌨️ 快捷键说明

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