dockmanager.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 802 行 · 第 1/2 页
CPP
802 行
// DockManager.cpp: implementation of the CDockManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DockManager.h"
#include "holdredraw.h"
#include "autoflag.h"
#include <multimon.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const int MINMAXSIZE = GetSystemMetrics(SM_CYCAPTION) * 4;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDockManager::CDockManager() :
m_nDockPos(DMP_UNDOCKED),
m_nLastDockPos(DMP_RIGHT),
m_nWidthDocked(-1),
m_nWidthDockedMax(-1),
m_nHeightDocked(-1),
m_nHeightDockedMax(-1),
m_bResizeUpdate(TRUE),
m_bSizeUpdate(TRUE),
m_sizeMainMin(-1, -1),
m_sizeDockMin(-1, -1)
{
}
CDockManager::~CDockManager()
{
}
BOOL CDockManager::Initialize(CWnd* pMainWnd, CWnd* pDockWnd,
DM_POS nPos, DM_POS nLastPos,
int nWidthDocked, int nWidthDockedMax,
int nHeightDocked, int nHeightDockedMax)
{
if (!HookWindow(*pMainWnd) || !ScHookWindow(*pDockWnd))
return FALSE;
m_nLastDockPos = nLastPos;
m_nWidthDocked = nWidthDocked;
m_nWidthDockedMax = nWidthDockedMax;
m_nHeightDocked = nHeightDocked;
m_nHeightDockedMax = nHeightDockedMax;
return Dock(nPos);
}
BOOL CDockManager::Dock(DM_POS nPos)
{
if (nPos == DMP_UNDOCKED)
return UnDock();
if (IsDocked() && m_nDockPos == nPos)
return TRUE;
BOOL bDocked = IsDocked();
m_nDockPos = nPos;
CRect rDock;
ScGetCWnd()->GetWindowRect(rDock);
// save window pos if not currently docked
if (!bDocked)
m_rUndocked = rDock;
// and restore previous width
if (nPos == DMP_BELOW)
{
int nHeight = GetDockedHeight(Maximized());
if (nHeight != -1)
{
rDock.bottom = rDock.top + nHeight;
CAutoFlag af(m_bResizeUpdate, FALSE);
CAutoFlag af2(m_bSizeUpdate, FALSE);
MoveWindow(ScGetCWnd(), rDock);
}
}
else
{
int nWidth = GetDockedWidth(Maximized());
if (nWidth != -1)
{
rDock.right = rDock.left + nWidth;
CAutoFlag af(m_bResizeUpdate, FALSE);
CAutoFlag af2(m_bSizeUpdate, FALSE);
MoveWindow(ScGetCWnd(), rDock);
}
}
// also restore main window pos if maximized
if (Maximized())
OnMaximize();
else
UpdateDockWindowPos();
return TRUE;
}
BOOL CDockManager::UnDock()
{
if (!IsDocked())
return TRUE;
m_nLastDockPos = m_nDockPos;
m_nDockPos = DMP_UNDOCKED;
// restore window pos
ScGetCWnd()->MoveWindow(m_rUndocked);
// also restore main window pos if maximized
if (Maximized())
OnMaximize();
return TRUE;
}
LRESULT CDockManager::WindowProc(HWND /*hRealWnd*/, UINT msg, WPARAM wp, LPARAM lp)
{
if (!IsDocked())
return Default();
switch (msg)
{
case WM_MOVE:
{
LRESULT lr = Default();
if (m_bResizeUpdate)
UpdateDockWindowPos();
return lr;
}
break;
case WM_SIZE:
{
LRESULT lr = Default();
if (m_bResizeUpdate)
UpdateDockWindowPos();
return lr;
}
break;
case WM_SYSCOMMAND:
if (wp == SC_MAXIMIZE || wp == SC_RESTORE)
{
CAutoFlag af(m_bResizeUpdate, FALSE);
LRESULT lr = Default();
if (wp == SC_MAXIMIZE)
OnMaximize();
else
OnRestore();
return lr;
}
break;
case WM_NCLBUTTONDBLCLK:
if (wp == HTCAPTION)
{
CAutoFlag af(m_bResizeUpdate, FALSE);
BOOL bIsZoomed = Maximized();
LRESULT lr = Default();
if (!bIsZoomed)
OnMaximize();
else
OnRestore();
return lr;
}
break;
case WM_NCLBUTTONDOWN:
// if this is in the caption and the main window in maxed
// then eat
if (wp == HTCAPTION && Maximized())
{
// activate the window first
SendMessage(WM_ACTIVATE, WA_CLICKACTIVE, NULL);
return 0;
}
break;
case WM_GETMINMAXINFO:
{
// if the main window is zoomed then don't restrict how far
// the docked window can be resized
LRESULT lr = Default();
// save off our last min size
LPMINMAXINFO pMMI = (LPMINMAXINFO)lp;
m_sizeMainMin = pMMI->ptMinTrackSize;
OnMinMaxInfo(pMMI, TRUE);
return lr;
}
}
return Default();
}
void CDockManager::OnMaximize()
{
ASSERT (Maximized());
BOOL bDockVisible = ::IsWindowVisible(ScGetHwnd());
CRect rMain = GetWorkArea();
if (bDockVisible && IsDocked())
{
CRect rDock;
::GetWindowRect(ScGetHwnd(), rDock);
switch (m_nDockPos)
{
case DMP_LEFT:
if (m_nWidthDockedMax == -1)
rMain.left += min(rDock.Width(), rMain.Width() / 2);
else
rMain.left += m_nWidthDockedMax;
break;
case DMP_RIGHT:
if (m_nWidthDockedMax == -1)
rMain.right -= min(rDock.Width(), rMain.Width() / 2);
else
rMain.right -= m_nWidthDockedMax;
break;
case DMP_BELOW:
if (m_nHeightDockedMax == -1)
rMain.bottom -= min(rDock.Height(), rMain.Height() / 2);
else
rMain.bottom -= m_nHeightDockedMax;
break;
default:
ASSERT(0);
return;
}
}
MoveWindow(GetCWnd(), rMain);
if (IsDocked())
UpdateDockWindowPos();
}
void CDockManager::OnRestore()
{
ASSERT (!Maximized());
BOOL bDockVisible = ::IsWindowVisible(ScGetHwnd());
if (bDockVisible && IsDocked())
{
CRect rDock;
GetWindowRect(rDock);
switch (m_nDockPos)
{
case DMP_LEFT:
if (m_nWidthDocked != -1)
{
rDock.right = rDock.left;
rDock.left -= m_nWidthDocked;
}
break;
case DMP_RIGHT:
if (m_nWidthDocked != -1)
{
rDock.left = rDock.right;
rDock.right += m_nWidthDocked;
}
break;
case DMP_BELOW:
if (m_nHeightDocked != -1)
{
rDock.top = rDock.bottom;
rDock.bottom += m_nHeightDocked;
}
break;
default:
ASSERT(0);
return;
}
MoveWindow(ScGetCWnd(), rDock);
}
}
LRESULT CDockManager::ScWindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_MOVE:
if (IsDocked())
{
LRESULT lr = ScDefault(hRealWnd);
if (m_bResizeUpdate)
UpdateMainWindowPos();
return lr;
}
break;
case WM_SIZE:
if (IsDocked())
{
LRESULT lr = ScDefault(hRealWnd);
if (m_bResizeUpdate)
UpdateMainWindowPos();
// save dock width
if (m_bSizeUpdate && ::IsWindowVisible(ScGetHwnd()))
{
CRect rDock;
::GetWindowRect(ScGetHwnd(), rDock);
if (Maximized())
{
if (m_nDockPos == DMP_BELOW)
m_nHeightDockedMax = rDock.Height();
else
m_nWidthDockedMax = rDock.Width();
}
else
{
if (m_nDockPos == DMP_BELOW)
m_nHeightDocked = rDock.Height();
else
m_nWidthDocked = rDock.Width();
}
}
return lr;
}
break;
case WM_SYSCOMMAND:
if (IsDocked())
{
switch (wp)
{
// hide system menu
case SC_KEYMENU:
case SC_MOUSEMENU:
return 0;
// don't allow docked window to be minimized or maximized directly
// instead, send the message to the main window
case SC_MAXIMIZE:
case SC_MINIMIZE:
return SendMessage(msg, wp, lp);
// if the dock window is being closed and the main window is maximized
// then readjust the main window rect
case SC_CLOSE:
if (Maximized())
{
LRESULT lr = ScDefault(hRealWnd);
OnMaximize();
return lr;
}
break;
}
}
break;
case WM_NCRBUTTONDOWN:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?