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

📄 bcgdockcontext.cpp

📁 一个完整的编辑器的代码(很值得参考
💻 CPP
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This source code is a part of BCGControlBar library.
// You may use, compile or redistribute it as part of your application 
// for free. You cannot redistribute it as a part of a software development 
// library without the agreement of the author. If the sources are 
// distributed along with the application, you should leave the original 
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES on your own risk.
// 
// Stas Levin <stas@iet.co.il>
//*******************************************************************************

// BCGDockContext.cpp:
//

#include "stdafx.h"
#include "bcgcontrolbar.h"
#include "BCGDockContext.h"
#include "BCGDockBar.h"
#include "BCGSizingControlBar.h"
#include "bcgtoolbar.h"

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

/////////////////////////////////////////////////////////////////////////////
// CBCGDockContext
//
// this class is needed for 8-dim stretching of floated controlbars

CBCGDockContext::CBCGDockContext(CControlBar* pBar) : CDockContext( pBar )
{
}

CBCGDockContext::~CBCGDockContext()
{
}

// Aliases duplicated from CDockContext 

#define m_rectRequestedSize     m_rectDragHorz
#define m_rectActualSize        m_rectDragVert
#define m_rectActualFrameSize   m_rectFrameDragHorz
#define m_rectFrameBorders      m_rectFrameDragVert


// Duplicated from CDockContext in order to call Stretch()
// because it's not virtual
void CBCGDockContext::StartResize(int nHitTest, CPoint pt)
{
	ASSERT_VALID(m_pBar);
	ASSERT(m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC);
	m_bDragging = FALSE;

	InitLoop();

	// GetWindowRect returns screen coordinates(not mirrored)
	// So if the desktop is mirrored then turn off mirroring
	// for the desktop dc so that we draw correct focus rect

	if (m_pDC->GetLayout() & LAYOUT_RTL)
		m_pDC->SetLayout(LAYOUT_LTR);

	// get true bar size (including borders)
	CRect rect;
	m_pBar->GetWindowRect(rect);
	m_ptLast = pt;
	m_nHitTest = nHitTest;

	CSize size = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
	m_rectRequestedSize = CRect(rect.TopLeft(), size);
	m_rectActualSize = CRect(rect.TopLeft(), size);
	m_rectActualFrameSize = CRect(rect.TopLeft(), size);

	// calculate frame rectangle
	CMiniFrameWnd::CalcBorders(&m_rectActualFrameSize);
	m_rectActualFrameSize.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);

	m_rectFrameBorders = CRect(CPoint(0,0),
		m_rectActualFrameSize.Size() - m_rectActualSize.Size());

	// initialize tracking state and enter tracking loop
	m_dwOverDockStyle = 0;
	Stretch(pt);   // call it here to handle special keys
	Track();
}


// Mostly duplicated from CDockContext
// changes are marked
void CBCGDockContext::Stretch(CPoint pt)
{
	CPoint ptOffset = pt - m_ptLast;

	//<---------------------------------------------------------->
	//<ET: Horizontally and vertically independently------------->
    CSize size;

	// horizontally
	if (m_nHitTest == HTLEFT 
		|| m_nHitTest == HTTOPLEFT 
		|| m_nHitTest == HTBOTTOMLEFT )
	{
		m_rectRequestedSize.left += ptOffset.x;
        size = m_pBar->CalcDynamicLayout(m_rectRequestedSize.Width(), LM_HORZ);
	}
	if (m_nHitTest == HTRIGHT
		|| m_nHitTest == HTTOPRIGHT 
		|| m_nHitTest == HTBOTTOMRIGHT )
	{
		m_rectRequestedSize.right += ptOffset.x;
        size = m_pBar->CalcDynamicLayout(m_rectRequestedSize.Width(), LM_HORZ);
	}

	// vertically
	if (m_nHitTest == HTTOP 
		|| m_nHitTest == HTTOPLEFT 
		|| m_nHitTest == HTTOPRIGHT )
	{
		m_rectRequestedSize.top += ptOffset.y;
        size = m_pBar->CalcDynamicLayout(m_rectRequestedSize.Height(), LM_HORZ|LM_LENGTHY);
	}
	if (m_nHitTest == HTBOTTOM
		|| m_nHitTest == HTBOTTOMRIGHT 
		|| m_nHitTest == HTBOTTOMRIGHT )
	{
		m_rectRequestedSize.bottom += ptOffset.y;
        size = m_pBar->CalcDynamicLayout(m_rectRequestedSize.Height(), LM_HORZ|LM_LENGTHY);
	}
	//<---------------------------------------------------------->
	//<---------------------------------------------------------->


	CRect rectDesk;
	HWND hWndDesk = ::GetDesktopWindow();
	::GetWindowRect(hWndDesk, &rectDesk);
	CRect rectTemp = m_rectActualFrameSize;

	//<---------------------------------------------------------->
	//<ET: cases for HT{X}{Y}------------------------------------>
    // left, top, top left
    if (m_nHitTest == HTLEFT || m_nHitTest == HTTOP || m_nHitTest == HTTOPLEFT)
    {
        rectTemp.left = rectTemp.right -
            (size.cx + m_rectFrameBorders.Width());
        rectTemp.top = rectTemp.bottom -
            (size.cy + m_rectFrameBorders.Height());
        CRect rect;
        if (rect.IntersectRect(rectDesk, rectTemp))
        {
            m_rectActualSize.left = m_rectActualSize.right - size.cx;
            m_rectActualSize.top = m_rectActualSize.bottom - size.cy;
            m_rectActualFrameSize.left = rectTemp.left;
            m_rectActualFrameSize.top = rectTemp.top;
        }
    } 
	else if (m_nHitTest == HTTOPRIGHT) // top right
    {
        rectTemp.top = rectTemp.bottom -
            (size.cy + m_rectFrameBorders.Height());
        rectTemp.right = rectTemp.left +
            (size.cx + m_rectFrameBorders.Width());
        CRect rect;
        if (rect.IntersectRect(rectDesk, rectTemp))
        {
            m_rectActualSize.left = m_rectActualSize.right - size.cx;
            m_rectActualSize.bottom = m_rectActualSize.top + size.cy;
            m_rectActualFrameSize.right = rectTemp.right;
            m_rectActualFrameSize.top = rectTemp.top;
        }
    } 
	else if (m_nHitTest == HTBOTTOMLEFT) // bottom left
    {
        rectTemp.bottom = rectTemp.top +
            (size.cy + m_rectFrameBorders.Height());
        rectTemp.left = rectTemp.right -
            (size.cx + m_rectFrameBorders.Width());
        CRect rect;
        if (rect.IntersectRect(rectDesk, rectTemp))
        {
            m_rectActualSize.right = m_rectActualSize.left + size.cx;
            m_rectActualSize.top = m_rectActualSize.bottom - size.cy;
            m_rectActualFrameSize.left = rectTemp.left;
            m_rectActualFrameSize.bottom = rectTemp.bottom;
        }
    } 
	else // bottom, right, bottom right
    {
        rectTemp.right = rectTemp.left +
            (size.cx + m_rectFrameBorders.Width());
        rectTemp.bottom = rectTemp.top +
            (size.cy + m_rectFrameBorders.Height());
        CRect rect;
        if (rect.IntersectRect(rectDesk, rectTemp))
        {
            m_rectActualSize.right = m_rectActualSize.left + size.cx;
            m_rectActualSize.bottom = m_rectActualSize.top + size.cy;
            m_rectActualFrameSize.right = rectTemp.right;
            m_rectActualFrameSize.bottom = rectTemp.bottom;
        }
    }
	//<---------------------------------------------------------->
	//<---------------------------------------------------------->

	
	m_ptLast = pt;

	// update feedback
	DrawFocusRect();
}

// Duplicated from CDockContext in order to call Stretch()
// because it's not virtual
BOOL CBCGDockContext::Track()
{
	// don't handle if capture already set
	if (::GetCapture() != NULL)
		return FALSE;

	// set capture to the window which received this message
	m_pBar->SetCapture();
	ASSERT(m_pBar == CWnd::GetCapture());

	// get messages until capture lost or cancelled/accepted
	while (CWnd::GetCapture() == m_pBar)
	{
		MSG msg;
		if (!::GetMessage(&msg, NULL, 0, 0))
		{
			AfxPostQuitMessage(msg.wParam);
			break;
		}

		switch (msg.message)
		{
		case WM_LBUTTONUP:
			if (m_bDragging)
				EndDrag();
			else
				EndResize();
			return TRUE;
		case WM_MOUSEMOVE:
			if (m_bDragging)
				Move(msg.pt);
			else
				Stretch(msg.pt);
			break;
		case WM_KEYUP:
			if (m_bDragging)
				OnKey((int)msg.wParam, FALSE);
			break;
		case WM_KEYDOWN:
			if (m_bDragging)
				OnKey((int)msg.wParam, TRUE);
			if (msg.wParam == VK_ESCAPE)
			{
				CancelLoop();
				return FALSE;
			}
			break;
		case WM_RBUTTONDOWN:
			CancelLoop();
			return FALSE;

		// just dispatch rest of the messages
		default:
			DispatchMessage(&msg);
			break;
		}
	}

	CancelLoop();

	return FALSE;
}

/////////////////////////////////////////////////////////////////////////
// CBCGMiniDockFrameWnd

IMPLEMENT_DYNCREATE(CBCGMiniDockFrameWnd, CMiniDockFrameWnd)

CBCGMiniDockFrameWnd::CBCGMiniDockFrameWnd()
{
}

CBCGMiniDockFrameWnd::~CBCGMiniDockFrameWnd()
{
}

CBCGMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
{
	if (!CMiniDockFrameWnd::Create(pParent, dwBarStyle))
		return FALSE;

	ModifyStyle(MFS_4THICKFRAME, 0);
	return true;
}

BEGIN_MESSAGE_MAP(CBCGMiniDockFrameWnd, CMiniDockFrameWnd)
	//{{AFX_MSG_MAP(CBCGMiniDockFrameWnd)
	ON_WM_NCLBUTTONDOWN()
	ON_WM_NCRBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CBCGMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point) 
{
	if (nHitTest == HTCAPTION)
	{
		// special activation for floating toolbars
		ActivateTopParent();

		// initiate toolbar drag for non-CBRS_FLOAT_MULTI toolbars
		if ((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0)
		{
			int nPos = 1;
			CControlBar* pBar = NULL;
			while(pBar == NULL && nPos < m_wndDockBar.m_arrBars.GetSize())
				pBar = reinterpret_cast<CBCGDockBar&>(m_wndDockBar).GetDockedControlBar(nPos++);

			ASSERT(pBar != NULL);
			ASSERT_KINDOF(CControlBar, pBar);
			ASSERT(pBar->m_pDockContext != NULL);
			pBar->m_pDockContext->StartDrag(point);
			return;
		}
	}
	else if (nHitTest >= HTSIZEFIRST && nHitTest <= HTSIZELAST)
	{
		// special activation for floating toolbars
		ActivateTopParent();

		int nPos = 1;
		CControlBar* pBar = NULL;
		while(pBar == NULL && nPos < m_wndDockBar.m_arrBars.GetSize())
			pBar = reinterpret_cast<CBCGDockBar&>(m_wndDockBar).GetDockedControlBar(nPos++);

		ASSERT(pBar != NULL);
		ASSERT_KINDOF(CControlBar, pBar);
		ASSERT(pBar->m_pDockContext != NULL);

		// CBRS_SIZE_DYNAMIC toolbars cannot have the CBRS_FLOAT_MULTI style
		ASSERT((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0);

		
		if (!pBar->IsKindOf(RUNTIME_CLASS(CBCGSizingControlBar))) {
			CMiniDockFrameWnd::OnNcLButtonDown(nHitTest,point);
		}
		else {
			pBar->m_pDockContext->StartResize(nHitTest, point);
		}
		return;
	}
	CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
}
//*********************************************************************************
void CBCGMiniDockFrameWnd::OnNcRButtonDown(UINT /*nHitTest*/, CPoint point)
{
	// By Alan Fritz

	if (CBCGToolBar::IsCustomizeMode ())
	{
		return;
	}

    CWnd* pParentWnd = GetParent ();
	ASSERT_VALID (pParentWnd);

    if (pParentWnd->IsKindOf (RUNTIME_CLASS (CFrameWnd)))
    {
        ((CFrameWnd*)pParentWnd)->SendMessage(BCGM_TOOLBARMENU,
					(WPARAM) GetSafeHwnd (),
					MAKELPARAM (point.x, point.y));
    }
    else
    {
        TRACE(_T("CBCGMiniDockFrameWnd parent is not a CFrameWnd\n"));
        ASSERT (FALSE);
    }
}

⌨️ 快捷键说明

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