Sign in to follow this  
Followers 0
storme

Browse for Folder Dialog - Automation

5 posts in this topic

#1 ·  Posted (edited)

G'day All

I 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)

#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

; #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
1 person likes this

Share this post


Link to post
Share on other sites



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!

Share this post


Link to post
Share on other sites

it error = 1 ;"Browse for Folder" dialog not found

please help me

Share this post


Link to post
Share on other sites

Hey, you saved my day. Thanks.

One comment, though: I added the handle of the FolderDialog as a parameter. The title is not always the standard text, and just searching for the ControlID did not work well. Note: needs to be replaced at the bottom when clicking ok as well.

Note2: there are dialogs which enable/disable 'ok' based on selected content; will do an error check for that as well

But apart from that - great work ! :shifty:

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  
Followers 0