Получение правильного RECT с поддержкой DPI из GetWindowRect из внешнего окна - PullRequest
13 голосов
/ 09 ноября 2011

Я делаю приложение DPI Aware, но мне нужно сделать GetWindowRect для HWND из других приложений.Моя проблема в том, что это нормально работает с приложениями, также поддерживающими DPI, но как мне определить, виртуален ли дескриптор HWND DPI, например, масштабирован, чтобы я мог масштабировать его сам?Или есть другие API, которые я пропустил, что даст мне размер окна с поддержкой DPI от HWND из другого процесса?

Я пробовал LogicalToPhysicalPoint, но это всегда кажется неудачнымВозможно, потому что HWND не принадлежит моему приложению.

Ответы [ 2 ]

6 голосов
/ 15 июня 2016

Это не актуальная проблема.Если вы отметите ваш процесс как поддерживающий высокое разрешение, система больше не будет выполнять виртуализацию DPI, и API больше не будут лгать вам о фактических значениях.

В частности, если вы вызываете GetWindowRect или GetClientRect из приложения с высоким разрешением, вы получите фактические значения в экранных координатах .Это будет справедливо не только для окон, принадлежащих процессу вашего приложения, но также и для окон, принадлежащих другим процессам, независимо от настройки осведомленности DPI этого другого процесса.

Начиная с Windows 8.1, PhysicalToLogicalPointФункции и LogicalToPhysicalPoint больше не нужны и фактически ничего не делают.В документации для этих двух функций это явно выражено:

В Windows 8.1 дополнительная виртуализация системы и межпроцессное взаимодействие означает, что для большинства приложений вам не нужны эти API.В результате в Windows 8.1 PhysicalToLogicalPoint и LogicalToPhysicalPoint больше не преобразуют точки.Система возвращает все точки приложения в своем собственном координатном пространстве.

Последнее предложение - просто другой способ выражения того, что я сказал выше. Система возвращает значения в соответствии с чувствительностью DPI для вызывающей стороны . Если ваш процесс поддерживает данные с высоким разрешением, вы получите реальные значения.Вам не нужно масштабировать значения самостоятельно.Если вы не осведомлены о высоком разрешении, вы можете обмануть насчет фактических значений.Но это имеет смысл, поскольку предполагается, что вы не можете справиться с истиной и не будете реагировать соответствующим образом.

Просто чтобы прояснить ситуацию, я должен указать, что на самом деле сейчас существует два уровня осведомленности с высоким DPI, так какWindows 8.1 (и продолжение в Windows 10):

  1. Существует первый уровень, представленный еще в Windows Vista, с высокой степенью разрешения DPI.На это указывает установка true в файле манифеста приложения, и это просто означает, что вы (приложение) можете работать с system DPI, для которого установлено что-то отличное от классического значения по умолчанию.из 96 DPI.

    Исходя из вышеизложенного, мы знаем, что если процесс с этим параметром DPI-осведомленности вызывает функцию API, которая возвращает экранные координаты, он получит значения в терминах DPI системы.

  2. Затем появился новый уровень, представленный в Windows 8.1, с на монитор с высоким разрешением.На это указывает настройка True/PM в манифесте приложения, и это означает, что вы (приложение) можете работать с разными мониторами, имеющими разные настройки DPI.Другими словами, хотя системный DPI по-прежнему существует (и это может быть 96 DPI, или это может быть что-то еще), к системе могут быть подключены мониторы, которые используют другой параметр DPI (что-то отличное от системного DPI).

    Опять же, исходя из вышеизложенного понимания, мы знаем, что если процесс, который поддерживает каждый монитор с высоким DPI, вызывает функцию API, которая возвращает экранные координаты, он получит фактические координаты относительно DPIмонитор с этим окном.

Если ваш процесс вообще не поддерживает DPI (нет настроек в манифесте или false), то при вызове функций API, которые возвращаюткоординаты экрана, вы получите координаты, масштабированные / виртуализированные на основе общесистемного DPI, равного 96 DPI.

0 голосов
/ 15 июня 2016

Флаг, поддерживающий DPI, устанавливается на уровне приложения, а не на уровне окна. Поэтому, если вы можете получить обработку этого конкретного дескриптора окна другого приложения, вы можете использовать функцию GetProcessDpiAwareness(), чтобы получить флаг, поддерживающий dpi этого конкретного окна. процесс, пожалуйста, смотрите эту документацию Microsoft https://msdn.microsoft.com/en-us/library/windows/desktop/dn302113(v=vs.85).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...