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

📄 dockpagebar.cpp

📁 主要用在管理系统,一个工程维护管理用vc++ 8.0 accesss数据库
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 

void CDockPageBar::OnNcLButtonDown(UINT nFlags, CPoint point) 
{
	UINT nItemIndex=0;
	POSITION pos;
	CPageItem *pItem;
	CRect rect;

	//Note: Here the rect coordinate is for NonClient painting,
	//      so it is referenced to the current window's topleft.
	GetWindowRect(&rect);
	point.Offset(-rect.TopLeft());
	if (HTITEMBUTTON==nFlags){
		for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
		{
			pItem=(CPageItem*)m_PageList.GetNext(pos);
			if(pItem)
			{
				if(pItem->m_rect.PtInRect(point))
				{
					SetFocus();
					SetActivePage(nItemIndex);
					CanDrag(point);			// drag PageItem
					return;
				}
			}
		}	
	}

	//Note: Here the rect coordinate is referenced to the screen
	point.Offset(rect.TopLeft());

	if ((nFlags >= HTSIZEFIRST) && (nFlags <= HTSIZELAST))
	{
		baseCDockPageBar::OnNcLButtonDown(nFlags, point);	
		return;
	}


	((CDockPageBarContext*)m_pDockContext)->m_isPage = FALSE;
	if (m_pDockBar != NULL&&HTGRIPPER==nFlags)
    {
        // start the drag
		SetFocus();
        ASSERT(m_pDockContext != NULL);
        m_pDockContext->StartDrag(point);
    }
    else
        CWnd::OnNcLButtonDown(nFlags, point);

}
void CDockPageBar::OnNcLButtonDblClk(UINT nFlags, CPoint point)
{
	if (HTGRIPPER==nFlags&&m_pDockBar != NULL)
	{
		// start the drag
		ASSERT(m_pDockContext != NULL);
		m_pDockContext->ToggleDocking();
	}
	else
		CWnd::OnNcLButtonDblClk(nFlags, point);
}
void CDockPageBar::EnableDocking(DWORD dwDockStyle)
{
	// must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
    ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
    // cannot have the CBRS_FLOAT_MULTI style
    ASSERT((dwDockStyle & CBRS_FLOAT_MULTI) == 0);
    // the bar must have CBRS_SIZE_DYNAMIC style
    ASSERT((m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);
	
    m_dwDockStyle = dwDockStyle;
    if (m_pDockContext == NULL)
    {
		m_pDockContext = new CDockPageBarContext(this);
		m_pDPBContext.AddTail(m_pDockContext);	//hengai
	}
	
    // permanently wire the bar's owner to its current parent
    if (m_hWndOwner == NULL)
        m_hWndOwner = ::GetParent(m_hWnd);
}

void CDockPageBar::CanDrag(CPoint pt)
{
	SetCapture();
	// get messages until capture lost or cancelled/accepted
	while (CWnd::GetCapture() == this)
	{
		MSG msg;
		if (!::GetMessage(&msg, NULL, 0, 0))
		{
			AfxPostQuitMessage(msg.wParam);
			break;
		}
		switch (msg.message)
		{
		case WM_LBUTTONUP:			
			ReleaseCapture();
			break;
		case WM_MOUSEMOVE:
			Move(msg.pt);
			break;
		default:
			DispatchMessage(&msg);
			break;
		}
	}
}

void CDockPageBar::Move(CPoint pt)
{
	CRect rect,wndRect;

	//Note: Here the rect coordinate is for NonClient painting,
	//      so it is referenced to the current window's topleft.

	GetWindowRect(&wndRect);
	GetItemGroupRect(&rect);
	rect.OffsetRect(-wndRect.TopLeft());
	pt.Offset(-wndRect.TopLeft());

	if(rect.PtInRect(pt))
	{
		int nItemIndex=0;
		POSITION pos;
		CPageItem *pItem;
		for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
		{
			pItem=(CPageItem*)m_PageList.GetNext(pos);
			if(pItem)
			{
				if(pItem->m_rect.PtInRect(pt))
				{
					if(nItemIndex != m_nActivePage)
					{
						POSITION oldPos = m_PageList.FindIndex(m_nActivePage);
						POSITION curPos = m_PageList.FindIndex(nItemIndex);
						CPageItem *pOldItem = (CPageItem*)m_PageList.GetAt(oldPos);
						// exchange PageItem
						m_PageList.SetAt(oldPos, pItem);
						m_PageList.SetAt(curPos, pOldItem);

						m_nActivePage = nItemIndex;
						UpdateWindow();
						break;
					}
				}
			}
		}
	}
	else
	{
		ReleaseCapture();
		StartDrag(pt);
	}
}

void CDockPageBar::StartDrag(CPoint pt)
{
	ClientToScreen(&pt);
	((CDockPageBarContext*)m_pDockContext)->m_isPage = TRUE;
	m_pDockContext->StartDrag(pt);
	((CDockPageBarContext*)m_pDockContext)->m_isPage = FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CDockPageBarContext

#define _AfxGetDlgCtrlID(hWnd)          ((UINT)(WORD)::GetDlgCtrlID(hWnd))

#define CX_BORDER   1
#define CY_BORDER   1

#define CBRS_ALIGN_INSERT_PAGE				0x0001L	// drag to another CDockPageBar
#define HORZF(dw) (dw & CBRS_ORIENT_HORZ)
#define VERTF(dw) (dw & CBRS_ORIENT_VERT)

 static void AFXAPI _AfxAdjustRectangle(CRect& rect, CPoint pt)
{
	int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
					(pt.x > rect.right) ? (pt.x - rect.right) : 0;
	int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
					(pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
	rect.OffsetRect(nXOffset, nYOffset);
}

void CDockPageBarContext::StartDrag(CPoint pt)
{
	ASSERT_VALID(m_pBar);
	m_bDragging = TRUE;

	InitLoop();

	// GetWindowRect returns screen coordinates(not mirrored),
	// so if the desktop is mirrored then turn off mirroring
	// for the desktop dc so that we get correct focus rect drawn.
	// This layout change should be remembered, just in case ...

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

	if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
	{
		// get true bar size (including borders)
		CRect rect;
		m_pBar->GetWindowRect(rect);
		m_ptLast = pt;
		CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
		CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
		CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);

		m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
		m_rectDragVert = CRect(rect.TopLeft(), sizeVert);

		// calculate frame dragging rectangle
		m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);
		m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat);

		CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
		CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);

		m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
		m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
	}
	else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED)
	{
		// get true bar size (including borders)
		CRect rect;
		m_pBar->GetWindowRect(rect);
		m_ptLast = pt;
		CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK);
		CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK);

		// calculate frame dragging rectangle
		m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
		m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert);

		CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
		CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
		m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
		m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
	}
	else
	{
		// get true bar size (including borders)
		CRect rect;
		m_pBar->GetWindowRect(rect);
		m_ptLast = pt;
		BOOL bHorz = HORZF(m_dwStyle);
		DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK;
		CSize size = m_pBar->CalcDynamicLayout(-1, dwMode);

		// calculate inverted dragging rect
		if (bHorz)
		{
			m_rectDragHorz = rect;
			m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size);
		}
		else // vertical orientation
		{
			m_rectDragVert = rect;
			m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size);
		}

		// calculate frame dragging rectangle
		m_rectFrameDragHorz = m_rectDragHorz;
		m_rectFrameDragVert = m_rectDragVert;

		CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
		CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
		m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
		m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
	}

	// adjust rectangles so that point is inside
	_AfxAdjustRectangle(m_rectDragHorz, pt);
	_AfxAdjustRectangle(m_rectDragVert, pt);
	_AfxAdjustRectangle(m_rectFrameDragHorz, pt);
	_AfxAdjustRectangle(m_rectFrameDragVert, pt);

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

CDockPageBarContext::~CDockPageBarContext(void)
{

}

//hengai
void CDockPageBarContext::FreeAll()
{
	for(POSITION pos = m_pDPBar.GetHeadPosition(); pos;)
	{
		CDockPageBar* pBar = (CDockPageBar*)m_pDPBar.GetNext(pos);
		ASSERT(pBar != NULL);
		delete pBar->m_pDockBar; pBar->m_pDockBar = NULL;
		delete pBar; pBar = NULL;
	}
	
	m_pDPBar.RemoveAll ();		// cuick 2004/04/08
}

BOOL CDockPageBarContext::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;
}
CDockPageBar * CDockPageBarContext::TryToGetDockPageBar(POINT pt)
{
	CFrameWnd * pFrameWnd=(CFrameWnd *)AfxGetMainWnd();

	POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
	while (pos != NULL)
	{
		CControlBar* pBar = (CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
		ASSERT(pBar != NULL);
		if (pBar->IsKindOf(RUNTIME_CLASS(CDockPageBar)))
		{
			CRect rect;
			pBar->GetWindowRect(&rect);
			if(rect.PtInRect(pt)&&!pBar->IsFloating())
				return (CDockPageBar*)pBar;
		}
	}
	return NULL;
}
//////////////////////////////////////////////////////////////////////
// drag and draw focus rect
void CDockPageBarContext::Move(CPoint pt)
{
	CPoint ptOffset = pt - m_ptLast;

	if(TRUE == isDockPage(pt))
	{
		m_dwOverDockStyle = CBRS_ALIGN_INSERT_PAGE;
	}
	else
	{

		//MACRO Definition for the adavnced docking
		//#define CBRS_ALIGN_INSERT_PAGE				0x0001L	
#define DOCK_ALIGN_INSERT_PAGE		CBRS_ALIGN_INSERT_PAGE
#define DOCK_IN_FRAME_CLIENT  0x02
#define DOCK_IN_FRAME_BORDER  0x04
#define DOCK_IN_DOCK_PAGE_BAR 0x08

#define HOR_BORDER_DETECT_PIXELS  max(CAPTION_HEIGHT+8,ITEMBUTTON_HEIGHT+8)
#define VER_BORDER_DETECT_PIXELS  16

#define BORDER_DETECT_LEFT   0x0100
#define BORDER_DETECT_RIGHT  0x0200
#define BORDER_DETECT_TOP    0x0400
#define BORDER_DETECT_BOTTOM 0x0800

		//POINT pt;
		//GetCursorPos(&pt);
		CWnd *pCurWnd= CWnd::FromHandle(::WindowFromPoint(pt));
		CDockPageBar *pDockPageBarWnd;

		DWORD borderDetect=0;
		CRect mainFrameRect,mainFrameClientRect;
		DWORD dwDockStyle=0;
		m_bAdvancedDock=FALSE;
		m_endDragDockStruct.dwDockStyle=0;

		CWnd *pMainFrameWnd=AfxGetMainWnd();

		pMainFrameWnd->GetWindowRect(&mainFrameRect);

		//Try to find a docking position
		if(mainFrameRect.PtInRect(pt))
		{
			//Get the pure client rect of the frame wnd
			GET_MAIN_FRAME_PURE_CLIENT(pMainFrameWnd,mainFrameClientRect);

			if((pDockPageBarWnd=TryToGetDockPageBar(pt))!=NULL){
				pDockPageBarWnd->GetWindowRect(&m_curRect);
				m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_DOCK_PAGE_BAR;
				m_bAdvancedDock=TRUE;
			}else if(mainFrameClientRect.PtInRect(pt)){
				m_curRect=mainFrameClientRect;
				m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_CLIENT;
				m_bAdvancedDock=TRUE;
			}else{ //the bar is move to the non client area (tool bar for example)

				CRect rc=mainFrameClientRect;
				
				rc.DeflateRect(-VER_BORDER_DETECT_PIXELS,-HOR_BORDER_DETECT_PIXELS);
				if(rc.PtInRect(pt)){
					m_curRect=rc;
					m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_BORDER;
					m_bAdvancedDock=TRUE;
				}else{
					const CRuntimeClass * pRunTimeClass=pCurWnd->GetRuntimeClass();
					TRACE0("Unprocessed window type:");
					TRACE0(pRunTimeClass->m_lpszClassName);
					TRACE0("\r\n");
					m_bAdvancedDock=FALSE;
				}
			}
		}else{
			CRect rc=mainFrameRect;

			rc.DeflateRect(-VER_BORDER_DETECT_PIXELS,-HOR_BORDER_DETECT_PIXELS);
			if(rc.PtInRect(pt)){
				m_curRect=rc;
				m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_BORDER;
				m_bAdvancedDock=TRUE;
			}else{
				const CRuntimeClass * pRunTimeClass=pCurWnd->GetRuntimeClass();
				TRACE0("Unprocessed window type:");
				TRACE0(pRunTimeClass->m_lpszClassName);
				TRACE0("\r\n");
				m_bAdvancedDock=FALSE;
			}
		}

		//Check whether the current position can be used for the advanced docking :-)
		if(m_bAdvancedDock&&
		   m_curRect.Width()>VER_BORDER_DETECT_PIXELS*2+1&&
		   m_curRect.Height()>HOR_BORDER_DETECT_PIXELS*2+1)
		{		    
			//Init the current detection border rect 
			CRect rectLeft(m_curRect.TopLeft(),CSize(VER_BORDER_DETECT_PIXELS,m_curRect.Height())),
				  rectTop(m_curRect.TopLeft(),CSize(m_curRect.Width(),HOR_BORDER_DETECT_PIXELS));
		    CRect rectRight=rectLeft,rectBottom=rectTop;

			rectRight.OffsetRect(m_curRect.Width()-VER_BORDER_DETECT_PIXELS,0);
			rectBottom.OffsetRect(0,m_curRect.Height()-HOR_BORDER_DETECT_PIXELS);

			borderDetect|=rectLeft.PtInRect(pt) ?   BORDER_DETECT_LEFT:0;
			borderDetect|=rectRight.PtInRect(pt) ?  BORDER_DETECT_RIGHT:0;
			borderDetect|=rectTop.PtInRect(pt) ?    BORDER_DETECT_TOP:0;
			borderDetect|=rectBottom.PtInRect(pt) ? BORDER_DETECT_BOTTOM:0;

⌨️ 快捷键说明

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