Ответ 1
Это не настоящая проблема. Если вы отметите свой процесс как осведомленный о высоком DPI, тогда система больше не будет делать каких-либо виртуализации DPI, и API больше не будут лгать вам о фактических значениях.
В частности, если вы вызываете GetWindowRect
или GetClientRect
из приложения с высоким уровнем DPI, вы получите фактические значения в координатах экрана. Это будет справедливо не только для окон, принадлежащих вашему приложению, но также и для окон, принадлежащих другим процессам, независимо от того, что другие настройки уровня DPI процесса.
Начиная с Windows 8.1, PhysicalToLogicalPoint
и LogicalToPhysicalPoint
функции больше не нужны и фактически ничего не делают. Документация для этих двух функций вызывает это явно:
В Windows 8.1 дополнительная виртуализация системы и межпроцессорная коммуникация означают, что для большинства приложений вам не нужны эти API. В результате в Windows 8.1,
PhysicalToLogicalPoint
иLogicalToPhysicalPoint
больше не преобразуются точки. Система возвращает все точки в приложение в своем собственном пространстве координат.
Последнее предложение - это просто другой способ выражения того, что я сказал выше. Система возвращает значения в соответствии с осознанием DPI вызывающего абонента. Если ваш процесс имеет высокий уровень DPI, то вы получите реальные значения. Вам не нужно масштабировать значения самостоятельно. Если вы не осведомлены о высоком уровне DPI, вы подвергаетесь лживым действиям относительно фактических значений. Но это имеет смысл, потому что предполагается, что вы не можете справиться с правдой и не будете реагировать соответствующим образом.
Чтобы быть ясным, я должен отметить, что в настоящее время на уровне Windows 8.1 (и продолжаются в Windows 10) на самом деле есть два уровня осведомленности о высоком уровне DPI:
-
Существует первый уровень, введенный обратно с Windows Vista, с высоким уровнем осведомленности о DPI. Это указывается параметром
true
в файле манифеста приложения, а это просто означает, что вы (приложение) можете иметь дело с системным DPI, который установлен на что-то отличное от классического значения по умолчанию 96 DPI.Исходя из вышеприведенных знаний, мы знаем, что если процесс с этим параметром информирования DPI вызывает функцию API, которая возвращает координаты экрана, она получит значения в терминах DPI системы.
-
Затем появился новый уровень, представленный в Windows 8.1, для обеспечения высокого уровня DPI для каждого монитора. Об этом указывает параметр
True/PM
в манифесте приложения, а это означает, что вы (приложение) можете иметь дело с различными мониторами, имеющими разные настройки DPI. Другими словами, хотя по-прежнему существует DPI по умолчанию (и может быть 96 DPI или это может быть что-то еще), могут быть подключены мониторы к системе, которые используют другую настройку DPI (что-то иное, чем системный DPI).Опять же, на основе вышеизложенного понимания, мы знаем, что если процесс, который для каждого монитора с высоким уровнем DPI, вызывает функцию API, которая возвращает экранные координаты, он получит фактические координаты относительно DPI монитора, который содержит соответствующее окно.
Если ваш процесс вообще не распознается DPI (нет значения в манифесте или false
), то при вызове функций API, возвращающих координаты экрана, вы получите координаты, масштабированные/виртуализированные на основе общесистемного DPI 96 DPI.