📄 sizecbar.cpp
字号:
BOOL CSizingControlBar::GetEdgeRect(CRect rcWnd, UINT nHitTest,
CRect& rcEdge)
{
rcEdge = rcWnd;
if (m_dwSCBStyle & SCBS_SHOWEDGES)
rcEdge.DeflateRect(1, 1);
BOOL bHorz = IsHorzDocked();
switch (nHitTest)
{
case HTLEFT:
if (!(m_dwSCBStyle & SCBS_EDGELEFT)) return FALSE;
rcEdge.right = rcEdge.left + m_cxEdge;
rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);
break;
case HTTOP:
if (!(m_dwSCBStyle & SCBS_EDGETOP)) return FALSE;
rcEdge.bottom = rcEdge.top + m_cxEdge;
rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);
break;
case HTRIGHT:
if (!(m_dwSCBStyle & SCBS_EDGERIGHT)) return FALSE;
rcEdge.left = rcEdge.right - m_cxEdge;
rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);
break;
case HTBOTTOM:
if (!(m_dwSCBStyle & SCBS_EDGEBOTTOM)) return FALSE;
rcEdge.top = rcEdge.bottom - m_cxEdge;
rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);
break;
default:
ASSERT(FALSE); // invalid hit test code
}
return TRUE;
}
UINT CSizingControlBar::GetEdgeHTCode(int nEdge)
{
if (nEdge == 0) return HTLEFT;
if (nEdge == 1) return HTTOP;
if (nEdge == 2) return HTRIGHT;
if (nEdge == 3) return HTBOTTOM;
ASSERT(FALSE); // invalid edge no
return HTNOWHERE;
}
void CSizingControlBar::GetRowInfo(int& nFirst, int& nLast, int& nThis)
{
ASSERT_VALID(m_pDockBar); // verify bounds
nThis = m_pDockBar->FindBar(this);
ASSERT(nThis != -1);
int i, nBars = m_pDockBar->m_arrBars.GetSize();
// find the first and the last bar in row
for (nFirst = -1, i = nThis - 1; i >= 0 && nFirst == -1; i--)
if (m_pDockBar->m_arrBars[i] == NULL)
nFirst = i + 1;
for (nLast = -1, i = nThis + 1; i < nBars && nLast == -1; i++)
if (m_pDockBar->m_arrBars[i] == NULL)
nLast = i - 1;
ASSERT((nLast != -1) && (nFirst != -1));
}
void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars)
{
arrSCBars.RemoveAll();
int nFirst, nLast, nThis;
GetRowInfo(nFirst, nLast, nThis);
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;
if (FindSizingBar(pBar) >= 0)
arrSCBars.Add((CSizingControlBar*)pBar);
}
}
const int CSizingControlBar::FindSizingBar(CControlBar* pBar) const
{
for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
if (m_arrBars[nPos] == pBar)
return nPos; // got it
return -1; // not found
}
BOOL CSizingControlBar::NegociateSpace(int nLengthAvail, BOOL bHorz)
{
ASSERT(bHorz == IsHorzDocked());
int nFirst, nLast, nThis;
GetRowInfo(nFirst, nLast, nThis);
// step 1: subtract the visible fixed bars' lengths
for (int i = nFirst; i <= nLast; i++)
{
CControlBar* pFBar = (CControlBar*)m_pDockBar->m_arrBars[i];
if (HIWORD(pFBar) == 0) continue; // placeholder
if (!pFBar->IsVisible() || (FindSizingBar(pFBar) >= 0)) continue;
CRect rcBar;
pFBar->GetWindowRect(&rcBar);
nLengthAvail -= (bHorz ? rcBar.Width() - 2 : rcBar.Height() - 2);
}
CSCBArray arrSCBars;
GetRowSizingBars(arrSCBars);
CSizingControlBar* pBar;
// step 2: compute actual and min lengths; also the common width
int nActualLength = 0;
int nMinLength = 2;
int nWidth = 0;
for (i = 0; i < arrSCBars.GetSize(); i++)
{
pBar = arrSCBars[i];
nActualLength += bHorz ? pBar->m_szHorz.cx - 2 :
pBar->m_szVert.cy - 2;
nMinLength += bHorz ? pBar->m_szMin.cx - 2:
pBar->m_szMin.cy - 2;
nWidth = max(nWidth, bHorz ? pBar->m_szHorz.cy :
pBar->m_szVert.cx);
}
// step 3: pop the bar out of the row if not enough room
if (nMinLength > nLengthAvail)
{
if (nFirst < nThis || nThis < nLast)
{ // not enough room - create a new row
m_pDockBar->m_arrBars.InsertAt(nLast + 1, this);
m_pDockBar->m_arrBars.InsertAt(nLast + 1, (CControlBar*) NULL);
m_pDockBar->m_arrBars.RemoveAt(nThis);
}
return FALSE;
}
// step 4: make the bars same width
for (i = 0; i < arrSCBars.GetSize(); i++)
if (bHorz)
arrSCBars[i]->m_szHorz.cy = nWidth;
else
arrSCBars[i]->m_szVert.cx = nWidth;
if (nActualLength == nLengthAvail)
return TRUE; // no change
// step 5: distribute the difference between the bars, but
// don't shrink them below minsize
int nDelta = nLengthAvail - nActualLength;
while (nDelta != 0)
{
int nDeltaOld = nDelta;
for (i = 0; i < arrSCBars.GetSize(); 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_bKeepSize) // 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 m_bKeepSize flags
if ((nDeltaOld == nDelta) || (nDelta == 0))
for (i = 0; i < arrSCBars.GetSize(); i++)
arrSCBars[i]->m_bKeepSize = FALSE;
}
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();
TRACE("ccc\n");
}
}
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.bPushed;
m_biHide.bPushed = bHit && bLButtonDown;
BOOL bWasRaised = m_biHide.bRaised;
m_biHide.bRaised = bHit && !bLButtonDown;
bNeedPaint |= (m_biHide.bPushed ^ bWasPushed) ||
(m_biHide.bRaised ^ bWasRaised);
if (bNeedPaint)
SendMessage(WM_NCPAINT);
}
void CSizingControlBar::LoadState(LPCTSTR lpszProfileName)
{
ASSERT_VALID(this);
ASSERT(GetSafeHwnd()); // must be called after Create()
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::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);
}
/////////////////////////////////////////////////////////////////////////
// CSCBButton
CSCBButton::CSCBButton()
{
bRaised = FALSE;
bPushed = FALSE;
}
void CSCBButton::Paint(CDC* pDC)
{
CRect rc = GetRect();
if (bPushed)
pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
else
if (bRaised)
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -