GetScaleFactorForMonitor - неверное значение

Oleg6619
Дата: 19.09.2019 09:59:37
Добрый день!
Есть Windows10 с установленным масштабом <>100%.
Для определения этого параметра использую GetScaleFactorForMonitor.
Если установлен 125%, то функция возвращает 100.
Если - 150 или 175%, то - 140.

GetDpiForMonitor всегда выдает 96dpi.

Где "собака порылась"?
Использую Delphi2007, но т.к. GetScaleFactorForMonitor вызываю из DLL, то это не принципиально.
ziv-2014
Дата: 19.09.2019 11:54:19
Oleg6619,
https://docs.microsoft.com/ru-ru/windows/win32/api/shtypes/ne-shtypes-device_scale_factor
https://docs.microsoft.com/en-us/windows/win32/api/shellscalingapi/nf-shellscalingapi-getscalefactorformonitor

typedef enum DEVICE_SCALE_FACTOR {
DEVICE_SCALE_FACTOR_INVALID,
SCALE_100_PERCENT,
SCALE_120_PERCENT,
SCALE_125_PERCENT,
SCALE_140_PERCENT,
SCALE_150_PERCENT,
SCALE_160_PERCENT,
SCALE_175_PERCENT,
SCALE_180_PERCENT,
SCALE_200_PERCENT,
SCALE_225_PERCENT,
SCALE_250_PERCENT,
SCALE_300_PERCENT,
SCALE_350_PERCENT,
SCALE_400_PERCENT,
SCALE_450_PERCENT,
SCALE_500_PERCENT
} ;
Oleg6619
Дата: 19.09.2019 12:19:00
Спасибо, но я это всё читал.

В переписке говорится, что DPI=144. А у меня GetDpiForMonitor тоже выдает 96dpi.

И никак с этим не справится.

Windows10 - последней сборки (Win32 will only return the correct value for version 1703 (Creator's Update)), так что должна по идее выдавать правильно. Но на деле.....
DmSer
Дата: 19.09.2019 12:36:18
А если такую процедурку сперва вызвать:

procedure CallSetProcessDPIAware;
var
  SetProcessDPIAware: function: Boolean; stdcall;
  H: THandle;
begin
  H := GetModuleHandle('User32.dll');
  if H > 0 then
  begin
    @SetProcessDPIAware := GetProcAddress(H, 'SetProcessDPIAware');
    if Assigned(SetProcessDPIAware) then
      SetProcessDPIAware();
  end;
end;
Oleg6619
Дата: 19.09.2019 12:47:32
DmSer
А если такую процедурку сперва вызвать:

procedure CallSetProcessDPIAware;
var
  SetProcessDPIAware: function: Boolean; stdcall;
  H: THandle;
begin
  H := GetModuleHandle('User32.dll');
  if H > 0 then
  begin
    @SetProcessDPIAware := GetProcAddress(H, 'SetProcessDPIAware');
    if Assigned(SetProcessDPIAware) then
      SetProcessDPIAware();
  end;
end;


А вот это помогло.
Спасибо!
Belotsky Serge
Дата: 19.09.2019 14:04:48
Oleg6619,
Не знаю, как в 2007, но в XE3 есть глобальная переменная Screen :TScreen;
        H1 := Screen.PixelsPerInch; // получить текущее DPI экрана