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

📄 menubar.cpp

📁 visual c++ 实例编程
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//			::GetClassName(pWnd->GetSafeHwnd(), str, 256);
//			LTRACE2(_T("    server wnd : %s\n"), str);
			return pWnd;
		}
	}

	return NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CMDIClientHook 
CMDIClientHook::CMDIClientHook()
{
	m_pMenuBar = NULL;
}

BOOL CMDIClientHook::Install(CMenuBar* pMenuBar, HWND hWndToHook)
{
	ASSERT_VALID(pMenuBar);
	ASSERT(m_pMenuBar == NULL);
	m_pMenuBar = pMenuBar;
	return HookWindow(hWndToHook);
}

CMDIClientHook::~CMDIClientHook()
{
	HookWindow((HWND)NULL);
}

LRESULT CMDIClientHook::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	ASSERT_VALID(m_pMenuBar);

	switch (nMsg) {
	case WM_MDISETMENU:			// only sent to MDI client window
		// Setting new frame/window menu: bypass MDI. wParam is new menu.
		if (wParam) {
			//LTRACE(_T("CMenuBar::WM_MDISETMENU 0x%04x\n"), wParam);
			CMenuEx* pMenuTmp=(CMenuEx*)CMenu::FromHandle((HMENU)wParam);
			CMenuEx* pMenuTmp2=(CMenuEx*)CMenu::FromHandle((HMENU)lParam);
			if(pMenuTmp && !pMenuTmp->IsKindOf(RUNTIME_CLASS(CMenuEx))) return 0;
			if(pMenuTmp2 && !pMenuTmp2->IsKindOf(RUNTIME_CLASS(CMenuEx))) return 0;
			m_pMenuBar->OnSetMenu(pMenuTmp,pMenuTmp2);
		}
		return 0;

	case WM_MDIREFRESHMENU:		// only sent to MDI client window
		// Normally, would call DrawMenuBar, but I have the menu, so eat it.
		//LTRACE(_T("CMenuBar::WM_MDIREFRESHMENU\n"));
		return 0;

	case WM_MDIACTIVATE:
	{
		m_pMenuBar->EnableGrayedDraw(FALSE);
		if (!::IsWindow((HWND)wParam)) break;
		CMDIChildWnd* pClient=(CMDIChildWnd*) CMDIChildWnd::FromHandle((HWND)wParam);
		CMDIFrameEx* pFrame=((CMDIFrameEx*)(m_pMenuBar->m_pParent/*GetParentFrame()*/));
		if (!pFrame->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))) break;
		if (pClient && pClient->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)))
		{
			CView* pView=pClient->GetActiveView();
			if(!pView) break;
			CDocument* pDoc=pView->GetDocument();
			if(!pDoc) break;
			CMultiDocTemplateEx* pTemplate =(CMultiDocTemplateEx*)pDoc->GetDocTemplate();
			if (!pTemplate->IsKindOf(RUNTIME_CLASS(CMultiDocTemplateEx))) break;
			m_pMenuBar->OnSetMenu(&(pTemplate->m_mnuDocMenu),
								  pFrame->GetWindowMenuPopup(&(pTemplate->m_mnuDocMenu)));
		}
		else 
		{	
			m_pMenuBar->OnSetMenu(pFrame->GetMainMenu(),
									pFrame->GetWindowMenuPopup(pFrame->GetMainMenu()));
			break;
		}
		break;
	}
	case WM_MDIDESTROY:
	{
		CSubclassWnd* p = GetHookMap().Lookup((HWND)wParam);
		ASSERT (p->IsKindOf(RUNTIME_CLASS(CMDIChildHook)));
		p->HookWindow((HWND)NULL);
		delete (CMDIChildHook*)p;
		AfxGetMainWnd()->PostMessage(WM_ACTIVATE,WA_ACTIVE,NULL);
		break;
	}
	case WM_MDIRESTORE:
	case WM_MDIMAXIMIZE:
		m_pMenuBar->EnableGrayedDraw(FALSE);
		break;
//	case WM_PAINT:
		//LTRACE(_T("CMenuBar:WM_PAINT\n"));
		// If you use no Doc-View project, when child window maximized,
		// WM_PAINT never sent! so this trick never do.
		// So this code moved to OnUpdateCmdUI.

		// After changing the MDI maximized state, the client window gets a
		// paint message. This is the most convenient place to find out; there
		// is no WM_MDIMAXIMIZED message.
//		if (/*m_pWndHooked->*/m_hWnd == m_pMenuBar->m_hWndMDIClient)
//			m_pMenuBar->CheckActiveChildWndMaximized();
//		break;
	}

	return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
}

/////////////////////////////////////////////////////////////////////////////
// CMDIChildHook 
IMPLEMENT_DYNAMIC( CMDIChildHook, CSubclassWnd );

CMDIChildHook::CMDIChildHook()
{
	m_pMenuBar = NULL;
}

BOOL CMDIChildHook::Install(CMenuBar* pMenuBar, HWND hWndToHook)
{
	ASSERT_VALID(pMenuBar);
	ASSERT(m_pMenuBar == NULL);
	m_pMenuBar = pMenuBar;
	return HookWindow(hWndToHook);
}

CMDIChildHook::~CMDIChildHook()
{
	HookWindow((HWND)NULL);
}

LRESULT CMDIChildHook::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	ASSERT_VALID(m_pMenuBar);

	switch (nMsg) 
	{
	  case WM_MDIACTIVATE:
	  {
		m_pMenuBar->EnableGrayedDraw(FALSE);
		CMDIFrameEx* pFrame=((CMDIFrameEx*)(m_pMenuBar->m_pParent/*GetParentFrame()*/));
		if (!pFrame->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))) break;
		if (!::IsWindow((HWND)lParam)) 
		{
			m_pMenuBar->OnSetMenu(pFrame->GetMainMenu(),
									pFrame->GetWindowMenuPopup(pFrame->GetMainMenu()));
			break;
		}
		CMDIChildWnd* pClient=(CMDIChildWnd*) CMDIChildWnd::FromHandle((HWND)lParam);
		if (pClient && pClient->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)))
		{
			CView* pView=pClient->GetActiveView();
			if(!pView) break;
			CDocument* pDoc=pView->GetDocument();
			if(!pDoc) break;
			CMultiDocTemplateEx* pTemplate =(CMultiDocTemplateEx*)pDoc->GetDocTemplate();
			if (!pTemplate->IsKindOf(RUNTIME_CLASS(CMultiDocTemplateEx))) break;
			m_pMenuBar->OnSetMenu(&(pTemplate->m_mnuDocMenu),
								  pFrame->GetWindowMenuPopup(&(pTemplate->m_mnuDocMenu)));
		}
		else 
		{	
			m_pMenuBar->OnSetMenu(pFrame->GetMainMenu(),
									pFrame->GetWindowMenuPopup(pFrame->GetMainMenu()));
			break;
		}
		break;
	  }
	  case WM_SIZE:
		  m_pMenuBar->EnableGrayedDraw(FALSE);
		break;
	}

	return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
}

/////////////////////////////////////////////////////////////////////////////
// CMDIFrameHook 
CMDIFrameHook::CMDIFrameHook()
{
	m_pMenuBar = NULL;
	m_bTimerSet=FALSE;
}

BOOL CMDIFrameHook::Install(CMenuBar* pMenuBar, HWND hWndToHook)
{
	ASSERT_VALID(pMenuBar);
	ASSERT(m_pMenuBar == NULL);
	m_pMenuBar = pMenuBar;
	return HookWindow(hWndToHook);
}

CMDIFrameHook::~CMDIFrameHook()
{
	HookWindow((HWND)NULL);
	if (m_bTimerSet)
	{
		m_pMenuBar->m_pParent->KillTimer((UINT)this);
		m_bTimerSet=FALSE;
		m_pMenuBar->EnableGrayedDraw(FALSE);
	}
}

LRESULT CMDIFrameHook::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	ASSERT_VALID(m_pMenuBar);
	// be care for other windows(MainFrame) hooking
	// possible called when already this wnd destroyed (WM_NCACTIVATE is)
	if (!::IsWindow(m_pMenuBar->m_hWnd)) {
		return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
	}

	BOOL bSend = FALSE;
	if (HWND hWndServer = m_pMenuBar->OleMenuDescriptor(bSend, nMsg, wParam, lParam)) {
		// OLE wnd will handle message
		if (bSend)
			return ::SendMessage(hWndServer, nMsg, wParam, lParam);
		else
			return ::PostMessage(hWndServer, nMsg, wParam, lParam);
	}

	CMenuEx* pMenuTmp;
	m_pMenuBar->m_pMenu->TrapWindowProc(nMsg, wParam, lParam);
	switch (nMsg) {
	case WM_MOUSEACTIVATE:
			if(m_pMenuBar->m_pMenu)
			{
				m_pMenuBar->EnableGrayedDraw(FALSE,1); 
			}
		break;
	case WM_COMMAND:
		if (lParam==NULL && LOWORD(wParam)==(WORD)ID_SHOWFULL)
		{
			m_pMenuBar->m_pParent->KillTimer((UINT)this);
			m_bTimerSet=FALSE;
			if(m_pMenuBar->m_pMenu)
				m_pMenuBar->EnableGrayedDraw(TRUE,TRUE);
			CRect r;
			if(m_pMenuBar->GetItemRect(m_pMenuBar->m_nLastIndex,r))
			{
				m_pMenuBar->m_bNoTimer=TRUE;
				int j;
				j=m_pMenuBar->m_arrDepth;
				//如去掉ID_SHOWFULL判断时,应注释掉下面一行,以避免选择菜单项后,菜单仍不消失问题。
				m_pMenuBar->PostMessage(WM_LBUTTONDOWN,MK_LBUTTON,r.left+(r.top<<16));
								
				m_pMenuBar->ReOpenMenu(j);

				m_pMenuBar->m_bNoTimer=FALSE;
				m_pMenuBar->m_bLoop = TRUE;							// continue loop
			}
			m_pMenuBar->m_Rect.SetRectEmpty();
		}
		else
		{
			if(m_pMenuBar->m_pMenu)
			{
				m_pMenuBar->EnableGrayedDraw(FALSE,1); 
			}
			m_pMenuBar->UpdateMenuRefresh(LOWORD(wParam));
		}
		break;
	case WM_TIMER:
		{
			if(wParam==(WPARAM)this)
			{
				m_pMenuBar->m_pParent->KillTimer((UINT)this);
				m_bTimerSet=FALSE;
				CRect r;
				if(m_pMenuBar->GetItemRect(m_pMenuBar->m_nLastIndex,r))
				{
					m_pMenuBar->m_bNoTimer=TRUE;
					int j;
					j=m_pMenuBar->m_arrDepth;
					m_pMenuBar->PostMessage(WM_KEYDOWN,VK_F10,0);

					m_pMenuBar->PostMessage(WM_LBUTTONDOWN,MK_LBUTTON,r.left+(r.top<<16));
					m_pMenuBar->m_bNoTimer=FALSE;
					m_pMenuBar->m_arrDepth=j;
					m_pMenuBar->PostMessage(WM_COMMAND,ID_SHOWFULL,NULL);
				}
			}
			else
			{
				if (m_bTimerSet)
				{
					m_pMenuBar->EnableGrayedDraw(FALSE);
				}
				m_pMenuBar->m_pParent->KillTimer(wParam);
			}
			break;
		}
	case WM_MENUSELECT:
		{
			if(!lParam) break;
			pMenuTmp=(CMenuEx*)CMenu::FromHandle((HMENU)lParam);
			if (!pMenuTmp->IsKindOf(RUNTIME_CLASS(CMenuEx))) break;
			m_pMenuBar->OnMenuSelect(pMenuTmp, (UINT)LOWORD(wParam));
			break;
		}
	case WM_DRAWITEM:
		{
			if (wParam==0) 
			{
				LPDRAWITEMSTRUCT pStruct=(LPDRAWITEMSTRUCT)lParam;
				UINT stateex = (((CMenuExData*)(pStruct->itemData))->nFlagsEx);
			    if(pStruct->itemState&ODS_SELECTED)
				{
					if ((stateex & MF_LASTARROW) && (!(m_pMenuBar->m_pMenu->CheckIfGrayedDraw())))
					{
						m_pMenuBar->m_pParent->SetTimer((UINT)this,1000,NULL);//&TimerFunc);
						m_bTimerSet=TRUE;
						POINT p;
						CDC* pDC = CDC::FromHandle(pStruct->hDC);
						CWnd *pWnd=pDC->GetWindow();
						HWND hwnd=pWnd->m_hWnd;
						p.y=pStruct->rcItem.top;
						p.x=pStruct->rcItem.left;
						ClientToScreen(hwnd,&p);
						m_pMenuBar->m_Rect.top=p.y;
						m_pMenuBar->m_Rect.left=p.x;
						p.y=pStruct->rcItem.bottom;
						p.x=pStruct->rcItem.right;
						ClientToScreen(hwnd,&p);
						m_pMenuBar->m_Rect.bottom=p.y;
						m_pMenuBar->m_Rect.right=p.x;

					}
					else
					{
						if(m_bTimerSet)
						{
							m_pMenuBar->m_pParent->KillTimer((UINT)this);
							m_bTimerSet=FALSE;
							m_pMenuBar->m_Rect.SetRectEmpty();
						}
					}
				}
			}
			break;
		}
	case WM_INITMENUPOPUP:
		if (!((BOOL)HIWORD(lParam)) && 
			m_pMenuBar->m_pMenu->IsMenu(CMenu::FromHandle((HMENU) wParam)))
			CMenuEx::UpdateMenu(m_pMenuBar->m_pMenu);
		if (!HIWORD(lParam) && m_pMenuBar->m_pWindowMenu && 
			(HMENU)wParam == m_pMenuBar->m_pWindowMenu->m_hMenu)
		{
			if(!wParam) break;
			pMenuTmp=(CMenuEx*)CMenu::FromHandle((HMENU)wParam);
			if (!pMenuTmp->IsKindOf(RUNTIME_CLASS(CMenuEx))) break;
			m_pMenuBar->OnInitMenuPopup(pMenuTmp, LOWORD(lParam), (BOOL)HIWORD(lParam));
		}
		break;

	case WM_NCACTIVATE:
		m_pMenuBar->OnFrameNcActivate((BOOL)wParam);
		m_pMenuBar->EnableGrayedDraw(FALSE);
		break;
	
	case WM_SYSCOLORCHANGE:
	case WM_SETTINGCHANGE:
		LTRACE(_T("CMenuBar::WM_SETTINGCHANGE\n"));
		// It's enough to reinitialize common resources once.
		m_pMenuBar->OnSettingChange(wParam, lParam);
		break;
	case WM_MEASUREITEM:
		if(((LPMEASUREITEMSTRUCT) lParam)->CtlType==ODT_MENU && m_pMenuBar->m_pMenu)
		{
			m_pMenuBar->m_pMenu->MeasureItem((LPMEASUREITEMSTRUCT) lParam);
			return TRUE;
		}
		break;
	case WM_MENUCHAR:
		if (m_pMenuBar->m_pMenu)
		{
			pMenuTmp=(CMenuEx*)CMenu::FromHandle((HMENU) lParam);
			if (!pMenuTmp->IsKindOf(RUNTIME_CLASS(CMenuEx))) break;
			return m_pMenuBar->m_pMenu->FindKeyboardShortcut((TCHAR) LOWORD(wParam), 
															 (UINT) HIWORD(wParam), pMenuTmp);
		}
	case WM_ACTIVATE:
		{
			if(m_bTimerSet)
			{
				m_pMenuBar->m_pParent->KillTimer((UINT)this);
				m_bTimerSet=FALSE;
			}
			m_pMenuBar->EnableGrayedDraw(FALSE);

			CMDIFrameEx* pFrame=((CMDIFrameEx*)(m_pMenuBar->m_pParent/*GetParentFrame()*/));
			if (!pFrame->IsKindOf(RUNTIME_CLASS(CMDIFrameEx))) break;
			CWnd* pWnd=m_pMenuBar->m_pParent;
			if (!pWnd->IsKindOf(RUNTIME_CLASS(CMDIFrameEx))) break;
			CMDIChildWnd* pClient=(CMDIChildWnd*) pFrame->MDIGetActive();
			if (pClient && pClient->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)))
			{
				CView* pView=pClient->GetActiveView();
				if(!pView) break;
				CDocument* pDoc=pView->GetDocument();
				if(!pDoc)
				{	
					m_pMenuBar->OnSetMenu(pFrame->GetMainMenu(),
										pFrame->GetWindowMenuPopup(pFrame->GetMainMenu()));
					break;
				}
				CMultiDocTemplateEx* pTemplate =(CMultiDocTemplateEx*)pDoc->GetDocTemplate();
				if (!pTemplate->IsKindOf(RUNTIME_CLASS(CMultiDocTemplateEx))) break;
				m_pMenuBar->OnSetMenu(&(pTemplate->m_mnuDocMenu),
								  pFrame->GetWindowMenuPopup(&(pTemplate->m_mnuDocMenu)));
			}
			else 
			{	
				m_pMenuBar->OnSetMenu(pFrame->GetMainMenu(),
									pFrame->GetWindowMenuPopup(pFrame->GetMainMenu()));
				break;
			}
			break;
		}
  	  case WM_SETFOCUS:
	  case WM_NCHITTEST:
		{
			m_pMenuBar->EnableGrayedDraw(FALSE);
			break;
		}
	}

	if (nMsg == CMenuBar::WM_GETMENU)
		return (LRESULT)m_pMenuBar->m_pMenu->m_hMenu;
	
	return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
}

//////////////////////////////////////////////////////////////////////
// CMenuItem interface
CMenuItem::CMenuItem()
{
	m_fsStyle = 0;
	m_fsState = 0;
	m_rcItem.SetRectEmpty();
	m_sizeHorz = CSize(0, 0);
	m_cAccessKey = 0;
}

void CMenuItem::ModifyState(BYTE fsRemove, BYTE fsAdd)
{
	m_fsState = (m_fsState & ~fsRemove) | fsAdd;
}

CSize CMenuItem::GetHorizontalSize() const
{
	if (m_fsState & MISTATE_HIDDEN)
		return CSize(0, 0);
	else
		return m_sizeHorz;
}

//////////////////////////////////////////////////////////////////////
// CMenuButton class	
CMenuButton::CMenuButton(CMenuEx* pMenu, int nIndex)
{
	ASSERT(nIndex >= 0);

	m_fsStyle |= (MISTYLE_TRACKABLE | MISTYLE_WRAPPABLE);
	InitButtonStringAndSubMenuHandle(pMenu, nIndex);
	InitHorizontalButtonSize();
	InitAccessKeyAndVerticalLinePoint();
}

void CMenuButton::InitButtonStringAndSubMenuHandle(CMenuEx* pMenu, int nIndex)
{
	pMenu->GetMenuText(nIndex,m_strBtn);

	m_pSubMenu = (CMenuEx*)pMenu->GetSubMenu(nIndex);
	if (!m_pSubMenu) {
		m_nID = pMenu->GetMenuItemID(nIndex);
		ASSERT(m_nID != -1);
	}
	else {
		m_nID = -1;
	}
}

void CMenuButton::InitHorizontalButtonSize()
{
	// get menu button Text size
	ASSERT(m_strBtn.IsEmpty() == FALSE);
	m_sizeHorz.cx = _CalcTextWidth(m_strBtn) + CXTEXTMARGIN*2;
	m_sizeHorz.cy = _cyHorzFont + _cyTextMargin*2;
}

voi

⌨️ 快捷键说明

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