1

VS2008、C++ を使用してブラウザ ヘルパー オブジェクトを作成しています。私のクラスは、他の多くのクラスの中で IDispEventImpl から派生しています

class ATL_NO_VTABLE CHelloWorldBHO :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,
    public IObjectWithSiteImpl<CHelloWorldBHO>,
    public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
    public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>

{
.
.
.
BEGIN_SINK_MAP(CHelloWorldBHO)
     SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
     SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, BeforeNavigate2)//Handle BeforeNavigate2
END_SINK_MAP()
.
.
.
}

上記のコードから明らかなように、私の DWebBrowserEvents2 は ATL のマクロを使用して処理されます。ここで、HTMLElementEvents2 (クリック、スクロールバーなどを検出するため) を処理したいと考えています。そのために、IHTMLElement の IHTMLDocument2 オブジェクトを QueryInterface() し、IConnectionPointContainer の QueryInterface() を呼び出して、IConnectionPointContainer::FindConnectionPoint(DIID_HTMLElementEvents2) を呼び出します。( HTMLElementEvents2 の処理に関する msdn の記事を参照してください)。問題は、クラスで IDispatch::Invoke を上書きすると、DWebBrowserEvents2 ハンドル (ATL マクロを使用して作成) が失敗することです。Invoke を上書きせずに HTMLElementEvents2 を処理する方法、または HTMLElementEvents2 のみを処理するように Invoke を実装する方法はありますか?
ありがとう、助けていただければ幸いです。

4

1 に答える 1

1

Invokeをオーバーライドしたり、IConnectionPointContainerを取得したりする必要はありません。これはATLプロジェクトであるため、別のIDispEventImplを実装します。

public IDispEventImpl<2, CHelloWorldBHO, &DIID_HTMLTextContainerEvents2, &LIBID_MSHTML, 4, 0>

トリックを行います。次に、エントリを次のようにシンクします。

SINK_ENTRY_EX(2, DIID_HTMLTextContainerEvents2, DISPID_ONSCROLL, OnScroll)

OnDocumentCompleteで、IWebBrowser2 :: get_Document、IHTMLDocument2 :: get_bodyを呼び出してから、DispEventAdviseを呼び出してイベントの受信を開始します。

DIID_HTMLElementEventsの代わりにDIID_HTMLTextContainerEvents2を使用したことに注意してください。これは、bodyオブジェクトがHTMLElementEvents2をサポートしていないためです。私の目的(スクロールを処理するため)では、これは問題なく機能します。

于 2009-07-17T20:34:11.823 に答える