musicstashall Posted September 26, 2017 Posted September 26, 2017 Tell me please, is it possible to get the same list of selected items, only from the desktop?
kosamja Posted September 27, 2017 Posted September 27, 2017 16 hours ago, musicstashall said: Tell me please, is it possible to get the same list of selected items, only from the desktop? its possible, use FindWindowSW
LarsJ Posted September 27, 2017 Author Posted September 27, 2017 musicstashall. Unfortunately, this version of the code does not work for the desktop. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
musicstashall Posted September 28, 2017 Posted September 28, 2017 And what can you offer to implement the work on the desktop?
LarsJ Posted September 28, 2017 Author Posted September 28, 2017 Since you are not the only one who has asked questions about the desktop I'll implement the code. But it'll not be soon. I'll recommend you to ask the question in the General Help and Support forum. The desktop can also be automated with standard automation code. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
LarsJ Posted September 28, 2017 Author Posted September 28, 2017 Added a list of examples at the bottom of first post. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
sree161 Posted October 14, 2017 Posted October 14, 2017 Hi Larsj, is there a way to get the location of selected file into a variable?? i tried to run the example script given in step1 and i jus wanted to know what are the variables that hold the location of focused file??
LarsJ Posted October 14, 2017 Author Posted October 14, 2017 Example 4) and 5) in post 7 uses GetFiles( True, True ) and GetFolders( True, True ) to get selected files or folders with full path in Windows Explorer. Use GetItems( True, True ) to get all selected items with full path no matter if it's files or folders. This code works in Windows Explorer. It does not work on the Desktop, and it does not work in an Open or Save dialog. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Bilgus Posted March 28, 2018 Posted March 28, 2018 @LarsJ I Was messing with grabbing the hWnd and IDispatch object of the desktop window using FindWindowSW() and Just couldn't seem to get it to work then looking at the source I notices the declaration was just hResult() So I Expanded it to this: "FindWindowSW hresult(variant*;variant*;int;long*;int;ptr*);" & _ ; Finds a window in the Shell windows collection and returns the window's handle and IDispatch interface. So I assume the definition needs expanded for all items not implemented yet or is there a way to do late binding that I'm missing??
Bilgus Posted March 28, 2018 Posted March 28, 2018 (edited) You can Use the desktop for most of the examples With the addition of a couple of functions: Spoiler expandcollapse popupFunc FindDesktopShellBrowser() Local $_dtag_IShellWindows = $dtag_IShellWindows ;Populate Method $_dtag_IShellWindows = StringReplace($_dtag_IShellWindows, "FindWindowSW hresult();", _ "FindWindowSW hresult(variant*;variant*;int;long*;int;ptr*);") Local Const $CSIDL_DESKTOP = 0x0 Local Enum $SWC_EXPLORER = 0x00, $SWC_BROWSER = 0x01, $SWC_3RDPARTY = 0x02, $SWC_CALLBACK = 0x04, $SWC_DESKTOP = 0x08 ; ShellWindowTypeConstants; Local Enum $SWFO_NEEDDISPATCH = 0x01, $SWFO_INCLUDEPENDING = 0x02, $SWFO_COOKIEPASSED = 0x04 ; ShellWindowFindWindowOptions; Local $pIDispatch, $oIDispatch Local $pIWebBrowserApp, $oIWebBrowserApp, $hWnd ; IShellWindows interface Local $oIShellWindows = ObjCreateInterface($CLSID_ShellWindows, $sIID_IShellWindows, $_dtag_IShellWindows) ;Find the desktop window in list of Shell Windows ConsoleWrite("FindWindowSW HRESULT 0x" & _ Hex($oIShellWindows.FindWindowSW($CSIDL_DESKTOP, 0, $SWC_DESKTOP, $hWnd, $SWFO_NEEDDISPATCH, $pIDispatch)) & @CRLF) ConsoleWrite("Desktop hWnd = 0x" & Hex($hWnd) & @CRLF) If $pIDispatch Then $oIDispatch = ObjCreateInterface($pIDispatch, $sIID_IDispatch, $dtag_IDispatch) $oIDispatch.QueryInterface($tRIID_IWebBrowserApp, $pIWebBrowserApp) If $pIWebBrowserApp Then $oIWebBrowserApp = ObjCreateInterface($pIWebBrowserApp, $sIID_IWebBrowserApp, $dtag_IWebBrowserApp) EndIf EndIf ; IServiceProvider interface Local $pIServiceProvider, $oIServiceProvider $oIWebBrowserApp.QueryInterface($tRIID_IServiceProvider, $pIServiceProvider) $oIServiceProvider = ObjCreateInterface($pIServiceProvider, $sIID_IServiceProvider, $dtag_IServiceProvider) ; IShellBrowser interface Local $pIShellBrowser $oIServiceProvider.QueryService($tRIID_STopLevelBrowser, $tRIID_IShellBrowser, $pIShellBrowser) $oIShellBrowser = ObjCreateInterface($pIShellBrowser, $sIID_IShellBrowser, $dtag_IShellBrowser) EndFunc ;==>FindDesktopShellBrowser Func ToggleDesktop($objShell) If IsObj($objShell) Then $objShell.ToggleDesktop EndIf EndFunc ;==>ToggleDesktop ; Get an IShellBrowser interface FindDesktopShellBrowser() ;GetIShellBrowser( $hExplorer ) ;And... If needed... ;Toggle Desktop ToggleDesktop(ObjCreate("shell.application")) Created Example Setting Destop View / Icon Size expandcollapse popup#include "Includes\AutomatingWindowsExplorer.au3" Opt("MustDeclareVars", 1) Example() Func Example() Local $objShell = ObjCreate("shell.application") Local Const $asFVM_VIEWS =["", "Icon", "Small Icon", "List", "Details", "Thumbnail", "Tile", "Thumbstrip", "Content", ""] ; Get an IShellBrowser interface FindDesktopShellBrowser() If Not IsObj($oIShellBrowser) Then MsgBox(0, "Automating Windows Explorer", "Could not get Desktop IShellBrowser interface. Terminating.") Return EndIf ; Get other interfaces GetShellInterfaces() ; Get current icon view Local $view = GetIconView() Local $iView, $iSize, $iSzRand, $sViewSz If IsArray($view) Then ; OS > XP ToggleDesktop($objShell) ;Show The Desktop $iView = $view[0] ; Icon view $iSize = $view[1] ; Icon size $sViewSz = "Icon View = " & $asFVM_VIEWS[$iView] & ", Size = " & $iSize ConsoleWrite ("Initial: " & $sViewSz & @CRLF) For $i = $FVM_FIRST To $FVM_LAST $iSzRand = Random(16, 64, 1) $sViewSz = "Icon View = " & $asFVM_VIEWS[$i] & ", Size = " & $iSzRand ConsoleWrite ($sViewSz & @CRLF) SetIconView($i, $iSzRand) ; Set view MsgBox(0, "Desktop View", "Current View: " & $sViewSz & @CRLF & "Next View: " & $asFVM_VIEWS[$i + 1]) Next 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 ;==>Example Func FindDesktopShellBrowser() Local $_dtag_IShellWindows = $dtag_IShellWindows ;Populate Method $_dtag_IShellWindows = StringReplace($_dtag_IShellWindows, "FindWindowSW hresult();", _ "FindWindowSW hresult(variant*;variant*;int;long*;int;ptr*);") Local Const $CSIDL_DESKTOP = 0 Local Enum $SWC_EXPLORER = 0x00, $SWC_BROWSER = 0x01, $SWC_3RDPARTY = 0x02, $SWC_CALLBACK = 0x04, $SWC_DESKTOP = 0x08 ; ShellWindowTypeConstants; Local Enum $SWFO_NEEDDISPATCH = 0x01, $SWFO_INCLUDEPENDING = 0x02, $SWFO_COOKIEPASSED = 0x04 ; ShellWindowFindWindowOptions; Local $pIDispatch, $oIDispatch Local $pIWebBrowserApp, $oIWebBrowserApp, $hWnd ; IShellWindows interface Local $oIShellWindows = ObjCreateInterface($CLSID_ShellWindows, $sIID_IShellWindows, $_dtag_IShellWindows) ;Find the desktop window in list of Shell Windows ConsoleWrite("FindWindowSW HRESULT 0x" & _ Hex($oIShellWindows.FindWindowSW($CSIDL_DESKTOP, 0, $SWC_DESKTOP, $hWnd, $SWFO_NEEDDISPATCH, $pIDispatch)) & @CRLF) ConsoleWrite("Desktop hWnd = 0x" & Hex($hWnd) & @CRLF) If $pIDispatch Then $oIDispatch = ObjCreateInterface($pIDispatch, $sIID_IDispatch, $dtag_IDispatch) $oIDispatch.QueryInterface($tRIID_IWebBrowserApp, $pIWebBrowserApp) If $pIWebBrowserApp Then $oIWebBrowserApp = ObjCreateInterface($pIWebBrowserApp, $sIID_IWebBrowserApp, $dtag_IWebBrowserApp) EndIf EndIf ; IServiceProvider interface Local $pIServiceProvider, $oIServiceProvider $oIWebBrowserApp.QueryInterface($tRIID_IServiceProvider, $pIServiceProvider) $oIServiceProvider = ObjCreateInterface($pIServiceProvider, $sIID_IServiceProvider, $dtag_IServiceProvider) ; IShellBrowser interface Local $pIShellBrowser $oIServiceProvider.QueryService($tRIID_STopLevelBrowser, $tRIID_IShellBrowser, $pIShellBrowser) $oIShellBrowser = ObjCreateInterface($pIShellBrowser, $sIID_IShellBrowser, $dtag_IShellBrowser) EndFunc ;==>FindDesktopShellBrowser Func ToggleDesktop($objShell) If IsObj($objShell) Then $objShell.ToggleDesktop EndIf EndFunc ;==>ToggleDesktop Edited March 28, 2018 by Bilgus LarsJ 1
LarsJ Posted March 29, 2018 Author Posted March 29, 2018 Bilgus, Very interesting indeed. Quite a lot of the above items are about automating the desktop. So far, they have been unanswered. I'll look into the code after the Easter holiday. Bilgus 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Bilgus Posted March 30, 2018 Posted March 30, 2018 (edited) Try as I might I couldn't seem to get FindWindowSw() to accept a PIDL for any KnownFolderIds I figured it might be my error I even tried sequential numbers with a properly formatted tag_Variant and I couldn't get it to work After searching on the net, I don't think it works for anyone else either so maybe its broken or the definition on MSDN is wrong This works just fine for grabbing the desktop window $oIShellWindows.FindWindowSW(NULL, NULL, $SWC_DESKTOP, $hWnd, $SWFO_NEEDDISPATCH, $pIDispatch) So giving up on a way to find know folders I decided an EnumShellWindows() function would be the next best thing Spoiler expandcollapse popupFunc EnumShellWindows() ; Local $_dtag_IWebBrowserApp = $dtag_IWebBrowserApp Local $_dtag_IShellWindows = $dtag_IShellWindows ;Populate Methods $_dtag_IWebBrowserApp = StringReplace($_dtag_IWebBrowserApp, "get_LocationName hresult();", _ "get_LocationName hresult(BStr*);") $_dtag_IWebBrowserApp = StringReplace($_dtag_IWebBrowserApp, "get_LocationURL hresult();", _ "get_LocationURL hresult(BStr*);") $_dtag_IShellWindows = StringReplace($_dtag_IShellWindows, "FindWindowSW hresult();", _ "FindWindowSW hresult(variant*;variant*;int;long*;int;ptr*);") ; Local $pIDispatch, $oIDispatch ; IShellWindows interface Local $oIShellWindows = ObjCreateInterface($CLSID_ShellWindows, $sIID_IShellWindows, $_dtag_IShellWindows) ; Number of shell windows Local $iWindows $oIShellWindows.get_Count($iWindows) ConsoleWrite("Window Count: " & $iWindows & @CRLF) ; Get an IWebBrowserApp object for each window ; This is done in two steps: ; 1. Get an IDispatch object for the window ; 2. Get the IWebBrowserApp interface ; Check if it's the right window Local $pIWebBrowserApp, $oIWebBrowserApp, $hWnd, $sLoc, $aRet[$iWindows + 2][2] $aRet[0][0] = 0 For $i = 0 To $iWindows If $i < $iWindows Then $oIShellWindows.Item($i, $pIDispatch) Else $oIShellWindows.FindWindowSW(Null, Null, $SWC_DESKTOP, $hWnd, $SWFO_NEEDDISPATCH, $pIDispatch) EndIf If $pIDispatch Then $oIDispatch = ObjCreateInterface($pIDispatch, $sIID_IDispatch, $dtag_IDispatch) $oIDispatch.QueryInterface($tRIID_IWebBrowserApp, $pIWebBrowserApp) If $pIWebBrowserApp Then $oIWebBrowserApp = ObjCreateInterface($pIWebBrowserApp, $sIID_IWebBrowserApp, $_dtag_IWebBrowserApp) $oIWebBrowserApp.get_HWND($hWnd) $aRet[$i + 1][0] = "0x" & Hex($hWnd) $sLoc = "" $oIWebBrowserApp.get_LocationURL($sLoc) ;try to get the full path first If $sLoc = "" Then $oIWebBrowserApp.get_LocationName($sLoc) Else $sLoc = PathCreateFromUrlW($sLoc) EndIf If $sLoc = "" And _WinAPI_GetShellWindow() = $hWnd Then $sLoc = "Desktop" $aRet[$i + 1][1] = $sLoc $aRet[0][0] += 1 EndIf EndIf Next Return $aRet EndFunc ;==>EnumShellWindows Func PathCreateFromUrlW($sURL, $vDll = "shlwapi.dll") Local $aRet = DllCall($vDll, "long", "PathCreateFromUrlW", "wstr", $sURL, "wstr", "", "dword*", 65534, "dword", 0) ;Ascend4nt If Not @error And IsArray($aRet) And $aRet[0] = 0 Then Return $aRet[2] EndIf EndFunc ;==>PathCreateFromUrlW Do Note The populate Methods part won't be needed eventually but they are just there to make it work with the current example files Edited March 30, 2018 by Bilgus PathCreateFromUrlW($sLoc)
Bilgus Posted March 31, 2018 Posted March 31, 2018 (edited) I updated the GetSetIconView example quite a bit It now lists all windows found with the above handy enum function Allows finding windows by Pidl(FolderIds) The example uses CSIDL for ease of putting in a list but that function is depreciated Adds a few functions from shlwapi and a some other misc stuff, there are still some other parts I'm not particularly happy with but I'll probably save that for an update of my DeskViewChanger script Spoiler expandcollapse popupOpt("MustDeclareVars", 1) #include "Includes\AutomatingWindowsExplorer.au3" #include <GuiComboBoxEx.au3> #include <GuiListView.au3> #include <ButtonConstants.au3> #include <ComboConstants.au3> #include <GUIConstantsEx.au3> #include <GUIListBox.au3> #include <WindowsConstants.au3> Global Const $asFVM_VIEWS = ["", "Icon", "Small Icon", "List", "Details", "Thumbnail", "Tile", "Thumbstrip", "Content", ""] Example() Func Example() Local $hForm1 = GUICreate("Form1", 303, 366, 254, 156) Local $IdListVw1 = GUICtrlCreateListView("Hwnd | Path", 8, 8, 281, 278) Local $hListVw = GUICtrlGetHandle($IdListVw1) Local $IdCombo1 = GUICtrlCreateCombo("By CSIDL", 8, 296, 281, 25) Local $hCombo1 = GUICtrlGetHandle($IdCombo1) Local $IdCombo2 = GUICtrlCreateCombo("Auto", 8, 328, 169, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) Local $hCombo2 = GUICtrlGetHandle($IdCombo2) Local $IdButton1 = GUICtrlCreateButton("Go", 192, 328, 97, 25) Local $aRet = EnumShellWindows() For $i = 1 To $aRet[0][0] GUICtrlCreateListViewItem($aRet[$i][0] & "|" & $aRet[$i][1], $IdListVw1) Next Local $iCSIDL, $sItems, $sPath = "|" For $i = 0 To 70 $sPath = _WinAPI_ShellGetSpecialFolderPath($i) $sPath = StringMid($sPath, StringInStr($sPath, "\", 1, -2) + 1) $sItems &= $sPath & "|" Next GUICtrlSetData($IdCombo1, $sItems) $sItems = "" For $i = 1 To UBound($asFVM_VIEWS) - 2 $sItems &= $asFVM_VIEWS[$i] & "|" Next GUICtrlSetData($IdCombo2, $sItems) _GUICtrlComboBox_SetCurSel($hCombo2, 0) GUISetState(@SW_SHOW) Local $nMsg, $hWnd, $pPidl While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $IdCombo1 _GUICtrlListView_SetItemSelected($hListVw, -1, False) Case $IdButton1 $hWnd = HWnd(_GUICtrlListView_GetItemText($hListVw, List_Index($hListVw))) If Not $hWnd Then ConsoleWrite("CSIDL = " & _GUICtrlComboBoxEx_GetCurSel($hCombo1) - 1 & @CRLF) $pPidl = _WinAPI_ShellGetSpecialFolderLocation(_GUICtrlComboBoxEx_GetCurSel($hCombo1) - 1) ConsoleWrite("pPidl = " & $pPidl & @CRLF) EndIf ConsoleWrite("View = " & _GUICtrlComboBoxEx_GetCurSel($hCombo2) & @CRLF) ShellSetView($hWnd, $pPidl, _GUICtrlComboBoxEx_GetCurSel($hCombo2), Random(16, 64, 1)) _WinAPI_CoTaskMemFree($pPidl) EndSwitch WEnd EndFunc ;==>Example Func List_Index($hWndList1) Local $iIndex = _GUICtrlListView_GetSelectionMark($hWndList1) If _GUICtrlListView_GetItemSelected($hWndList1, $iIndex) Then Return $iIndex Return -1 EndFunc ;==>List_Index Func ShellSetView($hExplorer, $pPidl, $iView, $iSize = 16) ;hExplorer = 0 & pPidl = 0 grabs desktop ; Get an IShellBrowser interface FindIShellBrowser($hExplorer, $pPidl) ;$hExplorer);GetIShellBrowser( $hExplorer ) If Not IsHWnd($hExplorer) Then MsgBox(0, "Automating Windows Explorer", "Window does not exist.") Return ElseIf Not IsObj($oIShellBrowser) Then MsgBox(0, "Automating Windows Explorer", "Could not get an IShellBrowser interface.") Return EndIf ; Get other interfaces GetShellInterfaces() ; Get current icon view Local $view = GetIconView() If StringInStr(_WinAPI_GetClassName($hExplorer), "Progman") Then ;This Might be flaky.. ToggleDesktop(ObjCreate("shell.application")) ;Show The Desktop Else WinActivate($hExplorer) EndIf If $iView < $FVM_FIRST Then $iView = -1 ;(Auto) ElseIf $iView > $FVM_LAST Then $iView = $FVM_LAST EndIf If IsArray($view) Then ; OS > XP SetIconView($iView, $iSize) ; NewView MsgBox(0, "Desktop View", "Current View: " & $asFVM_VIEWS[GetIconView()[0]] & @CRLF & _ "Original View: " & $asFVM_VIEWS[$view[0]]) $iView = $view[0] ; Icon view $iSize = $view[1] ; Icon size SetIconView($iView, $iSize) ; Restore old view Else ; OS = XP MsgBox(0, "Automating Windows Explorer", "XP Not Tested / Supported. Terminating.") Return $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 ;==>ShellSetView Func ToggleDesktop($objShell) If IsObj($objShell) Then $objShell.ToggleDesktop EndIf EndFunc ;==>ToggleDesktop #Region #SHELLFUNCTIONS# Func Create_IShellFolder() ;Don't forget IUnknown::Release;;;Apparently Autoit Releases this for us.. Local Static $oIShellFolder If Not IsObj($oIShellFolder) Then Local $pIShellFolder SHGetDesktopFolder($pIShellFolder) $oIShellFolder = ObjCreateInterface($pIShellFolder, $sIID_IShellFolder, $dtag_IShellFolder) EndIf Return $oIShellFolder EndFunc ;==>Create_IShellFolder Func Create_IShellWindows() ; IShellWindows interface ;;Populate Methods Local $_dtag_IShellWindows = $dtag_IShellWindows $_dtag_IShellWindows = StringReplace($_dtag_IShellWindows, "FindWindowSW hresult();", _ "FindWindowSW hresult(variant*;variant*;int;long*;int;ptr*);") ;; Local $oIShellWindows = ObjCreateInterface($CLSID_ShellWindows, $sIID_IShellWindows, $_dtag_IShellWindows) Return $oIShellWindows EndFunc ;==>Create_IShellWindows Func EnumShellWindows() ;;Populate Methods Local $_dtag_IWebBrowserApp = $dtag_IWebBrowserApp $_dtag_IWebBrowserApp = StringReplace($_dtag_IWebBrowserApp, "get_LocationName hresult();", _ "get_LocationName hresult(BStr*);") $_dtag_IWebBrowserApp = StringReplace($_dtag_IWebBrowserApp, "get_LocationURL hresult();", _ "get_LocationURL hresult(BStr*);") ;; ; IShellWindows interface Local $oIShellWindows = Create_IShellWindows() Local $pIDispatch, $oIDispatch, $iError, $aRet[1][2] If IsObj($oIShellWindows) Then ; Number of shell windows Local $iWindows $oIShellWindows.get_Count($iWindows) ConsoleWrite("Window Count: " & $iWindows & @CRLF) ; Get an IWebBrowserApp object for each window ; This is done in two steps: ; 1. Get an IDispatch object for the window ; 2. Get the IWebBrowserApp interface ; Check if it's the right window Local $pIWebBrowserApp, $oIWebBrowserApp, $hWnd, $sLoc, $aRet[$iWindows + 2][2] $aRet[0][0] = 0 For $i = 0 To $iWindows If $i < $iWindows Then $oIShellWindows.Item($i, $pIDispatch) Else $pIDispatch = IShellWindows_Desktop($oIShellWindows, $hWnd) EndIf If $pIDispatch Then $oIDispatch = ObjCreateInterface($pIDispatch, $sIID_IDispatch, $dtag_IDispatch) If IsObj($oIDispatch) Then $oIDispatch.QueryInterface($tRIID_IWebBrowserApp, $pIWebBrowserApp) EndIf If $pIWebBrowserApp Then $oIWebBrowserApp = ObjCreateInterface($pIWebBrowserApp, $sIID_IWebBrowserApp, $_dtag_IWebBrowserApp) $oIWebBrowserApp.get_HWND($hWnd) $aRet[$i + 1][0] = "0x" & Hex($hWnd) $sLoc = "" $oIWebBrowserApp.get_LocationURL($sLoc) ;try to get the full path first If $sLoc = "" Then $oIWebBrowserApp.get_LocationName($sLoc) Else $sLoc = PathCreateFromUrlW($sLoc) EndIf If $sLoc = "" And _WinAPI_GetShellWindow() = $hWnd Then $sLoc = "Desktop" $aRet[$i + 1][1] = $sLoc $aRet[0][0] += 1 EndIf EndIf Next Else $iError = 1 ;No $oIShellWindows EndIf Return SetError($iError, 0, $aRet) EndFunc ;==>EnumShellWindows Func FindIShellBrowser(ByRef $hExplorer, $pPidl = 0) ; IShellWindows interface Local $iError Local $oIShellWindows = Create_IShellWindows() Local $pIDispatch, $oIDispatch, $hWnd If IsObj($oIShellWindows) And (IsHWnd($hExplorer) Or $pPidl) Then $pIDispatch = IShellWindows_Desktop($oIShellWindows, $hWnd) If Not IsHWnd($hExplorer) Or $hWnd <> $hExplorer Then ; Number of shell windows Local $iWindows $oIShellWindows.get_Count($iWindows) ConsoleWrite("Window Count: " & $iWindows & @CRLF) ; Get an IWebBrowserApp object for each window ; This is done in two steps: ; 1. Get an IDispatch object for the window ; 2. Get the IWebBrowserApp interface ; Check if it's the right window Local $pIWebBrowserApp, $oIWebBrowserApp For $i = 0 To $iWindows - 1 $oIShellWindows.Item($i, $pIDispatch) If $pIDispatch Then $oIDispatch = ObjCreateInterface($pIDispatch, $sIID_IDispatch, $dtag_IDispatch) $oIDispatch.QueryInterface($tRIID_IWebBrowserApp, $pIWebBrowserApp) If $pIWebBrowserApp Then $oIWebBrowserApp = ObjCreateInterface($pIWebBrowserApp, $sIID_IWebBrowserApp, $dtag_IWebBrowserApp) $oIWebBrowserApp.get_HWND($hWnd) Local $pPidlFolder = $pPidl ? GetShellPidl($pIDispatch) : 0 If $hWnd = $hExplorer Or ($pPidl And IShellFolder_CompareIds($pPidlFolder, $pPidl) = 0) Then ;;ILIsEqual($pPidlFolder, $pPidl) Then ConsoleWrite("Found 0x" & Hex($hWnd) & @CRLF) _WinAPI_CoTaskMemFree($pPidlFolder) $hExplorer = HWnd($hWnd) ExitLoop EndIf _WinAPI_CoTaskMemFree($pPidlFolder) EndIf EndIf Next EndIf ElseIf IsObj($oIShellWindows) Then ;Get Desktop ShellWindow $pIDispatch = IShellWindows_Desktop($oIShellWindows, $hWnd) Else $iError = 1 ;No $oIShellWindows EndIf If $pIDispatch Then Local $pIShellBrowser = IUnknown_QueryService($pIDispatch, $tRIID_STopLevelBrowser, $tRIID_IShellBrowser) $oIShellBrowser = ObjCreateInterface($pIShellBrowser, $sIID_IShellBrowser, $dtag_IShellBrowser) ElseIf Not $iError Then ConsoleWrite("Error retrieving IShellBrowser Object") $iError = 2 EndIf Return SetError($iError, 0, $oIShellBrowser) EndFunc ;==>FindIShellBrowser Func GetShellPidl($pUnk) ;Don't forget to free with _WinAPI_CoTaskMemFree() Local $pIFolderView, $oIFolderView Local $pIPersistFolder2, $pPidlFolder, $iError ; IFolderView interface $pIFolderView = IUnknown_QueryService($pUnk, $tRIID_IFolderView, $tRIID_IFolderView) If $pIFolderView Then $oIFolderView = ObjCreateInterface($pIFolderView, $sIID_IFolderView, $dtag_IFolderView) Else $iError = 1 EndIf If IsObj($oIFolderView) Then ; IPersistFolder2 interface $oIFolderView.GetFolder($tRIID_IPersistFolder2, $pIPersistFolder2) Local $oIPersistFolder2 = ObjCreateInterface($pIPersistFolder2, $sIID_IPersistFolder2, $dtag_IPersistFolder2) If IsObj($oIPersistFolder2) Then $oIPersistFolder2.GetCurFolder($pPidlFolder) ConsoleWrite($pPidlFolder & ":" & _WinAPI_ShellGetPathFromIDList($pPidlFolder) & @CRLF) Else $iError = 3 EndIf Else $iError = 2 ;No $oIFolderView EndIf Return SetError($iError, 0, $pPidlFolder) EndFunc ;==>GetShellPidl Func IShellFolder_GetDisplayNameOf($pPidl, $fName = 0, $fFullPath = True) Local $iError Local $oIShellFolder = Create_IShellFolder() Local $tSTRRET = DllStructCreate($tagSTRRET), $sName ; Name format If Not $fFullPath Then If $fName = $SHGDN_NORMAL Then $fName = $SHGDN_INFOLDER Else ; $fName = $SHGDN_FORPARSING $fName = BitOR($SHGDN_INFOLDER, $SHGDN_FORPARSING) EndIf EndIf If IsObj($oIShellFolder) Then $oIShellFolder.GetDisplayNameOf($pPidl, $fName, $tSTRRET) StrRetToBuf(DllStructGetPtr($tSTRRET), $NULL, $sName) Else $iError = 1 EndIf Return $sName EndFunc ;==>IShellFolder_GetDisplayNameOf Func IShellFolder_CompareIds($pPidl1, $pPidl2) Local Enum $SHCIDS_ALLFIELDS = 0x80000000, $SHCIDS_CANONICALONLY = 0x10000000 Local $iError, $iCompare Local $oIShellFolder = Create_IShellFolder() If IsObj($oIShellFolder) Then $iCompare = $oIShellFolder.CompareIds(0, $pPidl1, $pPidl2) Else $iError = 1 EndIf ;Fallback If $iCompare <> 0 And IShellFolder_GetDisplayNameOf($pPidl1, $SHGDN_FORPARSING) = IShellFolder_GetDisplayNameOf($pPidl2, $SHGDN_FORPARSING) Then $iCompare = 0 Return SetError($iError, 0, $iCompare) EndFunc ;==>IShellFolder_CompareIds Func IShellWindows_Desktop($oIShellWindows, ByRef $hWnd) Local Enum $SWC_EXPLORER = 0x00, $SWC_BROWSER = 0x01, $SWC_3RDPARTY = 0x02, $SWC_CALLBACK = 0x04, $SWC_DESKTOP = 0x08 ; ShellWindowTypeConstants; Local Enum $SWFO_NEEDDISPATCH = 0x01, $SWFO_INCLUDEPENDING = 0x02, $SWFO_COOKIEPASSED = 0x04 ; ShellWindowFindWindowOptions; Local $pIDispatch If IsObj($oIShellWindows) Then $oIShellWindows.FindWindowSW(Null, Null, $SWC_DESKTOP, $hWnd, $SWFO_NEEDDISPATCH, $pIDispatch) EndIf Return $pIDispatch EndFunc ;==>IShellWindows_Desktop #Region #SHLWAPIFUNCTIONS# Func IUnknown_QueryService($pUnk, $tClsid, $tRiid, $vDll = "Shlwapi.dll") Local $sFunc = "IUnknown_QueryService" Local $aCall = DllCall($vDll, "long", $sFunc, "ptr", $pUnk, "ptr", DllStructGetPtr($tClsid), _ "ptr", DllStructGetPtr($tRiid), "ptr*", 0) If Not @error And IsArray($aCall) Then If $aCall[0] = $S_OK Then ConsoleWrite($sFunc & " S_OK " & $aCall[4] & @CRLF) Return $aCall[4] Else ConsoleWrite($sFunc & " Com Err: 0x" & Hex($aCall[0]) & @CRLF) EndIf Else ConsoleWrite($sFunc & " Failed") EndIf EndFunc ;==>IUnknown_QueryService Func PathCreateFromUrlW($sURL, $vDll = "shlwapi.dll") Local $sFunc = "PathCreateFromUrlW" ;65534 => Sizeof(Wstr) - 2 Null bytes Local $aCall = DllCall($vDll, "long", $sFunc, "wstr", _ $sURL, "wstr", "", "dword*", 65534, "dword", 0) ;Ascend4nt If Not @error And IsArray($aCall) Then If $aCall[0] = $S_OK Then ConsoleWrite($sFunc & " S_OK " & $aCall[2] & @CRLF) Return $aCall[2] Else ConsoleWrite($sFunc & " Com Err: 0x" & Hex($aCall[0]) & @CRLF) EndIf Else ConsoleWrite($sFunc & " Failed") EndIf EndFunc ;==>PathCreateFromUrlW #EndRegion #SHLWAPIFUNCTIONS# #EndRegion #SHELLFUNCTIONS# Edited March 31, 2018 by Bilgus LarsJ 1
LarsJ Posted April 2, 2018 Author Posted April 2, 2018 I haven't looked at the code yet, but I'm sure it's nice code. I think it's possible to automate the standard Open/Save dialogs in similar ways. But I've not tried. Do you know about techniques to automate these dialogs? Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Bilgus Posted April 11, 2018 Posted April 11, 2018 Playing with the interfaces for Dialogs for a few days I've come to the conclusion that you are only going to be able to access dialogs you create within your process. Well I should say easily access, I was able to get IUnknown from open/save as dialogs with AccessibleObjectFromWindow but The only interfaces exposed were IUnknown and IOleWindow so I've a feeling this is a dead end For the next try I found a function SHShellFolderView_Message that is depreciated It gets IShellFolderView from another function that seems to be unexposed ShellFolderViewFromWindow and only used by the former depreciated function This led me to an undocumented message CWM_GETISHELLBROWSER searching the net I found it as WM_GETISHELLBROWSER = WM_USER + 0x7 but very little info beyond that Basically I was able to identify a window as having an IShellBrowser interface if there was a pointer returned from SendMessage($hWnd, $WM_GETISHELLBROWSER, 0, 0) but it was a pointer within the host process therefore useless in its current form. From what I can tell you would need to inject code into the host of the dialog to make use of the object returned by the call to WM_GETISHELLBROWSER but that is as far as I've gotten thus far
artyb Posted July 9, 2020 Posted July 9, 2020 Hi, Thank you for this great work. I'm new to this though and could do with a bit of help. I want to automate clicking on a mapped network drive in windows explorer. Do I open your GUI using AutoIt and use other AutoIt commands on your GUI window? If so I couldn't find how to automate clicking on the 'Browse' tab? Or can the commands be sent directly somehow? I'm not sure of the work flow. An example would be amazing. Thank you, A
LarsJ Posted July 12, 2020 Author Posted July 12, 2020 On 7/9/2020 at 10:21 AM, artyb said: I want to automate clicking on a mapped network drive in windows explorer. This seems to be a completely normal automation task. If you're lucky, it can be done with the automation functions in the help file. The GUI in first post is just for demonstration of the features in the UDF. It cannot be used for your task. If you've more questions, ask them in the General Help and Support forum. Here you get much faster answers. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now