Recommended Posts

WideBoyDixon 9

WideBoyDixon 9

I needed to be able to retrieve the folder currently being explored by an instance of Windows Explorer. To that end, I had to write a function to do this which I've copied out below. Feel free to re-use this if you find it useful.

#include-once; ==================================================================================================; <_GetWindowsExplorerPath.au3>;; Functions:; _GetWindowsExplorerPath(); _GetWindowsExplorerPaths();; Author: WideBoyDixon; ==================================================================================================; ==================================================================================================; Func _GetWindowsExplorerPath($hWnd);; Function to get the path currently being explored by a Windows Explorer window;; $hWnd = Handle to the Windows Explorer window;; Returns:; Success: String - Path being explored by this window; Failure: "" empty string, with @error set:; @error = 1 = This is not a valid explorer window; @error = 2 = DLL call error, use _WinAPI_GetLastError();; Author: WideBoyDixon; ==================================================================================================Func_GetWindowsExplorerPath($hWnd)Local$pv,$pidl,$return="",$ret,$hMem,$pid,$folderPath=DllStructCreate("char[260]"),$classNameLocal$bPIDL=FalseLocalConst$CWM_GETPATH=0x400+12;; Check the classname of the window first$className=DllCall("user32.dll","int","GetClassName","hwnd",$hWnd,"str","","int",4096)If@errorThenReturnSetError(2,0,"")If($className[2]<>"ExploreWClass"And$className[2]<>"CabinetWClass")ThenReturnSetError(1,0,""); Retrieve the process ID for our process$pid=DllCall("kernel32.dll","int","GetCurrentProcessId")If@errorThenReturnSetError(2,0,""); Send the CWM_GETPATH message to the window$hMem=DllCall("user32.dll","lparam","SendMessage","hwnd",$hWnd,"int",$CWM_GETPATH,"wparam",$pid[0],"lparam",0)If@errorThenReturnSetError(2,0,"")If$hMem[0]=0ThenReturnSetError(1,0,""); Lock the shared memory$pv=DllCall("shell32.dll","ptr","SHLockShared","uint",$hMem[0],"uint",$pid[0])If@errorThenReturnSetError(2,0,"")If$pv[0]Then$pidl=DllCall("shell32.dll","ptr","ILClone","uint",$pv[0]); Clone the PIDLIf@errorThenReturnSetError(2,0,"")$bPIDL=TrueDllCall("shell32.dll","int","SHUnlockShared","uint",$pv); Unlock the shared memoryEndIfDllCall("shell32.dll","int","SHFreeShared","uint",$hMem,"uint",$pid); Free the shared memoryIf$bPIDLThen; Retrieve the path from the PIDL$ret=DllCall("shell32.dll","int","SHGetPathFromIDList","ptr",$pidl[0],"ptr",DllStructGetPtr($folderPath))If(@error=0)And($ret[0]<>0)Then$return=DllStructGetData($folderPath,1); Retrieve the valueDllCall("shell32.dll","none","ILFree","ptr",$pidl[0]); Free up the PIDL that we clonedReturnSetError(0,0,$return); SuccessEndIfReturnSetError(2,0,""); Failed a WinAPI callEndFunc; ==================================================================================================; Func _GetWindowsExplorerPaths();; Function to get a list of all paths currently being explored by a Windows Explorer window;; Returns:; Array; [0][0] - Number of items in the Array; [$i][0] - Window handle of the explorer window; [$i][1] - Folder being explored by this window;; Author: WideBoyDixon; ==================================================================================================Func_GetWindowsExplorerPaths()Local$nCount=0; The number of explorer windows we foundLocal$aPaths[1][2]; Our return arrayLocal$aWindows=WinList(); Look at all the windows we can findLocal$nI,$folderPath; Loop variable and folder path string; Loop through all windowsFor$nI=1To$aWindows[0][0]; Try to get the folder path for this window$folderPath=_GetWindowsExplorerPath($aWindows[$nI][1])If@error=0Then; Found the path ... store it$nCount+=1; Increment the number of windows we've foundReDim$aPaths[$nCount+1][2]; Make room for this one in the array$aPaths[$nCount][0]=$aWindows[$nI][1]; Store the window handle$aPaths[$nCount][1]=$folderPath; Store the path that's being explored$aPaths[0][0]=$nCount; Update the number of items in the arrayEndIfNextReturn$aPathsEndFunc

Share this post

Link to post

Share on other sites

WideBoyDixon 9

WideBoyDixon 9

Unfortunately, "No" and "No". In order to get the current folder in a FileOpen dialog you need to delve in to the depths of IShellBrowser and other shell interfaces and I'm not sure AutoIt can do that without creating an external DLL. The basics are:

[1] Use SendMessage to the dialog using WM_GETISHELLBROWSER (=WM_USER + 7) to get a pointer to an IShellBrowser

[2] Use the QueryActiveShellView method of IShellBrowser to get the active shell view which is a pointer to an IShellView

[3] Use the QueryInterface method of the IShellView to get a handle to a folder view IFolderView

[4] Use the GetFolder method of the IFolderView to get a handle to IPersistFolder2

[5] Call GetCurFolder on the IPersistFolder2 to get a PIDL for the current folder

Share this post

Link to post

Share on other sites

Digisoul 1

Digisoul 1

I needed to be able to retrieve the folder currently being explored by an instance of Windows Explorer. To that end, I had to write a function to do this which I've copied out below. Feel free to re-use this if you find it useful.

#include-once; ==================================================================================================; <_GetWindowsExplorerPath.au3>;; Functions:; _GetWindowsExplorerPath(); _GetWindowsExplorerPaths();; Author: WideBoyDixon; ==================================================================================================; ==================================================================================================; Func _GetWindowsExplorerPath($hWnd);; Function to get the path currently being explored by a Windows Explorer window;; $hWnd = Handle to the Windows Explorer window;; Returns:; Success: String - Path being explored by this window; Failure: "" empty string, with @error set:; @error = 1 = This is not a valid explorer window; @error = 2 = DLL call error, use _WinAPI_GetLastError();; Author: WideBoyDixon; ==================================================================================================Func_GetWindowsExplorerPath($hWnd)Local$pv,$pidl,$return="",$ret,$hMem,$pid,$folderPath=DllStructCreate("char[260]"),$classNameLocal$bPIDL=FalseLocalConst$CWM_GETPATH=0x400+12;; Check the classname of the window first$className=DllCall("user32.dll","int","GetClassName","hwnd",$hWnd,"str","","int",4096)If@errorThenReturnSetError(2,0,"")If($className[2]<>"ExploreWClass"And$className[2]<>"CabinetWClass")ThenReturnSetError(1,0,""); Retrieve the process ID for our process$pid=DllCall("kernel32.dll","int","GetCurrentProcessId")If@errorThenReturnSetError(2,0,""); Send the CWM_GETPATH message to the window$hMem=DllCall("user32.dll","lparam","SendMessage","hwnd",$hWnd,"int",$CWM_GETPATH,"wparam",$pid[0],"lparam",0)If@errorThenReturnSetError(2,0,"")If$hMem[0]=0ThenReturnSetError(1,0,""); Lock the shared memory$pv=DllCall("shell32.dll","ptr","SHLockShared","uint",$hMem[0],"uint",$pid[0])If@errorThenReturnSetError(2,0,"")If$pv[0]Then$pidl=DllCall("shell32.dll","ptr","ILClone","uint",$pv[0]); Clone the PIDLIf@errorThenReturnSetError(2,0,"")$bPIDL=TrueDllCall("shell32.dll","int","SHUnlockShared","uint",$pv); Unlock the shared memoryEndIfDllCall("shell32.dll","int","SHFreeShared","uint",$hMem,"uint",$pid); Free the shared memoryIf$bPIDLThen; Retrieve the path from the PIDL$ret=DllCall("shell32.dll","int","SHGetPathFromIDList","ptr",$pidl[0],"ptr",DllStructGetPtr($folderPath))If(@error=0)And($ret[0]<>0)Then$return=DllStructGetData($folderPath,1); Retrieve the valueDllCall("shell32.dll","none","ILFree","ptr",$pidl[0]); Free up the PIDL that we clonedReturnSetError(0,0,$return); SuccessEndIfReturnSetError(2,0,""); Failed a WinAPI callEndFunc; ==================================================================================================; Func _GetWindowsExplorerPaths();; Function to get a list of all paths currently being explored by a Windows Explorer window;; Returns:; Array; [0][0] - Number of items in the Array; [$i][0] - Window handle of the explorer window; [$i][1] - Folder being explored by this window;; Author: WideBoyDixon; ==================================================================================================Func_GetWindowsExplorerPaths()Local$nCount=0; The number of explorer windows we foundLocal$aPaths[1][2]; Our return arrayLocal$aWindows=WinList(); Look at all the windows we can findLocal$nI,$folderPath; Loop variable and folder path string; Loop through all windowsFor$nI=1To$aWindows[0][0]; Try to get the folder path for this window$folderPath=_GetWindowsExplorerPath($aWindows[$nI][1])If@error=0Then; Found the path ... store it$nCount+=1; Increment the number of windows we've foundReDim$aPaths[$nCount+1][2]; Make room for this one in the array$aPaths[$nCount][0]=$aWindows[$nI][1]; Store the window handle$aPaths[$nCount][1]=$folderPath; Store the path that's being explored$aPaths[0][0]=$nCount; Update the number of items in the arrayEndIfNextReturn$aPathsEndFunc

Regards,

WBD

Thats really awesome script. i want to know 1 more thing, isn't it possible to get the currently selected file in explorer?

73 108 111 118 101 65 117 116 111 105 116

Share this post

Link to post

Share on other sites

WideBoyDixon 9

WideBoyDixon 9

Thats really awesome script. i want to know 1 more thing, isn't it possible to get the currently selected file in explorer?

Technically it's possible but of course there might be more than one selected file (or there might be zero). Again you'd have to delve deep in to the Shell32.dll functions and I think the one you'd need is SHShellFolderView_Message along with SFVM_GETSELECTEDOBJECTS

I'm not sure quite how to program an array of PIDLs in AutoIt so I'm going to shy away from this one for now.

Share this post

Link to post

Share on other sites

picea892 6

picea892 6

Maybe I'm missing something, but I think there is an easier way to get this information. I use this method to get the current folder and selected file. Once obtained, this information is used to edit the file differently based on the type. Hope the below is clear. It is a function of a much larger script.

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key?Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox(be advised many downloads are not working due to ISP screwup with my storage)

Share this post

Link to post

Share on other sites

TheSaint 1,355

TheSaint 1,355

What was your solution? Especially since this topic's method doesn't work in Vista, SendMessage() returns 0.

Someone just had to ask that ... now I have to go and work out what I did ... I had to say something didn't I ... and I'm not even 100% sure I did solve it? I remember my Open Projects program also giving me some grief, because the Drive windows opened by TrueCrypt didn't always display a drive letter in the address bar ... but I do remember solving that somehow. Have you or anyone else tried my New Folders program in Vista ... especially without the address bar being active ... I don't have easy access to Vista at this point?

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key?Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox(be advised many downloads are not working due to ISP screwup with my storage)