首页 > 代码库 > VC 菜单栏的自绘(二)
VC 菜单栏的自绘(二)
没人看我代码一贴完事
//cpp文件 #include "StdAfx.h" #include "MenuBar.h" #include "resource.h" HHOOK gMsgFilterHook=NULL; CMenuBar* g_MenuBar; CMenuItem* gOldMenuItem = NULL; CMenuItem* gNewMenuItem = NULL; BOOL g_bPressed = FALSE; LRESULT CALLBACK MessageProc( int code, WPARAM wParam, LPARAM lParam) { if ( code == MSGF_MENU ) { MSG *pMsg = (MSG *)lParam; switch ( pMsg->message ) { case WM_MOUSEMOVE: { CPoint pt; pt.x = LOWORD(pMsg->lParam); pt.y = HIWORD(pMsg->lParam); if ( NULL == g_MenuBar ) break; g_MenuBar->ScreenToClient(&pt); int nItem = g_MenuBar->HitTest(pt); if ( nItem >= 0 ) { CMenuItem *pMenuItem = g_MenuBar->m_vecMenuItem.at(nItem); if ( pMenuItem == gOldMenuItem ) break; ::SendMessage(g_MenuBar->m_hWnd, WM_CANCELMODE, 0, 0); gNewMenuItem = pMenuItem; g_MenuBar->OnMouseMove(0, pt); } } break; default: break; } } return ::CallNextHookEx(gMsgFilterHook, code, wParam, lParam); } CMenuItem::CMenuItem() { } CMenuItem::~CMenuItem() { } void CMenuItem::DrawMenu(CDC* pDC) { int OldbkMode = pDC->SetBkMode(TRANSPARENT); switch(m_state) { case Normal: { } break; case Pressed: { CPen pen(PS_SOLID,1,0x123456); CPen*pOldPen = pDC->SelectObject(&pen); pDC->Rectangle(m_rcMenu); pDC->SelectObject(pOldPen); } break; case Hover: { CPen pen(PS_SOLID,1,0x888888); CPen*pOldPen = pDC->SelectObject(&pen); pDC->Rectangle(m_rcMenu); pDC->SelectObject(pOldPen); } break; default: ASSERT(FALSE); break; } pDC->DrawTextEx(m_strText,m_rcMenu,DT_SINGLELINE|DT_CENTER|DT_VCENTER,NULL); pDC->SetBkMode(OldbkMode); } void CMenuItem::ShowPopUpMenu(CWnd* pWnd) { CMenuBar* pMenuBar = (CMenuBar*)pWnd; CPoint pt; pt.x = m_rcMenu.left; pt.y = m_rcMenu.bottom; pMenuBar->ClientToScreen(&pt); if (m_hPopUpMenu) { DWORD dwThreadId = GetCurrentThreadId(); if (gMsgFilterHook == NULL ) { gMsgFilterHook = SetWindowsHookEx(WH_MSGFILTER,MessageProc,NULL, dwThreadId); } BOOL bRet = ::TrackPopupMenuEx(m_hPopUpMenu,TPM_VERTICAL|TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_LEFTALIGN,pt.x,pt.y,pMenuBar->m_hWnd,NULL); if (gMsgFilterHook) { UnhookWindowsHookEx(gMsgFilterHook); gMsgFilterHook = NULL; } } } CMenuBar::CMenuBar(void) { g_MenuBar = this; } CMenuBar::~CMenuBar(void) { int nCount = GetMenuItemCount(); if (nCount==0) return; for (int i = 0;i<nCount;i++) { CMenuItem* pMenuItem = m_vecMenuItem.at(i); delete pMenuItem ; } } BEGIN_MESSAGE_MAP(CMenuBar, CPanel) ON_WM_PAINT() ON_WM_CREATE() ON_WM_MOUSEMOVE() ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave) ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() void CMenuBar::OnPaint() { CPaintDC dc(this); // device context for painting int nCount = GetMenuItemCount();//子项个数 CRect rcClient; GetClientRect(rcClient); //m_imgBk.Draw(dc.m_hDC,rcClient); CFont font; font.CreateFont(14,0,0,0,FW_MEDIUM,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,_T("Arial")); dc.SelectObject(&font); for (int i = 0; i<nCount;i++) { CMenuItem * pMenuItem = m_vecMenuItem.at(i); pMenuItem->DrawMenu((CDC*)&dc); } } int CMenuBar::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CPanel::OnCreate(lpCreateStruct) == -1) return -1; return 0; } void CMenuBar::LoadMenuFromResource(UINT nIDResource) { m_Menu.LoadMenu(nIDResource); int nCount = m_Menu.GetMenuItemCount(); for (int i = 0;i<nCount;i++) { CString strText; m_Menu.GetMenuString(i,strText,MF_BYPOSITION); CMenuItem* pMenuItem = new CMenuItem; pMenuItem->m_strText = strText; pMenuItem->m_hPopUpMenu = m_Menu.GetSubMenu(i)->m_hMenu; pMenuItem->m_rcMenu = CRect(i*50,0,i*50+50,22); pMenuItem->m_state = CMenuItem::Normal; m_vecMenuItem.push_back(pMenuItem); } Invalidate(); } int CMenuBar::GetMenuItemCount() { return (int)m_vecMenuItem.size(); } int CMenuBar::HitTest(CPoint pt) { int nItem = HTERROR; int nCount = GetMenuItemCount(); for (int i = 0;i<nCount;i++) { CMenuItem* pMenuItem = m_vecMenuItem.at(i); if (pMenuItem) { BOOL bInRect = pMenuItem->m_rcMenu.PtInRect(pt); if (bInRect) { if (pMenuItem->m_state != CMenuItem::Hover) { pMenuItem->m_state = CMenuItem::Hover; InvalidateRect(pMenuItem->m_rcMenu); } nItem = i; } else { if (pMenuItem->m_state != CMenuItem::Normal) { pMenuItem->m_state = CMenuItem::Normal; InvalidateRect(pMenuItem->m_rcMenu); } } } } if (nItem == HTERROR) { if (gMsgFilterHook) { UnhookWindowsHookEx(gMsgFilterHook); gMsgFilterHook = NULL; g_bPressed = FALSE; } else { g_bPressed = TRUE; } gOldMenuItem = NULL; } return nItem; } void CMenuBar::OnMouseMove(UINT nFlags, CPoint point) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.dwHoverTime = 1; tme.hwndTrack= this->m_hWnd; TrackMouseEvent(&tme); int nItem = HitTest(point); if (nItem>=0) { if (gOldMenuItem!=NULL) { if (gNewMenuItem !=NULL && g_bPressed == TRUE) { gNewMenuItem->ShowPopUpMenu(this); gOldMenuItem = gNewMenuItem; } } } CPanel::OnMouseMove(nFlags, point); } LRESULT CMenuBar::OnMouseLeave(WPARAM,LPARAM) { int nCount = GetMenuItemCount(); for (int i = 0;i<nCount;i++) { CMenuItem* pMenuItem = m_vecMenuItem.at(i); if (pMenuItem) { if (pMenuItem->m_state != CMenuItem::Normal) { pMenuItem->m_state = CMenuItem::Normal; InvalidateRect(pMenuItem->m_rcMenu); } } } return 0; } void CMenuBar::OnLButtonDown(UINT nFlags, CPoint point) { g_bPressed = TRUE; int nItem = HitTest(point); if (nItem>=0) { gOldMenuItem = m_vecMenuItem.at(nItem); gOldMenuItem->m_state = CMenuItem::Pressed; InvalidateRect(gOldMenuItem->m_rcMenu); if (gOldMenuItem) { BOOL bInRect = gOldMenuItem->m_rcMenu.PtInRect(point); if (bInRect) { gOldMenuItem->ShowPopUpMenu(this); } } } CPanel::OnLButtonDown(nFlags, point); }
头文件
#pragma once #include "panel.h" #include <vector> using namespace std; class CMenuItem { public: CMenuItem(); ~CMenuItem(); public: void DrawMenu(CDC* pDC); public: enum STATE{Normal=1,Hover,Pressed}; public: CRect m_rcMenu; STATE m_state; CString m_strText; HMENU m_hPopUpMenu; public: void Draw(CDC* pDc); void ShowPopUpMenu(CWnd* pWnd); }; class CMenuBar : public CPanel { public: CMenuBar(void); ~CMenuBar(void); public: void LoadMenuFromResource(UINT nIDResource); int GetMenuItemCount(); int HitTest(CPoint pt); public: CMenu m_Menu; vector<CMenuItem*> m_vecMenuItem; public: DECLARE_MESSAGE_MAP() public: afx_msg void OnPaint(); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); public: afx_msg void onm ouseMove(UINT nFlags, CPoint point); afx_msg LRESULT onm ouseLeave(WPARAM,LPARAM); public: afx_msg void OnLButtonDown(UINT nFlags, CPoint point); };
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。