Jump to content

Implementing Windows Explorer right pane


LarsJ
 Share

Recommended Posts

This is very usefull as it really provides the full functionality of the windows explorer.

Unfortunately I receive a com-error when resizting.

80020010 (DISP_E_BADCALLEEhttp://msdn.microsoft.com/en-us/library/windows/desktop/dd542644(v=vs.85).aspx

Maybe wrong parameter types? I tried some things but couldnt fix it. Could you have a short look on this?

( windows 8, x64 )

Here is the com-error handler I used

$oMyError = ObjEvent( "AutoIt.Error" , "comErrorHandler" )  ; Initialize a COM error handler
Func comErrorHandler()
  ConsoleWrite(  "We intercepted a COM Error !"    & @CRLF                 & @CRLF & _
                 "err.description is: "  & @TAB & $oMyError.description    & @CRLF & _
                 "err.windescription:"   & @TAB & $oMyError.windescription & @CRLF & _
                 "err.number is: "       & @TAB & hex($oMyError.number,8)  & @CRLF & _
                 "err.lastdllerror is: " & @TAB & $oMyError.lastdllerror   & @CRLF & _
                 "err.scriptline is: "   & @TAB & $oMyError.scriptline     & @CRLF & _
                 "err.source is: "       & @TAB & $oMyError.source         & @CRLF & _
                 "err.helpfile is: "     & @TAB & $oMyError.helpfile       & @CRLF & _
                 "err.helpcontext is: "  & @TAB & $oMyError.helpcontext _
                )
Endfunc

Thank you so much

Bluesmaster

My UDF: [topic='156155']_shellExecuteHidden[/topic]

Link to comment
Share on other sites

Yes, this is not the usual listview. This is a real Windows Explorer. But only the right pane. All the functionality of Windows Explorer is working. E.g. keyboard shortcuts, the context (right click) menu, cut, copy, paste, drag & drop and automatic update of the window (if you create and save a new file in Scite the window is updated automatically, you don't even have to press F5).

Error when resizing

I get no errors on Windows 7 x64. I'm not able to test on Windows 8. So I can only be guessing.

Try to comment out this line

$oIExplorerBrowser.SetRect( $NULL, DllStructGetPtr( $tRECT ) )
in function WM_SIZING in the bottom of "Windows Explorer right pane - Vista, Win 7.au3" to verify that the error disappears.

If the error disappears then enable the above line again and replace these lines

$tRECT = DllStructCreate( $tagRECT )
DllStructSetData( $tRECT, "Left", 0 )
DllStructSetData( $tRECT, "Top", $aTBsize[1] + 6 )
DllStructSetData( $tRECT, "Right", $w )
DllStructSetData( $tRECT, "Bottom", $h )

WinMove( $hToolbar, "", 0, 0, $w, $aTBsize[1] )
$oIExplorerBrowser.SetRect( $NULL, DllStructGetPtr( $tRECT ) )
with these lines.

Local Static $tRECT2 = DllStructCreate( $tagRECT )
DllStructSetData( $tRECT2, "Left", 0 )
DllStructSetData( $tRECT2, "Top", $aTBsize[1] + 6 )
DllStructSetData( $tRECT2, "Right", $w )
DllStructSetData( $tRECT2, "Bottom", $h )

WinMove( $hToolbar, "", 0, 0, $w, $aTBsize[1] )
$oIExplorerBrowser.SetRect( $NULL, DllStructGetPtr( $tRECT2 ) )

The Static keyword secures that the pointer to $tRECT2 is still valid when the function exits.

Link to comment
Share on other sites

Oh hello LarsJ,

I firstly did not recognize that this great piece of code is also your work :)

Unfortunately it does not work with the static pointer. It does not even work on

my win 7 virtual machine???  My Autoit version is v3.3.8.1

As I do not know any better for now I compiled it and appended the file.
This could be a starting point to figure out the differences between our systems.

(I would never include any malicious code but anyway you should use a vm too)

Maybe you could do the same, I would really like to use this great code but need the resizing.
 

best regards

Bluesmaster

Windows Explorer right pane.rar

Edited by Bluesmaster

My UDF: [topic='156155']_shellExecuteHidden[/topic]

Link to comment
Share on other sites

Bluesmaster, Are you running a 32 bit Explorer on a 64 bit system? This can not be done as I have written in the last line of the first post just above the download link.

Link to comment
Share on other sites

I read it. And I could swear I had implemented "#AutoIt3Wrapper_UseX64=y".

But you are right, it seems as I had forgotten it.

Its also a bit mysterious to my why the "Initialize" - method tolerates that mistake and the "SetRect" method does not

But anyway: Sorry for my mistake and thank you for the hint.

Bluesmaster

My UDF: [topic='156155']_shellExecuteHidden[/topic]

Link to comment
Share on other sites

In ICU I use something like this to prevent this kind of error.

If @OSArch = "X64" And Not @AutoItX64 Then
MsgBox(16, "Fatal Error", "This software runs as a 32bit program and will not run correctly on a 64bit OS.")
Exit
ElseIf @OSArch <> "X64" And @AutoItX64 Then
MsgBox(16, "Fatal Error", "This software runs as a 64bit program and will not run correctly on a 32bit OS.")
Exit
EndIf
Link to comment
Share on other sites

  • 2 months later...

Hi;

There is a easy way to implement the windows explorer window in my own autoit program? I try to create a udf to call one single line to create the window but ive got too much const errors.  :sweating:

Can you help me out?

thanks!

by the way, i think this is the most perfect way to show it.  :thumbsup:

Link to comment
Share on other sites

I once started to do that. I use the "xp-version" because it uses the good old syslistview32 which can be automated more easy.

explorerRightPaneUDF.au3

post-77502-0-77625100-1393542606_thumb.ppost-77502-0-15709600-1393542611_thumb.p

Its not only 1 function because the interface need some callbacks-stubs but its ok.

All tributes go the amazing LarsJ. I will never understand how he has figured out all those miles of constants and interface definitions

 

best regards

Blues

 

Edited by Bluesmaster

My UDF: [topic='156155']_shellExecuteHidden[/topic]

Link to comment
Share on other sites

Blues;

I got it! thank you, do you know which functions that sets the preferences for this options?

- Open folder on the same window;

- change the view type ( Details, list,  small, medium, large icons);

- change the path folder with a button ( i try to use the "ToolbarFunctions.au3" but no luck).

Thank you a lot!

Link to comment
Share on other sites

What a lot of activity. I like that.

Phillipe, I do not have time right now, but I will come back with an answer tomorrow, if Bluesmaster or somebody else hasn't answered.

Link to comment
Share on other sites

Hi,
 
unfortunately I cannot answer all questions. Viewtype is easy:
 

DllStructSetData( $tFOLDERSETTINGS, "ViewMode", 1  )  ; 1 = medium  2 = small   | 3 = list  | 4  =  details  | 5 =  thumbnail| 6 =  large | 7 = filmstrip

Renavigation must be done with ...

$oIShellBrowser.BrowseObject( $pidlRel , 1 ) ; 0 = default user setting   |  1 = open folders in same window   | 2 = open folders in new window

...I think. But I dont know how to get the oIShellBrowser object I just got the pIShellBrowser
This must solve the first question too through the 2. parameter if we get this to run
 
 
ehm....LarsJ  ?   o:)
 
 
new more simplified code:
 

#include "WinAPIEx.au3"
global $hHook, $oIShellView, $hGui, $hExplorer
HotKeySet("{ESC}", "_Exit")
Func _Exit()
    _WinAPI_UnhookWindowsHookEx( $hHook )
    $oIShellView = 0
    Exit
EndFunc

explorerRightPane()

While Sleep(  1000 )
WEnd


Func explorerRightPane( $path = @ScriptDir , $x = 100 , $y = 100 , $width = 500 , $height = 500)


    ; 1 - CONSTANTS
    global $sIID_IServiceProvider = "{6D5140C1-7436-11CE-8034-00AA006009FA}"
    $dtag_IServiceProvider        = "QueryService hresult(ptr;ptr;ptr*);"
    $tagMSG                       = "hwnd hwnd;uint message;wparam wParam;lparam lParam;dword time;int X;int Y"
    global $sIID_ICommDlgBrowser  = "{000214F1-0000-0000-C000-000000000046}"
    $dtag_ICommDlgBrowser         = "OnDefaultCommand hresult(ptr);OnStateChange hresult(ptr;ulong);IncludeObject hresult(ptr;ptr);"
    $dtag_IOleWindow              = "GetWindow hresult(hwnd*);ContextSensitiveHelp hresult(int);"
    $sIID_IShellFolder            = "{000214E6-0000-0000-C000-000000000046}"
    $tRIID_IShellFolder           = _WinAPI_GUIDFromString( $sIID_IShellFolder )
    $dtag_IShellFolder            = "ParseDisplayName hresult(hwnd;ptr;wstr;ulong*;ptr*;ulong*);EnumObjects hresult(hwnd;dword;ptr*);BindToObject hresult(ptr;ptr;clsid;ptr*);BindToStorage hresult(ptr;ptr;clsid;ptr*);CompareIDs hresult(lparam;ptr;ptr);CreateViewObject hresult(hwnd;clsid;ptr*);GetAttributesOf hresult(uint;struct*;ulong*);GetUIObjectOf hresult(hwnd;uint;struct*;clsid;uint*;ptr*);GetDisplayNameOf hresult(ptr;dword;struct*);SetNameOf hresult(hwnd;ptr;wstr;dword;ptr*);"
    $sIID_IShellBrowser           = "{000214E2-0000-0000-C000-000000000046}"
    $dtag_IShellBrowser           = $dtag_IOleWindow &"InsertMenusSB hresult(handle;ptr);SetMenuSB hresult(handle;handle;hwnd);RemoveMenusSB hresult(handle);SetStatusTextSB hresult(ptr);EnableModelessSB hresult(int);TranslateAcceleratorSB hresult(ptr;word);BrowseObject hresult(ptr;uint);GetViewStateStream hresult(dword;ptr*);GetControlWindow hresult(uint;hwnd);SendControlMsg hresult(uint;uint;wparam;lparam;lresult);QueryActiveShellView hresult(ptr*);OnViewWindowActive hresult(ptr);SetToolbarItems hresult(ptr;uint;uint);"
    $sIID_IShellView              = "{000214E3-0000-0000-C000-000000000046}"
    $tRIID_IShellView             = _WinAPI_GUIDFromString( $sIID_IShellView )
    $dtag_IShellView              = $dtag_IOleWindow & "TranslateAccelerator hresult(ptr);EnableModeless hresult(int);UIActivate hresult(uint);Refresh hresult();CreateViewWindow hresult(ptr;ptr;ptr;ptr;hwnd*);DestroyViewWindow hresult();GetCurrentInfo hresult(ptr*);AddPropertySheetPages hresult(dword;ptr;lparam);SaveViewState hresult();SelectItem hresult(ptr;uint);GetItemObject hresult(uint;struct*;ptr*);"
    $tagFOLDERSETTINGS            = "uint ViewMode;uint fFlags"
    DllCall("ole32.dll", "long", "OleInitialize", "ptr", 0)


    ; 2 - GUI ( Wrapper )
    $hGui       = GUICreate( "" , $width, $height, $x, $y) ;  $WS_POPUP = 0x80000000
    GUISetState( @SW_SHOW, $hGui )
    Local $hMessageFilter ; , $hHook    ; Catch window messages
    $hMessageFilter = DllCallbackRegister( "boxCallbacks", "long", "int;wparam;lparam" )
    $hHook = _WinAPI_SetWindowsHookEx( $WH_GETMESSAGE , DllCallbackGetPtr( $hMessageFilter ) , 0 , _WinAPI_GetCurrentThreadId() )


    ; 3 - START DIR + SIZE
    Local $pDesktopFolder
    $aRet            = DllCall( "shell32.dll", "uint", "SHGetDesktopFolder", "ptr*", 0 )
    $pDesktopFolder  = $aRet[1]
    $oIDesktopFolder = ObjCreateInterface( $pDesktopFolder, $sIID_IShellFolder, $dtag_IShellFolder )    ; $oIDesktopFolder is used in oIShellBrowser_BrowseObject because the PIDLs are absolute PIDLs. This means that they are relative to the Desktop (and not the parent folder).
    Local $pParentFolder, $pidlRel, $pFolder
    $pPidlHome     = DllCall( "shell32.dll", "ptr", "ILCreateFromPathW", "wstr", $path )[0]
    $aRet          = DllCall( "shell32.dll", "long", "SHBindToParent", "ptr", $pPidlHome, "ptr", DllStructGetPtr( $tRIID_IShellFolder ), "ptr*", 0, "ptr*", 0 )
    $pParentFolder = $aRet[3]
    $pidlRel       = $aRet[4]
    $oIShellFolder = ObjCreateInterface( $pParentFolder, $sIID_IShellFolder, $dtag_IShellFolder ) ; Parent folder
    $oIShellFolder.BindToObject( $pidlRel, 0x00000000 , $tRIID_IShellFolder, $pFolder )           ; $NULL    = 0x00000000
    $oIShellFolder = ObjCreateInterface( $pFolder, $sIID_IShellFolder, $dtag_IShellFolder )       ; @ScriptDir
    $aPos          = WinGetClientSize(   $hGui     )
    $tRECT         = DllStructCreate(    $tagRECT  )
    DllStructSetData( $tRECT , "Left"   , 0        )
    DllStructSetData( $tRECT , "Top"    , 0        )
    DllStructSetData( $tRECT , "Right"  , $aPos[0] )
    DllStructSetData( $tRECT , "Bottom" , $aPos[1] )


    ; 4 - SHELL BROWSER
    Local $pShellView
    $oIShellFolder.CreateViewObject( $hGui, $tRIID_IShellView, $pShellView )
    $oIShellView        = ObjCreateInterface( $pShellView, $sIID_IShellView, $dtag_IShellView )
    $dtag_IShellBrowser = "QueryInterface hresult(ptr;ptr*);AddRef ulong();Release ulong();" & $dtag_IShellBrowser ; Inherits from IUnknown
    $pIShellBrowser     = DllCall('ole32.dll', 'ptr', 'CoTaskMemAlloc', 'uint_ptr', 152 )[0]  ; $AllocSize = $PtrSize * (18 + 1) = 8 * 19  = 152
    $tInterface         = DllStructCreate( "ptr[" & 18 + 1 & "]", $pIShellBrowser )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr( DllCallbackRegister( "oIShellBrowser_QueryInterface"     , "long"  , "ptr;ptr;ptr*"           ))  ,  2 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr(DllCallbackRegister( "oIShellBrowser_AddRef"              , "ulong" , "ptr"                    ))  ,  3 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr(DllCallbackRegister( "oIShellBrowser_Release"             , "ulong" , "ptr"                    ))  ,  4 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr(DllCallbackRegister( "oIShellBrowser_GetWindow"           , "long"  , "ptr;hwnd*"              ))  ,  5 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr( DllCallbackRegister( "oIShellBrowser_InsertMenusSB"      , "long"  , "ptr;handle;ptr"         ))  ,  7 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr(DllCallbackRegister( "oIShellBrowser_SetMenuSB"           , "long"  , "ptr;handle;handle;hwnd" ))  ,  8 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr(DllCallbackRegister( "oIShellBrowser_RemoveMenusSB"       , "long"  , "ptr;handle"             ))  ,  9 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr(DllCallbackRegister( "oIShellBrowser_BrowseObject"        , "long"  , "ptr;ptr;uint"            ))  , 13 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr(DllCallbackRegister( "oIShellBrowser_GetControlWindow"    , "long"  , "ptr;uint;hwnd"          ))  , 15 )
    DllStructSetData( $tInterface , 1,  DllCallbackGetPtr(DllCallbackRegister( "oIShellBrowser_OnViewWindowActive"  , "long"  , "ptr;ptr"                ))  , 18 )
    DllStructSetData( $tInterface , 1 , $pIShellBrowser + 8 ) ; Interface method pointers are actually pointer size away


    ; 5 - WINDOW
    $tFOLDERSETTINGS = DllStructCreate( $tagFOLDERSETTINGS )
    DllStructSetData( $tFOLDERSETTINGS, "ViewMode", 1  )  ; 1 = medium  2 = small   | 3 = list  | 4  =  details  | 5 =  thumbnail| 6 =  large | 7 = filmstrip
    DllStructSetData( $tFOLDERSETTINGS, "fFlags"  , 0x00800000   ) ;$FWF_NOCOLUMNHEADER  = 0x00800000 > sorgt auch für frei verschiebbare Elemente
    $hViewWindow = $oIShellView.CreateViewWindow(   0x00000000 , DllStructGetPtr( $tFOLDERSETTINGS ), $pIShellBrowser, DllStructGetPtr( $tRECT ), $hExplorer )    ;  $NULL    = 0x00000000
    ConsoleWrite( $hViewWindow )
    $oIShellView.UIActivate( 1 )  ; $SVUIA_ACTIVATE_NOFOCUS = 1


    ; 6 - REBROWSE (experiments, no success so far)
    Sleep( 2000 )

;~  Local $pParentFolder, $pidlRel, $pFolder
;~  $pPidlHome     = DllCall( "shell32.dll", "ptr", "ILCreateFromPathW", "wstr", "c:\" )[0]
;~  $aRet          = DllCall( "shell32.dll", "long", "SHBindToParent", "ptr", $pPidlHome, "ptr", DllStructGetPtr( $tRIID_IShellFolder ), "ptr*", 0, "ptr*", 0 )
;~  $pParentFolder = $aRet[3]
;~  $pidlRel       = $aRet[4]
;~  $oIShellFolder = ObjCreateInterface( $pParentFolder, $sIID_IShellFolder, $dtag_IShellFolder ) ; Parent folder
;~  $oIShellFolder.BindToObject( $pidlRel, 0x00000000 , $tRIID_IShellFolder, $pFolder )  ;  $NULL    = 0x00000000

    ; http://msdn.microsoft.com/en-us/library/windows/desktop/bb775113(v=vs.85).aspx

;~  $oIShellFolder = ObjCreateInterface( $pIShellBrowser, $sIID_IShellBrowser , $dtag_IShellBrowser ) ; Parent folder
;~  $oIShellBrowser.BrowseObject( $pidlRel , 1 ) ; 0 = default user setting   |  1 = open folders in same window   | 2 = open folders in new window

;~  Global Const $SBSP_DEFBROWSER            = 0x0000     ; Use default behavior, which respects the view option (the user setting to create new windows or to browse in place). In most cases, calling applications should use this flag.
;~  Global Const $SBSP_SAMEBROWSER           = 0x0001     ; Browse to another folder with the same Windows Explorer window.
;~  Global Const $SBSP_NEWBROWSER            = 0x0002     ; Creates another window for the specified folder.



EndFunc



; CALLBACKS (IShellBrowser)
Func oIShellBrowser_GetWindow( $pSelf, $hExplorer )
    DllStructSetData( DllStructCreate( "hwnd", $hExplorer ) , 1 , $hGui ) ; belege den DLL-Struct mit dem zugehörigen windowhandle ( $hExplorer ist der Pointer der auf dass DLL struct zeigen muss )
EndFunc
Func oIShellBrowser_QueryInterface( $pSelf, $pRIID, $pObj )
    Return 0x80004002  ;  $E_NOINTERFACE = 0x80004002
EndFunc
Func oIShellBrowser_AddRef( $pSelf )
EndFunc
Func oIShellBrowser_Release( $pSelf )
EndFunc
Func oIShellBrowser_InsertMenusSB( $pSelf, $hmenuShared, $lpMenuWidths )
EndFunc
Func oIShellBrowser_GetControlWindow( $pSelf, $id, $lphwnd )
EndFunc
Func oIShellBrowser_OnViewWindowActive( $pSelf, $ppshv )
EndFunc
Func oIShellBrowser_SetMenuSB( $pSelf, $hmenuShared, $holemenuRes, $hwndActiveObject )
EndFunc
Func oIShellBrowser_RemoveMenusSB( $pSelf, $hmenuShared )
EndFunc
Func oIShellBrowser_BrowseObject( $pidl, $wFlags )
EndFunc

My UDF: [topic='156155']_shellExecuteHidden[/topic]

Link to comment
Share on other sites

I have not gone ahead with the scripts by Bluesmaster. Instead I have moved most code from the start script to an UDF: WindowsExplorer.au3.

This is the new start script (included in the zip):

#include <GuiConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt( "MustDeclareVars", 1 )

; Project includes
#include "Resources\Include\WindowsExplorer.au3"  ; Include this file
#include "Resources\Include\ToolbarFunctions.au3" ; Edit this file to modify toolbar

MainFunc()


Func MainFunc()

  ; Create GUI
  Local $sTitle = "Windows Explorer right pane"
  Local $iStyle = BitOR( $GUI_SS_DEFAULT_GUI, $WS_CLIPCHILDREN, $WS_MAXIMIZEBOX, $WS_SIZEBOX )
  Local $hGui   = GUICreate( $sTitle, 700, 400, 200, 50, $iStyle )

  ; Show GUI
  GUISetState( @SW_SHOW, $hGui )

  ; Create toolbar
  ; CreateToolbar( $hGui, $bLargeIcons = False )
  CreateToolbar( $hGui, True )

  ; Create Explorer window
  ; CreateExplorerWindow( $hGui, $sFolder = @ScriptDir, $iView = $FVM_DETAILS )
  ;   $FVM_ICON       = 1 ; The view should display medium-size icons.
  ;   $FVM_SMALLICON  = 2 ; The view should display small icons.
  ;   $FVM_LIST       = 3 ; Object names are displayed in a list view.
  ;   $FVM_DETAILS    = 4 ; Object names and other selected information, such as the size or date last updated, are shown.
  ;   $FVM_THUMBNAIL  = 5 ; The view should display thumbnail icons.
  ;   $FVM_TILE       = 6 ; The view should display large icons.
  ;   $FVM_THUMBSTRIP = 7 ; The view should display icons in a filmstrip format.
  ;CreateExplorerWindow( $hGui, "C:\Windows", $FVM_ICON )
  CreateExplorerWindow( $hGui )

  ; Message loop
  Local $iMsg
  While 1
    $iMsg = GUIGetMsg()
    If $iMsg = 0 Or $iMsg = $GUI_EVENT_MOUSEMOVE Then ContinueLoop
    Switch $iMsg
      Case $idToolbarClick, $idDropDownMenu, $idBackMenu, $idViewMenu
        ToolbarEvent( $iMsg )
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

EndFunc

This code doesn't work on XP, and you need AutoIt 3.3.10.0+ (however, only a matter of a few includes).

Let me know if there are any issues.

Windows Explorer right pane.7z

Edited by LarsJ
Link to comment
Share on other sites

Link to comment
Share on other sites

Inververs, You are absolutely right. There is an issue when the window is resized. The faulty code is in the SetRect method of the ExplorerBrowser object in function WM_SIZING in bottom of WindowsExplorer.au3. It has something to do with differences in parameter passing on 32 and 64 bit systems. The problem is fixed in the new zip in post #15.

Note that this issue also exists in the zip in first post. And I have noticed a few other minor issues. I will update the zip. Hopefully within a relatively short time.

Link to comment
Share on other sites

@Lars

can you have a look at the code in #14 when you have some time then?

You dont really have to read it all. The issue is just point 6. where we need  oIShellBrowser from  pIShellBrowser

to renavigate/ navigate in place

 

But dont hurry 

best regards

Blues

My UDF: [topic='156155']_shellExecuteHidden[/topic]

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