Jump to content

Recommended Posts

Posted

260718-083122-504_AutoIt3_Ggm6F.png.c9e8c9ff930ecd74692acd686cb8df04.png

 

 

after WildByDesign 's  post
I went through the process of understanding Microsoft's patents and ended up with my own patents

I'm still in the process of building it, but I posted it now, to get opinions as I build it.

Font_Dialog.zip


Please, every comment is appreciated!
leave your comments and experiences here!
Thank you very much  :)

 

I know that I know nothing

Posted (edited)
...
    ; DarkMode($__g_hFontGUI, True)
    If StringInStr($CmdLineRaw, "/DarkMode") Then
        DarkMode($__g_hFontGUI, True)
        _GUIDarkTheme_ApplyDark($__g_hFontGUI)
    EndIf
...
Spoiler

..lazy, 2 min. patch

; https://www.autoitscript.com/forum/topic/213805-custom-font-dialog-box/
;----------------------------------------------------------------------------------------
; Title...........: Font_Dialog3.au3
; Description.....: Custom Font Dialog
; AutoIt Version..: 3.3.18.0   Author: ioa747           Script Version: 0.3
; Note............: Testet in Windows 11 Pro 25H2       Date:14/07/2026
;----------------------------------------------------------------------------------------
;~ #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#include-once
#include "GUIScrollbars_Ex.au3" ; "https://www.autoitscript.com/forum/topic/113723-scrollbars-made-easy-new-version-27-jan-22"
#include <StaticConstants.au3>
#include <Array.au3>
#include <GuiImageList.au3>
#include <GuiComboBoxEx.au3>
#include <ColorConstants.au3>
;~ #AutoIt3Wrapper_Run_Debug_Mode=Y

; Initialize System DPI awareness
;~ DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext", "int_ptr", -2)

#include "GuiCtrls_HiDpi.au3"
#include "GUIDarkTheme.au3"
_HiDpi_Ctrl_LazyInit()


Global $__g_hColorDefault = 0xFFFFFF, $__g_hColorHighlight = 0xC8CFFA, $__g_hColorText = 0x000000
Global $__g_aFonts, $__g_aSize, $__g_aWeight, $__g_aColor
Global $__g_iLastFontIdx = 0, $__g_iLastWeightIdx = 0, $__g_iLastSizeIdx = 0
Global $__g_idPopFont, $__g_idPopWeight, $__g_idPopSize
Global $__g_hFontGUI, $__g_hFontSubForm, $__g_hWeightSubForm, $__g_hSizeSubForm, $__g_hColorSubForm
Global $__g_idCheck_Italic, $__g_idCheck_Strikeout, $__g_idCheck_Underline
Global $__g_idScriptCombo, $__g_idFakeCombo, $__g_idFakeColor, $__g_idLabel_Sample
Global $__g_sFontDlgData

$__g_aFonts = _GetFonts() ; Make Fonts array

_Example1()


Func _Example1()

;~ $CmdLineRaw &= " /DarkMode" ; Switch to DarkMode

    Local $aResult = _Custom_Font_Gui("arial", 12, 0x943E00, 400, False, False, True)

    If IsArray($aResult) Then
;~     _ArrayDisplay($aResult, "Returned Font Data")

        ConsoleWrite("--- Result Data ---" & @CRLF)
        ConsoleWrite("Total Elements: " & $aResult[0] & @CRLF)
        ConsoleWrite("Attributes:     " & $aResult[1] & @CRLF)
        ConsoleWrite("Font Name:      " & $aResult[2] & @CRLF)
        ConsoleWrite("Size:           " & $aResult[3] & @CRLF)
        ConsoleWrite("Weight:         " & $aResult[4] & @CRLF)
        ConsoleWrite("Color RGB:      0x" & Hex($aResult[5], 6) & @CRLF)
        ConsoleWrite("" & @CRLF)

    Else
        ConsoleWrite("Error: $aResult is NOT an array! (Value: " & $aResult & ")" & @CRLF)
    EndIf

EndFunc   ;==>_Example1

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Function:    _Custom_Font_Gui
; Description: Creates and manages the custom Font Selection dialog.
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _Custom_Font_Gui($sFontName = "Segoe Script", $iPointSize = 10, $iFontColorRef = Default, $iFontWeight = 0, $bItalic = False, $bUnderline = False, $bStrikethru = False, $hWndOwner = 0)
    $__g_hFontGUI = _HiDpi_GUICreate("Font Selection", 445, 455, -1, -1, -1, -1, $hWndOwner)

    _HiDpi_GUICtrlCreateLabel("&Font:", 10, 7, 195, 23)
    $__g_idPopFont = _HiDpi_GUICtrlCreateInput("CurrentFont", 10, 25, 197, 23, -1)
    GUICtrlSetFont(-1, 11)

    _HiDpi_GUICtrlCreateLabel("Font &Weight:", 220, 7, 150, 23)
    $__g_idPopWeight = _HiDpi_GUICtrlCreateInput("CurrentWeight", 220, 25, 152, 23)
    GUICtrlSetFont(-1, 11)

    _HiDpi_GUICtrlCreateLabel("&Size:", 385, 7, 45, 23)
    $__g_idPopSize = _HiDpi_GUICtrlCreateInput("CurrentSize", 385, 25, 47, 23)
    GUICtrlSetFont(-1, 11)

    _HiDpi_GUICtrlCreateGroup("Effects", 10, 268, 110, 85)
    $__g_idCheck_Italic = _HiDpi_GUICtrlCreateCheckbox("&Italic", 20, 289, 77, 16)
    $__g_idCheck_Strikeout = _HiDpi_GUICtrlCreateCheckbox("Stri&keout", 20, 310, 77, 16)
    $__g_idCheck_Underline = _HiDpi_GUICtrlCreateCheckbox("&Underline", 20, 331, 77, 16)
    _HiDpi_GUICtrlCreateGroup("", -99, -99, 1, 1) ; Close previous groupbox

    _HiDpi_GUICtrlCreateLabel("Scrip&t:", 10, 360, 45, 15)
    $__g_idScriptCombo = _HiDpi_GUICtrlCreateCombo("", 10, 375, 112, 25)
    GUICtrlSetFont(-1, 10)

    _HiDpi_GUICtrlCreateLabel("&Color:", 10, 405, 45, 15)
    $iFontColorRef = ($iFontColorRef = Default ? 0x000000 : $iFontColorRef)

    ; Fake Color ComboBox
    $__g_idFakeCombo = _HiDpi_GUICtrlCreateLabel(@TAB & ($iFontColorRef == 0x000000 ? "BLACK" : "0x" & Hex($iFontColorRef, 6)), 10, 420, 197, 20, BitOR($SS_LEFT, $SS_CENTERIMAGE, $WS_BORDER))
    GUICtrlSetCursor(-1, 0)

    _HiDpi_GUICtrlCreateLabel(ChrW(59149), 189, 422, 16, 16, BitOR($SS_CENTER, $SS_CENTERIMAGE)) ; "▼"
    GUICtrlSetFont(-1, 11, Default, Default, "Segoe Fluent Icons")


    $__g_idFakeColor = _HiDpi_GUICtrlCreateLabel(($iFontColorRef == 0x000000 ? "0x000000" : "0x" & Hex($iFontColorRef, 6)), 12, 422, 30, 16, BitOR($SS_LEFT, $SS_CENTERIMAGE))
    GUICtrlSetColor(-1, $iFontColorRef) ; BLACK
    GUICtrlSetBkColor(-1, $iFontColorRef) ; BLACK
    ; GUICtrlSetState(-1, $GUI_DISABLE)


    _HiDpi_GUICtrlCreateGroup("Sample", 135, 268, 298, 127)
    $__g_idLabel_Sample = _HiDpi_GUICtrlCreateLabel("The quick brown fox jumps over the lazy dog", 147, 285, 274, 102)
    _HiDpi_GUICtrlCreateGroup("", -99, -99, 1, 1) ; Close previous groupbox

    Local $idButton_OK = _HiDpi_GUICtrlCreateButton("OK", 242, 410, 90, 33)
    Local $idButton_Cancel = _HiDpi_GUICtrlCreateButton("Cancel", 342, 410, 90, 33)

    Local $id_UP = GUICtrlCreateDummy()
    Local $id_DOWN = GUICtrlCreateDummy()

    Local $aAccelKeys[2][2] = [["{UP}", $id_UP], ["{DOWN}", $id_DOWN]]
    GUISetAccelerators($aAccelKeys)

    ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ; Initialize SubForms
    ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $__g_hFontSubForm = _Make_FontSubForm($__g_hFontGUI, 10, 50, 195, 194)
    $__g_hSizeSubForm = _Make_SizeSubForm($__g_hFontGUI, 385, 50, 45, 194)
    $__g_hColorSubForm = _Make_ColorSubForm($__g_hFontGUI, 10, 10, 195, 22 * 20)
    $__g_hWeightSubForm = _Make_WeightSubForm($__g_hFontGUI, 220, 50, 150, 194) ; <- keep it last


    ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ; Apply initial states to Attribute Checkboxes
    ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If $bItalic Then GUICtrlSetState($__g_idCheck_Italic, $GUI_CHECKED)
    If $bUnderline Then GUICtrlSetState($__g_idCheck_Underline, $GUI_CHECKED)
    If $bStrikethru Then GUICtrlSetState($__g_idCheck_Strikeout, $GUI_CHECKED)

    ; Find and Highlight the matching Font
    Local $iSelectedFontIdx = _BestMatchArraySearch($__g_aFonts, $sFontName, 1, 1)
    If @error Or $iSelectedFontIdx < 1 Then $iSelectedFontIdx = 1
    _SelectedFont($iSelectedFontIdx, True)

    ; Find and Highlight the matching Font Weight
    Local $iSelectedWeightIdx = 1
    For $i = 1 To $__g_aWeight[0][0]
        If $__g_aWeight[$i][2] = $iFontWeight Then
            $iSelectedWeightIdx = $i
            ExitLoop
        EndIf
    Next
    _SelectedWeight($iSelectedWeightIdx, True)

    ; Find and Highlight the matching Font Size in our Size SubForm
    Local $iSelectedSizeIdx = 1
    For $i = 1 To $__g_aSize[0][0]
        If $__g_aSize[$i][1] = $iPointSize Then
            $iSelectedSizeIdx = $i
            ExitLoop
        EndIf
    Next
    _SelectedSize($iSelectedSizeIdx, 1)

    GUISetState(@SW_SHOW, $__g_hFontGUI)

    ; DarkMode($__g_hFontGUI, True)
    If StringInStr($CmdLineRaw, "/DarkMode") Then
        DarkMode($__g_hFontGUI, True)
        _GUIDarkTheme_ApplyDark($__g_hFontGUI)
    EndIf


    ; set focus to PopFont as start point
    GUICtrlSetState($__g_idPopFont, $GUI_FOCUS)

    Local $aFakeComboArea[4] = [10, 420, 197, 20]
    Local $iMsg, $iActiveCtrl, $iIndex

    While 1
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case $GUI_EVENT_CLOSE, $idButton_Cancel
                ExitLoop

            Case $id_UP, $id_DOWN
                Local $iVal = ($iMsg = $id_DOWN ? +1 : -1)
                $iActiveCtrl = _GetActiveCtrl() ;$__g_hFontGUI

                Switch $iActiveCtrl
                    Case $__g_idPopFont
                        _SelectedFont($__g_iLastFontIdx + $iVal, 1)

                    Case $__g_idPopWeight
                        _SelectedWeight($__g_iLastWeightIdx + $iVal, 1)

                    Case $__g_idPopSize
                        _SelectedSize($__g_iLastSizeIdx + $iVal, 1)

                EndSwitch

            Case $__g_idPopFont
                $iIndex = _BestMatchArraySearch($__g_aFonts, GUICtrlRead($__g_idPopFont), 1, 1)
                If Not @error Then _SelectedFont($iIndex, 1)

            Case $__g_idPopWeight
                $iIndex = _BestMatchArraySearch($__g_aWeight, GUICtrlRead($__g_idPopWeight), 1, 2)
                If Not @error Then _SelectedWeight($iIndex, 1)

            Case $__g_idPopSize
                ; Search for the selected font size in the sizes array
                $iIndex = _ArraySearch($__g_aSize, GUICtrlRead($__g_idPopSize), 0, 0, 0, 0, 1, 1)
                ConsoleWrite("$iIndex=" & $iIndex & @CRLF)

                If $iIndex > 0 Then
                    ; Size found in the list, update selection and highlight it
                    _SelectedSize($iIndex, 1)
                Else
                    ; Custom size entered: clear previous selection highlight and update preview
                    If $__g_iLastSizeIdx > 0 Then GUICtrlSetBkColor($__g_aSize[$__g_iLastSizeIdx][0], $__g_hColorDefault)
                    _UpDateSample()
                EndIf

            Case $__g_idFakeCombo
                ; Toggle the visibility state of the color dropdown
                If BitAND(WinGetState($__g_hColorSubForm), $WIN_STATE_VISIBLE) Then
                    GUISetState(@SW_HIDE, $__g_hColorSubForm)
                Else
                    ; Position and show the dropdown right before it takes focus
                    Local $aWinPos = WinGetPos($__g_hFontGUI)
                    WinMove($__g_hColorSubForm, "", $aWinPos[0] + 13, $aWinPos[1] + 5)
                    GUISetState(@SW_SHOW, $__g_hColorSubForm)
                EndIf

            Case $__g_aColor[1][0] To $__g_aColor[$__g_aColor[0][0]][0]
                _SelectedColor($iMsg)

            Case $__g_aFonts[1][0] To $__g_aFonts[$__g_aFonts[0][0]][0]
                _SelectedFont($iMsg)

            Case $__g_aWeight[1][0] To $__g_aWeight[$__g_aWeight[0][0]][0]
                _SelectedWeight($iMsg)

            Case $__g_aSize[1][0] To $__g_aSize[$__g_aSize[0][0]][0]
                _SelectedSize($iMsg)

            Case $__g_idCheck_Italic, $__g_idCheck_Strikeout, $__g_idCheck_Underline
                _UpDateSample()

            Case $__g_idScriptCombo
                _UpDateSample()
                GUICtrlSetState($__g_idPopFont, $GUI_FOCUS)

            Case $idButton_OK
                ; Collect attributes (Italic = 2, Underline = 4, Strikeout = 8)
                Local $iAttributes = 0
                If GUICtrlRead($__g_idCheck_Italic) = $GUI_CHECKED Then $iAttributes = BitOR($iAttributes, 2)
                If GUICtrlRead($__g_idCheck_Underline) = $GUI_CHECKED Then $iAttributes = BitOR($iAttributes, 4)
                If GUICtrlRead($__g_idCheck_Strikeout) = $GUI_CHECKED Then $iAttributes = BitOR($iAttributes, 8)

                Local $sFaceName = GUICtrlRead($__g_idPopFont)
                Local $iWeight = Number(GUICtrlRead($__g_idPopWeight))
                Local $iSize = Number(GUICtrlRead($__g_idPopSize))
                Local $sColor = GUICtrlRead($__g_idFakeColor)
                ConsoleWrite("$sColor=" & $sColor & @CRLF)

                $iFontColorRef = Hex($sColor, 6)
                ConsoleWrite("$iFontColorRef=" & $iFontColorRef & @CRLF)

                ; Format the return data similar to standard _ChooseFont
                $__g_sFontDlgData = $iAttributes & "|" & $sFaceName & "|" & $iSize & "|" & $iWeight & "|" & $sColor

                ; Clean up GUI resource before returning the split array
                GUIDelete($__g_hFontGUI)

                Return StringSplit($__g_sFontDlgData, "|")

        EndSwitch

        ; Hide the color dropdown instantly if it loses focus
        If BitAND(WinGetState($__g_hColorSubForm), $WIN_STATE_VISIBLE) And Not WinActive($__g_hColorSubForm) Then
            ; Except if the mouse is over the FakeCombo bounds to prevent rapid toggle
            If Not _IsMouseOverArea($__g_hFontGUI, $aFakeComboArea) Then GUISetState(@SW_HIDE, $__g_hColorSubForm)
        EndIf

    WEnd

    ; if Cancel or Close was pressed
    GUIDelete($__g_hFontGUI)
    Return SetError(1, 0, False)
EndFunc   ;==>_Custom_Font_Gui

Func _UpDateSample()

    Local Static $sLastScriptLang

    ; Calculate the total attribute based on checkbox states (Italic = 2, Underline = 4, Strike = 8)
    Local $Attribute = 0
    If GUICtrlRead($__g_idCheck_Italic) = $GUI_CHECKED Then $Attribute = BitOR($Attribute, 2)
    If GUICtrlRead($__g_idCheck_Underline) = $GUI_CHECKED Then $Attribute = BitOR($Attribute, 4)
    If GUICtrlRead($__g_idCheck_Strikeout) = $GUI_CHECKED Then $Attribute = BitOR($Attribute, 8)

    Local $sFontName = GUICtrlRead($__g_idPopFont)
    Local $iSize = Int(GUICtrlRead($__g_idPopSize))
    Local $sColor = GUICtrlRead($__g_idFakeColor)
    Local $iWeight = Int(GUICtrlRead($__g_idPopWeight))

    Local $sScriptLang = GUICtrlRead($__g_idScriptCombo)
    If $sLastScriptLang <> $sScriptLang Then
        $sLastScriptLang = $sScriptLang
        Local $sSample = _GetScriptExample($sScriptLang)
        GUICtrlSetData($__g_idLabel_Sample, $sSample)
    EndIf

    ; UpdateWeightSubForm
    If IsArray($__g_aWeight) Then
        For $i = 1 To $__g_aWeight[0][0]
            GUICtrlSetFont($__g_aWeight[$i][0], 11, $__g_aWeight[$i][2], $Attribute, $sFontName)
            GUICtrlSetColor(-1, $__g_hColorText)
        Next
    EndIf


;~  ; Debug Console Output
;~  Local $sTxt = ""
;~  $sTxt &= "$sFontName=" & $sFontName & @CRLF
;~  $sTxt &= "$iSize=" & $iSize & @CRLF
;~  $sTxt &= "$iWeight=" & $iWeight & @CRLF
;~  $sTxt &= "$Attribute=" & $Attribute & @CRLF
;~  $sTxt &= "$sColor=" & $sColor & @CRLF
;~  $sTxt &= @CRLF
;~  ConsoleWrite($sTxt)

    ; Update the Sample Label
    GUICtrlSetFont($__g_idLabel_Sample, $iSize, $iWeight, $Attribute, $sFontName)
    GUICtrlSetColor($__g_idLabel_Sample, $sColor) ; Default Background

EndFunc   ;==>_UpDateSample
#Region ; ~~~~~~~~~~~~~ Selected functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _SelectedFont($iMsg, $bIndex = False)

    Local $idx = $iMsg - $__g_aFonts[1][0] + 1

    ; If $bIndex = True => $iMsg is already the active Index
    If $bIndex Then $idx = $iMsg

    ; Boundary safety checks for indices
    If $__g_iLastFontIdx < 1 Or $__g_iLastFontIdx > $__g_aFonts[0][0] Then $__g_iLastFontIdx = 1
    If $idx < 1 Or $idx > $__g_aFonts[0][0] Then Return

    GUICtrlSetBkColor($__g_aFonts[$__g_iLastFontIdx][0], $__g_hColorDefault) ; Default Background
    GUICtrlSetBkColor($__g_aFonts[$idx][0], $__g_hColorHighlight)            ; Selection Highlight
    GUICtrlSetData($__g_idPopFont, $__g_aFonts[$idx][1])
    $__g_iLastFontIdx = $idx

    ; -------------------------------------------------------------
    ; SMART SCROLLBAR (ONLY SCROLLS IF OUT OF VIEWPORT BOUNDS)
    Local $iRowHeight = 20
    Local $SB_VERT = 1

    Local $iTotalHeight = $__g_aFonts[0][0] * $iRowHeight
    Local $iUDFMax = _GUIScrollBars_GetScrollInfoMax($__g_hFontSubForm, $SB_VERT)

    ; 1. The target item's absolute Y pixel
    Local $iAbsoluteTargetY = ($idx - 1) * $iRowHeight

    ; 2. Get the clean height of the visible window (Aperture)
    Local $aPos = WinGetClientSize($__g_hFontSubForm)
    Local $iVisibleHeight = $aPos[1]

    ; 3. Read current scroll position in pixels
    Local $iCurrentScrollVal = _GUIScrollBars_GetScrollInfoPos($__g_hFontSubForm, $SB_VERT)
    Local $iCurrentScrollY = ($iCurrentScrollVal / $iUDFMax) * $iTotalHeight

    ; 4. Define visible area boundaries
    Local $iVisibleTop = $iCurrentScrollY
    Local $iVisibleBottom = $iCurrentScrollY + $iVisibleHeight

    ; 5. Check if the item is already visible (with a 1-row buffer)
    If $iAbsoluteTargetY < $iVisibleTop Or ($iAbsoluteTargetY + $iRowHeight) > $iVisibleBottom Then

        ; Calculate new scrollbar position
        Local $iCorrectPos = Int(($iAbsoluteTargetY / $iTotalHeight) * $iUDFMax)

        ; Apply precise scrollbar position
        _GUIScrollBars_SetScrollInfoPos($__g_hFontSubForm, $SB_VERT, $iCorrectPos)

    EndIf

    ; -------------------------------------------------------------
    ; Populate the script language ComboBox and prioritized language as active

    Local $iFirst = ""
    Local $sLangs = $__g_aFonts[$idx][2] ; e.g., "Greek|Cyrillic"

    ; Dynamically detect the system active script language
    Local Static $sLocalScript = _GetLocalScriptName()

    ; First Priority: Always default to Western for international compatibility
    If StringInStr($sLangs, "Western") Then
        $iFirst = "Western"

        ; Second Priority: Fallback to the user's local system language
    ElseIf StringInStr($sLangs, $sLocalScript) Then
        $iFirst = $sLocalScript

        ; Fallback: If neither is found, take the first available language from the list
    Else
        Local $iMark = StringInStr($sLangs, "|")
        If $iMark > 0 Then
            $iFirst = StringLeft($sLangs, $iMark - 1)
        Else
            $iFirst = $sLangs
        EndIf
    EndIf

    GUICtrlSetData($__g_idScriptCombo, "|" & $sLangs, $iFirst)

    ; -------------------------------------------------------------

    GUICtrlSetState($__g_idPopFont, $GUI_FOCUS)
    _UpDateSample()

EndFunc   ;==>_SelectedFont

Func _SelectedWeight($iMsg, $bIndex = False)

    Local $idx = $iMsg - $__g_aWeight[1][0] + 1

    ; If $bIndex = True, then $iMsg is already the active index
    If $bIndex Then $idx = $iMsg

    ; Boundary safety checks for indices to prevent out-of-bounds array crashes
    If $__g_iLastWeightIdx < 1 Or $__g_iLastWeightIdx > $__g_aWeight[0][0] Then $__g_iLastWeightIdx = 1
    If $idx < 1 Or $idx > $__g_aWeight[0][0] Then Return

    GUICtrlSetBkColor($__g_aWeight[$__g_iLastWeightIdx][0], $__g_hColorDefault) ; Default Background
    GUICtrlSetBkColor($__g_aWeight[$idx][0], $__g_hColorHighlight)              ; Selection Highlight
    GUICtrlSetData($__g_idPopWeight, $__g_aWeight[$idx][2])                     ; Update $__g_idPopWeight
    GUICtrlSetState($__g_idPopWeight, $GUI_FOCUS)                               ; Make selected
    $__g_iLastWeightIdx = $idx

    _UpDateSample()
EndFunc   ;==>_SelectedWeight

Func _SelectedSize($iMsg, $bIndex = False)

    Local $idx = $iMsg - $__g_aSize[1][0] + 1

    ; If $bIndex = True, then $iMsg is already the active index
    If $bIndex Then $idx = $iMsg

    ; Boundary safety checks for indices to prevent out-of-bounds array crashes
    If $__g_iLastSizeIdx < 1 Or $__g_iLastSizeIdx > $__g_aSize[0][0] Then $__g_iLastSizeIdx = 1
    If $idx < 1 Or $idx > $__g_aSize[0][0] Then Return

    GUICtrlSetBkColor($__g_aSize[$__g_iLastSizeIdx][0], $__g_hColorDefault) ; Default Background
    GUICtrlSetBkColor($__g_aSize[$idx][0], $__g_hColorHighlight)             ; Selection Highlight
    GUICtrlSetData($__g_idPopSize, $__g_aSize[$idx][1])
    GUICtrlSetState($__g_idPopSize, $GUI_FOCUS)
    $__g_iLastSizeIdx = $idx

    _UpDateSample()

EndFunc   ;==>_SelectedSize

Func _SelectedColor($iMsg, $bIndex = False)
    GUISetState(@SW_HIDE, $__g_hColorSubForm)
    Local $idx = $iMsg - $__g_aColor[1][0] + 1

    ; If $bIndex = True, then $iMsg is already the active index
    If $bIndex Then $idx = $iMsg

    ; Boundary safety checks for indices to prevent out-of-bounds array crashes
    If $idx < 1 Or $idx > $__g_aColor[0][0] Then Return

    GUICtrlSetData($__g_idFakeCombo, @TAB & $__g_aColor[$idx][1])

    GUICtrlSetData($__g_idFakeColor, "0x" & Hex($__g_aColor[$idx][2], 6))
    GUICtrlSetColor($__g_idFakeColor, $__g_aColor[$idx][2])
    GUICtrlSetBkColor($__g_idFakeColor, $__g_aColor[$idx][2])

    _UpDateSample()

EndFunc   ;==>_SelectedColor
#EndRegion ; ~~~~~~~~~~~~~ Selected functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ; ~~~~~~~~~~~~~ Make SubForms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _Make_FontSubForm($hGUI, $iLeft, $iTop, $iWidth, $iHeight)
    Local $hSubGUI = _HiDpi_GUICreate("FontSubForm", $iWidth, $iHeight, $iLeft, $iTop, BitOR($WS_CHILD, $WS_BORDER, $WS_TABSTOP), -1, $hGUI)
    GUISetBkColor($__g_hColorDefault, $hSubGUI)

    Local $iRowHeight = 20
    Local $iTotalFonts = $__g_aFonts[0][0]

    ; Create a label for each font name dynamically
    For $i = 1 To $iTotalFonts
        $__g_aFonts[$i][0] = _HiDpi_GUICtrlCreateLabel($__g_aFonts[$i][1], 5, ($i - 1) * $iRowHeight, $iWidth - 5, $iRowHeight, $SS_CENTERIMAGE)
        GUICtrlSetFont(-1, 11, 0, 0, $__g_aFonts[$i][1])
        GUICtrlSetColor(-1, $__g_hColorText)
    Next

    GUISetState(@SW_SHOW, $hSubGUI)

    ; Generate the scrollbars using the exact total height calculated
    _GUIScrollbars_Generate($hSubGUI, 0, $iTotalFonts * $iRowHeight)

    Return $hSubGUI
EndFunc   ;==>_Make_FontSubForm

Func _Make_WeightSubForm($hGUI, $iLeft, $iTop, $iWidth, $iHeight)
    Local $hSubGUI = _HiDpi_GUICreate("StyleSubForm", $iWidth, $iHeight, $iLeft, $iTop, BitOR($WS_CHILD, $WS_BORDER), -1, $hGUI)
    GUISetBkColor($__g_hColorDefault, $hSubGUI)

    ; Define the static list of standard Windows Font Weights
    Dim $__g_aWeight[11][3] = [ _
            [10, "", 0], _
            [0, "Dontcare", 0], _
            [0, "Thin", 100], _
            [0, "Extralight", 200], _
            [0, "Light", 300], _
            [0, "Normal", 400], _
            [0, "Medium", 500], _
            [0, "Semibold", 600], _
            [0, "Bold", 700], _
            [0, "Extrabold", 800], _
            [0, "Heavy", 900]]

    Local $iRowHeight = 20
    Local $iTotalWeights = $__g_aWeight[0][0]

    ; Create labels and apply their respective font weights dynamically
    For $i = 1 To $iTotalWeights
        $__g_aWeight[$i][0] = _HiDpi_GUICtrlCreateLabel($__g_aWeight[$i][1], 5, ($i - 1) * $iRowHeight, $iWidth - 5, $iRowHeight, $SS_CENTERIMAGE)
        GUICtrlSetFont(-1, 11, $__g_aWeight[$i][2])
        GUICtrlSetColor(-1, $__g_hColorText)
    Next

    GUISetState(@SW_SHOW, $hSubGUI)

    ; Generate scrollbars based on total height of the elements
    _GUIScrollbars_Generate($hSubGUI, 0, $iTotalWeights * $iRowHeight)

    Return $hSubGUI
EndFunc   ;==>_Make_WeightSubForm

Func _Make_SizeSubForm($hGUI, $iLeft, $iTop, $iWidth, $iHeight)
    Local $hSubGUI = _HiDpi_GUICreate("SizeSubForm", $iWidth, $iHeight, $iLeft, $iTop, BitOR($WS_CHILD, $WS_BORDER), -1, $hGUI)
    GUISetBkColor($__g_hColorDefault, $hSubGUI)

    ; Define the standard list of font sizes
    Local $aNum[17] = [16, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72]
    Dim $__g_aSize[17][2]
    $__g_aSize[0][0] = 16

    Local $iRowHeight = 20
    Local $iTotalSizes = $__g_aSize[0][0]

    ; Create label controls for each font size dynamically
    For $i = 1 To $iTotalSizes
        $__g_aSize[$i][1] = $aNum[$i]
        $__g_aSize[$i][0] = _HiDpi_GUICtrlCreateLabel($__g_aSize[$i][1], 5, ($i - 1) * $iRowHeight, $iWidth - 5, $iRowHeight, $SS_CENTERIMAGE)
        GUICtrlSetFont(-1, 11)
        GUICtrlSetColor(-1, $__g_hColorText)
    Next

    GUISetState(@SW_SHOW, $hSubGUI)

    ; Generate scrollbars based on the total height of all size items
    _GUIScrollbars_Generate($hSubGUI, 0, $iTotalSizes * $iRowHeight)

    Return $hSubGUI
EndFunc   ;==>_Make_SizeSubForm

Func _Make_ColorSubForm($hGUI, $iLeft, $iTop, $iWidth, $iHeight)
    Local $hSubGUI = _HiDpi_GUICreate("ColorSubForm", $iWidth, $iHeight, $iLeft, $iTop, BitOR($WS_POPUP, $WS_BORDER), $WS_EX_TOOLWINDOW, $hGUI)
    GUISetBkColor($__g_hColorDefault, $hSubGUI)

    ; Define the static list of standard Windows Font Weights
    Dim $__g_aColor[23][3] = [ _
            [22, "", 0], _
            [0, "BLACK", 0x000000], _
            [0, "WHITE", 0xFFFFFF], _
            [0, "SILVER", 0xC0C0C0], _
            [0, "GRAY", 0x808080], _
            [0, "MAROON", 0x800000], _
            [0, "RED", 0xFF0000], _
            [0, "CORAL", 0xFF7F50], _
            [0, "BROWN", 0xA52A2A], _
            [0, "CHOCOLATE", 0xD2691E], _
            [0, "YELLOW", 0xFFFF00], _
            [0, "OLIVE", 0x808000], _
            [0, "LIME", 0x00FF00], _
            [0, "GREEN", 0x008000], _
            [0, "AQUAMARINE", 0x7FFFD4], _
            [0, "AQUA", 0x00FFFF], _
            [0, "TEAL", 0x008080], _
            [0, "CADETBLUE", 0x5F9EA0], _
            [0, "NAVY", 0x000080], _
            [0, "BLUE", 0x0000FF], _
            [0, "BLUEVIOLET", 0x8A2BE2], _
            [0, "PURPLE", 0x800080], _
            [0, "FUCHSIA", 0xFF00FF]]


    Local $iRowHeight = 20
    Local $iTotalColors = $__g_aColor[0][0]

    For $i = 1 To $iTotalColors
        $__g_aColor[$i][0] = _HiDpi_GUICtrlCreateLabel(@TAB & $__g_aColor[$i][1], 0, ($i - 1) * $iRowHeight, $iWidth, $iRowHeight, $SS_CENTERIMAGE)
        GUICtrlSetColor(-1, $__g_hColorText)
        GUICtrlSetBkColor(-1, $__g_hColorDefault)
    Next

    For $i = 1 To $iTotalColors
        _HiDpi_GUICtrlCreateLabel("", 2, (($i - 1) * $iRowHeight) + 1, 30, $iRowHeight - 2)
        GUICtrlSetBkColor(-1, $__g_aColor[$i][2])
        GUICtrlSetState(-1, $GUI_DISABLE)
    Next

    GUISetState(@SW_HIDE, $hSubGUI)

    Return $hSubGUI
EndFunc   ;==>_Make_ColorSubForm
#EndRegion ; ~~~~~~~~~~~~~ Make SubForms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ; ~~~~~~~~~~~~~ Helper functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Func _GetActiveCtrl()
    ; Get the handle of the control that currently has input focus system-wide
    Local $hFocusCtrl = _WinAPI_GetFocus()

    ; Return its Control ID
    Return _WinAPI_GetDlgCtrlID($hFocusCtrl)
EndFunc   ;==>_GetActiveCtrl

Func _IsMouseOverArea($hGUI, $aArea)
    Local $a = GUIGetCursorInfo($hGUI)
    If IsArray($a) Then
        Local $iX = $a[0]
        Local $iY = $a[1]
        If $iX >= $aArea[0] And $iY >= $aArea[1] And $iX <= ($aArea[0] + $aArea[2]) And $iY <= ($aArea[1] + $aArea[3]) Then
            Return True
        EndIf
    EndIf
    Return False
EndFunc   ;==>_IsMouseOverArea

Func _GetFonts()
    ; Enumerate all system font families, excluding vertical fonts starting with '@'
    Local $aData = _WinAPI_EnumFontFamilies(0, '', $DEFAULT_CHARSET, 0x07, '@*', 1)
    If @error Or Not IsArray($aData) Then Return SetError(1, 0, 0)

    Local $iTotalRows = $aData[0][0]
    If $iTotalRows < 1 Then Return SetError(2, 0, 0)

    ; Sort the enumerated to group duplicates together
    _ArraySort($aData, 0, 1)

    Local $aReturnFonts[$iTotalRows + 1][3]
    Local $sLastName = ""
    Local $sLangList = ""
    Local $iUniqueIdx = 0

    For $i = 1 To $iTotalRows
        Local $sCurrentName = $aData[$i][0]
        Local $sCurrentLang = $aData[$i][3]

        ; If we encounter a new font family name
        If $sCurrentName <> $sLastName Then

            ; Save the language list to the PREVIOUS font before moving on
            If $iUniqueIdx > 0 Then
                $aReturnFonts[$iUniqueIdx][2] = StringTrimRight($sLangList, 1)
            EndIf

            ; Move to the next unique slot and store the new font name
            $iUniqueIdx += 1
            $aReturnFonts[$iUniqueIdx][1] = $sCurrentName
            $sLastName = $sCurrentName
            $sLangList = ""
        EndIf

        ; Append the current language/script to the list (preventing internal duplicates if any)
        If Not StringInStr($sLangList, $sCurrentLang & "|") Then
            $sLangList &= $sCurrentLang & "|"
        EndIf
    Next

    ; Save the very last font's language list after the loop ends!
    If $iUniqueIdx > 0 Then
        $aReturnFonts[$iUniqueIdx][2] = StringTrimRight($sLangList, 1)
    EndIf

    ; Resize the return array to fit
    ReDim $aReturnFonts[$iUniqueIdx + 1][3]
    $aReturnFonts[0][0] = $iUniqueIdx

    Return $aReturnFonts
EndFunc   ;==>_GetFonts

Func _BestMatchArraySearch(ByRef $aArray, $sSearchStr, $iStart = 0, $iSubItem = 0)

    If Not IsArray($aArray) Then Return SetError(1, 0, -1)

    Local $iRows = UBound($aArray, 1)
    Local $iCols = UBound($aArray, 2)

    ; Validate start index
    If $iStart < 0 Or $iStart >= $iRows Then Return SetError(2, 0, -1)

    ; Validate subitem index for 2D arrays
    If $iCols > 0 And ($iSubItem < 0 Or $iSubItem >= $iCols) Then Return SetError(3, 0, -1)

    ; Clean up search string
    $sSearchStr = StringStripWS($sSearchStr, 3)
    If $sSearchStr = "" Then Return 1 ; Return default first index if search is empty

    Local $aPart = StringSplit($sSearchStr, "")
    Local $iMaxMatchedLen = 0
    Local $iBestIndex = -1
    Local $sCurrentVal = ""

    ; Loop through each item in the array
    For $i = $iStart To $iRows - 1
        If $iCols > 0 Then
            $sCurrentVal = $aArray[$i][$iSubItem]
        Else
            $sCurrentVal = $aArray[$i]
        EndIf

        ; RESET search state for the current array item
        Local $iCurrentSearchLen = 1
        Local $sPattern = $aPart[1]

        ; Check how many characters match from the beginning of the string
        While (StringLeft($sCurrentVal, $iCurrentSearchLen) = $sPattern)
            ; If this item matches more characters than our previous best, update it
            If $iCurrentSearchLen > $iMaxMatchedLen Then
                $iMaxMatchedLen = $iCurrentSearchLen
                $iBestIndex = $i
            EndIf

            ; If we matched the entire search string, we found an exact match!
            If $iCurrentSearchLen >= $aPart[0] Then Return $i

            $iCurrentSearchLen += 1
            $sPattern &= $aPart[$iCurrentSearchLen]
        WEnd
    Next

    ; If no partial match was found, default to the first index
    If $iBestIndex = -1 Then $iBestIndex = 1

    Return $iBestIndex
EndFunc   ;==>_BestMatchArraySearch

Func _GetLocalScriptName()
    Switch @OSLang
        Case "0408"
            Return "Greek"
        Case "0419", "0422" ; Russian, Ukrainian
            Return "Cyrillic"
        Case "0415", "041b", "041e", "0424" ; Polish, Slovak, Hungarian, Slovenian
            Return "Central European"
        Case "041f" ; Turkish
            Return "Turkish"
        Case "0425" ; Estonian
            Return "Baltic"
        Case "042a" ; Vietnamese
            Return "Vietnamese"
        Case "040d" ; Hebrew
            Return "Hebrew"
        Case "0401" ; Arabic
            Return "Arabic"
        Case Else
            Return "Western" ; Standard default fallback
    EndSwitch
EndFunc   ;==>_GetLocalScriptName

Func _GetScriptExample($vLang)

    Switch $vLang
        Case "0408", "Greek"
            Return "Η γρήγορη καφέ αλεπού πηδάει πάνω από το τεμπέλικο σκυλί" & @CRLF & "0123456789"

        Case "0419", "0422", "Cyrillic" ; Russian, Ukrainian
            Return "Съешь же ещё этих мягких французских булок, да выпей чаю" & @CRLF & "0123456789"

        Case "0415", "041b", "041e", "0424", "Central European" ; Polish, Slovak, Hungarian, Slovenian, etc.
            Return "Příliš žluťoučký kůň úpěl ďábelské ódy" & @CRLF & "0123456789"

        Case "041f", "Turkish"
            Return "Pijamalı hasta yağız şoföre çabucak güvendi" & @CRLF & "0123456789"

        Case "0425", "Baltic" ; Estonian, Latvian, Lithuanian
            Return "Sarkanmatainais ķīniešu pusaudzis brauc ar velosipēdu" & @CRLF & "0123456789"

        Case "042a", "Vietnamese"
            Return "Hiến pháp nước Cộng hòa Xã hội Chủ nghĩa Việt Nam" & @CRLF & "0123456789"

        Case "040d", "Hebrew"
            Return "דג קרח שזה עתה בקע נע עם חול במים ראו 0123456789"

        Case "0401", "Arabic"
            Return "نص حكيم له سر قاطع تبسطه أذن واع بغير كتمان 0123456789"

        Case Else ; "Western" or anything else
            Return "The quick brown fox jumps over the lazy dog" & @CRLF & "0123456789"
    EndSwitch
EndFunc   ;==>_GetScriptExample
#EndRegion ; ~~~~~~~~~~~~~ Helper functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#Region ; ~~~~~~~~~~~~~ DarkMode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;--------------------------------------------------------------------------------------------------------------------------------
; https://www.autoitscript.com/forum/topic/211475-darkmode-udf-for-autoits-win32guis/#comment-1530103
;--------------------------------------------------------------------------------------------------------------------------------
Func DarkMode($hGui, $bDarkMode = True)

    Local Enum $DWMWA_USE_IMMERSIVE_DARK_MODE = (@OSBuild <= 18985) ? 19 : 20
    ; DWMWA_USE_IMMERSIVE_DARK_MODE ; https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
    ; Use with DwmSetWindowAttribute. Allows the window frame for this window to be drawn in dark mode colors when the dark mode system setting is enabled.
    ; For compatibility reasons, all windows default to light mode regardless of the system setting.
    ; The pvAttribute parameter points to a value of type BOOL. TRUE to honor dark mode for the window, FALSE to always use light mode.
    ; This value is supported starting with Windows 11 Build 22000.

    Local $iRet = _WinAPI_DwmSetWindowAttribute_unr($hGui, $DWMWA_USE_IMMERSIVE_DARK_MODE, $bDarkMode)
    If Not $iRet Then Return SetError(1, 0, -1)

    Local $aCtrls = _GetDirectChildControls($hGui)
    Local $handler, $sClass, $id, $iStyle

    For $i = 1 To $aCtrls[0][0]
        $sClass = $aCtrls[$i][1]
        $handler = $aCtrls[$i][0]
        $id = _WinAPI_GetDlgCtrlID($handler)
        $iStyle = _WinAPI_GetWindowLong($handler, $GWL_STYLE)
        ; ConsoleWrite("-> " & $sClass & ",   $iStyle=0x" & Hex($iStyle) & @CRLF)

        Switch $sClass
            Case "AutoIt v3 GUI"
                ; is tells Windows to render its scrollbars in dark theme.
                _SetCtrlColorMode($handler, $bDarkMode)
                If $bDarkMode Then
                    GUISetBkColor(0x1B1B1B, $handler)
                Else
                    GUISetBkColor(0xF0F0F0, $handler)
                EndIf

            Case "Button"
                ; Check if the button is GroupBox (BS_GROUPBOX = 0x00000007)
                If BitAND($iStyle, 0x0000000F) = 7 Then
                    _WinAPI_SetWindowTheme_unr($handler, "", "")
                    If $bDarkMode Then
                        GUICtrlSetColor($id, 0xFFFFFF)
                    Else
                        GUICtrlSetColor($id, 0x000000)
                    EndIf
                Else
                    ; Standard button gets standard explorer theme coloring
                    _SetCtrlColorMode($handler, $bDarkMode)
                EndIf

            Case "ComboBox"
                _SetCtrlColorMode($handler, $bDarkMode)
                If $bDarkMode Then
                    _WinAPI_SetWindowTheme_unr($handler, "CFD", "Combobox")
                    GUICtrlSetColor($id, 0xFFFFFF)
                    GUICtrlSetBkColor($id, 0x1B1B1B)
                Else
                    ; Reset to standard Windows theme
                    _WinAPI_SetWindowTheme_unr($handler, "", "")
                    GUICtrlSetColor($id, 0x000000)
                    GUICtrlSetBkColor($id, 0xFFFFFF)
                EndIf

            Case "Static"
                _SetCtrlColorMode($handler, $bDarkMode)
                If $bDarkMode Then
                    GUICtrlSetColor($id, 0xFFFFFF)
                Else
                    GUICtrlSetColor($id, 0x000000)
                EndIf
                GUICtrlSetBkColor($id, $GUI_BKCOLOR_TRANSPARENT)

            Case Else
                _SetCtrlColorMode($handler, $bDarkMode)
                If $bDarkMode Then
                    GUICtrlSetBkColor($id, 0x000000)
                    GUICtrlSetColor($id, 0xFFFFFF)
                Else
                    GUICtrlSetBkColor($id, 0xFFFFFF)
                    GUICtrlSetColor($id, 0x000000)
                EndIf

        EndSwitch
    Next

    If $bDarkMode Then
        GUISetBkColor(0x1B1B1B, $hGui) ; 0x1B1B1B Black

        $__g_hColorDefault = 0x1B1B1B
        $__g_hColorHighlight = 0x0078D7
        $__g_hColorText = 0xFFFFFF
    Else
        GUISetBkColor(0xF0F0F0, $hGui) ; 0xF0F0F0 Light Gray/Honeydew

        $__g_hColorDefault = 0xFFFFFF
        $__g_hColorHighlight = 0xC8CFFA
        $__g_hColorText = 0x000000
    EndIf

    ; Update subform custom controls dynamically
    _UpdateSubFormCtrls($__g_aFonts, $__g_hColorText, $__g_hColorDefault)
    _UpdateSubFormCtrls($__g_aSize, $__g_hColorText, $__g_hColorDefault)
    _UpdateSubFormCtrls($__g_aWeight, $__g_hColorText, $__g_hColorDefault)
    _UpdateSubFormCtrls($__g_aColor, $__g_hColorText, $__g_hColorDefault)

    ; Restore highlight background to active selections
    _SelectedSize($__g_iLastSizeIdx, 1)
    _SelectedWeight($__g_iLastWeightIdx, 1)
    _SelectedFont($__g_iLastFontIdx, 1)

    ; Update color combo
    Local $sColor = GUICtrlRead($__g_idFakeColor)
    GUICtrlSetColor($__g_idFakeColor, $sColor) ; BLACK
    GUICtrlSetBkColor($__g_idFakeColor, $sColor) ; BLACK

    _WinAPI_RedrawWindow($hGui, 0, 0, $RDW_UPDATENOW)

EndFunc   ;==>DarkMode
;----------------------------------------------------------------------------------------
Func _SetCtrlColorMode($hWnd, $bDarkMode = True, $sName = Default)
    If $sName = Default Then $sName = $bDarkMode ? 'DarkMode_Explorer' : 'Explorer'
    $bDarkMode = Not Not $bDarkMode
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Local Enum $eDefault, $eAllowDark, $eForceDark, $eForceLight, $eMax ; enum PreferredAppMode
    DllCall('uxtheme.dll', 'bool', 133, 'hwnd', $hWnd, 'bool', $bDarkMode) ; fnAllowDarkModeForWindow = 133
    DllCall('uxtheme.dll', 'int', 135, 'int', ($bDarkMode ? $eForceDark : $eForceLight)) ; fnAllowDarkModeForApp = 135
    _WinAPI_SetWindowTheme_unr($hWnd, $sName)
    DllCall('uxtheme.dll', 'none', 104) ; fnRefreshImmersiveColorPolicyState = 104
    _SendMessage($hWnd, $WM_THEMECHANGED, 0, 0)
EndFunc   ;==>_SetCtrlColorMode
;----------------------------------------------------------------------------------------
Func _WinAPI_SetWindowTheme_unr($hWnd, $sName = Null, $sList = Null)
    ; Causes a window to use a different set of visual style information than its class normally uses
    Local $sResult = DllCall('UxTheme.dll', 'long', 'SetWindowTheme', 'hwnd', $hWnd, 'wstr', $sName, 'wstr', $sList)
    If @error Then Return SetError(@error, @extended, 0)
    If $sResult[0] Then Return SetError(10, $sResult[0], 0)
    Return 1
EndFunc   ;==>_WinAPI_SetWindowTheme_unr
;----------------------------------------------------------------------------------------
Func _WinAPI_DwmSetWindowAttribute_unr($hWnd, $iAttribute, $iData)
    ; Sets the value of the specified attributes for non-client rendering to apply to the window
    Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $iAttribute, _
            'dword*', $iData, 'dword', 4)
    If @error Then Return SetError(@error, @extended, 0)
    If $aCall[0] Then Return SetError(10, $aCall[0], 0)
    Return 1
EndFunc   ;==>_WinAPI_DwmSetWindowAttribute_unr
;----------------------------------------------------------------------------------------
Func _GetDirectChildControls($hParent)
    Local $aResult[100][2] ; Create a dynamic array to store the results
    Local $iCount = 0

    ; Get the handle of the FIRST child control of the window
    Local $hCtrl = _WinAPI_GetWindow($hParent, $GW_CHILD)

    ; Loop to retrieve all siblings in sequence
    While $hCtrl <> 0
        $iCount += 1

        ; If the array is full, increase its size
        If $iCount >= UBound($aResult) Then ReDim $aResult[$iCount + 50][2]

        $aResult[$iCount][0] = $hCtrl ; The HWND of the control
        $aResult[$iCount][1] = _WinAPI_GetClassName($hCtrl) ; The class name

        ; Move to the next control at the same level
        $hCtrl = _WinAPI_GetWindow($hCtrl, $GW_HWNDNEXT)
    WEnd

    ; Resize the array to fit
    ReDim $aResult[$iCount + 1][2]
    $aResult[0][0] = $iCount

    Return $aResult
EndFunc   ;==>_GetDirectChildControls
;---------------------------------------------------------------------------------------
Func _UpdateSubFormCtrls(ByRef $aArray, $hTxtColor, $hBkColor)
    If IsArray($aArray) Then
        For $i = 1 To $aArray[0][0]
            GUICtrlSetColor($aArray[$i][0], $hTxtColor)
            GUICtrlSetBkColor($aArray[$i][0], $hBkColor)
        Next
    EndIf
EndFunc   ;==>_UpdateSubFormCtrls
;---------------------------------------------------------------------------------------
#EndRegion ; ~~~~~~~~~~~~~ DarkMode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:) 

image.thumb.png.7afc34a2fd2c910956f8c3f69c12608d.png

 

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting  image.gif.922e3a93535f431de08b31ee669cc446.gif
autoit_scripter_blue_userbar.png

Posted

Nicely done, glad you kept "for our eyes only" 1 native ComboBox control, i.e. the Script ComboBox control :D

If I got it right, 3 other ComboBox controls (i.e. Font, Font Weight, Size) became GUI child windows, created with GuiCreate and the "items" all became Labels.

I wonder why the Font Weight indicates a numeric value (400 for example when "Normal" is selected) . Shouldn't it indicate the same string value "Normal" as the one selected in the list, to mimic what happens in a ComboBox control ?

The 4th ComboBox Control (the "Color" one) didn't become a GUI child window but a GUI popup window. I notice that when it is displayed and the mouse is hovering over its "items", then no "hovered color" appears as in a real combobox. Also while the popup is displayed, moving the main GUI won't stick the popup to the GUI (i.e. the popup will stay at its place while the GUI is moving). Anyway it's acceptable imho

I am curious to know if you considered using a ComboBoxEx control (instead of the popup window) which allows natively to add a solid bitmap at the left and its caption at the right of each item, as found in the help file example function _GUICtrlComboBoxEx_CreateSolidBitMap

But maybe it isn't suitable to your script because of the background color of the listbox associated to the ComboBoxEx control ?

Great job @ioa747 :thumbsup:

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted

I'm just going through the code now and testing so I will provide some feedback bit-by-bit as I notice things.

  • The small "g" and likely other characters are getting cut off at the bottom of each comboitem. This may be different depending on DPI scale.
  • The symbol type of fonts are showing in their actual symbols and therefore the user cannot see the font name
    • MS handles their display of symbol type fonts by setting default font (Segoe UI) and default style for all combos

I've been doing some recent work on my intercepted ChooseFont dialog subclass and have some code that may (or may not) be helpful. But then again, since you are using _WinAPI_EnumFontFamilies(), you might not need the charset stuff since you already have it. I had to get mine from the DC.

; Temporarily load the current font to determine CHARSET
$hFont = _WinAPI_CreateFont($iSize, 0, 0, 0, $iWeight, $bItalic, 0, 0, $DEFAULT_CHARSET, 0, 0, $iQuality, 0, $sFont)
$hOldFont = _WinAPI_SelectObject($hDC, $hFont)
Local $tTextMetrics = _WinAPI_GetTextMetrics($hDC)
$iCharset = DllStructGetData($tTextMetrics, "tmCharSet")
ConsoleWrite("CHARSET (test): " & $iCharset & @CRLF)
_WinAPI_SelectObject($hDC, $hOldFont)
_WinAPI_DeleteObject($hFont)

But anyway, for the symbol fonts displaying as symbols in the combos, you can swap $SYMBOL_CHARSET for $ANSI_CHARSET but only for the combos which you want to show regular text and switch font to display as "Segoe UI". You don't want this for the Sample/Preview area, just the combos. This is just a suggestion. :)

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...