You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
7.8 KiB

Imports System.Drawing
Imports System.Windows.Forms
Public Class OwnerMenu
'holds menu items
Private _MenuItems As New ArrayList()
'default font
Private _Font As Font = SystemInformation.MenuFont
'default text color
Private _TextColor As Color = System.Drawing.SystemColors.MenuText
'constants
Private Const NORMALITEMHEIGHT As Integer = 20
Private Const SEPITEMHEIGHT As Integer = 12
Private Const EXTRAWIDTH As Integer = 30
Private Const ICONSIZE16 As Integer = 16
'structure to hold menu items
Private Structure LocalMenuItem
Dim MenuItemNumber As Integer
Dim MenuItem As Windows.Forms.MenuItem
Dim Icon As System.Drawing.Icon
Dim IconRectangle As System.Drawing.Rectangle
Dim TextLeft As Integer
Dim TextTopPosition As Integer
Dim Font As System.Drawing.Font
Dim TextColor As System.Drawing.Color
Dim Height As Integer
Dim Width As Integer
Dim IsSeperator As Boolean
End Structure
Public Sub New()
'
End Sub
'various constructors for the class
Public Sub New(ByVal Font As System.Drawing.Font)
_Font = Font
If _Font.Size > 12 Then
_Font = New Font(_Font.Name, 12, _Font.Style)
End If
End Sub
Public Sub New(ByVal TextColor As System.Drawing.Color)
_TextColor = TextColor
End Sub
Public Sub New(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)
End If
End Sub
'various constructors for the add method
Public Sub Add(ByVal MenuItem As Windows.Forms.MenuItem, _
ByVal Icon As System.Drawing.Icon, _
ByVal MenuItemNumber As Integer, _
ByVal IsSeperator As Boolean)
Me.Add(MenuItem, Icon, MenuItemNumber, IsSeperator, _Font, _TextColor)
End Sub
Public Sub Add(ByVal MenuItem As Windows.Forms.MenuItem, _
ByVal Icon As System.Drawing.Icon, _
ByVal MenuItemNumber As Integer, _
ByVal IsSeperator As Boolean, _
ByVal Font As System.Drawing.Font)
Me.Add(MenuItem, Icon, MenuItemNumber, IsSeperator, Font, _TextColor)
End Sub
Public Sub Add(ByVal MenuItem As Windows.Forms.MenuItem, _
ByVal Bitmap As System.Drawing.Bitmap, _
ByVal MenuItemNumber As Integer, _
ByVal IsSeperator As Boolean)
Dim Icon As Icon
Dim intIndexOfImageIWant As Int16 = 1
Icon = System.Drawing.Icon.FromHandle(Bitmap.GetHicon)
Me.Add(MenuItem, Icon, MenuItemNumber, IsSeperator, _Font, _TextColor)
End Sub
Public Sub Add(ByVal MenuItem As Windows.Forms.MenuItem, _
ByVal Icon As System.Drawing.Icon, _
ByVal MenuItemNumber As Integer, _
ByVal IsSeperator As Boolean, _
ByVal Font As System.Drawing.Font, _
ByVal TextColor As System.Drawing.Color)
'hold and save the last top and left position
Static LastTopPosition As Integer
Static LastLeftPosition As Integer
Dim li As New LocalMenuItem()
If MenuItemNumber = 0 Then
LastLeftPosition = 2
LastTopPosition = 0
Else
'calculate the new top position
LastTopPosition = LastTopPosition + IIf(IsSeperator, _
SEPITEMHEIGHT, NORMALITEMHEIGHT)
LastLeftPosition = 2
End If
Const ICONWIDTH As Integer = ICONSIZE16
Const ICONHEIGHT As Integer = ICONSIZE16
Dim IconRect As Rectangle
'calculate new drawing rectangle for icon
If IsSeperator Then
IconRect = New Rectangle(LastLeftPosition, LastTopPosition, _
ICONWIDTH, ICONHEIGHT)
Else
IconRect = New Rectangle(LastLeftPosition, LastTopPosition + 2, _
ICONWIDTH, ICONHEIGHT)
End If
'you don't need to set ownerdraw - the class does it for you
MenuItem.OwnerDraw = True
With li
.MenuItemNumber = MenuItemNumber
.Font = Font
.MenuItem = MenuItem
.Icon = Icon
.TextLeft = LastLeftPosition + ICONWIDTH
.TextTopPosition = LastTopPosition
.IconRectangle = IconRect
.TextColor = TextColor
.IsSeperator = IsSeperator
End With
_MenuItems.Add(li)
'set the handlers for the menuitems
AddHandler MenuItem.DrawItem, AddressOf Me.DrawItemHandler
AddHandler MenuItem.MeasureItem, AddressOf Me.MesaureItemHandler
End Sub
Private Sub DoDraw(ByVal LI As LocalMenuItem, _
ByRef e As System.Windows.Forms.DrawItemEventArgs)
e.DrawBackground()
Const LastLeftPosition As Integer = 2
Const ICONWIDTH As Integer = ICONSIZE16
Dim ThisMenuItem As MenuItem = LI.MenuItem
Dim MenuItemGraphics As Graphics = e.Graphics
Dim bBypassString As Boolean
'set size and textpoint for our text
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 As Integer = SizeF.Height
If Not LI.Icon Is Nothing Then
'draw the icon
MenuItemGraphics.DrawIcon(New Icon(LI.Icon, _
ICONSIZE16, ICONSIZE16), LI.IconRectangle)
ElseIf LI.IsSeperator Then
'draw the separator
MenuItemGraphics.DrawLine(New Pen(LI.TextColor, 1), _
TextPoint.X, TextPoint.Y + 11, _
TextPoint.X + LI.Width + EXTRAWIDTH, TextPoint.Y + 11)
bBypassString = True
End If
If Not bBypassString Then
'bypass string if separator
'draw differently if enabled/dsabled
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)
End If
End If
End Sub
Private Sub DoMeasure(ByVal LI As LocalMenuItem, _
ByRef e As System.Windows.Forms.MeasureItemEventArgs)
'calculate the size of the drawing area
Dim ThisMenuItem_Strings As String() = 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
End If
LI.Height = e.ItemHeight
LI.Width = e.ItemWidth
End Sub
Public Sub DrawItemHandler(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawItemEventArgs)
'look through the items and find out which one we are drawing
Dim li As LocalMenuItem
For Each li In _MenuItems
If li.MenuItem Is sender Then
DoDraw(li, e)
Exit For
End If
Next
End Sub
Public Sub MesaureItemHandler(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MeasureItemEventArgs)
'look through the items and find out which one we are measuring
Dim li As LocalMenuItem
For Each li In _MenuItems
If li.MenuItem Is sender Then
DoMeasure(li, e)
Exit For
End If
Next
End Sub
End Class