⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcgsizingcontrolbar.cpp

📁 一个完整的编辑器的代码(很值得参考
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	}

    ReleaseDC(&dc);
}

void CBCGSizingControlBar::OnPaint()
{
    // overridden to skip border painting based on clientrect
    CPaintDC dc(this);
}

UINT CBCGSizingControlBar::OnNcHitTest(CPoint point)
{
    CRect rcBar, rcEdge;
    GetWindowRect(rcBar);

	// By Erwin Tratar
    if (IsFloating()) {
		for (int i = 0; i < 4; i++)
			if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
				if (rcEdge.PtInRect(point)) return GetEdgeHTCode(i);

        return CControlBar::OnNcHitTest(point);
	}
	////////

    for (int i = 0; i < 4; i++)
        if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
            if (rcEdge.PtInRect(point)) return GetEdgeHTCode(i);

	for (i = 0; i < CBCGSIZINGCONTROLBAR_BUTTONS_NUM; i ++)
	{
		CSCBButton& btn = m_Buttons [i];

		CRect rc = btn.GetRect();
		rc.OffsetRect(rcBar.TopLeft());
		if (rc.PtInRect(point))
		{
			return btn.m_nHit;
		}
	}

	// Maybe on caption?
	CRect rcClient;
	GetClientRect(rcClient);
	ClientToScreen(&rcClient);

	if( !rcClient.PtInRect(point))
		return HTCAPTION;

    return HTCLIENT;
}

/////////////////////////////////////////////////////////////////////////
// CBCGSizingControlBar implementation helpers

void CBCGSizingControlBar::StartTracking(UINT nHitTest)
{
    SetCapture();

    // make sure no updates are pending
    RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
    
    BOOL bHorz = IsHorzDocked();

    m_szOld = bHorz ? m_szHorz : m_szVert;

    CRect rc;
    GetWindowRect(&rc);
	m_ptOld = ::GetMessagePos();
	ScreenToClient(&m_ptOld);

    m_htEdge = nHitTest;
    m_bTracking = TRUE;

    CSCBArray arrSCBars;
    GetRowSizingBars(arrSCBars);

    // compute the minsize as the max minsize of the sizing bars on row
    m_szMinT = m_szMin;
    for (int i = 0; i < arrSCBars.GetSize(); i++)
        if (bHorz)
            m_szMinT.cy = max(m_szMinT.cy, arrSCBars[i]->m_szMin.cy);
        else
            m_szMinT.cx = max(m_szMinT.cx, arrSCBars[i]->m_szMin.cx);

    if (!IsSideTracking())
    {
        // the control bar cannot grow with more than the size of 
        // remaining client area of the mainframe
        m_pDockSite->RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST,
            reposQuery, &rc, NULL, TRUE);
		m_pDockSite->SendMessage(WM_IDLEUPDATECMDUI);
        m_szMaxT = m_szOld + rc.Size() - CSize(4, 4);
    }
    else
    {
        // side tracking: max size is the actual size plus the amount
        // the neighbour bar can be decreased to reach its minsize
		BOOL bFound = FALSE;
        for (int i = 0; i < arrSCBars.GetSize (); i++)
		{
            if (arrSCBars [i] == this) 
			{
				bFound = TRUE;
				break;
			}
		}

		if (bFound)
		{
			CBCGSizingControlBar* pBar = arrSCBars[i +
				((m_htEdge == HTTOP || m_htEdge == HTLEFT) ? -1 : 1)];

			m_szMaxT = m_szOld + (bHorz ? pBar->m_szHorz :
				pBar->m_szVert) - pBar->m_szMin;
		}
    }

    OnTrackInvertTracker(); // draw tracker
}

void CBCGSizingControlBar::StopTracking()
{
    OnTrackInvertTracker(); // erase tracker

    m_bTracking = FALSE;
    ReleaseCapture();
    
    m_pDockSite->DelayRecalcLayout();
}

void CBCGSizingControlBar::OnTrackUpdateSize(CPoint& point)
{
    ASSERT(!IsFloating());

    CSize szDelta = point - m_ptOld;

    if (szDelta == CSize(0, 0)) return; // no size change

    CSize sizeNew = m_szOld;
    switch (m_htEdge)
    {
    case HTLEFT:    sizeNew -= CSize(szDelta.cx, 0); break;
    case HTTOP:     sizeNew -= CSize(0, szDelta.cy); break;
    case HTRIGHT:   sizeNew += CSize(szDelta.cx, 0); break;
    case HTBOTTOM:  sizeNew += CSize(0, szDelta.cy); break;
    }

    // enforce the limits
    sizeNew.cx = max(m_szMinT.cx, min(m_szMaxT.cx, sizeNew.cx));
    sizeNew.cy = max(m_szMinT.cy, min(m_szMaxT.cy, sizeNew.cy));

    BOOL bHorz = IsHorzDocked();
    szDelta = sizeNew - (bHorz ? m_szHorz : m_szVert);
    
    OnTrackInvertTracker(); // erase tracker

    (bHorz ? m_szHorz : m_szVert) = sizeNew; // save the new size

    CSCBArray arrSCBars;
    GetRowSizingBars(arrSCBars);

    for (int i = 0; i < arrSCBars.GetSize(); i++)
	{
		CBCGSizingControlBar* pBar = NULL;

        if (!IsSideTracking())
        {   // track simultaneously
            pBar = arrSCBars[i];
			ASSERT_VALID (pBar);

            (bHorz ? pBar->m_szHorz.cy : pBar->m_szVert.cx) =
                bHorz ? sizeNew.cy : sizeNew.cx;
        }
        else
        {   // adjust the neighbour's size too
            if (arrSCBars[i] != this) continue;

            pBar = arrSCBars[i +
                ((m_htEdge == HTTOP || m_htEdge == HTLEFT) ? -1 : 1)];
			ASSERT_VALID (pBar);

            (bHorz ? pBar->m_szHorz.cx : pBar->m_szVert.cy) -=
                bHorz ? szDelta.cx : szDelta.cy;
        }
	}

    OnTrackInvertTracker(); // redraw tracker at new pos
}

void CBCGSizingControlBar::OnTrackInvertTracker()
{
    ASSERT(m_bTracking);

	if (m_pDockBar == NULL)
	{
		return;
	}

    BOOL bHorz = IsHorzDocked();
    CRect rc, rcBar, rcDock, rcFrame;
    GetWindowRect(rcBar);
    m_pDockBar->GetWindowRect(rcDock);
    m_pDockSite->GetWindowRect(rcFrame);
    VERIFY(GetEdgeRect(rcBar, m_htEdge, rc));
    if (!IsSideTracking())
        rc = bHorz ? 
            CRect(rcDock.left + 1, rc.top, rcDock.right - 1, rc.bottom) :
            CRect(rc.left, rcDock.top + 1, rc.right, rcDock.bottom - 1);

    rc.OffsetRect(-rcFrame.TopLeft());

    CSize sizeNew = bHorz ? m_szHorz : m_szVert;
    CSize sizeDelta = sizeNew - m_szOld;
    if (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT && m_htEdge == HTTOP ||
        m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT && m_htEdge != HTBOTTOM ||
        m_nDockBarID == AFX_IDW_DOCKBAR_TOP && m_htEdge == HTLEFT ||
        m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM && m_htEdge != HTRIGHT)
        sizeDelta = -sizeDelta;
    rc.OffsetRect(sizeDelta);

    CDC *pDC = m_pDockSite->GetDCEx(NULL,
        DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
    CBrush* pBrush = CDC::GetHalftoneBrush();
    CBrush* pBrushOld = pDC->SelectObject(pBrush);

    pDC->PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATINVERT);
    
    pDC->SelectObject(pBrushOld);
    m_pDockSite->ReleaseDC(pDC);
}
//************************************************************************************
BOOL CBCGSizingControlBar::GetEdgeRect(CRect rcWnd, UINT nHitTest,
                                    CRect& rcEdge)
{
	if (!IsEdgeVisible (nHitTest))
	{
		rcEdge.SetRectEmpty ();
		return FALSE;
	}

    rcEdge = rcWnd;
    if (m_dwSCBStyle & SCBS_SHOWEDGES)
	{
        rcEdge.DeflateRect(1, 1);
	}

    BOOL bHorz = IsHorzDocked();

    switch (nHitTest)
    {
    case HTLEFT:
        rcEdge.right = rcEdge.left + m_cxEdge;
        rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);

		if (m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM)
		{
			rcEdge.bottom = rcWnd.bottom + 1;
		}

		if (m_nDockBarID == AFX_IDW_DOCKBAR_TOP)
		{
			rcEdge.top = rcWnd.top - 1;
		}

        break;

    case HTTOP:
        rcEdge.bottom = rcEdge.top + m_cxEdge;
        rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);

		if (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT)
		{
			rcEdge.left = rcWnd.left - 1;
		}

		if (m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT)
		{
			rcEdge.right = rcWnd.right + 1;
		}
        break;

    case HTRIGHT:
        rcEdge.left = rcEdge.right - m_cxEdge;
        rcEdge.DeflateRect(0, bHorz ? m_cxEdge: 0);

		if (m_nDockBarID == AFX_IDW_DOCKBAR_TOP)
		{
			rcEdge.top = rcWnd.top - 1;
		}

		if (m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM)
		{
			rcEdge.bottom = rcWnd.bottom + 1;
		}
        break;

    case HTBOTTOM:
        rcEdge.top = rcEdge.bottom - m_cxEdge;
        rcEdge.DeflateRect(bHorz ? 0 : m_cxEdge, 0);

		if (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT)
		{
			rcEdge.left = rcWnd.left - 1;
		}

		if (m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT)
		{
			rcEdge.right = rcWnd.right + 1;
		}
        break;

    default:
        ASSERT(FALSE); // invalid hit test code
    }

    return TRUE;
}

UINT CBCGSizingControlBar::GetEdgeHTCode(int nEdge)
{
	switch (nEdge)
	{
	case 0: return HTLEFT;
	case 1: return HTTOP;
	case 2: return HTRIGHT;
	case 3: return HTBOTTOM;
	}

    ASSERT(FALSE); // invalid edge no
    return HTNOWHERE;
}

void CBCGSizingControlBar::GetRowInfo(int& nFirst, int& nLast, int& nThis)
{
	if (m_pDockBar == NULL)
	{
		return;
	}

    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 CBCGSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars)
{
    arrSCBars.RemoveAll();

	if (m_pDockBar == NULL)
	{
		return;
	}

    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((CBCGSizingControlBar*)pBar);
    }
}

const int CBCGSizingControlBar::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 CBCGSizingControlBar::NegociateSpace(int nLengthAvail, BOOL bHorz)
{
	if (m_pDockBar == NULL)
	{
		return TRUE;
	}

    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()  : rcBar.Height() );
    }

    CSCBArray arrSCBars;
    GetRowSizingBars(arrSCBars);
    CBCGSizingControlBar* 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  :
			pBar->m_szVert.cy ;
		nMinLength += bHorz ? pBar->m_szMin.cx :
			pBar->m_szMin.cy ;
		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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -