Recent

Author Topic: [SOLVED] Windows: how to query the real DPI-setting of the monitor?  (Read 2588 times)

Seenkao

  • Hero Member
  • *****
  • Posts: 649
    • New ZenGL.
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #15 on: October 18, 2024, 05:07:36 pm »
Hello Seenkao, maybe we misunderstood. I need to know, in which Unit functions dlopen() and dlsym() exist. I must include this Unit with the 'uses' command.
В моём случае, это объявленные функции.

Google translate:
In my case, these are declared functions.
Code: Pascal  [Select][+][-]
  1. function dlopen (lpLibFileName: PAnsiChar): HMODULE; stdcall; external 'kernel32.dll' name 'LoadLibraryA';
  2. function dlclose(hLibModule: HMODULE): Boolean; stdcall; external 'kernel32.dll' name 'FreeLibrary';
  3. function dlsym  (hModule: HMODULE; lpProcName: PAnsiChar): Pointer; stdcall; external 'kernel32.dll' name 'GetProcAddress';


dlopen() is a Linux function.
Не путайте пожалуйста людей! В Windows эти функции так же существуют.
Но большинству людей лучше использовать стандартные функции.

Google translate:
Please don't confuse people! These functions also exist in Windows.  :)
But most people are better off using the default features.
Rus: Стремлюсь к созданию минимальных и достаточно быстрых приложений.

Eng: I strive to create applications that are minimal and reasonably fast.
Working on ZenGL

rvk

  • Hero Member
  • *****
  • Posts: 6640
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #16 on: October 18, 2024, 05:32:54 pm »
In my case, these are declared functions.
Code: Pascal  [Select][+][-]
  1. function dlopen (lpLibFileName: PAnsiChar): HMODULE; stdcall; external 'kernel32.dll' name 'LoadLibraryA';
  2. function dlclose(hLibModule: HMODULE): Boolean; stdcall; external 'kernel32.dll' name 'FreeLibrary';
  3. function dlsym  (hModule: HMODULE; lpProcName: PAnsiChar): Pointer; stdcall; external 'kernel32.dll' name 'GetProcAddress';

Please don't confuse people! These functions also exist in Windows.  :)
But most people are better off using the default features.
No, dlopen and dlclose do NOT exist on Windows as dlopen and dlclose.
What you are doing there is just re-mapping LoadLibraryA from kernel32.dll to a function called dlopen.
But as a name, dlopen it doesn't not exists on Windows.

For Windows the function LoadLibrary is already defined.

BTW. Even on Linux you can use the LoadLibrary, which is re-mapped in FPC to dlopen()  ;)

Of course you can do it the other way around (like you did) but for FPC these (LoadLibrary) is already standard defined.

Seenkao

  • Hero Member
  • *****
  • Posts: 649
    • New ZenGL.
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #17 on: October 18, 2024, 05:51:38 pm »
Да, вы правы. Я слишком заработался и уже подзабыл об этом.  :)


Google translate:
Yes, you are right. I was too busy working and had already forgotten about it. :)
Rus: Стремлюсь к созданию минимальных и достаточно быстрых приложений.

Eng: I strive to create applications that are minimal and reasonably fast.
Working on ZenGL

jcmontherock

  • Sr. Member
  • ****
  • Posts: 274
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #18 on: October 18, 2024, 06:25:12 pm »
You can find it in regedit at:

HKCU/Control Panel/DesktopWindowMetrics

Windows 11 UTF8-64 - Lazarus 4RC1-64 - FPC 3.2.2

LV

  • Full Member
  • ***
  • Posts: 189
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #19 on: October 18, 2024, 10:13:09 pm »
My sister has a laptop with real 1920x1080 pixels. But she changed something in the Windows10 System-Control to have bigger Fonts and this results, that only 1536x864 pixels

Proportion:
1920 - 100 %
1536 - x %,

therefore x = 125%

- "System" > "Screen" > "Scaling": 100% (96ppi), 125% (120ppi)
 

=>    120ppi

rvk

  • Hero Member
  • *****
  • Posts: 6640
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #20 on: October 18, 2024, 10:24:28 pm »
1920 - 100 %
1536 - x %,

therefore x = 125%
Of course the problem is that the 1920 is not known by the program. It's not dpi aware so the system just reports 1536. You know nothing about that 1920. How are you then going to get that x? That's why this topic was started (with the two solutions given).

LV

  • Full Member
  • ***
  • Posts: 189
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #21 on: October 18, 2024, 10:31:08 pm »
given

My sister has a laptop with real 1920x1080 pixels.

to find ...

rvk

  • Hero Member
  • *****
  • Posts: 6640
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #22 on: October 18, 2024, 10:36:16 pm »
given

My sister has a laptop with real 1920x1080 pixels.

to find ...
Note the red part in this quote

My sister has a laptop with real 1920x1080 pixels. But she changed something in the Windows10 System-Control to have bigger Fonts and this results, that only 1536x864 pixels are reported by this command:
Code: Pascal  [Select][+][-]
  1. writeln(Screen.Width, 'x', Screen.Height);
So how are you going to get that 1920 in code??

LV

  • Full Member
  • ***
  • Posts: 189
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #23 on: October 18, 2024, 10:40:36 pm »
I want to detect, that this laptop runs with 120 dpi.

rvk

  • Hero Member
  • *****
  • Posts: 6640
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #24 on: October 18, 2024, 10:45:16 pm »
I want to detect, that this laptop runs with 120 dpi.
So, how would you do that without knowing 1920 but only 1536?

My screen could be a different resolution.
For 4k screens a much higher resolution is normal with higher dpi settings.

I'm currently testing with an nvidia virtual resolution of 4k.
3840 at 250% also gives 1536.

So... For knowing the dpi you would still need to detect the real screen width (which isn't reported to your program due to the NON-dpi awareness). That's why you need the GetScaleFactorForMonitor or registry (or retrieve the real width some other way).

« Last Edit: October 18, 2024, 10:54:19 pm by rvk »

LV

  • Full Member
  • ***
  • Posts: 189
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #25 on: October 18, 2024, 10:54:41 pm »
So, how would you do that

Occam's razor "Entities must not be multiplied beyond necessity"  :)

Hartmut

  • Hero Member
  • *****
  • Posts: 891
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #26 on: October 19, 2024, 04:08:00 pm »
First of all the good news: meanwhile I got the results from my sisters Win10 laptop (which has an increased Font size):
 - GetScaleFactorForMonitor() returns 125%, which is exact the result I was searching for.
 - GetDpiForMonitor() returns 2x '96', so in this case it is not usable (but I put it in my drawer for a future use).



But she changed something in the Windows10 System-Control to have bigger Fonts
There are two ways to change the size of fonts in Windows
- "System" > "Screen" > "Scaling": 100% (96ppi), 125% (120ppi), 150% (144 ppi), etc. - this changes the pixel density, i.e. the ppi, and this is what Screen.PixelsPerInch reports (and LCL uses for scaling)
- "Ease of Access" > "Text size": slider starting at 100% - this changes only the text size, not the ppi. Screen.PixelsPerInch always reports the same value (not handled by LCL scaling). Maybe this is what your sister changed.

Thank you wp for clarification. My sister does not remember what she changed. I will check it when I visit her the next time.



Thanks a lot to all who helped me. Special thanks to Seenkao and rvk for helping me to load this dll dynamically. Again I learned a lot.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5802
  • Compiler Developer
Re: Windows: how to query the real DPI-setting of the monitor?
« Reply #27 on: October 20, 2024, 11:15:59 am »
Thanks rvk, now I begin to understand. I will use your code. Which Unit do I need for LoadLibrary() and GetProcAddress() and FreeLibrary() ?

If you use the DynLibs unit then LoadLibrary, GetProcAddress and FreeLibrary are available on all platforms that support dynamic libraries. On e.g. *nix-based platforms they'll internally use dlopen, dlsym and dlclose respectively.

Hartmut

  • Hero Member
  • *****
  • Posts: 891
Re: [SOLVED] Windows: how to query the real DPI-setting of the monitor?
« Reply #28 on: October 20, 2024, 11:42:26 am »
Thanks PascalDragon for that info. Until now I use Unit 'system' for these 3 functions. Is Unit DynLibs anyhow better than Unit 'system' for this?

rvk

  • Hero Member
  • *****
  • Posts: 6640
Re: [SOLVED] Windows: how to query the real DPI-setting of the monitor?
« Reply #29 on: October 20, 2024, 05:58:40 pm »
Thanks PascalDragon for that info. Until now I use Unit 'system' for these 3 functions. Is Unit DynLibs anyhow better than Unit 'system' for this?
For Windows this doesn't matter. Actually... DynLibs.LoadLibrary just calls System.LoadLibrary.

(Not sure if that's the case for all OS'es. Maybe others need to do InitDynLibs first, but for Windows this is empty.)

If you set your cursor on LoadLibrary (with DynLibs in your uses) and press ALT+Up and CTRL+SHIFT+Down, you'll see the implementation of DynLibs.LoadLibrary (which is even declared as inline).

Code: Pascal  [Select][+][-]
  1. Function LoadLibrary(const Name : UnicodeString) : TLibHandle;
  2. begin
  3.   Result:=System.LoadLibrary(Name);
  4. end;

So for Windows it makes no difference but if you go cross-platform you might need to add DynLibs to you uses clause.
See https://wiki.freepascal.org/Lazarus/FPC_Libraries#Loadlibrary_-_dynamically_loading_a_dynamic_library


 

TinyPortal © 2005-2018