Environment: VC6 SP4; Windows 98, NT4, 2000, XP; Internet Explorer 5.x, 6.x
Recently, I had to connect to a running instance of Internet Explorer inside a Citrix environment in seamless mode (it’s a way to launch an application in a new session without the Desktop).
All the methods exposed in other articles (such as Using ShellWindows) are not bug free. For example, if you kill explorer.exe and you try to get ShellWindows, this object is unavailable. This also happens in Citrix environments if you open an Internet Explorer window in the seamless mode because you don’t have a Desktop launched (and, of course, no explorer.exe is running in that session).
On the other side, if you use Browser Helper Objects (BHO), you have to register your DLL and it will be loaded by all instances of both Windows Explorer and Internet Explorer. This is not desirable, especially if you want to attach your automation code only after opening some specific window.
I have found a better way to obtain the WebBrowser object associated to a running instance of Internet Explorer. It is based upon some yet-to-be-documented features of the Shell. This method ONLY works inside the process of Internet Explorer, so you will have to hook your code previously with SetWindowsHookEx().
I hope this can help somebody. The code is as follows:
#include <comdef.h> #include <shlobj.h> #define CWM_GETISHELLBROWSER (WM_USER+ 7) #define GetIShellBrowser(_hwnd) (IShellBrowser FAR *) :: SendMessage(_hwnd,CWM_GETISHELLBROWSER, 0, 0L) IShellBrowser* pShellBrowser=GetIShellBrowser(hWnd); // hWnd is the handle of the target IExplorer window if(pShellBrowser!=NULL) { //DO NOT release pShellBrowser IServiceProviderPtr pIsp; IServiceProviderPtr pIsp2; IWebBrowser2Ptr pBrowser; HRESULT hr= pShellBrowser->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&pIsp)); if(hr==S_OK && pIsp!=NULL) { hr=pIsp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&pIsp2)); if(hr==S_OK && pIsp2!=NULL) { hr=pIsp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&pBrowser)); if(hr==S_OK && pBrowser!=NULL) { //Here you have the browser attached to the IExplorer window } } } }
References
Namespace Extensions—the Undocumented Windows Shell
INFO: Accessing the Object Model from Within an ActiveX Control
Connect to Internet Explorer Instances, from Your Own Process.