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?
P.S: 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.