Search code examples
.netvb.netgdi+drawstringtoolstripmenu

Drawing text in vb.net to match a menu item


I'd like to put a number in the left-hand margin of a menu item in vb.net 2010, but it seems this can only be set to an image. So, I've been trying to create an image with the number I want there using Graphics.DrawString(). I've tried various ways, but I can't get the resulting image to look like the text in the menu item itself - is there a way to do this? Here's my current code (allocating an image to measure the text, then reallocating at the correct size is about version 3 of this - pretty ugly, but I'm not sure how else to measure).

mnuItem = New ToolStripMenuItem
numPeople = CInt(Math.Ceiling(Rnd() * 20))

' Calculate the size of the text
qImg = New Bitmap(1, 1)
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
gr = Graphics.FromImage(qImg)
gr.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
sz = gr.MeasureString(numPeople, mnuItem.Font, New Point(0, 0), sf)
w = CInt(Math.Ceiling(sz.Width))
h = CInt(Math.Ceiling(sz.Height))
m = Math.Max(w, h)

' Now allocate an image of the correct size
qImg = New Bitmap(m, m)
gr = Graphics.FromImage(qImg)
gr.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
gr.DrawString(numPeople, mnuItem.Font, Brushes.Black, New RectangleF((m - w) / 2, (m - h) / 2, w, h), sf)

mnuItem.Image = qImg

Here's a couple of examples of what this gives - note how fuzzy the margin text (image) is compared to the menu item text:

Example menu with fuzzy text Example menu with fuzzy text

I've tried all the TextRenderingHint options, and some are better than others, but none give the crisp look of the menu text. Is there a way to get closer to that look?


Solution

  • Have you tried with creating your own ToolStripMenuItem?

    Class CustomToolStripMenuItem
        Inherits System.Windows.Forms.ToolStripMenuItem
        Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            e.Graphics.DrawString("11", Me.Font, System.Drawing.Brushes.Black, New System.Drawing.PointF(0, 0))
        End Sub
    End Class
    

    I am NOT doing any calculation to correctly display it, but I think you can do it. It appears like this on my system (see the "Save As" item)

    enter image description here