用MFC创建菜单按钮

来源:互联网 发布:qq数据库.7z.001 编辑:程序博客网 时间:2024/05/16 04:46

现在有不少的软件都有这样的一种界面效果:当用户单击某一个按钮之后,并不

是简单地执行某种功能或弹出一个对话框,而是在按钮旁边弹出一个菜单,让用

户作更详细地选择,这在某种程度上就代替了简单的对话框,而且较对话框更

"用户友好"。这样的按钮基本上有两种类型:在按钮上显示文字的和在按钮

上显示箭头的,显示箭头常见的有向右的和向下的两种,还有向上的和向左的。

图示为常见的风格,即向下的箭头和在按钮左下角弹出菜单。那么,我们在编

程时如何实现这一功能呢?

---- 我们知道,MFC中的CButton类有一个虚函数名叫DrawItem(),若在对话框

模板中为控件指定了BS_OWNERDRAW风格,则在运行时将调用这个函数来画按钮,

CMenu类的成员函数TrackPopupMenu()则可以在屏幕的任何位置弹出菜单。由

上得到启发,只要我们合理地使用这两个函数,就能创建出"菜单按钮"来。

 

---- 下面的CMenuButton类封装了全部的这些功能,让我们先来看一下它的制作

原理。

 

---- 在取得了按钮的矩形区域之后,取其一个角落的值传递给

TrackPopupMenu()函数即可实现弹出菜单,在TrackPopupMenu内部使用

TPM_RETURNCMD标志可以得到用户选择的菜单的命令ID,以供进一步的处理;

在重载了DrawItem()函数之后,我们可以在函数的内部使用

CDC::DrawFrameControl()函数来画出基本的按钮外观,再在中间部位画一个箭

头即可。箭头可以用Marlett字体来画。也许有人会担心,若果其他人的机器没

Marlett字体怎么办?其实,任何一台安装Windows的机器离开了Marlett字体

都无法正常工作,先请看下图,这是Windows"系统工具"中自带的"字符映射表"。

 

 

---- 看到最上面一行中的那几个箭头了吗?就是要把它们画在按钮上。等一等,

另外的几个符号怎么也那么熟悉?这不就是几乎每个窗口上都有的"最小化"、

"还原"、"关闭"和"最大化"按钮吗?不错,Windows正是使用这几个字符在标题

栏上绘图的。其实,Windows中的最"标准"的画箭头的方法就是使用Marlett字

体,无论是工具栏上的箭头还是组合框中的箭头,都是这样画出的。有时,在乱

 

删了字体之后,组合框或工具栏的下拉箭头会变成数字6或者9,为什么?看到

状态栏上的"击键值"了吗?--"6",往右数,那个小一点的下箭头正好是--"9"。

 

 

---- 下面是具体的制作过程。

 

---- 首先,生成一个MFC AppWizard EXE 工程,最好是基于对话框的工程,当

然,利用现有的工程也可以。生成一个以CButton为基类的新类,名为

CMenuButton,然后用ClassWizard为其添加两个成员函数:DrawItem()

PreSubclassWidnow();手工为CMenuButton类添加BOOL类型m_bDrawFocusRect

成员变量,用于决定是否在按钮上画焦点矩形,添加SetDrawFocusRect()函数用

于设置这个标志,默认为画焦点矩形;添加两个枚举类型的变量m_ArrowType和

m_PopupPos,用于决定所画的箭头的类型和菜单弹出的位置。箭头可为右箭头、

下箭头、小右箭头、小下箭头、上箭头和左箭头(参见本文开始处的图);菜单

的弹出位置可以为按钮的左上角、右上角、左下角和右下角。最后手工添加两

个函数,SetArrowType()和SetMenuPopupPos(),用于设置以上各种风格,其默

值分别为画右箭头和在左下角弹出。如果只需要菜单而不需要画箭头,只需置空

BS_OWNERDRAW标志位即可,添加一个SetStyle()函数,用于设置是画箭头还是显

示文本,其默认值是画箭头。 为方便处理按钮的BN_CLICKED通知消息,为

CMenuButton类创建一个公有的成员函数OnClick(),以便在BN_CLICKED的消息处

理器中调用。它有两个参数,第一个是菜单资源的ID,第二个参数为子菜单的

ID,默认为0。如果只有一组子菜单,则可使用其默认值0。OnClick()函数的

返回值为所选的菜单项的命令ID,若未作任何有效选择,则返回0。 

原创粉丝点击