Jump to content

Recommended Posts

Posted
19 minutes ago, Engr said:

WildByDesign, thank you (and others) for developing this scaling UDF!

You're welcome. Welcome to the forum, by the way.

Thank you for reporting this issue. I appreciate the reproducible code as well because that saves time. I was able to reproduce the issue as well. I will dig into this issue tonight. I'll have to check for a buddy control and, if so, handle the situation differently. I'll let you know when I've got something working to fix it.

Posted

PMv2 2026.08.16:

  • Added support for scaling Edit/Input controls that have a buddy UpDown control
  • Improvements to the way that the global map is managed - thanks ioa747

 

@Engr I've added support for the Edit/Input controls that have an UpDown control. The download is on the first post.

There may be some imperfections with the scaling for Edit/Input controls with UpDown buddy control but it is generally working. I'll have another look at it tomorrow to make sure that I've got it done as best as possible.

Posted

PMv2 2026.08.16 Looks much better!  As you mentioned, I do see a bit of scaling imperfections - at least in regards to the width of the UpDown control being slightly too narrow.  Tomorrow I will add to other scripts and test ...

Posted (edited)
8 hours ago, Engr said:

at least in regards to the width of the UpDown control being slightly too narrow.

I can't really change the UpDown controls. Well, technically I can move and/or resize them. But the problem is that anytime you resize the GUI, the OS will move the UpDown controls back. That is because the OS entirely manages the size and position of the UpDown controls based on the width of the Edit control and position of the Edit control. So I just scale the Edit control and the OS handles the UpDown.

I do see a problem with the initial font scaling though. The very first time that the GUI is shown, the fonts are a bit smaller than they should be.

So this morning I've added some more logic to handle the initial font scaling much better in situations where the user hasn't changed from the default font that AutoIt uses.

For example, if a user changes the default control font like this:

GUICtrlSetFont(-1, 8.5, $FW_NORMAL, $GUI_FONTNORMAL, "Segoe UI")

The UDF already knows how to handle the scaling for that.

But if the user doesn't set a default font for any controls, the font face name either comes up blank or as "MS Shell Dlg". This is the case where the UDF was not scaling properly for. Your repro example did not have any usage of GUICtrlSetFont, which is perfectly fine by the way. I have to be able to detect and handle as many scenarios as possible because many users likely would not use GUICtrlSetFont for every control and just use default. Now I've got logic setup to detect this and scale the initial control fonts in this specific scenario and it looks so much better now.

The reason why it's so important that I detect and handle the initial font scaling (when GUI first shows) properly is because that is the baseline for every single DPI change that follows. 

I've got a few more things to test and change but I should be able to get an updated UDF out later today.

Also, thank you for your bug report, feedback and testing. All of that makes things better in the end. And having a repro script right from the start was also very helpful. I appreciate it.

Edited by WildByDesign
Posted

Getting really close ...

I the following code has been "tweaked" and all seems to work well - except ... Without PMv2 2026.08.17, font parameters seem to be that of the system upon which the script is running - which is desired.  (My system default font is: Segoe UI Semibold, 9 point)  With PMv2 2026.08.17, the font is displayed as Segoe UI, 8.5 point.  If I then add, "GUISetFont(9, $FW_NORMAL, $GUI_FONTNORMAL, "Segoe UI Semibold")" to the script, all is well.

Seems to me the fonts within AutoIt, unless explicitly changed, should follow the current system default.  Am I missing something?  Should I acquire the current default system fonts and set within my scripts?

#include <FontConstants.au3>
#include <GUIConstantsEx.au3>

#include "PMv2.au3" ;PMv2-2026.08.17
_PM_Init()

Opt("GUIOnEventMode", 1)

Global $hMainGUI = GUICreate("PMv2 Test", 450, 75)

    GUISetFont(9, $FW_NORMAL, $GUI_FONTNORMAL, "Segoe UI Semibold") ;*** My Default System Font - Commenting out with PMv2 sets to:
                                                                                                                ;   GUISetFont(8.5, $FW_NORMAL, $GUI_FONTNORMAL, "Segoe UI") ***
    GUISetOnEvent($GUI_EVENT_CLOSE, "f_Exit")

    ;CD Begin Folder Input
    GUICtrlCreateLabel("CD Begin:", 50, 10, 150, 20)
    GUICtrlCreateLabel("CD", 50, 32, 20, 20)
    Global $g_idCDBeginDir = GUICtrlCreateInput("1", 70, 30, 50, 24, 0x2000)
    GUICtrlCreateUpdown(-1, 0x21)
    GUICtrlSetLimit (-1, 16, 1)

    ;CD End Folder Input
    GUICtrlCreateLabel("CD End:", 150, 10, 150, 20)
    GUICtrlCreateLabel("CD", 150, 32, 20, 20)
    Global $g_idCDEndDir = GUICtrlCreateInput("10", 170, 30, 50, 24, 0x2000)
    GUICtrlCreateUpdown(-1, 0x21)
    GUICtrlSetLimit (-1, 16, 1)

    ;Number Of Tracks Per CD Folder Input
    GUICtrlCreateLabel("Tracks/CD:", 250, 10, 140, 20)
    Global $g_idTracksPerCD = GUICtrlCreateInput("20", 250, 30, 50, 24, 0x2000)
    GUICtrlCreateUpdown(-1, 0x21)
    GUICtrlSetLimit (-1, 99, 1)

    ;Number Of MP3s Per Track Input
    GUICtrlCreateLabel("MP3s/Track:", 340, 10, 140, 20)
    Global $g_idMP3sPerTrack = GUICtrlCreateInput("3", 340, 30, 50, 24, 0x2000)
    GUICtrlCreateUpdown(-1, 0x21)
    GUICtrlSetLimit (-1, 16, 1)

_PM_Scale($hMainGUI)
GUISetState(@SW_SHOW, $hMainGUI)

While 1
    Sleep(100)
WEnd

Func f_Exit()
    Exit
EndFunc

 

Posted (edited)
16 hours ago, Engr said:

Seems to me the fonts within AutoIt, unless explicitly changed, should follow the current system default.  Am I missing something?  Should I acquire the current default system fonts and set within my scripts?

I agree with you that AutoIt should follow system default font if you have not specifically set a font. I think the problem is that AutoIt was first created many years ago and based heavily on dialogs.

From what I can see, if we don't set a font, AutoIt uses "MS Shell Dlg" font for Labels (Static controls), Input/Edit, Buttons and more.

However, ListView and TreeView, I can see that they are created with "Segoe UI Variable Small" font. Segoe UI Variable is, from my understanding, default on Windows 11 systems. I would recommend it when it comes to high DPI scaling. I've actually been thinking about using it and have some ways to detect if it's available on a users' system to make sure.

From my understanding, you would use the Display variant for larger sizes like headings. Or Small or Text for regular GUI controls.

GUISetFont(9, $FW_NORMAL, $GUI_FONTNORMAL, "Segoe UI Variable")
GUISetFont(9, $FW_NORMAL, $GUI_FONTNORMAL, "Segoe UI Variable Text")
GUISetFont(9, $FW_NORMAL, $GUI_FONTNORMAL, "Segoe UI Variable Display")

Just as examples. It's something that I want to explore more since many more people are on Windows 11 now.

But yes, it seems that AutoIt defaults to "MS Shell Dlg" font for most controls unless we specifically set a font.

Edited by WildByDesign
Posted

@ioa747 I'm trying to do something that converts pixels into font points (opposite of your _PMA_PtToPx function) and round to the nearest 0.5, but math is not my best area.

Can you let me know if this is correct?

Func __PM_PxToPt($iPixels, $hWnd = 0)
    Local $iDpi = __PM_GetWindowDPI($hWnd)
    Local $fPoints = $iPixels * (72 / $iDpi)
    Return Round($fPoints / 0.5) * 0.5
EndFunc   ;==>__PM_PxToPt

The part that I don't understand is that the lower the pixel value, the higher the point value goes up which seems odd to me.

Posted

It seems okay.

 

#include "..\PMv2.au3" ; 'https://www.autoitscript.com/forum/topic/213823-automatic-per-monitor-v2-scaling-udf/'
#include <GUIConstants.au3>

_PM_Init()

_test()

Func _test()
    Local $hGUI = GUICreate("", 400, 300)
    _PM_Scale($hGUI)
    GUISetState(@SW_SHOW, $hGUI)

For $i = 1 To 100
    ConsoleWrite("_PxToPt(" & $i & ") ")
    ConsoleWrite("" & __PM_PxToPt($i, $hGUI) & @CRLF)
Next

EndFunc


Func __PM_PxToPt($iPixels, $hWnd = 0)
    Local $iDpi = __PM_GetWindowDPI($hWnd)
    If $iDpi <= 0 Then $iDpi = 96 ; Safety check against zero/invalid DPI ??
    Local $fPoints = $iPixels * (72 / $iDpi)
    ConsoleWrite(" -> $fPoints:" & $fPoints)
    ConsoleWrite(" -> Return:")
    Return Round($fPoints / 0.5) * 0.5
EndFunc   ;==>__PM_PxToPt

I know that I know nothing

Posted

WildByDesign, Thank you for the information on the "Segoe UI Variable" font family!  I have installed it on my Windows 10 systems and spent way too much time "tinkering" with system and program settings ...

Unfortunately, I found another issue.  Using my last code sample with PMv2-2026.08.17 enabled, if you try to directly enter, via keyboard, the desired "Tracks/CD" it only allows entry of one digit.  Valid entry should be 1 through 99.  Disabling PMv2-2026.08.17 allows correct two digit data entry.  Using the up/down entry arrows works fine in both cases.

Posted (edited)
9 hours ago, Engr said:

Unfortunately, I found another issue.  Using my last code sample with PMv2-2026.08.17 enabled, if you try to directly enter, via keyboard, the desired "Tracks/CD" it only allows entry of one digit.  Valid entry should be 1 through 99.  Disabling PMv2-2026.08.17 allows correct two digit data entry.  Using the up/down entry arrows works fine in both cases.

It looks like this is unrelated to the UDF. I removed the UDF and still had that issue. It looks like you need to use GUICtrlSetLimit on both the Input control and the UpDown control differently.

;Number Of Tracks Per CD Folder Input
GUICtrlCreateLabel("Tracks/CD:", 250, 10, 140, 20)
Global $g_idTracksPerCD = GUICtrlCreateInput("0", 250, 30, 50, 24, 0x2000)
GUICtrlSetLimit(-1, 2, 1) ; for Input/Edit control, GUICtrlSetLimit sets max number of characters allowed
GUICtrlCreateUpdown(-1, 0x21)
GUICtrlSetLimit(-1, 99, 1) ; for UpDown control, GUICtrlSetLimit sets max number as actual value

Some AutoIt controls work differently for different control types. This (above) seems to work accurately for me. You will need to adapt your script to use GUICtrlSetLimit for each Input and each UpDown.

Edited by WildByDesign
Posted (edited)
15 hours ago, ioa747 said:

It seems okay.

Thanks for checking and also for providing the testing script. I appreciate that. :)

I trust your math. I don't usually trust my own math though.

However it seems that, no matter what, the conversion from LOGFONT (lfHeight) or TEXTMETRIC (tmHeight) to font points to use with GUICtrlSetFont is never going to be a perfect conversion. I've tried a bunch of different math for both and different rounding techniques as well.

For now, I stick with WM_SETFONT with the value from tmHeight from TEXTMETRIC for all controls. But I am curious about using the lfHeight from LOGFONT since we have that as well, but the fonts end up way bigger (or smaller) for some reason when I use that in testing. Some fonts continually shrink until they disappear.

EDIT: Although I should be clear that my current method is not perfect for font size scaling either. It's close and consistent, but not perfect. So it is an area that needs some fine-tuning.

Edited by WildByDesign
Posted
1 hour ago, WildByDesign said:

I trust your math


Thank you very much. :)
 (no one has ever told me that before) 


 

I know that I know nothing

Posted
1 hour ago, ahmet said:

Have you checked Map the Logical Fonts for getting the right font for MS Shell Dlg?

I had that registry key open from a few days ago but I did not know much about it. Your link is very helpful. Thank you. :)

On my machine, MS Shell Dlg maps to Microsoft Sans Serif. Although I understand that different computers can map that font to different fonts depending on language.

Do you think that I should avoid swapping MS Shell Dlg for Segoe UI Variable?

The default GUI controls look significantly better and scale better with Segoe UI Variable. But I do not know how that might affect languages other than English.

Posted

I suppose that using substitution from registry is the correct way. Can you investigate how other applications handle that?

Posted

I apologize, everyone, but it seems that this PMv2 project may be destined to fail.

So, I've spent the past 3-4 days learning more about fonts. Cell height, character height and all of the various measurements involved. I have tried many different variations of math and measurements and it seems that I am not able to ensure 100% perfect scaling for the fonts, in particular.

With each individual control, we get the TEXTMETRIC structure from _WinAPI_GetTextMetrics($hDC) and the tmHeight value generally gives us the cell height since it is provided as a positive number.

With each control, we also get the LOGFONT structure which we modify (DPI values) and feed into _WinAPI_CreateFontIndirect to create the font. $tLOGFONT.Height generally gives us the character height since it typically gives us a negative number.

I have had the best luck and most consistent behaviour when using tmHeight from the TEXTMETRIC structure (and apply DPI changes, rounding up with Ceiling):

$tLOGFONT.Height = Ceiling(($fNewDPI / $fPrevDPI) * DllStructGetData($tTEXTMETRIC, "tmHeight"))

Fonts would end up slightly larger (1-2 pixels), but each cycle through all DPI scaling settings would at least be consistent. No issue with shrinking fonts here.

Alternatively, we can do the DPI math of the Height already within the LOGFONT structure:

$tLOGFONT.Height = Floor(($fNewDPI / $fPrevDPI) * $tLOGFONT.Height)

But I have never had good results from this method, whether I use Floor, -Floor, Round, Ceiling, etc. It was never as consistent as using the TEXTMETRIC value.

Most recently, I decided to use the values without any kind of rounding. So it would have decimal values going into the LOGFONT structure that is fed into _WinAPI_CreateFontIndirect:

$tLOGFONT.Height = ($fNewDPI / $fPrevDPI) * DllStructGetData($tTEXTMETRIC, "tmHeight")

The interesting thing is that the OS handled the decimal places just fine and applied its own kind of internal rounding. The other interesting thing was that the font that I was specifically monitoring and measuring, Consolas, had 100% perfect size when cycling through all of the DPI scaling settings. It remained perfect throughout testing. The problem is that all of the other fonts shrunk. Each cycle through the DPI scaling settings caused the other fonts to get smaller each time until the fonts eventually disappeared.

What we have currently seems to work consistently, although the fonts are 1-2 pixels larger from what I can tell. And if anyone knows me from my other projects, I am not very happy being off by 1-2 pixels. So I just don't know how to move forward from here.

 

3 hours ago, ahmet said:

I suppose that using substitution from registry is the correct way. Can you investigate how other applications handle that?

From everything that I could understand, the only way to make modifications that way would require Admin and would also be a system-wide change which I don't think is a very good idea. I don't believe that there is any API available to make font mapping change without Admin.

Although maybe what I could do is make it an option. Maybe enabled by default, but make it known to anyone using the UDF that they could disable it easily.

Posted

You do not need to change font mapping.. When you get MS Shell Dlg you read a registry value of the "Ms Shell Dlg" key. You do not modify registry entry.

At this point I do not have much time to test that scaling issues that you have but I would like. This project looks interesting to me.
After you assign the value to Height member have you cahecked its value and the value of the next element in the structure?

Posted
6 hours ago, ahmet said:

You do not need to change font mapping.. When you get MS Shell Dlg you read a registry value of the "Ms Shell Dlg" key. You do not modify registry entry.

I did not quite understand what you meant at first, but I understand now. Reading the value of the registry key is certainly possible. But I don't think that we need to read the value from the registry because the OS automatically does this. It follows the font mapping key for MS Shell Dlg and loads the font that shows as the value. In my case, I can already see that it has loaded Microsoft Sans Serif font.

7 hours ago, ahmet said:

This project looks interesting to me.

Thank you. AutoIt definitely needs something like this to support PMv2 or DPI scaling in general since almost all monitors now are high DPI. Users can definitely benefit from this if we can get the font scaling perfect.

6 hours ago, ahmet said:

What about follwoing 

$tLOGFONT.Height = Ceiling(($fNewDPI / $fPrevDPI) * (DllStructGetData($tTEXTMETRIC, "tmHeight")) - $tTEXTMETRIC.tmAscent - $tTEXTMETRIC.tmDescent)

I appreciate this suggestion. However, unfortunately it made all fonts 3 pixels in size and smaller. I will try some more ideas. :)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...