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

📄 sizingcontrolbar.cpp

📁 Resource editor base speadrum Chinese mobile
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 
// FileName: SizingControlBar.cpp
// anli.wei 整理完成
// Copyright (C) 2004 Spreadtrum Corporation
// All rights reserved.

#include "stdafx.h"
#include "SizingControlBar.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar

IMPLEMENT_DYNAMIC(CSizingControlBar, CControlBar);

CSizingControlBar::CSizingControlBar() : m_nMargin(4)
{
	m_bTracking        = FALSE;
    m_bKeepSize        = FALSE;
    m_bParentSizing    = FALSE;
	m_bDragShowContent = FALSE;

	m_nDockBarID   = 0;
	m_dwSCBStyle   = 0;

    m_sizeHorz     = CSize(200, 200);
	m_sizeVert     = CSize(200, 200);
    m_sizeFloat    = CSize(200, 200);
	m_sizeMinHorz  = CSize(64, 32);
    m_sizeMinVert  = CSize(32, 32);
    m_sizeMinFloat = CSize(64, 32);   

	m_hHorzCursor  = NULL;
	m_hVertCursor  = NULL;
	m_pActiveWnd   = NULL;
}

CSizingControlBar::~CSizingControlBar()
{
}

BEGIN_MESSAGE_MAP(CSizingControlBar, CControlBar)
    //{{AFX_MSG_MAP(CSizingControlBar)
    ON_WM_CREATE()
    ON_WM_PAINT()
    ON_WM_NCPAINT()
    ON_WM_NCCALCSIZE()
    ON_WM_WINDOWPOSCHANGING()
    ON_WM_CAPTURECHANGED()
    ON_WM_SETTINGCHANGE()
    ON_WM_LBUTTONUP()
    ON_WM_MOUSEMOVE()
    ON_WM_NCLBUTTONDOWN()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONDBLCLK()
    ON_WM_RBUTTONDOWN()
    ON_WM_NCMOUSEMOVE()
    ON_WM_NCHITTEST()
    ON_WM_CLOSE()
    ON_WM_SIZE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CSizingControlBar::Create( LPCTSTR lpszWindowName, CWnd* pParentWnd, 
							    const CSize &sizeDefault, UINT nID, 
								BOOL  bHasGripper /* = FALSE */,
								DWORD dwStyle     /* = WS_CHILD | WS_VISIBLE | CBRS_TOP*/ )
{
    m_sizeHorz = m_sizeVert = m_sizeFloat = sizeDefault;

    return Create(lpszWindowName, pParentWnd, nID, dwStyle);
}

BOOL CSizingControlBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd, 
							   UINT nID, DWORD dwStyle)
{
    // must have a parent
	_ASSERTE( pParentWnd != NULL );
    ASSERT_VALID( pParentWnd );

    // cannot be both fixed and dynamic
    // (CBRS_SIZE_DYNAMIC is used for resizng when floating)
    _ASSERTE( !((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)) );

    m_dwStyle = dwStyle & CBRS_ALL; // save the control bar styles

    // register and create the window - skip CControlBar::Create()
    CString strClassName = ::AfxRegisterWndClass( CS_DBLCLKS,
                                                  ::LoadCursor(NULL, IDC_ARROW),
                                                  ::GetSysColorBrush(COLOR_BTNFACE), 
												  0);

    dwStyle &= ~CBRS_ALL;       // keep only the generic window styles
    dwStyle |= WS_CLIPCHILDREN; // prevents flashing
   
    if( !CWnd::Create(strClassName, lpszWindowName, dwStyle,
                      CRect(0, 0, 0, 0), pParentWnd, nID) )
	{
        return FALSE;
	}

    return TRUE;
}

/////////////////////////////////////////////////////////////////////////
// CSizingControlBar message handlers

int CSizingControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CControlBar::OnCreate(lpCreateStruct) == -1)
        return -1;

    m_dwSCBStyle |= SCBS_SHOWEDGES;

    return 0;
}

const BOOL CSizingControlBar::IsFloating() const
{
    return ( !IsHorzDocked() && !IsVertDocked() );
}

const BOOL CSizingControlBar::IsHorzDocked() const
{
    return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
            m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
}

const BOOL CSizingControlBar::IsVertDocked() const
{
    return ( m_nDockBarID == AFX_IDW_DOCKBAR_LEFT ||
             m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT );
}

const BOOL CSizingControlBar::IsSideTracking() const
{
    // don't call this when not tracking
    _ASSERTE( m_bTracking && !IsFloating() );

    return ( m_htEdge == HTLEFT || m_htEdge == HTRIGHT) ? IsHorzDocked() : IsVertDocked();
}

CSize CSizingControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
    if (bStretch) // the bar is stretched (is not the child of a dockbar)
	{
        if (bHorz)
            return CSize(32767, m_sizeHorz.cy);
        else
            return CSize(m_sizeVert.cx, 32767);
	}
    // dirty cast - we need access to protected CDockBar members
    CSCBDockBar* pDockBar = (CSCBDockBar*) m_pDockBar;

    // force imediate RecalcDelayShow() for all sizing bars on the row
    // with delayShow/delayHide flags set to avoid IsVisible() problems
    CSCBArray arrSCBars;
    GetRowSizingBars(arrSCBars);

    AFX_SIZEPARENTPARAMS layout;
    layout.hDWP = pDockBar->m_bLayoutQuery ?
                  NULL : ::BeginDeferWindowPos(arrSCBars.GetSize());
    for (int i = 0; i < arrSCBars.GetSize(); i++)
	{
        if (arrSCBars[i]->m_nStateFlags & (delayHide|delayShow))
            arrSCBars[i]->RecalcDelayShow(&layout);
	}
    if (layout.hDWP != NULL)
        ::EndDeferWindowPos(layout.hDWP);

    // get available length
    CRect rc = pDockBar->m_rectLayout;
    if (rc.IsRectEmpty())
        m_pDockSite->GetClientRect(&rc);

    int nLengthTotal = bHorz ? rc.Width() + 2 : rc.Height() - 2;

    if (IsVisible() && !IsFloating() &&
        m_bParentSizing && arrSCBars[0] == this)
	{
        if (NegotiateSpace(nLengthTotal, (bHorz != FALSE)))
            AlignControlBars();
	}

    m_bParentSizing = FALSE;

    if (bHorz)
        return CSize(max(m_sizeMinHorz.cx, m_sizeHorz.cx),
                     max(m_sizeMinHorz.cy, m_sizeHorz.cy));

    return CSize(max(m_sizeMinVert.cx, m_sizeVert.cx),
                 max(m_sizeMinVert.cy, m_sizeVert.cy));
}

CSize CSizingControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
    if (dwMode & (LM_HORZDOCK | LM_VERTDOCK)) // docked ?
    {
        if (nLength == -1)
            m_bParentSizing = TRUE;

        return CControlBar::CalcDynamicLayout(nLength, dwMode);
    }

    if (dwMode & LM_MRUWIDTH) return m_sizeFloat;
    if (dwMode & LM_COMMIT)   return m_sizeFloat; // already committed

    // check for dialgonal resizing hit test
    int nHitTest = m_pDockContext->m_nHitTest;

    if (IsFloating() &&
        (nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT ||
        nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT))
    {
        CPoint ptCursor;
        ::GetCursorPos(&ptCursor);

        CRect rcFrame, rcBar;
        GetParentFrame()->GetWindowRect(&rcFrame);
        GetWindowRect(&rcBar);
        
        if (nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT)
        {
            m_sizeFloat.cx = rcFrame.left + rcBar.Width() - ptCursor.x;
            m_pDockContext->m_rectFrameDragHorz.left = 
                min(ptCursor.x, rcFrame.left + rcBar.Width() - m_sizeMinFloat.cx);
        }

        if (nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT)
        {
            m_sizeFloat.cy = rcFrame.top + rcBar.Height() - ptCursor.y;
            m_pDockContext->m_rectFrameDragHorz.top =
                min(ptCursor.y, rcFrame.top + rcBar.Height() - m_sizeMinFloat.cy);
        }

        if (nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT)
            m_sizeFloat.cx = rcBar.Width() + ptCursor.x - rcFrame.right;

        if (nHitTest == HTBOTTOMLEFT || nHitTest == HTBOTTOMRIGHT)
            m_sizeFloat.cy = rcBar.Height() + ptCursor.y - rcFrame.bottom;
    }
    else
	{
        ((dwMode & LM_LENGTHY) ? m_sizeFloat.cy : m_sizeFloat.cx) = nLength;
	}

    m_sizeFloat.cx = max(m_sizeFloat.cx, m_sizeMinFloat.cx);
    m_sizeFloat.cy = max(m_sizeFloat.cy, m_sizeMinFloat.cy);

    return m_sizeFloat;
}

void CSizingControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
    // force non-client recalc if moved or resized
    lpwndpos->flags |= SWP_FRAMECHANGED;

    CControlBar::OnWindowPosChanging(lpwndpos);

    // find on which side are we docked
    m_nDockBarID = GetParent()->GetDlgCtrlID();

    if (!IsFloating())
	{
        if (lpwndpos->flags & SWP_SHOWWINDOW)
		{
            m_bKeepSize = TRUE;
		}
	}
}

/////////////////////////////////////////////////////////////////////////
// Mouse Handling
//
void CSizingControlBar::OnLButtonDown(UINT nFlags, CPoint point)
{
    if(m_pDockBar != NULL)
    {
        // start the drag
        _ASSERTE(m_pDockContext != NULL);

        ClientToScreen(&point);
        m_pDockContext->StartDrag(point);
    }
    else
	{
        CWnd::OnLButtonDown(nFlags, point);
	}
}

void CSizingControlBar::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    if (m_pDockBar != NULL)
    {
        // toggle docking
        _ASSERTE(m_pDockContext != NULL);
        m_pDockContext->ToggleDocking();
    }
    else
	{
        CWnd::OnLButtonDblClk(nFlags, point);
	}
}

void CSizingControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point) 
{
    UNUSED_ALWAYS(point);

    if (m_bTracking || IsFloating())
	{
        return;
	}

    if ((nHitTest >= HTSIZEFIRST) && (nHitTest <= HTSIZELAST))
	{
		StartTracking(nHitTest, point); // sizing edge hit
	}
}

void CSizingControlBar::OnLButtonUp(UINT nFlags, CPoint point)
{
    if (m_bTracking)
	{
        StopTracking();
	}
	else
	{
		CControlBar::OnLButtonUp(nFlags, point);
	}
}

void CSizingControlBar::OnRButtonDown(UINT nFlags, CPoint point)
{
    if (m_bTracking)
        StopTracking();

    CControlBar::OnRButtonDown(nFlags, point);
}

void CSizingControlBar::OnMouseMove(UINT nFlags, CPoint point)
{
    if (m_bTracking)
    {
        CPoint ptScreen = point;
        ClientToScreen(&ptScreen);

        OnTrackUpdateSize(ptScreen);
    }

    CControlBar::OnMouseMove(nFlags, point);
}

void CSizingControlBar::OnCaptureChanged(CWnd *pWnd)
{
    if (m_bTracking && (pWnd != this))
        StopTracking();

    CControlBar::OnCaptureChanged(pWnd);
}

void CSizingControlBar::OnNcCalcSize(BOOL bCalcValidRects,
                                     NCCALCSIZE_PARAMS FAR* lpncsp)
{
    UNUSED_ALWAYS(bCalcValidRects);

    // compute the the client area
    m_dwSCBStyle &= ~SCBS_EDGEALL;

    // add resizing edges between bars on the same row
    if (!IsFloating() && m_pDockBar != NULL)
    {
        CSCBArray arrSCBars;
        int nThis;
        GetRowSizingBars(arrSCBars, nThis);

        BOOL bHorz = IsHorzDocked();
        if (nThis > 0)
            m_dwSCBStyle |= bHorz ? SCBS_EDGELEFT : SCBS_EDGETOP;

        if (nThis < arrSCBars.GetUpperBound())
            m_dwSCBStyle |= bHorz ? SCBS_EDGERIGHT : SCBS_EDGEBOTTOM;
    }

    NcCalcClient(&lpncsp->rgrc[0], m_nDockBarID);
}

void CSizingControlBar::NcPaintGripper(CDC* pDC, LPCRECT pRect)
{
    UNUSED_ALWAYS(pDC);
    UNUSED_ALWAYS(pRect);
}

void CSizingControlBar::NcCalcClient(LPRECT pRect, UINT nDockBarID)
{
	_ASSERTE( pRect != NULL );

    CRect rc(pRect);

    rc.DeflateRect(3, 5, 3, 3);
    if (nDockBarID != AFX_IDW_DOCKBAR_FLOAT)
        rc.DeflateRect(2, 0, 2, 2);

    switch(nDockBarID)
    {
    case AFX_IDW_DOCKBAR_TOP:
        m_dwSCBStyle |= SCBS_EDGEBOTTOM;
        break;
    case AFX_IDW_DOCKBAR_BOTTOM:
        m_dwSCBStyle |= SCBS_EDGETOP;
        break;
    case AFX_IDW_DOCKBAR_LEFT:
        m_dwSCBStyle |= SCBS_EDGERIGHT;
        break;
    case AFX_IDW_DOCKBAR_RIGHT:
        m_dwSCBStyle |= SCBS_EDGELEFT;
        break;
    }

    // make room for edges only if they will be painted
    if (m_dwSCBStyle & SCBS_SHOWEDGES)
	{
        rc.DeflateRect( (m_dwSCBStyle & SCBS_EDGELEFT)   ? m_nMargin : 0,
                        (m_dwSCBStyle & SCBS_EDGETOP)    ? m_nMargin : 0,
                        (m_dwSCBStyle & SCBS_EDGERIGHT)  ? m_nMargin : 0,
                        (m_dwSCBStyle & SCBS_EDGEBOTTOM) ? m_nMargin : 0 );
	}
    *pRect = rc;
}

void CSizingControlBar::OnNcPaint()
{
    // get window DC that is clipped to the non-client area
    CWindowDC dc(this);

    CRect rcClient, rcBar;
    GetClientRect(&rcClient);
    ClientToScreen(&rcClient);
    GetWindowRect(&rcBar);

    rcClient.OffsetRect( -rcBar.TopLeft() );
    rcBar.OffsetRect( -rcBar.TopLeft() );

    CDC dcMem;
    VERIFY( dcMem.CreateCompatibleDC(&dc) );
    
    CBitmap bmp;
    VERIFY( bmp.CreateCompatibleBitmap(&dc, rcBar.Width(), rcBar.Height()) );
    CBitmap* pOldBm = dcMem.SelectObject(&bmp);

    // draw borders in non-client area
    CRect rcDraw = rcBar;
    DrawBorders(&dcMem, rcDraw);

    // erase the NC background
    dcMem.FillRect(rcDraw, 
		CBrush::FromHandle((HBRUSH)GetClassLong(m_hWnd, GCL_HBRBACKGROUND)));

    if (m_dwSCBStyle & SCBS_SHOWEDGES)
    {
        CRect rcEdge; // paint the sizing edges
		UINT  uHitTest;
        for (int i = 0; i < 4; i++)
		{
			uHitTest = GetEdgeHTCode(i);
            if (GetEdgeRect(rcBar, uHitTest, rcEdge))
			{
				if( HTRIGHT == uHitTest || HTBOTTOM == uHitTest )
				{
					dcMem.Draw3dRect( rcEdge, ::GetSysColor(COLOR_BTNHIGHLIGHT),
                                ::GetSysColor(COLOR_3DDKSHADOW) );
				}
				else
				{
					if( HTLEFT == uHitTest ) rcEdge.right++;
					if( HTTOP  == uHitTest ) rcEdge.bottom++;

					dcMem.DrawEdge( rcEdge, EDGE_RAISED, BF_RECT);
				}
			}
		}
    }

	NcPaintGripper(&dcMem, rcClient);

    // client area is not our bussiness :)
    dc.IntersectClipRect(&rcBar);
    dc.ExcludeClipRect(&rcClient);

    dc.BitBlt(0, 0, rcBar.Width(), rcBar.Height(), &dcMem, 0, 0, SRCCOPY);

    ReleaseDC(&dc);

    dcMem.SelectObject(pOldBm);
    bmp.DeleteObject();
    dcMem.DeleteDC();
}

void CSizingControlBar::OnPaint()
{
    // overridden to skip border painting based on clientrect
	// don't delete or annotate CPaintDC dc(this); !!!!! anli.wei
	CPaintDC dc(this);
}

void CSizingControlBar::OnSize(UINT nType, int cx, int cy) 
{
	UNUSED_ALWAYS(nType);

	// TODO: Add your message handler code here
	if( m_pActiveWnd != NULL )
	{
		m_pActiveWnd->MoveWindow(0, 0, cx, cy);
	}
}

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

    if (!IsFloating())
	{
		UINT uHitTest = 0;
        for (int i = 0; i < 4; i++)
		{
			uHitTest = GetEdgeHTCode(i);
			if (GetEdgeRect(rcBar, uHitTest, rcEdge))
			{
                if (rcEdge.PtInRect(point))
				{
					if( m_hHorzCursor != NULL && 
						(HTLEFT == uHitTest || HTRIGHT == uHitTest) )
					{
						SetCursor(m_hHorzCursor);
					}
					if( m_hVertCursor != NULL &&
						(HTTOP == uHitTest || HTBOTTOM == uHitTest) )
					{
						SetCursor(m_hVertCursor);
					}
                    return uHitTest;
				}
			}
		}
	}

⌨️ 快捷键说明

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