Jump to content

File Manager - Good Autoit example


Recommended Posts

Hi

I've been browsing the forums looking for a good file manager example. I have found a few but nothing that has really peaked my interest.. I was wondering if anyone had a good one they wished to share or could point me to a post of a good example. I'm looking for something very minimalistic. I'm thinking of something similar to metapath. I made some false starts on designing one but it is quite a bit more work than I expected and think I would rather tweak an existing one.

Anyways thanks for the help.

Link to comment
Share on other sites

A while back I used that code as a base for a MD5 Directory Compare Utility I wanted to make. I cleaned it up a lot, added a column for md5 sums and then got sidetracked and haven't had a chance to get back to it. It is a lot easier to read I believe.

If you want to make it work as I have it, you will need to download the MD5 Command Line Message Digest Utility from the fine people at Fourmilab.ch

un-zip it, grab the file called md5.exe and place it in c:\ (or change the location for it in my code. (line 267)

lol, After adding a dozen or so functions from my personal includes, this thing grew quite a bit

#include <GuiImageList.au3>
#include <GUIListView.au3>
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>

Global Const $tagSHFILEINFO     = 'dword hIcon; ' & _
                                  'int iIcon; ' & _
                                  'DWORD dwAttributes; ' & _
                                  'CHAR szDisplayName[255]; ' & _
                                  'CHAR szTypeName[80];'

Global Const $SHGFI_LARGEICON           = 0x0
Global Const $SHGFI_SMALLICON           = 0x1
Global Const $SHGFI_OPENICON            = 0x2
Global Const $SHGFI_SHELLICONSIZE       = 0X4
Global Const $SHGFI_PIDL                = 0x8
Global Const $SHGFI_USEFILEATTRIBUTES   = 0x10
Global Const $SHGFI_ADDOVERLAYS         = 0x20
Global Const $SHGFI_OVERLAYINDEX        = 0x40
Global Const $SHGFI_ICON                = 0x100
Global Const $SHGFI_DISPLAYNAME         = 0x200
Global Const $SHGFI_TYPENAME            = 0x400
Global Const $SHGFI_ATTRIBUTES          = 0x800
Global Const $SHGFI_ICONLOCATION        = 0x1000
Global Const $SHGFI_EXETYPE             = 0x2000
Global Const $SHGFI_SYSICONINDEX        = 0x4000
Global Const $SHGFI_LINKOVERLAY         = 0x8000
Global Const $SHGFI_SELECTED            = 0x10000
Global Const $SHGFI_ATTR_SPECIFIED      = 0x20000

Global Const $dwFILE_ATTRIBUTE_NORMAL   = 0x80
Global Const $FOLDER_ICON_INDEX = _GUIImageList_GetFileIconIndex(@SystemDir)


Opt("GUIOnEventMode", 1)

Global $sCurrentDir

Global $GUI_MAIN = GUICreate("Au3FTP", 882, 641, 193, 125)
GUISetOnEvent(-3,"GUI_Close")
GUISetFont(10,400,0,'Courier New')
Global $inpCurrentDirectory = GUICtrlCreateInput("", 8, 28, 850, 20, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY))
GUICtrlSetBkColor(-1,'0x00FFFFFF')
Global $ListView1 = GUICtrlCreateListView("Name|Date|Size|MD5", 8, 48, 850, 489,0,$LVS_EX_GRIDLINES)
GUICtrlSetBkColor(-1,'0x00FFFFFF')
Global $hListView1= GUICtrlGetHandle($ListView1)                                ; Get the Handle
GUICtrlSendMsg($ListView1, 0x101E, 0, 275)
GUICtrlSendMsg($ListView1, 0x101E, 1, 181)
GUICtrlSendMsg($ListView1, 0x101E, 2, 75)
GUICtrlSendMsg($ListView1, 0x101E, 3, 275)
GUIRegisterMsg($WM_NOTIFY, "_SHLV_WM_NOTIFY")
_GUICtrlListView_SetImageList($ListView1, _GUIImageList_GetSystemImageList(), 1) ; get shell32.dll image list
ListViewPopulateRootDir()                       ; use image list to provide images for HDD
GUISetState(@SW_SHOW)

While True
    Sleep(100)
WEnd

Func GUI_Close()
    Exit
EndFunc

Func _GUIImageList_GetSystemImageList()
    
    Local $FileInfo = DllStructCreate($tagSHFILEINFO)   
    Local $uFlags = BitOR($SHGFI_USEFILEATTRIBUTES, $SHGFI_SYSICONINDEX, $SHGFI_SMALLICON)
    Local $hImageList = _WinAPI_SHGetFileInfo( ".txt", _
                                        $dwFILE_ATTRIBUTE_NORMAL, _
                                        DllStructGetPtr($FileInfo), DllStructGetSize($FileInfo), _
                                        $uFlags )                           
    Return $hImageList
EndFunc

Func _GUIImageList_GetFileIconIndex($sFileSpec) 

    Local $FileInfo = DllStructCreate($tagSHFILEINFO)
    Local $uFlags = BitOR($SHGFI_SYSICONINDEX,$SHGFI_USEFILEATTRIBUTES,$SHGFI_SMALLICON)
    Local $hImageList = _WinAPI_SHGetFileInfo( $sFileSpec, _
                                        $FILE_ATTRIBUTE_NORMAL, _
                                        DllStructGetPtr($FileInfo), DllStructGetSize($FileInfo), _
                                        $uFlags )

    Return DllStructGetData($FileInfo, "iIcon")

EndFunc

Func _WinAPI_SHGetFileInfo($pszPath, $dwFileAttributes, $psfi, $cbFileInfo, $uFlags)
    Local $return = DllCall( "shell32.dll", "DWORD*", "SHGetFileInfo", _
                             "str", $pszPath, "DWORD", $dwFileAttributes, _
                             "ptr", $psfi, "UINT", $cbFileInfo, _ 
                             "UINT", $uFlags )
    If @error Then Return SetError(@error, 0, 0)
    Return $return[0]
EndFunc


Func ListViewPopulateRootDir()
        Local $drives = DriveGetDrive("ALL")
        GUICtrlSetData($inpCurrentDirectory, "Drive Selection")
        _GUICtrlListView_BeginUpdate($hListView1)
        _GUICtrlListView_DeleteAllItems($hListView1)
        For $i = 1 To $drives[0]
            _GUICtrlListView_AddItem($hListView1, StringUpper($drives[$i]) & "\", _GUIImageList_GetFileIconIndex($drives[$i] & "\"))
        Next
        _GUICtrlListView_EndUpdate($hListView1)
EndFunc
    

Func ListViewPopulateDir($sCurrentDir)
    If StringRight($sCurrentDir, 1) <> "\" Then $sCurrentDir &= "\"
    If DriveStatus(StringLeft($sCurrentDir, 3)) <> "READY" Then Return 0 * MsgBox(16 + 8192, 'Error on Drive Access', "Drive " & StringLeft($sCurrentDir, 3) & " not ready!")
    Local $dirs = FilespecToArray($sCurrentDir, "*", 2)
    Local $files = FilespecToArray($sCurrentDir, "*", 1)
    If Not $dirs[0] And Not $files[0] Then Return
    GUICtrlSetData($inpCurrentDirectory, $sCurrentDir)
    _GUICtrlListView_BeginUpdate($hListView1)
    _GUICtrlListView_DeleteAllItems($hListView1)
    _GUICtrlListView_SetItemCount($hListView1,$files[0] + $dirs[0])
    _GUICtrlListView_AddItem($hListView1, "[..]", 1)
    Local $pos = WinGetPos('Au3FTP')
    ProgressOn('', ' Creating MD5 Checksums ', '',-1,$pos[1] + 567,1)
    ProgressSet(0)
    Local $i
    While $i < $dirs[0]
        $i += 1 
        $item = _GUICtrlListView_AddItem($hListView1, $dirs[$i], $FOLDER_ICON_INDEX)
    WEnd
    $i = 0
    While $i < $files[0]
        $i += 1 
        $item = _GUICtrlListView_AddItem($hListView1, $files[$i], _GUIImageList_GetFileIconIndex($files[$i]))
        _GUICtrlListView_AddSubItem($hListView1, $item, __SHLV_FileDateString2Calc(FileGetTime($sCurrentDir & $files[$i], 0, 1)), 1)
        _GUICtrlListView_AddSubItem($hListView1, $item, File_AlignFileSize(FileGetSize($sCurrentDir & $files[$i])), 2)
        _GUICtrlListView_AddSubItem($hListView1, $item, File_GetMD5($files[$i],$sCurrentDir,False), 3)
        If $i/5 = Int($i/5) Then ProgressSet(Int(($i / $files[0])*100))
    WEnd
    ProgressOff()
    _GUICtrlListView_EndUpdate($hListView1)
EndFunc



Func __SHLV_FileDateString2Calc($filedate)
    Return StringRegExpReplace($filedate, "(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})", "$1/$2/$3 $4:$5:$6")
EndFunc

Func __SHLV_CalcDate2FileDateString($calcdate)
    Return StringRegExpReplace($calcdate, "(\d{4})/(\d{2})/(\d{2}) (\d{2})sad.gif\d{2})sad.gif\d{2})", "$1$2$3$4$5$6")
EndFunc


Func _SHLV_WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView1
            Switch $iCode
                Case $NM_DBLCLK; Sent by a list-view control when the user double-clicks an item with the left mouse button
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    If _GUICtrlListView_GetItemImage($hListView1, DllStructGetData($tInfo, "Index")) = $FOLDER_ICON_INDEX Then
                        $sCurrentDir &= _GUICtrlListView_GetItemText($hListView1, DllStructGetData($tInfo, "Index"))
                        ListViewPopulateDir($sCurrentDir)
                    ElseIf StringRegExp(_GUICtrlListView_GetItemText($hListView1, DllStructGetData($tInfo, "Index"), 0), "\A[A-Za-z]:\\\Z") Then
                        $sCurrentDir = _GUICtrlListView_GetItemText($hListView1, DllStructGetData($tInfo, "Index"))
                        ListViewPopulateDir($sCurrentDir)
                    ElseIf _GUICtrlListView_GetItemText($hListView1, DllStructGetData($tInfo, "Index")) = "[..]" Then
                        Local $slash = StringInStr($sCurrentDir, "\", 1, -2)
                        If $slash Then
                            $sCurrentDir = StringLeft($sCurrentDir, $slash)
                            ListViewPopulateDir($sCurrentDir)
                        ElseIf StringRegExp($sCurrentDir, "\A[A-Za-z]:\\\Z") Then
                            ListViewPopulateRootDir()
                        EndIf
                    EndIf
                   ; No return value
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func FilespecToArray($sFileSpec, $sFilter = "*", $iFlag = 0)
    Local $hSearch, $sFile, $asFileList
    $sFileSpec &= iif(StringRight($sFileSpec, 1) = "\",'','\')

    $hSearch = FileFindFirstFile($sFileSpec & $sFilter)
    If $hSearch = -1 Then 
        Local $RetArray[1] = ['0']
        Return $RetArray
    EndIf

    While 1
        $sFile = FileFindNextFile($hSearch)
        If @error Then ExitLoop
        
        If ($iflag = 0) Or ($iFlag = 1 And Not isDir($sFileSpec & $sFile)) Or ($iFlag = 2 And isDir($sFileSpec & $sFile)) Then $asFileList &= $sFile & '|'
    WEnd
    
    FileClose($hSearch)
    Return StringSplit(StringTrimRight($asFileList,1),'|')
EndFunc


Func isDir($filespec)
    If StringInStr(FileGetAttrib( $filespec ),"D") Then Return True
    If @error Then Return SetError(1)
    Return False
EndFunc
Func isHidden($filespec)
    If StringInStr(FileGetAttrib( $filespec ),"H") Then Return True
    If @error Then Return SetError(1)
    Return False
EndFunc
Func isReadonly($filespec)
    If StringInStr(FileGetAttrib( $filespec ),"R") Then Return True
    If @error Then Return SetError(1)
    Return False
EndFunc
Func isSystem($filespec)
    If StringInStr(FileGetAttrib( $filespec ),"S") Then Return True
    If @error Then Return SetError(1)
    Return False
EndFunc


;a If function, (comparable to excel's =IF(logical_test,value_if_true,value_if_false)
;For $E Any number (including negative numbers) besides 0 evalulates to a true result
;Any string besides an empty one '' evalulates to a true result
;Don't forget you can negate a true, or make a true from a false using the keyword not

Func iif($E, $T, $F)
    If $E Then Return $T
    Return $F
EndFunc

; if you set $check to $true
;   then targetfile must be a pathless filename
;   you must provide the full path to the filename as $targetdir
; if you do not provide a $targetdir then $targetfile must be the full path to the file
; if $targetfile has a path then either do not provide a $targetdir or make it equal to ""

Func File_GetMD5($targetfile,$targetdir = "",$check = True) 
    If $check Then
        If numtok($targetfile,92) = 1 Then
            If Not $targetdir Then Return SetError(1); targetfile doesn't have a path and no path was provided
            If Not FileExists($targetdir & '\' & $targetfile) Then Return SetError(1)
            $targetfile = '"' & $targetdir & '\' & $targetfile & '"'
        Else
            If $targetdir Then Return SetError(1)
            If Not FileExists($targetfile) Then Return SetError(1); targetfile has path and a path was provided
            $targetdir = gettok($targetfile,92,1,numtok($targetfile,92) - 1)
            $targetfile = '"' & $targetfile & '"'
        EndIf
    Else        
        $targetfile = '"' & $targetdir & '\' & $targetfile & '"'
    EndIf
            
    Local $md5 = Run(@ComSpec & " /c c:\md5 " & $targetfile, $targetdir,@SW_HIDE, $STDOUT_CHILD)
    While StdoutRead($md5,True) = ''
        Sleep(10)
    Wend
    Sleep(10)
    Local $result = StringTrimRight(StringReplace(StdoutRead($md5,False)," ","|",1),2)
    StdioClose($md5)
    Return $result
EndFunc



; Description ...:  Add $sToken to end of $sText but only if $sToken doesn't already exist in $sText
; Syntax.........:  addtok($sText, $sToken, $iTok)
; Parameters ....:  $sText    - A string to be split into tokens by the delimiter $iTok
;                  $iTok       - The delimiter, an ascii value (0-255) of a single character.
;                   $sToken     - The token to be added.

Func addtok($sText, $sToken, $iTok) 
    If Not IsNumber($iTok) Then Return $sText
    If $iTok < 0 Or $iTok > 255 Then Return $sText  
    If Not $sText Then Return $sToken
    If Not $sToken Then Return $sText
    RemTok_Dupes_First_Last($sText, $iTok)
    Local $i
    Local $aTokens = StringSplit($sText,$iTok)  
    For $i = 1 To $aTokens[0]
        If StringLower($aTokens[$i]) = StringLower($sToken) Then Return $sText
    Next
    $sText &= $iTok & $sToken
    Return $sText
EndFunc

; Description ...:  Retrieves token(s) from $sText
; Syntax.........:  gettok($sText, $iTok, $N, [ $N2] )
; Parameters ....:  $sText    - A string to be split into tokens by the delimiter $iTok
;                  $iTok       - The delimiter, an ascii value (0-255) of a single character.
;                   Retrieve a single token
;                   $N          - The number of the token you want returned.
;                   Retrieve a range of tokens
;                   $N2         - With positive values for $N and $N2, returns a string of tokens from token $N to $N2
;                   -$N         - With a negative value for $N, returns a string of tokens from the beginning of $sText to the $N token.                                  
;                   -$N2        - With a negative value for $N2, returns a string of tokens from token $N2 to the end of $sText

Func gettok($sText, $iTok, $n1, $n2 = 0)
    If Not IsNumber($iTok) Then Return $stext
    If Not IsNumber($n1) Or Not IsNumber($n2) Then Return ''
    If $iTok < 0 Or $iTok > 255 Then Return $stext
    If $n1 And $n2 And ($n1 < 0 Or $n2 < 0 Or $n1 > $n2)  Then Return ''
    
    RemTok_Dupes_First_Last($sText, $iTok)
    Local $i
    Local $aTokens = StringSplit($sText, $iTok) 
    if $n1 > 0 And $n2 = 0 Then
        If $n1 > $aTokens[0] Then Return ''
        Return $aTokens[$n1]        
    ElseIf $n1 > 0 And $n2 > 0 Then
        If $n1 > $aTokens[0] Then Return ''
        If $n2 > $aTokens[0] Then $n2 = $aTokens[0]
        $sText = $aTokens[$n1]
        For $i = $n1 + 1 To $n2
            $sText &= $iTok & $aTokens[$i]
        Next
        Return $sText       
    ElseIf $n1 < 0 And $n2 = 0 Then
        $n1 = Abs($n1)
        If $n1 > $aTokens[0] Then Return $sText
        $sText = $aTokens[1]
        For $i = 2 To $n1
            $sText &= $iTok & $aTokens[$i]
        Next
        Return $sText       
    ElseIf $n1 = 0 And $n2 < 0 Then
        $n2 = Abs($n2)
        If $n2 > $aTokens[0] Then Return ''
        $sText = $aTokens[$n2]
        For $i = $n2 + 1 To $aTokens[0]
            $sText &= $iTok & $aTokens[$i]
        Next
        Return $sText
    EndIf
EndFunc

; Description ...:  Return True or False if $sToken is a token in $sText
; Syntax.........:  istok($sText, $sToken, $iTok)
; Parameters ....:  $sText    - A string to be split into tokens by the delimiter $iTok
;                   $sToken     - The token to be checked for.
;                  $iTok       - The delimiter, an ascii value (0-255) of a single character.

Func istok($sText, $sToken, $iTok)  
    If (Not $sText) Or (Not $sToken) Or (Not IsNumber($iTok)) Or ($iTok < 0) Or ($iTok > 255) Then Return SetError(1)
    RemTok_Dupes_First_Last($sText, $iTok)
    Local $i
    Local $aTokens = StringSplit($sText,$iTok)
    $sToken = StringLower($sToken)
    For $i = 1 To $aTokens[0]
        If StringLower($aTokens[$i]) =  $sToken Then Return True
    Next
    Return False
EndFunc


; Description ...:  Retrieves the number of token(s) in $sText
; Syntax.........:  numtok($sText, $iTok)
; Parameters ....:  $sText     - A string to be split into tokens by the delimiter $iTok
;                  $iTok        - The delimiter, an ascii value (0-255) of a single character.

Func numtok($sText, $iTok)
    If (Not IsNumber($iTok)) Or ($iTok < 0) Or ($iTok > 255) Or (Not $sText) Then Return
    If Not RemTok_Dupes_First_Last($sText,$iTok) Then Return 1
    Local $aTokens = StringSplit($sText, $iTok)
    Return $aTokens[0]
EndFunc


;   if nobytes = 1 filesize less than 1000 bytes it will be diaplyed as 1kb, unless its a empty 0byte file
;   if nobytes = 0 Filesize digits are right aligned and the letters are left aligned
;   if nospace = 0 there will be a space between digits and letters
;   using the 3 optional parameters default values displays filesizes like windows explorer does
;   note: if a non monospace font is used then this function is useless

Func File_AlignFileSize($num, $nobytes = 1, $use_b_for_bytes = 1, $nospace = 0 )
    Select
        Case $num < 1000
            Select
                Case $nobytes
                    $num = "   " & iif($num = 0,'0','1') & iif($nospace,'',' ') & "KB"
                Case Not $nobytes And $use_b_for_bytes
                    $num = StringFormat("%4s",(iif($num = 0,"   0",StringFormat("%3." & (3 - StringLen(Int($num))) & "f",$num)))) & iif($nospace,'',' ') & "B"
                Case Else
                    $num = StringFormat("%4s",(iif($num = 0,"   0",StringFormat("%3." & (3 - StringLen(Int($num))) & "f",$num)))) & iif($nospace,'',' ') & "Bytes"
            EndSelect
        Case $num >= 1000 And $num < 1000000
            $num = $num / 1024  
            $num = StringFormat("%4s",(StringFormat("%3." & (3 - StringLen(Int($num))) & "f",$num))) & iif($nospace,'',' ') & "KB"
        Case $num >= 1000 And $num < 1000000000
            $num = $num / 1048576
            $num = StringFormat("%4s",(StringFormat("%3." & (3 - StringLen(Int($num))) & "f",$num))) & iif($nospace,'',' ') & "KB"
        Case $num >= 1000000 And $num < 1000000000000
            $num = $num / 1073741824
            $num = StringFormat("%4s",(StringFormat("%3." & (3 - StringLen(Int($num))) & "f",$num))) & iif($nospace,'',' ') & "KB"
        Case Else
            $num = $num / 1099511627776
            $num = StringFormat("%4s",(StringFormat("%3." & (3 - StringLen(Int($num))) & "f",$num))) & iif($nospace,'',' ') & "KB"
    EndSelect
    Return $num
EndFunc


Func RemTok_Dupes_First_Last(ByRef $sText, ByRef $iTok)
    $iTok = Chr($iTok)
    If Not StringInStr($sText, $iTok) Then Return False
    While StringInStr($sText, $iTok & $iTok)
        $sText = StringReplace($sText,$iTok & $iTok, $iTok)
    WEnd
    While StringRight($sText,1) = $iTok
        $sText = StringTrimRight($sText,1)
    WEnd
    While StringLeft($sText,1) = $iTok
        $sText = StringTrimLeft($sText,1)
    WEnd
    Return True
EndFunc
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...