Search code examples
c#.netsystem-traynotifyicon

Writing text to the system tray instead of an icon


I am trying to display 2-3 updatable characters in the system tray rather than display an .ico file - similar to what CoreTemp does when they display the temperature in the system try:

enter image description here

I am using a NotifyIcon in my WinForms application along with the following code:

Font fontToUse = new Font("Microsoft Sans Serif", 8, FontStyle.Regular, GraphicsUnit.Pixel);
Brush brushToUse = new SolidBrush(Color.White);
Bitmap bitmapText = new Bitmap(16, 16);
Graphics g = Drawing.Graphics.FromImage(bitmapText);

IntPtr hIcon;
public void CreateTextIcon(string str)
{
    g.Clear(Color.Transparent);
    g.DrawString(str, fontToUse, brushToUse, -2, 5);
    hIcon = (bitmapText.GetHicon);
    NotifyIcon1.Icon = Drawing.Icon.FromHandle(hIcon);
    DestroyIcon(hIcon.ToInt32);
}

Sadly this produces a poor result nothing like what CoreTemp gets:

enter image description here

You'd think the solution would be to increase the font size, but anything over size 8 doesn't fit inside the image. Increasing the bitmap from 16x16 to 32x32 does nothing either - it gets resized down.

Then there's the problem of me wanting to display "8.55" instead of just "55" - there's enough space around the icon but it appears unusable.

enter image description here

Is there a better way to do this? Why can windows do the following but I cannot?

enter image description here

Update:

Thanks for @NineBerry for a good solution. To add, I find Tahoma to be the best font to use.


Solution

  • This gives me a quite good looking display of a two digit string:

    enter image description here

    private void button1_Click(object sender, EventArgs e)
    {
        CreateTextIcon("89");
    }
    
    public void CreateTextIcon(string str)
    {
        Font fontToUse = new Font("Microsoft Sans Serif", 16, FontStyle.Regular, GraphicsUnit.Pixel);
        Brush brushToUse = new SolidBrush(Color.White);
        Bitmap bitmapText = new Bitmap(16, 16);
        Graphics g = System.Drawing.Graphics.FromImage(bitmapText);
    
        IntPtr hIcon;
        
        g.Clear(Color.Transparent);
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
        g.DrawString(str, fontToUse, brushToUse, -4, -2);
        hIcon = (bitmapText.GetHicon());
        notifyIcon1.Icon = System.Drawing.Icon.FromHandle(hIcon);
        DestroyIcon(hIcon.ToInt32);
    }
    

    What I changed:

    1. Use a larger font size, but move the x and y offset further to the left and top (-4, -2).

    2. Set TextRenderingHint on the Graphics object to disable anti-aliasing.

    It seems impossible to draw more than 2 digits or characters. The icons have a square format. Any text longer than two characters would mean reducing the height of the text a lot.

    The sample where you select the keyboard layout (ENG) is actually not a notification icon in the tray area but its very own shell toolbar.


    The best I could achieve to display 8.55:

    enter image description here

    private void button1_Click(object sender, EventArgs e)
    {
        CreateTextIcon("8'55");
    }
    
    public void CreateTextIcon(string str)
    {
        Font fontToUse = new Font("Trebuchet MS", 10, FontStyle.Regular, GraphicsUnit.Pixel);
        Brush brushToUse = new SolidBrush(Color.White);
        Bitmap bitmapText = new Bitmap(16, 16);
        Graphics g = System.Drawing.Graphics.FromImage(bitmapText);
    
        IntPtr hIcon;
        
        g.Clear(Color.Transparent);
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
        g.DrawString(str, fontToUse, brushToUse, -2, 0);
        hIcon = (bitmapText.GetHicon());
        notifyIcon1.Icon = System.Drawing.Icon.FromHandle(hIcon);
        //DestroyIcon(hIcon.ToInt32);
    }
    

    with the following changes:

    1. Use Trebuchet MS which is a very narrow font.
    2. Use the single quote instead of the dot because it has less space at the sides.
    3. Use font size 10 and adapt the offsets adequately.