[SOLVED] Windows: how to query the real DPI-setting of the monitor? lazarus / 34-Windows ---------------------------------------------------------------------- Hartmut · 2024-10-17 17:03 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i writeln(Screen.Width, 'x', Screen.Height); I did expect that this commands Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i writeln('DPI-Faktor1: ', Screen.PixelsPerInch);writeln('DPI-Faktor2: ', Screen.PrimaryMonitor.PixelsPerInch);would return '120', but both return '96'. I want to detect, that this laptop runs with 120 dpi. How can I do that? Is there a function in the LCL for that? Or a Windows-API- function? I googled for that but (in a reliable time) got lost in a labyrinth of very complicated links. Important: the code to detect the 120 dpi must run in a program with setting Project Options / Application / "Use LCL scaling (Hi-DPI)" and "DPI awareness" both = off. Thanks in advance. ---------------------------------------------------------------------- Thaddy · 2024-10-17 18:09 TScreen. Which is already initialized as Screen. ---------------------------------------------------------------------- Seenkao · 2024-10-17 22:47 Да я столкнулся с масштабированием в Windows. Рекомендованные способы определения масштаба вели к вычислению DPI, но при запросе DPI вывод был 96. При более подробном изучении, я узнал, что есть функция GetScaleFactorForMonitor которая возвращает текущий масштаб для данного монитора. Google translate: Yes, I encountered scaling in Windows. The recommended methods for determining the scale led to calculating the DPI, but when querying the DPI, the output was 96. Upon closer examination, I learned that there is a function GetScaleFactorForMonitor that returns the current scale for a given monitor. for pascal: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetScaleFactorForMonitor(hmonitor: HMONITOR; out Scale: UINT): HRESULT; stdcall; external 'Shcore.dll'; ---------------------------------------------------------------------- Hartmut · 2024-10-18 11:17 Thank you very much Seenkao for that suggestion. This is my code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetScaleFactorForMonitor(hmonitor: HMONITOR; out scale: UINT): HRESULT;                                 stdcall; external 'Shcore.dll'; procedure winShowPrimMonitorDPI;   {shows the DPI- percentage of the Primary Monitor}   var h: HMONITOR;       scale: UINT;       res: HRESULT;   begin   h:=Screen.PrimaryMonitor.Handle;   scale:=UINT(-1);   res:=GetScaleFactorForMonitor(h, scale);writeln('res=', res, ' scale=', scale);   end; The good news is: on my Win10 computer (which has a normal Font size) it works and results 'res=0, scale=100'. For the result on my sisters Win10 laptop (which has an increased Font size) I'm still waiting. The bad news is: unfortunately function GetScaleFactorForMonitor() does exist only from Win 8.1 on. And when I start above code on my Win7 computer, the program crashes immediately at start without any message. When I start it within the Lazarus IDE with the Debugger then I get this message: Code: [Select]The program can not be started, because Shcore.dll is missing on the computer. Install the program again to solve the problem. That means, if I create any program which contains function GetScaleFactorForMonitor(), then this program will crash at starting time on computers with Win8 or older. Unfortunately I can not live with that. What I need is a function to query the real DPI setting and it is ok, if this functions returns an error code (which I can catch) if it runs on e.g. Win7, but it may not crash. Do you (or someone else) have another idea? ---------------------------------------------------------------------- wp · 2024-10-18 11:38 Quote from: Hartmut on October 17, 2024, 07:03:46 pmBut 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. ---------------------------------------------------------------------- Seenkao · 2024-10-18 11:45 Вам надо создать функцию как переменную, произвести её активацию и при вызове её произвести проверку на существование данной функции. Код ниже прилагаю, но для вас он может быть не совсем верным. Используйте для данных действий уже готовые средства FPC/Lazarus. И, на всякий случай, проверку DPI так же желательно производить! Потому что на разных системах, программы могут работать по разному. Google translate: You need to create a function as a variable, activate it and when calling it, check for the existence of this function. I attach the code below, but it may not be entirely correct for you. Use ready-made FPC/Lazarus tools for these actions. And, just in case, it is also advisable to check the DPI! Because on different systems, programs may work differently. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  libShcore: HMODULE;  ...  GetDpiForMonitor: function(hmonitor: HMONITOR; dpiType: TMonitorDpiType; out dpiX: UINT; out dpiY: UINT): HRESULT; stdcall;  GetScaleFactorForMonitor: function(hmonitor: HMONITOR; out Scale: UINT): HRESULT; stdcall;... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure SetProcPoint;begin  ...   libShcore := dlopen('Shcore.dll');  if libShcore <> LIB_ERROR then  begin    (GetDpiForMonitor) := dlsym(libShcore, 'GetDpiForMonitor');    (GetScaleFactorForMonitor) := dlsym(libShcore, 'GetScaleFactorForMonitor');  end  else begin    (GetDpiForMonitor) := nil;    (GetScaleFactorForMonitor) := nil;  end;  ...end; Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TestScale;var  outX, outY: LongWord;begin  ...  if Assigned(GetScaleFactorForMonitor) then    if GetScaleFactorForMonitor(scrMonitor, outX) = S_OK then      scrScaleWindow := 100 / outx;  if (Assigned(GetDpiForMonitor)) and (outX = 100) then    if GetDpiForMonitor(scrMonitor, MDT_EFFECTIVE_DPI, outX, outY) = S_OK then      scrScaleWindow := 96 / outX;  ...end; Товарищи разработчики FPC/Lazarus, внесите пожалуйста данную функцию в ваш код! Так же можете использовать код, что я скинул, он сделан по вашему подобию и думаю не составит труда внести изменения. Google translate: Comrades FPC/Lazarus developers, please add this function to your code! You can also use the code that I dropped, it is made in your likeness and I think it will not be difficult to make changes. ---------------------------------------------------------------------- rvk · 2024-10-18 11:59 Quote from: Hartmut on October 17, 2024, 07:03:46 pmImportant: the code to detect the 120 dpi must run in a program with setting Project Options / Application / "Use LCL scaling (Hi-DPI)" and "DPI awareness" both = off. Just curious... why can't you have DPI awareness set to True in the Project options? (it's what gives Screen.PixelsPerInch its correct value) GetScaleFactorForMonitor works for me too on Windows 10. Quote from: Hartmut on October 18, 2024, 01:17:24 pmThat means, if I create any program which contains function GetScaleFactorForMonitor(), then this program will crash at starting time on computers with Win8 or older. Unfortunately I can not live with that. What I need is a function to query the real DPI setting and it is ok, if this functions returns an error code (which I can catch) if it runs on e.g. Win7, but it may not crash. Do you (or someone else) have another idea? You could try to see how Screen.PixelsPerInch does it. What are you going to do with the value? Because you set your program to be NOT DPI AWARE. So using that number for things, will screw up other things. But, ok, you asked for another idea... You defined the function GetScaleFactorForMonitor as stdcall; external 'Shcore.dll'; That's going to load the Shcore.dll at startup. If you don't want that, and you want to catch the non-exist error, then you need to load the Shcore.dll dynamically during runtime with LoadLibrary and GetProcAddress. Something like... (not tested): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TGetScaleFactorForMonitor = function(hmonitor: HMONITOR; out scale: UINT): HRESULT; stdcall; var  ShcoreLib: HMODULE;  GetScaleFactorForMonitor: TGetScaleFactorForMonitor;begin  ShcoreLib := LoadLibrary('Shcore.dll'); // Load the library  if ShcoreLib <> 0 then  begin    // Get the procedure address    @GetScaleFactorForMonitor := GetProcAddress(ShcoreLib, 'GetScaleFactorForMonitor');    if Assigned(GetScaleFactorForMonitor) then    begin      // Call the function      result := GetScaleFactorForMonitor(hMonitor, scale);      if result = S_OK then        Writeln('Scale factor: ', scale)      else        Writeln('Error calling GetScaleFactorForMonitor, HRESULT: ', result);    end    else      Writeln('GetScaleFactorForMonitor function not found in Shcore.dll.');    // Free the library    FreeLibrary(ShcoreLib);  end  else    Writeln('Could not load Shcore.dll.'); (Seenkao just beat me to it ) ---------------------------------------------------------------------- Hartmut · 2024-10-18 14:04 Thanks a lot to all for your valuable replies. I will answer them detailed later. Currently I'm stuck because I dont find the Unit for dlopen, LIB_ERROR and dlsym in a reliable time. I'm a bloody beginner to all this dll stuff. Can please someone help? ---------------------------------------------------------------------- Seenkao · 2024-10-18 14:06 Quote from: rvk on October 18, 2024, 01:59:37 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TGetScaleFactorForMonitor = function(hmonitor: HMONITOR; out scale: UINT): HRESULT; stdcall; var  ShcoreLib: HMODULE;  GetScaleFactorForMonitor: TGetScaleFactorForMonitor;begin  ShcoreLib := LoadLibrary('Shcore.dll'); // Load the library  if ShcoreLib <> 0 then  begin    // Get the procedure address    @GetScaleFactorForMonitor := GetProcAddress(ShcoreLib, 'GetScaleFactorForMonitor');    if Assigned(GetScaleFactorForMonitor) then    begin      // Call the function      result := GetScaleFactorForMonitor(hMonitor, scale);      if result = S_OK then        Writeln('Scale factor: ', scale)      else        Writeln('Error calling GetScaleFactorForMonitor, HRESULT: ', result);    end    else      Writeln('GetScaleFactorForMonitor function not found in Shcore.dll.');    // Free the library    FreeLibrary(ShcoreLib);  end  else    Writeln('Could not load Shcore.dll.'); GetProcAddress and LoadLibrary ---------------------------------------------------------------------- Hartmut · 2024-10-18 14:34 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. ---------------------------------------------------------------------- rvk · 2024-10-18 14:39 Quote from: Hartmut on October 18, 2024, 04:34:23 pmHello 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. Don't use dlopen(). You are on Windows so use LoadLibrary(). See my code. dlopen() is a Linux function. ---------------------------------------------------------------------- Hartmut · 2024-10-18 14:46 Thanks rvk, now I begin to understand. I will use your code. Which Unit do I need for LoadLibrary() and GetProcAddress() and FreeLibrary() ? ---------------------------------------------------------------------- rvk · 2024-10-18 14:49 Here is tested code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses Windows; type  TGetScaleFactorForMonitor = function(hmonitor: HMONITOR; out scale: UINT): HRESULT; stdcall; function winShowPrimMonitorDPI: Integer;var  ShcoreLib: HMODULE;  GetScaleFactorForMonitor: TGetScaleFactorForMonitor;  Scale: UINT;begin  Result := -1;  ShcoreLib := LoadLibrary('Shcore.dll'); // Load the library  if ShcoreLib <> 0 then  begin    pointer(GetScaleFactorForMonitor) := GetProcAddress(ShcoreLib, 'GetScaleFactorForMonitor');    if Assigned(GetScaleFactorForMonitor) then      if GetScaleFactorForMonitor(Screen.PrimaryMonitor.Handle, Scale) = 0 then        Result := Scale;    FreeLibrary(ShcoreLib);  end;end; procedure TForm1.FormCreate(Sender: TObject);var  Scale: Integer;begin  Scale := winShowPrimMonitorDPI;  Showmessage(Scale.ToString);end; ---------------------------------------------------------------------- rvk · 2024-10-18 14:57 Quote from: rvk on October 18, 2024, 04:49:25 pmHere is tested code: And a console version: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program project1; {$mode objfpc}{$H+} uses Windows, multimon; type  TGetScaleFactorForMonitor = function(hmonitor: HMONITOR; out scale: UINT): HRESULT; stdcall; function winShowPrimMonitorDPI: Integer;var  ShcoreLib: HMODULE;  GetScaleFactorForMonitor: TGetScaleFactorForMonitor;  Scale: UINT;begin  Result := -1;  ShcoreLib := LoadLibrary('Shcore.dll'); // Load the library  if ShcoreLib <> 0 then  begin    pointer(GetScaleFactorForMonitor) := GetProcAddress(ShcoreLib, 'GetScaleFactorForMonitor');    if Assigned(GetScaleFactorForMonitor) then      if GetScaleFactorForMonitor(MonitorFromWindow(0, MONITOR_DEFAULTTOPRIMARY), Scale) = 0 then        Result := Scale;    FreeLibrary(ShcoreLib);  end;end; {$R *.res} begin  Writeln('Scale is ', winShowPrimMonitorDPI);  readln;end. Of course... for multiple monitors you would need to consider which monitor the window is on (also for the LCL version above). Otherwise you can run into weird things when multiple monitors have different DPI settings ---------------------------------------------------------------------- Hartmut · 2024-10-18 15:06 Thank you rvk, this compiles. I will continue to investigate and report later (maybe tomorrow). ---------------------------------------------------------------------- Seenkao · 2024-10-18 15:07 Quote from: Hartmut on October 18, 2024, 04:34:23 pmHello 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function dlopen (lpLibFileName: PAnsiChar): HMODULE; stdcall; external 'kernel32.dll' name 'LoadLibraryA';function dlclose(hLibModule: HMODULE): Boolean; stdcall; external 'kernel32.dll' name 'FreeLibrary';function dlsym  (hModule: HMODULE; lpProcName: PAnsiChar): Pointer; stdcall; external 'kernel32.dll' name 'GetProcAddress'; Quote from: rvk on October 18, 2024, 04:39:46 pmdlopen() 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. ---------------------------------------------------------------------- rvk · 2024-10-18 15:32 Quote from: Seenkao on October 18, 2024, 05:07:36 pmIn my case, these are declared functions. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function dlopen (lpLibFileName: PAnsiChar): HMODULE; stdcall; external 'kernel32.dll' name 'LoadLibraryA';function dlclose(hLibModule: HMODULE): Boolean; stdcall; external 'kernel32.dll' name 'FreeLibrary';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 · 2024-10-18 15:51 Да, вы правы. Я слишком заработался и уже подзабыл об этом.  Google translate: Yes, you are right. I was too busy working and had already forgotten about it. ---------------------------------------------------------------------- jcmontherock · 2024-10-18 16:25 You can find it in regedit at: HKCU/Control Panel/DesktopWindowMetrics ---------------------------------------------------------------------- LV · 2024-10-18 20:13 Quote from: Hartmut on October 17, 2024, 07:03:46 pmMy 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% Quote from: wp on October 18, 2024, 01:38:35 pm- "System" > "Screen" > "Scaling": 100% (96ppi), 125% (120ppi)   =>    120ppi ---------------------------------------------------------------------- rvk · 2024-10-18 20:24 Quote from: LV on October 18, 2024, 10:13:09 pm1920 - 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 · 2024-10-18 20:31 given Quote from: Hartmut on October 17, 2024, 07:03:46 pmMy sister has a laptop with real 1920x1080 pixels. to find ... ---------------------------------------------------------------------- rvk · 2024-10-18 20:36 Quote from: LV on October 18, 2024, 10:31:08 pmgiven Quote from: Hartmut on October 17, 2024, 07:03:46 pmMy sister has a laptop with real 1920x1080 pixels. to find ... Note the red part in this quote Quote from: Hartmut on October 17, 2024, 07:03:46 pmMy 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i writeln(Screen.Width, 'x', Screen.Height);So how are you going to get that 1920 in code?? ---------------------------------------------------------------------- LV · 2024-10-18 20:40 Quote from: Hartmut on October 17, 2024, 07:03:46 pmI want to detect, that this laptop runs with 120 dpi. ---------------------------------------------------------------------- rvk · 2024-10-18 20:45 Quote from: LV on October 18, 2024, 10:40:36 pmQuote from: Hartmut on October 17, 2024, 07:03:46 pmI 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). ---------------------------------------------------------------------- LV · 2024-10-18 20:54 Quote from: rvk on October 18, 2024, 10:45:16 pmSo, how would you do that Occam's razor "Entities must not be multiplied beyond necessity" ---------------------------------------------------------------------- Hartmut · 2024-10-19 14:08 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). Quote from: wp on October 18, 2024, 01:38:35 pmQuote from: Hartmut on October 17, 2024, 07:03:46 pmBut 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 · 2024-10-20 09:15 Quote from: Hartmut on October 18, 2024, 04:46:08 pmThanks 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 · 2024-10-20 09:42 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 · 2024-10-20 15:58 Quote from: Hartmut on October 20, 2024, 11:42:26 amThanks 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Function LoadLibrary(const Name : UnicodeString) : TLibHandle;begin  Result:=System.LoadLibrary(Name);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 ---------------------------------------------------------------------- Hartmut · 2024-10-21 09:09 Thanks rvk for this new informations and the link. Quote from: jcmontherock on October 18, 2024, 06:25:12 pmYou can find it in regedit at: HKCU/Control Panel/DesktopWindowMetrics Thanks jcmontherock too. Meanwhile I checked this on my sisters Win10 laptop (which has an increased Font size): Registry-Key "HKCU/Control Panel/Desktop/WindowMetrics" has value AppliedDPI=120. On my Win10 computer (which has a normal Font size) value AppliedDPI=96. So the registry is an alternative to query this setting: 120/96 = 125% ---------------------------------------------------------------------- LV · 2024-10-21 09:18 Quote from: Hartmut on October 17, 2024, 07:03:46 pmImportant: the code to detect the 120 dpi must run in a program with setting Project Options / Application / "Use LCL scaling (Hi-DPI)" and "DPI awareness" both = off. Please, See the attached project and screenshots. Updated: I have a monitor with a resolution of 2560 x 1440 ---------------------------------------------------------------------- PascalDragon · 2024-10-22 19:52 Quote from: Hartmut on October 20, 2024, 11:42:26 amThanks PascalDragon for that info. Until now I use Unit 'system' for these 3 functions. Is Unit DynLibs anyhow better than Unit 'system' for this? The LoadLibrary, FreeLibrary and GetProcAddress declarations are provided by the System-unit (at least in current versions), however depending on the platform the implementation is provided by the DynLibs unit, because e.g. on Linux this requires linking against the C-library and by default FPC's RTL avoids that. If you include the DynLibs unit then you'll simply make sure that your program is more cross platform compatible.