dockmanager.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 802 行 · 第 1/2 页
CPP
802 行
// if this is in the caption then eat it
if (IsDocked() && wp == HTCAPTION)
{
// activate the window first
ScSendMessage(WM_ACTIVATE, WA_CLICKACTIVE, NULL);
return 0;
}
break;
case WM_NCLBUTTONDOWN:
// if this is in the caption and the main window in maxed
// then eat
if (IsDocked() && wp == HTCAPTION && Maximized())
{
// activate the window first
ScSendMessage(WM_ACTIVATE, WA_CLICKACTIVE, NULL);
return 0;
}
break;
case WM_NCLBUTTONDBLCLK:
if (wp == HTCAPTION)
{
// toggle the docked state
if (IsDocked())
UnDock();
else
Dock(m_nLastDockPos);
// and eat the message
return 0;
}
break;
case WM_NCHITTEST:
if (IsDocked())
{
UINT nHitTest = ScDefault(hRealWnd);
// if the main window is _not_ unmaximized then don't let the
// docked window be resized on it's docked edge
// because its not intuitive and causes no end of trouble :)
if (!Maximized())
{
switch (m_nDockPos)
{
case DMP_LEFT:
if (nHitTest == HTRIGHT || nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT)
nHitTest = HTCLIENT;
break;
case DMP_RIGHT:
if (nHitTest == HTLEFT || nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT)
nHitTest = HTCLIENT;
break;
case DMP_BELOW:
if (nHitTest == HTTOP || nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT)
nHitTest = HTCLIENT;
break;
default:
ASSERT(0);
break;
}
}
// else main window is maximized so _only_ let it be resized on its
// docked edge and resize the main window afterwards
else
{
switch (m_nDockPos)
{
case DMP_LEFT:
if (nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT ||
nHitTest == HTLEFT || nHitTest == HTTOPLEFT ||
nHitTest == HTBOTTOMLEFT || nHitTest == HTTOP || nHitTest == HTBOTTOM)
{
nHitTest = HTCLIENT;
}
break;
case DMP_RIGHT:
if (nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT ||
nHitTest == HTRIGHT || nHitTest == HTTOPLEFT ||
nHitTest == HTBOTTOMLEFT || nHitTest == HTTOP || nHitTest == HTBOTTOM)
{
nHitTest = HTCLIENT;
}
break;
case DMP_BELOW:
if (nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT ||
nHitTest == HTRIGHT || nHitTest == HTTOPLEFT ||
nHitTest == HTBOTTOMLEFT || nHitTest == HTLEFT || nHitTest == HTBOTTOM)
{
nHitTest = HTCLIENT;
}
break;
default:
ASSERT(0);
break;
}
}
return nHitTest;
}
break;
case WM_GETMINMAXINFO:
if (IsDocked())
{
LRESULT lr = ScDefault(hRealWnd);
// save off our last min size
LPMINMAXINFO pMMI = (LPMINMAXINFO)lp;
m_sizeDockMin = pMMI->ptMinTrackSize;
OnMinMaxInfo(pMMI, FALSE);
return lr;
}
case WM_WINDOWPOSCHANGED:
// if the dock window is being shown/hidden and the main window is maximized
// then adjust the main window rect
if (IsDocked() && Maximized())
{
LPWINDOWPOS lpwp = (LPWINDOWPOS)lp;
if (lpwp->flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
{
LRESULT lr = ScDefault(hRealWnd);
OnMaximize();
return lr;
}
}
break;
}
return ScDefault(hRealWnd);
}
void CDockManager::OnMinMaxInfo(LPMINMAXINFO pMMI, BOOL /*bMain*/)
{
if (Maximized())
{
CSize sizeMin = GetMinMaximizedSize();
CRect rWork = GetWorkArea();
if (m_nDockPos == DMP_BELOW)
{
pMMI->ptMinTrackSize.y = sizeMin.cy;
pMMI->ptMaxTrackSize.y = rWork.Height() - sizeMin.cy;
}
else
{
pMMI->ptMinTrackSize.x = sizeMin.cx;
pMMI->ptMaxTrackSize.x = rWork.Width() - sizeMin.cx;
}
}
else
{
CSize sizeMin;
if (m_nDockPos == DMP_BELOW)
{
sizeMin.cx = max(m_sizeMainMin.cx, m_sizeDockMin.cx);
sizeMin.cy = m_sizeDockMin.cy;
}
else
{
sizeMin.cx = m_sizeDockMin.cx;
sizeMin.cy = max(m_sizeMainMin.cy, m_sizeDockMin.cy);
}
pMMI->ptMinTrackSize.y = max(sizeMin.cy, pMMI->ptMinTrackSize.y);
pMMI->ptMinTrackSize.x = max(sizeMin.cx, pMMI->ptMinTrackSize.x);
}
}
void CDockManager::UpdateDockWindowPos(BOOL /*bJustRestored*/)
{
ASSERT (IsDocked());
if (!IsDocked())
return;
CRect rMain, rDock;
GetWindowRect(rMain);
::GetWindowRect(ScGetHwnd(), rDock);
if (Maximized())
{
CRect rWorkArea = GetWorkArea();
switch (m_nDockPos)
{
case DMP_LEFT:
rDock.top = rMain.top;
rDock.bottom = rMain.bottom;
rDock.left = rWorkArea.left;
rDock.right = rMain.left;
break;
case DMP_RIGHT:
rDock.top = rMain.top;
rDock.bottom = rMain.bottom;
rDock.right = rWorkArea.right;
rDock.left = rMain.right;
break;
case DMP_BELOW:
rDock.left = rMain.left;
rDock.right = rMain.right;
rDock.bottom = rWorkArea.bottom;
rDock.top = rMain.bottom;
break;
default:
ASSERT(0);
return;
}
}
else // not maximized
{
switch (m_nDockPos)
{
case DMP_LEFT:
rDock.top = rMain.top;
rDock.bottom = rMain.bottom;
rDock.left = rMain.left - rDock.Width();
rDock.right = rMain.left;
break;
case DMP_RIGHT:
rDock.top = rMain.top;
rDock.bottom = rMain.bottom;
rDock.right = rMain.right + rDock.Width();
rDock.left = rMain.right;
break;
case DMP_BELOW:
rDock.left = rMain.left;
rDock.right = rMain.right;
rDock.bottom = rMain.bottom + rDock.Height();
rDock.top = rMain.bottom;
break;
default:
ASSERT(0);
return;
}
}
MoveWindow(ScGetCWnd(), rDock);
}
void CDockManager::UpdateMainWindowPos()
{
ASSERT (IsDocked());
if (!IsDocked())
return;
CRect rMain, rDock;
GetWindowRect(rMain);
::GetWindowRect(ScGetHwnd(), rDock);
// if the main window is maximized then shrink/enlarge
// the window
if (Maximized())
{
rMain = GetWorkArea();
switch (m_nDockPos)
{
case DMP_LEFT:
rMain.left = rDock.right;
break;
case DMP_RIGHT:
rMain.right = rDock.left;
break;
case DMP_BELOW:
rMain.bottom = rDock.top;
break;
default:
ASSERT(0);
return;
}
}
// else just move the main window
else
{
switch (m_nDockPos)
{
case DMP_LEFT:
rMain.top = rDock.top;
rMain.bottom = rDock.bottom;
rMain.right = rDock.right + rMain.Width();
rMain.left = rDock.right;
break;
case DMP_RIGHT:
rMain.top = rDock.top;
rMain.bottom = rDock.bottom;
rMain.left = rDock.left - rMain.Width();
rMain.right = rDock.left;
break;
case DMP_BELOW:
rMain.left = rDock.left;
rMain.right = rDock.right;
rMain.top = rDock.top - rMain.Height();
rMain.bottom = rDock.top;
break;
default:
ASSERT(0);
return;
}
}
MoveWindow(GetCWnd(), rMain);
}
void CDockManager::MoveWindow(CWnd* pWnd, CRect rect)
{
CRect rOrg;
pWnd->GetWindowRect(rOrg);
// don't move if nuthin's changed
if (rect != rOrg)
pWnd->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(),
SWP_NOACTIVATE | SWP_NOZORDER);
}
CRect CDockManager::GetUnDockedRect()
{
if (IsDocked())
return m_rUndocked;
// else
CRect rect;
::GetWindowRect(ScGetHwnd(), rect);
return rect;
}
CRect CDockManager::GetWorkArea(BOOL bMaximized)
{
CRect rWorkArea(0, 0, 0, 0);
HMONITOR hMonitor = MonitorFromWindow(GetHwnd(), MONITOR_DEFAULTTONEAREST);
ASSERT (hMonitor);
if (hMonitor)
{
MONITORINFO mi;
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor, &mi);
rWorkArea = mi.rcWork;
if (bMaximized)
rWorkArea.InflateRect(4, 4);
}
return rWorkArea;
}
CSize CDockManager::GetMinMaximizedSize()
{
CSize sizeMin = GetWorkArea().Size();
if (IsDocked() && ::IsWindowVisible(ScGetHwnd()))
{
switch (m_nDockPos)
{
case DMP_LEFT:
case DMP_RIGHT:
sizeMin.cx = MINMAXSIZE;
break;
case DMP_BELOW:
sizeMin.cy = MINMAXSIZE;
break;
default:
ASSERT(0);
}
}
return sizeMin;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?