Schriftart von Labels bekommen

  • Guten Morgen,

    kann mir jemand helfen. Unzwar wie bekomme ich raus welche Schriftart und Größe ein Label hat? Praktisch das Gegenteil von GUICtrlSetFont.

    Einmal editiert, zuletzt von m-obi (23. Januar 2010 um 20:02)

  • Ich habe auch keine Funktion dazu gefunden, aber du könntest doch die aktuelle Schriftart in einer Ini speichern, wenn sie geändert wird...

    Spoiler anzeigen

    Grundkenntnisse in: C++, JavaScript
    Sehr gute Kenntnisse: PHP, JAVA, C und näturlich AutoIt


    Klaviatur, Anhang UDF, GDI+ Mühle

    Zitat

    "Wenn einen um 20h der Pizzadienst anruft und fragt, ob man's nur vergessen hat und ob man das gleiche
    möchte wie immer -- dann sollte man sein Bestellverhalten evtl überdenken"

    • Offizieller Beitrag

    Edit:
    Für ein einzelnes Control habe ich keine Lösung parat, da die einzig mir bekannte Funktion (GetTextFace) seltsamerweise immer 'SYSTEM' zurückgibt. :S (k.A. wo der Fehler liegt.
    Vielleicht hilft dir das als Ansatz:

    [autoit]

    #Include <WinAPI.au3>

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

    ; === Test-GUI
    $gui = GUICreate('test')
    $label = GUICtrlCreateLabel('test', 10, 10, 60, 17)
    $hWnd = GUICtrlGetHandle($label)
    GUICtrlSetFont(-1, Default, Default, Default, 'Courier New')

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

    ; === Device Context erstellen
    Local $hDC = _WinAPI_GetDC($hWnd)

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

    ; === Font auslesen
    MsgBox(0, 'Font Name', GetTextFace($hDC) )

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

    ; === Ressourcen löschen
    _WinAPI_ReleaseDC($hWnd, $hDC)
    GUIDelete($gui)

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

    Func GetTextFace($hdc)
    Local $tFaceName = DllStructCreate('char[128]')
    DllCall('gdi32.dll', 'int', 'GetTextFace', 'int', $hdc, 'int', 128, 'ptr', DllStructGetPtr($tFaceName))
    Return DllStructGetData($tFaceName, 1)
    EndFunc

    [/autoit]
  • Hatte MSDN auch schon durchforstet zum Thema Fonts, aber nix passendes gefunden. Aber es muss doch sowas geben, wenn man einen Font Seten kann, muss man ihn auch Geten können.

  • Bitteschön, eine Funktion um die Schrift eines Labels zu bekommen. Die Reihenfolge der Rückgabeparemter ist gleich wie bei GUICtrlSetFont

    Spoiler anzeigen
    [autoit]

    #include-once
    #include<WindowsConstants.au3>
    #include<WinAPI.au3>

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GUICtrlGetFont
    ; Description ...: gets the font of a GUI Control
    ; Syntax.........: _GUICtrlGetFont( [$hWnd] )
    ; Parameters ....: $hWnd - [optional] ControlID or Handle of the control. Default is last created GUICtrl... (-1)
    ; Return values .: Success - Array with options of font:
    ; [0] - Fontsize
    ; [1] - Font weight (400 = normal).
    ; [2] - italic:2 underlined:4 strike:8 char format (styles added together, 2+4 = italic and underlined).
    ; [3] - The name of the font to use.
    ; [4] - Font quality to select (PROOF_QUALITY=2 is default in AutoIt).
    ; Failure - 0, @error set to nonzero
    ; Author ........: Prog@ndy
    ; Modified.......:
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func _GUICtrlGetFont($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)

    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] [autoit][/autoit] [autoit]

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

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

    #include<Array.au3>
    GUICreate("bla")
    $label = GUICtrlCreateLabel("test", 10, 10, 100, 100)
    GUISetState()

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

    $font = _GUICtrlGetFont($label)
    _ArrayDisplay($font)

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

    GUICtrlSetFont($label, 24, 600, 4, "Arial")

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

    $font = _GUICtrlGetFont($label)
    _ArrayDisplay($font)

    [/autoit]
  • Ach progandy du bist ein Schatz, genau das wollte ich haben :D . Ich werde dich in meinem Script berücksichtigen.

  • HalliHallo :)

    diese Frage bezieht sich genau auf das Problem, welches ich gerade versuche im Englischen Forum zu lösen. Die hervorragende Extended Message Box UDF von Melba23 funktioniert tadellos unter Vista und Win7. Unter XP bekomme ich es aber nicht hin, den Default Font auszulesen. Woran liegt das? Ich denke genau an der Art und Weise wie ProgAndy oben in seiner Funktion die $PointSize berechnet. Die Funktion _WinAPI_MulDiv() gibt nur ganze Zahlen zurück, Fonts erlauben aber auch eine dezimale Größenangabe, und unter XP ist der Default Font (auf meinem Rechner) Tahoma/8.5...

    Spoiler anzeigen
    [autoit]


    #include-once
    #include<WindowsConstants.au3>
    #include<WinAPI.au3>

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

    ; http://www.autoit.de/index.php?page…4016#post134016
    ; ProgAndy

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GUICtrlGetFont
    ; Description ...: gets the font of a GUI Control
    ; Syntax.........: _GUICtrlGetFont( [$hWnd] )
    ; Parameters ....: $hWnd - [optional] ControlID or Handle of the control. Default is last created GUICtrl... (-1)
    ; Return values .: Success - Array with options of font:
    ; [0] - Fontsize
    ; [1] - Font weight (400 = normal).
    ; [2] - italic:2 underlined:4 strike:8 char format (styles added together, 2+4 = italic and underlined).
    ; [3] - The name of the font to use.
    ; [4] - Font quality to select (PROOF_QUALITY=2 is default in AutoIt).
    ; Failure - 0, @error set to nonzero
    ; Author ........: Prog@ndy
    ; Modified.......:
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func _GUICtrlGetFont($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)
    ConsoleWrite(DllStructGetData($tFONT, 'Height') & @crlf)
    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 ;==>_GUICtrlGetFont

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

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

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

    #include<Array.au3>
    GUICreate("bla")

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

    GUICtrlCreateLabel("test", 10, 10, 100, 100)

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

    $label = GUICtrlCreateLabel("test", 10, 50, 100, 100)
    GUICtrlSetFont($label, 8)

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

    GUISetState()

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

    $font = _GUICtrlGetFont($label)
    _ArrayDisplay($font)

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

    GUICtrlSetFont($label, 8.5)
    $font = _GUICtrlGetFont($label)
    _ArrayDisplay($font)

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

    GUICtrlSetFont($label, 10.5)
    $font = _GUICtrlGetFont($label)
    _ArrayDisplay($font)

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

    GUICtrlSetFont($label, 11)
    $font = _GUICtrlGetFont($label)
    _ArrayDisplay($font)

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

    GUICtrlSetFont($label, 11.5)
    $font = _GUICtrlGetFont($label)
    _ArrayDisplay($font)

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

    ConsoleWrite(_WinAPI_MulDiv(Abs(-10), 72, 96) & @crlf)
    ConsoleWrite(_WinAPI_MulDiv(Abs(-11), 72, 96) & @crlf)

    [/autoit]

    Ich hab mich schon durch MSDN gewühlt und bin dann bei einer ähnlichen Lösung wie oben dargestellt stecken geblieben.
    http://msdn.microsoft.com/en-us/library/ms901140.aspx

    Ich befürchte die Antwort liegt in diesem Satz versteckt: "The font mapper transforms this value into device units and matches its absolute value against the character height of the available fonts."

    GUICtrlSetFont($label, 8, 400, 0, "Tahoma") sieht eindeutig anders aus wie
    GUICtrlSetFont($label, 8.5, 400, 0, "Tahoma")

    Der Rückgabewert von LOGFONT für den ersten Fall ist -10, für den zweiten Fall -11... wobei gilt:
    _WinAPI_MulDiv(Abs(-10), 72, 96) = 8
    _WinAPI_MulDiv(Abs(-11), 72, 96) = 8

    Hat vielleicht jemand eine schlaue Idee dazu 8|?( :wacko: ;( ?

    Gruß

  • Was für ein biestiges Biest dieser Font-Mapper :pinch: ...
    Hab mal ein bisschen (sehr viel) an der Funktion von ProgAndy rumgeschraubt. Die unten angehängte Lösung "scheint" auf XP in allen Fällen zu funktionieren... mag die mal jemand durch sein Vista oder Win7 drücken?

    Edit: Ich habe nochmal ein consolewrite() in die Funktion eingebaut. Schaut euch mal an, was die GUI macht wenn der Font nicht explizit benannt wird... er sucht sich einen basierend auf der gewünschten Größe aus!... ts, ich sag nur Font-Mapper! Kein Wunder, hier steht die Beschreibung auf MSDN, schaut mal auf das Datum des Artikels...

    Tatsächlich ist die ermittelte FontSize nicht die ursprüngliche FontSize! Sondern ein Wert aus dem der Font-Mapper dann per GuiCtrlSetFont() denselben Font erzeugt wie der ausgelesene. Mir scheint es so, als wenn beim Erzeugen des Fonts der Font-Mapper intern ein paar (nicht ohne weiteres nachvollziehbare) Entscheidungen basierend auf dem Input und den Eigenschaften des gewünschten Fonts trifft und darauf basierend dann den Output generiert.

    Spoiler anzeigen
    [autoit]

    #include<WinAPI.au3>
    #include<WindowsConstants.au3>

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GUICtrlGetFont
    ; Description ...: Gets the font of a GUI Control
    ; Syntax.........: _GUICtrlGetFont( [$hWnd] )
    ; Parameters ....: $hWnd - [optional] ControlID or Handle of the control. Default is last created GUICtrl... (-1)
    ; Return values .: Success - Array with options of font:
    ; [0] - Fontsize
    ; [1] - Font weight (400 = normal).
    ; [2] - italic:2 underlined:4 strike:8 char format (styles added together, 2+4 = italic and underlined).
    ; [3] - The name of the font to use.
    ; [4] - Font quality to select (PROOF_QUALITY=2 is default in AutoIt).
    ; Failure - Array with options of font => EMPTY, @error set to nonzero
    ; Author ........: Prog@ndy
    ; Modified.......: KaFu
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func _GUICtrlGetFont($hWnd = -1)
    ; Author: Prog@ndy & KaFu
    Local $aReturn[5], $hObjOrg

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

    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, $aReturn)

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

    Local $hFONT = _SendMessage($hWnd, $WM_GETFONT)
    If Not $hFONT Then Return SetError(2, 0, $aReturn)

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

    Local $hDC = _WinAPI_GetDC($hWnd)
    $hObjOrg = _WinAPI_SelectObject($hDC, $hFONT)
    Local $tFONT = DllStructCreate($tagLOGFONT)
    Local $aRet = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFONT, 'int', DllStructGetSize($tFONT), 'ptr', DllStructGetPtr($tFONT))
    If @error Or $aRet[0] = 0 Then
    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return SetError(3, 0, $aReturn)
    EndIf

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

    ; Needed to extract FontFacename => DllStructGetData($tFONT, 'FaceName') is only valid if FontFacename has been set explicitly!
    $aRet = DllCall("gdi32.dll", "int", "GetTextFaceW", "handle", $hDC, "int", 0, "ptr", 0)
    Local $nCount = $aRet[0]
    Local $tBuffer = DllStructCreate("wchar[" & $aRet[0] & "]")
    Local $pBuffer = DllStructGetPtr($tBuffer)
    $aRet = DllCall("Gdi32.dll", "int", "GetTextFaceW", "handle", $hDC, "int", $nCount, "ptr", $pBuffer)
    If @error Then
    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return SetError(4, 0, $aReturn)
    EndIf
    ; FontFacename
    $aReturn[3] = DllStructGetData($tBuffer, 1)
    ConsoleWrite($aReturn[3] & @TAB & @TAB & DllStructGetData($tFONT, 'FaceName') & @CRLF)

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

    ; FontSize
    $aReturn[0] = Round(-1 * DllStructGetData($tFONT, 'Height') * 72 / _WinAPI_GetDeviceCaps($hDC, 90) + 0.1, 2) ; $LOGPIXELSY = 90 => DPI aware

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

    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)

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

    $aReturn[1] = DllStructGetData($tFONT, 'Weight')
    $aReturn[2] = 2 * (True = DllStructGetData($tFONT, 'Italic')) + 4 * (True = DllStructGetData($tFONT, 'Underline')) + 8 * (True = DllStructGetData($tFONT, 'StrikeOut'))
    $aReturn[4] = DllStructGetData($tFONT, 'Quality')

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

    Return $aReturn

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

    EndFunc ;==>_GUICtrlGetFont

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

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

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

    #Region TestGUI

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

    HotKeySet("{ESC}", "_Exit")
    Func _Exit()
    Exit
    EndFunc ;==>_Exit

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

    GUICreate("GetFont TestGUI", 600, 110)
    $label_ref = GUICtrlCreateLabel("The quick brown fox jumps over the lazy dog", 10, 10, 580, 50)
    $label_test = GUICtrlCreateLabel("The quick brown fox jumps over the lazy dog", 10, 60, 580, 50)
    GUISetState()

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

    $sFontname = ""
    For $iFontSize_Test = 6 To 14 Step 0.1
    GUICtrlSetFont($label_ref, $iFontSize_Test, 600, 0, $sFontname, 5)
    $font = _GUICtrlGetFont(GUICtrlGetHandle($label_ref))
    GUICtrlSetFont($label_test, $font[0], $font[1], $font[2], $font[3], $font[4])
    ConsoleWrite(Round($iFontSize_Test, 2) & @TAB & $font[0] & @CRLF)
    Sleep(50)
    Next

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

    $sFontname = "Tahoma"
    For $iFontSize_Test = 6 To 14 Step 0.1
    GUICtrlSetFont($label_ref, $iFontSize_Test, 600, 10, $sFontname, 5)
    $font = _GUICtrlGetFont(GUICtrlGetHandle($label_ref))
    GUICtrlSetFont($label_test, $font[0], $font[1], $font[2], $font[3], $font[4])
    Sleep(100)
    Next

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

    $sFontname = "Arial"
    For $iFontSize_Test = 6 To 14 Step 0.1
    GUICtrlSetFont($label_ref, $iFontSize_Test, 400, 0, $sFontname)
    $font = _GUICtrlGetFont(GUICtrlGetHandle($label_ref))
    GUICtrlSetFont($label_test, $font[0], $font[1], $font[2], $font[3], $font[4])
    Sleep(100)
    Next

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

    #EndRegion TestGUI

    [/autoit]

    6 Mal editiert, zuletzt von KaFu (21. Januar 2011 um 14:23)

    • Offizieller Beitrag

    Servus KaFu.

    Habe dein Testscript mal unter Win7 Ulimate 64 laufen lassen.
    Consolenausgabe:

    Spoiler anzeigen


    Die beiden Schriften im Kontrollfenster sind Teilweise unterschiedlich Hoch und Breit.
    Das selbe auch unter WinXP Pro Sp3.

  • Raupi, danke fürs Checken :)! Ich denke, da war was in der Berechnung noch nicht ganz richtig. Wie gesagt, ich glaube nicht, dass man überhaupt eine Punktlandung hinlegen kann, es wird nur ein Näherungswert ermittelt. Lass dass hier doch bitte nochmal laufen, funktioniert bei mir auf meinem XP Notebook und auch auf Win7.

    Spoiler anzeigen
    [autoit]

    #include<WinAPI.au3>
    #include<WindowsConstants.au3>

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

    Global Const $tagTEXTMETRIC = "long tmHeight;long tmAscent;long tmDescent;long tmInternalLeading;long tmExternalLeading;" & _
    "long tmAveCharWidth;long tmMaxCharWidth;long tmWeight;long tmOverhang;long tmDigitizedAspectX;long tmDigitizedAspectY;" & _
    "wchar tmFirstChar;wchar tmLastChar;wchar tmDefaultChar;wchar tmBreakChar;byte tmItalic;byte tmUnderlined;byte tmStruckOut;" & _
    "byte tmPitchAndFamily;byte tmCharSet"

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GUICtrlGetFont
    ; Description ...: Gets the font of a GUI Control
    ; Syntax.........: _GUICtrlGetFont( [$hWnd] )
    ; Parameters ....: $hWnd - [optional] ControlID or Handle of the control. Default is last created GUICtrl... (-1)
    ; Return values .: Success - Array with options of font:
    ; [0] - Fontsize
    ; [1] - Font weight (400 = normal).
    ; [2] - italic:2 underlined:4 strike:8 char format (styles added together, 2+4 = italic and underlined).
    ; [3] - The name of the font to use.
    ; [4] - Font quality to select (PROOF_QUALITY=2 is default in AutoIt).
    ; Failure - Array with options of font => EMPTY, @error set to nonzero
    ; Author ........: Prog@ndy
    ; Modified.......: KaFu
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func _GUICtrlGetFont($hWnd = -1)
    ; Author: Prog@ndy & KaFu
    Local $aReturn[5], $hObjOrg

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

    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, $aReturn)

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

    Local $hFONT = _SendMessage($hWnd, $WM_GETFONT)
    If Not $hFONT Then Return SetError(2, 0, $aReturn)

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

    Local $hDC = _WinAPI_GetDC($hWnd)
    $hObjOrg = _WinAPI_SelectObject($hDC, $hFONT)
    Local $tFONT = DllStructCreate($tagLOGFONT)
    Local $aRet = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFONT, 'int', DllStructGetSize($tFONT), 'ptr', DllStructGetPtr($tFONT))
    If @error Or $aRet[0] = 0 Then
    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return SetError(3, 0, $aReturn)
    EndIf

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

    Local $tTEXTMETRIC = _GetTextMetrics($hDC)

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

    ; Needed to extract FontFacename => DllStructGetData($tFONT, 'FaceName') is only valid if FontFacename has been set explicitly!
    $aRet = DllCall("gdi32.dll", "int", "GetTextFaceW", "handle", $hDC, "int", 0, "ptr", 0)
    Local $nCount = $aRet[0]
    Local $tBuffer = DllStructCreate("wchar[" & $aRet[0] & "]")
    Local $pBuffer = DllStructGetPtr($tBuffer)
    $aRet = DllCall("Gdi32.dll", "int", "GetTextFaceW", "handle", $hDC, "int", $nCount, "ptr", $pBuffer)
    If @error Then
    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return SetError(4, 0, $aReturn)
    EndIf
    ; FontFacename
    $aReturn[3] = DllStructGetData($tBuffer, 1)
    ConsoleWrite($aReturn[3] & @TAB & @TAB & DllStructGetData($tFONT, 'FaceName') & @CRLF)

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

    $aReturn[0] = Round(((-1 * DllStructGetData($tFONT, 'Height')) * 72 / _WinAPI_GetDeviceCaps($hDC, 90)) + 0.25, 2) ; $LOGPIXELSY = 90 => DPI aware

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

    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)

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

    $aReturn[1] = DllStructGetData($tFONT, 'Weight')
    $aReturn[2] = 2 * (True = DllStructGetData($tFONT, 'Italic')) + 4 * (True = DllStructGetData($tFONT, 'Underline')) + 8 * (True = DllStructGetData($tFONT, 'StrikeOut'))
    $aReturn[4] = DllStructGetData($tFONT, 'Quality')

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

    Return $aReturn

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

    EndFunc ;==>_GUICtrlGetFont

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

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

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

    Func _GetTextMetrics($hDC)
    Local $aRet, $tBuffer, $pBuffer
    $tBuffer = DllStructCreate($tagTEXTMETRIC)
    $pBuffer = DllStructGetPtr($tBuffer)
    DllCall("Gdi32.dll", "bool", "GetTextMetricsW", "handle", $hDC, "ptr", $pBuffer)
    If @error Then Return SetError(@error, @extended, 0)
    Return $tBuffer
    EndFunc ;==>_GetTextMetrics

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

    #Region TestGUI

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

    HotKeySet("{ESC}", "_Exit")
    Func _Exit()
    Exit
    EndFunc ;==>_Exit

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

    GUICreate("GetFont TestGUI", 600, 110)
    $label_ref = GUICtrlCreateLabel("The quick brown fox jumps over the lazy dog", 10, 10, 580, 50)
    $label_test = GUICtrlCreateLabel("The quick brown fox jumps over the lazy dog", 10, 60, 580, 50)
    GUISetState()

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

    $sFontname = ""
    For $iFontSize_Test = 6 To 14 Step 0.1
    GUICtrlSetFont($label_ref, $iFontSize_Test, 600, 0, $sFontname, 5)
    $font = _GUICtrlGetFont(GUICtrlGetHandle($label_ref))
    GUICtrlSetFont($label_test, $font[0], $font[1], $font[2], $font[3], $font[4])
    ConsoleWrite(Round($iFontSize_Test, 2) & @TAB & $font[0] & @CRLF)
    Sleep(50)
    Next

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

    $sFontname = "Tahoma"
    For $iFontSize_Test = 6 To 14 Step 0.1
    GUICtrlSetFont($label_ref, $iFontSize_Test, 600, 10, $sFontname, 5)
    $font = _GUICtrlGetFont(GUICtrlGetHandle($label_ref))
    GUICtrlSetFont($label_test, $font[0], $font[1], $font[2], $font[3], $font[4])
    Sleep(100)
    Next

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

    $sFontname = "Arial"
    For $iFontSize_Test = 6 To 14 Step 0.1
    GUICtrlSetFont($label_ref, $iFontSize_Test, 400, 0, $sFontname)
    $font = _GUICtrlGetFont(GUICtrlGetHandle($label_ref))
    GUICtrlSetFont($label_test, $font[0], $font[1], $font[2], $font[3], $font[4])
    Sleep(100)
    Next

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

    #EndRegion TestGUI

    [/autoit]
    • Offizieller Beitrag

    Schriftgrößen sind immer noch unterschiedlich 8|

    Spoiler anzeigen

    Edit: Bei kleinen Schriftgrößen fällt der Unterschied nicht so auf.

    • Offizieller Beitrag

    Hi,Kafu.

    Hab den Sleep mal auf 250 gesetzt.

    Deine Funktion klappt 100% ig, hab es sogar mit einem Lineal nachgemessen.
    Keien Ahnung warum es vorher so unterschiedlich war, vielleichst hab ich nen Knick in der Optik 8|

    • Offizieller Beitrag

    Kein Problem.

    Jetz hab ich eine neue Funktion für meine Sammlung ;):thumbup:

    Haddu gud gemacht. 8o:rock: :D

  • Hab die angehübschte Funktion hier im internationalen Forum gepostet (größerer Kundenkreis ;) ).

    Hier nochmal mein finaler Code inklusive beispielhafter Iteration aller Fonts auf eurem System (dafür wird die WinApiEx UDF von Yashied benötigt).

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <WindowsConstants.au3>

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GUICtrlGetFont
    ; Description ...: Gets the font of a GUI Control
    ; Syntax.........: _GUICtrlGetFont( [$hWnd] )
    ; Parameters ....: $hWnd - [optional] ControlID or Handle of the control. Default is last created GUICtrl... (-1)
    ;
    ; Return values .: Success - Array[5] with options of font:
    ; [0] - FontSize (~ approximation)
    ; [1] - Font weight (400 = normal).
    ; [2] - italic:2 underlined:4 strike:8 char format (styles added together, 2+4 = italic and underlined).
    ; [3] - The name of the font to use.
    ; [4] - Font quality to select (PROOF_QUALITY=2 is default in AutoIt).
    ;
    ; Failure - Array[5] with empty fields, @error set to nonzero
    ;
    ; Author ........: KaFu, Prog@ndy
    ;
    ; Comments.......: The FontSize returned is an approximation of the actual fontsize used for the control.
    ; The height of the font returned by GetObject is the height of the font's character cell or character in logical units.
    ; The character height value (also known as the em height) is the character cell height value minus the internal-leading value.
    ; The font mapper interprets the value specified in lfHeight. The result returned by the font mapper is not easily reversible
    ; The FontSize calculated below is an approximation of the actual size used for the analyzed control, qualified enough to use
    ; in another call to the font mapper resulting in the same font size as the the original font.
    ; MSDN.. ........: Windows Font Mapping: http://msdn.microsoft.com/en-us/library/…09(loband).aspx
    ; ===============================================================================================================================
    Func _GUICtrlGetFont($hWnd = -1)
    Local $aReturn[5], $hObjOrg

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

    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, $aReturn)

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

    Local $hFONT = _SendMessage($hWnd, $WM_GETFONT)
    If Not $hFONT Then Return SetError(2, 0, $aReturn)

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

    Local $hDC = _WinAPI_GetDC($hWnd)
    $hObjOrg = _WinAPI_SelectObject($hDC, $hFONT)
    Local $tFONT = DllStructCreate($tagLOGFONT)
    Local $aRet = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFONT, 'int', DllStructGetSize($tFONT), 'ptr', DllStructGetPtr($tFONT))
    If @error Or $aRet[0] = 0 Then
    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return SetError(3, 0, $aReturn)
    EndIf

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

    ; Need to extract FontFacename separately => DllStructGetData($tFONT, 'FaceName') is only valid if FontFacename has been set explicitly!
    $aRet = DllCall("gdi32.dll", "int", "GetTextFaceW", "handle", $hDC, "int", 0, "ptr", 0)
    Local $nCount = $aRet[0]
    Local $tBuffer = DllStructCreate("wchar[" & $aRet[0] & "]")
    Local $pBuffer = DllStructGetPtr($tBuffer)
    $aRet = DllCall("Gdi32.dll", "int", "GetTextFaceW", "handle", $hDC, "int", $nCount, "ptr", $pBuffer)
    If @error Then
    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return SetError(4, 0, $aReturn)
    EndIf
    $aReturn[3] = DllStructGetData($tBuffer, 1) ; FontFacename

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

    $aReturn[0] = Round(((-1 * DllStructGetData($tFONT, 'Height')) * 72 / _WinAPI_GetDeviceCaps($hDC, 90)) + 0.25, 2) ; $LOGPIXELSY = 90 => DPI aware ; 0.25 = Magic Number, don't ask...

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

    _WinAPI_SelectObject($hDC, $hObjOrg)
    _WinAPI_ReleaseDC($hWnd, $hDC)

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

    $aReturn[1] = DllStructGetData($tFONT, 'Weight')
    $aReturn[2] = 2 * (True = DllStructGetData($tFONT, 'Italic')) + 4 * (True = DllStructGetData($tFONT, 'Underline')) + 8 * (True = DllStructGetData($tFONT, 'StrikeOut'))
    $aReturn[4] = DllStructGetData($tFONT, 'Quality')

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

    Return $aReturn

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

    EndFunc ;==>_GUICtrlGetFont
    ;-----------------------------------------------------------------

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

    #region _GUICtrlGetFont - Test GUI

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

    #include <Array.au3>
    #include <File.au3>
    #include <GUIConstantsEx.au3>
    #include <WinAPIEx.au3>

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

    Global $FileList = _FileListToArray(_WinAPI_ShellGetSpecialFolderPath($CSIDL_FONTS), '*.ttf', 1)
    Global $FontList[UBound($FileList) - 1][2]

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

    For $i = 1 To $FileList[0]
    $FontList[$i - 1][0] = $FileList[$i]
    $FontList[$i - 1][1] = _WinAPI_GetFontResourceInfo($FileList[$i], 1)
    Next

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

    Opt("GUIOnEventMode", 1)
    Opt("GUICloseOnESC", 0)

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

    $hGUI = GUICreate("_GUICtrlGetFont", 1000, 200)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

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

    $c_Label_Reference = GUICtrlCreateLabel("The quick brown fox jumps over the lazy dog", 10, 10, 980, 90)
    $c_Label_Clone = GUICtrlCreateLabel("The quick brown fox jumps over the lazy dog", 10, 100, 980, 90)

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

    GUISetState()

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

    $sErrors = ""

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

    Global $aFontAttributtes[8] = [0, 2, 4, 6, 8, 10, 12, 14]
    For $iFontAttributte = 0 To UBound($aFontAttributtes) - 1
    For $iFontQuality = 0 To 5
    For $iFontWeight = 100 To 800 Step 100
    For $i = 0 To UBound($FontList) - 1
    $sFontname = $FontList[$i][1]
    $sFontfile = $FontList[$i][0]
    For $iFontSize = 2 To 48 Step 0.1
    $iFontSize = Round($iFontSize, 1)

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

    WinSetTitle($hGUI, "", "_GUICtrlGetFont - " & $sFontfile & " - " & $sFontname & " - " & $iFontSize & " - " & $iFontWeight & " - " & $aFontAttributtes[$iFontAttributte] & " - " & $sFontname & " - " & $iFontQuality)

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

    GUICtrlSetFont($c_Label_Reference, $iFontSize, $iFontWeight, $aFontAttributtes[$iFontAttributte], $sFontname, $iFontQuality)
    $aFont_Get = _GUICtrlGetFont($c_Label_Reference)
    GUICtrlSetFont($c_Label_Clone, $aFont_Get[0], $aFont_Get[1], $aFont_Get[2], $aFont_Get[3], $aFont_Get[4])

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

    $iFontSize_Reference = _GUICtrlGetFont_Height_EM($c_Label_Reference)
    $iFontSize_Clone = _GUICtrlGetFont_Height_EM($c_Label_Clone)
    If $iFontSize_Reference <> $iFontSize_Clone Then
    ConsoleWrite("! " & $iFontSize_Reference & @TAB & $iFontSize_Clone & @TAB & @TAB & @TAB & $iFontSize & @TAB & $iFontWeight & @TAB & $aFontAttributtes[$iFontAttributte] & @TAB & $sFontname & @TAB & $iFontQuality & @CRLF)
    $sErrors &= $iFontSize & @TAB & $iFontWeight & @TAB & $aFontAttributtes[$iFontAttributte] & @TAB & $sFontname & @TAB & $iFontQuality & @CRLF
    ClipPut($sErrors)
    MsgBox(48 + 262144, "_GUICtrlGetFont - ERROR", $iFontSize_Reference & @CRLF & $iFontSize_Clone & @CRLF & @CRLF & $iFontSize & @CRLF & $iFontWeight & @CRLF & $aFontAttributtes[$iFontAttributte] & @CRLF & $sFontname & @CRLF & $iFontQuality, 10, $hGUI)
    Else
    ;ConsoleWrite("+ " & $iFontSize_Reference & @TAB & $iFontSize_Clone & @TAB & @TAB & @TAB & $iFontSize & @TAB & $iFontWeight & @TAB & $aFontAttributtes[$iFontAttributte] & @TAB & $sFontname & @TAB & $iFontQuality & @CRLF)
    EndIf
    Next
    Next
    Next
    Next
    Next

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

    Func _GUICtrlGetFont_Height_EM($hWnd = -1)
    Local $hFONT
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)
    $hFONT = _SendMessage($hWnd, $WM_GETFONT)
    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)
    Return Abs(DllStructGetData($tFONT, 'Height'))
    EndFunc ;==>_GUICtrlGetFont_Height_EM

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

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

    #endregion _GUICtrlGetFont - Test GUI

    [/autoit]
  • Guten Abend,

    Windows arbeitet nicht mit stufenlosen Schriftgrößen und sind so auch die Aussagen im MSDN zum "font mapper" zu verstehen. Er sucht für eine vorgegebene Größe in Points die am besten passende vorhandene Größe. Wenn man die Fontgrößen in 0.1-Schritten variert, muss deshalb für unterschiedliche Eingangswerte ein identischer Wert zurückgeliefert werden. Und wenn für den Eingangswert 8.5 der Wert 8.3 zurückgegeben wird, ist das kein Beinbruch, denn der Wert 8.3 erzeugt eine Darstellung in identischer Größe.

    Wenn in den SetFont-Anweisungen kein Name vorgegeben wird, liefert Deine Funktion bei mir unter Vista immer den Namen "System", obwohl dieser "Notfallfont" offensichtlich nicht verwendet wird. Die Doku sagt dazu: "(OS default GUI font is used if the font is "" or is not found)." Ich habe deshalb eine andere Funktion eingebaut, um den fehlenden Fontnamen zu ermitteln, und mir scheint das Ergebnis plausibler. Schließlich habe ich als alter UDF-Vermeider das Ganze noch etwas eingedampft:

    Spoiler anzeigen
    [autoit]

    Func _GUICtrlGetFont($idCtrl)
    Local Const $DEFAULT_GUI_FONT = 17, $LF_FACESIZE = 32, $LOGPIXELSY = 90, $WM_GETFONT = 0x31
    Local $aFont[5] = [0, 0, 0, 0, 0]
    Local $FONT = GUICtrlSendMsg($idCtrl, $WM_GETFONT, 0, 0)
    Local $LOGFONT = DllStructCreate("LONG [5];BYTE [8];WCHAR[" & $LF_FACESIZE & "]")
    Local $DC = DllCall("User32.dll", "Handle", "GetDC", "HWND", GUICtrlGetHandle($idCtrl))
    Local $CDC = DllCall("Gdi32.dll", "Handle", "CreateCompatibleDC", "Handle", $DC[0])
    Local $PY = DllCall("Gdi32.dll", "Int", "GetDeviceCaps", "Handle", $CDC[0], "INT", $LOGPIXELSY)
    DllCall("Gdi32.dll", "BOOL", "DeleteDC", "Handle", $CDC[0])
    DllCall("User32.dll", "BOOL", "ReleaseDC", "HWND", GUICtrlGetHandle($idCtrl), "Handle", $DC[0])
    DllCall("Gdi32.dll", "INT", "GetObjectW", "Handle", $FONT, "INT", DllStructGetSize($LOGFONT), "Ptr", DllStructGetPtr($LOGFONT))
    $aFont[0] = Abs(Round(DllStructGetData($LOGFONT, 1, 1) / $PY[0] * 72, 1))
    $aFont[1] = DllStructGetData($LOGFONT, 1, 5)
    For $I = 1 To 3
    $aFont[2] += (DllStructGetData($LOGFONT, 2, $I) > 0) * (2 ^ $I)
    Next
    $aFont[3] = DllStructGetData($LOGFONT, 3)
    $aFont[4] = DllStructGetData($LOGFONT, 2, 7)
    If Not $aFont[3] Then
    $FONT = DllCall("Gdi32.dll", "Handle", "GetStockObject", "INT", $DEFAULT_GUI_FONT)
    DllCall("Gdi32.dll", "INT", "GetObjectW", "Handle", $FONT[0], "INT", DllStructGetSize($LOGFONT), "Ptr", DllStructGetPtr($LOGFONT))
    $aFont[3] = DllStructGetData($LOGFONT, 3)
    EndIf
    Return $aFont
    EndFunc

    [/autoit]


    P.S.: In den Stylebytes der LOGFONT-Struktur sind unter Vista als "True" die passenden Werte 2, 4 und 8 abgelegt, sodass man hier einfach den Inhalt der Bytes addieren könnte. Ich weiß allerdings nicht, ob das immer so war und bleiben wird, deshalb habe ich es nicht getan.

  • Hmm, merkwürdig :huh:, kann das mit den sich wechselnden Fonts auch gerade nicht nachstellen. Ich probiers morgen nochmal auf meinem Englischen XP Notebook. Ansonsten nettes Update, danke dir :thumbup: ...