Maneggiare HTMLElementEvents2 quando DWebBrowserEvents2 è stata gestita usando le macro di ATL
-
12-09-2019 - |
Domanda
Sto creando un Browser Helper Object utilizzando VS2008, C ++. La mia classe è stata derivata dalla IDispEventImpl tra molti altri
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()
.
.
.
}
Come risulta evidente dal codice di cui sopra, i miei DWebBrowserEvents2 vengono gestiti utilizzando le macro della ATL. Ora voglio gestire HTMLElementEvents2 (per rilevare i clic, le barre di scorrimento, etc.) per questo, QueryInterface () dell'oggetto IHTMLDocument2 per IHTMLElement, QueryInterface (), che per l'IConnectionPointContainer e chiamare IConnectionPointContainer :: FindConnectionPoint (DIID_HTMLElementEvents2). (Vedere articolo di MSDN sulla gestione HTMLElementEvents2). Il problema è che, quando ho sovrascrivere IDispatch :: Invoke nella mia classe, le maniglie DWebBrowserEvents2 (creati utilizzando le macro ATL) sicuro. Esiste un modo per gestire HTMLElementEvents2 senza sovrascrivere Invoke o implementare invocare in modo tale che essa gestisce solo HTMLElementEvents2?
Grazie, sarà apprezzato Qualsiasi aiuto.
Soluzione
Non v'è alcuna reale necessità di eseguire l'override Invoke o ottenere IConnectionPointContainer. Poiché si tratta di un progetto ATL, Implementazione di un altro IDispEventImpl:
public IDispEventImpl<2, CHelloWorldBHO, &DIID_HTMLTextContainerEvents2, &LIBID_MSHTML, 4, 0>
fa il trucco. Poi, affondare la voce come:
SINK_ENTRY_EX(2, DIID_HTMLTextContainerEvents2, DISPID_ONSCROLL, OnScroll)
In OnDocumentComplete, chiamare IWebBrowser2 :: get_Document, IHTMLDocument2 :: get_body, e quindi chiamare DispEventAdvise per iniziare a ricevere gli eventi.
Si noti che ho usato DIID_HTMLTextContainerEvents2 invece di DIID_HTMLElementEvents. Questo perché l'oggetto corpo non supporta HTMLElementEvents2, e per il mio scopo (per gestire lo scorrimento) questo funziona bene!