Jump to content
Sign in to follow this  
Deye

Someone quick to find a fix

Recommended Posts

derived from here 

I have updated the example to search file\folders in levels from root folders = 1

for the example search for a specific folder that you know exists in level 2 but wont exist in the following levels if the end level is 7 ..

I have added a button to abort the search otherwise the gui will hang without being able to gracefully exit 

Usage: select a drive from the drop-down combo and  type some folder name right after the selected drive

just interested to make it quit searching on demand if anyone can spot how it may be done or any other ideas

Spoiler
#include <File.au3>
#include <String.au3>
#include <GUIConstantsEx.au3>

HotKeySet("{ESC}", "TerminateSearch")

$aArray = DriveGetDrive("ALL")
For $i = 1 To $aArray[0]
    $aArray[$i] = StringUpper($aArray[$i])
Next
$sString = _ArrayToString($aArray, "|", 1)

$hGUI = GUICreate("Test", 310, 100)

;Use it like this for this example
$hCombo = GUICtrlCreateCombo("", 10, 10, 200, 20) ;File*.mp3
GUICtrlSetFont(-1, 12)
GUICtrlSetData(-1, $sString)

$hCombo2 = GUICtrlCreateCombo("Start Level", 10, 50, 120, 20) ;File*.mp3
GUICtrlSetFont(-1, 12)
GUICtrlSetData(-1, "1|2|3|4|5|6|7")

$Button = GUICtrlCreateButton("Search", 215, 08, 85, 25)
$ButtonCancel = GUICtrlCreateButton("Abort Search", 215, 38, 85, 25)
$ButtonResult = GUICtrlCreateButton("Copy result", 215, 68, 85, 25)

$Result = ""
$Cancel = False

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit

        Case $Button
            $sSearch = GUICtrlRead($hCombo)
            $iLevel = GUICtrlRead($hCombo2)
            If StringIsAlpha($iLevel) Then $iLevel = 1
            $Result = _Search($sSearch, $iLevel)
            MsgBox(262144, "", $Result)

        Case $ButtonCancel
            $Cancel = True

        Case $ButtonResult
            ClipPut($Result)
    EndSwitch
    Sleep(10)
WEnd

Func _Search($sSearch, $iStartLevel = 1, $iEndLevel = 7) ; $iLevel folders levels deeep
    Local $a = StringSplit($sSearch, ":"), $Ret
    Switch $iStartLevel
        Case 1
            $Ret = _GetAppropriatePath($a[1] & ":\*" & $a[2] & "*")
            If $Ret Then Return $Ret
            $iStartLevel += 1
            ContinueCase
        Case Else
            While $Cancel = False
                For $i = $iStartLevel - 1 To $iEndLevel
                    $Ret = _GetAppropriatePath($a[1] & ":\*" & _StringRepeat("\*", $i) & $a[2] & "*")
                    If $Ret Then Return $Ret
                Next
            WEnd
            $Cancel = False
    EndSwitch
    Return ""
EndFunc   ;==>_Search

Func _GetAppropriatePath($sPath, $iLevel = 0)
    Local $hSearch, $tPath, $File, $Item, $Path, $Ret, $Dir = '', $Suf = '', $Result = ''

    $tPath = DllStructCreate('wchar[1024]')
    $Ret = DllCall('kernel32.dll', 'dword', 'GetFullPathNameW', 'wstr', $sPath, 'dword', 1024, 'ptr', DllStructGetPtr($tPath), 'ptr', 0)
    If (@error) Or (Not $Ret[0]) Then
        Return ''
    EndIf
    $sPath = DllStructGetData($tPath, 1)
    If StringRight($sPath, 1) = '\' Then
        $Dir = '\'
    EndIf
    $Item = StringSplit(StringRegExpReplace($sPath, '\\\Z', ''), '\')
    Select
        Case $iLevel + 1 = $Item[0]
            If FileExists($sPath) Then
                Return $sPath
            Else
                Return ''
            EndIf
        Case $iLevel + 1 > $Item[0]
            Return ''
    EndSelect
    For $i = 1 To $iLevel + 1
        $Result &= $Item[$i] & '\'
    Next
    $Result = StringRegExpReplace($Result, '\\\Z', '')
    If Not FileExists($Result) Then
        Return ''
    EndIf
    $hSearch = FileFindFirstFile($Result & '\*')
    If $hSearch = -1 Then
        Return ''
    EndIf
    For $i = $iLevel + 3 To $Item[0]
        $Suf &= '\' & $Item[$i]
    Next

    While $Cancel = False
        $File = FileFindNextFile($hSearch)
        If @error Then
            $Result = ''
            ExitLoop
        EndIf
        If (Not @extended) And ($Dir) And ($iLevel + 2 = $Item[0]) Then
            ContinueLoop
        EndIf
        $Ret = DllCall('shlwapi.dll', 'int', 'PathMatchSpecW', 'wstr', $File, 'wstr', $Item[$iLevel + 2])
        If (Not @error) And ($Ret[0]) Then
            $Path = _GetAppropriatePath($Result & '\' & $File & $Suf & $Dir, $iLevel + 1)
            If $Path Then
                $Result = $Path
                ExitLoop
            EndIf
        EndIf
    WEnd
    FileClose($hSearch)
    $Cancel = False
    Return $Result
EndFunc   ;==>_GetAppropriatePath

Func TerminateSearch()
    $Cancel = True
EndFunc   ;==>TerminateSearch

 

Thanks

Edit: works ok with a hotkeyset @setting $cancel to True but not from the button in the loop .

will have to do for now :

Updated Code to terminate a search with the "ESC"  key

Edited by Deye

Share this post


Link to post
Share on other sites

Why not just use FileListToArrayRec with a depth parameter set?


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Absolutely  @BrewManNH

I struggled a bit to make it work in the way you suggested but it finally clinged :thumbsup:

 

Spoiler
#include <File.au3>
#include <String.au3>
#include <GUIConstantsEx.au3>

$aArray = DriveGetDrive("ALL")
For $i = 1 To $aArray[0]
    $aArray[$i] = StringUpper($aArray[$i])
Next
$sString = _ArrayToString($aArray, "|", 1)

$hGUI = GUICreate("Test", 320, 125)
$hCombo = GUICtrlCreateCombo("", 10, 8, 180, 20) ;File*.mp3
GUICtrlSetFont(-1, 12)
GUICtrlSetData(-1, $sString)

$hCombo2 = GUICtrlCreateCombo("LevelFiveDefault", 10, 70, 180, 20) ;File*.mp3
GUICtrlSetFont(-1, 12)
GUICtrlSetData(-1, "1|2|3|4|5|6|7")

$Button = GUICtrlCreateButton("Search", 215, 08, 100, 25)
GUICtrlSetFont(-1, 12)
$ButtonCancel = GUICtrlCreateButton("Abort Search", 215, 45, 100, 25)
$ButtonResult = GUICtrlCreateButton("Copy result", 215, 80, 100, 25)
GUICtrlSetFont(-1, 12)

$File = GUICtrlCreateRadio("File", 10, 38, 70, 25)
GUICtrlSetFont(-1, 12)
$Folder = GUICtrlCreateRadio("Folder", 100, 38, 70, 25)
GUICtrlSetFont(-1, 12)
GUICtrlSetState(-1, $GUI_CHECKED)

$Cancel = False
;~ HotKeySet("{ESC}", "TerminateSearch")

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            $sSearch = GUICtrlRead($hCombo)
            $iLevel = GUICtrlRead($hCombo2)
            If StringIsAlpha($iLevel) Then $iLevel = 5
            $aResult = _Search($sSearch, BitAND(GUICtrlRead($File), $GUI_CHECKED) ? 0 : 1, $iLevel)
            _ArrayDisplay($aResult, "Level " & $iLevel)
            ConsoleWrite("Done Searching" & @LF & @LF)

        Case $ButtonCancel
            $Cancel = True
        Case $ButtonResult
            ClipPut(_ArrayToString($aResult, @LF))
    EndSwitch
    Sleep(10)
WEnd

Func _Search($sSearch, $bFolder = 1, $iEndLevel = 5)
    Local $a = StringSplit($sSearch, ":"), $aRet[0]
    ConsoleWrite("Level = " & $iEndLevel & @LF)
    Return _FileListToArrayRec($a[1] & ":\", "*" & $a[2] & "*", ($bFolder ? 2 : 1), ($iEndLevel - 1) * -1, Default, 2)
EndFunc   ;==>_Search

 

Deye

Edited by Deye
cleanup

Share this post


Link to post
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...