1. 在Form1.VB中的MenuItem1的MeasureItem事件处理程序之后添加下列代码,下列代码是定义MenuItem2的DrawItem事件,其功能是对"新建"菜单项重新绘制:
Private Sub MenuItem2_DrawItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.DrawItemEventArgs ) Handles MenuItem2.DrawItem
Dim rfBound As RectangleF = New RectangleF ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height )
'根据DrawItemEventArgs参数获得菜单项矩形区域并存储到RectangleF类型实例中
Dim rfBound1 As Rectangle = New Rectangle ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height )
'根据DrawItemEventArgs参数获得菜单项矩形区域并存储到Rectangle类型实例中
'Rectangle类型实例和RectangleF类型实例差不多,但在后面代码中绘制菜单的函数是有区别的
e.Graphics.FillRectangle ( New SolidBrush ( Color.LightGray ) , rfBound )
Dim s As MenuItem = CType ( sender , MenuItem )
Dim s1 As String = s.Text
'获得菜单项对应的文本名称
Dim sfTemp As StringFormat = New StringFormat ( )
sfTemp.Alignment = StringAlignment.Center
'设定文本在矩形区域的对齐方式
sfTemp.LineAlignment = StringAlignment.Center
Dim rcText As RectangleF = rfBound
rcText.Width -= 5
e.Graphics.DrawString ( s1 , New Font ( "宋体" , 10 ) , New SolidBrush ( Color.Blue ) , rcText , sfTemp )
e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.LightGray ) ) , rfBound1 )
If e.State = ( DrawItemState.NoAccelerator Or DrawItemState.Selected ) Then
e.Graphics.FillRectangle ( New SolidBrush ( Color.LightYellow ) , rfBound )
e.Graphics.DrawString ( s1 , New Font ( "宋体" , 10 , FontStyle.Bold Or FontStyle.Underline ) , New SolidBrush ( Color.Red ) , rcText , sfTemp )
e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.Black ) ) , rfBound1 )
e.DrawFocusRectangle ( )
End If
End Sub
2. MenuItem2的DrawItem事件处理代码之后添加下列代码,下列代码是定义MenuItem2的MeasureItem事件,在此事件中实现设定"新建"菜单项的长度和高度:
Private Sub MenuItem2_MeasureItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.MeasureItemEventArgs ) Handles MenuItem2.MeasureItem
e.ItemWidth = 60
'设定菜单项的宽度
e.ItemHeight = 30
'设定菜单项的高度
End Sub
3. 在完成上述操作步骤后,再在MenuItem2的MeasureItem事件处理程序之后添加下列代码,下列代码是定义MenuItem3的DrawItem事件,其功能是对"打开"菜单项重新绘制:
Private Sub MenuItem3_DrawItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.DrawItemEventArgs ) Handles MenuItem3.DrawItem
Dim rfBound As RectangleF = New RectangleF ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height )
'根据DrawItemEventArgs参数获得菜单项矩形区域并存储到RectangleF类型实例中
Dim rfBound1 As Rectangle = New Rectangle ( e.Bounds.X , e.Bounds.Y , e.Bounds.Width - 1 , e.Bounds.Height )
'根据DrawItemEventArgs参数获得菜单项矩形区域并存储到Rectangle类型实例中
'Rectangle类型实例和RectangleF类型实例差不多,但在后面代码中绘制菜单的函数是有区别的
Dim s As MenuItem = CType ( sender , MenuItem )
Dim s1 As String = s.Text
Dim sfTemp As StringFormat = New StringFormat ( )
sfTemp.Alignment = StringAlignment.Center
sfTemp.LineAlignment = StringAlignment.Center
Dim rcText As RectangleF = rfBound
rcText.Width -= 5
e.Graphics.DrawString ( s1 , New Font ( "Veranda" , 10 ) , New SolidBrush ( Color.Blue ) , rcText , sfTemp )
e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.LightGray ) ) , rfBound1 )
If e.State = ( DrawItemState.NoAccelerator Or DrawItemState.Selected ) Then
e.Graphics.FillRectangle ( New SolidBrush ( Color.LightYellow ) , rfBound )
e.Graphics.DrawString ( s1 , New Font ( "Veranda" , 10 , FontStyle.Bold Or FontStyle.Underline ) , New SolidBrush ( Color.Red ) , rcText , sfTemp )
e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( Color.Black ) ) , rfBound1 )
e.DrawFocusRectangle ( )
End If
End Sub
4. MenuItem3的DrawItem事件处理代码之后添加下列代码,下列代码是定义MenuItem3的MeasureItem事件,在此事件中实现设定"新建"菜单项的长度和高度:
Private Sub MenuItem3_MeasureItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.MeasureItemEventArgs ) Handles MenuItem3.MeasureItem
e.ItemWidth = 60
'设定菜单项的宽度
e.ItemHeight = 30
'设定菜单项的高度
End Sub
在上述步骤都正确完成后,本文介绍的手工绘制菜单就完成,此时单击快捷键F5运行。
程序就可以得到图05所示的运行界面。
四.总结:
Visual Basic .net中实现绘制菜单最重要的是掌握DrawItem事件和MeasureItem事件用法及其绘制菜单时所要使用到的各种图形图象方法,如:绘制名称,色彩填充等。当然在绘制菜单时,首先把菜单项的"OwnerDraw"属性设定为"True"。因为这是触发DrawItem事件和MeasureItem事件的前提。本文实现的菜单虽不美观,但本文介绍的方法却是很实用的,在上述项目的基础上进行一定的修改,如再调用其他的绘制方法,一定可以完成一个更美观的菜单来。

