Thread: [code] Enumerate IE instances and retrieve interfaces.

  1. #1
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544

    [code] Enumerate IE instances and retrieve interfaces.

    No problems, just thought this code may be of use to someone.

    I wanted to enumerate open Internet Explorer windows and retrieve the corresponding COM interfaces. The standard solution, detailed in Q176792 only found 8 of the 30 ie windows I had opened. Fortunately, Active Accessibility provides another solution (detailed in Q249232). This code provides a function, EnumIEWindows(), that allows one to easily enumerate IE instances.

    Code:
    // Implementation 
    
    #include <mshtml.h>
    #include <oleacc.h>
    
    typedef BOOL (CALLBACK * IEENUMPROC)(HWND hwnd, LPVOID pif, LPARAM lParam);
    
    static BOOL CALLBACK EnumIEChildWindows(HWND hwnd, LPARAM lParam)
    {
    	TCHAR szClassName[100];
    
    	if (GetClassName(hwnd, szClassName, 100) &&
    	    lstrcmp(szClassName, TEXT("Internet Explorer_Server")) == 0)
    	{
    		*((HWND *) lParam) = hwnd;
    		return FALSE;
    	}
    
    	return TRUE;
    }
    
    BOOL WINAPI EnumIEWindows(IEENUMPROC lpEnumFunc, REFIID riid, LPARAM lParam)
    {
    	HWND hwnd;
    	HINSTANCE hInst;
    	LPFNOBJECTFROMLRESULT pfObjectFromLresult;
    	UINT uMsg     = RegisterWindowMessage(TEXT("WM_HTML_GETOBJECT"));
    
    	if (!(hInst = LoadLibrary(TEXT("OLEACC.DLL"))))
    	{
    		// Active Accessibility is not available on this machine.
    		// Windows 2000/XP have AA installed. It is available for other
    		// platforms as a redistributable.
    		return FALSE;
    	}
    
    	if (!(pfObjectFromLresult = (LPFNOBJECTFROMLRESULT) GetProcAddress(hInst, "ObjectFromLresult")))
    	{
    		FreeLibrary(hInst);
    		return FALSE;
    	}
    
    	hwnd = FindWindowEx(NULL, NULL, TEXT("IEFrame"), NULL);
    
    	while (hwnd != NULL)
    	{
    		HWND hwndChild = NULL;
    		EnumChildWindows(hwnd, EnumIEChildWindows, (LPARAM) &hwndChild);
    
    		if (hwndChild)
    		{
    			void * pif;
    			LRESULT lr;
    			HRESULT hr;
    		
    			if (SendMessageTimeout(hwndChild, uMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD_PTR *) &lr))
    			{
    				hr = pfObjectFromLresult(lr, riid, 0, &pif);
    
    				if (SUCCEEDED(hr))
    				{
    					if (!lpEnumFunc(hwnd, pif, lParam)) break;
    				}
    			} // else document is not ready.
    		}
    
    		hwnd = FindWindowEx(NULL, hwnd, TEXT("IEFrame"), NULL);
    	}
    
    	FreeLibrary(hInst);
    	return TRUE;
    }
    Code:
    // Optional header file
    
    #ifndef IEENUM_INCLUDED
    #define IEENUM_INCLUDED
    #include <objbase.h>
    typedef BOOL (CALLBACK * IEENUMPROC)(HWND hwnd, LPVOID pif, LPARAM lParam);
    BOOL WINAPI EnumIEWindows(IEENUMPROC lpEnumFunc, REFIID riid, LPARAM lParam);
    #endif
    Code:
    // Sample usage
    
    #include <mshtml.h>
    #include <exdisp.h>
    
    BOOL CALLBACK EnumIEWindowsProc(HWND hwnd, LPVOID pif, LPARAM lParam)
    {
    	IHTMLDocument2 * pDoc = (IHTMLDocument2 *) pif;
    	BSTR bstr = NULL;
    	VARIANT vt;
    
    
    	// -- Manipulate document object. --
    
    	pDoc->get_URL(&bstr);
    	MessageBoxW(NULL, bstr, NULL, 0);
    	SysFreeString(bstr);
    
    	V_VT(&vt)   = VT_BSTR;
    	V_BSTR(&vt) = SysAllocString(L"yellow");
    	pDoc->put_bgColor(vt);
    	VariantClear(&vt);
    
    
    	// -- Shows how to get parent window. --
    	
    	IHTMLWindow2 * pWindow = NULL;
    
    	pDoc->get_parentWindow(&pWindow);
    	if (pWindow)
    	{
    		bstr = SysAllocString(L"Hello World");
    		pWindow->alert(bstr);
    		SysFreeString(bstr);
    		pWindow->Release();
    	}
    
    
    	// -- Shows how to get parent web browser (See Q172763). --
    	
    	IWebBrowser2 * pBrowser  = NULL;
    	IServiceProvider * psp   = NULL;
    
    	pDoc->QueryInterface(IID_IServiceProvider, (void **) &psp);
    	if (psp)
    	{
    		psp->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void **) &pBrowser);
    		if (pBrowser)
    		{
    			pBrowser->get_LocationName(&bstr);
    			MessageBoxW(NULL, bstr, NULL, 0);
    			SysFreeString(bstr);
    			pBrowser->Release();
    		}
    
    		psp->Release();
    	}
    
    	// Generic release of pif.
    	((IUnknown *) pif)->Release();
    
    	// Return true to conntinue enumeration.
    	return TRUE;
    }
    
    
    int main(void)
    {
    	CoInitialize(NULL);
    
    	if (!EnumIEWindows(EnumIEWindowsProc, IID_IHTMLDocument2, 0))
    	{
    		MessageBox(NULL, TEXT("Active Accessibility is not installed. Please install Active Accessibility."),
    		           TEXT("Fatal Error"), MB_ICONSTOP);
    		return GetLastError();
    	}
    
    	CoUninitialize();
    	return 0;
    }
    Last edited by anonytmouse; 05-02-2004 at 02:40 AM.

  2. #2
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    I've been messing with some VC++/COM stuff recently...

    Here's another stab at enumerating Internet Explorer references but using some of VC++'s IDispatch wrapper abilities

    Code:
    #include <iostream>
    #include <string>
    #include <windows.h>
    #include <comip.h>	
    #include <comdef.h>
    
    //Paths to system dlls containing the interfaces we need
    #import "C:\WINDOWS\system32\shell32.DLL"
    #import "C:\WINDOWS\system32\SHDOCVW.DLL" 
    
    struct COM_INIT_ //Get COM ready
    {
    	COM_INIT_(){CoInitialize(0);}
    	~COM_INIT_(){CoUninitialize();}
    }COMINIT;
    
    
    int main(int argc, char *argv[])
    {
    	try
    	{
    		SHDocVw::IShellWindowsPtr lpIWins; //Shell Windows Enumeration
    		SHDocVw::IWebBrowser2Ptr lpIWeb; //WebBrowser/InternetExplorer Interface
    		Shell32::IShellDispatchPtr lpIShell; //Shell.Application Object
    		
    		lpIShell.CreateInstance(L"Shell.Application");	//Create a Shell.Application Object
    
    		lpIWins = lpIShell->Windows();	//Get references to all shell windows
    
    		for(LONG i = 0;i < lpIWins->Count;++i)
    		{			
    			//For each Shell Window check if it's using http for the protocol
    			//If so it's acting as a web browser, so show the URL
    			lpIWeb = lpIWins->Item(i);	
    			if(std::string(lpIWeb->GetLocationURL()).substr(0,4) == "http") 
    			{
                    std::cout << static_cast<char*>(lpIWeb->GetLocationURL()) << std::endl;
    			}
    		}
    		std::cout << "Success";
    	}
    	catch(_com_error& e)
    	{		
    		std::cout << "Com Error - " << e.ErrorMessage();
    	}
    }

Popular pages Recent additions subscribe to a feed