How do I listen the event of Running IE with IWebBrowser2 in C++ XE2?

爷,独闯天下 提交于 2019-12-12 19:00:42

问题


Currently I want to automate the running IE. I have successfully attached the running IE using below code (I assume there is only one IE within one tab)

#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." );
}

Now I can control the current running IE like navigating and read the current state. But as I want to show messages when the events like onDocumentComplete Event are fired. I have no idea how to listen the event following my current code. A simple sample code with BCB will be very appreciated as there are some samples with VC++ but my project is on C++ XE2.


Thanks @Remy Lebeau and this link, I finally solve my problem. I leave my code here and hope it maybe helpful for someone else.

A class derived from 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();
        }
};

Start to listen

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

Stop listening

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

回答1:


You have to write a class in your code that implements the DWebBrowserEvents2 interface. Then you can query the browser for its IConnectionPointContainer interface, call the IConnectionPointContainer::FindConnectionPoint() method to find the IConnectionPoint that cooresponds to DWebBrowserEvents2, and call the IConnectionPoint::Advise() method passing it an instance of your class. Don't forget to call IConnectionPoint::Unadvise() when you are done using the events.

To help you with that, you can derive your class from the VCL's TEventDispatcher class in utilcls.h. Its ConnectEvents() and DisconnectEvents() methods handle the IConnectionPoint stuff for you. You would then just override the abstract InvokeEvent() method (each of the browser's events have their own DISPID values).



来源:https://stackoverflow.com/questions/11642964/how-do-i-listen-the-event-of-running-ie-with-iwebbrowser2-in-c-xe2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!