📄 dockingframework.h
字号:
#pragma once
/////////////////////////////////////////////////////////////////////////////
// MFC Wrapper for an existing WTL Docking framework
// Written by Quynh Nguyen Huu
//
// Original WTL source code:
// - http://www.codeproject.com/wtl/TabbingFramework.asp
// - http://www.codeproject.com/wtl/wtldockingwindows.asp
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
/////////////////////////////////////////////////////////////////////////////
// Configurable parameters which should be set before include this file
// 1) DF_DEFAULT_CAPTION_CLASS
// Specify which kind of caption will be used before include this file
// - CVC6LikeCaption
// - COutlookLikeCaption
// - COutlookLikeExCaption (the default)
// - CVC7LikeCaption
// - CVC7LikeExCaption
#ifndef DF_DEFAULT_CAPTION_CLASS
# define DF_DEFAULT_CAPTION_CLASS COutlookLikeExCaption
#endif
// 2) DF_FOCUS_FEATURES
// #define DF_FOCUS_FEATURES
// before include this file will enable 'highlight' caption.
// Should only be used in case of 'CVC7LikeCaption' or 'CVC7LikeExCaption'.
// Otherwise the User Interface will not very nice.
/////////////////////////////////////////////////////////////////////////////
// Implementation
#include <afxwin.h>
#include <afxcmn.h>
#include <afxdisp.h>
#include "WTL4MFC.h"
// This file is already in WTL namespace
#include "TabControls\atlgdix.h"
namespace WTL {
// http://www.codeproject.com/wtl/tabbingframework.asp
#include "TabControls\TabbedFrame.h"
#include "TabControls\CustomTabCtrl.h"
#include "TabControls\DotNetTabCtrl.h"
#include "TabControls\SimpleTabCtrls.h"
#ifdef DF_FOCUS_FEATURES
# include "Docking\DockingFocus.h"
#else
# define __WTL_DW__DOCKINGFOCUS_H__
#endif
// http://www.codeproject.com/wtl/wtldockingwindows.asp
//#pragma message("to add/remove auto-hiding features just add/remove #include <DWAutoHide.h>")
#include "Docking\DWAutoHide.h"
#include "Docking\DockMisc.h"
#include "Docking\DockingFrame.h"
#include "Docking\TabDockingBox.h"
#include "Docking\VC7LikeCaption.h"
#include "Docking\stgreg.h"
#include "Docking\dbstate.h"
// http://www.codeproject.com/wtl/igorsplitpane.asp
#include "SplitPane\docktabsplitpane.h"
}
// Forward reference
class CDockingControlBar;
_BEGIN_WTL4MFC_NAMESPACE
//////////////////////////////////////////////////////////////////////////
// Simple implementation for WTL frame which forwards messages to MFC
class CSimpleFrameImpl : public ATL::CWindow, public ATL::CMessageMap
{
DECLARE_EMPTY_MSG_MAP()
public:
HWND m_hWndClient;
CFrameWnd* m_pMFCWndPeer;
CSimpleFrameImpl()
: m_hWndClient(NULL)
, m_pMFCWndPeer(NULL)
{}
LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ASSERT_KINDOF(CFrameWnd, m_pMFCWndPeer);
class CFriendWnd : public CFrameWnd
{
friend CSimpleFrameImpl;
};
return static_cast<CFriendWnd*>(m_pMFCWndPeer)->DefWindowProc(uMsg, wParam, lParam);
}
void UpdateBarsPosition(RECT& rect, BOOL bResizeBars)
{
ASSERT_KINDOF(CFrameWnd, m_pMFCWndPeer);
RECT rectClient = rect;
if(bResizeBars)
{
m_pMFCWndPeer->RepositionBars(0, 0xffff, 0, CWnd::reposDefault, NULL, &rectClient);
}
m_pMFCWndPeer->RepositionBars(0, 0xFFFF, 0, CWnd::reposQuery, &rect, &rectClient);
//////////////////////////////////////////////////////////////////////////
// Obtain handle of the window that will occupy remaining space
if(m_pMFCWndPeer->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)))
{
m_hWndClient = static_cast<CMDIFrameWnd*>(m_pMFCWndPeer)->m_hWndMDIClient;
}
else
{
m_hWndClient = ::GetDlgItem(m_hWnd, AFX_IDW_PANE_FIRST);
}
}
};
template<class TCaption>
struct IsReversalCaption {
enum { Value = TRUE };
};
template<>
struct IsReversalCaption<WTL::dockwins::COutlookLikeCaption> {
enum { Value = FALSE };
};
template<>
struct IsReversalCaption<WTL::dockwins::CVC7LikeCaption> {
enum { Value = FALSE };
};
template<class TCaption>
class CCorrespondingDocking
{
struct _Caption : public TCaption
{
void SetOrientation(bool bHorizontal)
{
__super::SetOrientation(IsReversalCaption<TCaption>::Value
? !bHorizontal : bHorizontal);
}
};
typedef WTL::dockwins::CDockingWindowTraits<_Caption,
WS_CAPTION | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
WS_EX_TOOLWINDOW> _AutoHidePaneTraits;
typedef WTL::dockwins::CDockingBoxTraits<TCaption,
WS_OVERLAPPEDWINDOW | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
WS_EX_TOOLWINDOW> _DockingBoxTraits;
public:
struct CBoxedDockingWindow : public WTL::dockwins::CBoxedDockingWindowImpl<
CBoxedDockingWindow,
ATL::CWindow,
WTL::dockwins::CBoxedDockingWindowTraits<TCaption,
WTL::dockwins::CTabDockingBox<_DockingBoxTraits>,
WS_OVERLAPPEDWINDOW | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
WS_EX_TOOLWINDOW > >
{
friend CDockingControlBar;
UINT m_nCtrlID;
CBoxedDockingWindow() : m_nCtrlID(0)
{
}
static void ModifySysMenu(HWND hWndPopup)
{
// Similar to CMiniDockFrameWnd
CMenu* pSysMenu = CWnd::FromHandle(hWndPopup)->GetSystemMenu(FALSE);
CString strHide;
if (pSysMenu && strHide.LoadString(AFX_IDS_HIDE))
{
pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
pSysMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, strHide);
}
}
void OnDocked(HDOCKBAR hBar,bool bHorizontal)
{
ModifySysMenu(hBar);
DWORD dwStyle = GetWindowLong(GWL_STYLE)&(~WS_SIZEBOX);
SetWindowLong(GWL_STYLE, dwStyle);
__super::OnDocked(hBar,bHorizontal);
ASSERT(GetOwnerDockingBar() == hBar);
}
void OnUndocked(HDOCKBAR hBar)
{
ModifySysMenu(m_hWnd);
DWORD dwStyle = GetWindowLong(GWL_STYLE) | WS_SIZEBOX;
SetWindowLong(GWL_STYLE, dwStyle);
__super::OnUndocked(hBar);
ASSERT(GetOwnerDockingBar() == NULL);
}
void GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
{
pMinMaxInfo->ptMinTrackSize.y = 100;
pMinMaxInfo->ptMinTrackSize.x = 100;
}
};
struct CDockingFrame : public WTL::dockwins::CDockingFrameImplBase<
CDockingFrame, CSimpleFrameImpl,
WTL::dockwins::CDockingFrameTraitsT<_AutoHidePaneTraits, WTL::dockwins::CSimpleSplitterBar<5>,
WS_OVERLAPPEDWINDOW | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> >
{
typedef std::vector<CBoxedDockingWindow*> _CList;
_CList m_listOfBoxedBar;
CBoxedDockingWindow* GetControlBar(UINT nID)
{
CBoxedDockingWindow* pControlBar = NULL;
for(_CList::const_iterator ite = m_listOfBoxedBar.begin();
ite != m_listOfBoxedBar.end(); ++ite)
{
CBoxedDockingWindow* pCurrent = *ite;
if( pCurrent->m_nCtrlID == nID)
{
pControlBar = pCurrent;
break;
}
}
return pControlBar;
}
void AddControlBar(CBoxedDockingWindow* pBar)
{
m_listOfBoxedBar.push_back(pBar);
}
void RemoveControlBar(CBoxedDockingWindow* pBar)
{
std::vector<CBoxedDockingWindow*>::iterator ite = std::find(
m_listOfBoxedBar.begin(),
m_listOfBoxedBar.end(),
pBar);
if(m_listOfBoxedBar.end() != ite)
{
m_listOfBoxedBar.erase(ite);
}
}
void LoadBarState(LPCTSTR lpszSection, BOOL blLoad)
{
if(m_listOfBoxedBar.empty())
{
// Don't have any tabbed control bar
return;
}
CWinApp* pWinApp = AfxGetApp();
HKEY hAppKey = pWinApp->GetAppRegistryKey();
DWORD dw;
HKEY hKeyProfile;
if( ERROR_SUCCESS != RegCreateKeyEx(hAppKey,
CString(lpszSection) + CString(_T("-WTLProfile")),
0, REG_NONE,
REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
&hKeyProfile, &dw))
{
hKeyProfile = NULL;
}
RegCloseKey(hAppKey);
if(hKeyProfile)
{
WTL::sstate::CDockWndMgrEx mgrDockWnds(m_hWnd);
for(std::vector<CBoxedDockingWindow*>::const_iterator ite = m_listOfBoxedBar.begin();
ite != m_listOfBoxedBar.end(); ++ite)
{
mgrDockWnds.Add(WTL::sstate::CDockingWindowStateAdapterEx<CBoxedDockingWindow>(**ite));
}
WTL::sstate::CWindowStateMgr<WTL::sstate::CStgRegistry> stateMgr(m_hWnd);
stateMgr.Initialize(m_hWnd);
stateMgr.Add(mgrDockWnds);
WTL::sstate::CStgRegistry storage(hKeyProfile);
if(blLoad)
{
stateMgr.Restore(storage);
}
else
{
stateMgr.Store(storage);
}
}
}
};
};
typedef CCorrespondingDocking<WTL::dockwins::DF_DEFAULT_CAPTION_CLASS>::CBoxedDockingWindow CWTLTabbedControlBar;
typedef CCorrespondingDocking<WTL::dockwins::DF_DEFAULT_CAPTION_CLASS>::CDockingFrame CWTLDockingFrame;
template<class T>
class CMFCFrameWndT : public CWTL4MFCWndT<T, CWTLDockingFrame>
{
public:
CMFCFrameWndT()
{
m_wndWTLPeer.m_pMFCWndPeer = this;
}
void LoadBarState(LPCTSTR lpszProfileSection)
{
__super::LoadBarState(lpszProfileSection);
m_wndWTLPeer.LoadBarState(lpszProfileSection, TRUE);
this->RecalcLayout();
}
void SaveBarState(LPCTSTR lpszProfileSection)
{
__super::SaveBarState(lpszProfileSection);
m_wndWTLPeer.LoadBarState(lpszProfileSection, FALSE);
}
afx_msg void OnUpdateControlBarMenu(CCmdUI* pCmdUI)
{
CWTLTabbedControlBar* pControlBar = m_wndWTLPeer.GetControlBar(pCmdUI->m_nID);
if(pControlBar)
{
pCmdUI->SetCheck(pControlBar->IsWindowVisible());
}
else
{
__super::OnUpdateControlBarMenu(pCmdUI);
}
}
afx_msg BOOL OnBarCheck(UINT nID)
{
CWTLTabbedControlBar* pControlBar = m_wndWTLPeer.GetControlBar(nID);
if(pControlBar)
{
// Toggle the control bar
pControlBar->Toggle();
return TRUE;
}
return __super::OnBarCheck(nID);
}
protected:
virtual void RecalcLayout(BOOL bNotify = TRUE)
{
if (FALSE == m_bInRecalcLayout)
{
m_bInRecalcLayout = TRUE;
m_wndWTLPeer.UpdateLayout(TRUE);
m_bInRecalcLayout = FALSE;
}
}
};
_END_WTL4MFC_NAMESPACE
//////////////////////////////////////////////////////////////////////////
// SDI Frame window
class CDockingFrameWnd : public WTL4MFC::CMFCFrameWndT<CFrameWnd>
{
DECLARE_DYNAMIC(CDockingFrameWnd)
};
//////////////////////////////////////////////////////////////////////////
// MDI Frame window
class CDockingMDIFrameWnd : public WTL4MFC::CMFCFrameWndT<CMDIFrameWnd>
{
DECLARE_DYNAMIC(CDockingMDIFrameWnd)
};
//////////////////////////////////////////////////////////////////////////
// Dock-able control bar
class CDockingControlBar
: public WTL4MFC::CWTL4MFCWndT<CWnd, WTL4MFC::CWTLTabbedControlBar>
{
DECLARE_DYNAMIC(CDockingControlBar)
public:
typedef WTL::dockwins::CDockingSide DockingSide;
CDockingControlBar();
BOOL Create(CFrameWnd* pParentWnd,
LPCTSTR lpszWindowName,
UINT nID,
const SIZE& size = CSize(200, 200),
DWORD dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
DWORD dwExStyle = WS_EX_TOOLWINDOW,
LPCTSTR lpszClassName = NULL)
{
return CreateEx(dwExStyle, lpszClassName,
lpszWindowName, dwStyle,
0, 0, size.cx, size.cy,
pParentWnd->m_hWnd,
(HMENU) nID, NULL);
}
bool DockTo(CDockingControlBar* pOtherControlBar, int index = 0)
{
ASSERT_KINDOF(CDockingControlBar, pOtherControlBar);
return m_wndWTLPeer.DockTo(pOtherControlBar->m_hWnd, index);
}
bool DockToParentFrame(DockingSide side,
unsigned long nBar = 0,
float fPctPos = 0.0)
{
RECT rtWindow;
GetWindowRect(&rtWindow);
return m_pWndParentFrame->DockWindow(this->m_wndWTLPeer, side, nBar, fPctPos,
rtWindow.right - rtWindow.left,
rtWindow.bottom - rtWindow.top);
}
protected:
WTL4MFC::CWTLDockingFrame* m_pWndParentFrame;
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void PostNcDestroy();
DECLARE_MESSAGE_MAP()
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct);
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -