_FilePathTrimToLimit

    • Offizieller Beitrag

    Diese Funktion dient dazu einen Dateipfad zu kürzen, um diesen in einem Label (begrenzter Platz) anzeigen zu können.
    Der Pfad wird dabei aber nicht einfach vorne oder hinten abgeschnitten, sondern es bleibt das Device erhalten und der Rest wird dann vom rechten Teil aufgefüllt.

    Skript und Beispiel:

    Spoiler anzeigen
    [autoit]


    $hGui = GUICreate('Test', 400, 200)
    GUISetFont(12, 400, 0, 'Courier New')
    $hPath1 = GUICtrlCreateLabel('', 10, 10, 380, 20)
    GUICtrlSetBkColor(-1, 0xCCCCCC)
    $hPath2 = GUICtrlCreateLabel('', 10, 60, 380, 20)
    GUICtrlSetBkColor(-1, 0xCCCCCC)
    GUISetState()

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

    ; Beispiel 1
    $sPath1 = 'c:\Users\Oscar\Pictures\Urlaub2011\Pic1045.jpg'
    $sPath1 = _FilePathTrimToLimit($sPath1, 38)
    GUICtrlSetData($hPath1, $sPath1)

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

    ; Beispiel 2
    $sPath2 = '\\Server\d\Backup\Users\Oscar\Pictures\Urlaub2011\Pic1045.jpg'
    $sPath2 = _FilePathTrimToLimit($sPath2, 38)
    GUICtrlSetData($hPath2, $sPath2)

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

    Do
    Until GUIGetMsg() = -3

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

    ;===============================================================================
    ; Function Name: _FilePathTrimToLimit($sFilepath, $iLimit)
    ; Description:: Begrenzt einen Dateipfad auf eine anzugebene Stringlänge.
    ; Dabei wird er aber nicht vorn oder hinten abgeschnitten,
    ; sondern es bleibt das Device erhalten und der rechte Teil
    ; des Pfades.
    ; Parameter(s): $sFilepath = der Pfad, der gekürzt werden soll
    ; $iLimit = auf wie viele Stellen der Pfad gekürzt werden soll
    ; Requirement(s): ---
    ; Return Value(s): Der gekürzte Pfad
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _FilePathTrimToLimit($sFilepath, $iLimit)
    Local $sDevice, $iLen = StringLen($sFilepath)
    If $iLimit < 1 Or $iLimit >= $iLen Then Return $sFilepath
    $sDevice = StringRegExpReplace($sFilepath, '([a-z]:\\|\\\\.+?\\[a-z]\\).+', '$1') & '...'
    Return $sDevice & StringRight($sFilepath, $iLimit - StringLen($sDevice))
    EndFunc ;==>_FilePathTrimToLimit

    [/autoit]

    Edit: Eine bessere Lösung für das Problem gibt es hier: _GuiCtrlSetPath

  • Nette Funktion!

    Cool wäre es, wenn die Funktion anhand der String Länge respektiv Font Größe und die Länge/Breite des Label berechnen würde.

    Wenn du z.B. in deinem Beispiel die Zeile

    $hPath1 = GUICtrlCreateLabel('', 10, 10, 380, 20)

    in

    $hPath1 = GUICtrlCreateLabel('', 10, 10, 280, 20)

    umänderst, dann fehlt ein Teil des Dateinamens.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Und dies hier?

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>

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

    $iFontSize = 12
    $sFontname = 'Courier New'
    $hGui = GUICreate('Test', 400, 200)
    GUISetFont($iFontSize, 400, 0, $sFontname)
    $hPath1 = GUICtrlCreateLabel('', 10, 10, 280, 20)
    GUICtrlSetBkColor(-1, 0xCCCCCC)
    $hPath2 = GUICtrlCreateLabel('', 10, 60, 300, 20)
    GUICtrlSetBkColor(-1, 0xCCCCCC)
    GUISetState()

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

    ; Beispiel 1
    $sPath1 = 'c:\Users\Oscar\Pictures\Urlaub2011\Pic1045.jpg'
    $sPath1 = _FilePathTrimToLimit($sPath1, $hPath1, $iFontSize, $sFontname)
    GUICtrlSetData($hPath1, $sPath1)

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

    ; Beispiel 2
    $sPath2 = '\\Server\d\Backup\Users\Oscar\Pictures\Urlaub2011\Pic1045.jpg'
    $sPath2 = _FilePathTrimToLimit($sPath2, $hPath2, $iFontSize, $sFontname)
    GUICtrlSetData($hPath2, $sPath2)

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

    Do
    Until GUIGetMsg() = -3

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

    ;===============================================================================
    ; Function Name: _FilePathTrimToLimit($sFilepath, $iLimit)
    ; Description:: Begrenzt einen Dateipfad auf eine anzugebene Stringlänge.
    ; Dabei wird er aber nicht vorn oder hinten abgeschnitten,
    ; sondern es bleibt das Device erhalten und der rechte Teil
    ; des Pfades.
    ; Parameter(s): $sFilepath = der Pfad, der gekürzt werden soll
    ; $CtrlID = die Control ID des Label
    ; $iFontSize = die Fontgröße des Labels
    ; $sFontname = Font Name
    ; Requirement(s): ---
    ; Return Value(s): Der gekürzte Pfad
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _FilePathTrimToLimit($sFilepath, $CtrlID, $iFontSize, $sFontname)
    Local $aSize = GetStringSize($sFilepath, $sFontname, $iFontSize, 0)
    Local $aPosCtrl = ControlGetPos("", "", $CtrlID)
    Local $iLimit = StringLen($sFilepath) - Ceiling(Ceiling(1 + ($aSize[0] - $aPosCtrl[2]) / 100) + ($aSize[0] - $aPosCtrl[2]) / $iFontSize)
    Local $sDevice, $iLen = StringLen($sFilepath)
    If $iLimit < 1 Or $iLimit >= $iLen Then Return $sFilepath
    $sDevice = StringRegExpReplace($sFilepath, '([a-z]:\\|\\\\.+?\\[a-z]\\).+', '$1') & '...'
    Return $sDevice & StringRight($sFilepath, $iLimit - StringLen($sDevice))
    EndFunc ;==>_FilePathTrimToLimit

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

    Func GetStringSize($string, $font, $fontsize, $fontstyle)
    Local $GDIp = False
    Local $iWidth = StringLen($string) * $fontsize
    Local $iHeight = 2 * $fontsize
    If Not $ghGDIPDll Then
    _GDIPlus_Startup()
    $GDIp = True
    EndIf
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    Local $hBitmap = $aResult[6]
    Local $hGrphContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    ;~ Local $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
    Local $hFormat = _GDIPlus_StringFormatCreate()
    Local $hFamily = _GDIPlus_FontFamilyCreate($font)
    Local $hFont = _GDIPlus_FontCreate($hFamily, $fontsize, $fontstyle)
    Local $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGrphContext, $string, $hFont, $tLayout, $hFormat)
    ;~ _GDIPlus_GraphicsDrawStringEx($hGrphContext, $string, $hFont, $aInfo[0], $hFormat, $hBrush)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    ;~ _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGrphContext)
    If $GDIp Then _GDIPlus_Shutdown()
    Local $aDim[2] = [Int(DllStructGetData($aInfo[0], "Width")), Int(DllStructGetData($aInfo[0], "Height"))]
    Return $aDim
    EndFunc

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    3 Mal editiert, zuletzt von UEZ (24. November 2011 um 10:46)

    • Offizieller Beitrag

    Nicht wirklich! Weil man ja den Text (die Textlänge genauer gesagt) vorher nicht kennt. Man muss den Text ja an das Label anpassen.

    Abmessen wie lange 3 Punkte wären, außerdem den festen Teil vorne und dann die von hinten solange Buchstaben reinstecken und ihre Breite von der noch verfügbaren Restbreite abziehen wie Platz ist (aus Performancegründen eventuell erst längere Strings hinzufügen, bis es schief geht und dann wieder zurücknehmen). Das wäre mein Algorithmus dafür :). Sinnvoll?

    • Offizieller Beitrag

    UEZ: Bei Deinem Skript schwankte das Ergebnis sehr stark (je nach verwendetem Font und -größe). Mal passte es, mal nicht.

    Ich habe mal Deine Funktion benutzt, um das hier _FilePathTrimToLabelWidth zu erstellen.
    Dabei habe ich die Idee von peethebee aufgegriffen und die Breite experimentell ermittelt.
    Nachteil ist, dass es relativ lange dauert. (Nachteil beseitigt)

  • War auch nur eine "Studie". Leider dauert das Erstellen in _FilePathTrimToLabelWidth zu lange.

    Ich schaue mal, ob mir dazu noch was einfällt....

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Wie wäre es mit einer Tabelle in der die wichtigsten (Grund-)Schriften enthalten sind - und wird nicht für jede Schriftart eine Ersatzschriftart angegeben / definiert - durch Windows bzw. für Windows?
    Also die Schriftart die er nimmt wenn er die eingestellte nicht findet? Dann wären feste Werte pro Schriftenfamilie ggf. ausreichend.

    Natürlich sollte Fett + Italic berücksichtigt werden ... 8| Fass ohne Boden?

    Oder liesse sich das nicht gleich sofort aus der Schrifart selbst auslesen? also wie Breit der jeweilige Buchstabe wird?


    Fragen über Fragen ....