GetClientRect возвращает масштабированные размеры?

Я зову GetClientRect через pinvoke в C# для получения размеров панели (в WindowsForm) я использую в качестве целевой области рендеринга DirectX. Я бы подумал, что WinAPI дает мне немасштабированные (т. Е. Возвращаемые значения должны быть одинаковыми независимо от настроек DPI дисплея Windows), но вместо этого он дает мне масштабированное (по крайней мере, в Windows 8.1, поскольку я его не тестировал) на других ОС).

ClientRectangle свойство также возвращает те же масштабированные размеры, что и GetClientRect, Это остается тем же, когда я изменил форму AutoScaleMode в none,

Это ожидаемое поведение с GetClientRect? Если да, то как мне получить немасштабированные размеры?

РЕДАКТИРОВАТЬ: Это влияет только на Windows 8.1. Протестировано на Windows 7 и GetClientRect возвращает немасштабированные размеры!

1 ответ

Решение

Там нет никакого преимущества для P/Invoking GetClientRect, Вы получаете точно то же самое, запрашивая ClientRectangle имущество.

И да, любой из них собирается вернуть размер клиентской области в физических пикселях, что явно не то, что вам нужно.

Вы, наверное, ищете ID2D1RenderTarget::GetSize метод, который возвращает размер цели рендеринга в независимых от устройства пикселях (DIP).

Если вам нужно преобразовать физические пиксели (например, из событий мыши), вы можете использовать что-то вроде ID2D1Factory::GetDesktopDpi чтобы получить текущие коэффициенты масштабирования, которые вы можете использовать для преобразования физических пикселей в DIP.

Причина, по которой вы видите другое поведение в Windows 8.1, вероятно, является результатом изменений в способе, которым она обрабатывает масштабирование DPI. Вы можете обнаружить, что указание вашего приложения с поддержкой DPI- более простое решение, чем приведенное выше. Это остановит автоматическое масштабирование пользовательского интерфейса в соответствии с текущими настройками DPI. Вы делаете это, добавляя следующее в манифест приложения:

<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/PM</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
</assembly>

В Visual Studio щелкните правой кнопкой мыши проект и выберите "Добавить" -> "Новый элемент". Выберите "Файл манифеста приложения" и добавьте приведенный выше код.

Связанное чтение: Написание DPI-Aware Desktop и приложений Win32

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