WildByDesign Posted August 4 Posted August 4 (edited) Per-Monitor v2 DPI Awareness Scaling Test: Have this GUI running and test by changing your DPI scaling settings from: Settings app > System > Display > Scale Work in progress, but might become more interesting. Possible UDF if everything goes well. EDIT: My initial script forgot to set the initial DPI scaled values. 🤦♂️ expandcollapse popup#include <GuiEdit.au3> #include <FontConstants.au3> #include <WindowsNotifsConstants.au3> #include <WinAPISysWin.au3> #include <WinAPIGdi.au3> #include <GUIConstantsEx.au3> #include <AutoItConstants.au3> #include <StructureConstants.au3> ; Apply PER_MONITOR_AWARE_V2 DPI Awareness DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext", "int_ptr", -4) Global $g_iScale = _WinAPI_GetDPIForWindow(WinGetHandle(AutoItWinGetTitle())) / 96 If @error Then $g_iScale = 1 Global $g_hCtrlFont = 0 Global Const $fDefFontSize = 8.5, $fDefPixel = $fDefFontSize * 96 / 72 Global Const $WM_DPICHANGED = 0x02E0 Global Const $WM_GETDPISCALEDSIZE = 0x02E4 Global Const $WM_DPICHANGED_BEFOREPARENT = 0x02E2 Global Const $WM_DPICHANGED_AFTERPARENT = 0x02E3 OnAutoItExitRegister("_Cleanup") Example() Func Example() Local $iCtrlSpaceV = 15 Local $sAppName = "Testing PerMonitorV2 DPI" Local $hGUI = GUICreate($sAppName, 440, 340, -1, -1) Local $idTestName = GUICtrlCreateLabel("Test Name:", 15, 20, -1, -1) Local $aPos = ControlGetPos($hGUI, "", $idTestName) Local $iPrev = $aPos[1] + $aPos[3] + $iCtrlSpaceV Local $idTestInput = GUICtrlCreateInput("Test Input", 15, $iPrev, 300, 22 * $g_iScale) Local $aPos = ControlGetPos($hGUI, "", $idTestInput) Local $iPrev = $aPos[1] + $aPos[3] + $iCtrlSpaceV Local $idCheckbox1 = GUICtrlCreateCheckbox("Test Checkbox1 ", 15, $iPrev) Local $aPos = ControlGetPos($hGUI, "", $idCheckbox1) Local $iPrev = $aPos[1] + $aPos[3] + $iCtrlSpaceV Local $idCheckbox2 = GUICtrlCreateCheckbox("Test Checkbox2 ", 15, $iPrev) Local $aPos = ControlGetPos($hGUI, "", $idCheckbox2) Local $iPrev = $aPos[1] + $aPos[3] + $iCtrlSpaceV _GUICtrlEdit_Create($hGUI, "This is a test" & @CRLF & "Another Line", 15, $iPrev, 394, 64 * $g_iScale) GUISetState(@SW_SHOW, $hGUI) GUIRegisterMsg($WM_DPICHANGED, _WM_DPICHANGED) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>Example Func _WM_DPICHANGED($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Local Static $iInitDPI = $g_iScale Local Static $iPrevDPI = $g_iScale ; Obtain new DPI values Local $iDPI = _WinAPI_LoWord($wParam) Local $iNewDPI = _WinAPI_LoWord($wParam) / 96 Local $hFont = $g_hCtrlFont ; Create new scaled font $g_hCtrlFont = _WinAPI_CreateFont(-Round($fDefPixel * $iNewDPI), 0, 0, 0, $FW_NORMAL, False, False, False, _ $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, "Segoe UI") ; Lock window drawing for smoother transition _WinAPI_LockWindowUpdate($hWnd) ; Enumerate child windows for sizing adjustments Local $aCtrls = _WinAPI_EnumChildWindows($hWnd, False) Local $hCtrl, $sClass, $aPos, $tPoint, $iX, $iY, $iW, $iH, $iOrigDPI If IsArray($aCtrls) Then For $i = 1 To $aCtrls[0][0] $hCtrl = $aCtrls[$i][0] $sClass = $aCtrls[$i][1] $aPos = WinGetPos($hCtrl) $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $aPos[0]) DllStructSetData($tPoint, "Y", $aPos[1]) ; Convert screen coordinates to client _WinAPI_ScreenToClient($hWnd, $tPoint) $iX = DllStructGetData($tPoint, "X") $iY = DllStructGetData($tPoint, "Y") $iW = _WinAPI_GetWindowWidth($hCtrl) $iH = _WinAPI_GetWindowHeight($hCtrl) ; Divide value by previous DPI factor to get original size, then multiply by new DPI factor (rounded to nearest .5) $iX = Round((($iX / $iPrevDPI) * $iNewDPI) / 0.5) * 0.5 $iY = Round((($iY / $iPrevDPI) * $iNewDPI) / 0.5) * 0.5 $iW = Round((($iW / $iPrevDPI) * $iNewDPI) / 0.5) * 0.5 $iH = Round((($iH / $iPrevDPI) * $iNewDPI) / 0.5) * 0.5 ; Set new position/sizes for control Local $iCtrlID = _WinAPI_GetDlgCtrlID($hCtrl) If $iCtrlID < 10000 Then GUICtrlSetResizing($iCtrlID, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT) GUICtrlSetPos($iCtrlID, $iX, $iY, $iW, $iH) ; working for GUICtrlCreate* controls only ElseIf $iCtrlID >= 10000 Then ControlMove($hWnd, "", $iCtrlID, $iX, $iY, $iW, $iH) ; working for UDF-created controls only ElseIf Not $iCtrlID Then ; probably custom SysLink or something which has no CtrlID ; can't move without CtrlID ; only need to modify X here EndIf ; Set new scaled font to each control _SendMessage($hCtrl, $WM_SETFONT, $g_hCtrlFont, True) Next EndIf ; Resize GUI window Local $tRECT = DllStructCreate($tagRECT, $lParam) Local $iX = $tRECT.left, $iY = $tRECT.top, $iW = $tRECT.right - $iX, $iH = $tRECT.bottom - $iY _WinAPI_SetWindowPos($hWnd, 0, $iX, $iY, $iW, $iH, BitOR($SWP_NOZORDER, $SWP_NOACTIVATE)) ; ; IMPORTANT: Desperately need a GUICtrlGetResizing() function to restore original control resizing behavior ; ; Update previous DPI with the now current DPI $iPrevDPI = $iNewDPI _WinAPI_LockWindowUpdate(0) ; Delete previous font If $hFont Then _WinAPI_DeleteObject($hFont) Return 0 EndFunc ;==>_WM_DPICHANGED Func _Cleanup() _WinAPI_DeleteObject($g_hCtrlFont) EndFunc Func _WinAPI_GetDPIForWindow($hWnd) ; UEZ Local $aResult = DllCall('user32.dll', "uint", "GetDpiForWindow", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDPIForWindow Edited August 4 by WildByDesign
argumentum Posted August 4 Posted August 4 27 minutes ago, WildByDesign said: Work in progress, Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting
fanxing Posted August 4 Posted August 4 It is rather cumbersome to have to wrap and then compute each control individually. At the very least, I have not been able to think of a better approach—for instance, one that would allow the interface to become fully adaptive simply by adding a function or a parameter. expandcollapse popup#include <GuiEdit.au3> #include <FontConstants.au3> #include <WindowsNotifsConstants.au3> #include <WinAPISysWin.au3> #include <WinAPIGdi.au3> #include <GUIConstantsEx.au3> #include <AutoItConstants.au3> #include <StructureConstants.au3> ; Apply PER_MONITOR_AWARE_V2 DPI Awareness DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext", "int_ptr", -4) Global $g_iScale = 1 Global $g_hCtrlFont = 0 Global Const $fDefFontSize = 8.5, $fDefPixel = $fDefFontSize * 96 / 72 Global Const $WM_DPICHANGED = 0x02E0 Global Const $WM_GETDPISCALEDSIZE = 0x02E4 Global Const $WM_DPICHANGED_BEFOREPARENT = 0x02E2 Global Const $WM_DPICHANGED_AFTERPARENT = 0x02E3 Global $g_aCtrlDesign[1][5] = [[0]] Global $g_iDesignClientW = 440, $g_iDesignClientH = 340 Global $g_iFrameW = 0, $g_iFrameH = 0 OnAutoItExitRegister("_Cleanup") Example() Func Example() Local $sAppName = "Testing PerMonitorV2 DPI" Local $hGUI = GUICreate($sAppName, $g_iDesignClientW, $g_iDesignClientH) _DPICtrlCreateLabel("Test Name:", 15, 20) _DPICtrlCreateInput("Test Input", 15, 50, 300, 24) _DPICtrlCreateCheckbox("Test Checkbox1 ", 15, 85) _DPICtrlCreateCheckbox("Test Checkbox2 ", 15, 110) _DPICtrlEditCreate($hGUI, "This is a test" & @CRLF & "Another Line", 15, 140, 394, 80) $g_iScale = _WinAPI_GetDPIForWindow($hGUI) / 96 If @error Then $g_iScale = 1 Local $aWin = WinGetPos($hGUI) Local $aClient = WinGetClientSize($hGUI) $g_iFrameW = $aWin[2] - $aClient[0] $g_iFrameH = $aWin[3] - $aClient[1] _ApplyDPI($hGUI, $g_iScale * 96) GUISetState(@SW_SHOW, $hGUI) GUIRegisterMsg($WM_DPICHANGED, _WM_DPICHANGED) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>Example ; ------------------------------------------------------------------------------ ; Wrapper functions – auto‑register each control with its design size ; ------------------------------------------------------------------------------ Func _DPICtrlCreateLabel($sText, $iX, $iY, $iW = -1, $iH = -1, $iStyle = -1, $iExStyle = -1) Local $id = GUICtrlCreateLabel($sText, $iX, $iY, $iW, $iH, $iStyle, $iExStyle) Local $hCtrl = GUICtrlGetHandle($id) Local $iRealW = $iW, $iRealH = $iH If $iW = -1 Or $iH = -1 Then Local $aRect = _WinAPI_GetWindowRect($hCtrl) If Not @error And IsArray($aRect) Then If $iW = -1 Then $iRealW = $aRect[2] - $aRect[0] If $iH = -1 Then $iRealH = $aRect[3] - $aRect[1] Else If $iW = -1 Then $iRealW = 100 If $iH = -1 Then $iRealH = 20 EndIf EndIf _AddDesignCtrl($hCtrl, $iX, $iY, $iRealW, $iRealH) Return $id EndFunc Func _DPICtrlCreateInput($sText, $iX, $iY, $iW, $iH, $iStyle = -1, $iExStyle = -1) Local $id = GUICtrlCreateInput($sText, $iX, $iY, $iW, $iH, $iStyle, $iExStyle) _AddDesignCtrl(GUICtrlGetHandle($id), $iX, $iY, $iW, $iH) Return $id EndFunc Func _DPICtrlCreateCheckbox($sText, $iX, $iY, $iW = -1, $iH = -1, $iStyle = -1) Local $id = GUICtrlCreateCheckbox($sText, $iX, $iY, $iW, $iH, $iStyle) Local $hCtrl = GUICtrlGetHandle($id) Local $iRealW = $iW, $iRealH = $iH If $iW = -1 Or $iH = -1 Then Local $aRect = _WinAPI_GetWindowRect($hCtrl) If Not @error And IsArray($aRect) Then If $iW = -1 Then $iRealW = $aRect[2] - $aRect[0] If $iH = -1 Then $iRealH = $aRect[3] - $aRect[1] Else If $iW = -1 Then $iRealW = 120 If $iH = -1 Then $iRealH = 20 EndIf EndIf _AddDesignCtrl($hCtrl, $iX, $iY, $iRealW, $iRealH) Return $id EndFunc Func _DPICtrlEditCreate($hGUI, $sText, $iX, $iY, $iW, $iH, $iStyle = -1, $iExStyle = -1) Local $hEdit = _GUICtrlEdit_Create($hGUI, $sText, $iX, $iY, $iW, $iH, $iStyle, $iExStyle) _AddDesignCtrl($hEdit, $iX, $iY, $iW, $iH) Return $hEdit EndFunc ; Store control’s design dimensions (96 DPI) Func _AddDesignCtrl($hCtrlOrID, $iX, $iY, $iW, $iH) Local $hCtrl = GUICtrlGetHandle($hCtrlOrID) If $hCtrl = 0 Then $hCtrl = $hCtrlOrID Local $iCount = UBound($g_aCtrlDesign, 1) ReDim $g_aCtrlDesign[$iCount + 1][5] $g_aCtrlDesign[$iCount][0] = $hCtrl $g_aCtrlDesign[$iCount][1] = $iX $g_aCtrlDesign[$iCount][2] = $iY $g_aCtrlDesign[$iCount][3] = $iW $g_aCtrlDesign[$iCount][4] = $iH $g_aCtrlDesign[0][0] = $iCount EndFunc ; ------------------------------------------------------------------------------ ; DPI change handler – keeps your original variable naming and logic flow ; ------------------------------------------------------------------------------ Func _WM_DPICHANGED($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Local Static $iInitDPI = $g_iScale Local Static $iPrevDPI = $g_iScale ; Obtain new DPI value (raw) Local $iDPI = _WinAPI_LoWord($wParam) Local $iNewDPI = $iDPI / 96 _ApplyDPI($hWnd, $iDPI, DllStructCreate($tagRECT, $lParam)) Return 0 EndFunc ;==>_WM_DPICHANGED ; ------------------------------------------------------------------------------ ; Core scaling function ; ------------------------------------------------------------------------------ Func _ApplyDPI($hWnd, $iDPI, $tRect = 0) Local $iNewDPI = $iDPI / 96 If $iNewDPI == $g_iScale And $g_hCtrlFont Then Return Local $hFont = $g_hCtrlFont $g_hCtrlFont = _WinAPI_CreateFont(-Round($fDefPixel * $iNewDPI), 0, 0, 0, $FW_NORMAL, False, False, False, _ $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $PROOF_QUALITY, $DEFAULT_PITCH, "Segoe UI") _WinAPI_LockWindowUpdate($hWnd) ; Adjust window size If IsDllStruct($tRect) Then ; Use suggested rectangle from the system Local $iX = DllStructGetData($tRect, "Left") Local $iY = DllStructGetData($tRect, "Top") Local $iW = DllStructGetData($tRect, "Right") - $iX Local $iH = DllStructGetData($tRect, "Bottom") - $iY _WinAPI_SetWindowPos($hWnd, 0, $iX, $iY, $iW, $iH, $SWP_NOZORDER) ; Recalculate frame difference after system resize Local $aNewWin = WinGetPos($hWnd) Local $aNewClient = WinGetClientSize($hWnd) $g_iFrameW = $aNewWin[2] - $aNewClient[0] $g_iFrameH = $aNewWin[3] - $aNewClient[1] Else ; First‑time scaling: compute new client area and center the window Local $iNewClientW = Round($g_iDesignClientW * $iNewDPI) Local $iNewClientH = Round($g_iDesignClientH * $iNewDPI) Local $iNewWinW = $iNewClientW + $g_iFrameW Local $iNewWinH = $iNewClientH + $g_iFrameH WinMove($hWnd, "", Default, Default, $iNewWinW, $iNewWinH) _CenterWindow($hWnd) EndIf ; Enumerate child controls from the design array and apply new positions/sizes Local $aCtrls = $g_aCtrlDesign For $i = 1 To $aCtrls[0][0] Local $hCtrl = $aCtrls[$i][0] Local $sClass = "" ; not used but kept for compatibility with original structure If Not IsHWnd($hCtrl) Then ContinueLoop ; Calculate new coordinates and dimensions directly from design sizes Local $iX = Round($aCtrls[$i][1] * $iNewDPI) Local $iY = Round($aCtrls[$i][2] * $iNewDPI) Local $iW = Round($aCtrls[$i][3] * $iNewDPI) Local $iH = Round($aCtrls[$i][4] * $iNewDPI) ; Move control using its handle _WinAPI_SetWindowPos($hCtrl, 0, $iX, $iY, $iW, $iH, $SWP_NOZORDER) ; Set the new scaled font _SendMessage($hCtrl, $WM_SETFONT, $g_hCtrlFont, True) Next ; Update previous DPI factor $g_iScale = $iNewDPI _WinAPI_LockWindowUpdate(0) ; Delete previous font If $hFont Then _WinAPI_DeleteObject($hFont) EndFunc ;==>_ApplyDPI Func _CenterWindow($hWnd) Local $aWin = WinGetPos($hWnd) If Not IsArray($aWin) Then Return Local $iW = $aWin[2], $iH = $aWin[3] Local $aWork = _GetWorkArea() Local $iX = ($aWork[2] - $aWork[0] - $iW) / 2 + $aWork[0] Local $iY = ($aWork[3] - $aWork[1] - $iH) / 2 + $aWork[1] WinMove($hWnd, "", $iX, $iY) EndFunc Func _GetWorkArea() Local $tRect = DllStructCreate($tagRECT) DllCall("user32.dll", "bool", "SystemParametersInfoW", "uint", 0x0030, "uint", 0, "struct*", $tRect, "uint", 0) Local $aRect[4] = [DllStructGetData($tRect, "Left"), DllStructGetData($tRect, "Top"), _ DllStructGetData($tRect, "Right"), DllStructGetData($tRect, "Bottom")] Return $aRect EndFunc Func _Cleanup() _WinAPI_DeleteObject($g_hCtrlFont) EndFunc Func _WinAPI_GetDPIForWindow($hWnd) ; UEZ Local $aResult = DllCall('user32.dll', "uint", "GetDpiForWindow", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_GetDPIForWindow TheDcoder and WildByDesign 1 1
WildByDesign Posted August 4 Posted August 4 (edited) 24 minutes ago, fanxing said: It is rather cumbersome to have to wrap and then compute each control individually. At the very least, I have not been able to think of a better approach—for instance, one that would allow the interface to become fully adaptive simply by adding a function or a parameter. This is fantastic. Your modified example worked wonderfully. Excellent work! I updated my initial example now because when I posted it last night, I had completely forgotten to scale the initial control sizes by the DPI factor which is why it got off to a bad start especially on 200% or higher. EDIT: By the way, the more that I read your updated code example, the more brilliant that I realize it is. I've got a lot to learn and your updated example will absolutely help me learn more. So I am very thankful. Edited August 4 by WildByDesign
WildByDesign Posted Sunday at 02:22 PM Posted Sunday at 02:22 PM (edited) For Per-Monitor v2 DPI awareness (needed in PMv2 UDF and GUIDarkTheme UDF), I needed a way to accurately obtain the LOGFONT and create font handle with the exact menubar font that is being used on a system level. And on top of that, I needed the scaled LOGFONT especially so that I could update the menubar font anytime WM_DPICHANGED is handled. WM_DPICHANGED gets the new DPI value and, at least in my usage, would then send that DPI as a parameter to the following new function: Func _GetSystemMenuFont($iDPI = 96) Local $tNCM = DllStructCreate("uint cbSize;int iBorderWidth;int iScrollWidth;int iScrollHeight;" & _ "int iCaptionWidth;int iCaptionHeight;byte lfCaptionFont[92];" & _ "int iSmCaptionWidth;int iSmCaptionHeight;byte lfSmCaptionFont[92];" & _ "int iMenuWidth;int iMenuHeight;byte lfMenuFont[92];" & _ "byte lfStatusFont[92];byte lfMessageFont[92];int iPaddedBorderWidth") DllStructSetData($tNCM, "cbSize", DllStructGetSize($tNCM)) Local $aResult = DllCall("user32.dll", "bool", "SystemParametersInfoForDpi", _ "uint", $SPI_GETNONCLIENTMETRICS, _ "uint", DllStructGetSize($tNCM), _ "ptr", DllStructGetPtr($tNCM), _ "uint", 0, _ "uint", $iDPI) ; Obtain LOGFONT structure for system menu font Local $tLogFont = DllStructCreate("long lfHeight;long lfWidth;long lfEscapement;long lfOrientation;" & _ "long lfWeight;byte lfItalic;byte lfUnderline;byte lfStrikeOut;byte lfCharSet;" & _ "byte lfOutPrecision;byte lfClipPrecision;byte lfQuality;byte lfPitchAndFamily;" & _ "wchar lfFaceName[32]", DllStructGetPtr($tNCM, "lfMenuFont")) ; Obtain font handle for system menu font Local $hMenuFont = _WinAPI_CreateFontIndirect($tLogFont) Return $hMenuFont EndFunc ;==>_GetSystemMenuFont It works perfectly. And as usual, you still need to manage deleting font resources and such. So I create an updated font on DPI change and delete the previous font. Edited Sunday at 02:22 PM by WildByDesign
WildByDesign Posted 2 hours ago Posted 2 hours ago (edited) Add font icons (Segoe Fluent Icons, Segoe MDL2 Assets, etc.) directly to ImageLists. You can specify font name, unicode hex, size and color and add to any ImageList for use in ListViews, TreeViews, Toolbars, tab controls and much more. This is a similar concept to my previous _CreateToolbarIconFromFont() function. However, this adds color and also adds directly to ImageList. Oh... and it is significantly sharper and smoother overall. 🤩 expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiListView.au3> #include <GDIPlus.au3> #include <WinAPITHeme.au3> DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext", "int_ptr", -2) Local $hGUI = GUICreate("Add Font Icons To ImageList", 600, 400) GUISetBkColor(0x000000) Local $iSize = 64 Local $hImageList = _GUIImageList_Create($iSize, $iSize, 5, 3) ; Add icons to the ImageList _AddFontIconToImageList($hImageList, "Segoe Fluent Icons", 0xE713, $iSize, 0xFF0078D4) ; Settings _AddFontIconToImageList($hImageList, "Segoe Fluent Icons", 0xE80F, $iSize, 0xFF107C10) ; Home _AddFontIconToImageList($hImageList, "Segoe Fluent Icons", 0xE74E, $iSize, 0xFFD83B01) ; Save Local $idListView = GUICtrlCreateListView("Icon Name |Description", 20, 20, 560, 360, BitOR($GUI_SS_DEFAULT_LISTVIEW, $LVS_NOCOLUMNHEADER)) GUICtrlSetBkColor(-1, 0x202020) GUICtrlSetColor(-1, 0xFFFFFF) _GUICtrlListView_SetImageList($idListView, $hImageList, 1) ; 1 = Small icon list Local $idItem1 = GUICtrlCreateListViewItem("Settings|Modify application settings", $idListView) Local $idItem2 = GUICtrlCreateListViewItem("Home|Return to main menu", $idListView) Local $idItem3 = GUICtrlCreateListViewItem("Save|Save current project changes", $idListView) _GUICtrlListView_SetItemImage(GUICtrlGetHandle($idListView), 0, 0) _GUICtrlListView_SetItemImage(GUICtrlGetHandle($idListView), 1, 1) _GUICtrlListView_SetItemImage(GUICtrlGetHandle($idListView), 2, 2) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Clean up resources _GUIImageList_Destroy($hImageList) GUIDelete($hGUI) Func _AddFontIconToImageList($hImageList, $sFontName, $iUnicodeDecimalOrHex, $iSize = 32, $iARGBColor = 0xFF000000) _GDIPlus_Startup() ; Render at 2x resolution for supersampling sharpness Local $iRenderSize = $iSize * 2 Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iRenderSize, $iRenderSize) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Use high quality rendering and ClearType hint _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2) _GDIPlus_GraphicsSetInterpolationMode($hGraphics, $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC) _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $GDIP_TEXTRENDERINGHINTCLEARTYPEGRIDFIT) Local $hBrush = _GDIPlus_BrushCreateSolid($iARGBColor) Local $hFamily = _GDIPlus_FontFamilyCreate($sFontName) Local $hFont = _GDIPlus_FontCreate($hFamily, $iRenderSize * 0.48, 0, 3) Local $tLayout = _GDIPlus_RectFCreate(0, 0, $iRenderSize, $iRenderSize) Local $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) Local $sChar = ChrW($iUnicodeDecimalOrHex) _GDIPlus_GraphicsDrawStringEx($hGraphics, $sChar, $hFont, $tLayout, $hFormat, $hBrush) ; Create final target size bitmap and downscale smoothly Local $hFinalBitmap = _GDIPlus_BitmapCreateFromScan0($iSize, $iSize) Local $hFinalGraphics = _GDIPlus_ImageGetGraphicsContext($hFinalBitmap) _GDIPlus_GraphicsSetInterpolationMode($hFinalGraphics, $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC) _GDIPlus_GraphicsDrawImageRect($hFinalGraphics, $hBitmap, 0, 0, $iSize, $iSize) ; Convert to HBITMAP Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hFinalBitmap) _GUIImageList_Add($hImageList, $hHBITMAP, 0) ; Clean up all handles _WinAPI_DeleteObject($hHBITMAP) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hFinalGraphics) _GDIPlus_BitmapDispose($hFinalBitmap) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() Return 1 EndFunc ;==>_AddFontIconToImageList Edited 1 hour ago by WildByDesign
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