Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1474

[VB6] Using IShellWindows to register for SHOpenFolderAndSelectItems

$
0
0
Name:  shellwin2.jpg
Views: 1
Size:  25.2 KB
Shell Window Registration

People who've made Explorer replacements or other apps that display a window have found that they can, at best, get the folder passed to them when someone uses 'Show in folder'/'Show in Explorer' in apps like Firefox, Chrome, and torrent clients. However, if you register everything properly, any app calling SHOpenFolderAndSelectItems will be able to pass the names of selected files to a folder you've registered as displaying.

Note that for it to start your app if it's not running with the path in question registered, it will have to be the default that opens when you pass a folder to ShellExecuteEx (i.e. registered as an Explorer replacement on the system).

Some time between Windows XP and Windows 10 the API changed. I've completed this demo for Windows 10, and whatever versions use IShellView to select the items. Windows XP uses IShellFolderViewDual instead. A little more work needs to be done there, since the pidl is passed in a variant. I've gotten it almost there though, the SelectItem function will output the VARENUM type of the variant. From there it just has to be converted to a long. I'll do that in a later version as I'll have to set up virtual machines.

Requirements
oleexp.tlb v4.8 (Released with this demo on 2022 Jan 19)
oleexpimp.tlb v2.07 (Released with oleexp 4.8)
oleexp Add-on mIID.bas (Included in the oleexp download, be sure to use the one from 4.8)


The question of how to do this has been asked many times in various forums for various languages, but apart to alluding to the need to use IShellWindows.RegisterPending, nobody definitely answered.

Special thanks to The_trick for identifying the problem with MSDN's IShellWindows documentation... RegisterPending absolutely does not accept a VT_VARIANT|VT_BYREF variant, but will accept any number of types of variants that can be converted to a pidl. This demo uses a simple BSTR (VB's String type), and The_trick notes it also accepts a CSIDLs, IPersistIDList, IPersistFolder2, IStream, and Byte Arrays (perhaps containing a full ITEMIDLIST structure rather than a pointer to one?). More work is needed to identify the best way to work with this.

The key is using both RegisterPending and Register, since RegisterPending accepts a path but not an object implementing all the required interfaces, and Register takes the object but not a path (and it never tries looking anything up). It uses APIs to convert the ThreadID to an hWnd to associate them.

In a full app, you'd call RegisterPending, create the file display, then finalize with Register.

Code:

    Set pSW = New ShellWindows
    Set pDisp = ucSW1.object
    pSW.RegisterPending App.ThreadID, Text1.Text, VarPtr(vre), SWC_BROWSER, lCookie
    pSW.Register pDisp, Form1.hWnd, SWC_BROWSER, lCookie


In the future I plan on releasing a more complete implementation of these various folder interfaces that work with my Shell Browser control, to create a full replacement for Explorer.

As a bonus, the UserControl has full prototypes for several additional interfaces that weren't used.
Attached Images
  
Attached Files

Viewing all articles
Browse latest Browse all 1474

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>