Welchen Font verwendet AutoIt für Gui und Controls?

    • Offizieller Beitrag

    Folgendes Problem:
    GuiSetFont und GuiCtrlSetFont verwenden als Default-Parameter:
    - Size 8.5
    - Fontname OS-GUI-Font

    Ich wollte eine Möglichkeit haben, nach Veränderungen am Font diesen auf "Default" zurückzusetzen.
    Hier ein Skriptbsp., das zeigt - es ist absolut unmöglich. Weder Größe noch Aussehen des Font sind tatsächlich mit dem Original nach Ersterstellung identisch.
    "Label-1" bleibt zum Vergleich unverändert.

    Spoiler anzeigen
    [autoit]


    #include <GuiConstants.au3>
    #include <GuiSlider.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate('Test')
    $Label_1 = GUICtrlCreateLabel('Label-1', 20, 20, 80)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $Label_2 = GUICtrlCreateLabel('Label-2', 20, 45, 80)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $sFontName = _SysGetFont()[3]
    GUICtrlCreateLabel('System Font: ' & $sFontName, 20, 70, 180, 20)
    GUICtrlCreateLabel('Setze Font für Label-2: System, Size vom Slider', 20, 100)
    $slider = GUICtrlCreateSlider(20, 120, 200, 20, $TBS_AUTOTICKS)
    GUICtrlSetLimit(-1, 28, 12)
    _GUICtrlSlider_SetPos($slider, 17)
    $lblSize = GUICtrlCreateLabel(GUICtrlRead($slider)/2, 230, 123, 30)
    $btSetFont = GUICtrlCreateButton('Setze Font', 20, 160, 60, 22)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While True
    Switch GUIGetMsg()
    Case -3
    Exit
    Case $btSetFont
    GUICtrlSetFont($Label_2, GUICtrlRead($slider)/2, 400, 0, $sFontName)
    Case $slider
    GUICtrlSetData($lblSize, GUICtrlRead($slider)/2)
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name....: _SysGetFont()
    ; Description......: Gets from Source the system settings for the font parameters
    ; Parameter(s).....: $iFontSource 0='Titlebar' (default), 1='Palette', 2='Menu', 3='ToolTip', 4='MessageBox'
    ; Return Value(s)..: [size, weight, attributes, fontname, quality]
    ; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
    ;===============================================================================
    Func _SysGetFont($iFontSource=0)
    Local $tNONCLIENTMETRICS = DllStructCreate('struct; uint cbSize;int iBorderWidth;int iScrollWidth;' & _
    'int iScrollHeight;int iCaptionWidth;int iCaptionHeight;byte lfCaptionFont[60];int iSMCaptionWidth;' & _
    'int iSMCaptionHeight;byte lfSMCaptionFont[60];int iMenuWidth;int iMenuHeight;byte lfMenuFont[60];' & _
    'byte lfStatusFont[60];byte lfMessageFont[60];int iPaddedBorderWidth;endstruct')
    DllStructSetData($tNONCLIENTMETRICS, 'cbSize', DllStructGetSize($tNONCLIENTMETRICS))
    DllCall('user32', 'int', 'SystemParametersInfoA', 'int', 41, 'int', DllStructGetSize($tNONCLIENTMETRICS), _
    'ptr', DllStructGetPtr($tNONCLIENTMETRICS), 'int', 0)
    Local $tagLF = 'struct;long;long;long;long;long;byte;byte;byte;byte;byte;byte;byte;byte;char[32];endstruct'
    Local $aFontSource[5] = ['lfCaptionFont','lfSMCaptionFont','lfMenuFont','lfStatusFont','lfMessageFont']
    Local $tLogFont = DllStructCreate($tagLF, DllStructGetPtr($tNONCLIENTMETRICS, $aFontSource[$iFontSource]))
    Local $aOut[5] = [ _
    Abs(DllStructGetData($tLogFont, 1))*0.7, _ ; Height * size
    DllStructGetData($tLogFont, 5), _ ; Weight * weight
    DllStructGetData($tLogFont, 6) + _ ; Italic * attribute
    DllStructGetData($tLogFont, 7) + _ ; Underline * attribute
    DllStructGetData($tLogFont, 8), _ ; StrikeOut * attribute
    DllStructGetData($tLogFont, 14), _ ; FaceName * fontname
    DllStructGetData($tLogFont, 12)] ; Quality * quality
    Return $aOut
    EndFunc ;==>_SysGetFont

    [/autoit]


    Hat jemand eine Idee, welche Werte tatsächlich dort verwendet werden? Nach meinem Verständnis liegt das Problem in AutoIt selbst begraben. In der Art, wie die Parameter vom Betriebssystem übernommen und umgesetzt werden. Beim Abfragen der Werte vom OS erhält man die Angaben aus dem LOGFONT als logische Größe (12). Mit dem Faktor 0.7 kann man dann näherungsweise den in AutoIt verwendeten Wert von 8.5 erreichen (rechnerisch 8.4).
    Die Lösung mit der Brechstange wäre natürlich, das Ctrl zu löschen und neu zu erstellen. Dann habe ich den sauberen Ausgangszustand, allerdings habe ich auch eine neue ID und muss ggf. für alle Funktionen, die das Ctrl nutzen noch ein ID-Management vorhalten. :S

    • Offizieller Beitrag

    Probier es mal so:

    Spoiler anzeigen
    [autoit]

    #include <GuiConstants.au3>
    #include <GuiSlider.au3>
    $hGui = GUICreate('Test')
    $Label_1 = GUICtrlCreateLabel('Label-1', 20, 20, 80)
    $hLabel = GUICtrlGetHandle($Label_1)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $Label_2 = GUICtrlCreateLabel('Label-2', 20, 45, 80)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $sFontName = _CtrlGetFont($hLabel)[3]
    GUICtrlCreateLabel('System Font: ' & $sFontName, 20, 70, 180, 20)
    GUICtrlCreateLabel('Setze Font für Label-2: System, Size vom Slider', 20, 100)
    $slider = GUICtrlCreateSlider(20, 120, 200, 20, $TBS_AUTOTICKS)
    GUICtrlSetLimit(-1, 28, 12)
    _GUICtrlSlider_SetPos($slider, 17)
    $lblSize = GUICtrlCreateLabel(GUICtrlRead($slider) / 2, 230, 123, 30)
    $btSetFont = GUICtrlCreateButton('Setze Font', 20, 160, 60, 22)
    GUISetState()
    While True
    Switch GUIGetMsg()
    Case -3
    Exit
    Case $btSetFont
    GUICtrlSetFont($Label_2, GUICtrlRead($slider) / 2, 400, 0, $sFontName)
    Case $slider
    GUICtrlSetData($lblSize, GUICtrlRead($slider) / 2)
    EndSwitch
    WEnd
    ;===============================================================================
    ; Function Name....: _SysGetFont()
    ; Description......: Gets from Source the system settings for the font parameters
    ; Parameter(s).....: $iFontSource 0='Titlebar' (default), 1='Palette', 2='Menu', 3='ToolTip', 4='MessageBox'
    ; Return Value(s)..: [size, weight, attributes, fontname, quality]
    ; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
    ;===============================================================================
    ;~ Func _SysGetFont($iFontSource=0)
    ;~ Local $tNONCLIENTMETRICS = DllStructCreate('struct; uint cbSize;int iBorderWidth;int iScrollWidth;' & _
    ;~ 'int iScrollHeight;int iCaptionWidth;int iCaptionHeight;byte lfCaptionFont[60];int iSMCaptionWidth;' & _
    ;~ 'int iSMCaptionHeight;byte lfSMCaptionFont[60];int iMenuWidth;int iMenuHeight;byte lfMenuFont[60];' & _
    ;~ 'byte lfStatusFont[60];byte lfMessageFont[60];int iPaddedBorderWidth;endstruct')
    ;~ DllStructSetData($tNONCLIENTMETRICS, 'cbSize', DllStructGetSize($tNONCLIENTMETRICS))
    ;~ DllCall('user32', 'int', 'SystemParametersInfoA', 'int', 41, 'int', DllStructGetSize($tNONCLIENTMETRICS), _
    ;~ 'ptr', DllStructGetPtr($tNONCLIENTMETRICS), 'int', 0)
    ;~ Local $tagLF = 'struct;long;long;long;long;long;byte;byte;byte;byte;byte;byte;byte;byte;char[32];endstruct'
    ;~ Local $aFontSource[5] = ['lfCaptionFont','lfSMCaptionFont','lfMenuFont','lfStatusFont','lfMessageFont']
    ;~ Local $tLogFont = DllStructCreate($tagLF, DllStructGetPtr($tNONCLIENTMETRICS, $aFontSource[$iFontSource]))
    ;~ Local $aOut[5] = [ _
    ;~ Abs(DllStructGetData($tLogFont, 1))*0.7, _ ; Height * size
    ;~ DllStructGetData($tLogFont, 5), _ ; Weight * weight
    ;~ DllStructGetData($tLogFont, 6) + _ ; Italic * attribute
    ;~ DllStructGetData($tLogFont, 7) + _ ; Underline * attribute
    ;~ DllStructGetData($tLogFont, 8), _ ; StrikeOut * attribute
    ;~ DllStructGetData($tLogFont, 14), _ ; FaceName * fontname
    ;~ DllStructGetData($tLogFont, 12)] ; Quality * quality
    ;~ Return $aOut
    ;~ EndFunc ;==>_SysGetFont

    [/autoit] [autoit][/autoit] [autoit]

    Func _CtrlGetFont($hwnd); Original by KaFu mod by Raupi
    If Not HWnd($hwnd) Then $hwnd = GUICtrlGetHandle($hwnd)
    Local $hDC = _WinAPI_GetDC($hwnd)
    Local $hFont = _SendMessage($hwnd, $WM_GETFONT)
    Local $hObject = _WinAPI_SelectObject($hDC, $hFont)
    Local $lvLOGFONT = DllStructCreate($tagLOGFONT)
    Local $aRet = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFont, 'int', DllStructGetSize($lvLOGFONT), 'ptr', DllStructGetPtr($lvLOGFONT))
    _WinAPI_SelectObject($hDC, $hObject)
    _WinAPI_ReleaseDC($hwnd, $hDC)
    Local $aOut[5] = [ _
    Round(ABS(DllStructGetData($lvLOGFONT, "Height"))*0.776,1), _ ; Height * size
    DllStructGetData($lvLOGFONT, "Weight"), _ ; Weight * weight
    DllStructGetData($lvLOGFONT, "Italic") + _ ; Italic * attribute
    DllStructGetData($lvLOGFONT, "Underline") + _ ; Underline * attribute
    DllStructGetData($lvLOGFONT, "StrikeOut"), _ ; StrikeOut * attribute
    DllStructGetData($lvLOGFONT, "FaceName"), _ ; FaceName * fontname
    DllStructGetData($lvLOGFONT, "Quality")] ; Quality * quality
    Return $aOut
    EndFunc ;==>_SysGetFont2

    [/autoit]

    Edit: Ach shit, C&P sollte man schon beherschen. Quellcode angepaßt.

    Edit2: Hab auch noch eine Funktion von Prog@ndy dazu gefunden :

    Spoiler anzeigen
    [autoit]

    Func _GUICtrlGetFont1($hWnd=-1)
    ; Author: Prog@ndy
    Local $hFONT
    Switch IsHWnd($hWnd)
    Case True
    $hFONT = _SendMessage($hWnd, $WM_GETFONT)
    Case Else
    $hFONT = GUICtrlSendMsg($hWnd, $WM_GETFONT,0,0)
    $hWnd = GUICtrlGetHandle($hWnd)
    EndSwitch
    If Not $hFONT Then Return SetError(1,0,0)
    Local $tFONT = DllStructCreate($tagLOGFONT)
    Local $aReturn = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFONT, 'int', DllStructGetSize($tFONT), 'ptr', DllStructGetPtr($tFONT))
    If @error Or $aReturn[0] = 0 Then Return SetError(2,0,0)
    Local $hDC = _WinAPI_GetDC($hWnd)
    Local $PointSize = -1*_WinAPI_MulDiv(DllStructGetData($tFONT,'Height'), 72, _WinAPI_GetDeviceCaps($hDC, 90)) ; $LOGPIXELSY
    _WinAPI_ReleaseDC($hWnd, $hDC)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aReturn[5] = [$PointSize, DllStructGetData($tFONT, 'Weight'), _
    2*(True = DllStructGetData($tFONT, 'Italic')) + 4*(True = DllStructGetData($tFONT, 'Underline')) + 8*(True = DllStructGetData($tFONT, 'StrikeOut')) , _
    DllStructGetData($tFONT, 'FaceName'), DllStructGetData($tFONT, 'Quality')]
    Return $aReturn
    EndFunc

    [/autoit]

    Scheinbar ignoriert Autoit Bruchzahlen bei Controls wie 8.5 und macht 8 daraus.
    Oder schaust du hier im Thread Schriftart von Labels bekommen

    • Offizieller Beitrag

    Ich verstehe dein Problem jetzt nicht. Bei meinem Script wird das 2. Label richtig gesetzt.
    In deinem Ursprungsscript ist schon der Wurm drin bei dem Fontnamen, da wird bei mir Segeo UI angezeigt, was der falsche Font ist.
    Schon nach dem Start des Scripts ohne eine Änderung wird beim klicken von Setze Font das Label2 verfälscht.


    Hier mal die Ausgabe von meinem Script, erst auf 14 Pt und dann auf 8.5 Pt zurück:
    autoit.de/wcf/attachment/25151/
    autoit.de/wcf/attachment/25152/

    Für mich sind nach dem Rückstellen auf 8,5 beide Label identisch ;)
    Hier die Ausgabe deines Scriptes:
    autoit.de/wcf/attachment/25153/
    autoit.de/wcf/attachment/25154/
    Man sieht sofort das da was nicht richtig läuft. Der Font ist schon falsch

    • Offizieller Beitrag

    Mit deiner Funktion wird bei mir kein FontName ausgelesen (Leerstring) und somit wird wieder auf den OS-Font 'Segeo UI' zurückgegriffen.
    Ich hatte diese UDF auch schon in einem Thread entdeckt - und da war auch der Hinweis, dass die Funktion ausschliesslich für Ctrl funktioniert, denen mit GuiCtrlSetFont Werte zugewiesen worden. (Was sie somit eigentlich überflüssig macht).

    • Offizieller Beitrag

    Muß ich jetzt nicht verstehen. Bei mir wird immer der Richtige Fontnamen zurückgegeben.

    Autoit 3.3.12.0 Windows Ultimate 64 SP1 . Script als x86 oder x64 funzt beides

    Nochmal das Script, damit ich ein falsches c&p ausschließen kann:

    Spoiler anzeigen
    [autoit]

    #include <GuiConstants.au3>
    #include <GuiSlider.au3>
    $hGui = GUICreate('Test')
    $Label_1 = GUICtrlCreateLabel('Label-1', 20, 20, 80)
    $hLabel = GUICtrlGetHandle($Label_1)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $Label_2 = GUICtrlCreateLabel('Label-2', 20, 45, 80)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $sFontName = _CtrlGetFont($Label_2)[3]
    GUICtrlCreateLabel('System Font: ' & $sFontName, 20, 70, 180, 20)
    GUICtrlCreateLabel('Setze Font für Label-2: System, Size vom Slider', 20, 100)
    $slider = GUICtrlCreateSlider(20, 120, 200, 20, $TBS_AUTOTICKS)
    GUICtrlSetLimit(-1, 28, 12)
    _GUICtrlSlider_SetPos($slider, 17)
    $lblSize = GUICtrlCreateLabel(GUICtrlRead($slider) / 2, 230, 123, 30)
    $btSetFont = GUICtrlCreateButton('Setze Font', 20, 160, 60, 22)
    GUISetState()
    While True
    Switch GUIGetMsg()
    Case -3
    Exit
    Case $btSetFont
    GUICtrlSetFont($Label_2, GUICtrlRead($slider) / 2, 400, 0, $sFontName)
    Case $slider
    GUICtrlSetData($lblSize, GUICtrlRead($slider) / 2)
    EndSwitch
    WEnd
    ;===============================================================================
    ; Function Name....: _SysGetFont()
    ; Description......: Gets from Source the system settings for the font parameters
    ; Parameter(s).....: $iFontSource 0='Titlebar' (default), 1='Palette', 2='Menu', 3='ToolTip', 4='MessageBox'
    ; Return Value(s)..: [size, weight, attributes, fontname, quality]
    ; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
    ;===============================================================================
    ;~ Func _SysGetFont($iFontSource=0)
    ;~ Local $tNONCLIENTMETRICS = DllStructCreate('struct; uint cbSize;int iBorderWidth;int iScrollWidth;' & _
    ;~ 'int iScrollHeight;int iCaptionWidth;int iCaptionHeight;byte lfCaptionFont[60];int iSMCaptionWidth;' & _
    ;~ 'int iSMCaptionHeight;byte lfSMCaptionFont[60];int iMenuWidth;int iMenuHeight;byte lfMenuFont[60];' & _
    ;~ 'byte lfStatusFont[60];byte lfMessageFont[60];int iPaddedBorderWidth;endstruct')
    ;~ DllStructSetData($tNONCLIENTMETRICS, 'cbSize', DllStructGetSize($tNONCLIENTMETRICS))
    ;~ DllCall('user32', 'int', 'SystemParametersInfoA', 'int', 41, 'int', DllStructGetSize($tNONCLIENTMETRICS), _
    ;~ 'ptr', DllStructGetPtr($tNONCLIENTMETRICS), 'int', 0)
    ;~ Local $tagLF = 'struct;long;long;long;long;long;byte;byte;byte;byte;byte;byte;byte;byte;char[32];endstruct'
    ;~ Local $aFontSource[5] = ['lfCaptionFont','lfSMCaptionFont','lfMenuFont','lfStatusFont','lfMessageFont']
    ;~ Local $tLogFont = DllStructCreate($tagLF, DllStructGetPtr($tNONCLIENTMETRICS, $aFontSource[$iFontSource]))
    ;~ Local $aOut[5] = [ _
    ;~ Abs(DllStructGetData($tLogFont, 1))*0.7, _ ; Height * size
    ;~ DllStructGetData($tLogFont, 5), _ ; Weight * weight
    ;~ DllStructGetData($tLogFont, 6) + _ ; Italic * attribute
    ;~ DllStructGetData($tLogFont, 7) + _ ; Underline * attribute
    ;~ DllStructGetData($tLogFont, 8), _ ; StrikeOut * attribute
    ;~ DllStructGetData($tLogFont, 14), _ ; FaceName * fontname
    ;~ DllStructGetData($tLogFont, 12)] ; Quality * quality
    ;~ Return $aOut
    ;~ EndFunc ;==>_SysGetFont
    Func _CtrlGetFont($hwnd); Original by KaFu mod by Raupi
    If Not HWnd($hwnd) Then $hwnd = GUICtrlGetHandle($hwnd)
    Local $hDC = _WinAPI_GetDC($hwnd)
    Local $hFont = _SendMessage($hwnd, $WM_GETFONT)
    Local $hObject = _WinAPI_SelectObject($hDC, $hFont)
    Local $lvLOGFONT = DllStructCreate($tagLOGFONT)
    Local $aRet = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFont, 'int', DllStructGetSize($lvLOGFONT), 'ptr', DllStructGetPtr($lvLOGFONT))
    _WinAPI_SelectObject($hDC, $hObject)
    _WinAPI_ReleaseDC($hwnd, $hDC)
    Local $aOut[5] = [ _
    Round(ABS(DllStructGetData($lvLOGFONT, "Height"))*0.776,1), _ ; Height * size
    DllStructGetData($lvLOGFONT, "Weight"), _ ; Weight * weight
    DllStructGetData($lvLOGFONT, "Italic") + _ ; Italic * attribute
    DllStructGetData($lvLOGFONT, "Underline") + _ ; Underline * attribute
    DllStructGetData($lvLOGFONT, "StrikeOut"), _ ; StrikeOut * attribute
    DllStructGetData($lvLOGFONT, "FaceName"), _ ; FaceName * fontname
    DllStructGetData($lvLOGFONT, "Quality")] ; Quality * quality
    Return $aOut
    EndFunc ;==>_SysGetFont2

    [/autoit]
    • Offizieller Beitrag

    np