Jump to content



Photo

Browse for Folder Dialog - Automation


  • Please log in to reply
2 replies to this topic

#1 storme

storme

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 754 posts

Posted 12 August 2011 - 02:16 PM

G'day All
I asked elsewhere and no one had an automation script for the "Browse for Folder" Dialog.
If you don't know they are the dialog boxes called up by "FileSelectFolder" (in Autoit). They are used when you want the user to select a folder and want to ensure they select a folder that exists.

It took me a while as I had to work out how to traverse a SysTreeView32 but it does what I want it to do now. :mellow:
Thanks to LurchMan for putting me on the right track.
If you have any improvements or bugs please let me know.

Target for test script (give it something to shoot at)
MsgBox(0,"Selected Folder",FileSelectFolder ( "Just a test", "C:\"))


Test Script (just selects "c:\Windows" in the target dialog)

AutoIt         
#include <Array.au3> #Include <GuiTreeView.au3>     _BFF_SelectFolder("C:\windows")   MsgBox(0, "_BFF_SelectFolder Result", "@error = " & @error)   Exit   ; #FUNCTION# ==================================================================================================================== ; Name...........: _BFF_SelectFolder ; Description ...: Automates the "Browse for Folder" Dialog so you can specify with a standard path ; Syntax.........: _BFF_SelectFolder($sPath[, $bClickOK = True]) ; Parameters ....: $sPath       - Path to select in dialog ;               $bClickOK       - Optional: Click OK button. Default or True then click OK button ; Return values .: Success - returns True ;               Failure - False ;               |@Error  - 1 = "Browse for Folder" dialog not found ;               |@Error  - 2 = Drive letter not in path ;               |@Error  - 3 = unable to locate my computer in tree ;               |@Error  - 4 = unable to locate directory ; Author ........: Storm-E aka John Morrison ; Modified.......: ; Remarks .......: Thanks to JohnOne for his fix for the clickitem delay ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _BFF_SelectFolder($sPath, $bClickOK = True) Local $asPath ; holds drive and folder section(s) Local $next Sleep(500) ;Get handle of "Browse for Folder" dialog Local $HWND = ControlGetHandle("Browse for Folder", "", "[CLASS:SysTreeView32; INSTANCE:1]") If @error Then   Return SetError(1, 0, "") EndIf ; get first item - ya gota start somewhere :) Local $hCurrentItem = _GUICtrlTreeView_GetFirstItem($HWND) $hCurrentItem = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) ; items under desktop $asPath = StringSplit($sPath, "\") If $asPath[$asPath[0]] = "" Then $asPath[0] -= 1 ; eliminates blank entry if path has a trailng \ If StringRight($asPath[1], 1) <> ":" Then   Return SetError(2, 0, "") EndIf ;Find My Computer Local $hCurrentItemChild = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) ; get items child While StringRight(_GUICtrlTreeView_GetText($HWND, $hCurrentItemChild), 2) <> ":)"   $hCurrentItem = _GUICtrlTreeView_GetNextSibling($HWND, $hCurrentItem) ; Step to next item   If $hCurrentItem = 0 Then    ;Ran out of items so didn't find my computer    Return SetError(3, 0, "")   EndIf   $hCurrentItemChild = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) WEnd _GUICtrlTreeView_Expand($HWND, $hCurrentItem) _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem) Do   $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) Until $next <> $hCurrentItem ;Find drive $hCurrentItem = $hCurrentItemChild While StringLeft(StringRight(_GUICtrlTreeView_GetText($HWND, $hCurrentItem), 3), 2) <> $asPath[1]   $hCurrentItem = _GUICtrlTreeView_GetNextSibling($HWND, $hCurrentItem) ; Step to next item   If $hCurrentItem = 0 Then    ;Ran out of items so didn't find my computer    Return SetError(3, 0, "")   EndIf WEnd ;Needed for dialog to update _GUICtrlTreeView_Expand($HWND, $hCurrentItem) _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem) Do   $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) Until $next <> $hCurrentItem ;Find directory If $asPath[0] > 1 Then ; Check if only drive was specified   For $item = 2 To $asPath[0]    $hCurrentItem = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem)    _GUICtrlTreeView_Expand($HWND, $hCurrentItem)    _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem)    Do     $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem)    Until $next <> $hCurrentItem    While _GUICtrlTreeView_GetText($HWND, $hCurrentItem) <> $asPath[$item]     $hCurrentItem = _GUICtrlTreeView_GetNextSibling($HWND, $hCurrentItem) ; Step to next item     If $hCurrentItem = 0 Then     ;Ran out of items so didn't find directory     Return SetError(4, 0, "")     EndIf    WEnd    _GUICtrlTreeView_Expand($HWND, $hCurrentItem)    _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem)    Do     $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem)    Until $next <> $hCurrentItem   Next EndIf ;Needed for dialog to update _GUICtrlTreeView_Expand($HWND, $hCurrentItem) _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem) Do   $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) Until $next <> $hCurrentItem If $bClickOK Then   ;Click OK button   ControlClick("Browse for Folder", "", "[CLASS:Button; INSTANCE:1]") EndIf EndFunc   ;==>_BFF_SelectFolder


AutoIt         
; #FUNCTION# ==================================================================================================================== ; Name...........: _BFF_SelectFolder ; Description ...: Automates the "Browse for Folder" Dialog so you can specify with a standard path ; Syntax.........: _BFF_SelectFolder($sPath[, $bClickOK = True]) ; Parameters ....: $sPath       - Path to select in dialog ;               $bClickOK       - Optional: Click OK button. Default or True then click OK button ; Return values .: Success - returns True ;               Failure - False ;               |@Error  - 1 = "Browse for Folder" dialog not found ;               |@Error  - 2 = Drive letter not in path ;               |@Error  - 3 = unable to locate my computer in tree ;               |@Error  - 4 = unable to locate directory ; Author ........: Storm-E aka John Morrison ; Modified.......: ; Remarks .......: Thanks to JohnOne for his fix for the clickitem delay ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _BFF_SelectFolder($sPath, $bClickOK = True) Local $asPath ; holds drive and folder section(s) Local $next Sleep(500) ;Get handle of "Browse for Folder" dialog Local $HWND = ControlGetHandle("Browse for Folder", "", "[CLASS:SysTreeView32; INSTANCE:1]") If @error Then   Return SetError(1, 0, "") EndIf ; get first item - ya gota start somewhere :) Local $hCurrentItem = _GUICtrlTreeView_GetFirstItem($HWND) $hCurrentItem = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) ; items under desktop $asPath = StringSplit($sPath, "\") If $asPath[$asPath[0]] = "" Then $asPath[0] -= 1 ; eliminates blank entry if path has a trailng \ If StringRight($asPath[1], 1) <> ":" Then   Return SetError(2, 0, "") EndIf ;Find My Computer Local $hCurrentItemChild = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) ; get items child While StringRight(_GUICtrlTreeView_GetText($HWND, $hCurrentItemChild), 2) <> ":)"   $hCurrentItem = _GUICtrlTreeView_GetNextSibling($HWND, $hCurrentItem) ; Step to next item   If $hCurrentItem = 0 Then    ;Ran out of items so didn't find my computer    Return SetError(3, 0, "")   EndIf   $hCurrentItemChild = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) WEnd _GUICtrlTreeView_Expand($HWND, $hCurrentItem) _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem) Do   $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) Until $next <> $hCurrentItem ;Find drive $hCurrentItem = $hCurrentItemChild While StringLeft(StringRight(_GUICtrlTreeView_GetText($HWND, $hCurrentItem), 3), 2) <> $asPath[1]   $hCurrentItem = _GUICtrlTreeView_GetNextSibling($HWND, $hCurrentItem) ; Step to next item   If $hCurrentItem = 0 Then    ;Ran out of items so didn't find my computer    Return SetError(3, 0, "")   EndIf WEnd ;Needed for dialog to update _GUICtrlTreeView_Expand($HWND, $hCurrentItem) _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem) Do   $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) Until $next <> $hCurrentItem ;Find directory If $asPath[0] > 1 Then ; Check if only drive was specified   For $item = 2 To $asPath[0]    $hCurrentItem = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem)    _GUICtrlTreeView_Expand($HWND, $hCurrentItem)    _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem)    Do     $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem)    Until $next <> $hCurrentItem    While _GUICtrlTreeView_GetText($HWND, $hCurrentItem) <> $asPath[$item]     $hCurrentItem = _GUICtrlTreeView_GetNextSibling($HWND, $hCurrentItem) ; Step to next item     If $hCurrentItem = 0 Then     ;Ran out of items so didn't find directory     Return SetError(4, 0, "")     EndIf    WEnd    _GUICtrlTreeView_Expand($HWND, $hCurrentItem)    _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem)    Do     $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem)    Until $next <> $hCurrentItem   Next EndIf ;Needed for dialog to update _GUICtrlTreeView_Expand($HWND, $hCurrentItem) _GUICtrlTreeView_ClickItem($HWND, $hCurrentItem) Do   $next = _GUICtrlTreeView_GetFirstChild($HWND, $hCurrentItem) Until $next <> $hCurrentItem If $bClickOK Then   ;Click OK button   ControlClick("Browse for Folder", "", "[CLASS:Button; INSTANCE:1]") EndIf EndFunc   ;==>_BFF_SelectFolder


Hope it helps someone out.
John Morrison

Edit
15/08/2011 - Fixed a Bug that stops routine from going beyond 2 levels deep.
01/09/2011 - Fix from JohnOne to wait untill each level is navigated..THANKS!

Edited by storme, 31 August 2011 - 02:28 PM.






#2 storme

storme

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 754 posts

Posted 15 August 2011 - 10:06 AM

Update due to a bug stopping it going beyond 2nd level.
Also had to add delays to allow for dialog to update.

#3 MachEnergy

MachEnergy

    Seeker

  • New Members
  • 1 posts

Posted 27 September 2011 - 09:47 PM

This looks great! Thanks for putting this out there for everybody, as it is exactly what I just discovered I needed.

What versions of Windows have you tested this script on? I'm finding that with Win7 and Vista, the newer Folder Browser style is failing. As a quick fix for Win7, I automated sending {RIGHT}{RIGHT}{TAB} with some short sleeps in between, and that got this script working wonderfully. When I tried it in WinXP, it always shows error code 3. I haven't yet figured out a good way to implement the same Send() fix I did for Vista and 7. Perhaps tomorrow....

Also, I'm new to these forums, so I'm curious why your post has two code windows where the 2nd window appears to be just the _BFF_SelectFolder defintion found in the 1st window. At quick skim, I see no differences.

Thanks again!




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users