@ selb ie было полностью правильно и точно в цель с его комментарием. Он даже был достаточно любезен, чтобы выделить одну из ключевых фраз, чтобы я обратил на это внимание. @ selb ie облегчил мне задачу. Ниже я включил фрагменты моего тестового кода.
Windows Поведение
Как указывал @ selb ie, если в настройках специальных возможностей включено масштабирование 125%, чтобы сделать все больше, Windows сообщает о разном размере экрана для осведомленных и незнакомых процессов.
Для процессов, поддерживающих DPI, Windows сообщит 2560x1440, потому что они должны уменьшить свое мышление, чтобы Windows мог увеличить его на 125% для получения четкого текста и т. Д. c.
Для процессов, не поддерживающих DPI, Windows сообщит вызывающему абоненту 2048x1152, чтобы вызывающий считал, что экран меньше, чем он есть на самом деле. Windows увеличивает количество заказов вызывающего абонента на 125%, чтобы размеры абонента соответствовали аппаратному размеру экрана (2560x1440).
Проблема
Проблема, с которой я столкнулся, заключалась в том, что мой код модульного теста ( DPI unaware) использовал размеры аппаратного обеспечения в моем коде DLL (2560x1440), полученном из базы данных, а не ОС, поэтому, когда Windows увеличил его, мои перемещенные windows были больше, чем размер аппаратного экрана.
Когда одна и та же DLL использовалась в приложении Forms с поддержкой DPI, Windows разрешалось для всего (без увеличения net), а перемещенный windows соответствовал аппаратным экранам.
Решения
Первое решение состоит в том, чтобы ваш процесс вызова учитывал DPI, чтобы вы могли использовать аппаратные размеры экрана в своем коде. Сделайте это, вызвав Win32 API в NET 4.6 и выше. Это то, что я использовал в своем модульном тесте для правильной работы.
[STAThread]
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
static void Main() {
if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
... either ConsoleApp code or Windows.Forms code here
}
Второе решение - включить поддержку DPI в файле EXE app.manifest
. Просто раскомментируйте код XML по умолчанию в файле app.manifest
по умолчанию, созданном AddNew в Visual Studio.
APP.MANIFEST FILE
<application xmlns = "urn:schemas-microsoft-com:asm.v3" >
<windowsSettings >
<dpiAware xmlns = "http://schemas.microsoft.com/SMI/2005/WindowsSettings" >
true </dpiAware >
</windowsSettings >
</application >
В NET 4.7 и выше, вы также можете использовать новые настройки PerMonitorV2
DPI в файле app.config
, а не в файле app.manifest. Это, по-видимому, позволяет использовать разную чувствительность к DPI для разных мониторов. (Я еще не пробовал это, но я упоминаю здесь для полноты.)
<configuration>
<!--requires NET 4.7, and the default is false />
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
<add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
</System.Windows.Forms.ApplicationConfigurationSection>
</configuration>