Menu Icons

waughp

Member
Joined
Feb 18, 2005
Messages
15
Programming Experience
Beginner
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

End
Class
--------------------------------------


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:
I see where you found this one on codeproject.com, but in my opion it's not very well written. I would subclass the MenuItem class and add the icon property, then do the custom drawing similar to the example you've shown.

Here's a link to a very good menu system also from codeproject.com: UltimateMenus By Kunal Mukherjee.

FYI: The new version of VB.NET soon to be released fixes the shortfall with the V1 framework's menus with the MenuStrip control. It has build in icons, gradients, ...
 
Back
Top