Я попытался заставить Windows 8.1 распознавать приложение Delphi XE6 (демонстрационная программа), которое я пытался создать, и заставить его распознать, что мое приложение поддерживает Per-Monitor DPI, исключительно с помощью метода манифеста. Delphi XE6 (и все другие аналогично обновленные версии Delphi) упрощают добавление манифеста внутри параметров проекта, и я это сделал.
Это содержимое .manifest, которое я определил с помощью ресурсов MSDN. Я подозреваю, что это могло быть немного неправильно.
Если вы хотите попробовать этот манифест, создайте пустое приложение VCL, используйте это содержимое в качестве своего манифеста и добавьте код (код в настоящее время прилагается к моему ответу на этот вопрос).
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<!-- Per Monitor DPI Awareness in Windows 8.1 uses asmv3:application + asmv3:windowsSettings -->
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
<!-- Dear Microsoft, Don't Lie to Me About What Version of Windows I am On -->
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows Vista and Windows Server 2008 -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 and Windows Server 2008 R2 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 and Windows Server 2012 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 and Windows Server 2012 R2 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
</application>
</compatibility>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
Кто-нибудь заставил это работать? Я обнаружил, что вышеперечисленное не распознается. Если я сначала позвоню SetProcessDPIAwareness(Process_Per_Monitor_DPI_Aware)
, а затем позвоню GetProcessDPIAwareness(hProc,Awareness)
, я верну необходимое Awareness = Process_Per_Monitor_DPI_Aware
, но я прочитал, что у этого подхода есть потенциальные недостатки, и поэтому я бы предпочел рабочий подход, основанный только на манифесте.
Если я позвоню GetProcessDPIAwareness(hProc,Awareness)
, я вернусь `Awareness = Process_DPI_Unaware '.
Еще меня беспокоит то, что в источниках MSDN указывается добавление ДОПОЛНИТЕЛЬНОГО манифеста. Принимая во внимание, что я использую возможность IDE Delphi XE6 связывать ОДИН и ТОЛЬКО ОДИН манифест в мое приложение. Я никогда не замечал, что добавление какого-либо дополнительного манифеста вместо того, чтобы иметь только один, когда-либо было проблемой, кроме того, возможно, система управления .manifest в Visual Studio 2010 была хромой, и поэтому совет существовал, и поэтому не имеет отношения к другим IDE / Языки.
В Visual Studio 2013 есть флажок прямо внутри параметров проекта, но у меня нет Visual Studio 2013, поэтому я не могу проверить рабочий .manifest.
Обновить:
Вот еще один снимок манифеста:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
Приведенный выше мини-манифест изменяет поведение приложения, но не совсем так, как я хотел. С помощью приведенного выше крошечного манифеста определяется СТАРЫЙ уровень осведомленности Windows 8.0 / Windows 7 / Vista DPI.
обновление 2:
Спасибо Реми за идеи. Интересно, что следующего достаточно для запуска приложения. Однако смешивание синтаксиса SMI / 2005 с приведенным выше привело к ошибке параллельного запуска. Вы можете видеть, что Microsoft довольно много перемешивает свои манифесты. Обратите внимание, что следующее на самом деле не решает мою проблему, но предоставляет еще одну «потенциальную базовую форму», которая может быть БЛИЖАЙШЕЙ к реальному решению:
<assembly xmlns="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0" >
<application>
<windowsSettings xmlns="http://schemas.microsoft.com/SMI/2011/WindowsSettings">
<dpiAware>true</dpiAware>
</windowsSettings>
</application>
</assembly>
обновление 3:
КРАСНЫЙ КОД! НЕ ИСПОЛЬЗУЙТЕ следующий флаг СОВМЕСТИМОСТИ ОС в любом приложении Delphi VCL: <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
. У Microsoft есть BROKEN MOUSE CAPTURE BEHAVIOR, BROKEN WINDOW PAINTING, ужасные способы, о которых я даже не мог догадаться. Включение этого флага вызвало очень тонкие ошибки в моем приложении, в том числе проблемы с рисованием, невозможность щелкнуть по элементам управления (сообщения о нажатии мыши не доходят до элементов управления из-за потери захвата мыши) и многие другие проблемы.
<dependency>
первым, затем<compatibility>
, затем, наконец,<application>
последним. Это порядок, в котором эти функции были представлены в Windows. XML не должен быть чувствительным к порядку, но может быть, если используется схема XML. Парсер Windows может быть чувствительным к порядку, ему может потребоваться увидеть наличие элемента<compatibility>
Win8.1, прежде чем он обработает элемент<dpiAware>
. - person Remy Lebeau   schedule 11.11.2014<WindowsSettings>
-http://schemas.microsoft.com/SMI/2005/WindowsSettings
, документация по манифестам приложений говорит, что пространство именhttp://schemas.microsoft.com/SMI/2011/WindowsSettings
, поэтому попробуйте оба. - person Remy Lebeau   schedule 11.11.2014uses PerMonitorApi; ... SomeLabelControl.Visible := SystemCanSupportPerMonitorDpi( False);
- person Warren P   schedule 11.11.2014