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

📄 menubar.cpp

📁 一个很好的LFP规约调试器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			int dx = pItem->m_sizeHorz.cx;
			if (dx + CXGAP > nWidth) {		// bigger than nWidth
				if (pItem->CanWrap()) {
					pItem->m_bWrapped = TRUE;
//					if (i != nCount - 1)
						++nResult;
				}
			}
			else if (dx + x + CXGAP > nWidth) {
				if (i > 0 && m_arrItem[i-1]->CanWrap()) {
			//		LTRACE("index %d is wrap\n", i-1);
					m_arrItem[i-1]->m_bWrapped = TRUE;
					pItem->m_bWrapped = FALSE;
					x = xStart;
//					if (i != nCount - 1)///////////////////////////
						++nResult;
				}
			}
			else {
				pItem->m_bWrapped = FALSE;
			}
			x += dx;

		}
	}
	*/

	return nResult + 1;
}

// calc only size, by using m_bWrapped
CSize CMenuBar::CalcSize(int nCount)
{
	ASSERT(nCount > 0);
	CPoint cur(CXGAP, CYGAP);
	CSize sizeResult(0, 0);
	int nWrap = 0;
	for (int i = 0; i < nCount; ++i) {
		CMenuItem* pItem = m_arrItem[i];
		if (pItem->IsValid()) {
			sizeResult.cx = max(cur.x + pItem->m_sizeHorz.cx, sizeResult.cx);
			sizeResult.cy = max(cur.y + pItem->m_sizeHorz.cy, sizeResult.cy);

			cur.x += pItem->m_sizeHorz.cx;
			
			if (pItem->m_bWrapped == TRUE) {
				LTRACE("    nIndex:%d is wrapped\n", i);
				cur.x = CXGAP;					// reset x pos
				cur.y += pItem->m_sizeHorz.cy;
				++nWrap;
			}

		}
	}

	sizeResult.cy += CYGAP;
	sizeResult.cx += CXGAP;
	return sizeResult;
}

void CMenuBar::SizeMenuBar(int nCount, int nLength, BOOL bVert)
{
	//LTRACE("CMenuBar::SizeMenuBar\n");
	ASSERT(nCount > 0);

	if (!bVert) {				// nLength is horizontal length

		if (IsFloating()) {		// half size wrapping

			CSize sizeMax, sizeMin, sizeMid;

			// Wrap MenuBar vertically
			WrapMenuBar(nCount, 0);
			sizeMin = CalcSize(nCount);

			// Wrap MenuBar horizontally
			WrapMenuBar(nCount, 32767);
			sizeMax = CalcSize(nCount);

			// we can never know this algorithm :), see CToolBar implementation
			while (sizeMin.cx < sizeMax.cx) {
//				LTRACE("looping sizeMin.cx:%d < sizeMax.cx:%d\n", sizeMin.cx, sizeMax.cx);
				sizeMid.cx = (sizeMin.cx + sizeMax.cx) / 2;
				WrapMenuBar(nCount, sizeMid.cx);
				sizeMid = CalcSize(nCount);
				if (sizeMid.cx == sizeMax.cx) {	// if you forget, it loops forever!
					return;
				}
//				LTRACE("    sizeMid : %d %d\n", sizeMid.cx, sizeMid.cy);

				if (nLength >= sizeMax.cx) {
//					LTRACE("    nLength:%d >= sizeMax.cx:%d\n", nLength, sizeMax.cx);
					if (sizeMin == sizeMid) {
						WrapMenuBar(nCount, sizeMax.cx);
//						LTRACE("out SizeMenuBar\n");
						return;
					}
					sizeMin = sizeMid;
				}
				else if (nLength < sizeMax.cx) {
//					LTRACE("    nLength:%d < sizeMax.cx:%d\n", nLength, sizeMax.cx);
					sizeMax = sizeMid;
				}
				else {
//					LTRACE("out SizeMenuBar\n");
					return;
				}
			}
		}
		else {								// each one wrapping
			LTRACE("    just each one wrapping\n");
			WrapMenuBar(nCount, nLength);
		}
	}
	else {						// nLength is vertical length
		CSize sizeMax, sizeMin, sizeMid;

		// Wrap MenuBar vertically
		WrapMenuBar(nCount, 0);
		sizeMin = CalcSize(nCount);

		// Wrap MenuBar horizontally
		WrapMenuBar(nCount, 32767);
		sizeMax = CalcSize(nCount);

		while (sizeMin.cx < sizeMax.cx) {
			sizeMid.cx = (sizeMin.cx + sizeMax.cx) / 2;
			WrapMenuBar(nCount, sizeMid.cx);
			sizeMid = CalcSize(nCount);
			if (sizeMid.cx == sizeMax.cx) {
				return;
			}
			if (nLength < sizeMid.cy) {
				if (sizeMin == sizeMid) {
					WrapMenuBar(nCount, sizeMax.cx);
					//LTRACE("out SizeMenuBar\n");
					return;
				}
				sizeMin = sizeMid;
			}
			else if (nLength > sizeMid.cy)
				sizeMax = sizeMid;
			else {
				//LTRACE("out SizeMenuBar\n");
				return;
			}
		}
	}

	//LTRACE("out SizeMenuBar\n");
}


void CMenuBar::DeleteItems()
{
	for(int i = 0; i < m_arrItem.GetSize(); ++i) {
		CMenuItem* pItem = m_arrItem[i];
		delete pItem;
	}

	m_arrItem.RemoveAll();

	m_pMenuIcon = NULL;
	m_pMenuControl = NULL;
}

void CMenuBar::OnDestroy() 
{
	CControlBar::OnDestroy();
	
	// TODO: 偙偺埵抲偵儊僢僙乕僕 僴儞僪儔梡偺僐乕僪傪捛壛偟偰偔偩偝偄
	_KillTimer();
	DeleteItems();
}

int CMenuBar::GetNextOrPrevButton(int nIndex, BOOL bPrev)
{
	int nCount = GetItemCount();
	if (bPrev) {				// <-
		--nIndex;
		if (nIndex < 0)
			nIndex = nCount - 1;
	}
	else {						// ->
		++nIndex;
		if (nIndex >= nCount)
			nIndex = 0;
	}

	if (!m_arrItem[nIndex]->CanTrack() || !m_arrItem[nIndex]->IsValid()) {
		return GetNextOrPrevButton(nIndex, bPrev);
	}

	return nIndex;
}

void CMenuBar::AddIcon(HICON hIcon)
{
//	ASSERT(m_bIcon == FALSE);

//	m_bIcon = TRUE;
}

CMenuControl::CMenuControl(CControlBar* pBar)
{
	m_bValid = FALSE;
	m_pBar = pBar;
	m_bDown = FALSE;
	m_nTracking = -1;

	int cxCaption = cyMenuButton - CYGAP + 1;
	m_sizeHorz = CSize(cxCaption*3 + CXGAP/2, cyMenuButton);
}

CMenuControl::~CMenuControl()
{

}

void CMenuControl::Update(CDC* pDC)
{
	// do nothing
}

void CMenuControl::Layout(CPoint point, BOOL bHorz)
{
	LTRACE("CMenuControl::Layout bHorz:%d\n", bHorz);
	m_bHorz = bHorz;

	// just layout easily
	if (bHorz) {
		m_rcItem = CRect(point, m_sizeHorz);
	}
	else {
		m_rcItem = CRect(point, CSize(m_sizeHorz.cy, m_sizeHorz.cx));
	}
}

void CMenuControl::DelayLayoutAndDraw(CDC* pDC, CSize sizeBar)
{
//	if (!IsValid())
//		return;

	// layout
	if (m_bHorz) {
		int cxCaption = cyMenuButton - CYGAP + 1;
		int cyCaption = cxCaption - 1;
		CRect rcCaption;
		rcCaption.right = sizeBar.cx;
		rcCaption.bottom = sizeBar.cy - CYGAP;
		rcCaption.left = rcCaption.right - cxCaption;
		rcCaption.top = rcCaption.bottom - cyCaption;

		m_arrCaption[0] = rcCaption;

		rcCaption -= CPoint(cxCaption+CXGAP/2, 0);
		m_arrCaption[1] = rcCaption;

		rcCaption -= CPoint(cxCaption, 0);
		m_arrCaption[2] = rcCaption;

		m_rcItem = CRect(m_arrCaption[2].left, m_arrCaption[2].top,
			m_arrCaption[0].right, m_arrCaption[0].bottom);
	}
	else {
		int cxCaption = cyMenuButton - CYGAPVERT - 1;
		int cyCaption = cxCaption - 1;
		CRect rcCaption;
		rcCaption.left = CYGAPVERT;
		rcCaption.bottom = sizeBar.cy;
		rcCaption.right = rcCaption.left + cxCaption;
		rcCaption.top = rcCaption.bottom - cyCaption;

		m_arrCaption[0] = rcCaption;	

		rcCaption -= CPoint(0, cyCaption+CXGAP/2);
		m_arrCaption[1] = rcCaption;

		rcCaption -= CPoint(0, cyCaption);
		m_arrCaption[2] = rcCaption;

		m_rcItem = CRect(m_arrCaption[2].left, m_arrCaption[2].top,
			m_arrCaption[0].right, m_arrCaption[0].bottom);
	}

	if (!IsValid())
		return;

	// draw frame controls
	for (int i = 0; i < 3; ++i) {
		DrawControl(pDC, i, FALSE);
	}

//	pDC->DrawFrameControl(m_arrCaption[0], DFC_CAPTION, DFCS_CAPTIONCLOSE);
//	pDC->DrawFrameControl(m_arrCaption[1], DFC_CAPTION, DFCS_CAPTIONRESTORE);
//	pDC->DrawFrameControl(m_arrCaption[2], DFC_CAPTION, DFCS_CAPTIONMIN);		
}


// pasted from CDockContext
void CMenuBarDockContext::StartDrag(CPoint pt)
{
	ASSERT_VALID(m_pBar);
	m_bDragging = TRUE;

	InitLoop();

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

#ifdef _MAC
		CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz,
			WS_THICKFRAME | WS_CAPTION, WS_EX_FORCESIZEBOX);
		CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert,
			WS_THICKFRAME | WS_CAPTION, WS_EX_FORCESIZEBOX);
#else
		CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
		CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
#endif
		m_rectFrameDragHorz.InflateRect(-cxBorder2, -cyBorder2);
		m_rectFrameDragVert.InflateRect(-cxBorder2, -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(-cxBorder2, -cyBorder2);
		m_rectFrameDragVert.InflateRect(-cxBorder2, -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(-cxBorder2, -cyBorder2);
		m_rectFrameDragVert.InflateRect(-cxBorder2, -cyBorder2);
	}

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

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

BOOL CMenuBarDockContext::_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());

#ifndef _MAC
	// 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;
		}
	}
#else
	Point   ptCur = {0};

	// get messages until capture lost or cancelled/accepted
	while (CWnd::GetCapture() == m_pBar)
	{
		EventRecord     er;

		if (OSEventAvail(everyEvent, &er))
		{
			GetNextEvent(everyEvent, &er);
			switch (er.what)
			{
			case mouseUp:
				if (m_bDragging)
					EndDrag();
				else
					EndResize();
				return TRUE;

			case keyDown:
			case keyUp:
			case autoKey:
			case app2Evt:
			{
				MSG     msg;

				if (WrapEvent(&er, &msg, PM_REMOVE))
				{
					if (m_bDragging)
						OnKey((int)msg.wParam, msg.message == WM_KEYDOWN);
					if (msg.message == WM_KEYUP && msg.wParam == VK_ESCAPE)
					{
						CancelLoop();
						return FALSE;
					}
				}
				break;
			}

			default:
				break;
			}
		}
		else
		{
			if (!EqualPt(er.where, ptCur))
			{
				POINT pt = {er.where.h, er.where.v};
				if (m_bDragging)
					Move(pt);
				else
					Stretch(pt);
			}
		}
	}
#endif
	CancelLoop();

	return FALSE;
}

void CMenuBarDockContext::_EndDrag()
{
	CancelLoop();

	if (m_dwOverDockStyle != 0)
	{
		CDockBar* pDockBar = GetDockBar(m_dwOverDockStyle);
		ASSERT(pDockBar != NULL);

		CRect rect = (m_dwOverDockStyle & CBRS_ORIENT_VERT) ?
			m_rectDragVert : m_rectDragHorz;

		UINT uID = _AfxGetDlgCtrlID(pDockBar->m_hWnd);
		if (uID >= AFX_IDW_DOCKBAR_TOP &&
			uID <= AFX_IDW_DOCKBAR_BOTTOM)
		{
			m_uMRUDockID = uID;
			m_rectMRUDockPos = rect;
			pDockBar->ScreenToClient(&m_rectMRUDockPos);
		}

		// dock it at the specified position, RecalcLayout will snap

		// insisting own line trick!
		CRect rcDockBar;
		pDockBar->GetWindowRect(rcDockBar);

		if (m_dwOverDockStyle & CBRS_ORIENT_VERT) {
			rect.top = rcDockBar.top - 1;
		}
		else {
			rect.left = rcDockBar.left - 10;
		}

		m_pDockSite->DockControlBar(m_pBar, pDockBar, &rect);
		m_pDockSite->RecalcLayout();

	}
	else if ((m_dwStyle & CBRS_SIZE_DYNAMIC) || (HORZF(m_dwStyle) && !m_bFlip) ||
			(VERTF(m_dwStyle) && m_bFlip))
	{
		m_dwMRUFloatStyle = CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI);
		m_ptMRUFloatPos = m_rectFrameDragHorz.TopLeft();
		m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
	}
	else // vertical float
	{
		m_dwMRUFloatStyle = CBRS_ALIGN_LEFT | (m_dwDockStyle & CBRS_FLOAT_MULTI);
		m_ptMRUFloatPos = m_rectFrameDragVert.TopLeft();
		m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
	}
}


void CMenuBar::OnPaintMDIClient()
{
	LTRACE("CMenuBar::OnPaintMDIClient\n");

	if (m_hWndMDIClient) {
		BOOL bMax = FALSE;
		// get active MDI child window
		HWND hWndChild = (HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0,
			(LPARAM)&bMax);
		//ASSERT(::IsWindow(hWndChild)); crash! tell me why!

		if (bMax != m_bMDIMaximized) {
			LTRACE("    max state changed\n");
			m_bMDIMaximized = bMax;
			
			if (bMax) {
				LTRACE("        maximized\n");
				m_pMenuControl->Validate(TRUE);
				m_pMenuIcon->Validate(TRUE);
			}
			else {
				LTRACE("        not maximized\n");
				m_pMenuControl->Validate(FALSE);

⌨️ 快捷键说明

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