Jump to content
Sign in to follow this  
myspacee

Update file list on user digit

Recommended Posts

myspacee

Hello,

at work ask me to replace and old tool. In a folder we have a lot of files with internal code (eg: Yc0daW)

Existing tool filter and update filename during user input in realtime.

Try to script something but works only on pressing a button:

#include <GuiConstantsEx.au3>
#include <File.au3>
#include <Array.au3>

;GUI
GUICreate("Automation", 300, 500)
$File_filter = GUICtrlCreateInput("", 10, 10, 280, 20)
$list_update = GUICtrlCreateButton("Update", 10, 35, 75, 20)
$list_files = GUICtrlCreateList("", 10, 60, 280, 300)


GUISetState(@SW_SHOW)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $list_update
            $sFolder = @WindowsDir & "\"
            $User_filter = ControlGetText("Automation", "", "Edit1")
            GUICtrlSetData($list_files, "")
            
            
            Local $FileList = _FileListToArray($sFolder, $User_filter & "*.*")

            If @error = 1 Then
                MsgBox(0, "", "No Folders Found.")
                Exit
            EndIf
            If @error = 4 Then
                MsgBox(0, "", "No Files Found.")
                Exit
            EndIf

            For $i = 1 To $FileList[0]
                GUICtrlSetData($list_files, $FileList[$i])
            Next
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

Can you help me to write some code that allow realtime update on user digit ?

thank you,

m.

Share this post


Link to post
Share on other sites
mikell

?

#include <GuiConstantsEx.au3>
#include <File.au3>
#include <Array.au3>
#include <WindowsConstants.au3> 
#include <EditConstants.au3>

;GUI
GUICreate("Automation", 300, 500)
$File_filter = GUICtrlCreateInput("", 10, 10, 280, 20)
$list_update = GUICtrlCreateButton("Update", 10, 35, 75, 20)
$list_files = GUICtrlCreateList("", 10, 60, 280, 300)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND") 

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd


Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)  
 #forceref $hWnd, $Msg, $lParam
 Switch BitAND($wParam, 0x0000FFFF)
    Case $File_filter
        If BitShift($wParam, 16) = $EN_UPDATE Then
           $sFolder = @DesktopDir & "\"
            $User_filter = GuiCtrlRead($File_filter)
            GUICtrlSetData($list_files, "")
            
            Local $FileList = _FileListToArray($sFolder, $User_filter & "*.*")
            If @error = 1 Then
                MsgBox(0, "", "No Folders Found.")
                Exit
            EndIf
            If @error = 4 Then
                MsgBox(0, "", "No Files Found.")
                Exit
            EndIf

            For $i = 1 To $FileList[0]
                GUICtrlSetData($list_files, $FileList[$i])
            Next
        EndIf
EndSwitch
  Return 'GUI_RUNDEFMSG'
EndFunc  ;==> _WM_COMMAND

Share this post


Link to post
Share on other sites
myspacee

Thank you for reply,

i'm bit rusty, sorry.

The function works but on large amount of files (>30k), is slow if compared to old VB tool...

Is there any way to speedup things ?

Thank you again for your time,

m.

Share this post


Link to post
Share on other sites
mikell

This slowness is not surprising, it's caused by the repeated use of _FileListToArray inside the WM_COMMAND

Anyway such a practice is not recommended

So the best way could be to use _FileListToArray once, and then make the filtering by working directly on the array or even better on a string obtained from the array

Edit

Maybe this ?

#include <GuiConstantsEx.au3>
#include <File.au3>
#include <Array.au3>
#include <WindowsConstants.au3> 
#include <EditConstants.au3>

$sFolder = @WindowsDir & "\"
Local $FileList = _FileListToArray($sFolder, "*.*")
_ArrayDelete($FileList, 0)
$sList = "|" & _ArrayToString($FileList) & "|"

;GUI
GUICreate("Automation", 300, 500)
$File_filter = GUICtrlCreateInput("", 10, 10, 280, 20)
$list_update = GUICtrlCreateButton("Update", 10, 35, 75, 20)
$list_files = GUICtrlCreateList("", 10, 60, 280, 300)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd


Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)  
 #forceref $hWnd, $Msg, $lParam
 Switch BitAND($wParam, 0x0000FFFF)
    Case $File_filter
        If BitShift($wParam, 16) = $EN_UPDATE Then
            $User_filter = GuiCtrlRead($File_filter)
            $char = StringRight($User_filter, 1)
            $left = StringTrimRight($User_filter, 1)
            $sList = StringRegExpReplace($sList, '(?i)(?<=\|)(\Q' & $left & '\E[^' & $char & '].+?\|)', "")       
            If $sList = "|" Then
                MsgBox(0, "", "No Files Found.")
                Exit
           EndIf
           GUICtrlSetData($list_files, $sList)
        EndIf
EndSwitch
  Return 'GUI_RUNDEFMSG'
EndFunc  ;==> _WM_COMMAND
Edited by mikell

Share this post


Link to post
Share on other sites
minusuits

Very Good Discussion ..

Thanks a lot..

Share this post


Link to post
Share on other sites
kylomas

@myspacee - try this (adapted from mikell's code)...

#include <GuiConstantsEx.au3>
#include <File.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>

$sFolder = @WindowsDir & "\"
Local $FileList = _FileListToArray($sFolder, "*.*")
_ArrayDelete($FileList, 0)
$sList = "|" & _ArrayToString($FileList) & "|"

;GUI
GUICreate("Automation", 300, 500)
$File_filter = GUICtrlCreateInput("", 10, 10, 280, 20)
$list_update = GUICtrlCreateButton("Update", 10, 35, 75, 20)
$list_files = GUICtrlCreateList("", 10, 60, 280, 300)
$dummy = guictrlcreatedummy()
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
        case $dummy
            $alist = stringregexp($slist,'\|(' & guictrlread($File_filter) & '[^\|]+)',3)
            if @error = 1 then
                guictrlsetdata($list_files,'|*no files found*')
            else
                guictrlsetdata($list_files,'|' & _arraytostring($alist))
            endif
    EndSwitch
WEnd

Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
 #forceref $hWnd, $Msg, $lParam
 Switch BitAND($wParam, 0x0000FFFF)
    Case $File_filter
        If BitShift($wParam, 16) = $EN_UPDATE Then
            GUICtrlSendToDummy($dummy)
        EndIf
EndSwitch
  Return 'GUI_RUNDEFMSG'
EndFunc  ;==> _WM_COMMAND

kylomas

edit: still getting significant lag time for dir's above 5k

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites
kylomas

This works a little bit better...about a 1 second lag when the list is completely refreshed (16K entries)...

#include <GuiConstantsEx.au3>
#include <File.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>

$sFolder = @WindowsDir & "\"
$sFolder = 'k:\sd\sd0100\mlb\boxes\'
Local $FileList = _FileListToArray($sFolder, "*.*")
_ArrayDelete($FileList, 0)
$sList = "|" & _ArrayToString($FileList) & "|"

;GUI
GUICreate("Automation", 300, 500)
$File_filter = GUICtrlCreateInput("", 10, 10, 280, 20)
$list_files = GUICtrlCreateList("", 10, 60, 280, 300)
guictrlsetdata($list_files,$slist)
$dummy = guictrlcreatedummy()
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

local $tlist, $tstr

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
        case $dummy
            $tlist = ''
            $tstr = guictrlread($File_filter)
            if stringlen($tstr) = 0 Then
                guictrlsetdata($list_files,$slist)
                ContinueLoop
            endif
            for $1 = 0 to ubound($FileList) - 1
                if stringleft($FileList[$1],stringlen($tstr)) = $tstr then $tlist &= $FileList[$1] & '|'
            Next
            guictrlsetdata($list_files,'|'& $tlist)
            $tstr =''
    EndSwitch
WEnd

Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
 #forceref $hWnd, $Msg, $lParam
 Switch BitAND($wParam, 0x0000FFFF)
    Case $File_filter
        If BitShift($wParam, 16) = $EN_UPDATE Then
            GUICtrlSendToDummy($dummy)
        EndIf
EndSwitch
  Return 'GUI_RUNDEFMSG'
EndFunc  ;==> _WM_COMMAND

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

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  

×