将文本写入系统托盘而不是图标

22
我想在系统托盘中显示2-3个可更新的字符,而不是显示一个.ico文件 - 就像CoreTemp在系统托盘中显示温度一样。

enter image description here

我正在使用一个NotifyIcon在我的WinForms应用程序中,同时使用以下代码:

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);
}

不幸的是,这会产生一个糟糕的结果,与CoreTemp得到的结果完全不同:

enter image description here

你可能认为解决方法是增加字体大小,但超过8号字体的任何内容都无法放入图像中。将位图从16x16增加到32x32也没有效果-它会被缩小。此外,我想显示“8.55”而不仅仅是“55”,虽然图标周围有足够的空间,但似乎无法使用。

enter image description here

有更好的方法吗?为什么Windows可以做到以下操作,而我却不能?

enter image description here

更新:

感谢 @NineBerry 提供的好的解决方案。另外,我发现 Tahoma 是最适合使用的字体。


1
我认为其他应用程序只需使用一组内置图标,而不是尝试即时生成它们。 - Glen Thomas
1个回答

27
这给我展示了一个相当好看的两位数字符串显示:

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);
}

我所做的更改:
  1. 使用更大的字体大小,但将x和y偏移进一步向左和向上移动(-4,-2)。

  2. 在Graphics对象上设置TextRenderingHint以禁用抗锯齿。

似乎不可能绘制超过2个数字或字符。图标具有正方形格式。任何长度超过两个字符的文本都意味着大大减少文本的高度。
在选择键盘布局(ENG)的示例实际上不是托盘区域中的通知图标,而是它自己的shell工具栏。
最好的效果是显示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);
}

以下是需要翻译的内容:

进行以下更改:

  1. 使用Trebuchet MS字体,它是一种非常窄的字体。
  2. 使用单引号代替句点,因为两侧留白更小。
  3. 使用字号10,并适当调整偏移量。

2
此外,我认为在此处使用“Tahoma”字体效果最佳。 - MSOACC
5
为了防止应用程序因内存泄漏而在约50分钟后退出,您需要添加这一行代码:DestroyIcon(hIcon)。请注意不要改变原文的意思,并尽可能使翻译通俗易懂。 - pollaris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接