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

📄 menubar.cpp

📁 在编写图形程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		UpdateBar();
	}

	CControlBar::OnMouseMove(nFlags, point);
}

LRESULT CMenuBar::OnSetMenuNull(WPARAM wParam, LPARAM)
{
	HWND hWnd = (HWND)wParam;
	ASSERT(::IsWindow(hWnd));
	::SetMenu(hWnd, NULL);
	
	return 0;
}

LRESULT CMenuBar::OnSettingChange(WPARAM wParam, LPARAM lParam)
{
	// reinitialize fonts etc
	if (!_InitCommonResources(TRUE)) {
		TRACE(_T("Failed to create bar resource\n"));
		return FALSE;
	}

	VERIFY(InitItems());

	CFrameWnd* pFrame = GetParentFrame();
	ASSERT_VALID(pFrame);
	pFrame->RecalcLayout();
	return 0;
}

void CMenuBar::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: 
//	LTRACE(_T("CMenuBar::OnLButtonUp\n"));
	if (m_pMenuControl && m_pMenuControl->OnMouseMsg(WM_LBUTTONUP, nFlags, point)) {
		CControlBar::OnLButtonUp(nFlags, point);
		return;
	}	

	CControlBar::OnLButtonUp(nFlags, point);
}

void CMenuBar::CheckActiveChildWndMaximized()
{
	//LTRACE(_T("CMenuBar::CheckActiveChildWndMaximized\n"));
	ASSERT(m_pMenuControl);
	ASSERT(m_pMenuIcon);

	BOOL bMaximized = FALSE;
	GetActiveChildWnd(bMaximized);
	if (m_bMDIMaximized != bMaximized) {
		LTRACE(_T("CMenuBar::CheckActiveChildWndMaximized---state changed, refreshing\n"));
		m_bMDIMaximized = bMaximized;
		m_pMenuControl->OnActivateChildWnd();
		m_pMenuIcon->OnActivateChildWnd();
		RefreshBar();
	}
}

void CMenuBar::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
	LTRACE(_T("CMenuBar::OnInitMenuPopup\n"));
	CMenu menu;
	menu.Attach((HMENU)m_hWindowMenu);

	// scan for first window command
	int n = menu.GetMenuItemCount();
	BOOL bAddSeperator = TRUE;
	for (int iPos=0; iPos<n; iPos++) {
		if (menu.GetMenuItemID(iPos) >= AFX_IDM_FIRST_MDICHILD) {
			bAddSeperator = FALSE;
			break;
		}
	}

	// iPos is either first window item, or end if none found.

	// delete everything after.
	while (iPos < (int)menu.GetMenuItemCount())
		menu.RemoveMenu(iPos, MF_BYPOSITION);

	// get active window so I can check its menu item
	ASSERT(m_hWndMDIClient);
	HWND hwndActive = (HWND)::SendMessage(m_hWndMDIClient,
		WM_MDIGETACTIVE, 0, NULL);

	// append window names in the form "# title"
	// *****fixed by VORGA, thanks!*****
	int iWin;
	int nID = AFX_IDM_FIRST_MDICHILD;
	CString sWinName, sMenuItem;
	HWND hwnd;
	for (iWin = 1; iWin <= 10; iWin++, nID++)
	{
		hwnd = ::GetDlgItem(m_hWndMDIClient, nID);
		if (hwnd == NULL)
			break;

		if (bAddSeperator)
		{
			menu.InsertMenu(iPos++, MF_BYPOSITION | MF_SEPARATOR);
		bAddSeperator = FALSE;
		}

		if (iWin < 10)
		{
			CWnd::FromHandle(hwnd)->GetWindowText(sWinName);
			sMenuItem.Format(_T("&%d %s"), iWin, (LPCTSTR)sWinName);
			menu.InsertMenu(iPos, MF_BYPOSITION, nID, sMenuItem);
			if (hwnd == hwndActive)
				menu.CheckMenuItem(iPos, MF_BYPOSITION | MF_CHECKED);
		}
		else
		{
			menu.InsertMenu(iPos, MF_BYPOSITION, nID, _szMoreWindows);
		}
		iPos++;
	}

	menu.Detach();
}

void CMenuBar::OnSetMenu(HMENU hNewMenu, HMENU hWindowMenu)
{
	ASSERT(m_pMenuIcon && m_pMenuControl);
	// We can get active MDI child window on this message!
	BOOL bMax = FALSE;
	HWND hWndChild = GetActiveChildWnd(bMax);

	if (!m_hWndActiveChild || m_hWndActiveChild != hWndChild) {// an active child window changed
		LTRACE(_T("CMenuBar::OnSetMenu---an active child window changed\n"));
		m_hWndActiveChild = hWndChild;
		// tell MenuIcon child window has been changed
		m_pMenuIcon->OnActivateChildWnd();
	}

	if (!m_hMenu || m_hMenu != hNewMenu) {	// menu changed
		LTRACE(_T("CMenuBar::OnSetMenu---menu changed\n"));
		LoadMenu(hNewMenu, hWindowMenu);	// set menubar menu
		GetOwner()->SetMenu(NULL);			// clear frame menu
	}
}

void CMenuBar::OnNcPaint() 
{
	EraseNonClientEx();
}

UINT CMenuBar::OnNcHitTest(CPoint point) 
{
	// make nonclient area clickable
	return HTCLIENT;
}

void CMenuBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
{
	// calculate border space (will add to top/bottom, subtract from right/bottom)
	CRect rect; rect.SetRectEmpty();
	BOOL bHorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0;
	_CalcInsideRect(rect, bHorz);
//	ASSERT(_afxComCtlVersion != -1);
//	ASSERT(_afxComCtlVersion >= VERSION_IE4 || rect.top >= 2);

	// adjust non-client area for border space
	lpncsp->rgrc[0].left += rect.left;
	lpncsp->rgrc[0].top += rect.top;
	// previous versions of COMCTL32.DLL had a built-in 2 pixel border
//	if (_afxComCtlVersion < VERSION_IE4)
//		lpncsp->rgrc[0].top -= 2;
	lpncsp->rgrc[0].right += rect.right;
	lpncsp->rgrc[0].bottom += rect.bottom;
}

void CMenuBar::OnDestroy() 
{
	CControlBar::OnDestroy();
	
	// TODO: 
	DeleteItems();
	
	if (m_nIDEvent)
		KillTimer(m_nIDEvent);

		// for SDI application
	if (m_bMDIApp == FALSE && m_hMenu != NULL)
		::FreeResource(m_hMenu);
}

void CMenuBar::OnTimer(UINT nIDEvent) 
{
	// TODO: 偙偺埵抲偵儊僢僙乕僕 僴儞僪儔梡偺僐乕僪傪捛壛偡傞偐傑偨偼僨僼僅儖僩偺張棟傪屇傃弌偟偰偔偩偝偄
	if (m_nTrackingState == buttonmouse) {
		CPoint pt; ::GetCursorPos(&pt);
		CRect rect;
		GetWindowRect(&rect);

		if (!rect.PtInRect(pt)) {
			UpdateBar();

			if (m_nIDEvent) {
				KillTimer(m_nIDEvent);
				m_nIDEvent = NULL;
			}
		}
	}	

	CControlBar::OnTimer(nIDEvent);
}

HWND CMenuBar::GetActiveChildWnd(BOOL& bMaximized)
{
	if (!m_hWndMDIClient)
		return NULL;

	BOOL bMax = FALSE;
	HWND hWnd = (HWND)::SendMessage(m_hWndMDIClient,
		WM_MDIGETACTIVE, 0, (LPARAM)&bMax);
	bMaximized = bMax;

	return hWnd;
}

/////////////////////////////////////////////////////////////////////////////
// CMenuBar system hook
void CMenuBar::OnMenuSelect(HMENU hMenu, UINT nIndex)
{
//	LTRACE(_T("CMenuBar::OnMenuSelect\n"));
	if (m_nTrackingState == popup) {
		m_bProcessRightArrow = (::GetSubMenu(hMenu, nIndex) == NULL);
		HMENU hSubMenu = ::GetSubMenu(hMenu, m_nCurIndex);
		if (hSubMenu == NULL)
			return;
		m_bProcessLeftArrow = (hMenu == hSubMenu);
	}
}

void CMenuBar::OnFrameNcActivate(BOOL bActive) 
{
	CFrameWnd* pFrame = GetTopLevelFrame();
	ASSERT_VALID(pFrame);

	if (pFrame->m_nFlags & WF_STAYACTIVE)
		bActive = TRUE;
	if (!pFrame->IsWindowEnabled())
		bActive = FALSE;
	if (bActive == m_bFrameActive)
		return;

	if (!bActive) {
		for (int i = 0; i < GetItemCount(); ++i) {
			m_arrItem[i]->ModifyState(0, MISTATE_INACTIVE);
		}
	}
	else {
		for (int i = 0; i < GetItemCount(); ++i) {
			m_arrItem[i]->ModifyState(MISTATE_INACTIVE, 0);
		}
	}

	m_bFrameActive = bActive;

	// InvalidateRect(NULL); is better, but too late
	// while clicking the application title bar (like IE5)
	// so we have to redraw now!
	CClientDC dc(this);
	DoPaint(&dc);
}

LRESULT CALLBACK CMenuBar::MenuInputFilter(int code, WPARAM wParam, LPARAM lParam)
{
	return (
		code == MSGF_MENU &&
		g_pMenuBar &&
		g_pMenuBar->OnMenuInput( *((MSG*)lParam) )
		) ? TRUE : CallNextHookEx(g_hMsgHook, code, wParam, lParam);
}

void CMenuBar::TrackPopup(int nIndex)
{
	ASSERT_VALID(this);

	m_nCurIndex = nIndex;
	m_bLoop = TRUE;
	while (m_bLoop == TRUE) {
		UpdateWindow();	// force to repaint when button hidden by other window
		UpdateBar(popup, m_nCurIndex);
	
		// install hook
		ASSERT(g_pMenuBar == NULL);
		g_pMenuBar = this;
		ASSERT(g_hMsgHook == NULL);

		m_bLoop = FALSE;
		g_hMsgHook = ::SetWindowsHookEx(WH_MSGFILTER,
			MenuInputFilter, NULL, AfxGetApp()->m_nThreadID);// m_bLoop may become TRUE

		// popup!!
		m_nTrackingState = popup;
		_nPrevIndexForCmd = m_nCurIndex;
		m_arrItem[m_nCurIndex]->TrackPopup(this, GetTopLevelParent());

		// uninstall hook
		::UnhookWindowsHookEx(g_hMsgHook);
		g_hMsgHook = NULL;
		g_pMenuBar = NULL;
	}

	UpdateBar();
}

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

	switch (nMsg) {
	case WM_MOUSEMOVE:
		if (pt != m_ptMouse) {
			int nIndex = HitTestOnTrack(pt);
			if (IsValidIndex(nIndex) && nIndex != m_nCurIndex) {
				// defferent button clicked
				AfxGetMainWnd()->PostMessage(WM_CANCELMODE); // destroy popupped menu
				UpdateBar();							// clean up
				m_nCurIndex = nIndex;
				m_bLoop = TRUE;							// continue loop
			}
			m_ptMouse = pt;
		}
		break;

	case WM_LBUTTONDOWN:
		if (HitTestOnTrack(pt) != -1 && HitTestOnTrack(pt) == m_nCurIndex) {
			// same button clicked
			AfxGetMainWnd()->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_LEFT  && m_bProcessLeftArrow) ||
			(vKey == VK_RIGHT && m_bProcessRightArrow)) {
			// no submenu
			int nNewIndex = GetNextOrPrevButton(m_nCurIndex, vKey==VK_LEFT);
			AfxGetMainWnd()->PostMessage(WM_CANCELMODE); // destroy popupped menu
			UpdateBar();
			m_nCurIndex = 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);
						UpdateBar(button, nNewIndex);
						return TRUE;
								   }
					case VK_SPACE:
					case VK_UP:
					case VK_DOWN:
						TrackPopup(m_nCurIndex);
						return TRUE;

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

					case VK_ESCAPE:
						UpdateBar();
						return TRUE;
					}
				}
			}

			// Alt + X pressed
			if ((bAlt || m_nTrackingState == button) && _istalnum(vkey)) {
				int nIndex;
				if (MapAccessKey(vkey, nIndex) == TRUE) {
					UpdateBar();
					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...
}

⌨️ 快捷键说明

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