Jump to content
LarsJ

Automating Windows Explorer

Recommended Posts

LarsJ

There are a lot of empty areas in Windows Explorer. Which part of the empty areas do you want to double click to go up one folder level? I'm not familiar with QTtabBar.

Share this post


Link to post
Share on other sites
sceatch

Thanks for answer.

On any empty area of opened folder, except folders and folder names.

scrsht.jpg

Edited by sceatch

Share this post


Link to post
Share on other sites
LarsJ
sceatch

Ok, thanks. I ll post it here, if i can do it myself.

Share this post


Link to post
Share on other sites
junkew

I do not think there is a direct way to get whitespace area

My logic would be

1. Activate the window where you want to look for whitespace
2. Go to right bottom based on the width, height, x, y properties
3. Go up in pixels about 5% from height and go left about 5% from width or initially start just per 1 pixel up/left
4. getElementFromPoint 
5. if Element equal to windowelement then you have whitespace area
6. if not repeat 3
    

 

Edited by junkew

Share this post


Link to post
Share on other sites
sceatch
23 hours ago, junkew said:

I do not think there is a direct way to get whitespace area

My logic would be

1. Activate the window where you want to look for whitespace
2. Go to right bottom based on the width, height, x, y properties
3. Go up in pixels about 5% from height and go left about 5% from width or initially start just per 1 pixel up/left
4. getElementFromPoint 
5. if Element equal to windowelement then you have whitespace area
6. if not repeat 3
    

 

Wow. A little bit difficult )

 I ll try to disassamble a QTTabBar program, and try to find a code in it....

Edited by sceatch

Share this post


Link to post
Share on other sites
LarsJ
junkew
#include <WinAPI.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>
Example()

Func Example()
    ; Retrieve a list of window handles.
    Local $aList = WinList()

    ; Loop through the array displaying only visable windows with a title.
    For $i = 1 To $aList[0][0]
        If $aList[$i][0] <> "" And BitAND(WinGetState($aList[$i][1]), 2) Then
            $hWND=$aList[$i][1]
            $wClass=_WinAPI_GetClassName($hWnd)
            if $wClass="CabinetWClass" then
                consolewrite("Title: " & $aList[$i][0] & " Handle: " & $hWnd &  " Class: " & $wClass & @CRLF )
                $controlTxt="[CLASS:DirectUIHWND; INSTANCE:3]"
                ; Retrieve the position x, y and size (width and height)
                Local $aPos = controlgetpos($hwnd,"",$controltxt)
                Local $aHandle = controlgethandle($hwnd,"",$controlTxt)
                consolewrite($apos[0] & $apos[1] & $apos[2] & $apos[3])
;~              _UIA_DrawRect($apos[0], $apos[1], $apos[0]+$apos[2], $apos[1] + $apos[3])
;~              left,right,top,bottom
                _UIA_DrawRect($apos[0], $apos[0]+$apos[2], $apos[1],$apos[1]+$apos[3])
;~              mousemove($apos[0]+5,$apos[1]+30)
                mouseclick("left",$apos[0]+5,$apos[1]+30,2)



            endif
        endif
    Next

EndFunc   ;==>Example


; Draw rectangle on screen.
Func _UIA_DrawRect($tLeft, $tRight, $tTop, $tBottom, $color = 0xFF, $PenWidth = 4)
    Local $hDC, $hPen, $obj_orig, $x1, $x2, $y1, $y2
    $x1 = $tLeft
    $x2 = $tRight
    $y1 = $tTop
    $y2 = $tBottom
    $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop)
    $hPen = _WinAPI_CreatePen($PS_SOLID, $PenWidth, $color)
    $obj_orig = _WinAPI_SelectObject($hDC, $hPen)

    _WinAPI_DrawLine($hDC, $x1, $y1, $x2, $y1) ; horizontal to right
    _WinAPI_DrawLine($hDC, $x2, $y1, $x2, $y2) ; vertical down on right
    _WinAPI_DrawLine($hDC, $x2, $y2, $x1, $y2) ; horizontal to left right
    _WinAPI_DrawLine($hDC, $x1, $y2, $x1, $y1) ; vertical up on left

    ; clear resources
    _WinAPI_SelectObject($hDC, $obj_orig)
    _WinAPI_DeleteObject($hPen)
    _WinAPI_ReleaseDC(0, $hDC)
EndFunc   ;==>_UIA_DrawRect

 

Share this post


Link to post
Share on other sites
sceatch

junkew, I run this script and nothing happens. Dont know what to do?

Share this post


Link to post
Share on other sites
junkew

Check help file for winlist and run that example. dumps all your mainwindows. helps in understanding.

script first selects the first explorer.

Then within that third control of directuiwind is selected.

Please check with au3inf your area with controls and post output here.probably change this line

$controlTxt="[CLASS:DirectUIHWND; INSTANCE:3]"
Edited by junkew
Add info

Share this post


Link to post
Share on other sites
LarsJ

The idea to execute a function when you click in empty space is very interesting.

In this example a mouse hook is used to detect double click in empty space of the listview in Windows Explorer right pane window (or File Explorer as it's called in Windows 10). Then the Back button in the navigation toolbar is clicked to navigate to the previous folder. You can open several Explorer windows.

If you limit the empty space to the listview in the right pane window it's easy to detect empty space: In empty space of a listview the control under the mouse is the listview itself. If it isn't empty space the control under the mouse is a listview item or a child control of a listview item eg. an edit control.

;#AutoIt3Wrapper_UseX64=n

#include <WinAPI.au3>
#include "CUIAutomation2.au3"

Opt( "MustDeclareVars", 1 )

Global $hHook, $hRightPaneWnd

Example()

Func Example()
  ; Press Esc to quit
  HotKeySet( "{ESC}", "Quit" )
  OnAutoItExitRegister( "OnAutoItExit" )

  ; Low level mouse hook to catch double clicks: Executes LowLevelMouseProc() on double click
  $hHook = _WinAPI_SetWindowsHookEx( $WH_MOUSE_LL, DllCallbackGetPtr( DllCallbackRegister( "LowLevelMouseProc", "long", "int;wparam;lparam" ) ), _WinAPI_GetModuleHandle( 0 ) )
  LowLevelMouseProc( 0, 0, 0 ) ; Initialize $hTimer, $iDoubleClickSpeed and $oUIAutomation variables

  ; Wait for double clicks
  While 1
    Sleep( 50 )
  WEnd
EndFunc

Func Quit()
  Exit
EndFunc

Func OnAutoItExit()
  _WinAPI_UnhookWindowsHookEx( $hHook )
EndFunc

Func LowLevelMouseProc( $iCode, $wParam, $lParam )
  Static $hTimer = TimerInit(), $iDoubleClickSpeed = 0, $hExplorer, $fXP = ( @OSVersion = "WIN_XP" )
  Static $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
  If $iDoubleClickSpeed = 0 Then
    $iDoubleClickSpeed = RegRead( "HKEY_CURRENT_USER\Control Panel\Mouse", "DoubleClickSpeed" )
    If @error Then $iDoubleClickSpeed = 500
  EndIf
  If $iCode = 0 And $wParam = 0 And $lParam = 0 Then Return

  If $iCode < 0 Then Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )

  If $wParam = 0x0201 Then ; 0x0201 = $WM_LBUTTONDOWN 

    If TimerDiff( $hTimer ) > $iDoubleClickSpeed Then
      ; First click

      ; Any open Explorer windows? Windows Explorer on XP, Vista, 7, 8, 10
      Local $aExplorer = WinList( "[REGEXPCLASS:^(Cabinet|Explore)WClass$]" )
      If $aExplorer[0][0] = 0 Then
        ConsoleWrite( "No open Explorer windows" & @CRLF & @CRLF )
        Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
      EndIf

      ; Get a window to check that mouse click is inside an Explorer right pane
      ; listview. We want the same window as returned by _WinAPI_WindowFromPoint
      ; for a point inside an Explorer right pane listview.
      Local $iExplorer = 0
      ReDim $aExplorer[$aExplorer[0][0]+1][3]
      For $i = 1 To $aExplorer[0][0]
        $hRightPaneWnd = 0
        GetRightPaneWnd( $aExplorer[$i][1] )
        If $hRightPaneWnd Then
          $aExplorer[$i][2] = $hRightPaneWnd
          $iExplorer += 1
        EndIf
      Next
      If Not $iExplorer Then _
        Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )

      ; _WinAPI_WindowFromPoint is used to check if a mouse click is inside an Explorer listview
      ; _WinAPI_WindowFromPoint returns the proper handle only if Explorer is the topmost window
      Local $tPoint = _WinAPI_GetMousePos()
      Local $hWindow = _WinAPI_WindowFromPoint( $tPoint )
      For $i = 1 To $aExplorer[0][0]
        If $hWindow = $aExplorer[$i][2] Then ExitLoop
      Next
      If $i > $aExplorer[0][0] Then
        ConsoleWrite( "Mouse click not inside Explorer listview" & @CRLF & @CRLF )
        Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
      EndIf

      ; Explorer handle
      $hExplorer = $aExplorer[$i][1]

      ; Reset timer to check if it's a double click
      $hTimer = TimerInit()

    Else
      ; Double click

      ConsoleWrite( "Double click inside Explorer listview" & @CRLF )

      ; Get control type and class name
      Local $pElement, $oElement, $iControlType, $sClassName
      $oUIAutomation.ElementFromPoint( _WinAPI_GetMousePos(), $pElement )
      $oElement = ObjCreateInterface( $pElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
      $oElement.GetCurrentPropertyValue( $UIA_ControlTypePropertyId, $iControlType )
      $oElement.GetCurrentPropertyValue( $UIA_ClassNamePropertyId, $sClassName )

      ; If it's a double click in empty space of a listview the control under the mouse is the listview itself.
      ; A double click not in empty space would have been a double click at a listview item or a child control.

      ; Double click in empty space of listview?
      If Not ( $iControlType = $UIA_ListControlTypeId _
         And ( $sClassName = "UIItemsView" Or $sClassName = "SysListView32" ) ) Then
        ConsoleWrite( "Double click not in empty space of listview" & @CRLF & @CRLF )
        Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
      EndIf

      ConsoleWrite( "Double click in empty space of listview" & @CRLF )

      ; Perform double click action
      ; Go to previous folder by clicking the Back button in the navigation toolbar

      ; Explorer object
      Local $pExplorer, $oExplorer
      $oUIAutomation.ElementFromHandle( $hExplorer, $pExplorer ) ; $hExplorer handle is calculated above
      $oExplorer = ObjCreateInterface( $pExplorer, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
      If Not IsObj( $oExplorer ) Then
        ConsoleWrite( "$oExplorer ERR" & @CRLF & @CRLF )
        Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
      EndIf
      ConsoleWrite( "$oExplorer OK" & @CRLF )

      Local $pCondition1, $pCondition2, $pCondition
      Local $pButton, $oButton

      If $fXP Then ; Windows XP

        ; The Back button is the first splitbutton

        ; Condition to find Back button
        $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_SplitButtonControlTypeId, $pCondition )
        If Not $pCondition Then
          ConsoleWrite( "$pCondition (button) ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$pCondition (button) OK" & @CRLF )

        ; Find Back button
        $oExplorer.FindFirst( $TreeScope_Descendants, $pCondition, $pButton )
        $oButton = ObjCreateInterface( $pButton, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
        If Not IsObj( $oButton ) Then
          ConsoleWrite( "$oButton ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$oButton OK" & @CRLF )

      Else ; Other Windows versions

        ; The Back button is the first button in the first ToolbarWindow32-class toolbar

        ; Condition to find toolbar
        $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ToolBarControlTypeId, $pCondition1 )
        If Not $pCondition1 Then
          ConsoleWrite( "$pCondition1 (toolbar) ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$pCondition1 (toolbar) OK" & @CRLF )

        ; Condition to find ToolbarWindow32-class
        $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "ToolbarWindow32", $pCondition2 )
        If Not $pCondition2 Then
          ConsoleWrite( "$pCondition2 (toolbar) ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$pCondition2 (toolbar) OK" & @CRLF )

        ; And condition, both conditions
        $oUIAutomation.CreateAndCondition( $pCondition1, $pCondition2, $pCondition )
        If Not $pCondition Then
          ConsoleWrite( "$pCondition (toolbar) ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$pCondition (toolbar) OK" & @CRLF )

        ; Find toolbar
        Local $pToolbar, $oToolbar
        $oExplorer.FindFirst( $TreeScope_Descendants, $pCondition, $pToolbar )
        $oToolbar = ObjCreateInterface( $pToolbar, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
        If Not IsObj( $oToolbar ) Then
          ConsoleWrite( "$oToolbar ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$oToolbar OK" & @CRLF )

        ; Condition to find Back button
        $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId, $pCondition )
        If Not $pCondition Then
          ConsoleWrite( "$pCondition (button) ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$pCondition (button) OK" & @CRLF )

        ; Find Back button
        $oToolbar.FindFirst( $TreeScope_Descendants, $pCondition, $pButton )
        $oButton = ObjCreateInterface( $pButton, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
        If Not IsObj( $oButton ) Then
          ConsoleWrite( "$oButton ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$oButton OK" & @CRLF )

      EndIf

      ; Button enabled?
      Local $bEnabled
      $oButton.CurrentIsEnabled( $bEnabled )
      If Not $bEnabled Then ConsoleWrite( "Disabled" & @CRLF & @CRLF )

      If $bEnabled Then
        ; Get Invoke object
        Local $pInvoke, $oInvoke
        $oButton.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke )
        $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern )
        If Not IsObj( $oInvoke ) Then
          ConsoleWrite( "$oInvoke ERR" & @CRLF & @CRLF )
          Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
        EndIf
        ConsoleWrite( "$oInvoke OK" & @CRLF & @CRLF )

        ; Invoke (click) button
        $oInvoke.Invoke()
      EndIf

    EndIf

  EndIf

  Return _WinAPI_CallNextHookEx( $hHook, $iCode, $wParam, $lParam )
EndFunc

; The window of interest is the child of the SHELLDLL_DefView-class window.
; This window is one of the right pane windows which contains the listview.
; The window is the same as returned by _WinAPI_WindowFromPoint function.
Func GetRightPaneWnd( $hParent )
  If Not $hParent Then Return
  Local $hChild = _WinAPI_GetWindow( $hParent, $GW_CHILD )
  While $hChild
    If _WinAPI_GetClassName( $hChild ) = "SHELLDLL_DefView" Then
      $hRightPaneWnd = _WinAPI_GetWindow( $hChild, $GW_CHILD )
      ; A SysListView32-class listview is three levels down
      If _WinAPI_GetClassName( $hRightPaneWnd ) <> "DirectUIHWND" Then
        $hRightPaneWnd = _WinAPI_GetWindow( $hRightPaneWnd, $GW_CHILD )
        $hRightPaneWnd = _WinAPI_GetWindow( $hRightPaneWnd, $GW_CHILD )
        $hRightPaneWnd = _WinAPI_GetWindow( $hRightPaneWnd, $GW_CHILD )
      EndIf
      $hChild = 0
    EndIf
    GetRightPaneWnd( $hChild )
    $hChild = _WinAPI_GetWindow( $hChild, $GW_HWNDNEXT )
  WEnd
EndFunc

If you run the example in SciTE you should see output similar to this in the console:

No open Explorer windows

Mouse click not inside Explorer listview

Double click inside Explorer listview
Double click not in empty space of listview

Double click inside Explorer listview
Double click in empty space of listview
$oExplorer OK
$pCondition1 (toolbar) OK
$pCondition2 (toolbar) OK
$pCondition (toolbar) OK
$oToolbar OK
$pCondition (button) OK
$oButton OK
Disabled

Double click inside Explorer listview
Double click in empty space of listview
$oExplorer OK
$pCondition1 (toolbar) OK
$pCondition2 (toolbar) OK
$pCondition (toolbar) OK
$oToolbar OK
$pCondition (button) OK
$oButton OK
$oInvoke OK

You need AutoIt 3.3.10 or later. Tested on Windows 10/7 32/64 bit and Windows XP 32 bit. I've not been able to test under Windows Vista or Windows 7 where Windows Explorer is based on a SysListView32-class listview. Let me know if there are any issues.

The zip contains all code: DoubleClick.7z

Edited by LarsJ

Share this post


Link to post
Share on other sites
sceatch

LarsJ, It Works!!! )))

Thanks you a lot!!! I dont think it would be so difficult! Really sorry fot that.

Just one moment - when script goes me back to previous folder, it highlights the folder where the cursor is now located. Dont know how to explain correctly. (I work in WinXP x86)

Edited by sceatch

Share this post


Link to post
Share on other sites
LarsJ
SharkyEXE

LarsJ

Hello

1) My Operating System; Microsoft Windows 7 Professional Service Pack 1 x64

2) User Control Account: Off

3) My Autoit Version: 3.3.14.2

Block 1

1) I use GetSetIconView.au3 on this post https://www.autoitscript.com/forum/topic/162905-automating-windows-explorer/?do=findComment&comment=1227436 to Change Icon View on " Details " in " Desktop -> Computer "

#include "G:\P\AutoIt3\P\Includes\AutomatingWindowsExplorer.au3"
Opt( "MustDeclareVars", 1 )
ShellExecuteWait ( "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" )
WinWait ( "Computer", "" )
WinActivate ( "Computer", "" )
WinWaitActive ( "Computer", "" )
WinSetOnTop ( "Computer", "", 1 )
Example()
While WinExists ( "Computer", "" )
WinClose ( "Computer", "" )
Sleep ( 1000 )
WEnd

Func Example()
    ; Windows Explorer on XP, Vista, 7, 8
    Local $hExplorer = WinGetHandle( "[REGEXPCLASS:^(Cabinet|Explore)WClass$]" )
    If Not $hExplorer Then
        MsgBox( 0, "Automating Windows Explorer", "Could not find Windows Explorer. Terminating." )
        Return
    EndIf

    ; Get an IShellBrowser interface
    GetIShellBrowser( $hExplorer )
    If Not IsObj( $oIShellBrowser ) Then
        MsgBox( 0, "Automating Windows Explorer", "Could not get an IShellBrowser interface. Terminating." )
        Return
    EndIf

    ; Get other interfaces
    GetShellInterfaces()

    ; Get current icon view
    Local $view = GetIconView()

    Local $iView, $iSize
    If IsArray( $view ) Then ; OS > XP
        $iView = $view[0] ; Icon view
        $iSize = $view[1] ; Icon size
        If $iView <> $FVM_DETAILS Then    ; Not details view
            SetIconView( $FVM_DETAILS, 16 ) ; Set details view
        ; ElseIf $iView <> $FVM_ICON Then   ; Not icon view
            ; SetIconView( $FVM_ICON, 48 )    ; Set icon view
        EndIf
        Sleep( 3000 )                     ; Wait 3 seconds
        ; SetIconView( $iView, $iSize )     ; Restore old view

    Else ; OS = XP
        $iView = $view
        If $iView <> $FVM_DETAILS Then    ; Not details view
            SetIconView( $FVM_DETAILS )     ; Set details view
        ElseIf $iView <> $FVM_ICON Then   ; Not icon view
            SetIconView( $FVM_ICON )        ; Set icon view
        EndIf
        Sleep( 3000 )                     ; Wait 3 seconds
        SetIconView( $iView )             ; Restore old view
    EndIf
EndFunc

2) I Run File " C:\Windows\Notepad.exe "

3) I See Windows with Title Name " Untitled - Notepad "

4) In Windows with Title Name " Untitled - Notepad " I Make One Click Left Button Mouse On Button " File "

5) I See Menu , In Menu I Make One Click Left Button Mouse On Button " Save As... "

6) I See Windows with Title Name " Save As "

7) In Windows with Title Name " Save As " Icon View as " Large Icon "

8) LarsJ , Please Make " GetSetIconViewOnNotepad.au3 " file To Change Icon View on " Details " In Windows with Title Name " Save As " In " C:\Windows\Notepad.exe "

Block 2

1) On " DeskTop " I Make One Click Right Button Mouse

2) I See Menu , In Menu I Make One Click Right Button Mouse On Stroke " View "

3) I See Menu , In Menu I Make One Click Right Button Mouse On Stroke " Small Icons "

4) LarsJ , Please Make " GetSetIconViewOnDesktop.au3 " file To Change Icon View on " Small Icons " On " DeskTop "

4) Thank You!

Share this post


Link to post
Share on other sites
LarsJ

SharkyEXE

Block 2: This version of the code does not support the desktop. I'll probably add support for the desktop at some point, but it'll not be right now.

Block 1: This code cannot be used for an Open or "Save as" dialog.

The tasks can be solved with standard automation by the Windows and Controls functions. I'll recommend you to add a post in the General Help and Support forum.

Share this post


Link to post
Share on other sites
Michael_1106

LarsJ,

Thank you for these functions.  I really needed something like this.

My question is:  How can I use SetCurrentFolder to go to one of my folders?  Like
"C:\My Folder\My Subfolder"

I've read through the examples, but wasn't able to figure it out.  Will I need to use a pointer to the PIDL of the folder?  If so, how do I get that?

Thank you.

– Michael

Share this post


Link to post
Share on other sites
LarsJ

Michael, Welcome to the AutoIt forums. Yes, you need the PIDL but you can easily get it with _WinAPI_ShellILCreateFromPath. You do it this way:

1. Save this code somewhere on your disk eg. C:\Windows\Temp\GotoFolder.au3

#include <WinAPIShellEx.au3>
#include "Includes\AutomatingWindowsExplorer.au3"

Opt( "MustDeclareVars", 1 )

Example()

Func Example()
  ; Windows Explorer on XP, Vista, 7, 8
  Local $hExplorer = WinGetHandle( "[REGEXPCLASS:^(Cabinet|Explore)WClass$]" )
  If Not $hExplorer Then
    MsgBox( 0, "Automating Windows Explorer", "Could not find Windows Explorer. Terminating." )
    Return
  EndIf

  ; Get an IShellBrowser interface
  GetIShellBrowser( $hExplorer )
  If Not IsObj( $oIShellBrowser ) Then
    MsgBox( 0, "Automating Windows Explorer", "Could not get an IShellBrowser interface. Terminating." )
    Return
  EndIf

  ; Get other interfaces
  GetShellInterfaces()

  ; Get PIDL from folder
  Local $pFolder = _WinAPI_ShellILCreateFromPath( "C:\My Folder\My Subfolder" )

  ; Set folder
  SetCurrentFolder( $pFolder, $SBSP_ABSOLUTE )

  ; Free memory
  _WinAPI_CoTaskMemFree( $pFolder )
EndFunc

You can get the include files in bottom of post 7.

2. Right click the file, create shortcut, copy shortcut to desktop

3. Windows explorer must be open, "C:\My Folder\My Subfolder" must exist, double click the shortcut
    Now "C:\My Folder\My Subfolder" should be the current folder

Note that this is a lot of code to execute just to set the current folder. This code should only be used if you also need to do other things, eg. to use some of the other examples in post 7.

There are easier ways to set the current folder. You can Create a new question in the "General Help and Support" forum if you are in doubt about something.

Regards Lars.

Share this post


Link to post
Share on other sites
LarsJ

Make item visible.

The following is an answer to this question.

#include "CUIAutomation2.au3"

Opt( "MustDeclareVars", 1 )

MakeItemVisible( "ItemName" )

Func MakeItemVisible( $sItemName )
  ; Windows Explorer on XP, Vista, 7, 8, 10
  Local $hExplorer = WinGetHandle( "[REGEXPCLASS:^(Cabinet|Explore)WClass$]" )
  If Not $hExplorer Then Return ConsoleWrite( "$hExplorer ERR" & @CRLF )
  ConsoleWrite( "$hExplorer OK" & @CRLF )

  ; Create UI Automation object
  Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
  If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF )
  ConsoleWrite( "$oUIAutomation OK" & @CRLF )

  ; Get Explorer object
  Local $pExplorer, $oExplorer
  $oUIAutomation.ElementFromHandle( $hExplorer, $pExplorer )
  $oExplorer = ObjCreateInterface( $pExplorer, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oExplorer ) Then Return ConsoleWrite( "$oExplorer ERR" & @CRLF )
  ConsoleWrite( "$oExplorer OK" & @CRLF )

  ; Get ListView (right pane window) object
  Local $pCondition, $pListView, $oListView
  $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ListControlTypeId, $pCondition )
  $oExplorer.FindFirst( $TreeScope_Descendants, $pCondition, $pListView )
  $oListView = ObjCreateInterface( $pListView, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oListView ) Then Return ConsoleWrite( "$oListView ERR" & @CRLF )
  ConsoleWrite( "$oListView OK" & @CRLF )

  ; Find visible item by name
  Local $pVisibleItem, $oVisibleItem
  $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, $sItemName, $pCondition )
  $oListView.FindFirst( $TreeScope_Descendants, $pCondition, $pVisibleItem )
  $oVisibleItem = ObjCreateInterface( $pVisibleItem, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If IsObj( $oVisibleItem ) Then Return ConsoleWrite( "$oVisibleItem OK" & @CRLF )

  ; Continue only if item is non-visible

  ConsoleWrite( "$oVisibleItem ERR" & @CRLF )

  ; Create ItemContainer object
  Local $pItemContainer, $oItemContainer
  $oListView.GetCurrentPattern( $UIA_ItemContainerPatternId, $pItemContainer )
  $oItemContainer = ObjCreateInterface( $pItemContainer, $sIID_IUIAutomationItemContainerPattern, $dtagIUIAutomationItemContainerPattern )
  If Not IsObj( $oItemContainer ) Then Return ConsoleWrite( "$oItemContainer ERR" & @CRLF )
  ConsoleWrite( "$oItemContainer OK" & @CRLF )

  ; Find non-visible item by name
  Local $pNonVisibleItem, $oNonVisibleItem
  $oItemContainer.FindItemByProperty( 0, $UIA_NamePropertyId, $sItemName, $pNonVisibleItem )
  $oNonVisibleItem = ObjCreateInterface( $pNonVisibleItem, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oNonVisibleItem ) Then Return ConsoleWrite( "$oNonVisibleItem ERR" & @CRLF )
  ConsoleWrite( "$oNonVisibleItem OK" & @CRLF )

  ; Make non-visible item visible
  Local $pVirtualItem, $oVirtualItem
  $oNonVisibleItem.GetCurrentPattern( $UIA_VirtualizedItemPatternId, $pVirtualItem )
  $oVirtualItem = ObjCreateInterface( $pVirtualItem, $sIID_IUIAutomationVirtualizedItemPattern, $dtagIUIAutomationVirtualizedItemPattern )
  If Not IsObj( $oVirtualItem ) Then Return ConsoleWrite( "$oVirtualItem ERR" & @CRLF )
  ConsoleWrite( "$oVirtualItem OK" & @CRLF )
  $oVirtualItem.Realize() ; Make item visible
EndFunc

All code: MakeItemVisible.7z

Edited by LarsJ
  • Like 1

Share this post


Link to post
Share on other sites
Michael_1106

LarsJ,

I'm very sorry I never responded to your post, especially since you wrote such an excellent, detailed answer.  I didn't know to "follow" this thread, so I never got an e-mail.  Again, please accept my apology.

Thank you for the code!  It fills my needs beautifully.

You mentioned that "this is a lot of code just to set the current folder".  Here's my situation:  I use speech recognition, and like to go to a folder by saying, "folder multimedia" or "folder PHP".  Until now, I've had AutoIt go to the Windows Explorer address bar and "Send" the folder (which is slow), or paste the folder (which replaces the existing clipboard contents).

So your solution here works better than either of those.  Given my situation, is there a better way that I'm not aware of?

Thank you again.

Sincerely,
Michael

Share this post


Link to post
Share on other sites
LarsJ

I'm quite inactive myself here in the summer period.

These were the ideas I was thinking about. But if they do not fit your purpose, keep the code that works. You can delete the part of the code you do not use.

Regards Lars.

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

×