Installierte Schriftarten + StringRegExpReplace

  • HeyHo,

    für mein aktuelles Projekt bräuchte ich eine Liste aller installierter Schriftarten.
    Mein Ansatz:

    [autoit]


    For $i=1 to 9999999
    $sFonts=RegEnumVal("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts",$i)
    IF @error <> 0 Then ExitLoop
    $sFonts2&=$sFonts
    Next
    $sFiltered=StringRegExpReplace($sFonts2,"((TrueType)|(Alle Auflösungen)|(VGA-Auflösung))","")
    $sFiltered=StringRegExpReplace($sFiltered,"[\(\)]",",")
    $sFiltered=StringReplace($sFiltered," ,,",",")
    MsgBox(0,"",$sFiltered)

    [/autoit]

    Meine Fragen:
    1.Gibt's da nicht ne einfachere Methode, z.B. eine UDF, um alle installierten Schriftarten auszulesen?
    2. Wie man sieht, hab ich StringRegExpReplace noch nicht so wirklich verstanden :whistling:
    Wie kann ich die beiden StringRegExpReplaces in eins packen?
    Oder gleich alle drei?
    Gibt's irgendwo ein wirklich gutes Tutorial zu so was?


    Vielen Dank schon mal für eure Geduld und Hilfe ;):D

  • Ordner vom Systempfad / Fonts durchsuchen lassen?

    Das haut nicht hin. Du kannst durchaus mehr Schriften in dem Ordner haben, die trotzdem nicht als Systemfont verfügbar sind.
    Probier es ruhig aus. Datei reinkopiert und Schrift ist trotzdem nicht verfügbar. Und schon wäre die Auflistung fürn A****.

    Mal davon abgesehen, das meist Dateiname <> Schriftname ist !

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

    • Offizieller Beitrag

    @Miraculi: Habe Dein Beispiel mal funktionsfähig gemacht:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    Global $sAllFonts = @CRLF, $i = 1
    While True
    $sFont = RegEnumVal("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts", $i)
    If @error Then ExitLoop
    $i += 1
    $sAllFonts &= $sFont & @CRLF
    WEnd
    $aAllFonts = StringRegExp($sAllFonts, '(.+?\(.+\))\r', 3)
    _ArraySort($aAllFonts)
    _ArrayDisplay($aAllFonts, 'Alle')

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

    $aTrueType = StringRegExp($sAllFonts, '(.+?\(TrueType\))\r', 3)
    _ArraySort($aTrueType)
    _ArrayDisplay($aTrueType, 'True Type')

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

    $aVGAResolution = StringRegExp($sAllFonts, '(.+?\(VGA-Auflösung\))\r', 3)
    _ArraySort($aVGAResolution)
    _ArrayDisplay($aVGAResolution, 'VGA-Auflösung')

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

    $aAllResolution = StringRegExp($sAllFonts, '(.+?\(Alle Auflösungen\))\r', 3)
    _ArraySort($aAllResolution)
    _ArrayDisplay($aAllResolution, 'Alle Auflösungen')

    [/autoit]
  • Ordner vom Systempfad / Fonts durchsuchen lassen?


    Hab ich natürlich schon versucht :P
    Aber wie Micha schon geschrieben hat, klappt das nicht :(

    Oscar :
    Danke :)
    Ich würde mich sehr freuen, wenn du die StringReg...s mir noch erklären könntest, damit ich da auch mal durchsteig :D

    @NSBM:

    Du hast einen Link zur Hilfe von StringReplace gepostet. Erstens ist ja wohl klar, dass ich mir die schon angeschaut habe und zweitens ging's mir um RegExp ... :pinch: :wacko:


    Edit: Ok, ich glaube, es verstanden zu haben. Habe aber noch eine Frage: Wie bekomm ich jetzt da noch z.B. das (TrueType) weg?
    Versucht habe ich es schon, aber weil die Schriften ja in einem Array sind klappt das bei mir irgendwie nicht... :S:huh:

    Edit2: Durch folgenden Code gelöst:

    [autoit]

    _ArrayTrim($aTrueType, 11,1) ; 11 Zeichen von Rechts löschen

    [/autoit]

    3 Mal editiert, zuletzt von Miraculi (9. Juni 2009 um 17:59)


  • 1.Gibt's da nicht ne einfachere Methode, z.B. eine UDF, um alle installierten Schriftarten auszulesen?

    Nicht direkt. Aber du kannst mit GDI die Schriftarten auslesen ;)

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
    #AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
    #include <GUIComboBox.au3>
    #include <GUIListBox.au3>
    #include <GuiConstantsEx.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <Constants.au3>
    #include <gdi\GDI.au3>
    #include <Array.au3>

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

    Opt('MustDeclareVars', 1)

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

    $Debug_CB = False ; Check ClassName being passed to ComboBox/ComboBoxEx functions, set to True and use a handle to another control to see it work

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

    Global $iMemo
    Global $FONT_COMBO_HANLDE, $FONT_COMBO_LISTBOX_HANLDE

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

    Global $EnumFontFamExProc = DllCallbackRegister("EnumFontFamExProc","int","ptr;ptr;dword;hwnd")
    ; by Prog@ndy
    Func EnumFontFamExProc( $lpelfe, _ ; // logical-font data
    $lpntme, _ ; // physical-font data
    $FontType, _ ; // type of font
    $lParam ); // application-defined data
    Local $lf = DllStructCreate($tagLOGFONTW,$lpelfe)

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

    Local $FONT_NAME = DllStructGetData($lf,"FaceName")
    _GUICtrlComboBox_AddString($lParam,$FONT_NAME)
    Return 1
    EndFunc

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

    ; by Prog@ndy
    Func _ListFontsToCombo($hCombo)

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

    _GUICtrlComboBox_BeginUpdate($hCombo)
    Local $DC = _WinAPI_GetDC(0)
    Local $LogFont = DllStructCreate($tagLOGFONTW)
    DllStructSetData($LogFont,"lfCharset",$DEFAULT_CHARSET)
    _GDI_EnumFontFamiliesEx($DC,$LogFont,DllCallbackGetPtr($EnumFontFamExProc),$hCombo,0)
    _WinAPI_ReleaseDC(0,$DC)
    _GUICtrlComboBox_EndUpdate($hCombo)

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

    EndFunc

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

    _Main()

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

    Func _Main()
    Local $tInfo, $hCombo

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

    ; Create GUI
    GUICreate("ComboBox Get ComboBox Info", 400, 296)
    $hCombo = GUICtrlCreateCombo("", 2, 2, 396, 296)
    $FONT_COMBO_HANLDE = GUICtrlGetHandle($hCombo)
    $iMemo = GUICtrlCreateEdit("", 2, 32, 396, 266, 0)
    GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New")
    GUISetState()

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

    _ListFontsToCombo($FONT_COMBO_HANLDE)

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

    _GUICtrlComboBox_GetComboBoxInfo($hCombo, $tInfo)
    GUIRegisterMsg($WM_COMMAND,"WM_COMMAND")

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

    $FONT_COMBO_LISTBOX_HANLDE = DllStructGetData($tInfo, "hList")

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

    Do

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

    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
    EndFunc ;==>_Main

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

    Func _UPDATELABEL()
    Local $Itm,$pos
    If Not IsDeclared("__FONT_PREVIEW_LAST_INDEX") Then Global $__FONT_PREVIEW_LAST_INDEX=-1

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

    $pos = _WinAPI_GetMousePos(True,$FONT_COMBO_LISTBOX_HANLDE)
    $Itm = _GUICtrlListBox_ItemFromPoint($FONT_COMBO_LISTBOX_HANLDE,DllStructGetData($pos,1),DllStructGetData($pos,2))

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

    If Not ($Itm = -1 Or $Itm =$__FONT_PREVIEW_LAST_INDEX) Then
    Local $sText
    _GUICtrlComboBox_GetLBText($FONT_COMBO_HANLDE,$Itm,$sText)
    Local $pos = WinGetPos($FONT_COMBO_HANLDE)
    If $pos[0]+$pos[2] > @DesktopWidth-350 Then $pos[0] -= ($pos[2]+350)
    SplashTextOn("FontPreview","abcxyzABCXYZ0189",350,80,$pos[0]+$pos[2],$pos[1],33,$sText,20)
    $__FONT_PREVIEW_LAST_INDEX = $Itm
    EndIf
    EndFunc

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

    ; Prog@ndy
    Func WM_COMMAND($hWnd,$uMsg,$wParam,$lParam)
    Switch _WinAPI_HiWord($wParam)
    Case $CBN_SELCHANGE
    If _GUICtrlComboBox_GetDroppedState($lParam) Then
    ConsoleWrite("nn" & @CRLF)
    ContinueCase
    Else
    SplashOff()
    AdlibDisable()
    EndIf
    Case $CBN_DROPDOWN
    AdlibEnable("_UPDATELABEL",10)
    Local $sText
    _GUICtrlComboBox_GetLBText($lParam,_GUICtrlComboBox_GetCurSel($lParam),$sText)
    ConsoleWrite($sText & @CRLF)
    Local $pos = WinGetPos($lParam)
    If $pos[0]+$pos[2] > @DesktopWidth-350 Then $pos[0] -= ($pos[2]+350)
    SplashTextOn("FontPreview","abcxyzABCXYZ0189",350,80,$pos[0]+$pos[2],$pos[1],33,$sText,20)
    Case $CBN_CLOSEUP,$CBN_SELENDOK
    SplashOff()
    AdlibDisable()
    EndSwitch
    EndFunc

    [/autoit]


    Du brauchst aber die GDI UDFs Downloads:[Blockierte Grafik: http://progandy.pr.funpic.de/dlcount.php/id=23/dl.png]

  • @progandy:

    Danke, aber das ist ja noch komplizierter :P So wie ich es jetzt mache, klappt's ja auch ;)

  • Vielleicht ist es so etwas überschaubarer?:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Global $aFonts[1]

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

    _GetSystemFonts()

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

    _ArrayDisplay($aFonts)

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

    Func _GetSystemFonts()
    Local Const $LOGFONT = "long lfHeight;long lfWidth;long lfEscapement;long lfOrientation;long lfWeight;byte lfItalic;byte lfUnderline; byte lfStrikeout;byte lfCharSet;byte lfOutPrecision;byte lfClipPrecision;byte lfQuality;byte lfPitchAndFamily;char lfFaceName[32]"
    Local $hGDI32 = DllOpen("Gdi32.dll"), $hUser32 = DllOpen("user32.dll")
    Local $hDesktop, $hDC, $iReturn
    Local $hCBFunc = DllCallbackRegister("EnumFontFamExProc", "long", "ptr;ptr;dword;lparam")
    Local $strctLOGFONT = DllStructCreate($LOGFONT)

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

    DllStructSetData($strctLOGFONT, "lfCharset", 1)

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

    $hDesktop = DllCall($hUser32, "hwnd", "GetDesktopWindow")
    $hDC = DllCall($hUser32, "ptr", "GetWindowDC", "hwnd", $hDesktop[0])

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

    DllCall($hGDI32, "long", "EnumFontFamiliesEx", "ptr", $hDC[0], "ptr", DllStructGetPtr($strctLOGFONT), "ptr", DllCallbackGetPtr($hCBFunc), "lparam", 10, "DWORD", 0)

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

    $aFonts = _ArrayUnique($aFonts, 1, 1)
    _ArraySort($aFonts, 0,1)

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

    DllCall($hUser32, "int", "ReleaseCapture")
    DllCallbackFree($hCBFunc)
    DllClose($hGDI32)
    DllClose($hUser32)
    EndFunc ;==>_GetSystemFonts

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

    Func EnumFontFamExProc($pLOGFONT, $TEXTMETRIC, $dwType, $lpData)
    Local Const $LOGFONT = "long lfHeight;long lfWidth;long lfEscapement;long lfOrientation;long lfWeight;byte lfItalic;byte lfUnderline; byte lfStrikeout;byte lfCharSet;byte lfOutPrecision;byte lfClipPrecision;byte lfQuality;byte lfPitchAndFamily;char lfFaceName[32]"

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

    ReDim $aFonts[UBound($aFonts)+1]
    $aFonts[UBound($aFonts)-1] = DllStructGetData(DllStructCreate($LOGFONT, $pLOGFONT), "lfFaceName")

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

    Return 1
    EndFunc ;==>EnumFontFamExProc

    [/autoit]

    Wobei ich hier die Sache mit dem ReDim, ArrayUnique und ArraySort nicht als güngstigste Lösung ansehe.
    Ist nur zu Anschauungszwecken.
    Wenn es performant werden soll dann würde ich auf eine Arraylist oder Dictionary ausweichen.

    Edit: Z.B. so:

    Spoiler anzeigen
    [autoit]

    Global $oAList = ObjCreate("System.Collections.ArrayList")

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

    _GetSystemFonts()

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

    For $FontName in $oAList
    ConsoleWrite( $FontName & @CRLF)
    Next

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

    Func _GetSystemFonts()
    Local Const $LOGFONT = "long lfHeight;long lfWidth;long lfEscapement;long lfOrientation;long lfWeight;byte lfItalic;byte lfUnderline; byte lfStrikeout;byte lfCharSet;byte lfOutPrecision;byte lfClipPrecision;byte lfQuality;byte lfPitchAndFamily;char lfFaceName[32]"
    Local $hGDI32 = DllOpen("Gdi32.dll"), $hUser32 = DllOpen("user32.dll")
    Local $hDesktop, $hDC, $iReturn
    Local $hCBFunc = DllCallbackRegister("EnumFontFamExProc", "long", "ptr;ptr;dword;lparam")
    Local $strctLOGFONT = DllStructCreate($LOGFONT)

    $oAList.Clear()

    DllStructSetData($strctLOGFONT, "lfCharset", 1)

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

    $hDesktop = DllCall($hUser32, "hwnd", "GetDesktopWindow")
    $hDC = DllCall($hUser32, "ptr", "GetWindowDC", "hwnd", $hDesktop[0])

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

    DllCall($hGDI32, "long", "EnumFontFamiliesEx", "ptr", $hDC[0], "ptr", DllStructGetPtr($strctLOGFONT), "ptr", DllCallbackGetPtr($hCBFunc), "lparam", 10, "DWORD", 0)

    $oAList.Sort

    DllCall($hUser32, "int", "ReleaseCapture")
    DllCallbackFree($hCBFunc)
    DllClose($hGDI32)
    DllClose($hUser32)
    EndFunc ;==>_GetSystemFonts

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

    Func EnumFontFamExProc($pLOGFONT, $TEXTMETRIC, $dwType, $lpData)
    Local Const $LOGFONT = "long lfHeight;long lfWidth;long lfEscapement;long lfOrientation;long lfWeight;byte lfItalic;byte lfUnderline; byte lfStrikeout;byte lfCharSet;byte lfOutPrecision;byte lfClipPrecision;byte lfQuality;byte lfPitchAndFamily;char lfFaceName[32]"
    Local $sFontName = DllStructGetData(DllStructCreate($LOGFONT, $pLOGFONT), "lfFaceName")

    If Not $oAList.Contains($sFontName) Then $oAList.Add ($sFontName)

    Return 1
    EndFunc ;==>EnumFontFamExProc

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

    Einmal editiert, zuletzt von AspirinJunkie (10. Juni 2009 um 12:44)