Simple Bitmapped menu items
2002-05-02 10:22
836 查看
简单位图菜单<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
这篇文章由Burchak Alexander原著。
有时应用程序使用动态创建的工具条。为什么我要为了位图菜单而创建工具条资源呢?(查看Iuri Apollonio 文章)
我提议装配菜单位图时使用标准位图表。我这个类的优点是位图和工具条图像可以用尺寸和视图等来区分。此类支持SDI和MDI用户界面中的弹出菜单。若你发现了bugs请提出来。
所有你对类CbitmapMenu要做的事是:
1. 添加CbitmapMenu类的实例给CmainFrame 类:
CbitmapMenu m_menu;
2. 添加一个CimageList对象。例如,给CmainFrame类添加其static 成员 :
CimageList m_imglist;
At the point you have in MainFrm.h:#include "BitmapMenu.h"
class CMainFrame : public CMDIFrameWnd
{
...
public :
CBitmapMenu m_menu;
static CImageList m_imglist;
...
};
在MainFrm.cpp中添加:#include "MainFrm.h"
CImageList CMainFrame :: m_imglist;
3.给这个项目添加N个图象资源。其中一个作为checkmark.
4.为菜单项添加一组CitemBitmap 对象(比如添加到MainFrm.cpp中),这些菜单项将显示位图。CItemBitmap g_ibs[ ] =
{
CItemBitmap(ID_FILE_NEW, &CMainFrame :: m_imglist, 0),
CItemBitmap(ID_FILE_OPEN, &Camp;MainFrame :: m_imglist, 1),
CItemBitmap(ID_HELP_CONTENTS, &CMainFrame :: m_imglist, 19),
CItemBitmap(-1, NULL, 0, &CMainFrame :: m_imglist, 27)
};
CitemBitmap类有2个构造器:CItemBitmap( UINT uID,CImageList *pilNormal,UINT uPosNormal);
CItemBitmap( UINT uID,CImageList *pilNormal,UINT uPosNormal,CImageList *pilChecked, UINT uPosChecked);
其中,
uID---菜单项ID,
pilNormal---CimageList 对象指针,使用一个位图作为“正常”菜单项状态,
pilChecked--- CimageList 对象指针,使用一个位图作为“检查”菜单项状态,
uPosNormal---在pilNormal图像列表中的图像索引,
uPosChecked---在pilChecked图像列表中的图像索引,
列表中的最后个CitemBitmap对象用来保存checkmark图象信息。
这个CbitmapMenu类用来画checked状态的菜单项。
5.在CmainFrame::OnCreate()函数中处理如下: m_menu.Initialize(IDR_MAINFRAME, this);
m_menu.AddBitmaps( g_ibs,sizeof(g_ibs) / sizeof(CItemBitmap));
6. 在CmainFrame 类中添加WM_MEASUREITEM, WM_DRAWITEM 和WM_INITMENUPOPUP 消息处理函数。
添加CmainFrame 类的消息映射: ON_WM_MEASUREITEM( )
ON_WM_DRAWITEM( )
ON_WM_INITMENUPOPUP( )
在CmainFrame类中添加下边函数: void CMainFrame :: OnMeasureItem(int nIDCtl,LPMEASUREITEMSTRUCT lpMIS)
{
if(lpMIS->CtlType == ODT_MENU)
m_menu.MeasureItem( lpMIS );
else
CMDIFrameWnd :: OnMeasureItem(nIDCtl, lpMIS);
}
void CMainFrame :: OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpDIS)
{
if(lpDIS->CtlType == ODT_MENU)
m_menu.DrawItem( lpDIS );
else
CMDIFrameWnd :: OnDrawItem(nIDCtl, lpDIS);
}
void CMainFrame :: OnInitMenuPopup(CMenu *pPopup,UINT nIndex,BOOL bSysMenu)
{
CMDIFrameWnd :: OnInitMenuPopup( pPopup,nIndex,bSysMenu);
if( !bSysMenu )
CBitmapMenu :: Synchronize( pPopup );
}
6.可选: 如果你想在视类中使用弹出式位图菜单,可按如下:
CMenu menu;
VERIFY( menu.LoadMenu( SOME_POPUP_MENU_RESOURCE_ID ) );
CMenu *pMenu = (CMenu *) menu.GetSubMenu( 0 );
ASSERT(pMenu != NULL);
pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, x, y, AfxGetMainWnd( ));
我们在TrackPopupMenu()中使用AfxGetMainWnd(),让主框架更新菜单项状态。如果你欲要使用“this”作为弹出菜单的父类,会存在两个问题:
1. 你需要手工check/gray/enable/disable 菜单项。
2. 你需要为了适当的绘制位图菜单而添加下面三个消息处理函数。
我并没提供第一个问题的解决办法。第二个问题的办法是在CmainFrame类中为相同消息添加处理函数: ON_WM_MEASUREITEM( )
ON_WM_DRAWITEM( )
ON_WM_INITMENUPOPUP( )
处理体如下:void CMyEditView :: OnMeasureItem(int nIDCtl,LPMEASUREITEMSTRUCT lpMIS)
{
if(lpMIS->CtlType == ODT_MENU)
((CMainFrame *) AfxGetMainWnd( ))->m_menu.MeasureItem( lpMIS );
else
CEditView :: OnMeasureItem(nIDCtl, lpMIS);
}
void CMyEditView :: OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpDIS)
{
if(lpDIS->CtlType == ODT_MENU)
((CMainFrame *) AfxGetMainWnd( ))->m_menu.DrawItem( lpDIS );
else
CEditView :: OnDrawItem(nIDCtl, lpDIS);
}
void CMyEditView :: OnInitMenuPopup(CMenu *pPopup,UINT nIndex,BOOL bSysMenu)
{
CEditView :: OnInitMenuPopup(pPopup,nIndex,bSysMenu);
if( !bSysMenu )
CBitmapMenu :: Synchronize( pPopup );
}
全文完。
相关文章推荐
- 用Ole Automation实现Delphi和AutoCad之间的数据交换
- ATL实现Connection Point的一种简单的方法
- 力争最简单把*、&说清楚
- 怎样为任何控件和区域添加提示信息:用自己封装的CTip类
- 使用C#开发COM+组件
- 通过SDK函数实现WIN32应用程序的唯一实例。
- WIN32 SDK - 捕获鼠标离开和滞留等事件
- 让应用程序禁止Windows屏幕保护
- Internet浏览提速技巧
- 如何实现SDI与MDI的转换?
- VB中得到当前目录API定义
- 怎样在一个一般窗口或是Dialog上面使用分割窗口.
- 存储过程实现BBS树形结构
- 基 于Win95 TAPI 的 调 制 解 调 器 编 程
- OICQ登录号码清除器实现原理
- 用VC++搞定应用软件图标
- LINUX中怎样限制不能使用FTP的用户
- GNU GRUB启动管理器
- 网络安全系列之三十七 Pangolin(穿山甲)和Havij(胡萝卜)的使用 推荐
- 测试常用辅助工具汇总