博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IHTMLDocument2 IE浏览器编程
阅读量:2376 次
发布时间:2019-05-10

本文共 6089 字,大约阅读时间需要 20 分钟。

执行script:

IHTMLDocument2 *pHTMLDocument=NULL; 
if 
(!(pHTMLDocument = (IHTMLDocument2*)m_Ie.get_Document()))   
//获取 IHTMLDocument2 的接口指针
    
return
;
CString sScript = L
"window.open(\'http://www.126.com/\',\'wwww\')"
;                //设置要调用的javascript函数
CString Type = L
"javascript"
;                                        
//设置调用的脚本类型
IHTMLWindow2   *m_pHtmlWindow=NULL; 
pHTMLDocument->get_parentWindow(&m_pHtmlWindow);                    
//得到子框架
VARIANT ret;
ret.vt = VT_EMPTY;
BSTR bstr = sScript.AllocSysString();
BSTR btype = Type.AllocSysString ();
m_pHtmlWindow->execScript(bstr,btype , &ret);                        
//执行要调用的脚本函数。
::SysFreeString(bstr);
::SysFreeString(btype);
获取doc3:

     CComPtr<IHTMLDocument3> pHtmlDoc3;

pDoc2->QueryInterface(IID_IHTMLDocument3, (void**)&pHtmlDoc3);    
CComPtr<IHTMLElement> pElemPay;
if (!m_csControlID.IsEmpty())
{
pHtmlDoc3->getElementById(_bstr_t(m_csControlID), &pElemPay);  
}
获取frame及其doc2:

IHTMLFramesCollection2 *pFramesCollection2 = NULL;

hr = pIHTMLDocument2->get_frames(&pFramesCollection2);//取得框架frame的集合
long nFrameCount = 0;
hr = pFramesCollection2->get_length(&nFrameCount);  //取得子框架个数
for (long i = 0; i<nFrameCount; i++)
{
CComVariant vDispWin2;//取得子框架的自动化接口
hr = pFramesCollection2->item(&CComVariant(i), &vDispWin2);
IHTMLWindow2 *pWin2 = NULL;
hr = vDispWin2.pdispVal->QueryInterface(IID_IHTMLWindow2, (void **)&pWin2);
IHTMLDocument2 *pDoc2 = NULL;
hr = pWin2->get_document(&pDoc2);//取得字框架的 IHTMLDocument2 接口
}

获取doc2:

        方法1:

        UINT nMsg = ::RegisterWindowMessage(_T("WM_HTML_GETOBJECT"));

LRESULT lRes;
::SendMessageTimeout(hWnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (PDWORD_PTR)&lRes);
if (!lRes)
{
Log(L"SendMessageTimeout Get lRes is fail\n");
return false;
}
IHTMLDocument2 *spDoc = NULL; 
HRESULT hr = ::ObjectFromLresult(lRes, IID_IHTMLDocument2, 0, (void **)&spDoc);//如果某控件不支持MSAA特性,此函数调用会失败。

       方法2:

       HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&m_spShellWin);

       m_spShellWin->get_Count(&m_nIECount);
for (int i = 0; i<m_nIECount; i++)
{
IDispatch *spDispIE = NULL;
VARIANT v;
v.vt = VT_I4;
v.lVal = i;
hr = m_spShellWin->Item(v, &spDispIE);
VariantClear(&v);
IWebBrowser2 *spBrowser = NULL;
hr = spDispIE->QueryInterface(IID_IWebBrowser2, (void**)&spBrowser);
IDispatch *spDispDoc = NULL;
hr = spBrowser->get_Document(&spDispDoc);
IHTMLDocument2 *spDocument2 = NULL;
hr = spDispDoc->QueryInterface(IID_IHTMLDocument2,(void**)&spDocument2);

       }

绑定连接点:

        CComPtr<IHTMLWindow2> pHTMLWindow2=NULL;

hr=pHTMLDocument2->get_parentWindow ((IHTMLWindow2**)&pHTMLWindow2); 
CComPtr<IServiceProvider>spServiceProv=NULL;  
hr=pHTMLWindow2->QueryInterface (IID_IServiceProvider,(void**)&spServiceProv);  
CComPtr<IWebBrowser2> pWebBrowser2=NULL;
hr = spServiceProv->QueryService(SID_SWebBrowserApp,IID_IWebBrowser2,(void**)&pWebBrowser2);
CComPtr<IConnectionPointContainer> pCPC;
pWebBrowser2->QueryInterface(IID_IConnectionPointContainer,(void**)&pCPC);
pCPC->FindConnectionPoint( DIID_DWebBrowserEvents2,&m_pCP);
hr=m_pCP->Advise( (IUnknown*)(void*)m_pEventListener,&m_dwCookie);

m_PEventListener:

       class IEEvent :

public  HTMLDocumentEvents  //IDispatch
       {
       public:
        IEEvent(void);
        ~IEEvent(void);
        public: 
        HRESULT STDMETHODCALLTYPE QueryInterface(const struct _GUID &iid,void ** ppv) 

                { 

       if(iid==IID_IUnknown) 
    *ppv=static_cast <IUnknown *>(this); 
       else 
       {
     if(iid==IID_IDispatch) 
   *ppv=static_cast <IDispatch *>(this); 
     else 
    return E_NOINTERFACE; 
       }
      return S_OK; 
        } 
      ULONG STDMETHODCALLTYPE AddRef(void) 
      { return 1; } 
     ULONG STDMETHODCALLTYPE Release(void) 
             { return 0; } 
     HRESULT  STDMETHODCALLTYPE GetTypeInfoCount( 
/* [out] */ UINT *pctinfo) ; 
      HRESULT  STDMETHODCALLTYPE GetTypeInfo( 
/* [in] */ UINT iTInfo, 
/* [in] */ LCID lcid, 
/* [out] */ ITypeInfo **ppTInfo); 
      HRESULT  STDMETHODCALLTYPE GetIDsOfNames( 
/* [in] */ REFIID riid, 
/* [size_is][in] */ LPOLESTR *rgszNames, 
/* [in] */ UINT cNames, 
/* [in] */ LCID lcid, 
/* [size_is][out] */ DISPID *rgDispId) ; 
      HRESULT  STDMETHODCALLTYPE Invoke( 
/* [in] */ DISPID dispIdMember, 
/* [in] */ REFIID riid, 
/* [in] */ LCID lcid, 
/* [in] */ WORD wFlags, 
/* [out][in] */ DISPPARAMS *pDispParams, 
/* [out] */ VARIANT *pVarResult, 
/* [out] */ EXCEPINFO *pExcepInfo, 
/* [out] */ UINT *puArgErr) ; 
           };

cpp:

IEEvent::IEEvent(void)

{
}
IEEvent::~IEEvent(void)
{
}
 
///实现IDispatch接口 
HRESULT  IEEvent::GetTypeInfoCount(  /* [out] */ UINT *pctinfo) 
return E_NOTIMPL; 
HRESULT  IEEvent::GetTypeInfo( 
 /* [in] */ UINT iTInfo, 
 /* [in] */ LCID lcid, 
 /* [out] */ ITypeInfo **ppTInfo) 
return E_NOTIMPL; 
HRESULT IEEvent::GetIDsOfNames( 
  /* [in] */ REFIID riid, 
  /* [size_is][in] */ LPOLESTR *rgszNames, 
  /* [in] */ UINT cNames, 
  /* [in] */ LCID lcid, 
  /* [size_is][out] */ DISPID *rgDispId) 
return E_NOTIMPL; 
HRESULT IEEvent::Invoke( 
/* [in] */ DISPID dispIdMember, 
/* [in] */ REFIID riid, 
/* [in] */ LCID lcid, 
/* [in] */ WORD wFlags, 
/* [out][in] */ DISPPARAMS *pDispParams, 
/* [out] */ VARIANT *pVarResult, 
/* [out] */ EXCEPINFO *pExcepInfo, 
/* [out] */ UINT *puArgErr) 
HRESULT hr = S_OK;
#ifdef DEBUG
       char szDisp[MAX_PATH];
sprintf(szDisp,"dispIdMember=%d\n",dispIdMember);
TRACE(szDisp);
#endif
return hr;
}

添加连接点后,需要在线程中添加消息循环,防止IE卡死。通过Unadvise卸载连接点。

有如下HTML,如何用程序触发点击按钮呢?

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2. <HTML>
  3.  <HEAD>
  4.   <TITLE> New Document </TITLE>
  5.   <META NAME="Generator" CONTENT="EditPlus">
  6.   <META NAME="Author" CONTENT="">
  7.   <META NAME="Keywords" CONTENT="">
  8.   <META NAME="Description" CONTENT="">
  9.  </HEAD>
  10.  <BODY>
  11.   <input type="button" id="btnTest" value="Test" onclick="alert('点击了我');"/>
  12.  </BODY>
  13. </HTML>

首先看JS的写法

  1. var oEvent = document.createEventObject();
  2. document.getElementById("btnTest").fireEvent("onclick", oEvent);

把这段在翻译到C++里面就是:

  1. IHTMLDocument * pDoc = (IHTMLDocument *)GetHtmlDocument();
  2. CComQIPtr<IHTMLDocument3> pDoc3(pDoc);
  3. CComQIPtr<IHTMLDocument4> pDoc4(pDoc);
  4. if( pDoc3 && pDoc4 )
  5. {
  6.     IHTMLElement * pElem = NULL;
  7.     pDoc3->getElementById(_bstr_t(_T("btnTest")), &pElem);
  8.     CComQIPtr<IHTMLElement3> pElem3(pElem);
  9.     if( pElem3 )
  10.     {
  11.         CComPtr<IHTMLEventObj> pEvent;
  12.         pDoc4->createEventObject( NULL, &pEvent);
  13.         if( pEvent )
  14.         {
  15.             _variant_t vEvent(pEvent);
  16.             VARIANT_BOOL vbSuccess = VARIANT_FALSE;
  17.             pElem3->fireEvent( _bstr_t(_T("onclick"))
  18.                 , &vEvent
  19.                 , &vbSuccess
  20.                 );
  21.         }
  22.         
  23.     }
  24. }

转载地址:http://wroxb.baihongyu.com/

你可能感兴趣的文章
互联网金融火爆预示大数据时代来临
查看>>
大数据安全和隐私问题永远无法解决
查看>>
中国网库董事长王海波:实体经济也需要大数据
查看>>
互联网大会:大数据驱动的智能创新
查看>>
评论:大数据是否仅仅只是炒作?
查看>>
让大数据成为政务信息化的战略资源
查看>>
大数据时代企业须把握三个变化
查看>>
华为发布敏捷交换机备战大数据
查看>>
百度企业营销会免费开讲助渝企“搜赢大数据时代”
查看>>
大数据挖掘变革 美赛达软硬云引领车联网商业蓝海
查看>>
大数据市场火爆 互联网思维激发运营商潜能
查看>>
赵先德:不提倡每个人都分析大数据
查看>>
大数据潮起 三领域争抢蛋糕
查看>>
百度助力中小企搜赢大数据
查看>>
大数据应用的10大神话和误区
查看>>
大数据风云再起 二线龙头接棒大涨
查看>>
大数据核心就是要预测未来趋势
查看>>
风投掘金可穿戴设备:大数据才是背后真金
查看>>
搞互联网金融的,少点大数据忽悠吧!
查看>>
检测食品质量,看大数据分析
查看>>