Windows 11 always takes a bigger PNG from ICO

youki 966 Reputation points
2023-11-15T03:10:12.7233333+00:00

I created an ICO file from PNG files (16-128 px) with IconFX. I’m using it in the system tray by NotifyIconData and LoadImage. It always takes a bigger size from the ICO and scales it down for displaying it in the system tray, it doesn‘t take the 16 or 32 px. Is that normal?

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,289 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,325 questions
Windows 11
Windows 11
A Microsoft operating system designed for productivity, creativity, and ease of use.
6,806 questions
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Castorix31 79,921 Reputation points
    2023-11-15T04:45:22.27+00:00

    I had done a test in WinUI 3 (C#), on Windows 10 22H2 also with a 16-128 icon (WinUI3_NotifyIcon, butterfly.ico in \Assets)

    I used LoadImage with 32 * 32, line 456 in https://github.com/castorix/WinUI3_NotifyIcon/blob/master/MainWindow.xaml.cs#L456C23-L456C32

    and NOTIFYICONDATA with the returned handle and NIF_ICON in https://github.com/castorix/WinUI3_NotifyIcon/blob/master/NotifyIcon.cs

    0 comments No comments

  2. Jeanine Zhang-MSFT 7,696 Reputation points Microsoft Vendor
    2023-11-15T06:13:41.9466667+00:00

    Hello,

    Welcome to Microsoft Q&A!

    According to the Doc:Icon scaling

    When Windows displays your app's icon, it will look for an exact size match first. If there is no exact match it will look for the next size above and scale down.

    I suggest you could try to use LoadIconMetric instead of LoadImage.

    Icons are extracted or created as follows.

    If an exact size match is found in the resource, that icon is used.

    If an exact size match cannot be found and a larger icon is available, a new icon is created by scaling the larger version down to the desired size.

    If an exact size match cannot be found and no larger icon is available, a new icon is created by scaling a smaller icon up to the desired size.

    Thank you.

    Jeanine


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  3. youki 966 Reputation points
    2023-11-16T01:33:52.49+00:00

    Guys,

    That's terrible.

    It is said everywhere that Windows uses the correct icon size, but that is not true with LoadIcon and LoadIconMetric.

    This only works when starting the application. During runtime, these methods scale the icons. I really don't understand how others do it. I can't find anything online that works on my Windows 11 computer.

    For LoadImage, I don't know if GetSystemMetrics(SM_CXSMICON) is correct, but it doesn't change its value via WM_DPICHANGED. I don't really know if my calculation is correct, I'll have to test it out, although I always have to adjust the icon design.

    My calculation is also different from GetSystemMetrics(SM_CXSMICON) above a specific scaling size.

    0 comments No comments

  4. youki 966 Reputation points
    2023-11-20T00:52:22.1633333+00:00

    To summarize again:

    The only solution for me is LoadImage to load the right size for my system tray icon. I calculate the size as follows:

    auto scaling = GetDpiForWindow(hWnd);
    auto iconSize = MulDiv(16, scaling, USER_DEFAULT_SCREEN_DPI);
    nid.hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON14), IMAGE_ICON, iconSize, iconSize, LR_DEFAULTCOLOR);
    

    This also works when executed by WM_DPICHANGED if the resolution or scaling changes during runtime.

    0 comments No comments