📄 sizecbar.cpp
字号:
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 code
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++)
{
CSizingControlBar* pBar =
(CSizingControlBar*) m_pDockBar->m_arrBars[i];
if (HIWORD(pBar) == 0) continue; // placeholder
if (!pBar->IsVisible()) continue;
if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
arrSCBars.Add(pBar);
}
}
BOOL CSizingControlBar::NegotiateSpace(int nLengthTotal, BOOL bHorz)
{
ASSERT(bHorz == IsHorzDocked());
int nFirst, nLast, nThis;
GetRowInfo(nFirst, nLast, nThis);
int nLengthAvail = nLengthTotal;
int nLengthActual = 0;
int nLengthMin = 2;
int nWidthMax = 0;
CSizingControlBar* pBar;
for (int i = nFirst; i <= nLast; i++)
{
pBar = (CSizingControlBar*) m_pDockBar->m_arrBars[i];
if (HIWORD(pBar) == 0) continue; // placeholder
if (!pBar->IsVisible()) continue;
BOOL bIsSizingBar =
pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar));
int nLengthBar; // minimum length of the bar
if (bIsSizingBar)
nLengthBar = bHorz ? pBar->m_szMinHorz.cx - 2 :
pBar->m_szMinVert.cy - 2;
else
{
CRect rcBar;
pBar->GetWindowRect(&rcBar);
nLengthBar = bHorz ? rcBar.Width() - 2 : rcBar.Height() - 2;
}
nLengthMin += nLengthBar;
if (nLengthMin > nLengthTotal)
{
// split the row after fixed bar
if (i < nThis)
{
m_pDockBar->m_arrBars.InsertAt(i + 1,
(CControlBar*) NULL);
return FALSE;
}
// only this sizebar remains on the row, adjust it to minsize
if (i == nThis)
{
if (bHorz)
m_szHorz.cx = m_szMinHorz.cx;
else
m_szVert.cy = m_szMinVert.cy;
return TRUE; // the dockbar will split the row for us
}
// we have enough bars - go negotiate with them
m_pDockBar->m_arrBars.InsertAt(i, (CControlBar*) NULL);
nLast = i - 1;
break;
}
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;
}
CSCBArray 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_bKeepSize = FALSE;
(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_szMinHorz.cx : pBar->m_szMinVert.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 < nNumBars; 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 nAlign = bHorz ? -2 : 0;
CRect rc, rcDock;
m_pDockBar->GetWindowRect(&rcDock);
for (int i = nFirst; i <= nLast; i++)
{
CSizingControlBar* pBar =
(CSizingControlBar*) m_pDockBar->m_arrBars[i];
if (HIWORD(pBar) == 0) continue; // placeholder
if (!pBar->IsVisible()) continue;
pBar->GetWindowRect(&rc);
rc.OffsetRect(-rcDock.TopLeft());
if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
rc = CRect(rc.TopLeft(),
bHorz ? pBar->m_szHorz : pBar->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();
}
#ifdef _SCB_REPLACE_MINIFRAME
#ifndef _SCB_MINIFRAME_CAPTION
/////////////////////////////////////////////////////////////////////////////
// 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)
{
}
#endif //_SCB_MINIFRAME_CAPTION
/////////////////////////////////////////////////////////////////////////////
// CSCBMiniDockFrameWnd
IMPLEMENT_DYNCREATE(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd);
BEGIN_MESSAGE_MAP(CSCBMiniDockFrameWnd, baseCSCBMiniDockFrameWnd)
//{{AFX_MSG_MAP(CSCBMiniDockFrameWnd)
ON_WM_NCLBUTTONDOWN()
ON_WM_GETMINMAXINFO()
ON_WM_WINDOWPOSCHANGING()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CSCBMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
{
// set m_bInRecalcLayout to avoid flashing during creation
// RecalcLayout will be called once something is docked
m_bInRecalcLayout = TRUE;
DWORD dwStyle = WS_POPUP|WS_CAPTION|WS_SYSMENU|MFS_MOVEFRAME|
MFS_4THICKFRAME|MFS_SYNCACTIVE|MFS_BLOCKSYSMENU|
FWS_SNAPTOBARS;
if (dwBarStyle & CBRS_SIZE_DYNAMIC)
dwStyle &= ~MFS_MOVEFRAME;
DWORD dwExStyle = 0;
#ifdef _MAC
if (dwBarStyle & CBRS_SIZE_DYNAMIC)
dwExStyle |= WS_EX_FORCESIZEBOX;
else
dwStyle &= ~(MFS_MOVEFRAME|MFS_4THICKFRAME);
#endif
if (!CMiniFrameWnd::CreateEx(dwExStyle,
NULL, &afxChNil, dwStyle, rectDefault, pParent))
{
m_bInRecalcLayout = FALSE;
return FALSE;
}
dwStyle = dwBarStyle & (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT) ?
CBRS_ALIGN_LEFT : CBRS_ALIGN_TOP;
dwStyle |= dwBarStyle & CBRS_FLOAT_MULTI;
CMenu* pSysMenu = GetSystemMenu(FALSE);
//pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
CString strHide;
LOADSTR(strHide ,AFX_IDS_HIDE);
if (strHide.GetLength())
{
pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
pSysMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, strHide);
}
// must initially create with parent frame as parent
if (!m_wndDockBar.Create(pParent, WS_CHILD | WS_VISIBLE | dwStyle,
AFX_IDW_DOCKBAR_FLOAT))
{
m_bInRecalcLayout = FALSE;
return FALSE;
}
// set parent to CMiniDockFrameWnd
m_wndDockBar.SetParent(this);
m_bInRecalcLayout = FALSE;
return TRUE;
}
void CSCBMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (nHitTest == HTCAPTION || nHitTest == HTCLOSE)
{
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) && (GetStyle() & MFS_4THICKFRAME) == 0
&& pBar->IsVisible())
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(CPoint(0, 0), pBar->m_szMinFloat - CSize(4, 4));
#ifndef _SCB_MINIFRAME_CAPTION
CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME);
#else
CMiniFrameWnd::CalcBorders(&r, WS_THICKFRAME|WS_CAPTION);
#endif //_SCB_MINIFRAME_CAPTION
lpMMI->ptMinTrackSize.x = r.Width();
lpMMI->ptMinTrackSize.y = r.Height();
}
}
void CSCBMiniDockFrameWnd::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
if ((GetStyle() & MFS_4THICKFRAME) != 0)
{
CSizingControlBar* pBar = GetSizingControlBar();
if (pBar != NULL)
{
lpwndpos->flags |= SWP_NOSIZE; // don't size this time
// prevents flicker
pBar->m_pDockBar->ModifyStyle(0, WS_CLIPCHILDREN);
// enable diagonal resizing
ModifyStyle(MFS_4THICKFRAME, 0);
#ifndef _SCB_MINIFRAME_CAPTION
// remove caption
ModifyStyle(WS_SYSMENU|WS_CAPTION, 0);
#endif
DelayRecalcLayout();
pBar->PostMessage(WM_NCPAINT);
}
}
CMiniFrameWnd::OnWindowPosChanging(lpwndpos);
}
#endif //_SCB_REPLACE_MINIFRAME
void CSizingControlBar::SetVertWidth(int nWidth)
{
m_szVert.cx = nWidth;
}
//#pragma optimize( "s", off )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -