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

UCC git Repository :: git.ucc.asn.au