CMenu自绘

来源:互联网 发布:c语言自学软件手机版 编辑:程序博客网 时间:2024/06/05 00:37

1、创建一个CMenu类的派生类,并重写DrawItem(LPDRAWITEMSTRUCT lpDS)、MeasureItem(LPMEASUREITEMSTRUCT lpMS)函数:

如下:

#pragma once#include "afxwin.h"class CMyMenu :public CMenu{public:CMyMenu(void);~CMyMenu(void);private:struct SItem{HICON hIcon;char szText[32];int nHeight;};CMap<WORD,WORD,SItem,SItem> m_map;//菜单Id与对应的节点信息public:virtual void DrawItem(LPDRAWITEMSTRUCT lpDS);virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMS);BOOL AppendMenu(UINT_PTR nIDNewItem = 0,LPCTSTR lpszNewItem = NULL ,HICON hIcon = NULL,UINT nFlags = 0);};

#include "StdAfx.h"#include "MyMenu.h"CMyMenu::CMyMenu(void){}CMyMenu::~CMyMenu(void){}void CMyMenu::DrawItem(LPDRAWITEMSTRUCT lpDS){CDC* pDC = CDC::FromHandle(lpDS->hDC);CRect rect = lpDS->rcItem;CString strText;SItem &sItem = m_map[lpDS->itemID];if(lpDS->itemID) strText = sItem.szText;//选中状态菜单项:画边线和浅蓝色填充if((lpDS->itemState & ODS_SELECTED)&&(lpDS->itemAction & ODA_SELECT)){pDC->FillSolidRect(&rect,::GetSysColor(COLOR_MENU));rect.DeflateRect(1,1);CPen pen(PS_SOLID,1,GetSysColor(COLOR_HIGHLIGHT));CBrush br(RGB(182,189,210));pDC->SelectObject(&pen);pDC->SelectObject(br);pDC->Rectangle(rect);}else//非选中状态:普通背景填充{pDC->FillSolidRect(&rect,GetSysColor(COLOR_MENU));if (rect.Height() == 10)//如果是分隔条菜单:画两条线{CPen pen1(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW));pDC->SelectObject(&pen1);pDC->MoveTo(rect.left+2,rect.top+4);pDC->LineTo(rect.right-2,rect.top+4);CPen pen2(PS_SOLID,1,GetSysColor(COLOR_HOTLIGHT));pDC->SelectObject(&pen2);pDC->MoveTo(rect.left+2,rect.top+5);pDC->LineTo(rect.right-2,rect.top+5);return;}rect.DeflateRect(1,1);}//画图标pDC->DrawIcon(rect.left+1,rect.top+1,sItem.hIcon);pDC->SetBkMode(TRANSPARENT);    rect.left+=35;pDC->DrawText(strText,rect,DT_LEFT|DT_VCENTER|DT_SINGLELINE);}void CMyMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMS){lpMS->itemWidth = 80;//菜单项的宽度lpMS->itemHeight = m_map[lpMS->itemID].nHeight;//每个菜单项的高度}BOOL CMyMenu::AppendMenu(UINT_PTR nIDNewItem,LPCTSTR lpszNewItem,HICON hIcon,UINT nFlags){//将菜单的文字和图标信息按照ID进行登记,以便自绘时使用SItem sItem = {hIcon};if(lpszNewItem) strcpy(sItem.szText,lpszNewItem);if(nFlags & MF_SEPARATOR) sItem.nHeight = 10;else sItem.nHeight = 35;//根据ID添加到map中m_map[nIDNewItem] = sItem;//每个插入的菜单项都自动添加自绘属性return CMenu::AppendMenu(nFlags|MF_OWNERDRAW,nIDNewItem,lpszNewItem);}

2、在主对话框的视图类的OnContextMenu(CWnd* pWnd, CPoint point)函数中进行弹出式菜单的操作:

void CMenu自绘View::OnContextMenu(CWnd* pWnd, CPoint point){CMyMenu Menu;Menu.CreatePopupMenu();HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);Menu.AppendMenu(ID_EDIT_UNDO,"撤销",hIcon);//hIcon = AfxGetApp()->LoadIcon(IDI_ICON2);Menu.AppendMenu(ID_EDIT_CUT,"剪切",hIcon);//hIcon = AfxGetApp()->LoadIcon(IDI_ICON3);Menu.AppendMenu(ID_FILE_SAVE,"保存",hIcon);//hIcon = AfxGetApp()->LoadIcon(IDI_ICON4);Menu.AppendMenu(ID_FILE_SAVE_AS,"另存为",hIcon);Menu.AppendMenu(0,NULL,0,MF_SEPARATOR);Menu.TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,this);}

如图:


原创粉丝点击