dotnet / winforms

Windows Forms is a .NET UI framework for building Windows desktop applications.
MIT License
4.38k stars 971 forks source link

NotifyIcon does not use the appropriate icon size #6955

Open carlreinke opened 2 years ago

carlreinke commented 2 years ago

.NET version

6.0

Did it work in .NET Framework?

No

Did it work in any of the earlier releases of .NET Core or .NET 5+?

No response

Issue description

There is a long-known issue that NotifyIcon does not use the proper icon size. Rather than using the small icon size, it takes whatever size the System.Drawing.Icon has been constructed for (usually the default icon size), which Windows then scales down to the small icon size.

There is a work-around:

_notifyIcon.Icon = new Icon(_notifyIcon.Icon, SystemInformation.SmallIconSize);

NotifyIcon should do this itself.

Steps to reproduce

  1. Create a new WinForms project, name it "NotifyIconBug".
  2. Add a resource file and name it Resource1.resx.
  3. Add an icon with sizes of 16x16 and 32x32 to the Resource1.resx and name it application_icon. Use images for the two sizes of the icon that are distinguishable from one another.
  4. Add a NotifyIcon to Form1 and name it notifyIcon1.
  5. Set the Icon property of the NotifyIcon to the icon: notifyIcon1.Icon = Resource1.application_icon;
  6. Run the project, having the notification area on a low-DPI display. The 32x32 size of the icon is displayed scaled down to 16x16 rather than displaying the 16x16 size.

I'd guess you could also recreate this on a high-DPI display as well if you scale up the above sizes accordingly.

dreddy-work commented 2 years ago

Thanks @carlreinke for reporting this. We may need to follow this doc here to get it right.

ghost commented 2 years ago

This issue is now marked as "up for grabs", and we’re looking for a community volunteer to work on this issue. If we receive no interest in 120 days, we will close the issue. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!

carlreinke commented 2 years ago

I don't contribute to projects that use stale bot on bug reports.

dreddy-work commented 2 years ago

@carlreinke , I understand your hesitation here but know that we are constantly monitoring the repo and prioritizing the issues as they come. In this case, we think the product can be benefitted if community contributed given the limited resources team have. Hence marked so. This does not mean only the author of the issue needs to work on it. WinForms team own the responsibility of closing the issues in such cases.

elachlan commented 1 year ago

related to #8905 (multi-icon)

elachlan commented 9 months ago

If only a 16x16 pixel icon is provided, it is scaled to a larger size in a system set to a high dpi value. This can lead to an unattractive result. It is recommended that you provide both a 16x16 pixel icon and a 32x32 icon in your resource file. Use LoadIconMetric to ensure that the correct icon is loaded and scaled appropriately. See Remarks for a code example.

The following code example shows the use of LoadIconMetric to load an icon for use with high DPI.


// Declare NOTIFYICONDATA details. 
// Error handling is omitted here for brevity. Do not omit it in your code.

NOTIFYICONDATA nid = {}; nid.cbSize = sizeof(nid); nid.hWnd = hWnd; nid.uFlags = NIF_ICON | NIF_TIP | NIF_GUID;

// Note: This is an example GUID only and should not be used. // Normally, you should use a GUID-generating tool to provide the value to // assign to guidItem. static const GUID myGUID = {0x23977b55, 0x10e0, 0x4041, {0xb8, 0x62, 0xb1, 0x95, 0x41, 0x96, 0x36, 0x69}}; nid.guidItem = myGUID;

// This text will be shown as the icon's tooltip. StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Test application");

// Load the icon for high DPI. LoadIconMetric(hInst, MAKEINTRESOURCE(IDI_SMALL), LIM_SMALL, &(nid.hIcon));

// Show the notification. Shell_NotifyIcon(NIM_ADD, &nid) ? S_OK : E_FAIL;