2

I was looking at a code sample by Raymond Chen, available here. From what I understand, he obtains a shell item using the IShellWindows interface. Then, using that item's IDispatch interface and a call to QueryInterface, he hops over to the item's IWebBrowserApp interface. And then a few lines later, it appears that he hops over to the item's IServiceProvider interface. My question is, before using QueryInterface, how would you even know that an IShellWindows item might support the IWebBrowserApp and IServiceProvider interfaces? For example, I don't see any documentation listing all the interfaces that an IShellWindows item supports.

11
  • 3
    The only really foolproof way is to get yourself a job with the Windows Shell team :) Commented Jun 6, 2019 at 0:53
  • 1
    You're not reading the text well enough. It says Given a window handle, you can you determine (1) whether it is an Explorer window, and if so (2) what folder it is viewing, and (3) what item is currently focused. IShellWindow does not support IWebBrowserApp, but you know in advance that you're looking for an Explorer window and that the Explorer window supports the web browser interface and is also a shell window. IShellWindow does not support IWebBrowserApp, but the Explorer window supports them both, and you know you're looking for an Explorer window. Commented Jun 6, 2019 at 1:47
  • You're not reading my question well enough. How do I know in advance that any object supports any particular set of interfaces? Commented Jun 6, 2019 at 1:50
  • 1
    It is very obscure and barely documented today, that's why he wrote a blog post about it. Goes back to around 1996 when Microsoft got excited about the Internet and realized they were falling behind, they integrated Explorer and Internet Explorer and gave the latter Explorer-like capabilities. It is poorly documented not in the least because the odds that the user is still using IE are getting to be quite low, other browsers did not try to emulate this feature. Commented Jun 6, 2019 at 7:30
  • 2
    As you found out already, there is no way to know, which interfaces any given COM object implements. Microsoft have acknowledged since, that discovering implemented interfaces might be a common task. When it came time to rejuvenate COM in the Windows Runtime, they made sure to provide a GetIids interface member. Microsoft apparently also acknowledged, that it was common enough for an implementation to hide that information, so they invented "cloaked" interfaces. So we're back at square one. Commented Jun 6, 2019 at 13:15

1 Answer 1

3

MSDN does not usually tell you which interfaces a object implements but if you look around you will often find some documentation and related interfaces you can QI. And just to make it clear, a interface is just a contract and multiple objects can implement a certain interface so you can't really blame Microsoft for not having a definitive list.

Let's try to pick apart your specific example.

The object that implements IShellWindows (CLSID_ShellWindows) does not really have any other interesting interfaces, you just care about its list of windows.

IShellWindows -> (IDispatch ->) IWebBrowserApp:

IShellWindows has a collection of open Internet Explorer and Explorer windows. For whatever reason it just gives you a IDispatch for each window instead of letting you ask for a specific interface. Possibly just because IShellWindows is also scriptable by Windows Scripting Host/Visual Basic and IDispatch plays a big role there.

The Shell windows collection includes file explorer windows and web browser windows Internet Explorer and 3rd-party web browsers). Normally each Shell window implements IDispatch; IShellWindows::Item and IShellWindows::FindWindowSW provide ways to access a Shell window's IDispatch interface.

..and the connection between IShellWindows and IWebBrowserApp/IWebBrowser2:

exdisp.h contains the following programming interfaces

  • IShellWindows
  • IWebBrowser2

IWebBrowserApp -> IShellBrowser:

Objects that have access to the site chain of the browser can get a reference to the browser on IShellBrowser using IServiceProvider::QueryService, with Service IDs such as SID_STopLevelBrowser and SID_SCommDlgBrowser. See the Knowledge Base article Retrieve the Top-Level IWebBrowser2 Interface from an ActiveX Control for more information on using service IDs.

The fact that the web browser and shell are connected like this should be no surprise for people that were interested in Windows around the Windows 98/IE 4 time frame. Internet Explorer and File Explorer were basically the same thing; Explorer could display web pages and IE could display the "file list" (IShellView).

IShellBrowser -> IShellView:

just a simple call to QueryActiveShellView.

There is a key point here; IShellFolder/IShellView can be implemented by a 3rd-party shell extension. Explorer implements IShellBrowser and it is IShellBrowser that hosts IShellView, and 3rd-party ISVs can also create file browsers that implement IShellBrowser. In theory you could have a file explorer app created by one company hosting a shell view created by a different company with no Microsoft code involved. IShellBrowser and IShellView is how they see each other.

IShellView -> IFolderView:

There is no direct connection here but if you look around you can connect the dots.

IShellFolderView is supported by the IShellView object that is returned from SHCreateShellFolderViewEx

[IShellFolderView is no longer available for use as of Windows 7. Instead, use IFolderView2 and IFolderView.]

In other cases where you can't find specific documentation you just have to try to query for interfaces you are interested in. The shell also has a ton of undocumented interfaces and a debugger is your only choice if you want to experiment with those.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the response. But notably, you skipped over the IWebBrowserApp part. :-) Which I think kind of proves my point that there's no clear, accessible way to determine these things.
Sorry, I guess I did not make that part clear. Better now? File Explorer and WebBrowser was basically the same thing until MS was forced to separate them.
It is also possible to check for IProvideClassInfo and then used the returned ITypeInfo to discover interfaces the object advertises support for. It can still support others that aren't mentioned). The only way to be sure is to call QI).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.