В данной статье рассматриваются возможности работы с экраном (TScreen) в среде разработки Delphi, особенно актуально для случаев, когда требуется определение реального DPI-масштабирования экрана монитора. Это может быть необходимо, например, для корректной работы с высоким разрешением (Hi-DPI) мониторов.
Контекст
В контексте обсуждения пользователь столкнулся с проблемой, когда реальное разрешение монитора (1920x1080 пикселей) не отображалось в его программе из-за изменений в настройках системы, связанных с масштабированием шрифтов. Пользователь искал способ определить реальное DPI-масштабирование монитора, которое отличалось от стандартного значения 96 DPI.
Решение проблемы
Для определения реального DPI-масштабирования монитора в операционной системе Windows можно использовать функцию GetScaleFactorForMonitor, которая возвращает текущий масштаб для заданного монитора. Эта функция доступна начиная с Windows 8.1, поэтому для работы с более старыми версиями ОС необходимо использовать альтернативные методы, например, чтение значения из реестра.
Пример кода
type
TGetScaleFactorForMonitor = function(hmonitor: HMONITOR; out scale: UINT): HRESULT; stdcall;
var
ShcoreLib: HMODULE;
GetScaleFactorForMonitor: TGetScaleFactorForMonitor;
Scale: UINT;
begin
ShcoreLib := LoadLibrary('Shcore.dll');
if ShcoreLib <> 0 then
begin
@GetScaleFactorForMonitor := GetProcAddress(ShcoreLib, 'GetScaleFactorForMonitor');
if Assigned(GetScaleFactorForMonitor) then
begin
Scale := UINT(-1);
if GetScaleFactorForMonitor(Screen.PrimaryMonitor.Handle, Scale) = S_OK then
writeln('Scale factor: ', Scale)
else
writeln('Error calling GetScaleFactorForMonitor, HRESULT: ', Result);
end;
FreeLibrary(ShcoreLib);
end
else
writeln('Could not load Shcore.dll.');
end;
Альтернативное решение
Если необходимо поддержка старых версий Windows, можно использовать чтение значения из реестра, где хранится информация об установленном масштабировании:
uses
Registry;
var
AppliedDPI: Integer;
begin
if RegQueryIntValue(HKEY_CURRENT_USER, 'Control Panel\Desktop\WindowMetrics', 'AppliedDPI', AppliedDPI) then
writeln('Applied DPI: ', AppliedDPI)
else
writeln('AppliedDPI not found in the registry.');
end;
Примечания
Важно учитывать, что код должен запускаться в программе, где опции "Use LCL scaling (Hi-DPI)" и "DPI awareness" отключены.
При работе с динамическими библиотеками следует использовать кросс-платформенные подходы, например, с помощью DynLibs, чтобы обеспечить совместимость с различными операционными системами.
При написании статьи следует использовать примеры кода на Object Pascal (Delphi), что будет полезно для читателей, знакомых с этой средой разработки.
Заключение
В данной статье были рассмотрены способы определения реального DPI-масштабирования монитора в операционной системе Windows, включая использование функции GetScaleFactorForMonitor и чтение значения из реестра. Предоставленные примеры кода могут быть использованы в проектах, написанных на Object Pascal, для разработчиков, использующих среду Delphi.
Контекст описания связан с разработкой под Windows, где требуется корректно определять реальное DPI-масштабирование монитора для работы программ с различными разрешениями, особенно Hi-DPI.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS