// ===================================================================================
// Class Specification :
// COXFrameWndSizeDock & COXMDIFrameWndSizeDock & COXMDIChildWndSizeDock
// COXSizeViewBar & COXSizeBarWrapper & COXDockDocument
// ===================================================================================
// Header file : OXFrameWndDock.h
// Version: 9.3
// This software along with its related components, documentation and files ("The Libraries")
// is � 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office. For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
// Some portions Copyright (C)1994-5 Micro Focus Inc, 2465 East Bayshore Rd, Palo Alto, CA 94303.
// //////////////////////////////////////////////////////////////////////////
// Properties:
// NO Abstract class (does not have any objects)
// YES Derived from CFrameWnd / CMDIFrameWnd
// YES Is a Cwnd.
// YES Two stage creation (constructor & Create())
// YES Has a message map
// NO Needs a resource (template)
// NO Persistent objects (saveable on disk)
// NO Uses exceptions
// //////////////////////////////////////////////////////////////////////////
// Desciption :
//
// The 2 classes COXFrameWndSizeDock & COXMDIFrameWndSizeDock provide the frame window
// functionality necessary to support sizeable control bars. If you wish to use sizeable
// control bars, you should derive your main frame class (CMainFrame) from them
// (COXMDIFrameWndSizeDock if an MDI app, COXFrameWndSizeDock if an SDI app).
// The two classes have almost identical functions to work with control bars.
//
//
// Remark:
//
// Prerequisites (necessary conditions):
// ***
/////////////////////////////////////////////////////////////////////////////
/*
We introduce Docking Views Framework now. To accomplish this task there were added
a lot of new functions to COXMDIFrameWndSizeDock and COXMDIChildWndSizeDock classes
and built new three new classes: COXSizeViewBar, COXSizeBarWrapper and COXDockDocument.
To implement Docking Views in your MDI application generally you have to take next steps:
1) Your mainframe window have to be derived from COXMDIFrameWndSizeDock
instead of CMDIFrameWnd;
2) Your MDIChild window have to be derived from COXMDIChildWndSizeDock
instead of CMDIChildWnd;
3) Your document have to be derived from COXDockDocument instead of CDocument;
4) Make sure you call EnableDocking() in your CMainFrame::OnCreate() function;
5) In the MDIChild system menu you will find "Dock Window" item. If you choose it,
MDIChild window will set to dockable state and docked to appropriate side of
the mainframe window. To undock window: right click over caption; system menu
will be displayed; "Dock Window" item will be checked; choose it.
By default MDIChild window will be created with CBRS_ALIGN_ANY style that means it could
be docked to any side of mainframe window. If you want to set your own docking style
you have to derive from COXMDIChildWndSizeDock your own CChildWnd class and set in
constructor m_dwDockStyle variable to the style you need.
At the moment we are not providing any functionality to change the docking style at
run-time and currently we are not supporting COLEDocument derivation. Also Docking Views
state cannot be saved/loaded to/from registry at this stage. If MDIChild window
has any child windows other than CView they won't be displayed in Dockable state.
All three new classes are created as internal classes to provide docking functionality
and will be probably changed in the future. COXMDIChildWndSizeDock uses COXSizeViewBar
as helper class to dock views. And COXSizeViewBar uses COXSizeBarWrapper and
COXSizableMiniDockFrameWnd to display views while docked or floating correspondingly.
Also there were added lots of functions to documented COXMDIFrameWndSizeDock and
COXMDIChildWndSizeDock classes. Although some of them are public they are not supposed
to be used explicitly in your applications and only provided here as internal functions
to be called by different classes in Docking Framework.
Below you will find some useful properties and methods that you can use in your
derivation of above described classes to control Docking Framework.
COXMDIFrameWndSizeDock:
BOOL IsDockable(CWnd* pWnd);
// --- In : pWnd - pointer to a child window
// --- Out :
// --- Returns: TRUE if pWnd is currently in Dockable state (Dockable MDIChild),
// or FALSE otherwise
// --- Effect :
COXMDIChildWndSizeDock:
// message ID that is sent to window when user want to toggle
// MDIChild window state (dockable/undockable)
static UINT m_nDockMessageID;
// string resource used as text of menu item to toggle the MDIChild window state
CString m_sDockMenuItem;
// docking style, could be:
//
// CBRS_ALIGN_TOP Allows docking at the top of the client area.
// CBRS_ALIGN_BOTTOM Allows docking at the bottom of the client area.
// CBRS_ALIGN_LEFT Allows docking on the left side of the client area.
// CBRS_ALIGN_RIGHT Allows docking on the right side of the client area.
// CBRS_ALIGN_ANY Allows docking on any side of the client area.
// CBRS_FLOAT_MULTI Allows multiple control bars to be floated in a
// single mini-frame window.
// 0 (that is, indicating no flags), the control bar will not dock.
//
// By default CBRS_ALIGN_ANY is set
DWORD m_dwDockStyle;
BOOL MakeItDockable(BOOL bDockable);
// --- In : bDockable - TRUE if MDIChild window is to be docked,
// FALSE if MDIChild window is to be undocked
// --- Out :
// --- Returns: TRUE if succeeds, FALSE otherwise
// --- Effect : Dock/Undock MDIChild window
inline BOOL IsDockable() { return m_bDockable; }
// --- Returns: TRUE if MDIChild window is in Dockable state,
// or FALSE otherwise
BOOL IsDockableFrame();
// --- Returns: TRUE if MDIFrame window is derived from COXMDIFrameWndSizeDock,
// or FALSE otherwise
CMDIChildWnd* MDIGetActive(BOOL* pbMaximized=NULL);
// --- In : pbMaximized - A pointer to a BOOL return value. Set to TRUE on
// return if the window is maximized; otherwise FALSE
// --- Returns: active MDIChild window (takes into account Dockable MDIChild window)
*/
#ifndef __FRAMESIZEDOCK_H__
#define __FRAMESIZEDOCK_H__
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "OXDllExt.h"
#include <afxole.h>
#include "OXSizeCtrlBar.h" // used class specification
#include "OXSzMiniDockFrmWnd.h"
#include "OXMainRes.h"
// Window arangement positions
#define CBRS_ARRANGE_TOPLEFT 1
#define CBRS_ARRANGE_TOPRIGHT 2
#define CBRS_ARRANGE_BOTTOMLEFT 4
#define CBRS_ARRANGE_BOTTOMRIGHT 8
#define CBRS_ARRANGE_LEFT ( CBRS_ARRANGE_TOPLEFT | CBRS_ARRANGE_BOTTOMLEFT )
#define CBRS_ARRANGE_TOP ( CBRS_ARRANGE_TOPRIGHT | CBRS_ARRANGE_TOPLEFT )
// special constants to define the source of activation of the view
#define ID_SOURCE_MDICHILD 0x00000001
#define ID_SOURCE_BARWRAPPER 0x00000002
#define ID_SOURCE_MINIDOCK 0x00000003
class OX_CLASS_DECL COXMDIChildWndSizeDock;
class OX_CLASS_DECL COXSizeViewBar;
class OX_CLASS_DECL COXMDIFrameWndSizeDock;
void ArrangeWindowsInWindow(CWnd* pParentWnd, CObArray& arrWnd, DWORD dwOrient);
void ForceLayoutAdjust(CControlBar* pBar);
class OX_CLASS_DECL COXFrameWndSizeDock : public CFrameWnd
{
DECLARE_DYNCREATE(COXFrameWndSizeDock)
// Data members -------------------------------------------------------------
public:
protected:
// Specifies whether the snaping and tear-off behaviour of toolbars,
// menubars and docking windows is enabled
BOOL m_bEnableSnapping;
private :
// Member functions ---------------------------------------------------------
public:
void SetDockState(const CDockState& state);
void GetDockState(CDockState& state) const;
// --- In : dwDockStyle : specifies which sides of the frame window control bars can be docked
// to. It can be a combination of CBRS_ALIGN_TOP, CBRS_ALIGN_BOTTOM,
// CBRS_ALIGN_LEFT, CBRS_ALIGN_RIGHT or CBRS_ALIGN_ANY.
// Note that CBRS_FLOAT_MULTI is not supported.
// --- Out :
// --- Returns :
// --- Effect : This function is equivalent to CFrameWnd:EnableDocking(), but should be called
// if your frame window is to support sizeable docking.
// NB: CFrameWnd::EnableDocking() is NOT virtual, so you must ensure you do not
// inadvertently call it for a COXFrameWndSizeDock or COXMDIFrameWndSizeDock
// object.
void EnableDocking(DWORD dwDockStyle);
// --- In : dwDockStyle : specifies which sides of the frame window, the control bars
// should be tiled for. It can be a combination of CBRS_ALIGN_TOP,
// CBRS_ALIGN_BOTTOM, CBRS_ALIGN_LEFT, CBRS_ALIGN_RIGHT or CBRS_ALIGN_ANY.
// --- Out :
// --- Returns :
// --- Effect : Tiles the sizeable control bars within a frame so they take up
// equal size. You should call RecalcLayout() after calling this function.
void TileDockedBars(DWORD dwDockStyle = CBRS_ALIGN_ANY);
// --- In : dwOrient specifies the orientation of the arrangement.
// It can be one of:
// CBRS_ARRANGE_TOPLEFT
// CBRS_ARRANGE_TOPRIGHT
// CBRS_ARRANGE_BOTTOMLEFT
// CBRS_ARRANGE_BOTTOMRIGHT
// --- Out :
// --- Returns :
// --- Effect : Arranges the floating control bars within a frame.
void ArrangeFloatingBars(DWORD dwOrient);
// --- In : arrWnd : array with window pointers
// dwOrient specifies the orientation of the arrangement.
// It can be one of:
// CBRS_ARRANGE_TOPLEFT
// CBRS_ARRANGE_TOPRIGHT
// CBRS_ARRANGE_BOTTOMLEFT
// CBRS_ARRANGE_BOTTOMRIGHT
// --- Out :
// --- Returns :
// --- Effect : Arranges the windows pointed at in arrWnd, within a frame.
void ArrangeWindows(CObArray& arrWnd, DWORD dwOrient);
// --- In :
// --- Out : arrWnd : arrary with all floating controlbars at that moment
// --- Returns :
// --- Effect : gets all floating controlbars
void GetFloatingBars(CObArray& arrWnd);
// --- In : pszProfileName : specifies the key to use within the registry/ini.
// --- Out :
// --- Returns :
// --- Effect : Loads the saved state of the bars from the Registry/ini, including sizes.
// This function calls CFrameWnd::LoadBarState() to do most of it�s work.
void LoadSizeBarState(LPCTSTR pszProfileName);
// --- In : pszProfileName : specifies the key to use within the registry/ini.
// --- Out :
// --- Returns :
// --- Effect : Saves the state of the bars to the Registry/ini, including sizes.
// This function calls CFrameWnd::SaveBarState() to do most of it�s work.
// Notes:
// 1. This function destroys any windows constructed with the SZBARF_AUTOTIDY
// flag. CControlBars created with this flag will not generally be around
// next time in.
// 2. Positions and sizes are saved in a binary format, based on the ID of the
// control bars. You should ensure all your CControlBars have unique ID�s.
void SaveSizeBarState(LPCTSTR pszProfileName);
// --- In :
// --- Out :
// --- Returns :
// --- Effect : destroys all controlbars managed by this frame window
void DestroyDynamicBars();
// --- In :
// --- Out :
// --- Returns :
// --- Effect : floats controlbar managed by this frame window
void FloatControlBar(CControlBar* pBar, CPoint point, DWORD dwStyle = CBRS_ALIGN_TOP);
// --- In : bEnable - Specifies whether then snapping behaviour
// should be turned on or off
// --- Out :
// --- Returns:
// --- Effect : Call this function to turn on the snaping and tear-off behaviour
// of toolbars, menubars and docking windows
void EnableSnapping(BOOL bEnable = TRUE) { m_bEnableSnapping = bEnable; };
void ShowControlBar(CControlBar* pBar, BOOL bShow, BOOL bDelay);
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif // _DEBUG
COXFrameWndSizeDock();
// --- In :
// --- Out :
// --- Returns :
// --- Effect : Destructor of object
virtual ~COXFrameWndSizeDock();
protected:
// Generated message map functions
//{{AFX_MSG(COXFrameWndSizeDock)
afx_msg void OnDestroy();
//}}AFX_MSG
LRESULT OnQuerySnapping(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
void SaveBarSizes(LPCTSTR pszSection, BOOL bSave);
friend COXMDIFrameWndSizeDock;
};
// COXMDIFrameWndSizeDock provides Docking Views functionality
class OX_CLASS_DECL COXMDIFrameWndSizeDock : public CMDIFrameWnd
{
DECLARE_DYNCREATE(COXMDIFrameWndSizeDock)
// Data members -------------------------------------------------------------
public:
// var to save the last active docking control bar window
COXSizeControlBar* m_pLastActiveCtrlBar;
protected:
// inner var to save the active Docking MDIChild window
COXMDIChildWndSizeDock* m_pActiveDockChild;
// inner var that is set to TRUE when destroying of the window is in process
BOOL m_bBeingDestroyed;
// Specifies whether the snaping and tear-off behaviour of toolbars,
// menubars and docking windows is enabled
BOOL m_bEnableSnapping;
private :
// Member functions ---------------------------------------------------------
public:
// --- In : (See COXFrameWndSizeDock above)
// --- Out : (See COXFrameWndSizeDock above)
// --- Returns : (See COXFrameWndSizeDock above)
// --- Effect : (See COXFrameWndSizeDock above)
void EnableDocking(DWORD dwDockStyle)
{ ((COXFrameWndSizeDock*)this)->EnableDocking(dwDockStyle); };
// --- In : (See COXFrameWndSizeDock above)
// --- Out : (See COXFrameWndSizeDock above)
// --- Returns : (See COXFrameWndSizeDock above)
// --- Effect : (See COXFrameWndSizeDock above)
void TileDockedBars(DWORD dwDockStyle = CBRS_ALIGN_ANY)
{ ((COXFrameWndSizeDock*)this)->TileDockedBars(dwDockStyle); };
// --- In : (See COXFrameWndSizeDock above)
// --- Out : (See COXFrameWndSizeDock above)
// --- Returns : (See COXFrameWndSizeDock above)
// --- Effect : (See COXFrameWndSizeDock above)
void ArrangeFloatingBars(DWORD dwOrient);
// --- In : (See COXFrameWndSizeDock above)
// --- Out : (See COXFrameWndSizeDock above)
// --- Returns : (See COXFrameWndSizeDock above)
// --- Effect : (See COXFrameWndSizeDock above)
void ArrangeWindows(CObArray& arrWnd, DWORD dwOrient);
// --- In : (See COXFrameWndSizeDock above)
// --- Out : (See COXFrameWndSizeDock above)
// --- Returns : (See COXFrameWndSizeDock above)
// --- Effect : (See COXFrameWndSizeDock above)
void GetFloatingBars(CObArray & arrWnd)
{ ((COXFrameWndSizeDock*)this)->GetFloatingBars(arrWnd); };
// --- In : (See COXFrameWndSizeDock above)
// --- Out : (See COXFrameWndSizeDock above)
// --- Returns : (See COXFrameWndSizeDock above)
// --- Effect : (See COXFrameWndSizeDock above)
void LoadSizeBarState(LPCTSTR pszProfileName)
{ ((COXFrameWndSizeDock*)this)->LoadSizeBarState(pszProfileName); };
// --- In : pBar : Points to the control bar to be floated in an MDI child frame.
// point : Position in screen co-ordinates of the top-left corner of the control bar
// dwStyle : Orientation of the control bar within the parent window.
// Provided for consistency.
// bVisible:
// --- Out :
// --- Returns :
// --- Effect : This function floats the specified control bar as an MDI Child window
// (as opposed to a mini-frame window) in the MDI client area (similar to
// the docking and non-docking views in the MS Visual C++ IDE).
void FloatControlBarInMDIChild(CControlBar* pBar, CPoint point,
DWORD dwStyle = CBRS_ALIGN_TOP, BOOL bVisible = TRUE);
// --- In : pBar : Points to the control bar to be floated in a mini frame.
// point : Position in screen co-ordinates of the top-left corner of the control bar
// dwStyle : Orientation of the control bar within the parent window.
// Provided for consistency.
// --- Out :
// --- Returns :
// --- Effect : This function floats the specified control bar as a mini frame window
void UnFloatInMDIChild(CControlBar* pBar, CPoint point,
DWORD dwStyle = CBRS_ALIGN_TOP);
// --- In : (See COXFrameWndSizeDock above)
// --- Out : (See COXFrameWndSizeDock above)
// --- Returns : (See COXFrameWndSizeDock above)
// --- Effect : (See COXFrameWndSizeDock above)
// --- Effect : Activate and deactivate child windows in a special way (takes into
// account Docking MDIChild windows)
void HookActivation();
// --- In : pWnd - pointer to a child window
// --- Out :
// --- Returns: TRUE if pWnd is currently in Dockable state (Dockable MDIChild),
// or FALSE otherwise
// --- Effect :
BOOL IsDockable(CWnd* pWnd);
// --- Returns: TRUE if currently active undocked MDIChild window is maximized,
// or FALSE otherwise
BOOL IsFrontChildMaximized();
// --- Returns: TRUE if destroying of the window is in process,
// or FALSE otherwise
inline BOOL IsBeingDestroyed() { return m_bBeingDestroyed; }
// --- In : pWnd - pointer to a child window
// --- Out :
// --- Returns:
// --- Effect : sets pWnd as active Dockable MDIChild window
void SetActiveChild(CWnd* pWnd);
// --- In : bEnable - Specifies whether then snapping behaviour
// should be turned on or off
// --- Out :
// --- Returns:
// --- Effect : Call this function to turn on the snaping and tear-off behaviour
// of toolbars, menubars and docking windows
void EnableSnapping(BOOL bEnable = TRUE) { m_bEnableSnapping = bEnable; };
// --- Returns: active Dockable MDIChild window
COXMDIChildWndSizeDock* GetActiveChild();
// Operations
void MDIActivate(CWnd* pWndActivate);
CMDIChildWnd* MDIGetActive(BOOL* pbMaximized=NULL) const;
void MDIMaximize(CWnd* pWnd);
void MDIRestore(CWnd* pWnd);
BOOL IsChild(const CWnd* pWnd);
BOOL OnBarCheck(UINT nID);
// --- In : pszProfileName : specifies the key to use within the registry/ini.
// --- Out :
// --- Returns :
// --- Effect : Saves the state of the bars to the Registry/ini, including sizes.
// This function calls CFrameWnd::SaveBarState() to do most of it�s work.
// Notes:
// 1. This function destroys any windows constructed with the SZBARF_AUTOTIDY
// flag. CControlBars created with this flag will not generally be around
// next time in.
// 2. Positions and sizes are saved in a binary format, based on the ID of the
// control bars. You should ensure all your CControlBars have unique ID�s.
void SaveSizeBarState(LPCTSTR pszProfileName);
void SaveBarState(LPCTSTR lpszProfileName) const;
void GetDockState(CDockState& state) const;
// Implementation
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COXMDIFrameWndSizeDock)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void OnUpdateFrameTitle(BOOL bAddToTitle);
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
virtual void OnUpdateFrameMenu(HMENU hMenuAlt);
virtual CFrameWnd* GetActiveFrame();
virtual BOOL DestroyWindow();
protected:
virtual LRESULT DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
public:
COXMDIFrameWndSizeDock(); // protected constructor used by dynamic creation
virtual ~COXMDIFrameWndSizeDock();
void FloatControlBar(CControlBar* pBar, CPoint point, DWORD dwStyle);
protected:
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
// helper function to undock all child windows before destroy them
void UndockAllViews();
// Generated message map functions
//{{AFX_MSG(COXMDIFrameWndSizeDock)
afx_msg void OnDestroy();
afx_msg LRESULT OnCommandHelp(WPARAM wParam, LPARAM lParam);
afx_msg void OnClose();
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
//}}AFX_MSG
afx_msg void OnWindowNew();
afx_msg void OnUpdateMDIWindowCmd(CCmdUI* pCmdUI);
LRESULT OnQuerySnapping(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
private:
};
////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Class COXBaseDockDocument is the main document data abstraction
// It overwrites virtual PARENTDOC functions to support Docking Views functionality
// Can be used in order to support docking functionality for different kind of
// documents
template<class PARENTDOC>
class COXBaseDockDocument : public PARENTDOC
{
protected:
// Data
// inner var that is set to TRUE when destroying of the document is in process
BOOL m_bBeingDestroyed;
public:
// Constructor
COXBaseDockDocument();
// Attributes
public:
// Operations
inline BOOL IsBeingDestroyed() { return m_bBeingDestroyed; }
// --- Returns: TRUE if destroying of the document is in process,
// or FALSE otherwise
// Overridables
virtual void OnCloseDocument();
// advanced overridables, closing down frame/doc, etc.
virtual BOOL CanCloseFrame(CFrameWnd* pFrame);
// Implementation
protected:
virtual ~COXBaseDockDocument();
// implementation helpers
virtual void UpdateFrameCounts();
CFrameWnd* GetParentFrame(CView* pView) const;
// helper function to undock all document views before destroy it
void UndockAllViews();
public:
// --- In : nID - Contains the command ID
// nCode - Identifies the command notification code
// pExtra - Used according to the value of nCode
// pHandlerInfo - If not NULL, OnCmdMsg fills in the pTarget
// and pmf members of the pHandlerInfo structure
// instead of dispatching the command. Typically,
// this parameter should be NULL
// --- Out :
// --- Returns: Nonzero if the message is handled; otherwise 0.
// --- Effect : Called by the framework to route and dispatch command messages
// and to handle the update of command user-interface objects
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);
};
template<class PARENTDOC>
COXBaseDockDocument<PARENTDOC>::COXBaseDockDocument() : m_bBeingDestroyed(FALSE) {}
template<class PARENTDOC>
COXBaseDockDocument<PARENTDOC>::~COXBaseDockDocument() {}
template<class PARENTDOC>
BOOL COXBaseDockDocument<PARENTDOC>::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
if(nCode==CN_COMMAND && nID==ID_FILE_CLOSE && pHandlerInfo==NULL)
{
CWnd* pMainWnd=AfxGetMainWnd();
if(pMainWnd->IsKindOf(RUNTIME_CLASS(COXMDIFrameWndSizeDock)))
{
if(SaveModified())
{
SetModifiedFlag(FALSE);
}
OnCloseDocument();
return TRUE;
}
}
return PARENTDOC::OnCmdMsg(nID,nCode,pExtra,pHandlerInfo);
}
template<class PARENTDOC>
BOOL COXBaseDockDocument<PARENTDOC>::CanCloseFrame(CFrameWnd* pFrameArg)
// permission to close all views using this frame
// (at least one of our views must be in this frame)
{
ASSERT_VALID(pFrameArg);
UNREFERENCED_PARAMETER(pFrameArg); // unused in release builds
POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = GetNextView(pos);
ASSERT_VALID(pView);
CFrameWnd* pFrame = GetParentFrame(pView);
// assume frameless views are ok to close
if (pFrame != NULL)
{
// assumes 1 document per frame
ASSERT_VALID(pFrame);
if (pFrame->m_nWindow > 0)
return TRUE; // more than one frame refering to us
}
}
// otherwise only one frame that we know about
if(SaveModified())
{
SetModifiedFlag(FALSE);
return TRUE;
}
else
{
return FALSE;
}
}
template<class PARENTDOC>
void COXBaseDockDocument<PARENTDOC>::OnCloseDocument()
// must close all views now (no prompting) - usually destroys this
{
if(m_bBeingDestroyed)
{
return;
}
m_bBeingDestroyed=TRUE;
CWnd* pMainWnd=AfxGetMainWnd();
BOOL bDockableFramework=pMainWnd->
IsKindOf(RUNTIME_CLASS(COXMDIFrameWndSizeDock)) ? TRUE : FALSE;
if(bDockableFramework)
{
// destroy all frames viewing this document
// the last destroy may destroy us
BOOL bAutoDelete = m_bAutoDelete;
m_bAutoDelete = FALSE; // don't destroy document while closing views
UndockAllViews();
while(!m_viewList.IsEmpty())
{
// get frame attached to the view
CView* pView = (CView*)m_viewList.GetHead();
ASSERT_VALID(pView);
CFrameWnd* pFrame = GetParentFrame(pView);
ASSERT_VALID(pFrame);
// and close it
PreCloseFrame(pFrame);
if(::IsWindow(pFrame->m_hWnd))
{
if(pFrame->IsKindOf(RUNTIME_CLASS(COXMDIChildWndSizeDock)))
{
COXMDIChildWndSizeDock* pMDIChild=(COXMDIChildWndSizeDock*)pFrame;
pMDIChild->DestroyWindow();
}
else
{
pFrame->DestroyWindow();
}
}
}
m_bAutoDelete = bAutoDelete;
// clean up contents of document before destroying the document itself
DeleteContents();
// delete the document if necessary
if (m_bAutoDelete)
delete this;
((COXMDIFrameWndSizeDock*)pMainWnd)->RecalcLayout();
}
else
{
PARENTDOC::OnCloseDocument();
}
}
template<class PARENTDOC>
void COXBaseDockDocument<PARENTDOC>::UpdateFrameCounts()
// assumes 1 doc per frame
{
// walk all frames of views (mark and sweep approach)
POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = GetNextView(pos);
ASSERT_VALID(pView);
ASSERT(::IsWindow(pView->m_hWnd));
if (pView->IsWindowVisible()) // Do not count invisible windows.
{
CFrameWnd* pFrame = GetParentFrame(pView);
if (pFrame != NULL)
pFrame->m_nWindow = -1; // unknown
}
}
// now do it again counting the unique ones
int nFrames = 0;
pos = GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = GetNextView(pos);
ASSERT_VALID(pView);
ASSERT(::IsWindow(pView->m_hWnd));
if (pView->IsWindowVisible()) // Do not count invisible windows.
{
CFrameWnd* pFrame = GetParentFrame(pView);
if (pFrame != NULL && pFrame->m_nWindow == -1)
{
ASSERT_VALID(pFrame);
// not yet counted (give it a 1 based number)
pFrame->m_nWindow = ++nFrames;
}
}
}
// lastly walk the frames and update titles (assume same order)
// go through frames updating the appropriate one
int iFrame = 1;
pos = GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = GetNextView(pos);
ASSERT_VALID(pView);
ASSERT(::IsWindow(pView->m_hWnd));
if (pView->IsWindowVisible()) // Do not count invisible windows.
{
CFrameWnd* pFrame = GetParentFrame(pView);
if (pFrame != NULL && pFrame->m_nWindow == iFrame)
{
ASSERT_VALID(pFrame);
if (nFrames == 1)
pFrame->m_nWindow = 0; // the only one of its kind
pFrame->OnUpdateFrameTitle(TRUE);
iFrame++;
}
}
}
ASSERT(iFrame == nFrames + 1);
}
template<class PARENTDOC>
CFrameWnd* COXBaseDockDocument<PARENTDOC>::GetParentFrame(CView* pView) const
{
if (pView->GetSafeHwnd() == NULL) // no Window attached
{
return NULL;
}
ASSERT_VALID(pView);
CWnd* pParentWnd = pView->GetParent(); // start with one parent up
while (pParentWnd != NULL)
{
if (pParentWnd->IsFrameWnd())
{
return (CFrameWnd*)pParentWnd;
}
else if (pParentWnd->IsKindOf(RUNTIME_CLASS(COXSizeViewBar)))
{
if(::IsWindow(((COXSizeViewBar*)pParentWnd)->m_pChildWnd->m_hWnd))
{
return (CFrameWnd*)((COXSizeViewBar*)pParentWnd)->m_pChildWnd;
}
else
{
return NULL;
}
}
pParentWnd = pParentWnd->GetParent();
}
return NULL;
}
template<class PARENTDOC>
void COXBaseDockDocument<PARENTDOC>::UndockAllViews()
{
POSITION pos=m_viewList.GetHeadPosition();
while(pos!=NULL)
{
// get frame attached to the view
CView* pView = (CView*)m_viewList.GetNext(pos);
ASSERT_VALID(pView);
CFrameWnd* pFrame = GetParentFrame(pView);
ASSERT_VALID(pFrame);
if(::IsWindow(pFrame->m_hWnd) &&
pFrame->IsKindOf(RUNTIME_CLASS(COXMDIChildWndSizeDock)))
{
COXMDIChildWndSizeDock* pMDIChild=(COXMDIChildWndSizeDock*)pFrame;
if(pMDIChild->IsDockable())
{
if(::IsWindow(pMDIChild->m_dockBar.m_hWnd))
{
pMDIChild->m_dockBar.DetachMDIChild(FALSE);
}
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Class COXDockDocument is the main document data abstraction
// It overwrites virtual CDocument functions to support Docking Views functionality
class OX_CLASS_DECL COXDockDocument : public COXBaseDockDocument<CDocument>
{
DECLARE_DYNAMIC(COXDockDocument)
protected:
//{{AFX_MSG(CDocument)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// COXSizeBarWrapper window
// This class wraps a view while MDIChild
class OX_CLASS_DECL COXSizeBarWrapper : public CWnd
{
// Construction
public:
COXSizeBarWrapper();
// Data
protected:
COXSizeViewBar* m_pParentWnd;
CView* m_pView;
BOOL m_bBeingDestroyed;
// Operations
public:
BOOL Create(COXSizeViewBar* pParentWnd);
void WrapView(COXSizeViewBar* pParentWnd, CView* pView);
void UnwrapView();
inline BOOL IsBeingDestroyed() { return m_bBeingDestroyed; }
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COXSizeBarWrapper)
public:
//}}AFX_VIRTUAL
public:
virtual ~COXSizeBarWrapper();
// implementation
protected:
// Generated message map functions
protected:
//{{AFX_MSG(COXSizeBarWrapper)
#if _MSC_VER >= 1400
afx_msg LRESULT OnNcHitTest(CPoint point);
#else
afx_msg UINT OnNcHitTest(CPoint point);
#endif
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
afx_msg void OnDestroy();
afx_msg void OnNcDestroy();
afx_msg void OnClose();
afx_msg BOOL OnNcActivate(BOOL bActive);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// This class provides docking functionality for MDIChild windows.
// Operates like "Control Center" between MDIChild window and its represantation
// while it is dockable
class OX_CLASS_DECL COXSizeViewBar : public COXSizeControlBar
{
DECLARE_DYNCREATE(COXSizeViewBar)
// Data members -------------------------------------------------------------
public:
COXMDIChildWndSizeDock* m_pChildWnd;
CView* m_pView;
COXSizeBarWrapper m_WrapperWnd;
BOOL m_bMaximized;
BOOL m_bBeingDestroyed;
private :
// Member functions ---------------------------------------------------------
public:
COXSizeViewBar(int nStyle=
SZBARF_STDMOUSECLICKS/*|SZBARF_NOCLOSEBTN|SZBARF_NOCAPTION*/|SZBARF_SOLIDGRIPPER);
// --- In : nStyle : See COXSizeControlBar::COXSizeViewBar for details
// --- Out :
// --- Returns :
// --- Effect : Constructor of object
// It will initialize the internal state
virtual void OnSizedOrDocked(int cx, int cy, BOOL bFloating, int flags);
// --- In :
// --- Out :
// --- Returns :
// --- Effect : See COXSizeControlBar::OnSizedOrDocked for details
virtual ~COXSizeViewBar();
// --- In :
// --- Out :
// --- Returns :
// --- Effect : Destructor of object
BOOL AttachMDIChild(COXMDIChildWndSizeDock* pWnd, DWORD dock = CBRS_ALIGN_TOP, bool dockToSide = false);
BOOL DetachMDIChild(BOOL bRedraw=TRUE);
BOOL QueryCloseView();
inline BOOL IsBeingDestroyed() { return m_bBeingDestroyed; }
// v93 - update 03 - 64-bit using OXINTRET instead of int here
virtual OXINTRET OnToolHitTest(CPoint point, TOOLINFO* pTI) const {
UNREFERENCED_PARAMETER(pTI);
UNREFERENCED_PARAMETER(point);
return -1;
}
virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler);
protected:
//{{AFX_MSG(COXSizeViewBar)
afx_msg BOOL OnNcActivate(BOOL bActive);
afx_msg void OnDestroy();
afx_msg void OnNcDestroy();
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
//}}AFX_MSG
// v9.3 - update 03 - 64-bit - fixed types in fn decls (now LRESULT, WPARAM, LPARAM
afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnAddContextMenuItems(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnActivateViewBar(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
friend COXMDIFrameWndSizeDock;
friend COXDockDocument;
friend COXSizableMiniDockFrameWnd;
friend COXSizeBarWrapper;
private:
};
// COXMDIChildWndSizeDock supports docking functionality using
// COXSizeViewBar and have to be used together with COXFrameWndSizeDock
class OX_CLASS_DECL COXMDIChildWndSizeDock : public CMDIChildWnd
{
DECLARE_DYNCREATE(COXMDIChildWndSizeDock)
// Data members -------------------------------------------------------------
public:
// message ID that is sent to window when user want to toggle
// MDIChild window state (dockable/undockable)
static UINT m_nDockMessageID;
COXSizeViewBar m_dockBar;
BOOL m_bDockable;
// string resource used as text of menu item to toggle the MDIChild window state
CString m_sDockMenuItem;
// docking style, could be:
//
// CBRS_ALIGN_TOP Allows docking at the top of the client area.
// CBRS_ALIGN_BOTTOM Allows docking at the bottom of the client area.
// CBRS_ALIGN_LEFT Allows docking on the left side of the client area.
// CBRS_ALIGN_RIGHT Allows docking on the right side of the client area.
// CBRS_ALIGN_ANY Allows docking on any side of the client area.
// CBRS_FLOAT_MULTI Allows multiple control bars to be floated in a
// single mini-frame window.
// 0 (that is, indicating no flags), the control bar will not dock.
//
// By default CBRS_ALIGN_ANY is set
DWORD m_dwDockStyle;
// inner var that is set to TRUE when destroying of the window is in process
BOOL m_bBeingDestroyed;
private :
// Member functions ---------------------------------------------------------
public:
virtual BOOL Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
const RECT& rect = rectDefault,
CMDIFrameWnd* pParentWnd = NULL,
CCreateContext* pContext = NULL);
void EnableDocking(DWORD dwDockStyle)
{ ((COXFrameWndSizeDock*)this)->EnableDocking(dwDockStyle); };
void TileDockedBars(DWORD dwDockStyle = CBRS_ALIGN_ANY)
{ ((COXFrameWndSizeDock*)this)->TileDockedBars(dwDockStyle); };
void GetFloatingBars(CObArray & arrWnd)
{ ((COXFrameWndSizeDock*)this)->GetFloatingBars(arrWnd); };
void DestroyDynamicBars()
{ ((COXFrameWndSizeDock*)this)->DestroyDynamicBars(); };
void LoadSizeBarState(LPCTSTR pszProfileName)
{ ((COXFrameWndSizeDock*)this)->LoadSizeBarState(pszProfileName); };
void SaveSizeBarState(LPCTSTR pszProfileName)
{ ((COXFrameWndSizeDock*)this)->SaveSizeBarState(pszProfileName); };
//////////////////////////////////////
BOOL MakeItDockable(BOOL bDockable, DWORD style = CBRS_ALIGN_TOP, bool dockToSide = false);
// --- In : bDockable - TRUE if MDIChild window is to be docked,
// FALSE if MDIChild window is to be undocked
// --- Out :
// --- Returns: TRUE if succeeds, FALSE otherwise
// --- Effect : Dock/Undock MDIChild window
inline BOOL IsDockable() { return m_bDockable; }
// --- Returns: TRUE if MDIChild window is in Dockable state,
// or FALSE otherwise
BOOL IsDockableFrame();
// --- Returns: TRUE if MDIFrame window is derived from COXMDIFrameWndSizeDock,
// or FALSE otherwise
CMDIChildWnd* MDIGetActive(BOOL* pbMaximized=NULL);
// --- In : pbMaximized - A pointer to a BOOL return value. Set to TRUE on
// return if the window is maximized; otherwise FALSE
// --- Returns: active MDIChild window (takes into account Dockable MDIChild window)
inline BOOL IsBeingDestroyed() { return m_bBeingDestroyed; }
// --- Returns: TRUE if destroying of the document is in process,
// or FALSE otherwise
//////////////////////////////////////
// Operations
void MDIDestroy();
void MDIActivate();
void MDIMaximize();
void MDIRestore();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COXMDIChildWndSizeDock)
public:
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
virtual void ActivateFrame(int nCmdShow = -1);
virtual void OnUpdateFrameTitle(BOOL bAddToTitle);
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual BOOL DestroyWindow();
//}}AFX_VIRTUAL
protected:
COXMDIChildWndSizeDock(); // protected constructor used by dynamic creation
virtual ~COXMDIChildWndSizeDock();
BOOL UpdateClientEdge(LPRECT lpRect = NULL);
virtual void OnAddContextMenuItems(HMENU hMenu);
virtual void OnAddSystemMenuItems(CMenu* pSysMenu);
// Generated message map functions
//{{AFX_MSG(COXMDIChildWndSizeDock)
afx_msg void OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd);
afx_msg BOOL OnNcActivate(BOOL bActive);
afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
afx_msg void OnClose();
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg void OnParentNotify(UINT message, LPARAM lParam);
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnNcRButtonDown(UINT nHitTest, CPoint point);
//}}AFX_MSG
afx_msg void OnStyleChanging(int nStyleType, LPSTYLESTRUCT lpStyleStruct);
// v9.3 - update 03 - 64-bit - changed these to LRESULT, WPARAM, LPARAM from LPARAM, UINT, LONG
afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
afx_msg void OnMakeItDockable();
DECLARE_MESSAGE_MAP()
friend COXSizeViewBar;
friend COXMDIFrameWndSizeDock;
friend COXDockDocument;
friend COXSizableMiniDockFrameWnd;
private:
};
#endif // __FRAMESIZEDOCK_H__