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

📄 bcgpdockbar.cpp

📁 远程网络监视程序的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// BCGPDockBar.cpp : implementation file
//

#include "stdafx.h"

#include "BCGPFrameWnd.h"
#include "BCGPMDIFrameWnd.h"
#include "BCGPOleIPFrameWnd.h"
#include "BCGPOleDocIPFrameWnd.h"
#include "BCGPMDIChildWnd.h"
#include "BCGPOleCntrFrameWnd.h"

#include "BCGPControlBar.h"
#include "BCGPDockBarRow.h"
#include "BCGPReBar.h"

#include "BCGPGlobalUtils.h"

#include "BCGPDockBar.h"

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

IMPLEMENT_DYNCREATE(CBCGPDockBar, CBCGPBaseControlBar)

/////////////////////////////////////////////////////////////////////////////
// CBCGPDockBar

CBCGPDockBar::CBCGPDockBar() : m_nDockBarID (0)
{
}

CBCGPDockBar::~CBCGPDockBar()
{
	while (!m_lstDockBarRows.IsEmpty ())
	{
		delete m_lstDockBarRows.RemoveHead ();
	}
}


BEGIN_MESSAGE_MAP(CBCGPDockBar, CBCGPBaseControlBar)
	//{{AFX_MSG_MAP(CBCGPDockBar)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_CONTEXTMENU()
	ON_WM_NCDESTROY()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CBCGPDockBar message handlers

BOOL CBCGPDockBar::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, DWORD dwBCGStyle, CCreateContext* pContext) 
{
	ASSERT_VALID (this);
	return CBCGPDockBar::CreateEx (0, dwStyle, rect, pParentWnd, dwBCGStyle, pContext);
}
//----------------------------------------------------------------------------------//
BOOL CBCGPDockBar::CreateEx(DWORD dwStyleEx, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, DWORD dwBCGStyle, CCreateContext* pContext) 
{
	ASSERT_VALID (this);

	DWORD dwEnableAlignment = GetEnabledAlignment ();
	EnableDocking (dwEnableAlignment | dwStyle);

	SetBarAlignment (dwStyle);

	dwStyle |= WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPED;
	dwStyleEx = WS_EX_LEFT;

	//-----------------------------
	// Register a new window class:
	//-----------------------------
	HINSTANCE hInst = AfxGetInstanceHandle();
	UINT uiClassStyle = CS_DBLCLKS;
	HCURSOR hCursor = ::LoadCursor (NULL, IDC_ARROW);
	HBRUSH hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);

	CString strClassName;
	strClassName.Format (_T("BCGDockBar:%x:%x:%x:%x"), 
		(UINT)hInst, uiClassStyle, (UINT)hCursor, (UINT)hbrBackground);

	//---------------------------------
	// See if the class already exists:
	//---------------------------------
	WNDCLASS wndcls;
	if (::GetClassInfo (hInst, strClassName, &wndcls))
	{
		//-----------------------------------------------
		// Already registered, assert everything is good:
		//-----------------------------------------------
		ASSERT (wndcls.style == uiClassStyle);
	}
	else
	{
		//-------------------------------------------
		// Otherwise we need to register a new class:
		//-------------------------------------------
		wndcls.style = uiClassStyle;
		wndcls.lpfnWndProc = ::DefWindowProc;
		wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
		wndcls.hInstance = hInst;
		wndcls.hIcon = NULL;
		wndcls.hCursor = hCursor;
		wndcls.hbrBackground = hbrBackground;
		wndcls.lpszMenuName = NULL;
		wndcls.lpszClassName = strClassName;
		
		if (!AfxRegisterClass (&wndcls))
		{
			AfxThrowResourceException();
		}
	}

	// Align the bar along borders; initially, create the dock bar with zero height/width
	CRect rectDockBar = rect;

	CRect rectParent;
	pParentWnd->GetClientRect (&rectParent);

	rectDockBar = rectParent;

	switch (GetCurrentAlignment ())
	{
	case CBRS_ALIGN_LEFT:
		rectDockBar.right = 0;
		m_nDockBarID = AFX_IDW_DOCKBAR_LEFT;
		break;

	case CBRS_ALIGN_RIGHT:
		rectDockBar.left = rectParent.right;
		m_nDockBarID = AFX_IDW_DOCKBAR_RIGHT;
		break;

	case CBRS_ALIGN_TOP:
		rectDockBar.bottom = rectParent.top;
		m_nDockBarID = AFX_IDW_DOCKBAR_TOP;
		break;

	case CBRS_ALIGN_BOTTOM:
		rectDockBar.top  = rectParent.bottom;
		m_nDockBarID = AFX_IDW_DOCKBAR_BOTTOM;
		break;
	}

	m_dwBCGStyle = dwBCGStyle;
	m_pDockSite = pParentWnd;

	return CWnd::CreateEx (dwStyleEx, strClassName, NULL, dwStyle, rectDockBar, pParentWnd, m_nDockBarID, pContext);
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::AlignDockBar (const CRect& rectToAlignBy, CRect& rectResult, 
								  BOOL bMoveImmediately)
{
	ASSERT_VALID (this);
	if (rectResult.IsRectEmpty ())
	{
		GetWindowRect (rectResult);
	}

	CRect rectOld;
	GetWindowRect (rectOld);

	int nCurrWidth = rectResult.Width ();
	int nCurrHeight = rectResult.Height ();

	switch (GetCurrentAlignment ())
	{
	case CBRS_ALIGN_LEFT:
		rectResult.TopLeft () = rectToAlignBy.TopLeft ();
		rectResult.bottom = rectResult.top + rectToAlignBy.Height ();
		rectResult.right = rectResult.left + nCurrWidth;
		break;

	case CBRS_ALIGN_TOP:
		rectResult.TopLeft () = rectToAlignBy.TopLeft ();
		rectResult.right = rectResult.left + rectToAlignBy.Width ();
		rectResult.bottom = rectResult.top + nCurrHeight;
		break;

	case CBRS_ALIGN_RIGHT:
		rectResult.BottomRight () = rectToAlignBy.BottomRight ();
		rectResult.top = rectResult.bottom - rectToAlignBy.Height ();
		rectResult.left = rectResult.right - nCurrWidth;
		break;
	case CBRS_ALIGN_BOTTOM:
		rectResult.BottomRight () = rectToAlignBy.BottomRight ();
		rectResult.left = rectResult.right - rectToAlignBy.Width ();
		rectResult.top = rectResult.bottom - nCurrHeight;	
		break;
	}

	if (rectResult != rectOld && bMoveImmediately)
	{
		CRect rectNew = rectResult;
		ASSERT_VALID (GetParent ());
		GetParent ()->ScreenToClient (rectNew);

		OnSetWindowPos (&wndBottom, rectNew, SWP_NOACTIVATE | SWP_NOZORDER);
	}
}
//----------------------------------------------------------------------------------//
// Moves control bar within row; floats the bar or moves it to an adjustent row 
// if the bar' virtual rectangle is being moved out of row beyond a limit
//----------------------------------------------------------------------------------//
BOOL CBCGPDockBar::MoveControlBar (CBCGPControlBar* pControlBar, UINT /*nFlags*/, 
									CPoint ptOffset)
{
	ASSERT_VALID (this);
	ASSERT_VALID (pControlBar);

	CBCGPDockBarRow* pRow = pControlBar->GetDockBarRow ();
	ASSERT_VALID (pRow);

	CRect rectVirtual;
	pControlBar->GetVirtualRect (rectVirtual);

	// where the virtual rectangle will be if it's moved according to ptOffset
	rectVirtual.OffsetRect (ptOffset);
	
	CPoint ptMouse;
	GetCursorPos (&ptMouse);

	CRect rectRow;
	pRow->GetWindowRect (rectRow);

	CPoint ptDelta (0, 0);

	// check whether the control bar should change its state from docked to floated
	CBCGPBaseControlBar* pDockBar = NULL;
	
	if (pControlBar->IsChangeState (15, &pDockBar))
	{
		pControlBar->UpdateVirtualRect (ptOffset);
		pControlBar->GetVirtualRect (rectVirtual);
		pControlBar->FloatControlBar (rectVirtual, DM_MOUSE);
		return TRUE; // indicates that the bar was floated and shouldn't be moved anymore within the dock bar
	}

	bool bOuterRow = false;
	CBCGPDockBarRow* pNextRow = RowFromPoint (rectVirtual.CenterPoint (), bOuterRow);
	
	int nBaseLineOffset = 0;
	int nOffsetLimit = 0;

	if (IsHorizontal ())
	{
		nBaseLineOffset = min (rectRow.bottom - rectVirtual.bottom, rectRow.top - rectVirtual.top);
		nOffsetLimit = rectVirtual.Height () * 2 / 3; // / 2;
	}
	else
	{
		nBaseLineOffset = min (rectRow.right - rectVirtual.right, rectRow.left - rectVirtual.left);
		nOffsetLimit = rectVirtual.Width () * 2 /3 ; // / 2;
	}

	if (abs (nBaseLineOffset) > nOffsetLimit)
	{
		if (pRow->GetBarCount () > 1  && nBaseLineOffset < pRow->GetRowHeight ())
		{
			// the bar should be put on the separate row, find a position to insert the row
			POSITION pos = m_lstDockBarRows.Find (pRow);
			ASSERT (pos != NULL);

			if (nBaseLineOffset < 0) // moving down - find the next visible row
			{
				// the new row should be inserted before next visible row
				FindNextVisibleRow (pos);
			}
			// otherwise the new row will be inserted before the current row 
			// (that's visible for sure) by AddRow (it inserts a row before spec. pos).

			pRow->RemoveControlBar (pControlBar);	
			CBCGPDockBarRow* pNewRow = 
					AddRow (pos, IsHorizontal () ? rectVirtual.Height () : rectVirtual.Width ());
			pNewRow->AddControlBarFromRow (pControlBar, DM_MOUSE);	

			return FALSE;
		}
		else if (pRow != pNextRow && pNextRow != NULL)
		{
			ASSERT_VALID (pNextRow);
			//the bar is moved from the separate row to adjustent row (if exist)
			
			if (pRow->IsExclusiveRow ())
			{
				SwapRows (pNextRow, pRow);
			}
			else
			{
				if (pNextRow->IsExclusiveRow ())
				{
					SwapRows (pRow, pNextRow);
				}
				else
				{
					pRow->RemoveControlBar (pControlBar);	
					pNextRow->AddControlBarFromRow (pControlBar, DM_MOUSE);
				}
			}
			
			pControlBar->m_bDisableMove = true;
			return FALSE;
		}
		
	}
	// just move the bar within the row
	if (abs (nBaseLineOffset) < rectRow.Height ())
	{
		HDWP hdwp = BeginDeferWindowPos (pRow->GetBarCount ());
		pRow->MoveControlBar (pControlBar, ptOffset, TRUE, hdwp);
		EndDeferWindowPos (hdwp);
		return FALSE;
	}
	return FALSE;		
}
//----------------------------------------------------------------------------------//
CBCGPDockBarRow* CBCGPDockBar::FindNextVisibleRow (POSITION& pos, BOOL bForward)
{
	if (m_lstDockBarRows.IsEmpty ())
	{
		pos = NULL;
		return NULL;
	}

	if (pos == NULL)
	{
		pos = bForward  ? m_lstDockBarRows.GetHeadPosition () 
						: m_lstDockBarRows.GetTailPosition ();
	}
	else
	{
		// we need to skip to the next / prev row from the current position
		bForward ? m_lstDockBarRows.GetNext (pos) : m_lstDockBarRows.GetPrev (pos);
	}

	while (pos != NULL)
	{
		POSITION posSave = pos;	
		CBCGPDockBarRow* pRow = (CBCGPDockBarRow*) 
									(bForward ? m_lstDockBarRows.GetNext (pos) 
											  : m_lstDockBarRows.GetPrev (pos));
		ASSERT_VALID (pRow);

		if (pRow->IsVisible ())
		{
			pos = posSave;
			return pRow;
		}
	}

	return NULL;
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType) 
{
	ASSERT_VALID (this);
	
	CWnd::CalcWindowRect(lpClientRect, nAdjustType);
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::DockControlBar (CBCGPControlBar* pControlBar, BCGP_DOCK_METHOD dockMethod, 
								    LPCRECT lpRect)
{
	ASSERT_VALID (this);
	ASSERT_VALID (pControlBar);

	CRect rectDockArea; rectDockArea.SetRectEmpty ();
	if (lpRect != NULL)
	{
		rectDockArea = lpRect;
	}

	BOOL bVertDock = !IsHorizontal ();
	CSize szBarSize = pControlBar->CalcFixedLayout (FALSE, !bVertDock);

	if (!m_lstControlBars.Find (pControlBar))
	{
		CBCGPDockBarRow* pRowToDock = NULL;
		bool bOuterRow = false;

		if (dockMethod == DM_MOUSE)
		{
			// calculate from which side the control bar is coming, using mouse cursor position.
			// the default bar width (for side bars) and height (for top/bottom bars)
			// is 30 for this example

			CPoint ptMouse;
			GetCursorPos (&ptMouse);

			CRect rectDockBar;
			GetWindowRect (&rectDockBar);

			// get pointer to the row on which the bar should be placed
			pRowToDock = RowFromPoint (ptMouse, bOuterRow);
		}
		else if (dockMethod == DM_DBL_CLICK || dockMethod == DM_RECT)
		{
			if (dockMethod == DM_DBL_CLICK && 
				m_lstDockBarRows.Find (pControlBar->m_recentDockInfo.m_pRecentDockBarRow) != NULL)
			{
				pRowToDock = pControlBar->m_recentDockInfo.m_pRecentDockBarRow;
			}
			else
			{
				int nRowCount = m_lstDockBarRows.GetCount ();

				if (CBCGPDockManager::m_bRestoringDockState)
				{
					if (pControlBar->m_recentDockInfo.m_nRecentRowIndex > nRowCount - 1)
					{
						for (int i = 0;  
							 i < pControlBar->m_recentDockInfo.m_nRecentRowIndex - nRowCount + 1; i++)
						{
							AddRow (NULL, bVertDock ? szBarSize.cx : szBarSize.cy);
						}
					}

					POSITION posRow = m_lstDockBarRows.FindIndex (pControlBar->m_recentDockInfo.m_nRecentRowIndex);
					pRowToDock = (CBCGPDockBarRow*) m_lstDockBarRows.GetAt (posRow);
				}
				else
				{
					if (pControlBar->m_recentDockInfo.m_nRecentRowIndex < nRowCount && 
						dockMethod == DM_DBL_CLICK)
					{
						POSITION pos = m_lstDockBarRows.FindIndex (pControlBar->m_recentDockInfo.m_nRecentRowIndex);
						pRowToDock = (CBCGPDockBarRow*) m_lstDockBarRows.GetAt (pos);
					}
					else if (dockMethod == DM_DBL_CLICK && 
							 !pControlBar->m_recentDockInfo.m_recentSliderInfo.m_rectDockedRect.IsRectEmpty ())
					{
						pRowToDock = FindRowByRect (pControlBar->m_recentDockInfo.m_recentSliderInfo.m_rectDockedRect);
					}
					else if (dockMethod == DM_RECT && lpRect != NULL)
					{
						pRowToDock = FindRowByRect (lpRect);
					}
				}

				if (pRowToDock == NULL)
				{
					AddRow (NULL, bVertDock ? szBarSize.cx : szBarSize.cy);
					pRowToDock = (CBCGPDockBarRow*) m_lstDockBarRows.GetTail ();
				}
			}

			ASSERT_VALID (pRowToDock);

⌨️ 快捷键说明

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