IHTMLDocument2 IE浏览器编程

执行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. }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值