简体   繁体   中英

Can't get NotifyIcon to load high DPI resource for DPI scaling >= 150%

My application is DPI-Aware, here's the full manifest:

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
                manifestVersion="1.0">
    <assemblyIdentity name="SlackUI"
                      type="win32"
                      version="1.0.0.0" />
    <asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
</asmv1:assembly>

And I am setting my NotifyIcon icon property like this:

notifyIcon.Icon = new Icon(Program.Settings.Data.WhiteNotificationIcon ?
                Properties.Resources.NotifyWhite : Properties.Resources.NotifyColor, SystemInformation.SmallIconSize)

However, this is not working for DPI scaling equal or above 150% on my Windows 8.1 system. When it's set to 100% SystemInformation.SmallIconSize reports a 16x16 size (correct), when it's 125% it reports a 20x20 size (correct), above that, for instance 150%, it should report a 24x24 size but instead reports 16x16 and loads the wrong resolution from my icon file.

Reading the following article ( http://blog.quppa.net/2011/01/07/small-icon-size-dpi-in-windows/ ) it tells me that...

Both WPF and WinForms wrap around the Win32 GetSystemMetrics function taking the arguments SM_CXSMICON (small icon width) and SM_CYSMICON (small icon height).

Which means there's probably no need to call GetSystemMetrics myself, right?

Any idea on how can I solve this?

PS: I'm talking about an open-source application that I'm developing, so if you want to take a closer look at the full source code you can do so here .

Strong hint that your manifest is not in fact doing its job

It is not. From your github SlackUI/SlackUI.csproj file:

<ItemGroup>
  <None Include="app.manifest">
    <SubType>Designer</SubType>
  </None>
</ItemGroup>

What it should look like is:

<PropertyGroup>
  <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>

Note the highly specific <ApplicationManifest> element, required to let MSBuild know that this should be the manifest for the executable. I tested your version by pasting it into a .csproj file, building and then using File + Open + File, select the .exe file from the bin/Debug directory. Opened the RT_MANIFEST node and double-clicked resource #1. It was just the default one that the compiler auto-generates, not the modified one from the app.manifest file.

So that's why it doesn't work. I have no fantastic theory how this happened, maybe you added it by hand. You fix it by right-clicking app.manifest in the Solution Explorer window and deleting it. Now use Project > Add New Item > General > Application Manifest File. Paste the changes again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM