Hello I'm a begginner to VB.net and I have a question on how to add icons to menus. I've searched all over and I've found several different examples, however, I could only get one of them to work and now I need help customizing it. Basically this code does everything I need it to do except it has a white background that does not go with my program. Here is the class I'm using:
Imports System.Drawing
Imports System.Windows.Forms
PublicClass OwnerDrawMenu
Private _MenuItems AsNew ArrayList()
Private _Font As Font = SystemInformation.MenuFont
Private _TextColor As Color = System.Drawing.SystemColors.MenuText
PrivateConst NORMALITEMHEIGHT AsInteger = 20
PrivateConst SEPITEMHEIGHT AsInteger = 12
PrivateConst EXTRAWIDTH AsInteger = 30
PrivateConst ICONSIZE16 AsInteger = 16
PrivateStructure LocalMenuItem
Dim MenuItemNumber AsInteger
Dim MenuItem As Windows.Forms.MenuItem
Dim Icon As System.Drawing.Icon
Dim IconRectangle As System.Drawing.Rectangle
Dim TextLeft AsInteger
Dim TextTopPosition AsInteger
Dim Font As System.Drawing.Font
Dim TextColor As System.Drawing.Color
Dim Height AsInteger
Dim Width AsInteger
Dim IsSeperator AsBoolean
EndStructure
PublicSubNew()
'
EndSub
PublicSubNew(ByVal Font As System.Drawing.Font)
_Font = Font
If _Font.Size > 12 Then
_Font = New Font(_Font.Name, 12, _Font.Style)
EndIf
EndSub
PublicSubNew(ByVal TextColor As System.Drawing.Color)
_TextColor = TextColor
EndSub
PublicSubNew(ByVal Font As System.Drawing.Font, ByVal TextColor As System.Drawing.Color)
_TextColor = TextColor
_Font = Font
If _Font.Size > 12 Then
_Font = New Font(_Font.Name, 12, _Font.Style)
EndIf
EndSub
PublicSub Add(ByVal MenuItem As Windows.Forms.MenuItem, ByVal Icon As System.Drawing.Icon, ByVal MenuItemNumber AsInteger, ByVal IsSeperator AsBoolean)
Me.Add(MenuItem, Icon, MenuItemNumber, IsSeperator, _Font, _TextColor)
EndSub
PublicSub Add(ByVal MenuItem As Windows.Forms.MenuItem, ByVal Icon As System.Drawing.Icon, ByVal MenuItemNumber AsInteger, ByVal IsSeperator AsBoolean, ByVal Font As System.Drawing.Font)
Me.Add(MenuItem, Icon, MenuItemNumber, IsSeperator, Font, _TextColor)
EndSub
PublicSub Add(ByVal MenuItem As Windows.Forms.MenuItem, ByVal Icon As System.Drawing.Icon, ByVal MenuItemNumber AsInteger, ByVal IsSeperator AsBoolean, ByVal Font As System.Drawing.Font, ByVal TextColor As System.Drawing.Color)
Static LastTopPosition AsInteger
Static LastLeftPosition AsInteger
Dim li AsNew LocalMenuItem()
If MenuItemNumber = 0 Then
LastLeftPosition = 2
LastTopPosition = 0
Else
LastTopPosition = LastTopPosition + IIf(IsSeperator, SEPITEMHEIGHT, NORMALITEMHEIGHT)
LastLeftPosition = 2
EndIf
Const ICONWIDTH AsInteger = ICONSIZE16
Const ICONHEIGHT AsInteger = ICONSIZE16
Dim IconRect As Rectangle
If IsSeperator Then
IconRect = New Rectangle(LastLeftPosition, LastTopPosition, ICONWIDTH, ICONHEIGHT)
Else
IconRect = New Rectangle(LastLeftPosition, LastTopPosition + 2, ICONWIDTH, ICONHEIGHT)
EndIf
MenuItem.OwnerDraw = True
With li
.MenuItemNumber = MenuItemNumber
.Font = Font
.MenuItem = MenuItem
.Icon = Icon
.TextLeft = LastLeftPosition + ICONWIDTH
.TextTopPosition = LastTopPosition
.IconRectangle = IconRect
.TextColor = TextColor
.IsSeperator = IsSeperator
EndWith
_MenuItems.Add(li)
AddHandler MenuItem.DrawItem, AddressOfMe.DrawItemHandler
AddHandler MenuItem.MeasureItem, AddressOfMe.MesaureItemHandler
EndSub
PrivateSub DoDraw(ByVal LI As LocalMenuItem, ByRef e As System.Windows.Forms.DrawItemEventArgs)
e.DrawBackground()
Const LastLeftPosition AsInteger = 2
Const ICONWIDTH AsInteger = ICONSIZE16
Dim ThisMenuItem As MenuItem = LI.MenuItem
Dim MenuItemGraphics As Graphics = e.Graphics
Dim ShadeRect As Rectangle
Dim bBypassString AsBoolean
Dim SizeF As SizeF = e.Graphics.MeasureString(LI.MenuItem.Text, _Font)
Dim TextPoint As PointF = New PointF(LI.TextLeft, LI.TextTopPosition + ((NORMALITEMHEIGHT - SizeF.Height) / 2))
Dim RectHeight AsInteger = SizeF.Height
IfNot LI.Icon IsNothingThen
MenuItemGraphics.DrawIcon(New Icon(LI.Icon, ICONSIZE16, ICONSIZE16), LI.IconRectangle)
ElseIf LI.IsSeperator Then
MenuItemGraphics.DrawLine(New Pen(LI.TextColor, 1), TextPoint.X, TextPoint.Y + 11, TextPoint.X + LI.Width + EXTRAWIDTH, TextPoint.Y + 11)
bBypassString = True
EndIf
IfNot bBypassString Then
If LI.MenuItem.Enabled Then
MenuItemGraphics.DrawString(Replace(LI.MenuItem.Text, "&", ""), LI.Font, New SolidBrush(LI.TextColor), TextPoint)
Else
MenuItemGraphics.DrawString(Replace(LI.MenuItem.Text, "&", ""), LI.Font, New SolidBrush(Drawing.SystemColors.GrayText), TextPoint)
EndIf
EndIf
EndSub
PrivateSub DoMeasure(ByVal LI As LocalMenuItem, ByRef e As System.Windows.Forms.MeasureItemEventArgs)
Dim ThisMenuItem_Strings AsString() = LI.MenuItem.Text.Split(",")
Dim TextSize As SizeF = e.Graphics.MeasureString(ThisMenuItem_Strings(0).Replace("&", ""), LI.Font)
e.ItemWidth = TextSize.Width + EXTRAWIDTH
If LI.MenuItem.Text = "-" Then
e.ItemHeight = SEPITEMHEIGHT
Else
e.ItemHeight = NORMALITEMHEIGHT
EndIf
LI.Height = e.ItemHeight
LI.Width = e.ItemWidth
EndSub
PublicSub DrawItemHandler(ByVal sender AsObject, ByVal e As System.Windows.Forms.DrawItemEventArgs)
Dim li As LocalMenuItem
ForEach li In _MenuItems
If li.MenuItem Is sender Then
DoDraw(li, e)
ExitFor
EndIf
Next
EndSub
PublicSub MesaureItemHandler(ByVal sender AsObject, ByVal e As System.Windows.Forms.MeasureItemEventArgs)
Dim li As LocalMenuItem
ForEach li In _MenuItems
If li.MenuItem Is sender Then
DoMeasure(li, e)
ExitFor
EndIf
Next
EndSub
EndClass
--------------------------------------
I'm supposed to add this to my Forms Load:
Dim odm As New OwnerDrawMenu(New Font("Tahoma", 8), System.Drawing.Color.Black)
odm.Add(Me.MenuOpenFile, New Icon("C:\Program Files\avondale\Graphics\Icons\Open.ico"), 0, False)
odm.Add(Me.FileMenuSep2, Nothing, 1, True)
odm.Add(Me.MenuSwitchUser, Nothing, 2, False)
odm.Add(Me.FileSep1, Nothing, 3, True)
odm.Add(Me.cmdExit, New Icon("C:\Program Files\avondale\Graphics\Icons\exit.ico"), 4, False)
----------------------------------------------------------------
As I said, this works perfectly except for the background for each menu item is white and I need it to be the default grey.
Thanks a lot to anybody who can help!
Pat
Imports System.Drawing
Imports System.Windows.Forms
PublicClass OwnerDrawMenu
Private _MenuItems AsNew ArrayList()
Private _Font As Font = SystemInformation.MenuFont
Private _TextColor As Color = System.Drawing.SystemColors.MenuText
PrivateConst NORMALITEMHEIGHT AsInteger = 20
PrivateConst SEPITEMHEIGHT AsInteger = 12
PrivateConst EXTRAWIDTH AsInteger = 30
PrivateConst ICONSIZE16 AsInteger = 16
PrivateStructure LocalMenuItem
Dim MenuItemNumber AsInteger
Dim MenuItem As Windows.Forms.MenuItem
Dim Icon As System.Drawing.Icon
Dim IconRectangle As System.Drawing.Rectangle
Dim TextLeft AsInteger
Dim TextTopPosition AsInteger
Dim Font As System.Drawing.Font
Dim TextColor As System.Drawing.Color
Dim Height AsInteger
Dim Width AsInteger
Dim IsSeperator AsBoolean
EndStructure
PublicSubNew()
'
EndSub
PublicSubNew(ByVal Font As System.Drawing.Font)
_Font = Font
If _Font.Size > 12 Then
_Font = New Font(_Font.Name, 12, _Font.Style)
EndIf
EndSub
PublicSubNew(ByVal TextColor As System.Drawing.Color)
_TextColor = TextColor
EndSub
PublicSubNew(ByVal Font As System.Drawing.Font, ByVal TextColor As System.Drawing.Color)
_TextColor = TextColor
_Font = Font
If _Font.Size > 12 Then
_Font = New Font(_Font.Name, 12, _Font.Style)
EndIf
EndSub
PublicSub Add(ByVal MenuItem As Windows.Forms.MenuItem, ByVal Icon As System.Drawing.Icon, ByVal MenuItemNumber AsInteger, ByVal IsSeperator AsBoolean)
Me.Add(MenuItem, Icon, MenuItemNumber, IsSeperator, _Font, _TextColor)
EndSub
PublicSub Add(ByVal MenuItem As Windows.Forms.MenuItem, ByVal Icon As System.Drawing.Icon, ByVal MenuItemNumber AsInteger, ByVal IsSeperator AsBoolean, ByVal Font As System.Drawing.Font)
Me.Add(MenuItem, Icon, MenuItemNumber, IsSeperator, Font, _TextColor)
EndSub
PublicSub Add(ByVal MenuItem As Windows.Forms.MenuItem, ByVal Icon As System.Drawing.Icon, ByVal MenuItemNumber AsInteger, ByVal IsSeperator AsBoolean, ByVal Font As System.Drawing.Font, ByVal TextColor As System.Drawing.Color)
Static LastTopPosition AsInteger
Static LastLeftPosition AsInteger
Dim li AsNew LocalMenuItem()
If MenuItemNumber = 0 Then
LastLeftPosition = 2
LastTopPosition = 0
Else
LastTopPosition = LastTopPosition + IIf(IsSeperator, SEPITEMHEIGHT, NORMALITEMHEIGHT)
LastLeftPosition = 2
EndIf
Const ICONWIDTH AsInteger = ICONSIZE16
Const ICONHEIGHT AsInteger = ICONSIZE16
Dim IconRect As Rectangle
If IsSeperator Then
IconRect = New Rectangle(LastLeftPosition, LastTopPosition, ICONWIDTH, ICONHEIGHT)
Else
IconRect = New Rectangle(LastLeftPosition, LastTopPosition + 2, ICONWIDTH, ICONHEIGHT)
EndIf
MenuItem.OwnerDraw = True
With li
.MenuItemNumber = MenuItemNumber
.Font = Font
.MenuItem = MenuItem
.Icon = Icon
.TextLeft = LastLeftPosition + ICONWIDTH
.TextTopPosition = LastTopPosition
.IconRectangle = IconRect
.TextColor = TextColor
.IsSeperator = IsSeperator
EndWith
_MenuItems.Add(li)
AddHandler MenuItem.DrawItem, AddressOfMe.DrawItemHandler
AddHandler MenuItem.MeasureItem, AddressOfMe.MesaureItemHandler
EndSub
PrivateSub DoDraw(ByVal LI As LocalMenuItem, ByRef e As System.Windows.Forms.DrawItemEventArgs)
e.DrawBackground()
Const LastLeftPosition AsInteger = 2
Const ICONWIDTH AsInteger = ICONSIZE16
Dim ThisMenuItem As MenuItem = LI.MenuItem
Dim MenuItemGraphics As Graphics = e.Graphics
Dim ShadeRect As Rectangle
Dim bBypassString AsBoolean
Dim SizeF As SizeF = e.Graphics.MeasureString(LI.MenuItem.Text, _Font)
Dim TextPoint As PointF = New PointF(LI.TextLeft, LI.TextTopPosition + ((NORMALITEMHEIGHT - SizeF.Height) / 2))
Dim RectHeight AsInteger = SizeF.Height
IfNot LI.Icon IsNothingThen
MenuItemGraphics.DrawIcon(New Icon(LI.Icon, ICONSIZE16, ICONSIZE16), LI.IconRectangle)
ElseIf LI.IsSeperator Then
MenuItemGraphics.DrawLine(New Pen(LI.TextColor, 1), TextPoint.X, TextPoint.Y + 11, TextPoint.X + LI.Width + EXTRAWIDTH, TextPoint.Y + 11)
bBypassString = True
EndIf
IfNot bBypassString Then
If LI.MenuItem.Enabled Then
MenuItemGraphics.DrawString(Replace(LI.MenuItem.Text, "&", ""), LI.Font, New SolidBrush(LI.TextColor), TextPoint)
Else
MenuItemGraphics.DrawString(Replace(LI.MenuItem.Text, "&", ""), LI.Font, New SolidBrush(Drawing.SystemColors.GrayText), TextPoint)
EndIf
EndIf
EndSub
PrivateSub DoMeasure(ByVal LI As LocalMenuItem, ByRef e As System.Windows.Forms.MeasureItemEventArgs)
Dim ThisMenuItem_Strings AsString() = LI.MenuItem.Text.Split(",")
Dim TextSize As SizeF = e.Graphics.MeasureString(ThisMenuItem_Strings(0).Replace("&", ""), LI.Font)
e.ItemWidth = TextSize.Width + EXTRAWIDTH
If LI.MenuItem.Text = "-" Then
e.ItemHeight = SEPITEMHEIGHT
Else
e.ItemHeight = NORMALITEMHEIGHT
EndIf
LI.Height = e.ItemHeight
LI.Width = e.ItemWidth
EndSub
PublicSub DrawItemHandler(ByVal sender AsObject, ByVal e As System.Windows.Forms.DrawItemEventArgs)
Dim li As LocalMenuItem
ForEach li In _MenuItems
If li.MenuItem Is sender Then
DoDraw(li, e)
ExitFor
EndIf
Next
EndSub
PublicSub MesaureItemHandler(ByVal sender AsObject, ByVal e As System.Windows.Forms.MeasureItemEventArgs)
Dim li As LocalMenuItem
ForEach li In _MenuItems
If li.MenuItem Is sender Then
DoMeasure(li, e)
ExitFor
EndIf
Next
EndSub
EndClass
--------------------------------------
I'm supposed to add this to my Forms Load:
Dim odm As New OwnerDrawMenu(New Font("Tahoma", 8), System.Drawing.Color.Black)
odm.Add(Me.MenuOpenFile, New Icon("C:\Program Files\avondale\Graphics\Icons\Open.ico"), 0, False)
odm.Add(Me.FileMenuSep2, Nothing, 1, True)
odm.Add(Me.MenuSwitchUser, Nothing, 2, False)
odm.Add(Me.FileSep1, Nothing, 3, True)
odm.Add(Me.cmdExit, New Icon("C:\Program Files\avondale\Graphics\Icons\exit.ico"), 4, False)
----------------------------------------------------------------
As I said, this works perfectly except for the background for each menu item is white and I need it to be the default grey.
Thanks a lot to anybody who can help!
Pat
Last edited: