📄 sizecbar.cpp
字号:
if (HIWORD(pFBar) == 0) continue; // placeholder
if (!pFBar->IsVisible()) continue;
BOOL bIsSizingBar = (FindSizingBar(pFBar) >= 0);
pBar = bIsSizingBar ? (CSizingControlBar*) pFBar : NULL;
int nLengthBar; // minimum length of the bar
if (bIsSizingBar)
nLengthBar = bHorz ? pBar->m_szMin.cx - 2 :
pBar->m_szMin.cy - 2;
else
{
CRect rcBar;
pFBar->GetWindowRect(&rcBar);
nLengthBar = bHorz ? rcBar.Width() - 2 : rcBar.Height() - 2;
}
nLengthMin += nLengthBar;
if (nLengthMin > nLengthTotal)
{
// if there is only this bar on the row, adjust it to minsize
if (nFirst == nLast)
{
if (bHorz)
m_szHorz.cx = m_szMin.cx;
else
m_szVert.cy = m_szMin.cy;
return TRUE;
}
// split the row if not enough room
m_pDockBar->m_arrBars.InsertAt(i, (CControlBar*) NULL);
if (i <= nThis)
return FALSE; // plain (fixed) controlbars - don't care
nLast = i - 1;
break; // we have enough bars - go negotiate with these
}
if (bIsSizingBar)
{
nLengthActual += bHorz ? pBar->m_szHorz.cx - 2 :
pBar->m_szVert.cy - 2;
nWidthMax = max(nWidthMax, bHorz ? pBar->m_szHorz.cy :
pBar->m_szVert.cx);
}
else
nLengthAvail -= nLengthBar;
}
CSizingControlBarArray arrSCBars;
GetRowSizingBars(arrSCBars);
int nNumBars = arrSCBars.GetSize();
int nDelta = nLengthAvail - nLengthActual;
// return faster when there is only one sizing bar per row (this one)
if (nNumBars == 1)
{
ASSERT(arrSCBars[0] == this);
if (nDelta != 0)
{
m_dwSCBStyle &= ~SCBS_KEEPSIZE;
(bHorz ? m_szHorz.cx : m_szVert.cy) += nDelta;
}
return TRUE;
}
// make all the bars the same width
for (i = 0; i < nNumBars; i++)
if (bHorz)
arrSCBars[i]->m_szHorz.cy = nWidthMax;
else
arrSCBars[i]->m_szVert.cx = nWidthMax;
// distribute the difference between the bars,
// but don't shrink them below their minsizes
while (nDelta != 0)
{
int nDeltaOld = nDelta;
for (i = 0; i < nNumBars; i++)
{
pBar = arrSCBars[i];
int nLMin = bHorz ? pBar->m_szMin.cx : pBar->m_szMin.cy;
int nL = bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy;
if ((nL == nLMin) && (nDelta < 0) || // already at min length
(pBar->m_dwSCBStyle & SCBS_KEEPSIZE) != 0) // or wants to keep its size
continue;
// sign of nDelta
int nDelta2 = (nDelta == 0) ? 0 : ((nDelta < 0) ? -1 : 1);
(bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) += nDelta2;
nDelta -= nDelta2;
if (nDelta == 0) break;
}
// clear SCBS_KEEPSIZE flags
if ((nDeltaOld == nDelta) || (nDelta == 0))
for (i = 0; i < nNumBars; i++)
arrSCBars[i]->m_dwSCBStyle &= ~SCBS_KEEPSIZE;
}
return TRUE;
}
void CSizingControlBar::AlignControlBars()
{
int nFirst, nLast, nThis;
GetRowInfo(nFirst, nLast, nThis);
BOOL bHorz = IsHorzDocked();
BOOL bNeedRecalc = FALSE;
int nPos, nAlign = bHorz ? -2 : 0;
CRect rc, rcDock;
m_pDockBar->GetWindowRect(&rcDock);
for (int i = nFirst; i <= nLast; i++)
{
CControlBar* pBar = (CControlBar*)m_pDockBar->m_arrBars[i];
if (HIWORD(pBar) == 0) continue; // placeholder
if (!pBar->IsVisible()) continue;
pBar->GetWindowRect(&rc);
rc.OffsetRect(-rcDock.TopLeft());
if ((nPos = FindSizingBar(pBar)) >= 0)
rc = CRect(rc.TopLeft(), bHorz ?
m_arrBars[nPos]->m_szHorz : m_arrBars[nPos]->m_szVert);
if ((bHorz ? rc.left : rc.top) != nAlign)
{
if (!bHorz)
rc.OffsetRect(0, nAlign - rc.top - 2);
else if (m_nDockBarID == AFX_IDW_DOCKBAR_TOP)
rc.OffsetRect(nAlign - rc.left, -2);
else
rc.OffsetRect(nAlign - rc.left, 0);
pBar->MoveWindow(rc);
bNeedRecalc = TRUE;
}
nAlign += (bHorz ? rc.Width() : rc.Height()) - 2;
}
if (bNeedRecalc)
m_pDockSite->DelayRecalcLayout();
}
void CSizingControlBar::OnUpdateCmdUI(CFrameWnd* pTarget,
BOOL bDisableIfNoHndler)
{
BOOL bNeedPaint = FALSE;
CPoint pt;
::GetCursorPos(&pt);
BOOL bHit = (OnNcHitTest(pt) == HTCLOSE);
BOOL bLButtonDown = (::GetKeyState(VK_LBUTTON) < 0);
BOOL bWasPushed = (m_biHide.m_dwFlags & BUT_PUSHED) != 0;
if (bHit && bLButtonDown)
m_biHide.m_dwFlags |= BUT_PUSHED;
else
m_biHide.m_dwFlags &= ~BUT_PUSHED;
BOOL bWasRaised = (m_biHide.m_dwFlags & BUT_RAISED) != 0;
if (bHit && !bLButtonDown)
m_biHide.m_dwFlags |= BUT_RAISED;
else
m_biHide.m_dwFlags &= ~BUT_RAISED;
bNeedPaint |= (((m_biHide.m_dwFlags & BUT_PUSHED) != 0) ^ bWasPushed) ||
(((m_biHide.m_dwFlags & BUT_RAISED) != 0) ^ bWasRaised);
if (bNeedPaint)
SendMessage(WM_NCPAINT);
}
void CSizingControlBar::LoadState(LPCTSTR lpszProfileName)
{
ASSERT_VALID(this);
ASSERT(GetSafeHwnd()); // must be called after Create()
// compensate the caption miscalculation in CFrameWnd::SetDockState()
CDockState state;
state.LoadState(lpszProfileName);
UINT nID = GetDlgCtrlID();
for (int i = 0; i < state.m_arrBarInfo.GetSize(); i++)
{
CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
ASSERT(pInfo != NULL);
if (!pInfo->m_bFloating)
continue;
// this is a floating dockbar - check the ID array
for (int j = 0; j < pInfo->m_arrBarID.GetSize(); j++)
if ((DWORD) pInfo->m_arrBarID[j] == nID)
{
// found this bar - offset origin and save settings
pInfo->m_pointPos.x++;
pInfo->m_pointPos.y +=
::GetSystemMetrics(SM_CYSMCAPTION) + 1;
pInfo->SaveState(lpszProfileName, i);
}
}
CWinApp* pApp = AfxGetApp();
TCHAR szSection[256];
wsprintf(szSection, _T("%s-SCBar-%d"), lpszProfileName,
GetDlgCtrlID());
m_szHorz.cx = max(m_szMin.cx, (int) pApp->GetProfileInt(szSection,
_T("sizeHorzCX"), m_szHorz.cx));
m_szHorz.cy = max(m_szMin.cy, (int) pApp->GetProfileInt(szSection,
_T("sizeHorzCY"), m_szHorz.cy));
m_szVert.cx = max(m_szMin.cx, (int) pApp->GetProfileInt(szSection,
_T("sizeVertCX"), m_szVert.cx));
m_szVert.cy = max(m_szMin.cy, (int) pApp->GetProfileInt(szSection,
_T("sizeVertCY"), m_szVert.cy));
m_szFloat.cx = max(m_szMin.cx, (int) pApp->GetProfileInt(szSection,
_T("sizeFloatCX"), m_szFloat.cx));
m_szFloat.cy = max(m_szMin.cy, (int) pApp->GetProfileInt(szSection,
_T("sizeFloatCY"), m_szFloat.cy));
}
void CSizingControlBar::SaveState(LPCTSTR lpszProfileName)
{
// place your SaveState or GlobalSaveState call in
// CMainFrame's OnClose() or DestroyWindow(), not in OnDestroy()
ASSERT_VALID(this);
ASSERT(GetSafeHwnd());
CWinApp* pApp = AfxGetApp();
TCHAR szSection[256];
wsprintf(szSection, _T("%s-SCBar-%d"), lpszProfileName,
GetDlgCtrlID());
pApp->WriteProfileInt(szSection, _T("sizeHorzCX"), m_szHorz.cx);
pApp->WriteProfileInt(szSection, _T("sizeHorzCY"), m_szHorz.cy);
pApp->WriteProfileInt(szSection, _T("sizeVertCX"), m_szVert.cx);
pApp->WriteProfileInt(szSection, _T("sizeVertCY"), m_szVert.cy);
pApp->WriteProfileInt(szSection, _T("sizeFloatCX"), m_szFloat.cx);
pApp->WriteProfileInt(szSection, _T("sizeFloatCY"), m_szFloat.cy);
}
void CSizingControlBar::GlobalLoadState(LPCTSTR lpszProfileName)
{
for (int i = 0; i < m_arrBars.GetSize(); i++)
((CSizingControlBar*) m_arrBars[i])->LoadState(lpszProfileName);
}
void CSizingControlBar::GlobalSaveState(LPCTSTR lpszProfileName)
{
for (int i = 0; i < m_arrBars.GetSize(); i++)
((CSizingControlBar*) m_arrBars[i])->SaveState(lpszProfileName);
}
/////////////////////////////////////////////////////////////////////////
// CSizingControlBarButton
CSizingControlBarButton::CSizingControlBarButton()
{
m_dwFlags = 0;
}
void CSizingControlBarButton::Paint(CDC* pDC)
{
CRect rc = GetRect();
if (m_dwFlags & BUT_PUSHED)
pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
else
if (m_dwFlags & BUT_RAISED)
pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
COLORREF clrOldTextColor = pDC->GetTextColor();
pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
CFont font;
int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
int pointsize = MulDiv(60, 96, ppi); // 6 points at 96 ppi
font.CreatePointFont(pointsize, _T("Marlett"));
CFont* oldfont = pDC->SelectObject(&font);
pDC->TextOut(ptOrg.x + 2, ptOrg.y + 2, CString(_T("r"))); // x-like
pDC->SelectObject(oldfont);
pDC->SetBkMode(nPrevBkMode);
pDC->SetTextColor(clrOldTextColor);
}
/////////////////////////////////////////////////////////////////////////////
// CSCBDockContext Drag Operations
static void AdjustRectangle(CRect& rect, CPoint pt)
{
int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
(pt.x > rect.right) ? (pt.x - rect.right) : 0;
int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
(pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
rect.OffsetRect(nXOffset, nYOffset);
}
void CSCBDockContext::StartDrag(CPoint pt)
{
ASSERT_VALID(m_pBar);
m_bDragging = TRUE;
InitLoop();
ASSERT((m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);
// get true bar size (including borders)
CRect rect;
m_pBar->GetWindowRect(rect);
m_ptLast = pt;
CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
// calculate frame dragging rectangle
m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);
#ifdef _MAC
CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz,
WS_THICKFRAME, WS_EX_FORCESIZEBOX);
#else
CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz, WS_THICKFRAME);
#endif
m_rectFrameDragHorz.DeflateRect(2, 2);
m_rectFrameDragVert = m_rectFrameDragHorz;
// adjust rectangles so that point is inside
AdjustRectangle(m_rectDragHorz, pt);
AdjustRectangle(m_rectDragVert, pt);
AdjustRectangle(m_rectFrameDragHorz, pt);
AdjustRectangle(m_rectFrameDragVert, pt);
// initialize tracking state and enter tracking loop
m_dwOverDockStyle = CanDock();
Move(pt); // call it here to handle special keys
Track();
}
/////////////////////////////////////////////////////////////////////////////
// CSCBMiniDockFrameWnd
IMPLEMENT_DYNCREATE(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd);
BEGIN_MESSAGE_MAP(CSCBMiniDockFrameWnd, CMiniFrameWnd)//baseCSCBMiniDockFrameWnd)
//{{AFX_MSG_MAP(CSCBMiniDockFrameWnd)
ON_WM_NCLBUTTONDOWN()
ON_WM_SIZE()
ON_WM_GETMINMAXINFO()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CSCBMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (nHitTest == HTCAPTION)
{
baseCSCBMiniDockFrameWnd::OnNcLButtonDown(nHitTest, point);
return;
}
if (GetSizingControlBar() != NULL)
CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
else
baseCSCBMiniDockFrameWnd::OnNcLButtonDown(nHitTest, point);
}
CSizingControlBar* CSCBMiniDockFrameWnd::GetSizingControlBar()
{
CWnd* pWnd = GetWindow(GW_CHILD); // get the dockbar
if (pWnd == NULL)
return NULL;
pWnd = pWnd->GetWindow(GW_CHILD); // get the controlbar
if (pWnd == NULL)
return NULL;
if (!pWnd->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
return NULL;
return (CSizingControlBar*) pWnd;
}
void CSCBMiniDockFrameWnd::OnSize(UINT nType, int cx, int cy)
{
CSizingControlBar* pBar = GetSizingControlBar();
if (pBar != NULL)
{
// check for caption
DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
if ((dwStyle & MFS_4THICKFRAME) != 0)
{
// prevents flicker
pBar->m_pDockBar->ModifyStyle(0, WS_CLIPCHILDREN);
// remove caption
ModifyStyle(MFS_4THICKFRAME|WS_SYSMENU|WS_CAPTION, 0);
ModifyStyleEx(WS_EX_TOOLWINDOW, 0);
DelayRecalcLayout();
pBar->PostMessage(WM_NCPAINT);
}
pBar->m_szFloat = CSize(cx + 4, cy + 4);
}
baseCSCBMiniDockFrameWnd::OnSize(nType, cx, cy);
}
void CSCBMiniDockFrameWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
baseCSCBMiniDockFrameWnd::OnGetMinMaxInfo(lpMMI);
CSizingControlBar* pBar = GetSizingControlBar();
if (pBar != NULL)
{
CRect r(0, 0, pBar->m_szMin.cx - 4, pBar->m_szMin.cy - 4);
CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME);
lpMMI->ptMinTrackSize.x = r.Width();
lpMMI->ptMinTrackSize.y = r.Height();
}
else
{
lpMMI->ptMinTrackSize.x = 1;
lpMMI->ptMinTrackSize.y = 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -