WildByDesign Posted August 21 Author Posted August 21 It took me forever, but I've figured out a formula that gives us the perfect conversion for font scaling. So far it seems to be 100% consistent and accurate. $tLOGFONT.Height = _WinAPI_MulDiv(($tLOGFONT.Height / $fPrevDPI), $iDPI, 96) I have to clean up some variable naming and such, but in this case $fPrevDPI is the scale of the previous DPI (eg. 1.25, 1.5, etc.) and $iDPI is the current DPI (96 pixels, 120 pixels, 144 pixels, etc.). This apparently takes care of the necessary rounding, whether rounding up or down, depending on whether the value is positive or negative. I am getting pixel perfect measurements right now. So I just have to clean up all of my testing math formulas, clarify some variable names and so on and should be able to get out the most accurate DPI scaling release later today. I thought that it was "game over" for this UDF, but it seems we are just getting started now. ahmet 1
WildByDesign Posted August 22 Author Posted August 22 PMv2 2026.08.22: Significant improvement in font scaling accuracy and control scaling Using _WinAPI_MulDiv() now to avoid previous rounding issues Exposing ioa747's _PM_PtToPx() as user facing function now when creating fonts for UDF created controls Example of using this function being used in Example.au3 now If Segoe UI font is used, it gets automatically upgraded to scaling friendly Segoe UI Variable now If no font is set for a control, most AutoIt controls use MS Shell Dlg font which generally maps to a Serif font Under this specific scenario, the default control font gets upgraded to Segoe UI Variable at 8.5 (only if not set) The UDF tests whether system has Segoe UI Variable installed and falls back to Segoe UI otherwise Latest download available in the first post of the topic. This is the most precise version of PMv2 yet for font scaling and control scaling. I didn't think it was possible. @ioa747 I realized how perfectly accurate your _PM_PtToPx() function is. I even took the time to measure and compare the fonts in various ways and everything was spot on perfect. So I decided to make it a user-facing function because it would be very helpful, especially for standard UDF created controls, to create fonts that match the native AutoIt controls. I am also using it now in the Example to create the font for the UDF created Edit control. ioa747 1
WildByDesign Posted August 22 Author Posted August 22 @ioa747 Can you please clarify something for me? $aData[2] = 0 ; placeholder for ...(for anything related to the current window) This is still available to be used, right? I am thinking of using SetWindowSubclass for WM_DPICHANGED for each top-level GUI window that is passed into _PM_Scale() initially. My thought is to store the subclass DLL handle there temporarily to handle WM_DPICHANGED. The reason why I am thinking of this change is so that anyone using the UDF can simply use the regular GUIRegisterMsg on WM_DPICHANGED if they need it. I do have the temporary workaround for this to use in the Example: ; This is a custom window message that allows user script to also receive message ; Allows having more than one GUIRegisterMsg _SendMessage($hWnd, $__PM_WM_DPICHANGED, $wParam, $lParam) However, it might not be best in the long term even though it works well. I'm thinking of implementing PMv2 in GUIDarkTheme UDF as well so I am in planning stages to avoid any kind of clashes between the two UDFs.
ioa747 Posted August 22 Posted August 22 28 minutes ago, WildByDesign said: This is still available to be used, right? Yes, $aData[2] is completely available for you to use! WildByDesign 1 I know that I know nothing
WildByDesign Posted August 28 Author Posted August 28 (edited) I realized that there was a problem with scaling ListBox controls. They would grow or shrink (mostly shrink) with every DPI change and eventually the control would be the size of a sliver. This was because of ListBox control default IntegralHeight behaviour in which the control size snaps down to the nearest full item so that it never leaves a partial item showing. If $LBS_NOINTEGRALHEIGHT is present, the UDF can continue on and resize the control as per normal. But if $LBS_NOINTEGRALHEIGHT is not present (default), the UDF needs to determine how many ListBox items are visible in the control and do the scaling math to keep that same number of visible items at each scaling factor. Here is what is working right now: ; Determine ListBox height of ListBox that does NOT have LBS_NOINTEGRALHEIGHT If $sClass = 'ListBox' And Not $bInitial Then ; need to determine number of visible items Local $iListHeight = _WinAPI_GetWindowHeight($hCtrl) Local $iItemHeight = _GUICtrlListBox_GetItemHeight($hCtrl) ;Local $iTargetItems = Floor(($iListHeight - 4) / $iItemHeight) Local $iTargetItems = Floor($iListHeight / $iItemHeight) ; may need -4 for borders here ; Calculate new height for ListBox only if LBS_NOINTEGRALHEIGHT is not set Local $iItemHeightNew = _WinAPI_MulDiv(($iItemHeight / $fPrevDPI), $iDPI, 96) If Not BitAND(_WinAPI_GetWindowLong($hCtrl, $GWL_STYLE), $LBS_NOINTEGRALHEIGHT) Then $iH = ($iTargetItems * $iItemHeightNew) + 4 ; borders EndIf EndIf I still have to figure out if I really need to get accurate measurement of the borders. I probably should. I could use GetSystemMetricsForDpi to get the correct border size, but I think that the metric that I need to pass to that function is different depending on the type of border. From my understanding, the math for the IntegralHeight snapping of ListBox controls only needs to be a few pixels above the iTargetItems * iItemHeightNew anyway and it snaps down. So I may not need accurate border measurement. Anyway, scaling ListBox was way more difficult then I expected. The timing of when to handle that measurement/math also made a significant difference in the outcome. I should be closer to release now. Edited August 28 by WildByDesign reworded "line" to "item" argumentum 1
WildByDesign Posted August 28 Author Posted August 28 PMv2 2026.08.28: Added new function _PM_GetMenuFont to obtain the DPI-scaled menubar font This is helpful in projects that use an owner-drawn menubar (eg. GUIDarkTheme UDF) Significant improvements in how scaling is handled for ListBox controls If ListBox has LBS_NOINTEGRALHEIGHT set, scaling occurs as per normal If LBS_NOINTEGRALHEIGHT is not set (default), the scaling always maintains the same number of items in view This is due to how IntegralHeight works in ListBox controls by always snapping down control height to nearest full item height Added a ListBox control to the Example GUI to test whether or not this new code is working correctly Added scaling for individual buttons within a ToolbarWindow32 control More work still needs to be done to handle ImageLists in toolbar buttons Improved scaling for SysIPAddress32 controls This requires destroying and re-creating SysIPAddress32 since the child Edit controls cannot be scaled More work still needs to be done to further improve SysIPAddress32 scaling Latest download available in the first post of the topic. ioa747 and argumentum 2
WildByDesign Posted Sunday at 10:51 AM Author Posted Sunday at 10:51 AM PMv2 2026.08.30: Removed the GUIRegisterMsg usage of $WM_DPICHANGED from the UDF $WM_DPICHANGED added to the existing window procedure __PM_WndProc() function This frees up $WM_DPICHANGED to be used by the user GUI script with GUIRegisterMsg if needed Updated Example to use GUIRegisterMsg with $WM_DPICHANGED to replicate user usage (if needed) Code cleanup Added many missing function headers, descriptions, etc. Latest download available in the first post of the topic.
WildByDesign Posted Sunday at 11:00 AM Author Posted Sunday at 11:00 AM I still have quite a bit of code that it commented out left in the UDF file. The reason is because some of that is work-in-progress for certain controls and features that were not quite finished or working correctly. I'm not 100% sure how to handle a few things with scaling still. ImageLists, for example. I know how to destroy them and recreate at new DPI size. But from a UDF perspective, I may not be able to know (or have access to) the source images of the users' ImageLists to be able to recreate them. This is a big part of why I wanted to free up $WM_DPICHANGED for GUIRegisterMsg because there may still be some things that the user needs or wants to do on DPI changes. There is CCM_DPISCALE which I have tested that scales ImageLists and is kind of neat. It works by stretching though which is not ideal, but it does work. The biggest problem is that you can't call it more than once. It's a one time deal which is a bit silly. Even disabling it and re-enabling it does not work. It only works once.
WildByDesign Posted Monday at 12:02 PM Author Posted Monday at 12:02 PM PMv2 2026.08.31: Added proper DPI scaling for SysMonthCal32 controls (both themed and unthemed) Added SysMonthCal32 control to Example GUI to show scaling of unthemed SysMonthCal32 control Added SysDateTimePick32 control to Example GUI to show scaling of themed SysMonthCal32 control Latest download available in the first post of the topic. argumentum and ioa747 2
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now