Не удается получить NotifyIcon для загрузки ресурса с высоким DPI для масштабирования DPI>= 150%

Мое приложение поддерживает DPI, вот полный манифест:

<?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>

И я устанавливаю свой NotifyIcon Свойство icon вроде этого:

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

Однако это не работает для масштабирования DPI, равного или превышающего 150% в моей системе Windows 8.1. Когда он установлен на 100% SystemInformation.SmallIconSize сообщает размер 16x16 (правильный), когда он составляет 125%, он сообщает размер 20x20 (правильный), при этом выше, например, 150%, он должен сообщать размер 24x24, но вместо этого сообщает 16x16 и загружает неправильное разрешение из моего файла значков.

Читая следующую статью ( http://blog.quppa.net/2011/01/07/small-icon-size-dpi-in-windows/), я узнаю, что...

И WPF, и WinForms обернуты вокруг функции Win32 GetSystemMetrics, принимая аргументы SM_CXSMICON (малая ширина значка) и SM_CYSMICON (малая высота значка).

Это означает, что, вероятно, нет необходимости звонить GetSystemMetrics себя, верно?

Любая идея о том, как я могу решить это?

PS: я говорю о приложении с открытым исходным кодом, которое я разрабатываю, поэтому, если вы хотите поближе взглянуть на полный исходный код, вы можете сделать это здесь.

1 ответ

Решение

Сильный намек на то, что ваш манифест на самом деле не выполняет свою работу

Это не. Из вашего файла github SlackUI/SlackUI.csproj:

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

Как это должно выглядеть:

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

Обратите внимание на весьма специфический <ApplicationManifest> элемент, необходимый, чтобы MSBuild знал, что это должен быть манифест для исполняемого файла. Я проверил вашу версию, вставив ее в файл.csproj, собрав, а затем, используя File + Open + File, выберите файл.exe из каталога bin/Debug. Открыл узел RT_MANIFEST и дважды щелкнул ресурс #1. Компилятор автоматически генерирует компилятор по умолчанию, а не модифицированный из файла app.manifest.

Вот почему это не работает. У меня нет фантастической теории, как это произошло, может быть, вы добавили это вручную. Чтобы исправить это, щелкните правой кнопкой мыши app.manifest в окне обозревателя решений и удалите его. Теперь используйте "Проект"> "Добавить новый элемент"> "Основные"> "Файл манифеста приложения". Вставьте изменения снова.

Другие вопросы по тегам