获取IWebBrowser2指针的两种方法

mac2024-03-29  40

  在Internet Explorer编程中,获取WebBrowser指针通常是一件很重要的事情,因为有了WebBrowser指针,我们就有了对IE完整的控制权。我们就可以对IE浏览器为所欲为了,想干什么都可以。比方说获取或者设置DOM控件的值。调用页面中的JavaScript,或者控制浏览器的行为 比方说刷新,前进、后退等等等等。

  下面两篇文章中,我将介绍两种方法来获取IWebBrowser2指针。

  第一种

  使用OLEACC.dll动态库中的ObjectFromLresult函数来获取。

  第二种

  使用IShellWindows 获取当前浏览器个数,然后遍历获取浏览器对象和IWebBrowser指针。

  下面介绍第一种方法:

  在MSDN中对ObjectFromLresult函数的解释

  The LresultFromObject function returns a reference, that is similar to a handle, to the specified object. Servers return this reference when handling WM_GETOBJECT.

  所以就必须要调用::RegisterWindowMessage( _T(“WM_HTML_GETOBJECT”) );和SendMessageTimeout返回的与WM_GETOBJECT消息关联的值。这样就可以利用ObjectFromLresult来获取IHTMLDocument2指针,有了IHTMLDocument2,剩下的事情就是QueryInterface来获取IWebBrowser2指针,这样就很轻松了。

  下面看下代码:

view plaincopy to clipboardprint? //用来接收EnumChildWindows的回调函数 //根据类名Internet Explorer_Server来判断是否是Internet Explorer控件 BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam) { TCHAR buf[100]; ::GetClassName( hwnd, (LPTSTR)&buf, 100 ); if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 ) { *(HWND*)lParam = hwnd; return FALSE; } else return TRUE; }; IWebBrowser2* GetWBByhWnd(HWND hIEWindow) { CoInitialize( NULL ); // Explicitly load MSAA so we know if it's installed HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") ); IWebBrowser2* pWebBrowser2=NULL; if ( hInst != NULL ) { HWND hWnd ; if(hIEWindow==NULL) { hWnd= FindWindow("IEFrame", NULL); if(hWnd==NULL) hWnd= FindWindow("CabinetWClass", NULL); if( hWnd == NULL) { MessageBox (NULL,"No Running instance of Internet Explorer!","message", MB_OK); } // walk Shell DocObject View->Internet Explorer_Server HWND hWndChild = FindWindowEx(hWnd, 0, "Shell DocObject View", NULL); if(hWndChild !=0) { hWndChild = FindWindowEx(hWndChild, 0, "Internet Explorer_Server", NULL); } hWnd=hWndChild; } else { hWnd = hIEWindow; HWND hWndChild=NULL; // Get 1st document window EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild ); if ( hWndChild ) { CComPtr<IHTMLDocument2> spDoc; LRESULT lRes; UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") ); ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes ); LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") ); if ( pfObjectFromLresult != NULL ) { HRESULT hr; hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument2, 0, (void**)&spDoc ); if ( SUCCEEDED(hr) ) { CComPtr<IHTMLWindow2>spWnd2; CComPtr<IServiceProvider>spServiceProv; hr=spDoc->get_parentWindow ((IHTMLWindow2**)&spWnd2); if(SUCCEEDED(hr)) { hr=spWnd2->QueryInterface (IID_IServiceProvider,(void**)&spServiceProv); if(SUCCEEDED(hr)) { hr = spServiceProv->QueryService(SID_SWebBrowserApp,IID_IWebBrowser2,(void**)&pWebBrowser2); if(SUCCEEDED(hr)) { return pWebBrowser2; } } } } } } // else document not ready } // else Internet Explorer is not running ::FreeLibrary( hInst ); } // else Active Accessibility is not installed CoUninitialize(); return NULL; }

  下面介绍第二种方法:

  这种方法是通过创建ShellWindows实例,得到浏览器对象实例的个数,通过遍历浏览器对象,获得IWebBrowser指针。

  在构造SHDocVw::IWebBrowser2Ptr spBrowser对象的适合,构造不成功 就会返回NULL,这样的化调用QueryInterface来获取IWebBrowser2指针是获取不到的。所有有了if(spBrowser!=NULL)这样一个判断。

  下面看代码:

view plaincopy to clipboardprint? IWebBrowser2* GetWB() { SHDocVw::IShellWindowsPtr m_spSHWinds; CComPtr<IDispatch> spDispatch; CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> pDoc2; CComPtr<IHTMLElement> pElement; CComPtr<IHTMLElementCollection> pElementCol; CComPtr<IHTMLFormElement> pFormElement; CComPtr<IHTMLInputTextElement> pInputElement; IWebBrowser2 * pWebBrowser = NULL; //创建ShellWindows实例 if (m_spSHWinds == NULL) { if (m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK) { MessageBox("Failed"); CoUninitialize(); return NULL; } } if (m_spSHWinds) { // 取得浏览器实例个数 int n = m_spSHWinds->GetCount(); for (int i = 0; i < n; i++) { _variant_t v = (long)i; IDispatchPtr spDisp = m_spSHWinds->Item(v); SHDocVw::IWebBrowser2Ptr spBrowser(spDisp); //生成一个IE窗口的智能指针 //SHDocVw::IWebBrowser2Ptr与IWebBrowser2是不一样的 //SHDocVw::IWebBrowser2Ptr是经过COM封装的,所以在此判断一下 //否则QueryInterface 会出错的。 if (spBrowser!=NULL) { HRESULT hr = spDisp.QueryInterface(IID_IWebBrowser2, &pWebBrowser); if (SUCCEEDED(hr)) { if (pWebBrowser !=NULL) { return pWebBrowser; } } } } } return NULL; }
最新回复(0)