c++ - 如何在C++ XE2中监听用IWebBrowser2运行IE的事件?

标签 c++ c++builder iwebbrowser2 c++builder-xe2

目前我想自动化运行的IE。我已经使用下面的代码成功附加了正在运行的 IE(我假设一个选项卡中只有一个 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();
}

最佳答案

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

为了帮助您实现这一点,您可以从 utilcls.h 中的 VCL TEventDispatcher 类派生您的类。它的 ConnectEvents()DisconnectEvents() 方法为您处理 IConnectionPoint 内容。然后,您只需覆盖抽象的 InvokeEvent() 方法(浏览器的每个事件都有自己的 DISPID 值)。

关于c++ - 如何在C++ XE2中监听用IWebBrowser2运行IE的事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11642964/

相关文章:

c++ - 绘制点之间的水平距离

c++ - 为什么我不能用 reset() 删除 unique_ptr<char[]>?

javascript - Delphi - 无法在多线程应用程序中使用 IWebBrowser2 抑制 JavaScript 错误对话框

c++ - 创建最小共享库

c++ - 获取鼠标坐标 Qt OpenGL

c++ - Qt5 与 CMake : how to find qt translations dir?

c++ IWebBrowser 模拟点击框

c++ - 如何在IOS中打印xml图像?

c++ - GotoBookmark 太慢?

c++ - 在 IWebBrowser2 OLE 控件中禁用脚本调试? C++