| 完美实现真彩自绘菜单 下载源代码
二、解决问题 // 声明,因为下面的结构要用到 CMenuEx*,又不支持向后引用,又什么办法啊!class CMenuEx;//自绘菜单数据项结构,就是要传给系统的那个牛X的LPCTSTR指针所指向的东东class CMenuEx : public CMenu{DECLARE_DYNAMIC( CMenuEx )// Constructorpublic:CMenuEx();virtual ~CMenuEx();virtual BOOL DestroyMenu();// Operationpublic:// 加载菜单操作BOOL LoadMenu(UINT nIDResource);BOOL LoadMenu(LPCTSTR lpszResourceName);BOOL LoadMenu(HMENU hMenu);BOOL LoadMenu(CMenu & Menu);// 菜单项操作,如果当前菜单为主菜单(top-level)就调用相应的CMenu的操作。如果是弹出菜单, // 就将新加入的菜单项定义为自绘菜单BOOL AppendMenu(UINT nFlags, UINT nIDNewItem = 0,LPCTSTR lpszNewItem = NULL);BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT nIDNewItem=0,LPCTSTR lpszNewItem=NULL );BOOL ModifyMenu(UINT nPosition,UINT nFlags,UINT nIDNewItem=0,LPCTSTR lpszNewItem=NULL );BOOL RemoveMenu(UINT nPosition, UINT nFlags);// 加载菜单图像操作//通过菜单索引表加载图像索引,此操作必须在设置过菜单图像后调用void SetImageIndex(const UINT* nIDResource,UINT nIDCount);void LoadToolBar(const CToolBar* pToolBar);// 通过工具栏加载图像,和图像索引// 取自绘菜单项的数据项UINT GetMenuItemSize() const;LPMENUITEM GetMenuItem(UINT nPosition);// 取子菜单操作,如果位置nPosition存在子菜单,返回该子菜单指针// 如果不存在子菜单,返回NULLCMenuEx* GetSubMenu(int nPosition);// 在当前菜单和所以子菜单中中寻找相应ID// 如果找到,返回ID所在菜单的指针,没找到返回NULLCMenuEx* FindPopupMenuFromID(UINT nID);// Attributesprotected:// 指示为主菜单(top-level menu or menubar)还是弹出菜单(popupmenu)BOOL m_bPopupMenu;// 分割条的默认高度int m_nSeparator;// 绘制菜单需要的颜色COLORREF m_crBackground;// 菜单背景色COLORREF m_crTextSelected;// 菜单项被选中时的文字颜色COLORREF m_crText;// 菜单项文字颜色COLORREF m_crLeft;// 菜单左侧的背景颜色COLORREF m_crSelectedBroder;// 菜单选中框的线条颜色COLORREF m_crSelectedFill;// 菜单选中框的填充颜色// 菜单项图像的尺寸CSize m_szImage;CImageList* m_pImageList;// 菜单项正常的图像列表 CImageList* m_pDisabledImageList;// 菜单项禁用时的图像列表CImageList* m_pHotImageList;// 菜单项被选中时的图像列表protected:// 包含所有菜单项的数组CArray m_MenuItemArr;public:// 设置颜色操作void SetTextSelectedColor(COLORREF color);void SetBackgroundColor(COLORREF color);void SetTextColor(COLORREF color);void SetLeftColor(COLORREF color);void SetSelectedBroderColor(COLORREF color);void SetSelectedFillColor(COLORREF color);// 设置图像列表操作void SetImageList(CImageList* pImageList);void SetDisabledImageList(CImageList* pImageList);void SetHotImageList(CImageList* pImageList);// 设置当前菜单为主菜单还是弹出菜单void SetPopupMenu(BOOL bPopupMenu);// Implementationpublic:// 绘制菜单项的虚拟函数,由MFC框架自动调用virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);// 更新弹出菜单菜单项操作// 因为有时候系统会通过菜单句柄插入一些非自绘菜单// 该函数就是更新这些非自绘菜单为自绘菜单void UpdatePopupMenu();protected:// 绘制菜单项的辅助函数,想自己的菜单看上去更COOL,就拿他们开刀void DrawBackground(CDC* pDC,CRect rect);void DrawMenuImage(CDC* pDC,CRect rect,LPDRAWITEMSTRUCT lpDIS);void DrawMenuText(CDC* pDC,CRect rect,LPDRAWITEMSTRUCT lpDIS);void DrawSelected(CDC* pDC,CRect rect,LPDRAWITEMSTRUCT lpDIS);// Static Memberpublic:// 在CMainFrame的OnMeasureItem()消息映射函数中调用它,用来测量所有菜单项尺寸static void MeasureItem(LPMEASUREITEMSTRUCT lpMIS);// 在CMainFrame的OnInitPopupMenu()消息映射函数中调用它,// 用来更新系统自动添加的菜单项为自绘菜单static void InitPopupMenu(CMenu* pPopupMenu,UINT nIndex,BOOL bSystem);};#endif // !defined(MENUEX_H) 三、实现方法 有了以上的强有力的武器,就可以对我们的程序下手了:)在MDI或SDI中使用CMenuEx的时候需要修改以下地方。
三、总结 |