分享
 
 
 

创意无极限,用VB7制作您的个性化菜单

王朝vb·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

创意无极限,用VB7制作您的个性化菜单

现代的软件开发,由于开发工具的大幅度进步,早已经让编程变得相当简单了,大家使用同样的工具,能不能写出好的程序来,在很大的程度上来说,已经不单单是技术的较量,而更多的是创意的竞争了。如何让用户对您的软件产生好感,我想除了过硬的技术以外,我们还需要一些新奇的东西,让用户有一种耳目一新的感觉!今天我就从软件界面中最常使用的菜单方面着手,教你制作一个个性化的菜单!

VB7中的菜单,如果没有对它编写过特殊的处理程序,虽然不能说难看,但是和现在流行的Office,XP等程序的菜单相比,实在是不够漂亮,如果不想让您的软件看上去象是上个世纪的作品,那么就开始学习编写新的菜单吧!

在VB7中,有两种生成菜单的方法,一种是让系统自动生成,一种是让程序按照一定的指定方式生成。前者可以不用编程,就生成菜单,但是这并不是我们想要的;所以我们选择后者。

好,第一步,我们先在窗体上面放上一个MainMenu控件吧!至于菜单的标题,你喜欢怎么写就怎么写,为了做个示范,我的菜单如下:

文件 MenuItem1

新建 MenuItem2

打开 MenuItem3

保存 MenuItem4

退出 MenuItem5

运行一下这个窗体,我们发现在“文件”的菜单下面出现了四个关于文件的菜单项。好,第一步成功了!但这仅仅只是第一步!接下来,在进行下面的讲解前,我们假设在您的手头上面有一些图标文件,它们是C:\file.ico, C:\new.ico, C:\open.ico, C:\save.ico, C:\exit.ico ,当然如果你手上没有,也可以用其他的图标暂时代替一下,只要能有效果就可以了!好了,既然我们不要程序自动生成菜单,那么我们把这些菜单项的OwnerDraw属性修改一下,在菜单的属性框中找到OwnerDraw,并且设置成True。(这个时候再运行的话,由于还没有写菜单的生成方式,我们将看不到菜单!)

继续以前,我还要先简单说一下这个菜单的生成原理,菜单的生成靠的时两个过程,一个过程叫作:MeasureItems,另一个过程叫作DrawItem。前者的作用是对菜单的大小进行测量(Measure),后者是在测量的基础上进行绘制(Draw),我们要做的事情就是重新写这两个受保护的事件,让菜单按我们的意愿绘制出来(显示出来)。

添加一个模块,下面的添加这两个事件的具体代码,代码对初学者来说可能有些长,但是通读一遍绝对有很多好处!!我会尽量给出所有的注释。

Imports System

Imports System.ComponentModel

Imports System.Drawing

Imports System.Drawing.Drawing2D

Imports System.Drawing.Text

Imports System.Windows.Forms

'以上是这个模块要用到的一些名字空间(只是一些前缀!注意,写了这些,仅仅是为了简化下面的书写,并没有其他任何实际功能。)

Module IconsMenuMain

Sub MeasureItems(ByVal EvMeasureItem As System.Windows.Forms.MeasureItemEventArgs , ByVal Mi As MenuItem, ByVal MyFont As Font)

'开始“测量菜单”的事件

Dim sf As StringFormat = New StringFormat()

'新建的字符格式对象

sf.HotkeyPrefix = HotkeyPrefix.Show

'指定与文本相关的热键前缀的显示类型。将其设置为显示

sf.SetTabStops(60, New Single() {0})

'第一个参数firstTabOffset表示

'文本行开头和第一个制表位之间的空格数。

'第二个参数tabStops()表示

'制表位之间的距离(以空格数表示)的数组。

EvMeasureItem.ItemHeight = 22 '设置项目的高度,最好是字体的高度!!

EvMeasureItem.ItemWidth=CInt(EvMeasureItem.Graphics.MeasureString (GetRealText(Mi), MyFont, 10000, sf).Width) + 10 '设置项目的宽度

sf.Dispose()

sf = Nothing '销毁对象

End Sub

说明:上面这个事件决定了菜单的大小,也就是菜单的高度和宽度,如果您有兴趣的话,可以将高度常数22,宽度中的附加值常数10 都变成事件参数!这样就有不同高度的菜单了!下面这个事件,我就将窗体菜单的渐变色的起始色和最终色变成了参数,用来分别控制每个菜单中的文字渐变底色!

Sub DrawItems(ByVal EvDrawItems As System.Windows.Forms.DrawItemEventArgs, ByVal Mi As MenuItem, ByVal m_Icon As Icon, ByVal StartColor As Color, ByVal EndColor As Color, ByVal MyFont As Font)

Dim br As Brush '定义刷子

Dim fDisposeBrush As Boolean '是否销毁刷子的标志

If Not m_Icon Is Nothing Then

'如果没有图标

If Not Mi.Checked Then

'无论是否菜单项目被选择了,都先画图标,尽管后者什么都没有EvDrawItems.Graphics.DrawIcon(m_Icon, EvDrawItems.Bounds.Left + 2, EvDrawItems.Bounds.Top + 2)

Else

EvDrawItems.Graphics.DrawIcon(m_Icon, EvDrawItems.Bounds.Left + 2, EvDrawItems.Bounds.Top + 2)

Dim nPen As System.Drawing.Pen

If Not Mi.Enabled Then

nPen = New Pen(Color.DarkGray) '如果可用,就填充颜色DarkGray

Else

nPen = New Pen(Color.Gray) '不然用颜色Gray

End If

EvDrawItems.Graphics.DrawRectangle(nPen,1,EvDrawItems.Bounds.Top, 20, 20)

EvDrawItems.Graphics.DrawRectangle(nPen, 3, EvDrawItems.Bounds.Top + 2, 16, 16)

'画上两个框,两个框构成一个“回“字型

End If

Else

'如果有图标

If Mi.Checked Then '如果菜单处于复选状态

Dim nPen As System.Drawing.Pen 新建一个画笔对象

If Not Mi.Enabled Then 根据是否可用决定画笔颜色

nPen = New Pen(Color.DarkGray)

Else

nPen = New Pen(Color.Gray)

End If

EvDrawItems.Graphics.DrawRectangle(nPen, 1,EvDrawItems.Bounds.Top, 20, 20)

'有图标,同时被选中,则只要画“回“字型中较大的一个框

Dim Pnts() As Point

ReDim Pnts(2) '这三个点就是一个“勾“的位置

Pnts(0) = New Point(15, EvDrawItems.Bounds.Top + 6)

Pnts(1) = New Point(8, EvDrawItems.Bounds.Top + 13)

Pnts(2) = New Point(5, EvDrawItems.Bounds.Top + 10)

'根据是否可用来决定画“勾“的颜色,并且画上“勾”

当然你可以根据需要来创造您自己菜单复选的图形

If Mi.Enabled Then

EvDrawItems.Graphics.DrawLines(New Pen(Color.Black), Pnts)

Else

EvDrawItems.Graphics.DrawLines(New Pen(Color.Gray), Pnts)

End If

End If

End If

Dim rcBk As Rectangle = EvDrawItems.Bounds

rcBk.X += 24 '先获得一个和菜单一样大小的矩形,然后将矩形的X方向长度缩短,缩短的大小就是图标的大小,以后将以这个矩形作为菜单文字背景底色的填充范围

'根据菜单项目是否被选中来决定是否使用颜色渐变刷子,

'如果是则设置刷子的颜色,同时将是否销毁刷子的标志设置为真

If CBool(EvDrawItems.State And DrawItemState.Selected) Then

br = New LinearGradientBrush(rcBk, StartColor, EndColor, 0)

设置起始色和最终色

fDisposeBrush = True ‘设置刷子销毁标志

Else

br = SystemBrushes.Control ‘这个颜色是系统的默认

End If

'画上渐变的菜单文字底色

EvDrawItems.Graphics.FillRectangle(br, rcBk)

If fDisposeBrush Then br.Dispose() '前面使用New方法新建的渐变颜色刷子的实例要销毁,但是前面的声明还是有效的

br = Nothing '将整个刷子暂时清空

Dim sf As StringFormat = New StringFormat()

sf.HotkeyPrefix = HotkeyPrefix.Show

'指定与文本相关的热键前缀的显示类型。将其设置为显示

sf.SetTabStops(60, New Single() {0})

'第一个参数firstTabOffset表示

'文本行开头和第一个制表位之间的空格数。

'第二个参数tabStops()表示

'制表位之间的距离(以空格数表示)的数组。

If Mi.Enabled Then '根据菜单是否可用来决定图像刷子的颜色

br = New SolidBrush(EvDrawItems.ForeColor)

Else

br = New SolidBrush(Color.Gray)

End If

'在菜单上面写字

EvDrawItems.Graphics.DrawString(GetRealText(Mi),MyFont,br,EvDrawItems.Bounds.Left + 25, EvDrawItems.Bounds.Top + 2, sf)

br.Dispose()

br = Nothing

sf.Dispose()

sf = Nothing

End Sub

Function GetRealText(ByVal Mi As MenuItem) As String

这个事件是用来获得菜单文本的

Dim s As String = Mi.Text '获得菜单原始文本

If Mi.ShowShortcut And Mi.Shortcut <> Shortcut.None Then

Dim k As Keys = CType(Mi.Shortcut, Keys)

'如果有菜单快捷键就让菜单文本加上快捷键文本

s = s & Convert.ToChar(9) & TypeDescriptor.GetConverter(GetType(Keys)).ConvertToString(k)

End If

Return s

End Function

说明:当然您可以让菜单的文本变成任何您想要的文本!

End Module

好了,最后一步就要看看我们的实际效果了,在原来的窗体上写上代码吧!!

下面我们以“美化”第一,第二个菜单项为例子,当然,一般主菜单不应该有图标的。看懂了以后,各位按照自己的想象力来画自己的菜单好了。

Private Sub MenuItem1_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles MenuItem1.MeasureItem

第一个测量事件 ,特别注意“Handles“标志 !

Dim MyFont As New System.Drawing.Font("Arial", 8) ‘定义一个你喜欢的字体

MeasureItems(e, MenuItem1, Myfont)

End Sub

Private Sub MenuItem1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles MenuItem1.DrawItem

Dim Ic As New Icon("C:\file.ico") ‘定义一个您喜欢的图标

Dim MyFont As New System.Drawing.Font("Arial", 8) ‘这个字体最好和前面保持一致,当然如果您愿意,也可以在前面一种字体的确定范围用新字体写字,但是字体最好不要设置得太过火了,不然可能有意想不到的后果!

DrawItems(e, MenuItem2, Ic, Color.Blue, Color.Yellow, Myfont)

End Sub

Private Sub MenuItem2_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles MenuItem2.DrawItem

e.Graphics.CompositingQuality=Drawing.Drawing2D.CompositingQuality.HighQuality

Dim Ic As New Icon("C:\open.ico")

Dim MyFont As New System.Drawing.Font("Arial", 14)

DrawItems(e, MenuItem2, Ic, Color.Tomato, Color.LavenderBlush, MyFont)

End Sub

Private Sub MenuItem2_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles MenuItem2.MeasureItem

Dim MyFont As New System.Drawing.Font("Arial", 14)

MeasureItems(e, MenuItem2, MyFont)

End Sub

运行一下,你会得到一个主菜单也有图标,各个菜单项的字体和底色都不同的菜单!这只是一个演示,但是最好不要在真正的软件中这样设计,菜单应该保持统一的风格。

这篇文章只是介绍一个修改菜单的基本方法,我希望大家能够举一反三,发挥自己的创造力,制作出自己的个性化菜单来!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有