Jump to content

Browse for Folder Dialog - Automation


storme
 Share

Recommended Posts

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
Link to comment
Share on other sites

Update due to a bug stopping it going beyond 2nd level.

Also had to add delays to allow for dialog to update.

Link to comment
Share on other sites

  • 1 month later...

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!

Link to comment
Share on other sites

  • 2 years later...
  • 9 months later...

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:

Link to comment
Share on other sites

  • 3 years later...

did you read this thread and try the code posted above? this is a very old thread. i would imagine this doesn't work on Win10. it's  code that doesn't work. poor sample usage to be sure. not even posted in a manner where it compiles and it must expect the dialog to be present. really bad. the code needs tidy to be run to even start reading it. The example should walk through the usage properly, which it does not. And navigating the Explorer under Windows 10 cannot be done like this from any of my test.

 

describe to us what you want to do. What app or site you are trying to automate. don't make us pull teeth. Supply YOUR code, what you have tried. 

Edited by Earthshine

My resources are limited. You must ask the right questions

 

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...