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

📄 menubar.cpp

📁 VC开发实用实例
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

BOOL CMenuBar::OnMenuInput(MSG& m)
{
	ASSERT_VALID(this);
	int nMsg = m.message;
	CPoint pt = m.lParam;
	ScreenToClient(&pt);
	int nIndex;

	switch (nMsg) {
	case WM_MOUSEMOVE:
		{
			if (pt != m_ptMouse) 
			{
				nIndex = HitTestOnTrack(pt);
				if (IsValidIndex(nIndex) && nIndex != m_nCurIndex) 
				{
					// defferent button clicked
					m_pParent->PostMessage(WM_CANCELMODE); // destroy popupped menu
					UpdateBar();							// clean up
					m_nCurIndex = nIndex;
					m_nLastIndex=nIndex;
					m_bLoop = TRUE;							// continue loop
				}
				m_ptMouse = pt;
			}
			if (!m_Rect.IsRectEmpty() && !m_pMenu->CheckIfGrayedDraw())
			{
				POINT pt2;
				pt2.x=pt.x;
				pt2.y=pt.y;
				/*m_pParent->*/ClientToScreen(&pt2);
				if (m_hookFrame.m_bTimerSet &&
					(pt2.x<m_Rect.left || pt2.x>m_Rect.right ||
					 pt2.y<m_Rect.top || pt2.y>m_Rect.bottom))
				{
					m_pParent->KillTimer((UINT)&m_hookFrame);
					m_hookFrame.m_bTimerSet=FALSE;
					EnableGrayedDraw(FALSE);
				}
			}
			break;
		}
		break;

	case WM_LBUTTONDOWN:
		nIndex = HitTestOnTrack(pt);
		if(m_hookFrame.m_bTimerSet)
		{
			m_pParent->KillTimer((UINT)&m_hookFrame);
			m_hookFrame.m_bTimerSet=FALSE;
		}
		

		if (nIndex != -1 && nIndex == m_nCurIndex) {
			// same button clicked
			m_pParent->PostMessage(WM_CANCELMODE); // destroy popupped menu
			UpdateBar(button, m_nCurIndex);
			m_bLoop = FALSE;						// out of loop
			return TRUE;							// eat it!
		}
		break;

	case WM_KEYDOWN:	
	{
		TCHAR vKey = m.wParam;
		/*if (m_dwStyle & CBRS_ORIENT_VERT) 
		{	// if vertical
			break; // do nothing
		}*/

		if (vKey== VK_ESCAPE)
		{
			if(m_arrDepth<=2)EnableGrayedDraw(FALSE);
		}
		else if ((vKey == VK_UP  ) ||
			(vKey == VK_DOWN )) 
		{
			TRACE ("UP/DOWN\n");
			m_nDirectionKey=vKey;
			//AfxMessageBox("OK");
		}
		else if ((vKey == VK_LEFT  ) ||
			(vKey == VK_RIGHT )) 
		{
			m_nDirectionKey=VK_DOWN;
			CString str;
			str.Format("LEFT/RIGHT m_arrDepth=%d\n",m_arrDepth);
			TRACE (str);
		}
		if ((vKey == VK_LEFT  && m_bProcessLeftArrow) ||
			(vKey == VK_RIGHT && m_bProcessRightArrow)) 
		{
			// no submenu
			int nNewIndex = GetNextOrPrevButton(m_nCurIndex, vKey==VK_LEFT);
			m_pParent->PostMessage(WM_CANCELMODE); // destroy popupped menu
			UpdateBar();
			m_nCurIndex = nNewIndex;
			if(nNewIndex>=0) m_nLastIndex=nNewIndex;
			m_bLoop = TRUE;							// continue loop			
			return TRUE;							// eat it!
		}
	}
		break;

	case WM_SYSKEYDOWN:
//		LTRACE(_T("    m_bIgnore = TRUE\n"));
		m_bIgnoreAlt = TRUE;					// next SysKeyUp will be ignored
		break;
	}

	return FALSE;	// pass along...
}

BOOL CMenuBar::TranslateFrameMessage(MSG* pMsg)
{
	ASSERT_VALID(this);
	ASSERT(pMsg);

/*	if (_GetCmdSentWnd(NULL)->GetSafeHwnd() != GetTopLevelParent()->GetSafeHwnd()) {
		if (m_nTrackingState == popup) {
			LTRACE(_T("CMenuBar::TranslateMessage - SendMessage\n"));
			pMsg->hwnd = _GetCmdSentWnd(NULL)->GetSafeHwnd();
			_GetCmdSentWnd(NULL)->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
			return TRUE;
		}
	}
*/
	UINT nMsg = pMsg->message;
	if (WM_LBUTTONDOWN <= nMsg && nMsg <= WM_MOUSELAST) {
		if (pMsg->hwnd != m_hWnd && m_nTrackingState > 0) {
			// clicked outside
			UpdateBar();
		}
	}
	else if (nMsg == WM_SYSKEYDOWN || nMsg == WM_SYSKEYUP || nMsg == WM_KEYDOWN) {
		BOOL bAlt = HIWORD(pMsg->lParam) & KF_ALTDOWN;	// Alt key presed?
		TCHAR vkey = pMsg->wParam;						// + X key
		if (vkey == VK_MENU ||
			(vkey == VK_F10 && !((GetKeyState(VK_SHIFT) & 0x80000000) ||
			                   (GetKeyState(VK_CONTROL) & 0x80000000) || bAlt))) {
			// only alt key pressed
			if (nMsg == WM_SYSKEYUP) {
				switch (m_nTrackingState) {
				case none:
					if (m_bIgnoreAlt == TRUE) {
//						LTRACE(_T("    ignore ALT key up\n"));
						m_bIgnoreAlt = FALSE;
						break;
					}
				
					if (m_bMDIApp) {
						UpdateBar(button, GetNextOrPrevButton(0, FALSE));
					}
					else {
						UpdateBar(button, 0);
					}
					break;
				case button:
					UpdateBar();
					break;
				case buttonmouse:
					break;	// do nothing
				}
			}
			return TRUE;
		}
		else if ((nMsg == WM_SYSKEYDOWN || nMsg == WM_KEYDOWN)) {
			if (m_nTrackingState == button) {
				if (m_dwStyle & CBRS_ORIENT_HORZ) {	// if horizontal
					switch (vkey) {
					case VK_LEFT:
					case VK_RIGHT: {
						int nNewIndex  = GetNextOrPrevButton(m_nCurIndex, vkey == VK_LEFT);
						m_nDirectionKey=VK_DOWN;
						UpdateBar(button, nNewIndex);
						return TRUE;
								   }
					case VK_SPACE:
					case VK_UP:
					case VK_DOWN:

						RefreshMenuPainting(m_pMenu,m_nCurIndex);

						TrackPopup(m_nCurIndex);
						return TRUE;

					case VK_ESCAPE:
						EnableGrayedDraw(FALSE,TRUE);
						UpdateBar();
						return TRUE;
					}
				}
				else {								// if vertical
					switch (vkey) {
					case VK_UP:
					case VK_DOWN:{
						int nNewIndex = GetNextOrPrevButton(m_nCurIndex, vkey == VK_LEFT);//UP);
						m_nDirectionKey=VK_DOWN;
						UpdateBar(button, nNewIndex);
						return TRUE;
								   }
					case VK_SPACE:
					case VK_RIGHT:
					case VK_LEFT:

						m_nDirectionKey=VK_DOWN;
						RefreshMenuPainting(m_pMenu,m_nCurIndex);

						TrackPopup(m_nCurIndex);
						return TRUE;

					case VK_ESCAPE:
						EnableGrayedDraw(FALSE,TRUE);
						UpdateBar();
						return TRUE;
					}
				}
			}

			// Alt + X pressed
			if ((bAlt || m_nTrackingState == button) && _istalnum(vkey)) {
				int nIndex;
				if (MapAccessKey(vkey, nIndex) == TRUE) {
					UpdateBar();

					RefreshMenuPainting(m_pMenu,nIndex);

					TrackPopup(nIndex);
					return TRUE;		// eat it!
				}
				else if (m_nTrackingState==button && !bAlt) {
//					MessageBeep(0);		// if you want
					return TRUE;
				}
			}

			if (m_nTrackingState > 0) {	// unknown key
				if (m_nTrackingState != buttonmouse) {	// if tracked with mouse, don't update bar
					UpdateBar();
				}
			}
		}
	}
	return FALSE;	// pass along...
}

BOOL CMenuBar::MapAccessKey(TCHAR cAccessKey, int& nIndex)
{
	for (int i = 0; i < GetItemCount(); ++i) {
		// fixing point
		TCHAR cKey = m_arrItem[i]->GetAccessKey();
		if (toupper(cKey)/*_totupper(cKey)*/ == cAccessKey) {// *****fixed by andi, thanx!*****
			nIndex = i;
			return TRUE;
		}
	}
	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// CMenuBar layout
int CMenuBar::GetClipBoxLength(BOOL bHorz)
{
	CFrameWnd* pFrame = GetTopLevelFrame(); ASSERT_VALID(pFrame);
	CRect rcFrame; pFrame->GetWindowRect(rcFrame);

	CWnd* pParent = GetParent(); ASSERT_VALID(pParent);
	CRect rcParent; pParent->GetWindowRect(rcParent);

	const int cxFrameBorder = ::GetSystemMetrics(SM_CXFRAME);
	int cxNonClient = cxFrameBorder*2 + m_cxLeftBorder + m_cxRightBorder;
	if (m_dwExStyle & CBRS_GRIPPER)
		cxNonClient += CX_GRIPPER_ALL;

	if (m_dwStyle & CBRS_SIZE_DYNAMIC) {
		if (bHorz) {
			return rcFrame.Width() - cxNonClient;
		}
		else {
			int nResult = rcParent.Height();
			// I don't know the reason of the following code...
			nResult -= m_cxRightBorder + m_cxLeftBorder + cyBorder2*2;	
			if (m_dwExStyle & CBRS_GRIPPER)
				nResult -= CY_GRIPPER_ALL;

			return nResult;
		}
	}
	else {
		CRect rect; GetClientRect(rect);
		if (bHorz) {
			return rect.Width();
		}
		else {
			return rect.Height();
		}
	}
}

CSize CMenuBar::CalcLayout(DWORD dwMode, int nLength)
{
	ASSERT_VALID(this);
	ASSERT(::IsWindow(m_hWnd));
	if (dwMode & LM_HORZDOCK)
		ASSERT(dwMode & LM_HORZ);

	// make SC_CLOSE button disable
	if (m_dwStyle & CBRS_FLOATING) 
	{
		CFrameWnd* pMiniFrame = CControlBar::GetParentFrame(); 
		ASSERT_KINDOF(CMiniFrameWnd, pMiniFrame);
//		Don't do this, cause right click menu turns unavairable
//		pMiniFrame->ModifyStyle(WS_SYSMENU, 0);
		CMenu* pSysMenu = pMiniFrame->GetSystemMenu(FALSE);	ASSERT_VALID(pSysMenu);
		pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
	}

	int nCount = GetItemCount();
	CSize sizeResult(0, 0);

	if (nCount > 0)
	{
		if (!(m_dwStyle & CBRS_SIZE_FIXED))
		{
			BOOL bDynamic = m_dwStyle & CBRS_SIZE_DYNAMIC;

			if (bDynamic && (dwMode & LM_MRUWIDTH))
			{
				LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_MRUWIDTH\n"));
				SizeMenuBar(m_nMRUWidth);
				CalcItemLayout(nCount);// added

				sizeResult = CalcSize(nCount);
			}
			else if (bDynamic && (dwMode & LM_HORZDOCK))
			{
				LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_HORZDOCK\n"));
				if (IsFloating() || (m_dwStyle & CBRS_ORIENT_VERT)) {
					// I can't synchronize horz size on dragging with size on dock bar
					// as VC++ developer can't.
					SizeMenuBar(32767);
				}
				else {
					// Menu Button wrapped by frame width
					SizeMenuBar(GetClipBoxLength(TRUE));
				}

				CalcItemLayout(nCount);// added
				
				sizeResult = CalcSize(nCount);
				if (!IsFloating() && !(m_dwStyle & CBRS_ORIENT_VERT)) {
					if (m_pDockContext->m_pDC) {// while dragging (m_pDockContext->m_bDragging is helpless)
						sizeResult.cx = GetClipBoxLength(TRUE);
					}
				}
			}
			else if (bDynamic && (dwMode & LM_VERTDOCK))
			{
				LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_VERTDOCK\n"));
				//SizeMenuBar(0);
				CalcItemLayout(nCount, TRUE);// added

				sizeResult = CalcVertDockSize(nCount);
				if (!IsFloating() && !(m_dwStyle & CBRS_ORIENT_HORZ)) {
					if (m_pDockContext->m_pDC) {// while dragging
						sizeResult.cy = GetClipBoxLength(FALSE);//GetrcParent.Height() - m_cxRightBorder - m_cxLeftBorder;
					}
				}
			}
			else if (bDynamic && (nLength != -1))
			{
				LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---nLength != -1\n"));
				CRect rect; rect.SetRectEmpty();
				_CalcInsideRect(rect, (dwMode & LM_HORZ));
				BOOL bVert = (dwMode & LM_LENGTHY);
				int nLen = nLength + (bVert ? rect.Height() : rect.Width());

				SizeMenuBar(nLen, bVert);
				CalcItemLayout(nCount, bVert);// added

				sizeResult = CalcSize(nCount);
			}
			else if (bDynamic && (m_dwStyle & CBRS_FLOATING))
			{
				LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---CBRS_FLOATING\n"));
				SizeMenuBar(m_nMRUWidth);
				CalcItemLayout(nCount);// added

				sizeResult = CalcSize(nCount);
			}
			else
			{
				if (!bDynamic) {
					InvalidateRect(NULL);
					goto Junk;
				}

				LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---other\n"));
				BOOL bVert = !(dwMode & LM_HORZ);
				SizeMenuBar(GetClipBoxLength(TRUE));
				CalcItemLayout(nCount, bVert);// added

				if (bVert) {
					InvalidateRect(NULL);// draw forcefully for captions
					sizeResult = CalcVertDockSize(nCount);
					// DockBar not replaced yet, so I can't get precise size
					sizeResult.cy = 10000;
				}
				else {
					sizeResult = CalcSize(nCount);
					sizeResult.cx = GetClipBoxLength(TRUE);
				}
			}
		}
		else {// CBRS_SIZE_FIXED
			LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_FIXED)\n"));
Junk:
			BOOL bVert = !(dwMode & LM_HORZ);
			SizeMenuBar(32767);
			CalcItemLayout(nCount, bVert);// added

			if (bVert) {
				sizeResult = CalcVertDockSize(nCount);
			}
			else {
				sizeResult = CalcSize(nCount);
			}
		}

		if (dwMode & LM_COMMIT)
		{
			LTRACE(_T("CMenuBar::CalcLayout---LM_COMMIT\n"));
			int nControlCount = 0;
			BOOL bIsDelayed = m_bDelayedButtonLayout;
			m_bDelayedButtonLayout = FALSE;

			if ((m_dwStyle & CBRS_FLOATING) && (m_dwStyle & CBRS_SIZE_DYNAMIC))
				m_nMRUWidth = sizeResult.cx;

			//CalcItemLayout(nCount, dwMode);

			m_bDelayedButtonLayout = bIsDelayed;
		}
	}

	//BLOCK: Adjust Margins
	{
		CRect rect; rect.SetRectEmpty();
		_CalcInsideRect(rect, (dwMode & LM_HORZ));
		sizeResult.cy -= rect.Height();
		sizeResult.cx -= rect.Width();

		CSize size = CControlBar::CalcFixedLayout((dwMode & LM_STRETCH), (dwMode & LM_HORZ));
		sizeResult.cx = max(sizeResult.cx, size.cx);
		sizeResult.cy = max(sizeResult.cy, size.cy);
	}
	return sizeResult;
}

CSize CMenuBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
	LTRACE(_T("CMenuBar::CalcFixedLayout\n"));
	ASSERT_VALID(this);
	ASSERT(::IsWindow(m_hWnd));

	DWORD dwMode = bStretch ? LM_STRETCH : 0;
	dwMode |= bHorz ? LM_HORZ : 0;

	return CalcLayout(dwMode);
}

CSize CMenuBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
	LTRACE(_T("CMenuBar::CalcDynamicLayout\n"));
	if ((nLength == -1) && !(dwMode & LM_MRUWIDTH) && !(dwMode & LM_COMMIT) &&
		((dwMode & LM_HORZDOCK) || (dwMode & LM_VERTDOCK)))
	{
		LTRACE(_T("    FixedLayout\n"));
		return CalcFixedLayout(dwMode & LM_STRETCH, dwMode & LM_HORZDOCK);
	}
	return CalcLayout(dwMode, nLength);
}

// set m_bWrapped by nWidth
int CMenuBar::WrapMenuBar(int nCount, int nWidth)
{
//	LTRACE(_T("CMenuBar::WrapMenuBar\n"));
	int nResult = 0;

⌨️ 快捷键说明

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