Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows chooses wrong icon from multi-icon file and self renders to correct size

I have an .ico file with 5 icon sizes embedded in it being used as the main application icon and the System Tray icon.

When it shows up in the task bar the icon is using the 16x16 format which is desired. When the icon shows up in the Notification Area/System tray, it is using the 32x32 format and Windows is rendering it down to a 16x16 icon, which looks horrible.

How do I force windows to use the 16x16 icon size in the notification area? Here's my code to put the icon in the system tray:

ContextMenu cmNotify = new ContextMenu();
MenuItem miNotify = new MenuItem(Properties.Resources.Notify_Text);
miNotify.DefaultItem = true;
miNotify.Click += new EventHandler(notifyHandler);
cmNotify.MenuItems.Add(miNotify);


notifyIcon = new NotifyIcon();
notifyIcon.Icon = this.Icon;
notifyIcon.Visible = true;
notifyIcon.ContextMenu = cmNotify;
notifyIcon.Text = AppConstants.APPLICATION_NAME;
like image 702
BrianH Avatar asked Mar 05 '09 20:03

BrianH


3 Answers

Both responses are close, but contain a subtle poison. You should not hardcode the requested size as 16x16.

Instead, query SystemInformation.SmallIconSize to determine the appropriate dimensions. Although the default is certainly 16x16, this could be changed by various things, such as DPI scaling.

See the MSDN article for more information on this property.

An example of usage would be

notifyIcon.Icon = new System.Drawing.Icon(this.Icon, SystemInformation.SmallIconSize),
like image 60
Lem Avatar answered Nov 18 '22 07:11

Lem


Change this:

notifyIcon.Icon = this.Icon;

to this:

notifyIcon.Icon = new System.Drawing.Icon(this.Icon, 16, 16);
like image 33
BrianH Avatar answered Nov 18 '22 08:11

BrianH


You need to create a new instance of the icon. When creating (loading) the new instance, specify the size. The Icon class constructor has several different overloads for you to choose from. Here's how you can do it if the icon file is embedded into your main executable (which is often the case):

Assembly asm = this.GetType().Assembly;

var smallIconSize = new System.Drawing.Size(16, 16);
notifyIcon.Icon = new System.Drawing.Icon(
    asm.GetManifestResourceStream("MyPrettyAppIcon.ico"), smallIconSize);
like image 1
irobot Avatar answered Nov 18 '22 06:11

irobot