3

現在、実行中の IE を自動化したいと考えています。以下のコードを使用して、実行中の IE を正常にアタッチしました (1 つのタブ内に IE が 1 つしかないと仮定します)。

#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 Event のようなイベントが発生したときにメッセージを表示したいので。現在のコードに続くイベントをリッスンする方法がわかりません。VC++ のサンプルがいくつかありますが、私のプロジェクトは C++ XE2 上にあるため、BCB を使用した簡単なサンプル コードは非常に高く評価されます。


@Remy Lebeau とこのリンクに感謝します。ようやく問題が解決しました。ここに自分のコードを残しておきます。他の人に役立つことを願っています。

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();
}
4

1 に答える 1

3

インターフェイスを実装するコードにクラスを記述する必要がありDWebBrowserEvents2ます。次に、ブラウザにそのIConnectionPointContainerインターフェイスを照会し、メソッドを呼び出して に対応IConnectionPointContainer::FindConnectionPoint()する を見つけ、クラスのインスタンスを渡すメソッドを呼び出します。イベントの使用が終わったら、忘れずに電話してください。IConnectionPointDWebBrowserEvents2IConnectionPoint::Advise()IConnectionPoint::Unadvise()

TEventDispatcherこれを支援するために、utilcls.h でVCL のクラスからクラスを派生させることができます。そのメソッドConnectEvents()DisconnectEvents()メソッドが処理IConnectionPointします。次に、抽象メソッドをオーバーライドするだけですInvokeEvent()(ブラウザーの各イベントには独自のDISPID値があります)。

于 2012-07-26T02:14:35.777 に答える