2012-07-25 59 views
2

目前我想自动运行IE浏览器。我已经成功连接使用以下代码的运行IE(I假设仅存在一个IE一个翼片内)如何在C++ XE2中监听使用IWebBrowser2运行IE的事件?

#include "atl/atlbase.h" 
#include <exdisp.h> 
#include <mshtml.h> 
CComQIPtr<IWebBrowser2> pCurIE;  
void __fastcall TForm4::Button3Click(TObject *Sender) 
{ 
    bool SuccessToHook = false; 
    CComPtr<IShellWindows> m_spSHWinds; 
    if (FAILED(m_spSHWinds.CoCreateInstance(__uuidof(ShellWindows)))){ 

     return ; 
    } 


    LONG nCount; 
    m_spSHWinds->get_Count(&nCount); 
    ShowMessage(nCount); 
    for (int i = 0; i < nCount; i++) { 
     CComPtr<IDispatch> pDisp; 
     m_spSHWinds->Item(CComVariant(i), &pDisp); 
     CComQIPtr<IWebBrowser2> pIE(pDisp); 
     if (pIE == NULL){ 

      continue ; 
     } 
     CComPtr<IDispatch> pDispDoc; 
     pIE->get_Document(&pDispDoc); 
     CComQIPtr<IHTMLDocument2> pHtmlDoc(pDispDoc); 
     if (pHtmlDoc){ 
      pCurIE = pIE; 
      SuccessToHook = true; 
      break ; 
     } 
    } 
    ShowMessage(SuccessToHook ? "Success to hook." : "Failed to hook."); 
} 

现在我可以控制当前运行IE像导航和读取的当前状态。但是,当我想在onDocumentComplete事件这样的事件被触发时显示消息。我不知道如何按照我当前的代码来收听活动。一个简单的示例代码与BCB将非常赞赏,因为有一些样本与VC + +,但我的项目是在C++ XE2。


谢谢@Remy Lebeau和this link,我终于解决了我的问题。 我在这里留下我的代码,并希望这可能对别人有帮助。

从TEventDispatcher

#include <exdisp.h> 
#include <exdispid.h> 
#include <mshtml.h> 
#include <mshtmdid.h> 
#include <utilcls.h> 
//--------------------------------------------------------------------------- 
class TForm4; 
class EventHandler:public TEventDispatcher<EventHandler,&DIID_DWebBrowserEvents2>{ 
    private: 
     bool connected; 
     TForm4 *theform; 
     IUnknown* server; 
    protected: 
     HRESULT InvokeEvent(DISPID id, TVariant *params){ 
      switch(id){ 
       case DISPID_DOCUMENTCOMPLETE: 
        ShowMessage("On Document Complete"); 
        break; 
       default: 
        break; 
      } 
     } 
    public: 
     EventHandler(){ 
      connected = false; //not connected; 
      theform = false; //backptr to form is null 
     } 
     ~EventHandler(){ 
      if (connected) 
       Disconnect(); 
     } 
     void Connect(TForm4 *form, IUnknown* srv){ 
      server = srv; 
      theform = form; //back pointer to form to do stuff with it. 
      server->AddRef(); //addref the server 
      ConnectEvents(server); 
     } 
     void Disconnect(){ 
      DisconnectEvents(server); //disconnect the events 
      server->Release(); 
     } 
}; 

开始派生的类听

void __fastcall TForm4::Button5Click(TObject *Sender) 
{ 
    Event = new EventHandler(); 
    Event->Connect(this, pCurIE); 
} 

停止监听

void __fastcall TForm4::Button6Click(TObject *Sender) 
{ 
    Event->Disconnect(); 
} 

回答

2

你必须写在代码中的类,它实现了DWebBrowserEvents2接口。然后,您可以查询浏览器的IConnectionPointContainer接口,调用IConnectionPointContainer::FindConnectionPoint()方法找到与DWebBrowserEvents2对应的IConnectionPoint,并调用IConnectionPoint::Advise()方法将其传递给您的类的一个实例。当您完成使用事件时,请不要忘记拨打IConnectionPoint::Unadvise()

为了帮助你,你可以从utilcls.h中的VCL的TEventDispatcher类中派生出你的类。它的ConnectEvents()DisconnectEvents()方法为你处理IConnectionPoint的东西。然后您将覆盖抽象的InvokeEvent()方法(每个浏览器的事件都有其自己的DISPID值)。

+0

感谢您的回复。我先试试吧! – Willy 2012-07-26 03:25:43

+0

它的工作原理!你已经回答了我很多问题......非常感谢你! – Willy 2012-07-26 07:26:39