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

📄 sizingcontrolbar.cpp

📁 Resource editor base speadrum Chinese mobile
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    return HTCLIENT;
}

void CSizingControlBar::OnClose()
{
    // do nothing: protection against accidentally destruction by the
    //   child control (i.e. if user hits Esc in a child editctrl)
}

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar implementation helpers

void CSizingControlBar::StartTracking(UINT nHitTest, const CPoint &pt)
{
	m_pDockSite->LockWindowUpdate();

    SetCapture();

    // make sure no updates are pending
    if(!m_bDragShowContent)
	{
        RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
	}

    m_bTracking = TRUE;
    m_htEdge    = nHitTest;

    BOOL bHorz         = IsHorzDocked();
    BOOL bHorzTracking = ( m_htEdge == HTLEFT || m_htEdge == HTRIGHT );

    m_nTrackPosOld = bHorzTracking ? pt.x : pt.y;

    CRect rcBar, rcEdge;
    GetWindowRect(&rcBar);
    GetEdgeRect(rcBar, m_htEdge, rcEdge);

	CPoint &ptCenter   = rcEdge.CenterPoint();
    m_nTrackEdgeOffset = m_nTrackPosOld - (bHorzTracking ? ptCenter.x : ptCenter.y);
    
    CSCBArray arrSCBars;
    int nThis;
    GetRowSizingBars(arrSCBars, nThis);

    m_nTrackPosMin = m_nTrackPosMax = m_nTrackPosOld;
    if(!IsSideTracking())
    {
        // calc minwidth as the max minwidth of the sizing bars on row
        int nMinWidth = bHorz ? m_sizeMinHorz.cy : m_sizeMinVert.cx;
        for (int i = 0; i < arrSCBars.GetSize(); i++)
		{
            nMinWidth = max(nMinWidth, bHorz ? arrSCBars[i]->m_sizeMinHorz.cy :
                                       arrSCBars[i]->m_sizeMinVert.cx);
		}

        int nExcessWidth = (bHorz ? m_sizeHorz.cy : m_sizeVert.cx) - nMinWidth;

        // the control bar cannot grow with more than the width of
        // remaining client area of the mainframe
        CRect rcT;
        m_pDockSite->RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST,
                                    reposQuery, &rcT, NULL, TRUE);
        int nMaxWidth = bHorz ? rcT.Height() - 2 : rcT.Width() - 2;

        BOOL bTopOrLeft = ( m_htEdge == HTTOP || m_htEdge == HTLEFT );

        m_nTrackPosMin -= bTopOrLeft ? nMaxWidth    : nExcessWidth;
        m_nTrackPosMax += bTopOrLeft ? nExcessWidth : nMaxWidth;
    }
    else
    {
        // side tracking:
        // max size is the actual size plus the amount the other
        // sizing bars can be decreased until they reach their minsize
        if (m_htEdge == HTBOTTOM || m_htEdge == HTRIGHT)
            nThis++;

		CSizingControlBar * pBar = NULL;
        for (int i = 0; i < arrSCBars.GetSize(); i++)
        {
			pBar = arrSCBars[i];
            int nExcessWidth = bHorz ? 
                               pBar->m_sizeHorz.cx - pBar->m_sizeMinHorz.cx :
                               pBar->m_sizeVert.cy - pBar->m_sizeMinVert.cy;

            if (i < nThis)
                m_nTrackPosMin -= nExcessWidth;
            else
                m_nTrackPosMax += nExcessWidth;
        }
    }

    OnInvertTracker(); // draw tracker
}

void CSizingControlBar::StopTracking()
{
    OnInvertTracker(); // erase tracker

    m_bTracking = FALSE;
    ReleaseCapture();

    m_pDockSite->DelayRecalcLayout();

	m_pDockSite->UnlockWindowUpdate();
}

void CSizingControlBar::OnTrackUpdateSize(CPoint& point)
{
    _ASSERTE( !IsFloating() );

    BOOL bHorzTrack = ( m_htEdge == HTLEFT || m_htEdge == HTRIGHT );

    int nTrackPos = bHorzTrack ? point.x : point.y;
    nTrackPos     = max(m_nTrackPosMin, min(m_nTrackPosMax, nTrackPos));

    int nDelta    = nTrackPos - m_nTrackPosOld;

    if (nDelta == 0)
        return; // no pos change

    OnInvertTracker(); // erase tracker

    m_nTrackPosOld = nTrackPos;
    
    BOOL bHorz = IsHorzDocked();

    CSize sizeNew = bHorz ? m_sizeHorz : m_sizeVert;
    switch (m_htEdge)
    {
    case HTLEFT:    sizeNew -= CSize(nDelta, 0); break;
    case HTTOP:     sizeNew -= CSize(0, nDelta); break;
    case HTRIGHT:   sizeNew += CSize(nDelta, 0); break;
    case HTBOTTOM:  sizeNew += CSize(0, nDelta); break;
    }

    CSCBArray arrSCBars;
    int nThis;
    GetRowSizingBars(arrSCBars, nThis);

    if(!IsSideTracking())
	{
		CSizingControlBar* pBar = NULL;
        for (int i = 0; i < arrSCBars.GetSize(); i++)
        {
            pBar = arrSCBars[i];
            // make same width (or height)
            (bHorz ? pBar->m_sizeHorz.cy : pBar->m_sizeVert.cx) =
             bHorz ? sizeNew.cy : sizeNew.cx;
        }
	}
    else
    {
        int nGrowingBar = nThis;
        BOOL bBefore    = ( m_htEdge == HTTOP || m_htEdge == HTLEFT );

        if (bBefore && nDelta > 0)
            nGrowingBar--;

        if (!bBefore && nDelta < 0)
            nGrowingBar++;

        if (nGrowingBar != nThis)
            bBefore = !bBefore;

        // nGrowing is growing
        nDelta = abs(nDelta);
        CSizingControlBar* pBar = arrSCBars[nGrowingBar];
        (bHorz ? pBar->m_sizeHorz.cx : pBar->m_sizeVert.cy) += nDelta;

        // the others are shrinking
        int nFirst = bBefore ? nGrowingBar - 1 : nGrowingBar + 1;
        int nLimit = bBefore ? -1 : arrSCBars.GetSize();

        for (int i = nFirst; nDelta != 0 && i != nLimit; i += (bBefore ? -1 : 1))
        {
            pBar = arrSCBars[i];
                
            int nDeltaT = min(nDelta,
                              (bHorz ? pBar->m_sizeHorz.cx    : pBar->m_sizeVert.cy) -
                              (bHorz ? pBar->m_sizeMinHorz.cx : pBar->m_sizeMinVert.cy));

            (bHorz ? pBar->m_sizeHorz.cx : pBar->m_sizeVert.cy) -= nDeltaT;
            nDelta -= nDeltaT;
        }
    }

    OnInvertTracker(); // redraw tracker at new pos

    if (m_bDragShowContent)
	{
        m_pDockSite->DelayRecalcLayout();
	}
}

void CSizingControlBar::OnInvertTracker()
{
    _ASSERTE( m_bTracking );

    if (m_bDragShowContent)
        return; // don't show tracker if DragFullWindows is on

    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);
	}

    BOOL bHorzTracking = ( m_htEdge == HTLEFT || m_htEdge == HTRIGHT );

    int nOfs = m_nTrackPosOld - m_nTrackEdgeOffset;
    nOfs -= bHorzTracking ? rc.CenterPoint().x : rc.CenterPoint().y;

    rc.OffsetRect(bHorzTracking ? nOfs : 0, bHorzTracking ? 0 : nOfs);
    rc.OffsetRect( -rcFrame.TopLeft() );

    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 CSizingControlBar::GetEdgeRect(const 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_nMargin;
        rcEdge.DeflateRect(0, bHorz ? m_nMargin: 0);
        break;
    case HTTOP:
        if ( !(m_dwSCBStyle & SCBS_EDGETOP) ) return FALSE;

        rcEdge.bottom = rcEdge.top + m_nMargin;
        rcEdge.DeflateRect(bHorz ? 0 : m_nMargin, 0);
        break;
    case HTRIGHT:
        if ( !(m_dwSCBStyle & SCBS_EDGERIGHT) ) return FALSE;

        rcEdge.left = rcEdge.right - m_nMargin;
        rcEdge.DeflateRect(0, bHorz ? m_nMargin: 0);
        break;
    case HTBOTTOM:
        if ( !(m_dwSCBStyle & SCBS_EDGEBOTTOM) ) return FALSE;

        rcEdge.top = rcEdge.bottom - m_nMargin;
        rcEdge.DeflateRect(bHorz ? 0 : m_nMargin, 0);
        break;
    default:
        _ASSERTE(FALSE); // invalid hit test code
    }

    return TRUE;
}

UINT CSizingControlBar::GetEdgeHTCode(int nEdge)
{
	switch( nEdge )
	{
    case 0: return HTLEFT;
    case 1: return HTTOP;
    case 2: return HTRIGHT;
    case 3: return HTBOTTOM;
	default:
		_ASSERTE(FALSE); // invalid edge code
	}
    return HTNOWHERE;
}

void CSizingControlBar::GetRowInfo(int& nFirst, int& nLast, int& nThis)
{
	_ASSERTE( m_pDockBar != NULL );
    ASSERT_VALID(m_pDockBar); // verify bounds

    nThis = m_pDockBar->FindBar(this);
    _ASSERTE(nThis != -1);

	int i = -1;
    // 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;
		}
	}

	int nBars = m_pDockBar->m_arrBars.GetSize();
    for (nLast = -1, i = nThis + 1; i < nBars && nLast == -1; i++)
	{
		if (m_pDockBar->m_arrBars[i] == NULL)
		{
            nLast = i - 1;
		}
	}

    _ASSERTE( (nLast != -1) && (nFirst != -1) );
}

void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars)
{
    int nThis; // dummy
    GetRowSizingBars(arrSCBars, nThis);
}

void CSizingControlBar::GetRowSizingBars(CSCBArray& arrSCBars, int& nThis)
{
    arrSCBars.RemoveAll();

    int nFirst, nLast, nThisTmp;
    GetRowInfo(nFirst, nLast, nThisTmp);

    nThis = -1;
	CSizingControlBar* pBar = NULL;
    for (int i = nFirst; i <= nLast; i++)
    {
        pBar = (CSizingControlBar*) m_pDockBar->m_arrBars[i];
        if(HIWORD(pBar) == 0 || !pBar->IsVisible() ) 
		{
			continue; // placeholder
		}
       
        if (pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
        {
            if (pBar == this)
			{
                nThis = arrSCBars.GetSize();
			}

            arrSCBars.Add(pBar);
        }
    }
}

BOOL CSizingControlBar::NegotiateSpace(int nLengthTotal, BOOL bHorz)
{
    if( bHorz != IsHorzDocked() )
		return FALSE;

    int nFirst, nLast, nThis;
    GetRowInfo(nFirst, nLast, nThis);

    int nLengthAvail  = nLengthTotal;
    int nLengthActual = 0;
    int nLengthMin    = 2;
    int nWidthMax     = 0;

    CSizingControlBar* pBar = NULL;

    for (int i = nFirst; i <= nLast; i++)
    {
        pBar = (CSizingControlBar*) m_pDockBar->m_arrBars[i];
        if( HIWORD(pBar) == 0 || !pBar->IsVisible() ) 
		{
			continue; // placeholder
		}
       
        BOOL bIsSizingBar = pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar));

        int nLengthBar; // minimum length of the bar
        if (bIsSizingBar)
		{
            nLengthBar = bHorz ? pBar->m_sizeMinHorz.cx - 2 : pBar->m_sizeMinVert.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_sizeHorz.cx = m_sizeMinHorz.cx;
                else
                    m_sizeVert.cy = m_sizeMinVert.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_sizeHorz.cx - 2 : pBar->m_sizeVert.cy - 2;
            nWidthMax = max(nWidthMax, bHorz ? pBar->m_sizeHorz.cy : pBar->m_sizeVert.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)
    {
        _ASSERTE( arrSCBars[0] == this );

        if (nDelta == 0)  return TRUE;
        
        m_bKeepSize = FALSE;
        (bHorz ? m_sizeHorz.cx : m_sizeVert.cy) += nDelta;

        return TRUE;
    }

    // make all the bars the same width
    for(i = 0; i < nNumBars; i++)
	{
        if (bHorz)
            arrSCBars[i]->m_sizeHorz.cy = nWidthMax;
        else
            arrSCBars[i]->m_sizeVert.cx = nWidthMax;
	}
    // distribute the difference between the bars,
    // but don't shrink them below their minsizes
    for(; nDelta != 0; )
    {
        int nDeltaOld = nDelta;
        for (i = 0; i < nNumBars; i++)
        {
            pBar = arrSCBars[i];
            int nLMin = bHorz ? pBar->m_sizeMinHorz.cx : pBar->m_sizeMinVert.cy;
            int nL    = bHorz ? pBar->m_sizeHorz.cx : pBar->m_sizeVert.cy;

			// already at min length or wants to keep its size
            if( (nL == nLMin) && (nDelta < 0) || pBar->m_bKeepSize) 
                continue;

            // sign of nDelta
            int nDelta2 = (nDelta == 0) ? 0 : ((nDelta < 0) ? -1 : 1);

            (bHorz ? pBar->m_sizeHorz.cx : pBar->m_sizeVert.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);

	CSizingControlBar* pBar = NULL;
    for (int i = nFirst; i <= nLast; i++)
    {
        pBar = (CSizingControlBar*) m_pDockBar->m_arrBars[i];
        if (HIWORD(pBar) == 0 || !pBar->IsVisible() ) 
		{
			continue; // placeholder
		}
        
        pBar->GetWindowRect(&rc);
        rc.OffsetRect(-rcDock.TopLeft());

        if(pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
		{
            rc = CRect(rc.TopLeft(), bHorz ? pBar->m_sizeHorz : pBar->m_sizeVert);
		}

        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)
{
    UNUSED_ALWAYS(bDisableIfNoHndler);
    UNUSED_ALWAYS(pTarget);
}

⌨️ 快捷键说明

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