VisualC 中自绘菜单的实现
2008-04-09 04:09:50来源:互联网 阅读 ()
下载本文源代码
应用程序中的菜单,在界面中占据了重要位置,它的效果如何,直接影响了整个程序的界面效果,正因为这个原因,当今流行的应用程序的菜单都支持附带图标、反映当前状态的功能,也就是说,菜单项上不再仅仅有文字,还有附带一个小小的图标,同时在用户操作菜单时,菜单能够以不同的状态反映用户的操作,这些功能的实现,可以大大,美化程序界面,增强程序的吸引力。
Visual C 为开发人员提供了应用程序自动生成方法,使开发人员可以避开繁琐的界面开发,专著于各种功能的具体实现。虽然这种自动生成应用程序框架的手段方便了初级程序设计人员,但是它也有着先天的不足,那就是通过这种手段生成的应用程序界面比较简单,不适宜应用程序的推广。对于Visual C 自动生成的框架程序,要实现菜单的上述功能,唯一的办法就是通过菜单自绘的手段来实现,本例将通过实现CMenu类的子类CmenuEx类,详细介绍了如何编程实现菜单的自绘,使应用程序中的菜单也可以拥有图标,并且能够反映用户的不同操作,下图为程序编译运行后的效果:
图一、自绘菜单实现后的效果图
一、实现方法:
要实现漂亮的界面菜单,必须要启动菜单项的自绘功能,所谓菜单的自绘,就是让菜单自己管理自己的显示效果,为此,首先要作的就是设置菜单项的风格为MF_OWNERDRAW(自绘制),设置菜单的自绘功能即可以通过CMenu类的AppendMenu()函数在菜单的初始阶段实现,也可以通过ModifyMenu()函数对已存在的菜单项进行类型修改。
具体的菜单的自绘是通过重载CMenu类的DrawItem()函数来实现的,这个函数根据各种菜单状态,处理当前菜单项中菜单图标、文字显示的功能。DrawItem()函数的原形为:virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ),它参数为一个指向DRAWITEMSTRUCT结构的指针,DRAWITEMSTRUCT结构如下:
typedef struct tagDRAWITEMSTRUCT {
UINT CtlType; //控件类型;
UINT CtlID; //组合框、列表框等控件的ID标识号;
UINT itemID; //菜单项的ID标识号或列表框、组合框中某一项的索引值;
UINT itemAction; //控件行为;
UINT itemState; //控件状态;
HWND hwndItem; //父窗口句柄或菜单句柄
HDC hDC; //控件对应的绘图设备句柄
RECT rcItem; //控件所占据的矩形区域
DWORD itemData; //列表框或组合框中某一项的值
}
可以看出,上面的DRAWITEMSTRUCT结构包含了控件自绘时的各种信息。
其中,结构成员CtlType指定了控件的类型,其取值ODT_BUTTON表示按钮控件;ODT_COMBOBOX表示组合框控件;ODT_LISTBOX表示列表框控件;ODT_LISTVIEW表示列表视图控件;ODT_MENU菜单项;ODT_STATIC表示静态文本控件;ODT_TAB表示Tab控件。CtlID指定了自绘控件的ID值,而对于菜单项则不需要使用该成员。itemID表示菜单项ID,也可以表示列表框或者组合框中某项的索引值,对于一个空的列表框或组合框,该成员的值为-1。
itemAction指定绘制行为,其取值可以为下表中所示值的一个或者多个的联合:ODA_DRAWENTIRE表示整个控件都需要被绘制;ODA_FOCUS表示控件需要在获得或失去焦点时被绘制;ODA_SELECT表示控件需要在选中状态改变时被绘制。
itemState指定了当前绘制操作时所绘项的状态,例如,如果菜单项应该被灰色显示,则可以指定ODS_GRAYED状态标志。其取值可以为下表中所示值的一个或者多个的联合:ODS_CHECKED表示菜单项将被选中,该值只对菜单项有用;
ODS_COMBOBOXEDIT在自绘组合框控件中只绘制选择区域;
ODS_DEFAULT表示当前控件处于默认状态;
ODS_DISABLED表示控件将被禁止;
ODS_FOCUS表示控件需要输入焦点;
ODS_GRAYED表示控件需要被灰色显示,该值只在绘制菜单时使用;
ODS_HOTLIGHT表示鼠标指针位于控件之上时控件会显示高亮颜色(支持Windows 98/Me, Windows 2000/XP);
ODS_SELECTED表示选中控件;hwndItem 指定了组合框、列表框和按钮等自绘控件的窗口句柄;如果自绘的对象时菜单项,则表示包含该菜单项的菜单句柄。hDC指定了绘制操作所使用的设备环境。 rcItem指定了将被绘制的矩形区域。这个矩形区域就是上面hDC的作用范围。系统会自动裁剪组合框、列表框或按钮等控件的自绘制区域以外的部分。也就是说rcItem中的坐标点(0,0)指的就是控件的左上角。但是系统不裁剪菜单项,所以在绘制菜单项的时候,必须先通过一定的换算得到该菜单项的位置,以保证绘制操作在我们希望的区域中进行。
itemData这个成员变量最为关键,菜单自绘时所需要的图标、文本等信息都是通过它获取的,至于它的具体值,是通过CMenu类的CMenu::AppendMenu()、CMenu::InSertMenu()、CMenu::ModifMenu()等函数的调用来传递的。
菜单自绘仅仅重载CMenu::DrawItem()函数是不够的,还需要重载CMenu:: MeasureItem()函数,在这个函数里面填充MEASUREITEMSTRUCT结构,通知Windows自绘控件的尺寸。该函数的原形为:
virtual void MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct );
该函数的参数为一个指向MEASUREITEMSTRUCT结构的指针对象,该对象结构为:
typedef struct tagMEASUREITEMSTRUCT {
UINT CtlType; //控件类型;
UINT CtlID; //控件的ID识别号,它不包括菜单控件;
UINT itemID; //菜单项的ID识别号;
UINT itemWidth; //菜单项的宽度;
UINT itemHeight; //菜单项的高度;
DWORD itemData //自绘控件所需要的数据,
} MEASUREITEMSTRUCT;
上面这个结构中,成员变量CtlType等于ODT_COMBOBOX 时,表示当前控件为自绘型的组合框,等于ODT_LISTBOX 时表示当前控件为自绘列表控制件,等于ODT_MENU 时表示当前控件为自绘菜单。对于组合框和列表框控件,成员变量itemData是通过相应的AddString()、InsertString()获取的, 对于菜单控件,成员变量itemData与DRAWITEMSTRUCT结构中的itemData是一致的。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:用VC 模拟实现QQ密码盗窃软件
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash