From 6d7bff2476459049f4f554291a680e0f6003ea66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 7 Jun 2015 21:10:18 +0200 Subject: GH-1060 remove updater code --- mmc_updater/depends/win32cpp/docking.h | 4214 -------------------------------- 1 file changed, 4214 deletions(-) delete mode 100644 mmc_updater/depends/win32cpp/docking.h (limited to 'mmc_updater/depends/win32cpp/docking.h') diff --git a/mmc_updater/depends/win32cpp/docking.h b/mmc_updater/depends/win32cpp/docking.h deleted file mode 100644 index 9e7c4486..00000000 --- a/mmc_updater/depends/win32cpp/docking.h +++ /dev/null @@ -1,4214 +0,0 @@ -// Win32++ Version 7.2 -// Released: 5th AUgust 2011 -// -// David Nash -// email: dnash@bigpond.net.au -// url: https://sourceforge.net/projects/win32-framework -// -// -// Copyright (c) 2005-2011 David Nash -// -// Permission is hereby granted, free of charge, to -// any person obtaining a copy of this software and -// associated documentation files (the "Software"), -// to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, -// merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom -// the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice -// shall be included in all copies or substantial portions -// of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. -// -//////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////// -// docking.h -// Declaration of the CDocker class - -#ifndef _WIN32XX_DOCKING_H_ -#define _WIN32XX_DOCKING_H_ - - -#include "wincore.h" -#include "gdi.h" -#include "toolbar.h" -#include "tab.h" -#include "frame.h" -#include "default_resource.h" - - -// Docking Styles -#define DS_DOCKED_LEFT 0x0001 // Dock the child left -#define DS_DOCKED_RIGHT 0x0002 // Dock the child right -#define DS_DOCKED_TOP 0x0004 // Dock the child top -#define DS_DOCKED_BOTTOM 0x0008 // Dock the child bottom -#define DS_NO_DOCKCHILD_LEFT 0x0010 // Prevent a child docking left -#define DS_NO_DOCKCHILD_RIGHT 0x0020 // Prevent a child docking right -#define DS_NO_DOCKCHILD_TOP 0x0040 // Prevent a child docking at the top -#define DS_NO_DOCKCHILD_BOTTOM 0x0080 // Prevent a child docking at the bottom -#define DS_NO_RESIZE 0x0100 // Prevent resizing -#define DS_NO_CAPTION 0x0200 // Prevent display of caption when docked -#define DS_NO_CLOSE 0x0400 // Prevent closing of a docker while docked -#define DS_NO_UNDOCK 0x0800 // Prevent undocking and dock closing -#define DS_CLIENTEDGE 0x1000 // Has a 3D border when docked -#define DS_FIXED_RESIZE 0x2000 // Perfomed a fixed resize instead of a proportional resize on dock children -#define DS_DOCKED_CONTAINER 0x4000 // Dock a container within a container -#define DS_DOCKED_LEFTMOST 0x10000 // Leftmost outer docking -#define DS_DOCKED_RIGHTMOST 0x20000 // Rightmost outer docking -#define DS_DOCKED_TOPMOST 0x40000 // Topmost outer docking -#define DS_DOCKED_BOTTOMMOST 0x80000 // Bottommost outer docking - -// Required for Dev-C++ -#ifndef TME_NONCLIENT - #define TME_NONCLIENT 0x00000010 -#endif -#ifndef TME_LEAVE - #define TME_LEAVE 0x000000002 -#endif -#ifndef WM_NCMOUSELEAVE - #define WM_NCMOUSELEAVE 0x000002A2 -#endif - -namespace Win32xx -{ - // Class declarations - class CDockContainer; - class CDocker; - - typedef Shared_Ptr DockPtr; - - struct ContainerInfo - { - TCHAR szTitle[MAX_MENU_STRING]; - int iImage; - CDockContainer* pContainer; - }; - - /////////////////////////////////////// - // Declaration of the CDockContainer class - // A CDockContainer is a CTab window. A CTab has a view window, and optionally a toolbar control. - // A top level CDockContainer can contain other CDockContainers. The view for each container - // (including the top level container) along with possibly its toolbar, is displayed - // within the container parent's view page. - class CDockContainer : public CTab - { - public: - - // Nested class. This is the Wnd for the window displayed over the client area - // of the tab control. The toolbar and view window are child windows of the - // viewpage window. Only the ViewPage of the parent CDockContainer is displayed. It's - // contents are updated with the view window of the relevant container whenever - // a different tab is selected. - class CViewPage : public CWnd - { - - public: - CViewPage() : m_pView(NULL), m_pTab(NULL) {} - virtual ~CViewPage() {} - virtual CToolBar& GetToolBar() const {return (CToolBar&)m_ToolBar;} - virtual CWnd* GetView() const {return m_pView;} - virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); - virtual void OnCreate(); - virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam); - virtual void PreRegisterClass(WNDCLASS &wc); - virtual void RecalcLayout(); - virtual void SetView(CWnd& wndView); - virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam); - - CWnd* GetTabCtrl() const { return m_pTab;} - - private: - CToolBar m_ToolBar; - tString m_tsTooltip; - CWnd* m_pView; - CWnd* m_pTab; - }; - - public: - CDockContainer(); - virtual ~CDockContainer(); - virtual void AddContainer(CDockContainer* pContainer); - virtual void AddToolBarButton(UINT nID, BOOL bEnabled = TRUE); - virtual CDockContainer* GetContainerFromIndex(UINT nPage); - virtual CDockContainer* GetContainerFromView(CWnd* pView) const; - virtual int GetContainerIndex(CDockContainer* pContainer); - virtual SIZE GetMaxTabTextSize(); - virtual CViewPage& GetViewPage() const { return (CViewPage&)m_ViewPage; } - virtual void RecalcLayout(); - virtual void RemoveContainer(CDockContainer* pWnd); - virtual void SelectPage(int nPage); - virtual void SetTabSize(); - virtual void SetupToolBar(); - - // Attributes - CDockContainer* GetActiveContainer() const {return GetContainerFromView(GetActiveView());} - CWnd* GetActiveView() const; - std::vector& GetAllContainers() const {return m_pContainerParent->m_vContainerInfo;} - CDockContainer* GetContainerParent() const { return m_pContainerParent; } - CString& GetDockCaption() const { return (CString&)m_csCaption; } - HICON GetTabIcon() const { return m_hTabIcon; } - LPCTSTR GetTabText() const { return m_tsTabText.c_str(); } - virtual CToolBar& GetToolBar() const { return GetViewPage().GetToolBar(); } - CWnd* GetView() const { return GetViewPage().GetView(); } - void SetActiveContainer(CDockContainer* pContainer); - void SetDockCaption(LPCTSTR szCaption) { m_csCaption = szCaption; } - void SetTabIcon(HICON hTabIcon) { m_hTabIcon = hTabIcon; } - void SetTabIcon(UINT nID_Icon); - void SetTabIcon(int i, HICON hIcon) { CTab::SetTabIcon(i, hIcon); } - void SetTabText(LPCTSTR szText) { m_tsTabText = szText; } - void SetTabText(UINT nTab, LPCTSTR szText); - void SetView(CWnd& Wnd); - - protected: - virtual void OnCreate(); - virtual void OnLButtonDown(WPARAM wParam, LPARAM lParam); - virtual void OnLButtonUp(WPARAM wParam, LPARAM lParam); - virtual void OnMouseLeave(WPARAM wParam, LPARAM lParam); - virtual LRESULT OnNotifyReflect(WPARAM wParam, LPARAM lParam); - virtual void PreCreate(CREATESTRUCT &cs); - virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam); - - private: - std::vector m_vContainerInfo; - tString m_tsTabText; - CString m_csCaption; - CViewPage m_ViewPage; - int m_iCurrentPage; - CDockContainer* m_pContainerParent; - HICON m_hTabIcon; - int m_nTabPressed; - - }; - - typedef struct DRAGPOS - { - NMHDR hdr; - POINT ptPos; - UINT DockZone; - } *LPDRAGPOS; - - - ///////////////////////////////////////// - // Declaration of the CDocker class - // A CDocker window allows other CDocker windows to be "docked" inside it. - // A CDocker can dock on the top, left, right or bottom side of a parent CDocker. - // There is no theoretical limit to the number of CDockers within CDockers. - class CDocker : public CWnd - { - public: - // A nested class for the splitter bar that seperates the docked panes. - class CDockBar : public CWnd - { - public: - CDockBar(); - virtual ~CDockBar(); - virtual void OnDraw(CDC* pDC); - virtual void PreCreate(CREATESTRUCT &cs); - virtual void PreRegisterClass(WNDCLASS& wc); - virtual void SendNotify(UINT nMessageID); - virtual void SetColor(COLORREF color); - virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam); - - CDocker* GetDock() {return m_pDock;} - int GetWidth() {return m_DockBarWidth;} - void SetDock(CDocker* pDock) {m_pDock = pDock;} - void SetWidth(int nWidth) {m_DockBarWidth = nWidth;} - - private: - CDockBar(const CDockBar&); // Disable copy construction - CDockBar& operator = (const CDockBar&); // Disable assignment operator - - CDocker* m_pDock; - DRAGPOS m_DragPos; - CBrush m_brBackground; - int m_DockBarWidth; - }; - - // A nested class for the window inside a CDocker which includes all of this docked client. - // It's the remaining part of the CDocker that doesn't belong to the CDocker's children. - // The Docker's view window is a child window of CDockClient. - class CDockClient : public CWnd - { - public: - CDockClient(); - virtual ~CDockClient() {} - virtual void Draw3DBorder(RECT& Rect); - virtual void DrawCaption(WPARAM wParam); - virtual void DrawCloseButton(CDC& DrawDC, BOOL bFocus); - virtual CRect GetCloseRect(); - virtual void SendNotify(UINT nMessageID); - - CString& GetCaption() const { return (CString&)m_csCaption; } - CWnd* GetView() const { return m_pView; } - void SetDock(CDocker* pDock) { m_pDock = pDock;} - void SetCaption(LPCTSTR szCaption) { m_csCaption = szCaption; } - void SetCaptionColors(COLORREF Foregnd1, COLORREF Backgnd1, COLORREF ForeGnd2, COLORREF BackGnd2); - void SetClosePressed() { m_IsClosePressed = TRUE; } - void SetView(CWnd& Wnd) { m_pView = &Wnd; } - - protected: - virtual void OnLButtonDown(WPARAM wParam, LPARAM lParam); - virtual void OnLButtonUp(WPARAM wParam, LPARAM lParam); - virtual void OnMouseActivate(WPARAM wParam, LPARAM lParam); - virtual void OnMouseMove(WPARAM wParam, LPARAM lParam); - virtual void OnNCCalcSize(WPARAM& wParam, LPARAM& lParam); - virtual LRESULT OnNCHitTest(WPARAM wParam, LPARAM lParam); - virtual LRESULT OnNCLButtonDown(WPARAM wParam, LPARAM lParam); - virtual void OnNCMouseLeave(WPARAM wParam, LPARAM lParam); - virtual LRESULT OnNCMouseMove(WPARAM wParam, LPARAM lParam); - virtual LRESULT OnNCPaint(WPARAM wParam, LPARAM lParam); - virtual void OnWindowPosChanged(WPARAM wParam, LPARAM lParam); - virtual void PreRegisterClass(WNDCLASS& wc); - virtual void PreCreate(CREATESTRUCT& cs); - virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam); - - private: - CDockClient(const CDockClient&); // Disable copy construction - CDockClient& operator = (const CDockClient&); // Disable assignment operator - - CString m_csCaption; - CPoint m_Oldpt; - CDocker* m_pDock; - CWnd* m_pView; - BOOL m_IsClosePressed; - BOOL m_bOldFocus; - BOOL m_bCaptionPressed; - BOOL m_IsTracking; - COLORREF m_Foregnd1; - COLORREF m_Backgnd1; - COLORREF m_Foregnd2; - COLORREF m_Backgnd2; - }; - - // This nested class is used to indicate where a window could dock by - // displaying a blue tinted window. - class CDockHint : public CWnd - { - public: - CDockHint(); - virtual ~CDockHint(); - virtual RECT CalcHintRectContainer(CDocker* pDockTarget); - virtual RECT CalcHintRectInner(CDocker* pDockTarget, CDocker* pDockDrag, UINT uDockSide); - virtual RECT CalcHintRectOuter(CDocker* pDockDrag, UINT uDockSide); - virtual void DisplayHint(CDocker* pDockTarget, CDocker* pDockDrag, UINT uDockSide); - virtual void OnDraw(CDC* pDC); - virtual void PreCreate(CREATESTRUCT &cs); - virtual void ShowHintWindow(CDocker* pDockTarget, CRect rcHint); - - private: - CDockHint(const CDockHint&); // Disable copy construction - CDockHint& operator = (const CDockHint&); // Disable assignment operator - - CBitmap m_bmBlueTint; - UINT m_uDockSideOld; - }; - - class CTarget : public CWnd - { - public: - CTarget() {} - virtual ~CTarget(); - virtual void OnDraw(CDC* pDC); - virtual void PreCreate(CREATESTRUCT &cs); - - protected: - CBitmap m_bmImage; - - private: - CTarget(const CTarget&); // Disable copy construction - CTarget& operator = (const CTarget&); // Disable assignment operator - }; - - class CTargetCentre : public CTarget - { - public: - CTargetCentre(); - virtual ~CTargetCentre(); - virtual void OnDraw(CDC* pDC); - virtual void OnCreate(); - virtual BOOL CheckTarget(LPDRAGPOS pDragPos); - BOOL IsOverContainer() { return m_bIsOverContainer; } - - private: - CTargetCentre(const CTargetCentre&); // Disable copy construction - CTargetCentre& operator = (const CTargetCentre&); // Disable assignment operator - - BOOL m_bIsOverContainer; - CDocker* m_pOldDockTarget; - }; - - class CTargetLeft : public CTarget - { - public: - CTargetLeft() {m_bmImage.LoadImage(IDW_SDLEFT,0,0,0);} - virtual BOOL CheckTarget(LPDRAGPOS pDragPos); - - private: - CTargetLeft(const CTargetLeft&); // Disable copy construction - CTargetLeft& operator = (const CTargetLeft&); // Disable assignment operator - }; - - class CTargetTop : public CTarget - { - public: - CTargetTop() {m_bmImage.LoadImage(IDW_SDTOP,0,0,0);} - virtual BOOL CheckTarget(LPDRAGPOS pDragPos); - private: - CTargetTop(const CTargetTop&); // Disable copy construction - CTargetTop& operator = (const CTargetTop&); // Disable assignment operator - }; - - class CTargetRight : public CTarget - { - public: - CTargetRight() {m_bmImage.LoadImage(IDW_SDRIGHT,0,0,0);} - virtual BOOL CheckTarget(LPDRAGPOS pDragPos); - - private: - CTargetRight(const CTargetRight&); // Disable copy construction - CTargetRight& operator = (const CTargetRight&); // Disable assignment operator - }; - - class CTargetBottom : public CTarget - { - public: - CTargetBottom() {m_bmImage.LoadImage(IDW_SDBOTTOM,0,0,0);} - virtual BOOL CheckTarget(LPDRAGPOS pDragPos); - }; - - friend class CTargetCentre; - friend class CTargetLeft; - friend class CTargetTop; - friend class CTargetRight; - friend class CTargetBottom; - friend class CDockClient; - friend class CDockContainer; - - public: - // Operations - CDocker(); - virtual ~CDocker(); - virtual CDocker* AddDockedChild(CDocker* pDocker, DWORD dwDockStyle, int DockSize, int nDockID = 0); - virtual CDocker* AddUndockedChild(CDocker* pDocker, DWORD dwDockStyle, int DockSize, RECT rc, int nDockID = 0); - virtual void Close(); - virtual void CloseAllDockers(); - virtual void Dock(CDocker* pDocker, UINT uDockSide); - virtual void DockInContainer(CDocker* pDock, DWORD dwDockStyle); - virtual CDockContainer* GetContainer() const; - virtual CDocker* GetActiveDocker() const; - virtual CDocker* GetDockAncestor() const; - virtual CDocker* GetDockFromID(int n_DockID) const; - virtual CDocker* GetDockFromPoint(POINT pt) const; - virtual CDocker* GetDockFromView(CWnd* pView) const; - virtual CDocker* GetTopmostDocker() const; - virtual int GetDockSize() const; - virtual CTabbedMDI* GetTabbedMDI() const; - virtual int GetTextHeight(); - virtual void Hide(); - virtual BOOL LoadRegistrySettings(tString tsRegistryKeyName); - virtual void RecalcDockLayout(); - virtual BOOL SaveRegistrySettings(tString tsRegistryKeyName); - virtual void Undock(CPoint pt, BOOL bShowUndocked = TRUE); - virtual void UndockContainer(CDockContainer* pContainer, CPoint pt, BOOL bShowUndocked); - virtual BOOL VerifyDockers(); - - // Attributes - virtual CDockBar& GetDockBar() const {return (CDockBar&)m_DockBar;} - virtual CDockClient& GetDockClient() const {return (CDockClient&)m_DockClient;} - virtual CDockHint& GetDockHint() const {return m_pDockAncestor->m_DockHint;} - - - std::vector & GetAllDockers() const {return GetDockAncestor()->m_vAllDockers;} - int GetBarWidth() const {return GetDockBar().GetWidth();} - CString& GetCaption() const {return GetDockClient().GetCaption();} - std::vector & GetDockChildren() const {return (std::vector &)m_vDockChildren;} - int GetDockID() const {return m_nDockID;} - CDocker* GetDockParent() const {return m_pDockParent;} - DWORD GetDockStyle() const {return m_DockStyle;} - CWnd* GetView() const {return GetDockClient().GetView();} - BOOL IsChildOfDocker(CWnd* pWnd) const; - BOOL IsDocked() const; - BOOL IsDragAutoResize(); - BOOL IsRelated(CWnd* pWnd) const; - BOOL IsUndocked() const; - void SetBarColor(COLORREF color) {GetDockBar().SetColor(color);} - void SetBarWidth(int nWidth) {GetDockBar().SetWidth(nWidth);} - void SetCaption(LPCTSTR szCaption); - void SetCaptionColors(COLORREF Foregnd1, COLORREF Backgnd1, COLORREF ForeGnd2, COLORREF BackGnd2); - void SetCaptionHeight(int nHeight); - void SetDockStyle(DWORD dwDockStyle); - void SetDockSize(int DockSize); - void SetDragAutoResize(BOOL bAutoResize); - void SetView(CWnd& wndView); - - protected: - virtual CDocker* NewDockerFromID(int idDock); - virtual void OnActivate(WPARAM wParam, LPARAM lParam); - virtual void OnCaptionTimer(WPARAM wParam, LPARAM lParam); - virtual void OnCreate(); - virtual void OnDestroy(WPARAM wParam, LPARAM lParam); - virtual void OnDockDestroyed(WPARAM wParam, LPARAM lParam); - virtual void OnExitSizeMove(WPARAM wParam, LPARAM lParam); - virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam); - virtual void OnSetFocus(WPARAM wParam, LPARAM lParam); - virtual void OnSysColorChange(WPARAM wParam, LPARAM lParam); - virtual LRESULT OnSysCommand(WPARAM wParam, LPARAM lParam); - virtual LRESULT OnWindowPosChanging(WPARAM wParam, LPARAM lParam); - virtual void OnWindowPosChanged(WPARAM wParam, LPARAM lParam); - virtual void PreCreate(CREATESTRUCT &cs); - virtual void PreRegisterClass(WNDCLASS &wc); - virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam); - - private: - CDocker(const CDocker&); // Disable copy construction - CDocker& operator = (const CDocker&); // Disable assignment operator - void CheckAllTargets(LPDRAGPOS pDragPos); - void CloseAllTargets(); - void DockOuter(CDocker* pDocker, DWORD dwDockStyle); - void DrawAllCaptions(); - void DrawHashBar(HWND hBar, POINT Pos); - void ConvertToChild(HWND hWndParent); - void ConvertToPopup(RECT rc); - void MoveDockChildren(CDocker* pDockTarget); - void PromoteFirstChild(); - void RecalcDockChildLayout(CRect rc); - void ResizeDockers(LPDRAGPOS pdp); - CDocker* SeparateFromDock(); - void SendNotify(UINT nMessageID); - void SetUndockPosition(CPoint pt); - std::vector SortDockers(); - - CDockBar m_DockBar; - CDockHint m_DockHint; - CDockClient m_DockClient; - CTargetCentre m_TargetCentre; - CTargetLeft m_TargetLeft; - CTargetTop m_TargetTop; - CTargetRight m_TargetRight; - CPoint m_OldPoint; - CTargetBottom m_TargetBottom; - CDocker* m_pDockParent; - CDocker* m_pDockAncestor; - CDocker* m_pDockActive; - - std::vector m_vDockChildren; - std::vector m_vAllDockers; // Only used in DockAncestor - - CRect m_rcBar; - CRect m_rcChild; - - BOOL m_BlockMove; - BOOL m_Undocking; - BOOL m_bIsClosing; - BOOL m_bIsDragging; - BOOL m_bDragAutoResize; - int m_DockStartSize; - int m_nDockID; - int m_nTimerCount; - int m_NCHeight; - DWORD m_dwDockZone; - double m_DockSizeRatio; - DWORD m_DockStyle; - HWND m_hOldFocus; - - }; // class CDocker - - struct DockInfo - { - DWORD DockStyle; - int DockSize; - int DockID; - int DockParentID; - RECT Rect; - }; - -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -namespace Win32xx -{ - - ///////////////////////////////////////////////////////////// - // Definitions for the CDockBar class nested within CDocker - // - inline CDocker::CDockBar::CDockBar() : m_pDock(NULL), m_DockBarWidth(4) - { - m_brBackground.CreateSolidBrush(RGB(192,192,192)); - } - - inline CDocker::CDockBar::~CDockBar() - { - } - - inline void CDocker::CDockBar::OnDraw(CDC* pDC) - { - CRect rcClient = GetClientRect(); - pDC->SelectObject(&m_brBackground); - pDC->PatBlt(0, 0, rcClient.Width(), rcClient.Height(), PATCOPY); - } - - inline void CDocker::CDockBar::PreCreate(CREATESTRUCT &cs) - { - // Create a child window, initially hidden - cs.style = WS_CHILD; - } - - inline void CDocker::CDockBar::PreRegisterClass(WNDCLASS& wc) - { - wc.lpszClassName = _T("Win32++ Bar"); - wc.hbrBackground = m_brBackground; - } - - inline void CDocker::CDockBar::SendNotify(UINT nMessageID) - { - // Send a splitter bar notification to the parent - m_DragPos.hdr.code = nMessageID; - m_DragPos.hdr.hwndFrom = m_hWnd; - m_DragPos.ptPos = GetCursorPos(); - m_DragPos.ptPos.x += 1; - GetParent()->SendMessage(WM_NOTIFY, 0L, (LPARAM)&m_DragPos); - } - - inline void CDocker::CDockBar::SetColor(COLORREF color) - { - // Useful colors: - // GetSysColor(COLOR_BTNFACE) // Default Grey - // RGB(196, 215, 250) // Default Blue - - m_brBackground.CreateSolidBrush(color); - } - - inline LRESULT CDocker::CDockBar::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - { - switch (uMsg) - { - case WM_SETCURSOR: - { - if (!(m_pDock->GetDockStyle() & DS_NO_RESIZE)) - { - HCURSOR hCursor; - DWORD dwSide = GetDock()->GetDockStyle() & 0xF; - if ((dwSide == DS_DOCKED_LEFT) || (dwSide == DS_DOCKED_RIGHT)) - hCursor = LoadCursor(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(IDW_SPLITH)); - else - hCursor = LoadCursor(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(IDW_SPLITV)); - - if (hCursor) SetCursor(hCursor); - else TRACE(_T("**WARNING** Missing cursor resource for slider bar\n")); - - return TRUE; - } - else - SetCursor(LoadCursor(NULL, IDC_ARROW)); - } - break; - - case WM_ERASEBKGND: - return 0; - - case WM_LBUTTONDOWN: - { - if (!(m_pDock->GetDockStyle() & DS_NO_RESIZE)) - { - SendNotify(UWM_BAR_START); - SetCapture(); - } - } - break; - - case WM_LBUTTONUP: - if (!(m_pDock->GetDockStyle() & DS_NO_RESIZE) && (GetCapture() == this)) - { - SendNotify(UWM_BAR_END); - ReleaseCapture(); - } - break; - - case WM_MOUSEMOVE: - if (!(m_pDock->GetDockStyle() & DS_NO_RESIZE) && (GetCapture() == this)) - { - SendNotify(UWM_BAR_MOVE); - } - break; - } - } - - // pass unhandled messages on for default processing - return CWnd::WndProcDefault(uMsg, wParam, lParam); - } - - - //////////////////////////////////////////////////////////////// - // Definitions for the CDockClient class nested within CDocker - // - inline CDocker::CDockClient::CDockClient() : m_pView(0), m_IsClosePressed(FALSE), - m_bOldFocus(FALSE), m_bCaptionPressed(FALSE), m_IsTracking(FALSE) - { - m_Foregnd1 = RGB(32,32,32); - m_Backgnd1 = RGB(190,207,227); - m_Foregnd2 = GetSysColor(COLOR_BTNTEXT); - m_Backgnd2 = GetSysColor(COLOR_BTNFACE); - } - - inline void CDocker::CDockClient::Draw3DBorder(RECT& Rect) - { - // Imitates the drawing of the WS_EX_CLIENTEDGE extended style - // This draws a 2 pixel border around the specified Rect - CWindowDC dc(this); - CRect rcw = Rect; - dc.CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); - dc.MoveTo(0, rcw.Height()); - dc.LineTo(0, 0); - dc.LineTo(rcw.Width(), 0); - dc.CreatePen(PS_SOLID,1, GetSysColor(COLOR_3DDKSHADOW)); - dc.MoveTo(1, rcw.Height()-2); - dc.LineTo(1, 1); - dc.LineTo(rcw.Width()-2, 1); - dc.CreatePen(PS_SOLID,1, GetSysColor(COLOR_3DHILIGHT)); - dc.MoveTo(rcw.Width()-1, 0); - dc.LineTo(rcw.Width()-1, rcw.Height()-1); - dc.LineTo(0, rcw.Height()-1); - dc.CreatePen(PS_SOLID,1, GetSysColor(COLOR_3DLIGHT)); - dc.MoveTo(rcw.Width()-2, 1); - dc.LineTo(rcw.Width()-2, rcw.Height()-2); - dc.LineTo(1, rcw.Height()-2); - } - - inline CRect CDocker::CDockClient::GetCloseRect() - { - // Calculate the close rect position in screen co-ordinates - CRect rcClose; - - int gap = 4; - CRect rc = GetWindowRect(); - int cx = GetSystemMetrics(SM_CXSMICON); - int cy = GetSystemMetrics(SM_CYSMICON); - - rcClose.top = 2 + rc.top + m_pDock->m_NCHeight/2 - cy/2; - rcClose.bottom = 2 + rc.top + m_pDock->m_NCHeight/2 + cy/2; - rcClose.right = rc.right - gap; - rcClose.left = rcClose.right - cx; - -#if defined(WINVER) && defined (WS_EX_LAYOUTRTL) && (WINVER >= 0x0500) - if (GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_LAYOUTRTL) - { - rcClose.left = rc.left + gap; - rcClose.right = rcClose.left + cx; - } -#endif - - - return rcClose; - } - - inline void CDocker::CDockClient::DrawCaption(WPARAM wParam) - { - if (IsWindow() && m_pDock->IsDocked() && !(m_pDock->GetDockStyle() & DS_NO_CAPTION)) - { - BOOL bFocus = m_pDock->IsChildOfDocker(GetFocus()); - m_bOldFocus = FALSE; - - // Acquire the DC for our NonClient painting - CDC* pDC; - if ((wParam != 1) && (bFocus == m_bOldFocus)) - pDC = GetDCEx((HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN|DCX_PARENTCLIP); - else - pDC = GetWindowDC(); - - // Create and set up our memory DC - CRect rc = GetWindowRect(); - CMemDC dcMem(pDC); - int rcAdjust = (GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE)? 2 : 0; - int Width = MAX(rc.Width() -rcAdjust, 0); - int Height = m_pDock->m_NCHeight + rcAdjust; - dcMem.CreateCompatibleBitmap(pDC, Width, Height); - m_bOldFocus = bFocus; - - // Set the font for the title - NONCLIENTMETRICS info = {0}; - info.cbSize = GetSizeofNonClientMetrics(); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); - dcMem.CreateFontIndirect(&info.lfStatusFont); - - // Set the Colours - if (bFocus) - { - dcMem.SetTextColor(m_Foregnd1); - dcMem.CreateSolidBrush(m_Backgnd1); - dcMem.SetBkColor(m_Backgnd1); - } - else - { - dcMem.SetTextColor(m_Foregnd2); - dcMem.CreateSolidBrush(m_Backgnd2); - dcMem.SetBkColor(m_Backgnd2); - } - - // Draw the rectangle - dcMem.CreatePen(PS_SOLID, 1, RGB(160, 150, 140)); - dcMem.Rectangle(rcAdjust, rcAdjust, rc.Width() -rcAdjust, m_pDock->m_NCHeight +rcAdjust); - - // Display the caption - int cx = (m_pDock->GetDockStyle() & DS_NO_CLOSE)? 0 : GetSystemMetrics(SM_CXSMICON); - CRect rcText(4 +rcAdjust, rcAdjust, rc.Width() -4 - cx -rcAdjust, m_pDock->m_NCHeight +rcAdjust); - dcMem.DrawText(m_csCaption, m_csCaption.GetLength(), rcText, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS); - - // Draw the close button - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE)) - DrawCloseButton(dcMem, bFocus); - - // Draw the 3D border - if (GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE) - Draw3DBorder(rc); - - // Copy the Memory DC to the window's DC - pDC->BitBlt(rcAdjust, rcAdjust, Width, Height, &dcMem, rcAdjust, rcAdjust, SRCCOPY); - - // Required for Win98/WinME - pDC->Destroy(); - } - } - - inline void CDocker::CDockClient::DrawCloseButton(CDC& DrawDC, BOOL bFocus) - { - // The close button isn't displayed on Win95 - if (GetWinVersion() == 1400) return; - - if (m_pDock->IsDocked() && !(m_pDock->GetDockStyle() & DS_NO_CAPTION)) - { - // Determine the close button's drawing position relative to the window - CRect rcClose = GetCloseRect(); - UINT uState = GetCloseRect().PtInRect(GetCursorPos())? m_IsClosePressed && IsLeftButtonDown()? 2 : 1 : 0; - ScreenToClient(rcClose); - - if (GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE) - { - rcClose.OffsetRect(2, m_pDock->m_NCHeight+2); - if (GetWindowRect().Height() < (m_pDock->m_NCHeight+4)) - rcClose.OffsetRect(-2, -2); - } - else - rcClose.OffsetRect(0, m_pDock->m_NCHeight-2); - - // Draw the outer highlight for the close button - if (!IsRectEmpty(&rcClose)) - { - switch (uState) - { - case 0: - { - // Normal button - DrawDC.CreatePen(PS_SOLID, 1, RGB(232, 228, 220)); - DrawDC.MoveTo(rcClose.left, rcClose.bottom); - DrawDC.LineTo(rcClose.right, rcClose.bottom); - DrawDC.LineTo(rcClose.right, rcClose.top); - DrawDC.LineTo(rcClose.left, rcClose.top); - DrawDC.LineTo(rcClose.left, rcClose.bottom); - break; - } - - case 1: - { - // Popped up button - // Draw outline, white at top, black on bottom - DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); - DrawDC.MoveTo(rcClose.left, rcClose.bottom); - DrawDC.LineTo(rcClose.right, rcClose.bottom); - DrawDC.LineTo(rcClose.right, rcClose.top); - DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); - DrawDC.LineTo(rcClose.left, rcClose.top); - DrawDC.LineTo(rcClose.left, rcClose.bottom); - } - - break; - case 2: - { - // Pressed button - // Draw outline, black on top, white on bottom - DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); - DrawDC.MoveTo(rcClose.left, rcClose.bottom); - DrawDC.LineTo(rcClose.right, rcClose.bottom); - DrawDC.LineTo(rcClose.right, rcClose.top); - DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); - DrawDC.LineTo(rcClose.left, rcClose.top); - DrawDC.LineTo(rcClose.left, rcClose.bottom); - } - break; - } - - // Manually Draw Close Button - if (bFocus) - DrawDC.CreatePen(PS_SOLID, 1, m_Foregnd1); - else - DrawDC.CreatePen(PS_SOLID, 1, m_Foregnd2); - - DrawDC.MoveTo(rcClose.left + 3, rcClose.top +3); - DrawDC.LineTo(rcClose.right - 2, rcClose.bottom -2); - - DrawDC.MoveTo(rcClose.left + 4, rcClose.top +3); - DrawDC.LineTo(rcClose.right - 2, rcClose.bottom -3); - - DrawDC.MoveTo(rcClose.left + 3, rcClose.top +4); - DrawDC.LineTo(rcClose.right - 3, rcClose.bottom -2); - - DrawDC.MoveTo(rcClose.right -3, rcClose.top +3); - DrawDC.LineTo(rcClose.left + 2, rcClose.bottom -2); - - DrawDC.MoveTo(rcClose.right -3, rcClose.top +4); - DrawDC.LineTo(rcClose.left + 3, rcClose.bottom -2); - - DrawDC.MoveTo(rcClose.right -4, rcClose.top +3); - DrawDC.LineTo(rcClose.left + 2, rcClose.bottom -3); - } - } - } - - inline void CDocker::CDockClient::OnNCCalcSize(WPARAM& wParam, LPARAM& lParam) - { - // Sets the non-client area (and hence sets the client area) - // This function modifies lParam - - UNREFERENCED_PARAMETER(wParam); - - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION)) - { - if (m_pDock->IsDocked()) - { - LPRECT rc = (LPRECT)lParam; - rc->top += m_pDock->m_NCHeight; - } - } - } - - inline LRESULT CDocker::CDockClient::OnNCHitTest(WPARAM wParam, LPARAM lParam) - { - // Identify which part of the non-client area the cursor is over - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION)) - { - if (m_pDock->IsDocked()) - { - CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - - // Indicate if the point is in the close button (except for Win95) - if ((GetWinVersion() > 1400) && (GetCloseRect().PtInRect(pt))) - return HTCLOSE; - - ScreenToClient(pt); - - // Indicate if the point is in the caption - if (pt.y < 0) - return HTCAPTION; - } - } - return CWnd::WndProcDefault(WM_NCHITTEST, wParam, lParam); - } - - inline LRESULT CDocker::CDockClient::OnNCLButtonDown(WPARAM wParam, LPARAM lParam) - { - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION)) - { - if ((HTCLOSE == wParam) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE)) - { - m_IsClosePressed = TRUE; - SetCapture(); - } - - m_bCaptionPressed = TRUE; - m_Oldpt.x = GET_X_LPARAM(lParam); - m_Oldpt.y = GET_Y_LPARAM(lParam); - if (m_pDock->IsDocked()) - { - CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - ScreenToClient(pt); - m_pView->SetFocus(); - - // Update the close button - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE)) - { - CWindowDC dc(this); - DrawCloseButton(dc, m_bOldFocus); - } - - return 0L; - } - } - return CWnd::WndProcDefault(WM_NCLBUTTONDOWN, wParam, lParam); - } - - inline void CDocker::CDockClient::OnLButtonUp(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & (DS_NO_CAPTION|DS_NO_CLOSE))) - { - m_bCaptionPressed = FALSE; - if (m_IsClosePressed && GetCloseRect().PtInRect(GetCursorPos())) - { - // Destroy the docker - if (dynamic_cast(m_pDock->GetView())) - { - CDockContainer* pContainer = ((CDockContainer*)m_pDock->GetView())->GetActiveContainer(); - CDocker* pDock = m_pDock->GetDockFromView(pContainer); - pDock->GetDockClient().SetClosePressed(); - m_pDock->UndockContainer(pContainer, GetCursorPos(), FALSE); - pDock->Destroy(); - } - else - { - m_pDock->Hide(); - m_pDock->Destroy(); - } - } - } - } - - inline void CDocker::CDockClient::OnLButtonDown(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - m_IsClosePressed = FALSE; - ReleaseCapture(); - CWindowDC dc(this); - DrawCloseButton(dc, m_bOldFocus); - } - - inline void CDocker::CDockClient::OnMouseActivate(WPARAM wParam, LPARAM lParam) - // Focus changed, so redraw the captions - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION)) - { - m_pDock->GetDockAncestor()->PostMessage(UWM_DOCK_ACTIVATED, 0, 0); - } - } - - inline void CDocker::CDockClient::OnMouseMove(WPARAM wParam, LPARAM lParam) - { - OnNCMouseMove(wParam, lParam); - } - - inline void CDocker::CDockClient::OnNCMouseLeave(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - m_IsTracking = FALSE; - CWindowDC dc(this); - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & (DS_NO_CAPTION|DS_NO_CLOSE)) && m_pDock->IsDocked()) - DrawCloseButton(dc, m_bOldFocus); - - m_IsTracking = FALSE; - } - - inline LRESULT CDocker::CDockClient::OnNCMouseMove(WPARAM wParam, LPARAM lParam) - { - if (!m_IsTracking) - { - TRACKMOUSEEVENT TrackMouseEventStruct = {0}; - TrackMouseEventStruct.cbSize = sizeof(TrackMouseEventStruct); - TrackMouseEventStruct.dwFlags = TME_LEAVE|TME_NONCLIENT; - TrackMouseEventStruct.hwndTrack = m_hWnd; - _TrackMouseEvent(&TrackMouseEventStruct); - m_IsTracking = TRUE; - } - - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION)) - { - if (m_pDock->IsDocked()) - { - // Discard phantom mouse move messages - if ( (m_Oldpt.x == GET_X_LPARAM(lParam) ) && (m_Oldpt.y == GET_Y_LPARAM(lParam))) - return 0L; - - if (IsLeftButtonDown() && (wParam == HTCAPTION) && (m_bCaptionPressed)) - { - CDocker* pDock = (CDocker*)GetParent(); - if (pDock) - pDock->Undock(GetCursorPos()); - } - - // Update the close button - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE)) - { - CWindowDC dc(this); - DrawCloseButton(dc, m_bOldFocus); - } - } - - m_bCaptionPressed = FALSE; - } - return CWnd::WndProcDefault(WM_MOUSEMOVE, wParam, lParam); - } - - inline LRESULT CDocker::CDockClient::OnNCPaint(WPARAM wParam, LPARAM lParam) - { - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION)) - { - if (m_pDock->IsDocked()) - { - DefWindowProc(WM_NCPAINT, wParam, lParam); - DrawCaption(wParam); - return 0; - } - } - return CWnd::WndProcDefault(WM_NCPAINT, wParam, lParam); - } - - inline void CDocker::CDockClient::OnWindowPosChanged(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - // Reposition the View window to cover the DockClient's client area - CRect rc = GetClientRect(); - m_pView->SetWindowPos(NULL, rc, SWP_SHOWWINDOW); - } - - inline void CDocker::CDockClient::PreRegisterClass(WNDCLASS& wc) - { - wc.lpszClassName = _T("Win32++ DockClient"); - wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); - } - - inline void CDocker::CDockClient::PreCreate(CREATESTRUCT& cs) - { - DWORD dwStyle = m_pDock->GetDockStyle(); - if (dwStyle & DS_CLIENTEDGE) - cs.dwExStyle = WS_EX_CLIENTEDGE; - -#if defined(WINVER) && defined (WS_EX_LAYOUTRTL) && (WINVER >= 0x0500) - if (m_pDock->GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_LAYOUTRTL) - cs.dwExStyle |= WS_EX_LAYOUTRTL; -#endif - - } - - inline void CDocker::CDockClient::SendNotify(UINT nMessageID) - { - // Fill the DragPos structure with data - DRAGPOS DragPos; - DragPos.hdr.code = nMessageID; - DragPos.hdr.hwndFrom = m_hWnd; - DragPos.ptPos = GetCursorPos(); - - // Send a DragPos notification to the docker - GetParent()->SendMessage(WM_NOTIFY, 0L, (LPARAM)&DragPos); - } - - inline void CDocker::CDockClient::SetCaptionColors(COLORREF Foregnd1, COLORREF Backgnd1, COLORREF Foregnd2, COLORREF Backgnd2) - { - // Set the colors used when drawing the caption - // m_Foregnd1 Foreground colour (focused). m_Backgnd1 Background colour (focused) - // m_Foregnd2 Foreground colour (not focused). m_Backgnd2 Foreground colour (not focused) - m_Foregnd1 = Foregnd1; - m_Backgnd1 = Backgnd1; - m_Foregnd2 = Foregnd2; - m_Backgnd2 = Backgnd2; - } - - inline LRESULT CDocker::CDockClient::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - switch (uMsg) - { - case WM_LBUTTONUP: - { - ReleaseCapture(); - if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE)) - { - CWindowDC dc(this); - DrawCloseButton(dc, m_bOldFocus); - OnLButtonUp(wParam, lParam); - } - } - break; - - case WM_MOUSEACTIVATE: - OnMouseActivate(wParam, lParam); - break; - - case WM_MOUSEMOVE: - OnMouseMove(wParam, lParam); - break; - - case WM_NCCALCSIZE: - OnNCCalcSize(wParam, lParam); - break; - - case WM_NCHITTEST: - return OnNCHitTest(wParam, lParam); - - case WM_NCLBUTTONDOWN: - return OnNCLButtonDown(wParam, lParam); - - case WM_NCMOUSEMOVE: - return OnNCMouseMove(wParam, lParam); - - case WM_NCPAINT: - return OnNCPaint(wParam, lParam); - - case WM_NCMOUSELEAVE: - OnNCMouseLeave(wParam, lParam); - break; - - case WM_WINDOWPOSCHANGED: - OnWindowPosChanged(wParam, lParam); - break; - } - - return CWnd::WndProcDefault(uMsg, wParam, lParam); - } - - - ////////////////////////////////////////////////////////////// - // Definitions for the CDockHint class nested within CDocker - // - inline CDocker::CDockHint::CDockHint() : m_uDockSideOld(0) - { - } - - inline CDocker::CDockHint::~CDockHint() - { - } - - inline RECT CDocker::CDockHint::CalcHintRectContainer(CDocker* pDockTarget) - { - // Calculate the hint window's position for container docking - CRect rcHint = pDockTarget->GetDockClient().GetWindowRect(); - if (pDockTarget->GetDockClient().GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE) - rcHint.InflateRect(-2, -2); - pDockTarget->ScreenToClient(rcHint); - - return rcHint; - } - - inline RECT CDocker::CDockHint::CalcHintRectInner(CDocker* pDockTarget, CDocker* pDockDrag, UINT uDockSide) - { - // Calculate the hint window's position for inner docking - CRect rcHint = pDockTarget->GetDockClient().GetWindowRect(); - if (pDockTarget->GetDockClient().GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE) - rcHint.InflateRect(-2, -2); - pDockTarget->ScreenToClient(rcHint); - - int Width; - CRect rcDockDrag = pDockDrag->GetWindowRect(); - CRect rcDockTarget = pDockTarget->GetDockClient().GetWindowRect(); - if ((uDockSide == DS_DOCKED_LEFT) || (uDockSide == DS_DOCKED_RIGHT)) - { - Width = rcDockDrag.Width(); - if (Width >= (rcDockTarget.Width() - pDockDrag->GetBarWidth())) - Width = MAX(rcDockTarget.Width()/2 - pDockDrag->GetBarWidth(), pDockDrag->GetBarWidth()); - } - else - { - Width = rcDockDrag.Height(); - if (Width >= (rcDockTarget.Height() - pDockDrag->GetBarWidth())) - Width = MAX(rcDockTarget.Height()/2 - pDockDrag->GetBarWidth(), pDockDrag->GetBarWidth()); - } - switch (uDockSide) - { - case DS_DOCKED_LEFT: - rcHint.right = rcHint.left + Width; - break; - case DS_DOCKED_RIGHT: - rcHint.left = rcHint.right - Width; - break; - case DS_DOCKED_TOP: - rcHint.bottom = rcHint.top + Width; - break; - case DS_DOCKED_BOTTOM: - rcHint.top = rcHint.bottom - Width; - break; - } - - return rcHint; - } - - inline RECT CDocker::CDockHint::CalcHintRectOuter(CDocker* pDockDrag, UINT uDockSide) - { - // Calculate the hint window's position for outer docking - CDocker* pDockTarget = pDockDrag->GetDockAncestor(); - CRect rcHint = pDockTarget->GetClientRect(); - if (pDockTarget->GetDockClient().GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE) - rcHint.InflateRect(-2, -2); - - int Width; - CRect rcDockDrag = pDockDrag->GetWindowRect(); - CRect rcDockTarget = pDockTarget->GetDockClient().GetWindowRect(); - - // Limit the docked size to half the parent's size if it won't fit inside parent - if ((uDockSide == DS_DOCKED_LEFTMOST) || (uDockSide == DS_DOCKED_RIGHTMOST)) - { - Width = rcDockDrag.Width(); - int BarWidth = pDockDrag->GetBarWidth(); - if (Width >= pDockTarget->GetDockClient().GetClientRect().Width() - pDockDrag->GetBarWidth()) - Width = MAX(pDockTarget->GetDockClient().GetClientRect().Width()/2 - BarWidth, BarWidth); - } - else - { - Width = rcDockDrag.Height(); - int BarWidth = pDockDrag->GetBarWidth(); - if (Width >= pDockTarget->GetDockClient().GetClientRect().Height() - pDockDrag->GetBarWidth()) - Width = MAX(pDockTarget->GetDockClient().GetClientRect().Height()/2 - BarWidth, BarWidth); - } - switch (uDockSide) - { - case DS_DOCKED_LEFTMOST: - rcHint.right = rcHint.left + Width; - break; - case DS_DOCKED_RIGHTMOST: - rcHint.left = rcHint.right - Width; - break; - case DS_DOCKED_TOPMOST: - rcHint.bottom = rcHint.top + Width; - break; - case DS_DOCKED_BOTTOMMOST: - rcHint.top = rcHint.bottom - Width; - break; - } - - return rcHint; - } - - inline void CDocker::CDockHint::DisplayHint(CDocker* pDockTarget, CDocker* pDockDrag, UINT uDockSide) - { - // Ensure a new hint window is created if dock side changes - if (uDockSide != m_uDockSideOld) - { - Destroy(); - pDockTarget->RedrawWindow( NULL, NULL, RDW_NOERASE | RDW_UPDATENOW ); - pDockDrag->RedrawWindow(); - } - m_uDockSideOld = uDockSide; - - if (!IsWindow()) - { - CRect rcHint; - - if (uDockSide & 0xF) - rcHint = CalcHintRectInner(pDockTarget, pDockDrag, uDockSide); - else if (uDockSide & 0xF0000) - rcHint = CalcHintRectOuter(pDockDrag, uDockSide); - else if (uDockSide & DS_DOCKED_CONTAINER) - rcHint = CalcHintRectContainer(pDockTarget); - else - return; - - ShowHintWindow(pDockTarget, rcHint); - } - } - - inline void CDocker::CDockHint::OnDraw(CDC* pDC) - { - // Display the blue tinted bitmap - CRect rc = GetClientRect(); - CMemDC MemDC(pDC); - MemDC.SelectObject(&m_bmBlueTint); - pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &MemDC, 0, 0, SRCCOPY); - } - - inline void CDocker::CDockHint::PreCreate(CREATESTRUCT &cs) - { - cs.style = WS_POPUP; - - // WS_EX_TOOLWINDOW prevents the window being displayed on the taskbar - cs.dwExStyle = WS_EX_TOOLWINDOW; - - cs.lpszClass = _T("Win32++ DockHint"); - } - - inline void CDocker::CDockHint::ShowHintWindow(CDocker* pDockTarget, CRect rcHint) - { - // Save the Dock window's blue tinted bitmap - CClientDC dcDesktop(NULL); - CMemDC dcMem(&dcDesktop); - CRect rcBitmap = rcHint; - CRect rcTarget = rcHint; - pDockTarget->ClientToScreen(rcTarget); - - m_bmBlueTint.CreateCompatibleBitmap(&dcDesktop, rcBitmap.Width(), rcBitmap.Height()); - CBitmap* pOldBitmap = dcMem.SelectObject(&m_bmBlueTint); - dcMem.BitBlt(0, 0, rcBitmap.Width(), rcBitmap.Height(), &dcDesktop, rcTarget.left, rcTarget.top, SRCCOPY); - dcMem.SelectObject(pOldBitmap); - TintBitmap(&m_bmBlueTint, -64, -24, +128); - - // Create the Hint window - if (!IsWindow()) - { - Create(pDockTarget); - } - - pDockTarget->ClientToScreen(rcHint); - SetWindowPos(NULL, rcHint, SWP_SHOWWINDOW|SWP_NOZORDER|SWP_NOACTIVATE); - } - - - //////////////////////////////////////////////////////////////// - // Definitions for the CTargetCentre class nested within CDocker - // - inline CDocker::CTargetCentre::CTargetCentre() : m_bIsOverContainer(FALSE), m_pOldDockTarget(0) - { - } - - inline CDocker::CTargetCentre::~CTargetCentre() - { - } - - inline void CDocker::CTargetCentre::OnDraw(CDC* pDC) - { - CBitmap bmCentre(IDW_SDCENTER); - CBitmap bmLeft(IDW_SDLEFT); - CBitmap bmRight(IDW_SDRIGHT); - CBitmap bmTop(IDW_SDTOP); - CBitmap bmBottom(IDW_SDBOTTOM); - - if (bmCentre.GetHandle()) pDC->DrawBitmap(0, 0, 88, 88, bmCentre, RGB(255,0,255)); - else TRACE(_T("Missing docking resource: Target Centre\n")); - - if (bmLeft.GetHandle()) pDC->DrawBitmap(0, 29, 31, 29, bmLeft, RGB(255,0,255)); - else TRACE(_T("Missing docking resource: Target Left\n")); - - if (bmTop.GetHandle()) pDC->DrawBitmap(29, 0, 29, 31, bmTop, RGB(255,0,255)); - else TRACE(_T("Missing docking resource: Target Top\n")); - - if (bmRight.GetHandle()) pDC->DrawBitmap(55, 29, 31, 29, bmRight, RGB(255,0,255)); - else TRACE(_T("Missing docking resource: Target Right\n")); - - if (bmBottom.GetHandle()) pDC->DrawBitmap(29, 55, 29, 31, bmBottom, RGB(255,0,255)); - else TRACE(_T("Missing docking resource: Target Bottom\n")); - - if (IsOverContainer()) - { - CBitmap bmMiddle(IDW_SDMIDDLE); - pDC->DrawBitmap(31, 31, 25, 26, bmMiddle, RGB(255,0,255)); - } - } - - inline void CDocker::CTargetCentre::OnCreate() - { - // Use a region to create an irregularly shapped window - POINT ptArray[16] = { {0,29}, {22, 29}, {29, 22}, {29, 0}, - {58, 0}, {58, 22}, {64, 29}, {87, 29}, - {87, 58}, {64, 58}, {58, 64}, {58, 87}, - {29, 87}, {29, 64}, {23, 58}, {0, 58} }; - - CRgn rgnPoly; - rgnPoly.CreatePolygonRgn(ptArray, 16, WINDING); - SetWindowRgn(&rgnPoly, FALSE); - } - - inline BOOL CDocker::CTargetCentre::CheckTarget(LPDRAGPOS pDragPos) - { - CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom); - if (NULL == pDockDrag) return FALSE; - - CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pDragPos->ptPos); - if (NULL == pDockTarget) return FALSE; - - if (!IsWindow()) Create(); - m_bIsOverContainer = (dynamic_cast(pDockTarget->GetView()) != NULL); - - // Redraw the target if the dock target changes - if (m_pOldDockTarget != pDockTarget) Invalidate(); - m_pOldDockTarget = pDockTarget; - - int cxImage = 88; - int cyImage = 88; - - CRect rcTarget = pDockTarget->GetDockClient().GetWindowRect(); - int xMid = rcTarget.left + (rcTarget.Width() - cxImage)/2; - int yMid = rcTarget.top + (rcTarget.Height() - cyImage)/2; - SetWindowPos(HWND_TOPMOST, xMid, yMid, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW); - - // Create the docking zone rectangles - CPoint pt = pDragPos->ptPos; - ScreenToClient(pt); - CRect rcLeft(0, 29, 31, 58); - CRect rcTop(29, 0, 58, 31); - CRect rcRight(55, 29, 87, 58); - CRect rcBottom(29, 55, 58, 87); - CRect rcMiddle(31, 31, 56, 57); - - // Test if our cursor is in one of the docking zones - if ((rcLeft.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_LEFT)) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_LEFT); - pDockDrag->m_dwDockZone = DS_DOCKED_LEFT; - return TRUE; - } - else if ((rcTop.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_TOP)) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_TOP); - pDockDrag->m_dwDockZone = DS_DOCKED_TOP; - return TRUE; - } - else if ((rcRight.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_RIGHT)) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_RIGHT); - pDockDrag->m_dwDockZone = DS_DOCKED_RIGHT; - return TRUE; - } - else if ((rcBottom.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_BOTTOM)) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_BOTTOM); - pDockDrag->m_dwDockZone = DS_DOCKED_BOTTOM; - return TRUE; - } - else if ((rcMiddle.PtInRect(pt)) && (IsOverContainer())) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_CONTAINER); - pDockDrag->m_dwDockZone = DS_DOCKED_CONTAINER; - return TRUE; - } - else - return FALSE; - } - - //////////////////////////////////////////////////////////////// - // Definitions for the CTarget class nested within CDocker - // CTarget is the base class for a number of CTargetXXX classes - inline CDocker::CTarget::~CTarget() - { - } - - inline void CDocker::CTarget::OnDraw(CDC* pDC) - { - BITMAP bm = m_bmImage.GetBitmapData(); - int cxImage = bm.bmWidth; - int cyImage = bm.bmHeight; - - if (m_bmImage) - pDC->DrawBitmap(0, 0, cxImage, cyImage, m_bmImage, RGB(255,0,255)); - else - TRACE(_T("Missing docking resource\n")); - } - - inline void CDocker::CTarget::PreCreate(CREATESTRUCT &cs) - { - cs.style = WS_POPUP; - cs.dwExStyle = WS_EX_TOPMOST|WS_EX_TOOLWINDOW; - cs.lpszClass = _T("Win32++ DockTargeting"); - } - - - //////////////////////////////////////////////////////////////// - // Definitions for the CTargetLeft class nested within CDocker - // - inline BOOL CDocker::CTargetLeft::CheckTarget(LPDRAGPOS pDragPos) - { - CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom); - if (NULL == pDockDrag) return FALSE; - - CPoint pt = pDragPos->ptPos; - CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pt)->GetTopmostDocker(); - if (pDockTarget != pDockDrag->GetDockAncestor()) - { - Destroy(); - return FALSE; - } - - BITMAP bm = m_bmImage.GetBitmapData(); - int cxImage = bm.bmWidth; - int cyImage = bm.bmHeight; - - if (!IsWindow()) - { - Create(); - CRect rc = pDockTarget->GetWindowRect(); - int yMid = rc.top + (rc.Height() - cyImage)/2; - SetWindowPos(HWND_TOPMOST, rc.left + 10, yMid, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW); - } - - CRect rcLeft(0, 0, cxImage, cyImage); - ScreenToClient(pt); - - // Test if our cursor is in one of the docking zones - if ((rcLeft.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_LEFT)) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_LEFTMOST); - pDockDrag->m_dwDockZone = DS_DOCKED_LEFTMOST; - return TRUE; - } - - return FALSE; - } - - - //////////////////////////////////////////////////////////////// - // Definitions for the CTargetTop class nested within CDocker - // - inline BOOL CDocker::CTargetTop::CheckTarget(LPDRAGPOS pDragPos) - { - CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom); - if (NULL == pDockDrag) return FALSE; - - CPoint pt = pDragPos->ptPos; - CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pt)->GetTopmostDocker(); - if (pDockTarget != pDockDrag->GetDockAncestor()) - { - Destroy(); - return FALSE; - } - - BITMAP bm = m_bmImage.GetBitmapData(); - int cxImage = bm.bmWidth; - int cyImage = bm.bmHeight; - - if (!IsWindow()) - { - Create(); - CRect rc = pDockTarget->GetWindowRect(); - int xMid = rc.left + (rc.Width() - cxImage)/2; - SetWindowPos(HWND_TOPMOST, xMid, rc.top + 10, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW); - } - - CRect rcTop(0, 0, cxImage, cyImage); - ScreenToClient(pt); - - // Test if our cursor is in one of the docking zones - if ((rcTop.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_TOP)) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_TOPMOST); - pDockDrag->m_dwDockZone = DS_DOCKED_TOPMOST; - return TRUE; - } - - return FALSE; - } - - - //////////////////////////////////////////////////////////////// - // Definitions for the CTargetRight class nested within CDocker - // - inline BOOL CDocker::CTargetRight::CheckTarget(LPDRAGPOS pDragPos) - { - CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom); - if (NULL == pDockDrag) return FALSE; - - CPoint pt = pDragPos->ptPos; - CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pt)->GetTopmostDocker(); - if (pDockTarget != pDockDrag->GetDockAncestor()) - { - Destroy(); - return FALSE; - } - - BITMAP bm = m_bmImage.GetBitmapData(); - int cxImage = bm.bmWidth; - int cyImage = bm.bmHeight; - - if (!IsWindow()) - { - Create(); - CRect rc = pDockTarget->GetWindowRect(); - int yMid = rc.top + (rc.Height() - cyImage)/2; - SetWindowPos(HWND_TOPMOST, rc.right - 10 - cxImage, yMid, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW); - } - - CRect rcRight(0, 0, cxImage, cyImage); - ScreenToClient(pt); - - // Test if our cursor is in one of the docking zones - if ((rcRight.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_RIGHT)) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_RIGHTMOST); - pDockDrag->m_dwDockZone = DS_DOCKED_RIGHTMOST; - return TRUE; - } - - return FALSE; - } - - - //////////////////////////////////////////////////////////////// - // Definitions for the CTargetBottom class nested within CDocker - // - inline BOOL CDocker::CTargetBottom::CheckTarget(LPDRAGPOS pDragPos) - { - CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom); - if (NULL == pDockDrag) return FALSE; - - CPoint pt = pDragPos->ptPos; - CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pt)->GetTopmostDocker(); - if (pDockTarget != pDockDrag->GetDockAncestor()) - { - Destroy(); - return FALSE; - } - - BITMAP bm = m_bmImage.GetBitmapData(); - int cxImage = bm.bmWidth; - int cyImage = bm.bmHeight; - - if (!IsWindow()) - { - Create(); - CRect rc = pDockTarget->GetWindowRect(); - int xMid = rc.left + (rc.Width() - cxImage)/2; - SetWindowPos(HWND_TOPMOST, xMid, rc.bottom - 10 - cyImage, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW); - } - CRect rcBottom(0, 0, cxImage, cyImage); - ScreenToClient(pt); - - // Test if our cursor is in one of the docking zones - if ((rcBottom.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_BOTTOM)) - { - pDockDrag->m_BlockMove = TRUE; - pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_BOTTOMMOST); - pDockDrag->m_dwDockZone = DS_DOCKED_BOTTOMMOST; - return TRUE; - } - - return FALSE; - } - - - ///////////////////////////////////////// - // Definitions for the CDocker class - // - inline CDocker::CDocker() : m_pDockParent(NULL), m_pDockActive(NULL), m_BlockMove(FALSE), m_Undocking(FALSE), - m_bIsClosing(FALSE), m_bIsDragging(FALSE), m_bDragAutoResize(TRUE), m_DockStartSize(0), m_nDockID(0), - m_nTimerCount(0), m_NCHeight(0), m_dwDockZone(0), m_DockSizeRatio(1.0), m_DockStyle(0), m_hOldFocus(0) - { - // Assume this docker is the DockAncestor for now. - m_pDockAncestor = this; - } - - inline CDocker::~CDocker() - { - GetDockBar().Destroy(); - - std::vector ::iterator iter; - if (GetDockAncestor() == this) - { - // Destroy all dock descendants of this dock ancestor - for (iter = GetAllDockers().begin(); iter < GetAllDockers().end(); ++iter) - { - (*iter)->Destroy(); - } - } - } - - inline CDocker* CDocker::AddDockedChild(CDocker* pDocker, DWORD dwDockStyle, int DockSize, int nDockID /* = 0*/) - // This function creates the docker, and adds it to the docker heirachy as docked - { - // Create the docker window as a child of the frame window. - // This pernamently sets the frame window as the docker window's owner, - // even when its parent is subsequently changed. - - assert(pDocker); - - // Store the Docker's pointer in the DockAncestor's vector for later deletion - GetDockAncestor()->m_vAllDockers.push_back(DockPtr(pDocker)); - - pDocker->SetDockStyle(dwDockStyle); - pDocker->m_nDockID = nDockID; - pDocker->m_pDockAncestor = GetDockAncestor(); - pDocker->m_pDockParent = this; - pDocker->SetDockSize(DockSize); - CWnd* pFrame = GetDockAncestor()->GetAncestor(); - pDocker->Create(pFrame); - pDocker->SetParent(this); - - // Dock the docker window - if (dwDockStyle & DS_DOCKED_CONTAINER) - DockInContainer(pDocker, dwDockStyle); - else - Dock(pDocker, dwDockStyle); - - // Issue TRACE warnings for any missing resources - HMODULE hMod= GetApp()->GetResourceHandle(); - - if (!(dwDockStyle & DS_NO_RESIZE)) - { - if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SPLITH), RT_GROUP_CURSOR)) - TRACE(_T("**WARNING** Horizontal cursor resource missing\n")); - if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SPLITV), RT_GROUP_CURSOR)) - TRACE(_T("**WARNING** Vertical cursor resource missing\n")); - } - - if (!(dwDockStyle & DS_NO_UNDOCK)) - { - if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDCENTER), RT_BITMAP)) - TRACE(_T("**WARNING** Docking center bitmap resource missing\n")); - if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDLEFT), RT_BITMAP)) - TRACE(_T("**WARNING** Docking left bitmap resource missing\n")); - if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDRIGHT), RT_BITMAP)) - TRACE(_T("**WARNING** Docking right bitmap resource missing\n")); - if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDTOP), RT_BITMAP)) - TRACE(_T("**WARNING** Docking top bitmap resource missing\n")); - if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDBOTTOM), RT_BITMAP)) - TRACE(_T("**WARNING** Docking center bottom resource missing\n")); - } - - if (dwDockStyle & DS_DOCKED_CONTAINER) - { - if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDMIDDLE), RT_BITMAP)) - TRACE(_T("**WARNING** Docking container bitmap resource missing\n")); - } - - return pDocker; - } - - inline CDocker* CDocker::AddUndockedChild(CDocker* pDocker, DWORD dwDockStyle, int DockSize, RECT rc, int nDockID /* = 0*/) - // This function creates the docker, and adds it to the docker heirachy as undocked - { - assert(pDocker); - - // Store the Docker's pointer in the DockAncestor's vector for later deletion - GetDockAncestor()->m_vAllDockers.push_back(DockPtr(pDocker)); - - pDocker->SetDockSize(DockSize); - pDocker->SetDockStyle(dwDockStyle & 0XFFFFFF0); - pDocker->m_nDockID = nDockID; - pDocker->m_pDockAncestor = GetDockAncestor(); - - // Initially create the as a child window of the frame - // This makes the frame window the owner of our docker - CWnd* pFrame = GetDockAncestor()->GetAncestor(); - pDocker->Create(pFrame); - pDocker->SetParent(this); - - // Change the Docker to a POPUP window - DWORD dwStyle = WS_POPUP| WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_VISIBLE; - pDocker->SetWindowLongPtr(GWL_STYLE, dwStyle); - pDocker->SetRedraw(FALSE); - pDocker->SetParent(0); - pDocker->SetWindowPos(HWND_TOP, rc, SWP_SHOWWINDOW|SWP_FRAMECHANGED); - pDocker->SetRedraw(TRUE); - pDocker->RedrawWindow(0, 0, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_ALLCHILDREN); - pDocker->SetWindowText(pDocker->GetCaption().c_str()); - - return pDocker; - } - - inline void CDocker::CheckAllTargets(LPDRAGPOS pDragPos) - // Calls CheckTarget for each possible target zone - { - if (!GetDockAncestor()->m_TargetCentre.CheckTarget(pDragPos)) - { - if (!GetDockAncestor()->m_TargetLeft.CheckTarget(pDragPos)) - { - if(!GetDockAncestor()->m_TargetTop.CheckTarget(pDragPos)) - { - if(!GetDockAncestor()->m_TargetRight.CheckTarget(pDragPos)) - { - if(!GetDockAncestor()->m_TargetBottom.CheckTarget(pDragPos)) - { - // Not in a docking zone, so clean up - NMHDR nmhdr = pDragPos->hdr; - CDocker* pDockDrag = (CDocker*)FromHandle(nmhdr.hwndFrom); - if (pDockDrag) - { - if (pDockDrag->m_BlockMove) - pDockDrag->RedrawWindow(0, 0, RDW_FRAME|RDW_INVALIDATE); - - GetDockHint().Destroy(); - pDockDrag->m_dwDockZone = 0; - pDockDrag->m_BlockMove = FALSE; - } - } - } - } - } - } - } - - inline BOOL CDocker::VerifyDockers() - // A diagnostic routine which verifies the integrity of the docking layout - { - BOOL bResult = TRUE; - - // Check dock ancestor - std::vector::iterator iter; - - for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); ++iter) - { - if (GetDockAncestor() != (*iter)->m_pDockAncestor) - { - TRACE(_T("Invalid Dock Ancestor\n")); - bResult = FALSE; - } - } - - // Check presence of dock parent - for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); ++iter) - { - if ((*iter)->IsUndocked() && (*iter)->m_pDockParent != 0) - { - TRACE(_T("Error: Undocked dockers should not have a dock parent\n")); - bResult = FALSE; - } - - if ((*iter)->IsDocked() && (*iter)->m_pDockParent == 0) - { - TRACE(_T("Error: Docked dockers should have a dock parent\n")); - bResult = FALSE; - } - } - - // Check dock parent/child relationship - for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); ++iter) - { - std::vector::iterator iterChild; - for (iterChild = (*iter)->GetDockChildren().begin(); iterChild != (*iter)->GetDockChildren().end(); ++iterChild) - { - if ((*iterChild)->m_pDockParent != (*iter).get()) - { - TRACE(_T("Error: Docking parent/Child information mismatch\n")); - bResult = FALSE; - } - if ((*iterChild)->GetParent() != (*iter).get()) - { - TRACE(_T("Error: Incorrect windows child parent relationship\n")); - bResult = FALSE; - } - } - } - - // Check dock parent chain - for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); ++iter) - { - CDocker* pDockTopLevel = (*iter)->GetTopmostDocker(); - if (pDockTopLevel->IsDocked()) - TRACE(_T("Error: Top level parent should be undocked\n")); - } - - return bResult; - } - - inline void CDocker::Close() - { - // Destroy the docker - Hide(); - Destroy(); - } - - inline void CDocker::CloseAllDockers() - { - assert(this == GetDockAncestor()); // Must call CloseAllDockers from the DockAncestor - - std::vector ::iterator v; - - SetRedraw(FALSE); - std::vector AllDockers = GetAllDockers(); - for (v = AllDockers.begin(); v != AllDockers.end(); ++v) - { - // The CDocker is destroyed when the window is destroyed - (*v)->m_bIsClosing = TRUE; - (*v)->Destroy(); // Destroy the window - } - - GetDockChildren().clear(); - SetRedraw(TRUE); - RecalcDockLayout(); - } - - inline void CDocker::CloseAllTargets() - { - GetDockAncestor()->m_TargetCentre.Destroy(); - GetDockAncestor()->m_TargetLeft.Destroy(); - GetDockAncestor()->m_TargetTop.Destroy(); - GetDockAncestor()->m_TargetRight.Destroy(); - GetDockAncestor()->m_TargetBottom.Destroy(); - } - - inline void CDocker::Dock(CDocker* pDocker, UINT DockStyle) - // Docks the specified docker inside this docker - { - assert(pDocker); - - pDocker->m_pDockParent = this; - pDocker->m_BlockMove = FALSE; - pDocker->SetDockStyle(DockStyle); - m_vDockChildren.push_back(pDocker); - pDocker->ConvertToChild(m_hWnd); - - // Limit the docked size to half the parent's size if it won't fit inside parent - if (((DockStyle & 0xF) == DS_DOCKED_LEFT) || ((DockStyle &0xF) == DS_DOCKED_RIGHT)) - { - int Width = GetDockClient().GetWindowRect().Width(); - int BarWidth = pDocker->GetBarWidth(); - if (pDocker->m_DockStartSize >= (Width - BarWidth)) - pDocker->SetDockSize(MAX(Width/2 - BarWidth, BarWidth)); - - pDocker->m_DockSizeRatio = ((double)pDocker->m_DockStartSize) / (double)GetWindowRect().Width(); - } - else - { - int Height = GetDockClient().GetWindowRect().Height(); - int BarWidth = pDocker->GetBarWidth(); - if (pDocker->m_DockStartSize >= (Height - BarWidth)) - pDocker->SetDockSize(MAX(Height/2 - BarWidth, BarWidth)); - - pDocker->m_DockSizeRatio = ((double)pDocker->m_DockStartSize) / (double)GetWindowRect().Height(); - } - - // Redraw the docked windows - GetAncestor()->SetForegroundWindow(); - GetTopmostDocker()->m_hOldFocus = pDocker->GetView()->GetHwnd(); - pDocker->GetView()->SetFocus(); - - GetTopmostDocker()->SetRedraw(FALSE); - RecalcDockLayout(); - GetTopmostDocker()->SetRedraw(TRUE); - GetTopmostDocker()->RedrawWindow(); - } - - inline void CDocker::DockInContainer(CDocker* pDock, DWORD dwDockStyle) - // Add a container to an existing container - { - if ((dwDockStyle & DS_DOCKED_CONTAINER) && (dynamic_cast(pDock->GetView()))) - { - // Transfer any dock children to this docker - pDock->MoveDockChildren(this); - - // Transfer container children to the target container - CDockContainer* pContainer = (CDockContainer*)GetView(); - CDockContainer* pContainerSource = (CDockContainer*)pDock->GetView(); - - if (pContainerSource->GetAllContainers().size() > 1) - { - // The container we're about to add has children, so transfer those first - std::vector::reverse_iterator riter; - std::vector AllContainers = pContainerSource->GetAllContainers(); - for ( riter = AllContainers.rbegin() ; riter < AllContainers.rend() -1; ++riter ) - { - // Remove child container from pContainerSource - CDockContainer* pContainerChild = (*riter).pContainer; - pContainerChild->ShowWindow(SW_HIDE); - pContainerSource->RemoveContainer(pContainerChild); - - // Add child container to this container - pContainer->AddContainer(pContainerChild); - - CDocker* pDockChild = GetDockFromView(pContainerChild); - pDockChild->SetParent(this); - pDockChild->m_pDockParent = this; - } - } - - pContainer->AddContainer((CDockContainer*)pDock->GetView()); - pDock->m_pDockParent = this; - pDock->m_BlockMove = FALSE; - pDock->ShowWindow(SW_HIDE); - pDock->SetWindowLongPtr(GWL_STYLE, WS_CHILD); - pDock->SetDockStyle(dwDockStyle); - pDock->SetParent(this); - } - } - - inline void CDocker::DockOuter(CDocker* pDocker, DWORD dwDockStyle) - // Docks the specified docker inside the dock ancestor - { - assert(pDocker); - - pDocker->m_pDockParent = GetDockAncestor(); - - DWORD OuterDocking = dwDockStyle & 0xF0000; - DWORD DockSide = OuterDocking / 0x10000; - dwDockStyle &= 0xFFF0FFFF; - dwDockStyle |= DockSide; - - // Set the dock styles - DWORD dwStyle = WS_CHILD | WS_VISIBLE; - pDocker->m_BlockMove = FALSE; - pDocker->SetWindowLongPtr(GWL_STYLE, dwStyle); - pDocker->ShowWindow(SW_HIDE); - pDocker->SetDockStyle(dwDockStyle); - - // Set the docking relationships - std::vector::iterator iter = GetDockAncestor()->m_vDockChildren.begin(); - GetDockAncestor()->m_vDockChildren.insert(iter, pDocker); - pDocker->SetParent(GetDockAncestor()); - pDocker->GetDockBar().SetParent(GetDockAncestor()); - - // Limit the docked size to half the parent's size if it won't fit inside parent - if (((dwDockStyle & 0xF) == DS_DOCKED_LEFT) || ((dwDockStyle &0xF) == DS_DOCKED_RIGHT)) - { - int Width = GetDockAncestor()->GetDockClient().GetWindowRect().Width(); - int BarWidth = pDocker->GetBarWidth(); - if (pDocker->m_DockStartSize >= (Width - BarWidth)) - pDocker->SetDockSize(MAX(Width/2 - BarWidth, BarWidth)); - - pDocker->m_DockSizeRatio = ((double)pDocker->m_DockStartSize) / (double)GetDockAncestor()->GetWindowRect().Width(); - } - else - { - int Height = GetDockAncestor()->GetDockClient().GetWindowRect().Height(); - int BarWidth = pDocker->GetBarWidth(); - if (pDocker->m_DockStartSize >= (Height - BarWidth)) - pDocker->SetDockSize(MAX(Height/2 - BarWidth, BarWidth)); - - pDocker->m_DockSizeRatio = ((double)pDocker->m_DockStartSize) / (double)GetDockAncestor()->GetWindowRect().Height(); - } - - // Redraw the docked windows - GetAncestor()->SetFocus(); - pDocker->GetView()->SetFocus(); - RecalcDockLayout(); - } - - inline void CDocker::DrawAllCaptions() - { - std::vector::iterator iter; - for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); iter++) - { - if ((*iter)->IsDocked()) - (*iter)->GetDockClient().DrawCaption((WPARAM)1); - } - } - - inline void CDocker::DrawHashBar(HWND hBar, POINT Pos) - // Draws a hashed bar while the splitter bar is being dragged - { - CDocker* pDock = ((CDockBar*)FromHandle(hBar))->GetDock(); - if (NULL == pDock) return; - - BOOL bVertical = ((pDock->GetDockStyle() & 0xF) == DS_DOCKED_LEFT) || ((pDock->GetDockStyle() & 0xF) == DS_DOCKED_RIGHT); - - CClientDC dcBar(this); - - WORD HashPattern[] = {0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA}; - CBitmap bmHash; - CBrush brDithered; - bmHash.CreateBitmap(8, 8, 1, 1, HashPattern); - brDithered.CreatePatternBrush(&bmHash); - dcBar.SelectObject(&brDithered); - - CRect rc = FromHandle(hBar)->GetWindowRect(); - ScreenToClient(rc); - int cx = rc.Width(); - int cy = rc.Height(); - int BarWidth = pDock->GetDockBar().GetWidth(); - - if (bVertical) - dcBar.PatBlt(Pos.x - BarWidth/2, rc.top, BarWidth, cy, PATINVERT); - else - dcBar.PatBlt(rc.left, Pos.y - BarWidth/2, cx, BarWidth, PATINVERT); - } - - inline CDockContainer* CDocker::GetContainer() const - { - CDockContainer* pContainer = NULL; - if (dynamic_cast(GetView())) - pContainer = (CDockContainer*)GetView(); - - return pContainer; - } - - inline CDocker* CDocker::GetActiveDocker() const - // Returns the docker whose child window has focus - { - CWnd* pWnd = GetFocus(); - CDocker* pDock= NULL; - while (pWnd && (pDock == NULL)) - { - if (IsRelated(pWnd)) - pDock = (CDocker*)pWnd; - - pWnd = pWnd->GetParent(); - } - - return pDock; - } - - inline CDocker* CDocker::GetDockAncestor() const - // The GetDockAncestor function retrieves the pointer to the - // ancestor (root docker parent) of the Docker. - { - return m_pDockAncestor; - } - - inline CDocker* CDocker::GetDockFromPoint(POINT pt) const - // Retrieves the Docker whose view window contains the specified point - { - // Step 1: Find the top level Docker the point is over - CDocker* pDockTop = NULL; - CWnd* pAncestor = GetDockAncestor()->GetAncestor(); - - // Iterate through all top level windows - CWnd* pWnd = GetWindow(GW_HWNDFIRST); - while(pWnd) - { - if (IsRelated(pWnd) || pWnd == pAncestor) - { - CDocker* pDockTest; - if (pWnd == pAncestor) - pDockTest = GetDockAncestor(); - else - pDockTest = (CDocker*)pWnd; - - CRect rc = pDockTest->GetClientRect(); - pDockTest->ClientToScreen(rc); - if ((this != pDockTest) && rc.PtInRect(pt)) - { - pDockTop = pDockTest; - break; - } - } - - pWnd = pWnd->GetWindow(GW_HWNDNEXT); - } - - // Step 2: Find the docker child whose view window has the point - CDocker* pDockTarget = NULL; - if (pDockTop) - { - CDocker* pDockParent = pDockTop; - CDocker* pDockTest = pDockParent; - - while (IsRelated(pDockTest)) - { - pDockParent = pDockTest; - CPoint ptLocal = pt; - pDockParent->ScreenToClient(ptLocal); - pDockTest = (CDocker*)pDockParent->ChildWindowFromPoint(ptLocal); - assert (pDockTest != pDockParent); - } - - CRect rc = pDockParent->GetDockClient().GetWindowRect(); - if (rc.PtInRect(pt)) pDockTarget = pDockParent; - } - - return pDockTarget; - } - - inline CDocker* CDocker::GetDockFromID(int n_DockID) const - { - std::vector ::iterator v; - - if (GetDockAncestor()) - { - for (v = GetDockAncestor()->m_vAllDockers.begin(); v != GetDockAncestor()->m_vAllDockers.end(); v++) - { - if (n_DockID == (*v)->GetDockID()) - return (*v).get(); - } - } - - return 0; - } - - inline CDocker* CDocker::GetDockFromView(CWnd* pView) const - { - CDocker* pDock = 0; - std::vector::iterator iter; - std::vector AllDockers = GetAllDockers(); - for (iter = AllDockers.begin(); iter != AllDockers.end(); ++iter) - { - if ((*iter)->GetView() == pView) - pDock = (*iter).get(); - } - - return pDock; - } - - inline int CDocker::GetDockSize() const - { - // Returns the size of the docker to be used if it is redocked - // Note: This function returns 0 if the docker has the DS_DOCKED_CONTAINER style - - CRect rcParent; - if (GetDockParent()) - rcParent = GetDockParent()->GetWindowRect(); - else - rcParent = GetDockAncestor()->GetWindowRect(); - - double DockSize = 0; - if ((GetDockStyle() & DS_DOCKED_LEFT) || (GetDockStyle() & DS_DOCKED_RIGHT)) - DockSize = (double)(rcParent.Width()*m_DockSizeRatio); - else if ((GetDockStyle() & DS_DOCKED_TOP) || (GetDockStyle() & DS_DOCKED_BOTTOM)) - DockSize = (double)(rcParent.Height()*m_DockSizeRatio); - else if ((GetDockStyle() & DS_DOCKED_CONTAINER)) - DockSize = 0; - - return (int)DockSize; - } - - inline CDocker* CDocker::GetTopmostDocker() const - // Returns the docker's parent at the top of the Z order. - // Could be the dock ancestor or an undocked docker. - { - CDocker* pDockTopLevel = (CDocker* const)this; - - while(pDockTopLevel->GetDockParent()) - { - assert (pDockTopLevel != pDockTopLevel->GetDockParent()); - pDockTopLevel = pDockTopLevel->GetDockParent(); - } - - return pDockTopLevel; - } - - inline CTabbedMDI* CDocker::GetTabbedMDI() const - { - CTabbedMDI* pTabbedMDI = NULL; - if (dynamic_cast(GetView())) - pTabbedMDI = (CTabbedMDI*)GetView(); - - return pTabbedMDI; - } - - inline int CDocker::GetTextHeight() - { - NONCLIENTMETRICS nm = {0}; - nm.cbSize = GetSizeofNonClientMetrics(); - SystemParametersInfo (SPI_GETNONCLIENTMETRICS, 0, &nm, 0); - LOGFONT lf = nm.lfStatusFont; - - CClientDC dc(this); - dc.CreateFontIndirect(&lf); - CSize szText = dc.GetTextExtentPoint32(_T("Text"), lstrlen(_T("Text"))); - return szText.cy; - } - - inline void CDocker::Hide() - { - // Undocks a docker (if needed) and hides it. - // Do unhide the docker, dock it. - - if (IsDocked()) - { - if (dynamic_cast(GetView())) - { - CDockContainer* pContainer = GetContainer(); - CDocker* pDock = GetDockFromView(pContainer->GetContainerParent()); - pDock->UndockContainer(pContainer, GetCursorPos(), FALSE); - } - else - { - CDocker* pDockUndockedFrom = SeparateFromDock(); - pDockUndockedFrom->RecalcDockLayout(); - } - } - - ShowWindow(SW_HIDE); - } - - inline BOOL CDocker::IsChildOfDocker(CWnd* pWnd) const - // returns true if the specified window is a child of this docker - { - while ((pWnd != NULL) && (pWnd != GetDockAncestor())) - { - if (pWnd == (CWnd*)this) return TRUE; - if (IsRelated(pWnd)) break; - pWnd = pWnd->GetParent(); - } - - return FALSE; - } - - inline BOOL CDocker::IsDocked() const - { - return (((m_DockStyle&0xF) || (m_DockStyle & DS_DOCKED_CONTAINER)) && !m_Undocking); // Boolean expression - } - - inline BOOL CDocker::IsDragAutoResize() - { - return m_bDragAutoResize; - } - - inline BOOL CDocker::IsRelated(CWnd* pWnd) const - // Returns TRUE if the hWnd is a docker within this dock family - { - if (GetDockAncestor() == pWnd) return TRUE; - - std::vector::iterator iter; - for (iter = GetAllDockers().begin(); iter < GetAllDockers().end(); ++iter) - { - if ((*iter).get() == pWnd) return TRUE; - } - - return FALSE; - } - - inline BOOL CDocker::IsUndocked() const - { - return (!((m_DockStyle&0xF)|| (m_DockStyle & DS_DOCKED_CONTAINER)) && !m_Undocking); // Boolean expression - } - - inline BOOL CDocker::LoadRegistrySettings(tString tsRegistryKeyName) - // Recreates the docker layout based on information stored in the registry. - // Assumes the DockAncestor window is already created. - { - BOOL bResult = FALSE; - - if (0 != tsRegistryKeyName.size()) - { - std::vector vDockList; - std::vector vActiveContainers; - tString tsKey = _T("Software\\") + tsRegistryKeyName + _T("\\Dock Windows"); - HKEY hKey = 0; - RegOpenKeyEx(HKEY_CURRENT_USER, tsKey.c_str(), 0, KEY_READ, &hKey); - if (hKey) - { - DWORD dwType = REG_BINARY; - DWORD BufferSize = sizeof(DockInfo); - DockInfo di; - int i = 0; - TCHAR szNumber[20]; - tString tsSubKey = _T("DockChild"); - tsSubKey += _itot(i, szNumber, 10); - - // Fill the DockList vector from the registry - while (0 == RegQueryValueEx(hKey, tsSubKey.c_str(), NULL, &dwType, (LPBYTE)&di, &BufferSize)) - { - vDockList.push_back(di); - i++; - tsSubKey = _T("DockChild"); - tsSubKey += _itot(i, szNumber, 10); - } - - dwType = REG_DWORD; - BufferSize = sizeof(int); - int nID; - i = 0; - tsSubKey = _T("ActiveContainer"); - tsSubKey += _itot(i, szNumber, 10); - // Fill the DockList vector from the registry - while (0 == RegQueryValueEx(hKey, tsSubKey.c_str(), NULL, &dwType, (LPBYTE)&nID, &BufferSize)) - { - vActiveContainers.push_back(nID); - i++; - tsSubKey = _T("ActiveContainer"); - tsSubKey += _itot(i, szNumber, 10); - } - - RegCloseKey(hKey); - if (vDockList.size() > 0) bResult = TRUE; - } - - // Add dockers without parents first - std::vector::iterator iter; - for (iter = vDockList.begin(); iter < vDockList.end() ; ++iter) - { - DockInfo di = (*iter); - if (di.DockParentID == 0) - { - CDocker* pDocker = NewDockerFromID(di.DockID); - if (pDocker) - { - if (di.DockStyle & 0xF) - AddDockedChild(pDocker, di.DockStyle, di.DockSize, di.DockID); - else - AddUndockedChild(pDocker, di.DockStyle, di.DockSize, di.Rect, di.DockID); - } - else - { - TRACE(_T("Failed to add dockers without parents from registry")); - bResult = FALSE; - } - } - } - - // Remove dockers without parents from vDockList - for (UINT n = (UINT)vDockList.size(); n > 0; --n) - { - iter = vDockList.begin() + n-1; - if ((*iter).DockParentID == 0) - vDockList.erase(iter); - } - - // Add remaining dockers - while (vDockList.size() > 0) - { - bool bFound = false; - std::vector::iterator iter; - for (iter = vDockList.begin(); iter < vDockList.end(); ++iter) - { - DockInfo di = *iter; - CDocker* pDockParent = GetDockFromID(di.DockParentID); - - if (pDockParent != 0) - { - CDocker* pDock = NewDockerFromID(di.DockID); - if(pDock) - { - pDockParent->AddDockedChild(pDock, di.DockStyle, di.DockSize, di.DockID); - bFound = true; - } - else - { - TRACE(_T("Failed to add dockers with parents from registry")); - bResult = FALSE; - } - - vDockList.erase(iter); - break; - } - } - - if (!bFound) - { - TRACE(_T("Orphaned dockers stored in registry ")); - bResult = FALSE; - break; - } - } - - std::vector::iterator iterID; - for (iterID = vActiveContainers.begin(); iterID < vActiveContainers.end(); ++iterID) - { - CDocker* pDocker = GetDockFromID(*iterID); - if (pDocker) - { - CDockContainer* pContainer = pDocker->GetContainer(); - if (pContainer) - { - int nPage = pContainer->GetContainerIndex(pContainer); - if (nPage >= 0) - pContainer->SelectPage(nPage); - } - } - } - } - - if (!bResult) CloseAllDockers(); - return bResult; - } - - inline void CDocker::MoveDockChildren(CDocker* pDockTarget) - // Used internally by Dock and Undock - { - assert(pDockTarget); - - // Transfer any dock children from the current docker to the target docker - std::vector::iterator iter; - for (iter = GetDockChildren().begin(); iter < GetDockChildren().end(); ++iter) - { - pDockTarget->GetDockChildren().push_back(*iter); - (*iter)->m_pDockParent = pDockTarget; - (*iter)->SetParent(pDockTarget); - (*iter)->GetDockBar().SetParent(pDockTarget); - } - GetDockChildren().clear(); - } - - inline CDocker* CDocker::NewDockerFromID(int nID) - // Used in LoadRegistrySettings. Creates a new Docker from the specified ID - { - UNREFERENCED_PARAMETER(nID); - - // Override this function to create the Docker objects as shown below - - CDocker* pDock = NULL; - /* switch(nID) - { - case ID_CLASSES: - pDock = new CDockClasses; - break; - case ID_FILES: - pDock = new CDockFiles; - break; - default: - TRACE(_T("Unknown Dock ID\n")); - break; - } */ - - return pDock; - } - - inline void CDocker::OnActivate(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(lParam); - - // Only top level undocked dockers get this message - if (LOWORD(wParam) == WA_INACTIVE) - { - GetTopmostDocker()->m_hOldFocus = ::GetFocus(); - - // Send a notification of focus lost - int idCtrl = ::GetDlgCtrlID(m_hOldFocus); - NMHDR nhdr={0}; - nhdr.hwndFrom = m_hOldFocus; - nhdr.idFrom = idCtrl; - nhdr.code = UWM_FRAMELOSTFOCUS; - SendMessage(WM_NOTIFY, (WPARAM)idCtrl, (LPARAM)&nhdr); - } - } - - inline void CDocker::OnCaptionTimer(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(lParam); - - if (this == GetDockAncestor()) - { - if (wParam == 1) - { - DrawAllCaptions(); - m_nTimerCount++; - if (m_nTimerCount == 10) - { - KillTimer(wParam); - m_nTimerCount = 0; - } - } - } - } - - inline void CDocker::OnCreate() - { - -#if defined(WINVER) && defined (WS_EX_LAYOUTRTL) && (WINVER >= 0x0500) - if (GetParent()->GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_LAYOUTRTL) - { - DWORD dwExStyle = GetWindowLongPtr(GWL_EXSTYLE); - SetWindowLongPtr(GWL_EXSTYLE, dwExStyle | WS_EX_LAYOUTRTL); - } -#endif - - // Create the various child windows - GetDockClient().SetDock(this); - GetDockClient().Create(this); - - assert(GetView()); // Use SetView in CMainFrame's constructor to set the view window - GetView()->Create(&GetDockClient()); - - // Create the slider bar belonging to this docker - GetDockBar().SetDock(this); - if (GetDockAncestor() != this) - GetDockBar().Create(GetParent()); - - // Now remove the WS_POPUP style. It was required to allow this window - // to be owned by the frame window. - SetWindowLongPtr(GWL_STYLE, WS_CHILD); - SetParent(GetParent()); // Reinstate the window's parent - - // Set the default colour for the splitter bar - COLORREF rgbColour = GetSysColor(COLOR_BTNFACE); - CWnd* pFrame = GetDockAncestor()->GetAncestor(); - ReBarTheme* pTheme = (ReBarTheme*)pFrame->SendMessage(UWM_GETREBARTHEME, 0, 0); - - if (pTheme && pTheme->UseThemes && pTheme->clrBkgnd2 != 0) - rgbColour =pTheme->clrBkgnd2; - - SetBarColor(rgbColour); - - // Set the caption height based on text height - m_NCHeight = MAX(20, GetTextHeight() + 5); - } - - inline void CDocker::OnDestroy(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - // Destroy any dock children first - std::vector::iterator iter; - for (iter = GetDockChildren().begin(); iter < GetDockChildren().end(); ++iter) - { - (*iter)->Destroy(); - } - - if (dynamic_cast(GetView()) && IsUndocked()) - { - CDockContainer* pContainer = (CDockContainer*)GetView(); - if (pContainer->GetAllContainers().size() > 1) - { - // This container has children, so destroy them now - std::vector AllContainers = pContainer->GetAllContainers(); - std::vector::iterator iter; - for (iter = AllContainers.begin(); iter < AllContainers.end(); ++iter) - { - if ((*iter).pContainer != pContainer) - { - // Reset container parent before destroying the dock window - CDocker* pDock = GetDockFromView((*iter).pContainer); - if (pContainer->IsWindow()) - pContainer->SetParent(&pDock->GetDockClient()); - - pDock->Destroy(); - } - } - } - } - - GetDockBar().Destroy(); - - // Post a destroy docker message - if ( GetDockAncestor()->IsWindow() ) - GetDockAncestor()->PostMessage(UWM_DOCK_DESTROYED, (WPARAM)this, 0L); - } - - inline void CDocker::OnDockDestroyed(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(lParam); - - CDocker* pDock = (CDocker*)wParam; - - assert( this == GetDockAncestor() ); - std::vector::iterator iter; - for (iter = GetAllDockers().begin(); iter < GetAllDockers().end(); ++iter) - { - if ((*iter).get() == pDock) - { - GetAllDockers().erase(iter); - break; - } - } - } - - inline void CDocker::OnExitSizeMove(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - m_BlockMove = FALSE; - m_bIsDragging = FALSE; - SendNotify(UWM_DOCK_END); - } - - inline LRESULT CDocker::OnNotify(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - LPDRAGPOS pdp = (LPDRAGPOS)lParam; - - switch (((LPNMHDR)lParam)->code) - { - case UWM_DOCK_START: - { - if (IsDocked()) - { - Undock(GetCursorPos()); - SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(pdp->ptPos.x, pdp->ptPos.y)); - } - } - break; - - case UWM_DOCK_MOVE: - { - CheckAllTargets((LPDRAGPOS)lParam); - } - break; - - case UWM_DOCK_END: - { - CDocker* pDock = (CDocker*)FromHandle(pdp->hdr.hwndFrom); - if (NULL == pDock) break; - - UINT DockZone = pdp->DockZone; - CRect rc = pDock->GetWindowRect(); - - switch(DockZone) - { - case DS_DOCKED_LEFT: - case DS_DOCKED_RIGHT: - pDock->SetDockSize(rc.Width()); - Dock(pDock, pDock->GetDockStyle() | DockZone); - break; - case DS_DOCKED_TOP: - case DS_DOCKED_BOTTOM: - pDock->SetDockSize(rc.Height()); - Dock(pDock, pDock->GetDockStyle() | DockZone); - break; - case DS_DOCKED_CONTAINER: - { - DockInContainer(pDock, pDock->GetDockStyle() | DockZone); - CDockContainer* pContainer = (CDockContainer*)GetView(); - int nPage = pContainer->GetContainerIndex((CDockContainer*)pDock->GetView()); - pContainer->SelectPage(nPage); - } - break; - case DS_DOCKED_LEFTMOST: - case DS_DOCKED_RIGHTMOST: - pDock->SetDockSize(rc.Width()); - DockOuter(pDock, pDock->GetDockStyle() | DockZone); - break; - case DS_DOCKED_TOPMOST: - case DS_DOCKED_BOTTOMMOST: - pDock->SetDockSize(rc.Height()); - DockOuter(pDock, pDock->GetDockStyle() | DockZone); - break; - } - - GetDockHint().Destroy(); - CloseAllTargets(); - } - break; - - case UWM_BAR_START: - { - CPoint pt = pdp->ptPos; - ScreenToClient(pt); - if (!IsDragAutoResize()) - DrawHashBar(pdp->hdr.hwndFrom, pt); - m_OldPoint = pt; - } - break; - - case UWM_BAR_MOVE: - { - CPoint pt = pdp->ptPos; - ScreenToClient(pt); - - if (pt != m_OldPoint) - { - if (IsDragAutoResize()) - ResizeDockers(pdp); - else - { - DrawHashBar(pdp->hdr.hwndFrom, m_OldPoint); - DrawHashBar(pdp->hdr.hwndFrom, pt); - } - - m_OldPoint = pt; - } - } - break; - - case UWM_BAR_END: - { - POINT pt = pdp->ptPos; - ScreenToClient(pt); - - if (!IsDragAutoResize()) - DrawHashBar(pdp->hdr.hwndFrom, pt); - - ResizeDockers(pdp); - } - break; - case NM_SETFOCUS: - if (GetDockAncestor()->IsWindow()) - GetDockAncestor()->PostMessage(UWM_DOCK_ACTIVATED, 0, 0); - break; - case UWM_FRAMEGOTFOCUS: - if (GetDockAncestor()->IsWindow()) - GetDockAncestor()->PostMessage(UWM_DOCK_ACTIVATED, 0, 0); - if (GetView()->IsWindow()) - GetView()->SendMessage(WM_NOTIFY, wParam, lParam); - break; - case UWM_FRAMELOSTFOCUS: - if (GetDockAncestor()->IsWindow()) - GetDockAncestor()->PostMessage(UWM_DOCK_ACTIVATED, 0, 0); - if (GetView()->IsWindow()) - GetView()->SendMessage(WM_NOTIFY, wParam, lParam); - break; - } - return 0L; - } - - inline void CDocker::ResizeDockers(LPDRAGPOS pdp) - // Called when the docker's splitter bar is dragged - { - assert(pdp); - - POINT pt = pdp->ptPos; - ScreenToClient(pt); - - CDocker* pDock = ((CDockBar*)FromHandle(pdp->hdr.hwndFrom))->GetDock(); - if (NULL == pDock) return; - - RECT rcDock = pDock->GetWindowRect(); - ScreenToClient(rcDock); - - double dBarWidth = pDock->GetDockBar().GetWidth(); - int iBarWidth = pDock->GetDockBar().GetWidth(); - int DockSize; - - switch (pDock->GetDockStyle() & 0xF) - { - case DS_DOCKED_LEFT: - DockSize = MAX(pt.x, iBarWidth/2) - rcDock.left - (int)(.5* dBarWidth); - DockSize = MAX(-iBarWidth, DockSize); - pDock->SetDockSize(DockSize); - pDock->m_DockSizeRatio = ((double)pDock->m_DockStartSize)/((double)pDock->m_pDockParent->GetWindowRect().Width()); - break; - case DS_DOCKED_RIGHT: - DockSize = rcDock.right - MAX(pt.x, iBarWidth/2) - (int)(.5* dBarWidth); - DockSize = MAX(-iBarWidth, DockSize); - pDock->SetDockSize(DockSize); - pDock->m_DockSizeRatio = ((double)pDock->m_DockStartSize)/((double)pDock->m_pDockParent->GetWindowRect().Width()); - break; - case DS_DOCKED_TOP: - DockSize = MAX(pt.y, iBarWidth/2) - rcDock.top - (int)(.5* dBarWidth); - DockSize = MAX(-iBarWidth, DockSize); - pDock->SetDockSize(DockSize); - pDock->m_DockSizeRatio = ((double)pDock->m_DockStartSize)/((double)pDock->m_pDockParent->GetWindowRect().Height()); - break; - case DS_DOCKED_BOTTOM: - DockSize = rcDock.bottom - MAX(pt.y, iBarWidth/2) - (int)(.5* dBarWidth); - DockSize = MAX(-iBarWidth, DockSize); - pDock->SetDockSize(DockSize); - pDock->m_DockSizeRatio = ((double)pDock->m_DockStartSize)/((double)pDock->m_pDockParent->GetWindowRect().Height()); - break; - } - - RecalcDockLayout(); - } - - inline void CDocker::OnSetFocus(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - if (IsUndocked() && m_hOldFocus) - ::SetFocus(m_hOldFocus); - else - // Pass focus on the the view window - GetView()->SetFocus(); - - if ((this == GetTopmostDocker()) && (this != GetDockAncestor())) - { - // Send a notification to top level window - int idCtrl = ::GetDlgCtrlID(m_hOldFocus); - NMHDR nhdr={0}; - nhdr.hwndFrom = m_hOldFocus; - nhdr.idFrom = idCtrl; - nhdr.code = NM_SETFOCUS; - SendMessage(WM_NOTIFY, (WPARAM)idCtrl, (LPARAM)&nhdr); - } - } - - inline void CDocker::OnSysColorChange(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - if (this == GetDockAncestor()) - { - COLORREF rgbColour = GetSysColor(COLOR_BTNFACE); - CWnd* pFrame = GetDockAncestor()->GetAncestor(); - ReBarTheme* pTheme = (ReBarTheme*)pFrame->SendMessage(UWM_GETREBARTHEME, 0, 0); - - if (pTheme && pTheme->UseThemes && pTheme->clrBand2 != 0) - rgbColour = pTheme->clrBkgnd2; - else - rgbColour = GetSysColor(COLOR_BTNFACE); - - // Set the splitter bar colour for each docker decendant - std::vector::iterator iter; - for (iter = GetAllDockers().begin(); iter < GetAllDockers().end(); ++iter) - (*iter)->SetBarColor(rgbColour); - - // Set the splitter bar colour for the docker ancestor - SetBarColor(rgbColour); - } - } - - inline LRESULT CDocker::OnSysCommand(WPARAM wParam, LPARAM lParam) - { - switch(wParam&0xFFF0) - { - case SC_MOVE: - // An undocked docker is being moved - { - BOOL bResult = FALSE; - m_bIsDragging = TRUE; - SetCursor(LoadCursor(NULL, IDC_ARROW)); - - if (SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &bResult, 0)) - { - // Turn on DragFullWindows for this move - SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, 0, 0); - - // Process this message - DefWindowProc(WM_SYSCOMMAND, wParam, lParam); - - // Return DragFullWindows to its previous state - SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, bResult, 0, 0); - return 0L; - } - } - break; - case SC_CLOSE: - // The close button is pressed on an undocked docker - m_bIsClosing = TRUE; - break; - } - return CWnd::WndProcDefault(WM_SYSCOMMAND, wParam, lParam); - } - - inline LRESULT CDocker::OnWindowPosChanging(WPARAM wParam, LPARAM lParam) - { - // Suspend dock drag moving while over dock zone - if (m_BlockMove) - { - LPWINDOWPOS pWndPos = (LPWINDOWPOS)lParam; - pWndPos->flags |= SWP_NOMOVE|SWP_FRAMECHANGED; - return 0; - } - - return CWnd::WndProcDefault(WM_WINDOWPOSCHANGING, wParam, lParam); - } - - inline void CDocker::OnWindowPosChanged(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - - if (m_bIsDragging) - { - // Send a Move notification to the parent - if ( IsLeftButtonDown() ) - { - LPWINDOWPOS wPos = (LPWINDOWPOS)lParam; - if ((!(wPos->flags & SWP_NOMOVE)) || m_BlockMove) - SendNotify(UWM_DOCK_MOVE); - } - else - { - CloseAllTargets(); - m_BlockMove = FALSE; - } - } - else if (this == GetTopmostDocker()) - { - // Reposition the dock children - if (IsUndocked() && IsWindowVisible() && !m_bIsClosing) RecalcDockLayout(); - } - } - - inline void CDocker::PreCreate(CREATESTRUCT &cs) - { - // Specify the WS_POPUP style to have this window owned - if (this != GetDockAncestor()) - cs.style = WS_POPUP; - - cs.dwExStyle = WS_EX_TOOLWINDOW; - } - - inline void CDocker::PreRegisterClass(WNDCLASS &wc) - { - wc.lpszClassName = _T("Win32++ Docker"); - wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); - } - - inline void CDocker::RecalcDockChildLayout(CRect rc) - { - // This function positions the Docker's dock children, the Dockers client area - // and draws the dockbar bars. - - // Notes: - // 1) This function is called recursively. - // 2) The client area and child dockers are positioned simultaneously with - // DeferWindowPos to avoid drawing errors in complex docker arrangements. - // 3) The docker's client area contains the docker's caption (if any) and the docker's view window. - - // Note: All top level dockers are undocked, including the dock ancestor. - if (IsDocked()) - { - rc.OffsetRect(-rc.left, -rc.top); - } - - HDWP hdwp = BeginDeferWindowPos((int)m_vDockChildren.size() +2); - - // Step 1: Calculate the position of each Docker child, DockBar, and Client window. - // The Client area = the docker rect minus the area of dock children and the dock bar (splitter bar). - for (UINT u = 0; u < m_vDockChildren.size(); ++u) - { - CRect rcChild = rc; - double DockSize = m_vDockChildren[u]->m_DockStartSize;; - - // Calculate the size of the Docker children - switch (m_vDockChildren[u]->GetDockStyle() & 0xF) - { - case DS_DOCKED_LEFT: - if (!(GetDockStyle() & DS_FIXED_RESIZE)) - DockSize = MIN(m_vDockChildren[u]->m_DockSizeRatio*(GetWindowRect().Width()), rcChild.Width()); - rcChild.right = rcChild.left + (int)DockSize; - break; - case DS_DOCKED_RIGHT: - if (!(GetDockStyle() & DS_FIXED_RESIZE)) - DockSize = MIN(m_vDockChildren[u]->m_DockSizeRatio*(GetWindowRect().Width()), rcChild.Width()); - rcChild.left = rcChild.right - (int)DockSize; - break; - case DS_DOCKED_TOP: - if (!(GetDockStyle() & DS_FIXED_RESIZE)) - DockSize = MIN(m_vDockChildren[u]->m_DockSizeRatio*(GetWindowRect().Height()), rcChild.Height()); - rcChild.bottom = rcChild.top + (int)DockSize; - break; - case DS_DOCKED_BOTTOM: - if (!(GetDockStyle() & DS_FIXED_RESIZE)) - DockSize = MIN(m_vDockChildren[u]->m_DockSizeRatio*(GetWindowRect().Height()), rcChild.Height()); - rcChild.top = rcChild.bottom - (int)DockSize; - break; - } - - if (m_vDockChildren[u]->IsDocked()) - { - // Position this docker's children - hdwp = m_vDockChildren[u]->DeferWindowPos(hdwp, NULL, rcChild, SWP_SHOWWINDOW|SWP_FRAMECHANGED); - m_vDockChildren[u]->m_rcChild = rcChild; - - rc.SubtractRect(rc, rcChild); - - // Calculate the dimensions of the splitter bar - CRect rcBar = rc; - DWORD DockSide = m_vDockChildren[u]->GetDockStyle() & 0xF; - - if (DS_DOCKED_LEFT == DockSide) rcBar.right = rcBar.left + m_vDockChildren[u]->GetBarWidth(); - if (DS_DOCKED_RIGHT == DockSide) rcBar.left = rcBar.right - m_vDockChildren[u]->GetBarWidth(); - if (DS_DOCKED_TOP == DockSide) rcBar.bottom = rcBar.top + m_vDockChildren[u]->GetBarWidth(); - if (DS_DOCKED_BOTTOM == DockSide) rcBar.top = rcBar.bottom - m_vDockChildren[u]->GetBarWidth(); - - // Save the splitter bar position. We will reposition it later. - m_vDockChildren[u]->m_rcBar = rcBar; - rc.SubtractRect(rc, rcBar); - } - } - - // Step 2: Position the Dock client and dock bar - hdwp = GetDockClient().DeferWindowPos(hdwp, NULL, rc, SWP_SHOWWINDOW |SWP_FRAMECHANGED); - EndDeferWindowPos(hdwp); - - // Position the dockbar. Only docked dockers have a dock bar. - if (IsDocked()) - { - // The SWP_NOCOPYBITS forces a redraw of the dock bar. - GetDockBar().SetWindowPos(NULL, m_rcBar, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS ); - } - - // Step 3: Now recurse through the docker's children. They might have children of their own. - for (UINT v = 0; v < m_vDockChildren.size(); ++v) - { - m_vDockChildren[v]->RecalcDockChildLayout(m_vDockChildren[v]->m_rcChild); - } - } - - inline void CDocker::RecalcDockLayout() - // Repositions the dock children of a top level docker - { - if (GetDockAncestor()->IsWindow()) - { - CRect rc = GetTopmostDocker()->GetClientRect(); - GetTopmostDocker()->RecalcDockChildLayout(rc); - GetTopmostDocker()->UpdateWindow(); - } - } - - inline std::vector CDocker::SortDockers() - // Returns a vector of sorted dockers, used by SaveRegistrySettings. - { - std::vector vSorted; - std::vector::iterator itSort; - std::vector::iterator itAll; - - // Add undocked top level dockers - for (itAll = GetAllDockers().begin(); itAll < GetAllDockers().end(); ++itAll) - { - if (!(*itAll)->GetDockParent()) - vSorted.push_back((*itAll).get()); - } - - // Add dock ancestor's children - vSorted.insert(vSorted.end(), GetDockAncestor()->GetDockChildren().begin(), GetDockAncestor()->GetDockChildren().end()); - - // Add other dock children - int index = 0; - itSort = vSorted.begin(); - while (itSort < vSorted.end()) - { - vSorted.insert(vSorted.end(), (*itSort)->GetDockChildren().begin(), (*itSort)->GetDockChildren().end()); - itSort = vSorted.begin() + (++index); - } - - // Add dockers docked in containers - std::vector vDockContainers; - for (itSort = vSorted.begin(); itSort< vSorted.end(); ++itSort) - { - if ((*itSort)->GetContainer()) - vDockContainers.push_back(*itSort); - } - - for (itSort = vDockContainers.begin(); itSort < vDockContainers.end(); ++itSort) - { - CDockContainer* pContainer = (*itSort)->GetContainer(); - - for (UINT i = 1; i < pContainer->GetAllContainers().size(); ++i) - { - CDockContainer* pChild = pContainer->GetContainerFromIndex(i); - CDocker* pDock = GetDockFromView(pChild); - vSorted.push_back(pDock); - } - } - - return vSorted; - } - - inline BOOL CDocker::SaveRegistrySettings(tString tsRegistryKeyName) - // Stores the docking configuration in the registry - // NOTE: This function assumes that each docker has a unique DockID - { - assert(VerifyDockers()); - - std::vector vSorted = SortDockers(); - std::vector::iterator iter; - std::vector vDockInfo; - - if (0 != tsRegistryKeyName.size()) - { - // Fill the DockInfo vector with the docking information - for (iter = vSorted.begin(); iter < vSorted.end(); ++iter) - { - DockInfo di = {0}; - di.DockID = (*iter)->GetDockID(); - di.DockStyle = (*iter)->GetDockStyle(); - di.DockSize = (*iter)->GetDockSize(); - di.Rect = (*iter)->GetWindowRect(); - if ((*iter)->GetDockParent()) - di.DockParentID = (*iter)->GetDockParent()->GetDockID(); - - vDockInfo.push_back(di); - } - - tString tsKeyName = _T("Software\\") + tsRegistryKeyName; - HKEY hKey = NULL; - HKEY hKeyDock = NULL; - - try - { - if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, tsKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL)) - throw (CWinException(_T("RegCreateKeyEx Failed"))); - - RegDeleteKey(hKey, _T("Dock Windows")); - if (ERROR_SUCCESS != RegCreateKeyEx(hKey, _T("Dock Windows"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyDock, NULL)) - throw (CWinException(_T("RegCreateKeyEx Failed"))); - - // Add the Dock windows information to the registry - for (UINT u = 0; u < vDockInfo.size(); ++u) - { - DockInfo di = vDockInfo[u]; - TCHAR szNumber[16]; - tString tsSubKey = _T("DockChild"); - tsSubKey += _itot((int)u, szNumber, 10); - if(ERROR_SUCCESS != RegSetValueEx(hKeyDock, tsSubKey.c_str(), 0, REG_BINARY, (LPBYTE)&di, sizeof(DockInfo))) - throw (CWinException(_T("RegSetValueEx failed"))); - } - - // Add Active Container to the registry - int i = 0; - for (iter = vSorted.begin(); iter < vSorted.end(); ++iter) - { - CDockContainer* pContainer = (*iter)->GetContainer(); - - if (pContainer && (pContainer == pContainer->GetActiveContainer())) - { - TCHAR szNumber[20]; - tString tsSubKey = _T("ActiveContainer"); - tsSubKey += _itot(i++, szNumber, 10); - int nID = GetDockFromView(pContainer)->GetDockID(); - if(ERROR_SUCCESS != RegSetValueEx(hKeyDock, tsSubKey.c_str(), 0, REG_DWORD, (LPBYTE)&nID, sizeof(int))) - throw (CWinException(_T("RegSetValueEx failed"))); - } - } - - RegCloseKey(hKeyDock); - RegCloseKey(hKey); - } - - catch (const CWinException& e) - { - // Roll back the registry changes by deleting the subkeys - if (hKey) - { - if (hKeyDock) - { - RegDeleteKey(hKeyDock, _T("Dock Windows")); - RegCloseKey(hKeyDock); - } - - RegDeleteKey(HKEY_CURRENT_USER ,tsKeyName.c_str()); - RegCloseKey(hKey); - } - - e.what(); - return FALSE; - } - } - - return TRUE; - } - - inline void CDocker::SendNotify(UINT nMessageID) - // Sends a docking notification to the docker below the cursor - { - DRAGPOS DragPos; - DragPos.hdr.code = nMessageID; - DragPos.hdr.hwndFrom = m_hWnd; - DragPos.ptPos = GetCursorPos(); - DragPos.DockZone = m_dwDockZone; - m_dwDockZone = 0; - - CDocker* pDock = GetDockFromPoint(DragPos.ptPos); - - if (pDock) - pDock->SendMessage(WM_NOTIFY, 0L, (LPARAM)&DragPos); - else - { - if (GetDockHint().IsWindow()) GetDockHint().Destroy(); - CloseAllTargets(); - m_BlockMove = FALSE; - } - } - - inline void CDocker::SetDockStyle(DWORD dwDockStyle) - { - if (IsWindow()) - { - if ((dwDockStyle & DS_CLIENTEDGE) != (m_DockStyle & DS_CLIENTEDGE)) - { - if (dwDockStyle & DS_CLIENTEDGE) - { - DWORD dwExStyle = (DWORD)GetDockClient().GetWindowLongPtr(GWL_EXSTYLE)|WS_EX_CLIENTEDGE; - GetDockClient().SetWindowLongPtr(GWL_EXSTYLE, dwExStyle); - GetDockClient().RedrawWindow(0, 0, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_FRAME); - } - else - { - DWORD dwExStyle = (DWORD)GetDockClient().GetWindowLongPtr(GWL_EXSTYLE); - dwExStyle &= ~WS_EX_CLIENTEDGE; - GetDockClient().SetWindowLongPtr(GWL_EXSTYLE, dwExStyle); - GetDockClient().RedrawWindow(0, 0, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_FRAME); - } - } - - RecalcDockLayout(); - } - - m_DockStyle = dwDockStyle; - } - - inline void CDocker::SetCaption(LPCTSTR szCaption) - // Sets the caption text - { - GetDockClient().SetCaption(szCaption); - - if (IsWindow()) - SetWindowText(szCaption); - } - - inline void CDocker::SetCaptionColors(COLORREF Foregnd1, COLORREF Backgnd1, COLORREF ForeGnd2, COLORREF BackGnd2) - { - GetDockClient().SetCaptionColors(Foregnd1, Backgnd1, ForeGnd2, BackGnd2); - } - - inline void CDocker::SetCaptionHeight(int nHeight) - // Sets the height of the caption - { - m_NCHeight = nHeight; - RedrawWindow(); - RecalcDockLayout(); - } - - inline void CDocker::SetDockSize(int DockSize) - // Sets the size of a docked docker - { - if (IsDocked()) - { - assert (m_pDockParent); - switch (GetDockStyle() & 0xF) - { - case DS_DOCKED_LEFT: - m_DockStartSize = MIN(DockSize,m_pDockParent->GetWindowRect().Width()); - m_DockSizeRatio = ((double)m_DockStartSize)/((double)m_pDockParent->GetWindowRect().Width()); - break; - case DS_DOCKED_RIGHT: - m_DockStartSize = MIN(DockSize,m_pDockParent->GetWindowRect().Width()); - m_DockSizeRatio = ((double)m_DockStartSize)/((double)m_pDockParent->GetWindowRect().Width()); - break; - case DS_DOCKED_TOP: - m_DockStartSize = MIN(DockSize,m_pDockParent->GetWindowRect().Height()); - m_DockSizeRatio = ((double)m_DockStartSize)/((double)m_pDockParent->GetWindowRect().Height()); - break; - case DS_DOCKED_BOTTOM: - m_DockStartSize = MIN(DockSize,m_pDockParent->GetWindowRect().Height()); - m_DockSizeRatio = ((double)m_DockStartSize)/((double)m_pDockParent->GetWindowRect().Height()); - break; - } - - RecalcDockLayout(); - } - else - { - m_DockStartSize = DockSize; - m_DockSizeRatio = 1.0; - } - } - - inline void CDocker::SetDragAutoResize(BOOL bAutoResize) - { - m_bDragAutoResize = bAutoResize; - } - - inline void CDocker::SetView(CWnd& wndView) - // Assigns the view window to the docker - { - CWnd* pWnd = &wndView; - GetDockClient().SetView(wndView); - if (dynamic_cast(pWnd)) - { - CDockContainer* pContainer = (CDockContainer*)&wndView; - SetCaption(pContainer->GetDockCaption().c_str()); - } - } - - inline void CDocker::PromoteFirstChild() - // One of the steps required for undocking - { - // Promote our first child to replace ourself - if (m_pDockParent) - { - for (UINT u = 0 ; u < m_pDockParent->m_vDockChildren.size(); ++u) - { - if (m_pDockParent->m_vDockChildren[u] == this) - { - if (m_vDockChildren.size() > 0) - // swap our first child for ourself as a child of the parent - m_pDockParent->m_vDockChildren[u] = m_vDockChildren[0]; - else - // remove ourself as a child of the parent - m_pDockParent->m_vDockChildren.erase(m_pDockParent->m_vDockChildren.begin() + u); - break; - } - } - } - - // Transfer styles and data and children to the child docker - CDocker* pDockFirstChild = NULL; - if (m_vDockChildren.size() > 0) - { - pDockFirstChild = m_vDockChildren[0]; - pDockFirstChild->m_DockStyle = (pDockFirstChild->m_DockStyle & 0xFFFFFFF0 ) | (m_DockStyle & 0xF); - pDockFirstChild->m_DockStartSize = m_DockStartSize; - pDockFirstChild->m_DockSizeRatio = m_DockSizeRatio; - - if (m_pDockParent) - { - pDockFirstChild->m_pDockParent = m_pDockParent; - pDockFirstChild->SetParent(m_pDockParent); - pDockFirstChild->GetDockBar().SetParent(m_pDockParent); - } - else - { - std::vector::iterator iter; - for (iter = GetDockChildren().begin() + 1; iter < GetDockChildren().end(); ++iter) - (*iter)->ShowWindow(SW_HIDE); - - pDockFirstChild->ConvertToPopup(GetWindowRect()); - pDockFirstChild->GetDockBar().ShowWindow(SW_HIDE); - } - - m_vDockChildren.erase(m_vDockChildren.begin()); - MoveDockChildren(pDockFirstChild); - } - } - - inline void CDocker::ConvertToChild(HWND hWndParent) - { - DWORD dwStyle = WS_CHILD | WS_VISIBLE; - SetWindowLongPtr(GWL_STYLE, dwStyle); - SetParent(FromHandle(hWndParent)); - GetDockBar().SetParent(FromHandle(hWndParent)); - } - - inline void CDocker::ConvertToPopup(RECT rc) - { - // Change the window to an "undocked" style - ShowWindow(SW_HIDE); - DWORD dwStyle = WS_POPUP| WS_CAPTION | WS_SYSMENU | WS_THICKFRAME; - SetWindowLongPtr(GWL_STYLE, dwStyle); - - // Change the window's parent and reposition it - GetDockBar().ShowWindow(SW_HIDE); - SetWindowPos(0, 0, 0, 0, 0, SWP_NOSENDCHANGING|SWP_HIDEWINDOW|SWP_NOREDRAW); - m_pDockParent = 0; - SetParent(0); - SetWindowPos(NULL, rc, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOOWNERZORDER); - GetDockClient().SetWindowPos(NULL, GetClientRect(), SWP_SHOWWINDOW); - - SetWindowText(GetCaption().c_str()); - } - - inline CDocker* CDocker::SeparateFromDock() - { - // This performs some of the tasks required for undocking. - // It is also used when a docker is hidden. - CDocker* pDockUndockedFrom = GetDockParent(); - if (!pDockUndockedFrom && (GetDockChildren().size() > 0)) - pDockUndockedFrom = GetDockChildren()[0]; - - GetTopmostDocker()->m_hOldFocus = 0; - PromoteFirstChild(); - m_pDockParent = 0; - - GetDockBar().ShowWindow(SW_HIDE); - m_DockStyle = m_DockStyle & 0xFFFFFFF0; - m_DockStyle &= ~DS_DOCKED_CONTAINER; - - return pDockUndockedFrom; - } - - inline void CDocker::SetUndockPosition(CPoint pt) - { - m_Undocking = TRUE; - CRect rc; - rc = GetDockClient().GetWindowRect(); - CRect rcTest = rc; - rcTest.bottom = MIN(rcTest.bottom, rcTest.top + m_NCHeight); - if ( !rcTest.PtInRect(pt)) - rc.SetRect(pt.x - rc.Width()/2, pt.y - m_NCHeight/2, pt.x + rc.Width()/2, pt.y - m_NCHeight/2 + rc.Height()); - - ConvertToPopup(rc); - m_Undocking = FALSE; - - // Send the undock notification to the frame - NMHDR nmhdr = {0}; - nmhdr.hwndFrom = m_hWnd; - nmhdr.code = UWM_UNDOCKED; - nmhdr.idFrom = m_nDockID; - CWnd* pFrame = GetDockAncestor()->GetAncestor(); - pFrame->SendMessage(WM_NOTIFY, m_nDockID, (LPARAM)&nmhdr); - - // Initiate the window move - SetCursorPos(pt.x, pt.y); - ScreenToClient(pt); - PostMessage(WM_SYSCOMMAND, (WPARAM)(SC_MOVE|0x0002), MAKELPARAM(pt.x, pt.y)); - } - - inline void CDocker::Undock(CPoint pt, BOOL bShowUndocked) - { - // Return if we shouldn't undock - if (GetDockStyle() & DS_NO_UNDOCK) return; - - // Undocking isn't supported on Win95 - if (1400 == GetWinVersion()) return; - - CDocker* pDockUndockedFrom = SeparateFromDock(); - - // Position and draw the undocked window, unless it is about to be closed - if (bShowUndocked) - { - SetUndockPosition(pt); - } - - RecalcDockLayout(); - if ((pDockUndockedFrom) && (pDockUndockedFrom->GetTopmostDocker() != GetTopmostDocker())) - pDockUndockedFrom->RecalcDockLayout(); - } - - inline void CDocker::UndockContainer(CDockContainer* pContainer, CPoint pt, BOOL bShowUndocked) - { - assert(pContainer); - assert(this == GetDockFromView(pContainer->GetContainerParent())); - - // Return if we shouldn't undock - if (GetDockFromView(pContainer)->GetDockStyle() & DS_NO_UNDOCK) return; - - // Undocking isn't supported on Win95 - if (1400 == GetWinVersion()) return; - - GetTopmostDocker()->m_hOldFocus = 0; - CDocker* pDockUndockedFrom = GetDockFromView(pContainer->GetContainerParent()); - pDockUndockedFrom->ShowWindow(SW_HIDE); - if (GetView() == pContainer) - { - // The parent container is being undocked, so we need - // to transfer our child containers to a different docker - - // Choose a new docker from among the dockers for child containers - CDocker* pDockNew = 0; - CDocker* pDockOld = GetDockFromView(pContainer); - std::vector AllContainers = pContainer->GetAllContainers(); - std::vector::iterator iter = AllContainers.begin(); - while ((0 == pDockNew) && (iter < AllContainers.end())) - { - if ((*iter).pContainer != pContainer) - pDockNew = (CDocker*)FromHandle(::GetParent((*iter).pContainer->GetParent()->GetHwnd())); - - ++iter; - } - - if (pDockNew) - { - // Move containers from the old docker to the new docker - CDockContainer* pContainerNew = (CDockContainer*)pDockNew->GetView(); - for (iter = AllContainers.begin(); iter != AllContainers.end(); ++iter) - { - if ((*iter).pContainer != pContainer) - { - CDockContainer* pChildContainer = (CDockContainer*)(*iter).pContainer; - pContainer->RemoveContainer(pChildContainer); - if (pContainerNew != pChildContainer) - { - pContainerNew->AddContainer(pChildContainer); - CDocker* pDock = GetDockFromView(pChildContainer); - pDock->SetParent(pDockNew); - pDock->m_pDockParent = pDockNew; - } - } - } - - // Now transfer the old docker's settings to the new one. - pDockUndockedFrom = pDockNew; - pDockNew->m_DockStyle = pDockOld->m_DockStyle; - pDockNew->m_DockStartSize = pDockOld->m_DockStartSize; - pDockNew->m_DockSizeRatio = pDockOld->m_DockSizeRatio; - if (pDockOld->IsDocked()) - { - pDockNew->m_pDockParent = pDockOld->m_pDockParent; - pDockNew->SetParent(pDockOld->GetParent()); - } - else - { - CRect rc = pDockOld->GetWindowRect(); - pDockNew->ShowWindow(SW_HIDE); - DWORD dwStyle = WS_POPUP| WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_VISIBLE; - pDockNew->SetWindowLongPtr(GWL_STYLE, dwStyle); - pDockNew->m_pDockParent = 0; - pDockNew->SetParent(0); - pDockNew->SetWindowPos(NULL, rc, SWP_SHOWWINDOW|SWP_FRAMECHANGED| SWP_NOOWNERZORDER); - } - pDockNew->GetDockBar().SetParent(pDockOld->GetParent()); - pDockNew->GetView()->SetFocus(); - - // Transfer the Dock children to the new docker - pDockOld->MoveDockChildren(pDockNew); - - // insert pDockNew into its DockParent's DockChildren vector - if (pDockNew->m_pDockParent) - { - std::vector::iterator p; - for (p = pDockNew->m_pDockParent->m_vDockChildren.begin(); p != pDockNew->m_pDockParent->m_vDockChildren.end(); ++p) - { - if (*p == this) - { - pDockNew->m_pDockParent->m_vDockChildren.insert(p, pDockNew); - break; - } - } - } - } - } - else - { - // This is a child container, so simply remove it from the parent - CDockContainer* pContainerParent = (CDockContainer*)GetView(); - pContainerParent->RemoveContainer(pContainer); - pContainerParent->SetTabSize(); - pContainerParent->SetFocus(); - pContainerParent->GetViewPage().SetParent(pContainerParent); - } - - // Finally do the actual undocking - CDocker* pDock = GetDockFromView(pContainer); - CRect rc = GetDockClient().GetWindowRect(); - ScreenToClient(rc); - pDock->GetDockClient().SetWindowPos(NULL, rc, SWP_SHOWWINDOW); - pDock->Undock(pt, bShowUndocked); - pDockUndockedFrom->ShowWindow(); - pDockUndockedFrom->RecalcDockLayout(); - pDock->BringWindowToTop(); - } - - inline LRESULT CDocker::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - switch (uMsg) - { - case WM_ACTIVATE: - OnActivate(wParam, lParam); - break; - case WM_SYSCOMMAND: - return OnSysCommand(wParam, lParam); - - case WM_EXITSIZEMOVE: - OnExitSizeMove(wParam, lParam); - break; - case WM_WINDOWPOSCHANGING: - return OnWindowPosChanging(wParam, lParam); - - case WM_WINDOWPOSCHANGED: - OnWindowPosChanged(wParam, lParam); - break; - case WM_DESTROY: - OnDestroy(wParam, lParam); - break; - case WM_SETFOCUS: - OnSetFocus(wParam, lParam); - break; - case WM_TIMER: - OnCaptionTimer(wParam, lParam); - break; - case UWM_DOCK_DESTROYED: - OnDockDestroyed(wParam, lParam); - break; - case UWM_DOCK_ACTIVATED: - DrawAllCaptions(); - SetTimer(1, 100, NULL); - break; - case WM_SYSCOLORCHANGE: - OnSysColorChange(wParam, lParam); - break; - case WM_NCLBUTTONDBLCLK : - m_bIsDragging = FALSE; - break; - } - - return CWnd::WndProcDefault(uMsg, wParam, lParam); - } - - - ////////////////////////////////////// - // Declaration of the CDockContainer class - inline CDockContainer::CDockContainer() : m_iCurrentPage(0), m_hTabIcon(0), m_nTabPressed(-1) - { - m_pContainerParent = this; - } - - inline CDockContainer::~CDockContainer() - { - if (m_hTabIcon) - DestroyIcon(m_hTabIcon); - } - - inline void CDockContainer::AddContainer(CDockContainer* pContainer) - { - assert(pContainer); - - if (this == m_pContainerParent) - { - ContainerInfo ci = {0}; - ci.pContainer = pContainer; - lstrcpy(ci.szTitle, pContainer->GetTabText()); - ci.iImage = ImageList_AddIcon(GetImageList(), pContainer->GetTabIcon()); - int iNewPage = (int)m_vContainerInfo.size(); - m_vContainerInfo.push_back(ci); - - if (m_hWnd) - { - TCITEM tie = {0}; - tie.mask = TCIF_TEXT | TCIF_IMAGE; - tie.iImage = ci.iImage; - tie.pszText = m_vContainerInfo[iNewPage].szTitle; - TabCtrl_InsertItem(m_hWnd, iNewPage, &tie); - - SetTabSize(); - } - - pContainer->m_pContainerParent = this; - if (pContainer->IsWindow()) - { - // Set the parent container relationships - pContainer->GetViewPage().SetParent(this); - pContainer->GetViewPage().ShowWindow(SW_HIDE); - } - } - } - - inline void CDockContainer::AddToolBarButton(UINT nID, BOOL bEnabled /* = TRUE */) - // Adds Resource IDs to toolbar buttons. - // A resource ID of 0 is a separator - { - GetToolBar().AddButton(nID, bEnabled); - } - - inline CDockContainer* CDockContainer::GetContainerFromIndex(UINT nPage) - { - CDockContainer* pContainer = NULL; - if (nPage < m_vContainerInfo.size()) - pContainer = (CDockContainer*)m_vContainerInfo[nPage].pContainer; - - return pContainer; - } - - inline CWnd* CDockContainer::GetActiveView() const - // Returns a pointer to the active view window, or NULL if there is no active veiw. - { - CWnd* pWnd = NULL; - if (m_pContainerParent->m_vContainerInfo.size() > 0) - { - CDockContainer* pActiveContainer = m_pContainerParent->m_vContainerInfo[m_pContainerParent->m_iCurrentPage].pContainer; - if (pActiveContainer->GetViewPage().GetView()->IsWindow()) - pWnd = pActiveContainer->GetViewPage().GetView(); - } - - return pWnd; - } - - inline CDockContainer* CDockContainer::GetContainerFromView(CWnd* pView) const - { - assert(pView); - - std::vector::iterator iter; - CDockContainer* pViewContainer = 0; - for (iter = GetAllContainers().begin(); iter != GetAllContainers().end(); ++iter) - { - CDockContainer* pContainer = (*iter).pContainer; - if (pContainer->GetView() == pView) - pViewContainer = pContainer; - } - - return pViewContainer; - } - - inline int CDockContainer::GetContainerIndex(CDockContainer* pContainer) - { - assert(pContainer); - int iReturn = -1; - - for (int i = 0; i < (int)m_pContainerParent->m_vContainerInfo.size(); ++i) - { - if (m_pContainerParent->m_vContainerInfo[i].pContainer == pContainer) - iReturn = i; - } - - return iReturn; - } - - inline SIZE CDockContainer::GetMaxTabTextSize() - { - CSize Size; - - // Allocate an iterator for the ContainerInfo vector - std::vector::iterator iter; - - for (iter = m_vContainerInfo.begin(); iter != m_vContainerInfo.end(); ++iter) - { - CSize TempSize; - CClientDC dc(this); - NONCLIENTMETRICS info = {0}; - info.cbSize = GetSizeofNonClientMetrics(); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); - dc.CreateFontIndirect(&info.lfStatusFont); - TempSize = dc.GetTextExtentPoint32(iter->szTitle, lstrlen(iter->szTitle)); - if (TempSize.cx > Size.cx) - Size = TempSize; - } - - return Size; - } - - inline void CDockContainer::SetupToolBar() - { - // Use this function to set the Resource IDs for the toolbar(s). - -/* // Set the Resource IDs for the toolbar buttons - AddToolBarButton( IDM_FILE_NEW ); - AddToolBarButton( IDM_FILE_OPEN ); - AddToolBarButton( IDM_FILE_SAVE ); - AddToolBarButton( 0 ); // Separator - AddToolBarButton( IDM_EDIT_CUT ); - AddToolBarButton( IDM_EDIT_COPY ); - AddToolBarButton( IDM_EDIT_PASTE ); - AddToolBarButton( 0 ); // Separator - AddToolBarButton( IDM_FILE_PRINT ); - AddToolBarButton( 0 ); // Separator - AddToolBarButton( IDM_HELP_ABOUT ); -*/ - } - - inline void CDockContainer::OnCreate() - { - assert(GetView()); // Use SetView in CMainFrame's constructor to set the view window - - ContainerInfo ci = {0}; - ci.pContainer = this; - lstrcpy(ci.szTitle, GetTabText()); - ci.iImage = ImageList_AddIcon(GetImageList(), GetTabIcon()); - m_vContainerInfo.push_back(ci); - - // Create the page window - GetViewPage().Create(this); - - // Create the toolbar - GetToolBar().Create(&GetViewPage()); - DWORD style = (DWORD)GetToolBar().GetWindowLongPtr(GWL_STYLE); - style |= CCS_NODIVIDER ; - GetToolBar().SetWindowLongPtr(GWL_STYLE, style); - SetupToolBar(); - if (GetToolBar().GetToolBarData().size() > 0) - { - // Set the toolbar images - // A mask of 192,192,192 is compatible with AddBitmap (for Win95) - if (!GetToolBar().SendMessage(TB_GETIMAGELIST, 0L, 0L)) - GetToolBar().SetImages(RGB(192,192,192), IDW_MAIN, 0, 0); - - GetToolBar().SendMessage(TB_AUTOSIZE, 0L, 0L); - } - else - GetToolBar().Destroy(); - - SetFixedWidth(TRUE); - SetOwnerDraw(TRUE); - - // Add tabs for each container. - for (int i = 0; i < (int)m_vContainerInfo.size(); ++i) - { - // Add tabs for each view. - TCITEM tie = {0}; - tie.mask = TCIF_TEXT | TCIF_IMAGE; - tie.iImage = i; - tie.pszText = m_vContainerInfo[i].szTitle; - TabCtrl_InsertItem(m_hWnd, i, &tie); - } - } - - inline void CDockContainer::OnLButtonDown(WPARAM wParam, LPARAM lParam) - { - // Overrides CTab::OnLButtonDown - - UNREFERENCED_PARAMETER(wParam); - - CPoint pt((DWORD)lParam); - TCHITTESTINFO info = {0}; - info.pt = pt; - m_nTabPressed = HitTest(info); - } - - inline void CDockContainer::OnLButtonUp(WPARAM wParam, LPARAM lParam) - { - // Overrides CTab::OnLButtonUp and takes no action - - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - } - - inline void CDockContainer::OnMouseLeave(WPARAM wParam, LPARAM lParam) - { - // Overrides CTab::OnMouseLeave - - if (IsLeftButtonDown() && (m_nTabPressed >= 0)) - { - CDocker* pDock = (CDocker*)FromHandle(::GetParent(GetParent()->GetHwnd())); - if (dynamic_cast(pDock)) - { - CDockContainer* pContainer = GetContainerFromIndex(m_iCurrentPage); - pDock->UndockContainer(pContainer, GetCursorPos(), TRUE); - } - } - - m_nTabPressed = -1; - CTab::OnMouseLeave(wParam, lParam); - } - - inline LRESULT CDockContainer::OnNotifyReflect(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - - switch (((LPNMHDR)lParam)->code) - { - case TCN_SELCHANGE: - { - // Display the newly selected tab page - int nPage = GetCurSel(); - SelectPage(nPage); - } - break; - } - - return 0L; - } - - inline void CDockContainer::PreCreate(CREATESTRUCT &cs) - { - // For Tabs on the bottom, add the TCS_BOTTOM style - CTab::PreCreate(cs); - cs.style |= TCS_BOTTOM; - } - - inline void CDockContainer::RecalcLayout() - { - if (GetContainerParent() == this) - { - // Set the tab sizes - SetTabSize(); - - // Position the View over the tab control's display area - CRect rc = GetClientRect(); - AdjustRect(FALSE, &rc); - CDockContainer* pContainer = m_vContainerInfo[m_iCurrentPage].pContainer; - pContainer->GetViewPage().SetWindowPos(HWND_TOP, rc, SWP_SHOWWINDOW); - } - } - - inline void CDockContainer::RemoveContainer(CDockContainer* pWnd) - { - assert(pWnd); - - // Remove the tab - int iTab = GetContainerIndex(pWnd); - if (iTab > 0) - { - // DeleteItem(iTab); - TabCtrl_DeleteItem(m_hWnd, iTab); - } - - // Remove the ContainerInfo entry - std::vector::iterator iter; - int iImage = -1; - for (iter = m_vContainerInfo.begin(); iter != m_vContainerInfo.end(); ++iter) - { - if (iter->pContainer == pWnd) - { - iImage = (*iter).iImage; - if (iImage >= 0) - TabCtrl_RemoveImage(m_hWnd, iImage); - - m_vContainerInfo.erase(iter); - break; - } - } - - // Set the parent container relationships - pWnd->GetViewPage().SetParent(pWnd); - pWnd->m_pContainerParent = pWnd; - - // Display the first page - m_iCurrentPage = 0; - if (IsWindow()) - SelectPage(0); - } - - inline void CDockContainer::SelectPage(int nPage) - { - if (this != m_pContainerParent) - m_pContainerParent->SelectPage(nPage); - else - { - if ((nPage >= 0) && (nPage < (int)m_vContainerInfo.size() )) - { - if (GetCurSel() != nPage) - SetCurSel(nPage); - - // Create the new container window if required - if (!m_vContainerInfo[nPage].pContainer->IsWindow()) - { - CDockContainer* pContainer = m_vContainerInfo[nPage].pContainer; - pContainer->Create(GetParent()); - pContainer->GetViewPage().SetParent(this); - } - - // Determine the size of the tab page's view area - CRect rc = GetClientRect(); - AdjustRect(FALSE, &rc); - - // Swap the pages over - CDockContainer* pOldContainer = m_vContainerInfo[m_iCurrentPage].pContainer; - CDockContainer* pNewContainer = m_vContainerInfo[nPage].pContainer; - pOldContainer->GetViewPage().ShowWindow(SW_HIDE); - pNewContainer->GetViewPage().SetWindowPos(HWND_TOP, rc, SWP_SHOWWINDOW); - pNewContainer->GetViewPage().GetView()->SetFocus(); - - // Adjust the docking caption - CDocker* pDock = (CDocker*)FromHandle(::GetParent(::GetParent(m_hWnd))); - if (dynamic_cast(pDock)) - { - pDock->SetCaption(pNewContainer->GetDockCaption().c_str()); - pDock->RedrawWindow(); - } - - m_iCurrentPage = nPage; - } - } - } - - inline void CDockContainer::SetActiveContainer(CDockContainer* pContainer) - { - int nPage = GetContainerIndex(pContainer); - assert (0 <= nPage); - SelectPage(nPage); - } - - inline void CDockContainer::SetTabIcon(UINT nID_Icon) - { - HICON hIcon = (HICON)LoadImage(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(nID_Icon), IMAGE_ICON, 0, 0, LR_SHARED); - SetTabIcon(hIcon); - } - - inline void CDockContainer::SetTabSize() - { - CRect rc = GetClientRect(); - AdjustRect(FALSE, &rc); - if (rc.Width() < 0 ) - rc.SetRectEmpty(); - - int nItemWidth = MIN(25 + GetMaxTabTextSize().cx, (rc.Width()-2)/(int)m_vContainerInfo.size()); - int nItemHeight = MAX(20, GetTextHeight() + 5); - SendMessage(TCM_SETITEMSIZE, 0L, MAKELPARAM(nItemWidth, nItemHeight)); - } - - inline void CDockContainer::SetTabText(UINT nTab, LPCTSTR szText) - { - CDockContainer* pContainer = GetContainerParent()->GetContainerFromIndex(nTab); - pContainer->SetTabText(szText); - - CTab::SetTabText(nTab, szText); - } - - inline void CDockContainer::SetView(CWnd& Wnd) - { - GetViewPage().SetView(Wnd); - } - - inline LRESULT CDockContainer::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - switch (uMsg) - { - case WM_SIZE: - RecalcLayout(); - return 0; - - // The following are called in CTab::WndProcDefault - // case WM_LBUTTONDOWN: - // OnLButtonDown(wParam, lParam); - // break; - // case WM_LBUTTONUP: - // OnLButtonUp(wParam, lParam); - // break; - // case WM_MOUSELEAVE: - // OnMouseLeave(wParam, lParam); - // break; - - case WM_SETFOCUS: - { - // Pass focus on to the current view - GetActiveView()->SetFocus(); - } - break; - } - - // pass unhandled messages on to CTab for processing - return CTab::WndProcDefault(uMsg, wParam, lParam); - } - - - /////////////////////////////////////////// - // Declaration of the nested CViewPage class - inline BOOL CDockContainer::CViewPage::OnCommand(WPARAM wParam, LPARAM lParam) - { - CDockContainer* pContainer = (CDockContainer*)GetParent(); - BOOL bResult = FALSE; - if (pContainer && pContainer->GetActiveContainer()) - bResult = (BOOL)pContainer->GetActiveContainer()->SendMessage(WM_COMMAND, wParam, lParam); - - return bResult; - } - - inline void CDockContainer::CViewPage::OnCreate() - { - if (m_pView) - m_pView->Create(this); - } - - inline LRESULT CDockContainer::CViewPage::OnNotify(WPARAM wParam, LPARAM lParam) - { - UNREFERENCED_PARAMETER(wParam); - - switch (((LPNMHDR)lParam)->code) - { - - // Display tooltips for the toolbar - case TTN_GETDISPINFO: - { - int iIndex = GetToolBar().HitTest(); - LPNMTTDISPINFO lpDispInfo = (LPNMTTDISPINFO)lParam; - if (iIndex >= 0) - { - int nID = GetToolBar().GetCommandID(iIndex); - if (nID > 0) - { - m_tsTooltip = LoadString(nID); - lpDispInfo->lpszText = (LPTSTR)m_tsTooltip.c_str(); - } - else - m_tsTooltip = _T(""); - } - } - break; - } // switch LPNMHDR - - return 0L; - } - - inline void CDockContainer::CViewPage::PreRegisterClass(WNDCLASS &wc) - { - wc.lpszClassName = _T("Win32++ TabPage"); - wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); - } - - inline void CDockContainer::CViewPage::RecalcLayout() - { - CRect rc = GetClientRect(); - if (GetToolBar().IsWindow()) - { - GetToolBar().SendMessage(TB_AUTOSIZE, 0L, 0L); - CRect rcToolBar = m_ToolBar.GetClientRect(); - rc.top += rcToolBar.Height(); - } - - GetView()->SetWindowPos(NULL, rc, SWP_SHOWWINDOW); - } - - inline void CDockContainer::CViewPage::SetView(CWnd& wndView) - // Sets or changes the View window displayed within the frame - { - // Assign the view window - m_pView = &wndView; - - if (m_hWnd) - { - if (!m_pView->IsWindow()) - { - // The container is already created, so create and position the new view too - GetView()->Create(this); - } - - RecalcLayout(); - } - } - - inline LRESULT CDockContainer::CViewPage::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - switch (uMsg) - { - case WM_SIZE: - RecalcLayout(); - break; - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) - { - // Send the focus change notifications to the grandparent - case NM_KILLFOCUS: - case NM_SETFOCUS: - case UWM_FRAMELOSTFOCUS: - ::SendMessage(::GetParent(::GetParent(m_hWnd)), WM_NOTIFY, wParam, lParam); - break; - } - - break; - } - - // pass unhandled messages on for default processing - return CWnd::WndProcDefault(uMsg, wParam, lParam); - } - -} // namespace Win32xx - -#endif // _WIN32XX_DOCKING_H_ - -- cgit v1.2.3