_FilePathTrimToLabelWidth

    • Offizieller Beitrag

    Hier nun eine Funktion, die einen übergebenen Pfad soweit kürzt, dass er in ein anzugebenes Label passt.

    Mit Hilfe von UEZ und peethebee ist das hier entstanden:

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>

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

    $iFontSize = 16
    $sFontname = 'Times New Roman'
    $iFontStyle = 0
    ;~ $sFontname = 'Courier New'
    $hGui = GUICreate('Test', 600, 200)
    GUISetFont($iFontSize, 400, $iFontStyle, $sFontname)
    $hPath1 = GUICtrlCreateLabel('', 10, 10, 300, 50)
    GUICtrlSetBkColor(-1, 0xCCCCCC)
    $hPath2 = GUICtrlCreateLabel('', 10, 80, 580, 50)
    GUICtrlSetBkColor(-1, 0xCCCCCC)
    GUISetState()

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

    ; Beispiel 1
    $sPath1 = 'C:\Users\Oscar\Pictures\Urlaub2011\Pic1045.jpg'
    $iTimer = TimerInit()
    $sPath1 = _FilePathTrimToLabelWidth($sPath1, $hGui, $hPath1, $iFontSize, $sFontname, $iFontStyle)
    ConsoleWrite(Int(TimerDiff($iTimer)) & ' mSec.' & @CR)
    GUICtrlSetData($hPath1, $sPath1)

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

    ; Beispiel 2
    $sPath2 = '\\Server\d\Backup\Users\Oscar\Pictures\Urlaub2011\Pic1045.jpg'
    $iTimer = TimerInit()
    $sPath2 = _FilePathTrimToLabelWidth($sPath2, $hGui, $hPath2, $iFontSize, $sFontname, $iFontStyle)
    ConsoleWrite(Int(TimerDiff($iTimer)) & ' mSec.' & @CR)
    GUICtrlSetData($hPath2, $sPath2)

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

    Do
    Until GUIGetMsg() = -3

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

    ;===============================================================================
    ; Function Name: _FilePathTrimToLabelWidth($sFilepath, $hGui, $iCtrlID, $iFontSize, $sFontname[, $iFontStyle])
    ; Description:: Begrenzt einen Dateipfad auf die Breite eines Labels.
    ; 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
    ; $hGui = das Handle des Fensters
    ; $iCtrlID = die Control ID des Label
    ; $iFontSize = Fontgröße
    ; $sFontname = Fontname
    ; $iFontStyle = Fontstyle (optional)
    ; Requirement(s): #include <GDIPlus.au3>
    ; Return Value(s): Der gekürzte Pfad
    ; Author(s): Oscar + UEZ + peethebee (http://www.autoit.de)
    ;===============================================================================
    Func _FilePathTrimToLabelWidth($sFilepath, $hGui, $iCtrlID, $iFontSize, $sFontname, $iFontStyle = 0)
    Local $sDevice, $iLen = StringLen($sFilepath)
    _GDIPlus_Startup()
    Local $iSize = _GetStringSize($sFilepath, $hGui, $iFontSize, $sFontname, $iFontStyle)
    Local $aPosCtrl = ControlGetPos($hGui, '', $iCtrlID)
    If $iSize < $aPosCtrl[2] Then Return $sFilepath
    $sDevice = StringRegExpReplace($sFilepath, '(?i)([a-z]:\\|\\\\.+?\\[a-z]\\).+', '$1') & '...'
    For $i = $iLen To 1 Step -1
    $iSize = _GetStringSize($sDevice & StringRight($sFilepath, $i), $hGui, $iFontSize, $sFontname, $iFontStyle)
    If $iSize < $aPosCtrl[2] Then ExitLoop
    Next
    _GDIPlus_Shutdown()
    Return $sDevice & StringRight($sFilepath, $i)
    EndFunc ;==>_FilePathTrimToLabelWidth

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

    Func _GetStringSize($sString, $hGui, $iFontSize, $sFontname, $iFontStyle)
    Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)
    Local $hFormat = _GDIPlus_StringFormatCreate()
    Local $hFamily = _GDIPlus_FontFamilyCreate($sFontname)
    Local $hFont = _GDIPlus_FontCreate($hFamily, $iFontSize, $iFontStyle)
    Local $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_GraphicsDispose($hGraphic)
    Return Int(DllStructGetData($aInfo[0], 'Width'))
    EndFunc ;==>_GetStringSize

    [/autoit]

    Edit: Extrem beschleunigt. Schuld waren die dauernden Aufrufe von _GDIPlus_Startup() und _GDIPlus_Shutdown().

    Edit2: Es gab noch einen Bug beim RegExp-Pattern. Außerdem habe ich noch ein wenig "aufgeräumt".

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

  • Du kannst das Skript extrem beschleunigen, wenn du _GDIPlus_Startup() / _GDIPlus_Shutdown() vorher aufrufst!

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>
    _GDIPlus_Startup()

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

    $iFontSize = 24
    $sFontname = 'Times New Roman'
    ;~ $sFontname = 'Courier New'
    $hGui = GUICreate('Test', 600, 200)
    GUISetFont($iFontSize, 400, 0, $sFontname)
    $hPath1 = GUICtrlCreateLabel('', 10, 10, 300, 50)
    GUICtrlSetBkColor(-1, 0xCCCCCC)
    $hPath2 = GUICtrlCreateLabel('', 10, 80, 580, 50)
    GUICtrlSetBkColor(-1, 0xCCCCCC)
    GUISetState()

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

    ; Beispiel 1
    $sPath1 = 'c:\Users\Oscar\Pictures\Urlaub2011\Pic1045.jpg'
    $iTimer = TimerInit()
    $sPath1 = _FilePathTrimToLabelWidth($sPath1, $hGui, $hPath1, $iFontSize, $sFontname)
    ConsoleWrite(Int(TimerDiff($iTimer)) & ' mSec.' & @CR)
    GUICtrlSetData($hPath1, $sPath1)

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

    ; Beispiel 2
    $sPath2 = '\\Server\d\Backup\Users\Oscar\Pictures\Urlaub2011\Pic1045.jpg'
    $iTimer = TimerInit()
    $sPath2 = _FilePathTrimToLabelWidth($sPath2, $hGui, $hPath2, $iFontSize, $sFontname)
    ConsoleWrite(Int(TimerDiff($iTimer)) & ' mSec.' & @CR)
    GUICtrlSetData($hPath2, $sPath2)

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

    Do
    Until GUIGetMsg() = -3
    _GDIPlus_Shutdown()

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

    ;===============================================================================
    ; Function Name: _FilePathTrimToLabelWidth($sFilepath, $CtrlID, $iFontSize, $sFontname)
    ; Description:: Begrenzt einen Dateipfad auf die Breite eines Labels.
    ; 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
    ; $hGui = das Handle des Fensters
    ; $CtrlID = die Control ID des Label
    ; $iFontSize = Fontgröße
    ; $sFontname = Fontname
    ; Requirement(s): #include <GDIPlus.au3>
    ; Return Value(s): Der gekürzte Pfad
    ; Author(s): Oscar + UEZ + peethebee (http://www.autoit.de)
    ;===============================================================================
    Func _FilePathTrimToLabelWidth($sFilepath, $hGui, $CtrlID, $iFontSize, $sFontname)
    Local $sDevice, $iLen = StringLen($sFilepath)
    Local $iSize = _GetStringSize($sFilepath, $sFontname, $iFontSize, 0)
    Local $aPosCtrl = ControlGetPos($hGui, '', $CtrlID)
    If $iSize < $aPosCtrl[2] Then Return $sFilepath
    $sDevice = StringRegExpReplace($sFilepath, '([a-z]:\\|\\\\.+?\\[a-z]\\).+', '$1') & '...'
    For $i = $iLen - StringLen($sDevice) To 1 Step -1
    $iSize = _GetStringSize($sDevice & StringRight($sFilepath, $i), $sFontname, $iFontSize, 0)
    If $iSize < $aPosCtrl[2] Then ExitLoop
    Next
    Return $sDevice & StringRight($sFilepath, $i)
    EndFunc ;==>_FilePathTrimToLabelWidth

    [/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 $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_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGrphContext)
    If $GDIp Then _GDIPlus_Shutdown()
    Return Int(DllStructGetData($aInfo[0], 'Width'))
    EndFunc ;==>_GetStringSize

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯