用C#和VB.NET实现VS.NET或Office XP风格的菜单(二)

菜单

用C#和VB.NET实现VS.NET或Office XP风格的菜单

小气的神 2001.08.18

2.“Owner-drawn menus”技术

这个例子是VB.NET语法的.我去掉了和Menu无关的Class,原因是错误太多,你会遇到类库和命名空间的移植性的问题:

最多的是Beta1 System.WinForms 和Beta 2 的System.Windows.Froms的命名空间问题;

然后是Beta1中的BitAnd 、BitOR等等Bitxxx的函数在Beta2中已去掉了Bit又和VB中一样了(据说Beta1的这项改动遭到了总多VB Fans的投诉,说不能把VB也C#化,Bit是什么东东),这样你需要把这类函数改掉;

然后是NameObjectCollectionBase从原来的system.collections中删除了,Beta2放在system.collections.specialized 中,真的有些昏倒,开始我还以为Beta2中删除了这个类。

最后是一些Overrides和 Overloads的问题,具体的看VS.NET或Framework SDK Beta 2编译时的提示就可以了,这方面MS做得不错,Task list中告诉你具体得建议,照做就是了。

具体一点你可以在Framework SDK Beta 2安装目录的Doc目录中找到这两个文件,这是从Beta1移植到Beta2上不错的指导文件:APIChangesBeta1toBeta2.htm 和Change List - Beta1 to Beta2.doc 特别是这个doc文件洋洋洒洒90多页,但很有帮助。

希望你还能在排除所有的错误之后保持清醒,找到最核心有用的代码,来分析。主要是CActionMenu.vb,焦点在OnMeasureItem和OnDrawItem这两个函数或说事件处理程序上。OnMeasureItem主要是处理MenuItem的ItemHeight和ItemWidth的,从它传的MeasureItemEventArgs参数数就知道。OnDrawItem主要是如何画菜单的问题。关键字Overrides表明我们要在子类中重新定义MenuItem中的这两个方法。

从56行到58行是OnMeasureItem函数:

Protected Overrides Sub OnMeasureItem(ByVal e As System.Windows.Forms.MeasureItemEventArgs)

If Me.Action.Caption = "-" Then

e.ItemHeight = 5

Else

e.ItemHeight = 20

End If

Dim fs As FontStyle

If Me.DefaultItem = True Then fs = fs Or FontStyle.Bold

Dim fnt As New Font("Tahoma", 8, fs)

Dim sf As SizeF = e.Graphics.MeasureString(Me.Action.Caption, fnt)

fnt.Dispose()

e.ItemWidth = CInt(sf.Width) + 20

End Sub

MeasureItemEventArgs提供4个属性Graphis、Index、ItemHeight和ItemWidth。Me相当于C#或Java的this关键字。fnt.Dispose()中Dispose是一个很有意思的函数调用,在以往的Windows编程中象字体、画笔等许多资源都希望快使用快释放,这个语句是用来控制GC(garbage collection)的,意思是我已使用完了这个设备或资源,GC你可以收回了。

从70到146行是有关OnItemDraw函数的:

Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)

' colors, fonts

Dim clrBgIcon, clrBgText, clrText As Color, fs As FontStyle, fnt As Font

Dim b As SolidBrush, p As Pen

Dim fEnabled As Boolean = Not CType(e.State And DrawItemState.Disabled, Boolean)

Dim fSelected As Boolean = CType(e.State And DrawItemState.Selected, Boolean)

Dim fDefault As Boolean = CType(e.State And DrawItemState.Default, Boolean)

Dim fBreak As Boolean = (Me.Action.Caption = "-")

If fEnabled And fSelected And Not fBreak Then

clrBgIcon = Color.Silver

clrBgText = Color.White

clrText = Color.Blue

fs = fs Or FontStyle.Underline

Else

clrBgIcon = Color.Gray

clrBgText = Color.Silver

clrText = Color.Black

End If

If Not fEnabled Then

clrText = Color.White

End If

If fDefault Then

fs = fs Or FontStyle.Bold

End If

fnt = New Font("Tahoma", 8, fs)

' total background (partly to remain for icon)

b = New SolidBrush(clrBgIcon)

e.Graphics.FillRegion(b, New [Region](e.Bounds))

b.Dispose()

' icon?

If Not Me.Action.ActionList Is Nothing Then

Dim il As ImageList = Me.Action.ActionList.ImageList

If Not il Is Nothing Then

Dim index As Integer = Me.Action.Image

If index > -1 And index < il.Images.Count Then

Dim rect As Rectangle = e.Bounds

With rect

.X += 2

.Y += 2

.Width = 16

.Height = 16

End With

e.Graphics.DrawImage(il.Images.Item(index), rect)

End If

End If

End If

' text background

Dim rf As RectangleF

With rf

.X = 18

.Y = e.Bounds.Y

.Width = e.Bounds.Width - .X

.Height = e.Bounds.Height

End With

b = New SolidBrush(clrBgText)

e.Graphics.FillRegion(b, New [Region](rf))

b.Dispose()

' text/line

rf.Y += 3 : rf.Height -= 3

If Not fBreak Then

b = New SolidBrush(clrText)

e.Graphics.DrawString(Me.Action.Caption, fnt, b, rf)

fnt.Dispose()

b.Dispose()

Else

p = New Pen(Color.Black)

rf.Y -= 1

e.Graphics.DrawLine(p, rf.X, rf.Y, rf.Right, rf.Y)

p.Dispose()

End If

' border

If fEnabled And fSelected And Not fBreak Then

p = New Pen(Color.Black)

e.Graphics.DrawRectangle(p, e.Bounds)

p.Dispose()

End If

End Sub

DrawItemEventArgs参数给了你和菜单相关的所有环境和信息,它包括6个属性:Bounds、Font、ForeColor、Graphics、Index、States。如果你以前用过Windows下的GDI函数,那一定很熟悉这些函数,不是很复杂只需要你一点点算术知识和美术观点就可以了,如果你是第一次那么在纸上画几个矩形块就可以了理解和做的很好,比起以前TC下的菜单编程容易得多。主要是作者是如何把Icon画在菜单上的,然后是根据不同的States表现一下菜单的ForeColor, Bounds就是菜单项最前面的表示选中等等的小方块。

好了第二部分涉及到了大部分技术细节了,这里你需要关注的是,如何画出来,下一部分我们来看如何画的好看些,象VS.NET或Office XP那样子。

时间: 2024-11-02 15:47:01

用C#和VB.NET实现VS.NET或Office XP风格的菜单(二)的相关文章

用C#和VB.NET实现VS.NET或Office XP风格的菜单(一)

菜单 用C#和VB.NET实现VS.NET或Office XP风格的菜单 小气的神 2001.08.18 VS.NET或Office XP中的菜单都是非常漂亮的,反正我很喜欢.可惜VS.NET没有带制作这种菜单的控件或组件,不知正式版本会不会提供一个模板和向导.至今还记得刚学计算机语言时自己用Turbo C制作菜单的感受,那些矩形框函数和象素操作的确很迷人,况且那时是如此的流行菜单. 这篇文章中我会介绍有关在Framework SDK Beta 2 中制作自己风格的菜单,所以你最好已安装了Fra

用C#和VB.NET实现VS.NET或Office XP风格的菜单(三)

菜单 用C#和VB.NET实现VS.NET或Office XP风格的菜单 小气的神 2001.08.18 3. "MenuItemStyle"接口和VS.NET风格的菜单项 这个Project又将切换到C#语言.我是这样想的:先针对普通菜单.Office200风格.VS.NET风格三种情况定义一个统一的接口(interface),其中包括画Icon(DrawIcon).画分割条(DrawSeparator).画菜单背景(DrawBackground).写菜单项的文字(DrawMenuT

VB编程实现Windows XP风格的界面

虽然WindowsXP的界面非常华丽.但是令人遗憾的是,我们用VB写的程序除了菜单和窗口的外观是XP风格外,其他控件还是一如既往的是普通风格.我想,有的程序在XP下有XP的风格,VB也一定有办法实现XP的风格.后来笔者在网上看到一篇介绍XML的文章,又在网上找到了一篇实现XP风格的文章,经过自己的实践,终于找到了VB程序实现XP风格的办法.为了使其他的网友不至于走像我这样的多的弯路,将此办法写出来,与大家共同提高!! 具体的实现方法如下: ①:在你的窗体加入代码.如果是多个窗口,可以将此代码放到

vb.net 读取Excel表,Office认为文件有问题,受保护,不让打开

问题描述 别人的程序可能有BUG,凡是它导出的Excel都会出现"excel检测到此文件存在一个问题,打开此文件可能有危险,仅应打开受信任的文件."的报警.需要手动点击"打开",再到点击上方红色条,找到"仍然编辑",才能对这个Excel表进行操作.现在我自己用vb.net写一个程序,就是要打开这个Excel来进行自动排版,一打开就会报错,就是上面那个报警,有什么办法可以无提示的打开这个文件呢?手工"另存为"的方法不用说了,我希

VB.NET里最方面的XP风格解决方案

解决   将以下代码添加到InitializeComponent()之后 On Error Resume Next        Dim y As Integer        Dim AppName As String        Dim ManFileName As String        Dim FullAppExeNameAndPath As String        FullAppExeNameAndPath = Application.ExecutablePath      

vb变量、常数和数据类型及过程概述(十二)

If...Then...Else用 If...Then...Else 块定义几个语句块,执行其中一个语句:If condition1 Then[statementblock-1][ElseIf condition2 Then[statementblock-2]] ...[Else[statementblock-n]]End IfVisual Basic 首先测试 condition1.如果它为 False,Visual Basic就测试condition2,依此类推,直到找到一个为 True 的

vb.net中如何制作自动搜索的下拉菜单?

问题描述 就像这样的,例如输入1,自动去数据库查询某字段含1的所有数据字段,并且显示在下拉菜单中? 解决方案 解决方案二: 解决方案三:我看了别的资料,说是用combobox.AutoComplete属性,这个怎么用啊解决方案四:lookupedit?解决方案五:lookupedit是什么呀解决方案六:搜索:asp.net自动补全解决方案七:用文字改变的触发事件,刷新下拉表.解决方案八: 解决方案九:webForm的话,可以用jQuery的Autocomplete(自动完成.自动填充)插件完成

VB打造超酷个性化菜单(一)

菜单 VB打造超酷个性化菜单(一) 众所周知,MS Office 2003推出已经有一段时间了,但我们依然不会忘记Office XP刚刚推出时其令人耳目一新的菜单给我们留下的深刻印象.突起的悬浮式图标,不同寻常的菜单项填充方式,不仅让办公一族们赞不绝口,更让广大的程序员和编程爱好者对这种风格的菜单的制作产生了浓厚的兴趣.所以,在这篇文章里,我们就来好好地研究研究用VB怎么制作这种风格的菜单,在文章的最后,我将给出源代码的下载地址.事实上,在了解其原理以后,不论是用VB.VC还是Delphi,都能

vb.net的MainMenu控件

MainMenu(主菜单)控件是vb.net用来取代Visual Basic以前版本的"菜单编辑器".MainMenu控件较"菜单编辑器"有很大优势,因为以控件的"身份",更有利于应用程序对整个菜单的操作,而且,可以实现不同窗体的多次利用,而不必每个窗体都要重新设计菜单.MainMenu控件在工具箱中的图标如图所示: 1.在设计时添加MainMenu控件 添加MainMenu控件与添加其他控件的方法一样(双击或拖动),但是MainMenu控件本身