大家过来探讨vbnet 的菜单自画

lyouj 2003-09-03 11:34:00
将OwnerDraw设成true后有什么注意事项,请高手作答。我碰到一个问题:
我写了如下函数:
Public Class MyMenuItem
Inherits MenuItem
Sub New()
MyBase.New()
Me.OwnerDraw = True
End Sub

Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
MyBase.OnDrawItem(e)
Dim MyCaption As String = Me.Text
Dim MyBrush As System.Drawing.Brush = System.Drawing.Brushes.Black

Dim MyFont As New Font(FontFamily.GenericSerif, 10, FontStyle.Regular, GraphicsUnit.Pixel)
Dim MySizeF As SizeF = e.Graphics.MeasureString(MyCaption, MyFont)
'Draw the item, and then draw a Rectangle around it.
MyBase.OnDrawItem(e)
e.DrawBackground()
Select Case e.State
Case DrawItemState.HotLight + DrawItemState.NoAccelerator
e.Graphics.DrawRectangle(Drawing.Pens.Black, New Rectangle(e.Bounds.X, e.Bounds.Y, MySizeF.Width, MySizeF.Height))
End Select

e.Graphics.DrawString(MyCaption, MyFont, MyBrush, e.Bounds.X, e.Bounds.Y)
End Sub
但运行后顶级菜单项重叠,下拉菜单不出来。不知除了重写 OnDrawItem,还要干什么。
...全文
97 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Montaque 2003-09-09
  • 打赏
  • 举报
回复
MeasureItem
shining007 2003-09-09
  • 打赏
  • 举报
回复
to benlee(寂寞成双): 有没有.net风格的菜单,谢谢
lyouj 2003-09-08
  • 打赏
  • 举报
回复
非常感谢!!!!收获不少。
benlee 2003-09-08
  • 打赏
  • 举报
回复
给你参考一下!
benlee 2003-09-08
  • 打赏
  • 举报
回复

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

Dim mRectBitmap As New RectangleF(e.Bounds.Left, e.Bounds.Top, IconSize, IconSize)
Dim mRectText As New RectangleF(e.Bounds.Left + IconSize, e.Bounds.Top, e.Bounds.Width - IconSize, IconSize)
Dim mClientRect As New Rectangle(e.Bounds.Left, e.Bounds.Top, e.Bounds.Width - 2, e.Bounds.Height - 2)

'处理分隔符号
If Me.Text = "-" Then
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), mRectBitmap)
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLightLight), mRectText)
e.Graphics.DrawLine(SystemPens.ControlDark, e.Bounds.Left + IconSize + cintBuffer, e.Bounds.Top + CType(e.Bounds.Height / 2, Integer), e.Bounds.Left + e.Bounds.Width - cintBuffer, e.Bounds.Top + CType(e.Bounds.Height / 2, Integer))
Exit Sub
End If

'针对被选取的MenuItem

If IsSelected(e.State) And Not IsDisabled(e.State) Then
'填充矩形内部
e.Graphics.FillRectangle(getCurrentBackColor(e.State), mClientRect)
'设置被选取选项的边框颜色
e.Graphics.DrawRectangle(New Pen(SystemColors.ControlDarkDark), mClientRect)
Else
'填充图像区的矩形内部
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), mRectBitmap)
'填充文本区的矩形内部
e.Graphics.FillRectangle(getCurrentBackColor(e.State), mRectText)
End If

'处理文本部分
Dim mStringFormat As New StringFormat()
mStringFormat.Alignment = StringAlignment.Near
mStringFormat.LineAlignment = StringAlignment.Center
mStringFormat.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show
Dim mRF As RectangleF = RectangleF.Empty
With mRF
.X = mRectText.X + cintBuffer
.Y = mRectText.Y
.Width = mRectText.Width - cintBuffer
.Height = mRectText.Height
End With
e.Graphics.DrawString(Me.Text, Me.Font, getCurrentTextColor(e.State), mRF, mStringFormat)
If Me.Shortcut <> Shortcut.None And Me.ShowShortcut Then
mStringFormat.Alignment = StringAlignment.Far
e.Graphics.DrawString(Me.ShortCutText, Me.Font, getCurrentTextColor(e.State), mRF, mStringFormat)
End If

'处理图像部分
If Not (Me.Bitmap Is Nothing) Then
If Not IsDisabled(e.State) Then
If IsSelected(e.State) Then
'被选取的图标,以重叠暂止图像制作出浮起的效果
ControlPaint.DrawImageDisabled(e.Graphics, Me.Bitmap, e.Bounds.Left + cintBuffer, e.Bounds.Top + cintBuffer, SystemColors.ControlLight)
e.Graphics.DrawImage(Me.Bitmap, e.Bounds.Left + cintBuffer - 1, e.Bounds.Top + cintBuffer - 1)
Else
'若未被选取,则绘制正常图像
e.Graphics.DrawImage(Me.Bitmap, e.Bounds.Left + cintBuffer, e.Bounds.Top + cintBuffer)
End If
Else
'绘制暂止的图像
ControlPaint.DrawImageDisabled(e.Graphics, Me.Bitmap, e.Bounds.Left + cintBuffer, e.Bounds.Top + cintBuffer, SystemColors.ControlLight)
End If
End If
End Sub

'设置初始值
Protected Sub InitBaseValue()
Me.Font = SystemInformation.MenuFont
Me.IconSize = 24
Me.OwnerDraw = True
End Sub

'获取当前的文本颜色
Protected Function getCurrentTextColor(ByVal State As DrawItemState) As Brush
If IsDisabled(State) Then
Return New SolidBrush(SystemColors.GrayText)
Else
Return New SolidBrush(SystemColors.WindowText)
End If
End Function

'获取当前的背景颜色
Protected Function getCurrentBackColor(ByVal State As DrawItemState) As SolidBrush
If IsDisabled(State) Then
Return New SolidBrush(SystemColors.ControlLightLight)
End If
If IsSelected(State) Then
Return New SolidBrush(Color.LightSteelBlue)
Else
Return New SolidBrush(SystemColors.ControlLightLight)
End If
End Function

Protected ReadOnly Property IsSelected(ByVal State As DrawItemState) As Boolean
Get
Return CType(State And DrawItemState.Selected, Boolean)
End Get
End Property

Protected ReadOnly Property IsDisabled(ByVal State As DrawItemState) As Boolean
Get
Return CType(State And DrawItemState.Disabled, Boolean)
End Get
End Property

Protected ReadOnly Property ShortCutText() As String
Get
'如果该菜单选项不具备快捷键, 则返回空字串
If Me.Shortcut = Shortcut.None Or Me.ShowShortcut = False Then
Return ""
End If
'反之则返回快捷键对应的完整文本
Dim k As Keys = CType(Shortcut, Keys)
Return TypeDescriptor.GetConverter(GetType(Keys)).ConvertToString(k)
End Get
End Property

Public Sub New()
MyBase.New()
InitBaseValue()
End Sub

Public Sub New(ByVal text As String)
MyBase.New(text)
InitBaseValue()
End Sub

Public Sub New(ByVal text As String, ByVal bitmapA As Bitmap)
MyBase.New(text)
Me.Bitmap = bitmapA
If Not Me.Bitmap Is Nothing Then
Me.TransparentColor = Me.Bitmap.GetPixel(0, 0)
End If
InitBaseValue()
End Sub

Public Sub New(ByVal menuText As String, ByVal HandlerClick As EventHandler, ByVal bitmapA As Bitmap)
MyBase.New(menuText, HandlerClick)
Me.Bitmap = bitmapA
If Not Me.Bitmap Is Nothing Then
Me.TransparentColor = Me.Bitmap.GetPixel(0, 0)
End If
InitBaseValue()
End Sub
End Class
benlee 2003-09-08
  • 打赏
  • 举报
回复
Imports System.ComponentModel

Public Class IconMenuItem
Inherits System.Windows.Forms.MenuItem

Private mFont As Font '用来保存字体
Private mBitmap As Bitmap '用来保存影像
Private mTransparentColor As Color '用来保存图像的透明色
Private mintIconSize As Integer '用来保存图像的大小(长宽必须相同)
Private Const cintBuffer As Integer = 4 '设置边界缓冲区的大小
Private minttag As Integer 'tag值

Public Property Font() As Font
Get
Return mFont
End Get
Set(ByVal Value As Font)
mFont = Value
End Set
End Property

Public Property tag() As Integer
Get
Return minttag
End Get
Set(ByVal Value As Integer)
minttag = Value
End Set
End Property
Public Property Bitmap() As Bitmap
Get
Return mBitmap
End Get
Set(ByVal Value As Bitmap)
mBitmap = Value
Me.TransparentColor = Me.Bitmap.GetPixel(0, 0)
End Set
End Property

Public Property TransparentColor() As Color
Get
Return mTransparentColor
End Get
Set(ByVal Value As Color)
mTransparentColor = Value
mBitmap.MakeTransparent(mTransparentColor)
End Set
End Property

Public Property IconSize() As Integer
Get
Return mintIconSize
End Get
Set(ByVal Value As Integer)
mintIconSize = Value
End Set
End Property

Protected Overrides Sub OnMeasureItem(ByVal e As System.Windows.Forms.MeasureItemEventArgs)
MyBase.OnMeasureItem(e)
' 针对分隔符号
If Me.Text = "-" Then
e.ItemHeight = 4
Exit Sub
End If

'处理菜单选项的访问键
Dim mStringFormat As New StringFormat()
mStringFormat.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show
e.ItemWidth = CInt(e.Graphics.MeasureString(Me.Text, Me.Font, 1000, mStringFormat).Width) + 2 * cintBuffer
e.ItemWidth += IconSize
'处理快捷键(ShortCut)
If Me.Shortcut <> Shortcut.None And Me.ShowShortcut Then
e.ItemWidth += cintBuffer + CInt(e.Graphics.MeasureString(" " & Me.ShortCutText, Me.Font).Width)
End If
e.ItemHeight = IconSize
End Sub
lyouj 2003-09-07
  • 打赏
  • 举报
回复
受益非浅,不过还有个问题,就是给菜单条左边加图标,怎么才能使图标的里的
白底色变成透明色?
szch 2003-09-07
  • 打赏
  • 举报
回复
顶级菜单是不能使用该类,要么用系统默认的,要么另外写.
fankun 2003-09-07
  • 打赏
  • 举报
回复
快点UP,支持楼主!
cnhgj 2003-09-03
  • 打赏
  • 举报
回复
http://lszy.net/tm/ShowArticle.asp?ArticleID=1106

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧