没人看我代码一贴完事
//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 paintingint 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 OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM,LPARAM);
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};
VC 菜单栏的自绘(二)