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

📄 menubar.cpp

📁 用户管理系统
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	// get last item position to measure bar size
	CRect rcItem;
	GetItemRect(m_nItemCount-1, &rcItem);

	CRect rcRect(0, 0, rcItem.right, rcItem.bottom);

	if (GetParent() == GetParentFrame())
	{
		// not in a rebar yet, just resize the toolbar
		MoveWindow(&rcRect, FALSE);
	}
	else
	{
		// update band information
		REBARBANDINFO rbbi;
		ZeroMemory(&rbbi, sizeof(rbbi));
		rbbi.cbSize = sizeof(rbbi);
		rbbi.fMask = RBBIM_CHILD;

		CReBarCtrl* pReBar = (CReBarCtrl*)GetParent();

		for (UINT i=0; i<pReBar->GetBandCount(); i++)
		{
			pReBar->GetBandInfo(i, &rbbi);

			if (rbbi.hwndChild == m_hWnd)
			{
				rbbi.fMask = RBBIM_CHILDSIZE;
		
				rbbi.cyMinChild = rbbi.cyMaxChild = rbbi.cyChild = rcRect.Height();
				rbbi.cxMinChild = rcRect.Width();

				pReBar->SetBandInfo(i, &rbbi);

				// force updating bands layout
				CRect rcClient;
				pReBar->GetClientRect(&rcClient);
				pReBar->MoveWindow(0, 0, 1, 1, FALSE);
				pReBar->MoveWindow(&rcClient);

				// recalc frame window layout
				GetParentFrame()->RecalcLayout();
		
				break;
			}
		}
	}
}


/////////////////////////////////////////////////////////////////////////////
// CMenuBar menu popup

LRESULT CMenuBar::OnPopupMenu(WPARAM wParam, LPARAM lParam)
{
	// correct index if necessary
	if (m_nPressed<0)
		m_nPressed = m_nItemCount - 1;
	if (m_nPressed>=m_nItemCount)
		m_nPressed = 0;

	OpenPopup();

	return 0;
}

BOOL CMenuBar::OpenMenu(UINT nChar)
{
	for (int i=0; i<m_nItemCount; i++)
	{
		CString strText;
		m_pMenu->GetMenuString(i, strText, MF_BYPOSITION);

		// check menu mnemonic
		int iAmpersand = strText.Find('&');
		if (iAmpersand >=0 && toupper(nChar)==toupper(strText[iAmpersand+1]))
		{
			// open matching menu
			m_nPressed = i;
			m_bKeyboard = TRUE;
			PostMessage(MBM_POPUPMENU);
			SetPrefix(TRUE);
			return TRUE;
		}
	}
	return FALSE;
}


void CMenuBar::OpenPopup()
{
	// if the menu bar has focus, give it back
	CWnd *pWnd = GetFocus();
	if (pWnd && pWnd->m_hWnd==m_hWnd && m_pPrevFocus && IsWindow(m_pPrevFocus->m_hWnd))
	{
		BOOL bRest = m_bPrefix;	// prevent from removing prefixes
		m_pPrevFocus->SetFocus();
		SetPrefix(bRest);
		m_pPrevFocus = NULL;
	}

	m_bSelPopup = FALSE;
	m_hSelMenu = (HMENU)-1;

	m_bKeepPrefix = FALSE;
	m_bNextMenu = FALSE;

	m_bPopMenu = FALSE;

	CMenu *pSubMenu = m_pMenu->GetSubMenu(m_nPressed);

	// change the state of the menu button
	SetHotItem(-1);
	PressButton(m_nPressed, TRUE);

	// notify frame window that menu is selected
	GetParentFrame()->SendMessage(WM_MENUSELECT, MAKELONG(m_nPressed, MF_POPUP | MF_HILITE | MF_MOUSESELECT), (LPARAM)m_pMenu->m_hMenu);

	CRect rc;
	GetItemRect(m_nPressed, &rc);
	ClientToScreen(&rc);

	CRect rcScreen;
	CWnd *pDesktop = GetDesktopWindow();
	if(pDesktop) 
		pDesktop->GetWindowRect(rcScreen);
	else
		AfxMessageBox("Err0");
	rc.IntersectRect(rc, rcScreen);
    CString str;
	TPMPARAMS tpm;
	tpm.cbSize = sizeof(tpm);
	tpm.rcExclude = rc;

	// install message filter
	g_pMenuBar = this;
	g_hMsgHook = SetWindowsHookEx(WH_MSGFILTER,	MenuInputFilter, NULL, GetCurrentThreadId());
	// do menu loop
//	TrackPopupMenuEx(pSubMenu->GetSafeHmenu(),
//		TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_VERTICAL | TPM_VERPOSANIMATION,
//		rc.left, rc.bottom, m_hWnd, &tpm);
	if(pSubMenu && pDesktop)
	{
//		str.Format("%d", pSubMenu->GetSafeHmenu());
//	    AfxMessageBox(str);

	TrackPopupMenuEx(pSubMenu->GetSafeHmenu(),
		TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_VERTICAL | TPM_VERPOSANIMATION,
		rc.left, rc.bottom, m_hWnd, &tpm);
	}
	else
		AfxMessageBox("Err");

	// remove message filter
	UnhookWindowsHookEx(g_hMsgHook);

	g_hMsgHook = NULL;
	g_pMenuBar = NULL;

	// unpress the button
	PressButton(m_nPressed, FALSE);

	// remove prefixes if not asked to keep
	if (!m_bKeepPrefix)
		SetPrefix(FALSE);

	// notify frame window that menu is closing
	// if another menu is not about to open
	if (!m_bNextMenu)
		GetParentFrame()->SendMessage(WM_MENUSELECT, MAKELONG(m_nPressed, 0xFFFF), (LPARAM)m_pMenu->GetSafeHmenu());
}


/////////////////////////////////////////////////////////////////////////////
// CMenuBar message handlers

void CMenuBar::OnLButtonDown(UINT nFlags, CPoint point) 
{
	int	nTest = HitTest(&point);

	if (nTest<0 || nTest>=m_nItemCount)
	{
		AfxMessageBox("Err");
		return;
	}
	m_nPressed = nTest;
	m_bKeyboard = FALSE;

	// open menu when button is clicked
	OpenPopup();
}

void CMenuBar::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
{
	CToolBarCtrl::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);

	// pass message to frame window to let the update handlers do their job
	GetParentFrame()->SendMessage(WM_INITMENUPOPUP, (WPARAM)pPopupMenu->GetSafeHmenu(), MAKELONG(nIndex, bSysMenu));

	MENUITEMINFO miinfo;
	ZeroMemory(&miinfo, sizeof(miinfo));
	miinfo.cbSize = sizeof(miinfo);
	miinfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STATE;

	// set ownerdraw flag for menu items
	for (int i=0; i<(int)pPopupMenu->GetMenuItemCount(); i++)
	{
		GetMenuItemInfo(pPopupMenu->m_hMenu, i, TRUE, &miinfo);
		//if (miinfo.fType & MFT_SEPARATOR)
		//{
		//	//continue;	// use standard separators
		//}
		miinfo.fType |= MFT_OWNERDRAW;
		SetMenuItemInfo(pPopupMenu->m_hMenu, i, TRUE, &miinfo);
	}

	if (m_bKeyboard)
	{
		// a simple trick to highlight the first menu item
		PostMessage(WM_KEYDOWN, VK_DOWN, 0);
		m_bKeyboard = FALSE;
	}
}


BOOL CMenuBar::PreMenuMessage(MSG* pMsg) 
{
	if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_MENU)
		SetPrefix(TRUE);
	else if (pMsg->message == WM_KEYUP && pMsg->wParam == VK_MENU)
		SetPrefix(FALSE);
	else if (pMsg->message == WM_ACTIVATE)
	    Activate(LOWORD(pMsg->wParam) != WA_INACTIVE);
	else if (pMsg->message == WM_MENUCHAR)
	    OpenMenu(LOWORD(pMsg->wParam));
	else if (pMsg->message == WM_SETTINGCHANGE)
	    UpdateSettings();
	else if (pMsg->message == WM_SYSCOMMAND)
	{
	   if (pMsg->wParam  == SC_KEYMENU && OnKeyMenu(pMsg->lParam))
		  return FALSE;
	} 
	return TRUE;
}
BOOL CMenuBar::PreTranslateMessage(MSG* pMsg) 
{
	// handle key messages when the menu bar has focus
   if (pMsg->message == WM_KEYDOWN || 
	   pMsg->message == WM_SYSKEYDOWN)
	{
		int nItem = GetHotItem();

		switch (pMsg->wParam)
		{
		case VK_RETURN:	// open selected menu
		case VK_UP:
		case VK_DOWN:
			m_nPressed = nItem;
			m_bKeyboard = TRUE;
			OpenPopup();
			return TRUE;

		case VK_ESCAPE:	// restore focus
			if(m_pPrevFocus)
			   m_pPrevFocus->SetFocus();
			m_pPrevFocus = NULL;
			return TRUE;

		default:		// check mnemonic
			if (OpenMenu((UINT)pMsg->wParam))
				return TRUE;
			break;
		}
	}
	
	return CToolBarCtrl::PreTranslateMessage(pMsg);
}

void CMenuBar::OnKillFocus(CWnd* pNewWnd) 
{
	SetHotItem(-1);

	SetPrefix(FALSE);

	CToolBarCtrl::OnKillFocus(pNewWnd);
}

// pass these messages to parent frame to enable status bar updating
void CMenuBar::OnEnterIdle(UINT nWhy, CWnd* pWho) 
{
	GetParentFrame()->SendMessage(WM_ENTERIDLE, nWhy, (LPARAM)pWho->m_hWnd);
}

void CMenuBar::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu) 
{
	GetParentFrame()->SendMessage(WM_MENUSELECT, MAKELONG(nItemID, nFlags), (LPARAM)hSysMenu);
}


BOOL CMenuBar::OnKeyMenu(UINT nKey)
{
	if (nKey == VK_SPACE)
	{
		// window menu will be opened
		if (GetFocus()->m_hWnd == m_hWnd)
			Highlight(-1);
		else
			SetPrefix(FALSE);
	}
	else if (nKey == 0)
	{
		// activate or deactivate menu bar
		if (GetFocus()->m_hWnd == m_hWnd)
			Highlight(-1);
		else
		{
			SetPrefix();
			Highlight();
		}

		return TRUE;
	}

	return FALSE;
}


/////////////////////////////////////////////////////////////////////////////
// CMenuBar menu bar drawing

void CMenuBar::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMTBCUSTOMDRAW lpNMCustomDraw = (LPNMTBCUSTOMDRAW)pNMHDR;

	switch (lpNMCustomDraw->nmcd.dwDrawStage)
	{
		case CDDS_PREPAINT:
			if (m_bFlatMenu || !m_bWndActive)
				*pResult = CDRF_NOTIFYITEMDRAW;
			break;

		case CDDS_ITEMPREPAINT:
			if (m_bFlatMenu)	// draw flat-style menu bar
			{
				CDC dc;
				dc.Attach(lpNMCustomDraw->nmcd.hdc);
				CRect rcRect = lpNMCustomDraw->nmcd.rc;

				int nState = lpNMCustomDraw->nmcd.uItemState;

				BOOL bHilight = nState & (CDIS_HOT | CDIS_SELECTED);

				if (bHilight)	// draw highlight rectangle
				{
                    DrawTop(&dc,rcRect,nState);
/*					CBrush brHighlight;
					brHighlight.CreateSysColorBrush(COLOR_HIGHLIGHT);
					CBrush brMenuHilight;
					brMenuHilight.CreateSysColorBrush(COLOR_MENUHILIGHT);
					dc.FillRect(&rcRect, &brMenuHilight);
					dc.FrameRect(&rcRect, &brHighlight);
*/
				}

				char buf[80];
				SendMessage(TB_GETBUTTONTEXT, lpNMCustomDraw->nmcd.dwItemSpec, (LPARAM)buf);

				CString strText = buf;

				// draw text
				dc.SelectObject(GetFont());
//				dc.SetTextColor(GetSysColor(m_bWndActive
//					? (bHilight ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT)
//					: COLOR_GRAYTEXT));
				dc.SetTextColor(GetSysColor(m_bWndActive?COLOR_MENUTEXT : COLOR_GRAYTEXT));
				dc.SetBkMode(TRANSPARENT);
				dc.DrawText(strText, &rcRect, DT_VCENTER | DT_CENTER | DT_SINGLELINE
					| (m_bPrefix ? 0 : DT_HIDEPREFIX));

				dc.Detach();
				*pResult = CDRF_SKIPDEFAULT;
			}
			else if (!m_bWndActive)	// draw gray text if window is inactive
			{
				lpNMCustomDraw->clrText = GetSysColor(COLOR_GRAYTEXT);
				*pResult = CDRF_DODEFAULT;
			}
			break;
	}
}


void CMenuBar::SetPrefix(BOOL bPrefix)
{
	if (m_bPrefix == bPrefix)
		return;

	// ignore if cues are always displayed
	if (!bPrefix && m_bCues)
		return;

	m_bPrefix = bPrefix;
	RedrawWindow();
}

void CMenuBar::Activate(BOOL bActive)
{
	if (m_bWndActive == bActive)
		return;

	SetPrefix(FALSE);

	// change the color of menu text
	m_bWndActive = bActive;
	RedrawWindow();
}


/////////////////////////////////////////////////////////////////////////////
// CMenuBar menu item drawing

void CMenuBar::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{
	CDC dc;
	dc.CreateCompatibleDC(NULL);

	dc.SelectObject(&m_Font);

	UINT nID = lpMeasureItemStruct->itemID;

	CMenu* pMenu = m_bPopMenu ? m_pPopupMenu : m_pMenu;

	CString strString;
	pMenu->GetMenuString(nID, strString, MF_BYCOMMAND);

	// split string to command name and keyboard shortcut

⌨️ 快捷键说明

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