ownerdraw menu almost ok

P

Peter Proost

Hi group,

I've got this ownerdraw menu module which I got from a site and modified to
my personal needs, but the only problem I'm having is with the lines in a
menu, when you type - as text, it normaly becomes a full line and the height
of the menuitem is reduced but when you set a menu to ownerdraw and use my
draw and measure item handlers this doesn't work anymore, has anyone worked
out a good sloution for this before?

Greetz Peter

This is how I call my draw and measure item handlers, don't forget to set
the menuitem ownerdraw property to true if you want to test it

Private Sub mnuKlantenAlgemeen_DrawItem(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DrawItemEventArgs) Handles mnuKlantenAlgemeen.DrawItem
DrawItems(e, mnuKlantenAlgemeen, nothing)
End Sub

Private Sub mnuKlantenAlgemeen_MeasureItem(ByVal sender As Object, ByVal e
As _ System.Windows.Forms.MeasureItemEventArgs) Handles
mnuKlantenAlgemeen.MeasureItem
MeasureItems(e, mnuKlantenAlgemeen)
End Sub

'place this in a new class

'Module om icoontjes aan een menu toe te voegen

Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Text
Imports System.Windows.Forms


Module IconsMenuMain

Dim m_Font As New Font("Arial", 8)

Sub MeasureItems(ByVal EvMeasureItem As
System.Windows.Forms.MeasureItemEventArgs, ByVal Mi As MenuItem)
Try
Dim sf As StringFormat = New StringFormat()
sf.HotkeyPrefix = HotkeyPrefix.Show
sf.SetTabStops(60, New Single() {0})
EvMeasureItem.ItemHeight = 22
EvMeasureItem.ItemWidth =
CInt(EvMeasureItem.Graphics.MeasureString(GetRealText(Mi), _
m_Font,
10000, sf).Width) + 30
sf.Dispose()
sf = Nothing
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
'Private bmp As Bitmap
Sub DrawItems(ByVal EvDrawItems As
System.Windows.Forms.DrawItemEventArgs, ByVal Mi As MenuItem, ByVal m_Icon
As Icon)
'bmp = New Bitmap(EvDrawItems.Bounds.Width,
EvDrawItems.Bounds.Height)
'Dim g As Graphics
'g = Graphics.FromImage(bmp)
Try
Dim br As Brush
Dim br2 As Brush
Dim fDisposeBrush As Boolean
Dim rand As Pen

Dim rcBk As Rectangle = EvDrawItems.Bounds
rcBk.Height -= 2
rcBk.Width -= 2
If CBool(EvDrawItems.State And DrawItemState.Selected) Then
br = New LinearGradientBrush(rcBk, Color.CadetBlue,
Color.LightBlue, 0)
fDisposeBrush = True
rand = New Pen(Color.DarkBlue, 1)
EvDrawItems.Graphics.FillRectangle(br, rcBk)
EvDrawItems.Graphics.DrawRectangle(rand, rcBk)

Else
br = SystemBrushes.Control
br2 = New SolidBrush(Color.WhiteSmoke)
rand = System.Drawing.SystemPens.Control
EvDrawItems.Graphics.DrawRectangle(rand, rcBk)
rcBk.X += 24
rcBk.Width -= 23
'rcBk.Y -= 1
rcBk.Height += 2
EvDrawItems.Graphics.FillRectangle(br2, rcBk)
rcBk.X = 0
rcBk.Width = 24
EvDrawItems.Graphics.FillRectangle(br, rcBk)
br2.Dispose()

End If




'Dim rcIcon As New Rectangle(EvDrawItems.Bounds.Left + 2,
EvDrawItems.Bounds.Top + 2, m_Icon.Width, m_Icon.Height)
'EvDrawItems.Graphics.ExcludeClip(rcIcon)

If fDisposeBrush Then br.Dispose()
br = Nothing

Dim sf As StringFormat = New StringFormat()
sf.HotkeyPrefix = HotkeyPrefix.Show
sf.SetTabStops(60, New Single() {0})
If Mi.Enabled Then
br = New SolidBrush(EvDrawItems.ForeColor)
Else
br = New SolidBrush(Color.Gray)
End If


EvDrawItems.Graphics.DrawString(GetRealText(Mi), m_Font, br, _
EvDrawItems.Bounds.Left + 25, _
EvDrawItems.Bounds.Top + 2, sf)

br.Dispose()
br = Nothing
sf.Dispose()
sf = Nothing
If Not m_Icon Is Nothing Then
If Not Mi.Checked Then
EvDrawItems.Graphics.DrawIcon(m_Icon,
EvDrawItems.Bounds.Left + 2, _
EvDrawItems.Bounds.Top +
2)
Else
EvDrawItems.Graphics.DrawIcon(m_Icon,
EvDrawItems.Bounds.Left + 2, _
EvDrawItems.Bounds.Top +
2)

End If

End If
'g.Dispose()
'EvDrawItems.Graphics.DrawImageUnscaled(bmp, 0, 0)

Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub

Function GetRealText(ByVal Mi As MenuItem) As String
Try
Dim s As String = Mi.Text
If Mi.ShowShortcut And Mi.Shortcut <> Shortcut.None Then
Dim k As Keys = CType(Mi.Shortcut, Keys)
s = s & Convert.ToChar(9) & _

TypeDescriptor.GetConverter(GetType(Keys)).ConvertToString(k)
End If
Return s & StrDup(4, " ")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Function

End Module
 
K

Ken Tucker [MVP]

Hi,

You are using a fixed height for the menu item in the measure
item event. Try increasing the height by measuring the height of the
string.

EvMeasureItem.ItemHeight =
CInt(EvMeasureItem.Graphics.MeasureString(GetRealText(Mi), m_Font, 10000,
sf).height) + 5

Ken
---------------------
Hi group,

I've got this ownerdraw menu module which I got from a site and modified to
my personal needs, but the only problem I'm having is with the lines in a
menu, when you type - as text, it normaly becomes a full line and the height
of the menuitem is reduced but when you set a menu to ownerdraw and use my
draw and measure item handlers this doesn't work anymore, has anyone worked
out a good sloution for this before?

Greetz Peter

This is how I call my draw and measure item handlers, don't forget to set
the menuitem ownerdraw property to true if you want to test it

Private Sub mnuKlantenAlgemeen_DrawItem(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DrawItemEventArgs) Handles mnuKlantenAlgemeen.DrawItem
DrawItems(e, mnuKlantenAlgemeen, nothing)
End Sub

Private Sub mnuKlantenAlgemeen_MeasureItem(ByVal sender As Object, ByVal e
As _ System.Windows.Forms.MeasureItemEventArgs) Handles
mnuKlantenAlgemeen.MeasureItem
MeasureItems(e, mnuKlantenAlgemeen)
End Sub

'place this in a new class

'Module om icoontjes aan een menu toe te voegen

Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Text
Imports System.Windows.Forms


Module IconsMenuMain

Dim m_Font As New Font("Arial", 8)

Sub MeasureItems(ByVal EvMeasureItem As
System.Windows.Forms.MeasureItemEventArgs, ByVal Mi As MenuItem)
Try
Dim sf As StringFormat = New StringFormat()
sf.HotkeyPrefix = HotkeyPrefix.Show
sf.SetTabStops(60, New Single() {0})
EvMeasureItem.ItemHeight = 22
EvMeasureItem.ItemWidth =
CInt(EvMeasureItem.Graphics.MeasureString(GetRealText(Mi), _
m_Font,
10000, sf).Width) + 30
sf.Dispose()
sf = Nothing
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
'Private bmp As Bitmap
Sub DrawItems(ByVal EvDrawItems As
System.Windows.Forms.DrawItemEventArgs, ByVal Mi As MenuItem, ByVal m_Icon
As Icon)
'bmp = New Bitmap(EvDrawItems.Bounds.Width,
EvDrawItems.Bounds.Height)
'Dim g As Graphics
'g = Graphics.FromImage(bmp)
Try
Dim br As Brush
Dim br2 As Brush
Dim fDisposeBrush As Boolean
Dim rand As Pen

Dim rcBk As Rectangle = EvDrawItems.Bounds
rcBk.Height -= 2
rcBk.Width -= 2
If CBool(EvDrawItems.State And DrawItemState.Selected) Then
br = New LinearGradientBrush(rcBk, Color.CadetBlue,
Color.LightBlue, 0)
fDisposeBrush = True
rand = New Pen(Color.DarkBlue, 1)
EvDrawItems.Graphics.FillRectangle(br, rcBk)
EvDrawItems.Graphics.DrawRectangle(rand, rcBk)

Else
br = SystemBrushes.Control
br2 = New SolidBrush(Color.WhiteSmoke)
rand = System.Drawing.SystemPens.Control
EvDrawItems.Graphics.DrawRectangle(rand, rcBk)
rcBk.X += 24
rcBk.Width -= 23
'rcBk.Y -= 1
rcBk.Height += 2
EvDrawItems.Graphics.FillRectangle(br2, rcBk)
rcBk.X = 0
rcBk.Width = 24
EvDrawItems.Graphics.FillRectangle(br, rcBk)
br2.Dispose()

End If




'Dim rcIcon As New Rectangle(EvDrawItems.Bounds.Left + 2,
EvDrawItems.Bounds.Top + 2, m_Icon.Width, m_Icon.Height)
'EvDrawItems.Graphics.ExcludeClip(rcIcon)

If fDisposeBrush Then br.Dispose()
br = Nothing

Dim sf As StringFormat = New StringFormat()
sf.HotkeyPrefix = HotkeyPrefix.Show
sf.SetTabStops(60, New Single() {0})
If Mi.Enabled Then
br = New SolidBrush(EvDrawItems.ForeColor)
Else
br = New SolidBrush(Color.Gray)
End If


EvDrawItems.Graphics.DrawString(GetRealText(Mi), m_Font, br, _
EvDrawItems.Bounds.Left + 25, _
EvDrawItems.Bounds.Top + 2, sf)

br.Dispose()
br = Nothing
sf.Dispose()
sf = Nothing
If Not m_Icon Is Nothing Then
If Not Mi.Checked Then
EvDrawItems.Graphics.DrawIcon(m_Icon,
EvDrawItems.Bounds.Left + 2, _
EvDrawItems.Bounds.Top +
2)
Else
EvDrawItems.Graphics.DrawIcon(m_Icon,
EvDrawItems.Bounds.Left + 2, _
EvDrawItems.Bounds.Top +
2)

End If

End If
'g.Dispose()
'EvDrawItems.Graphics.DrawImageUnscaled(bmp, 0, 0)

Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub

Function GetRealText(ByVal Mi As MenuItem) As String
Try
Dim s As String = Mi.Text
If Mi.ShowShortcut And Mi.Shortcut <> Shortcut.None Then
Dim k As Keys = CType(Mi.Shortcut, Keys)
s = s & Convert.ToChar(9) & _

TypeDescriptor.GetConverter(GetType(Keys)).ConvertToString(k)
End If
Return s & StrDup(4, " ")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Function

End Module
 
P

Peter Proost

Hi Ken,

I have to admit I feel pretty stupid for the moment, the whole time I've
been looking at the drawitem handler, setting the height in the measureitem
didn't even cross my mind although it's as logical as 1 + 1 = 2, I guess
that's what 2 hours of copy pasting the same code in 60+ forms does to your
head...

Thanks again

Greetz Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top