C++ – Advise HTMLElementEvents2 sink (MSDN website)

c++comvisual-studio-2008

From the msdn website

void CMyClass::ConnectEvents(IHTMLElement* pElem)
{
    HRESULT hr;
    IConnectionPointContainer* pCPC = NULL;
    IConnectionPoint* pCP = NULL;
    DWORD dwCookie;

    // Check that this is a connectable object.
    hr = pElem->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);

    if (SUCCEEDED(hr))
    {
        // Find the connection point.
        hr = pCPC->FindConnectionPoint(DIID_HTMLElementEvents2, &pCP);

        if (SUCCEEDED(hr))
        {
            // Advise the connection point.
            // pUnk is the IUnknown interface pointer for your event sink
            hr = pCP->Advise(pUnk, &dwCookie);

            if (SUCCEEDED(hr))
            {
                // Successfully advised
            }

            pCP->Release();
        }

        pCPC->Release();
    }
} 

How do I get the pUnk pointer? I have defined CComObject *pUnk as a global variable and initialize it as CComObject::CreateInstance(&pUnk); I then use thus defined pUnk in the code above which gives the following errors:

Error 1 error C2065: 'm_dwRef' : undeclared identifier c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlcom.h 2575

Error 2 error C3861: 'FinalRelease': identifier not found c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlcom.h 2576

WHat would be the correct way to get pUnk?
A Sample code would be highly useful.
Thanks!

[Edit: I'm trying to use this sample code in my IE extension application that uses ATL to handle HTMLElementEvents2. My class derives from IDispEventImpl to handle Web browser events and I'm trying to derive from another instance of IDispEventImpl to handle HTMLElementEvents2

class ATL_NO_VTABLE CMyClass:
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CSecurMailBHO, &CLSID_MyClass>,
    public IObjectWithSiteImpl<CMyClass>,
    public IDispatchImpl<ISecurMailBHO, &IID_IMyClass, &LIBID_MyClassLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
    public IDispEventImpl<1, CMyClass, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>, //Safe alternative to Invoke
    public IDispEventImpl<2, CMyClass, &DIID_HTMLElementEvents2, &LIBID_MSHTML, 4, 0>
{
.
.
.
BEGIN_SINK_MAP(CMyClass)
     SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)//Do stuff OnDocumentComplete
     SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, BeforeNavigate2)//Handle BeforeNavigate2

     SINK_ENTRY_EX(2, DIID_HTMLElementEvents2, DISPID_HTMLELEMENTEVENTS2_ONSCROLL, OnScroll)//Handle OnScroll Event

END_SINK_MAP()
.
.

}

In my OnDocumentComplete, I call IWebBrowser2::get_Document followed by IHTMLDocument2::get_body to get the IHTMLElement object body. This is what's being sent to ConnectEvents function above. But so far, no luck. I don't know what the pUnk pointer is, and further, it seems that the call to FindConnectionPoint fails, i.e, there is no HTMLElementEvents2 connection point in the point container. Any ideas as to how I should go on about handling the htmlelementevents?????????

End Edit]

Best Solution

ATLEventHandling Sample

Edit:

void CMyClass::ConnectEvents(IHTMLElement* pElem)
{
    typedef IDispEventImpl<2, CMyClass, DIID_HTMLElementEvents2, LIBID_MSHTML, 4, 0> IMyClassHTMLElementEvents2Sink;
    IMyClassHTMLElementEvents2Sink::DispEventAdvise(pElem);
}

Because you have multiple functions DispEventAdvise on the the base IDispEventImpl classes.

Also it seems earliest version of MSHTML that defines HTMLElementEvents2 is 5.0.

Related Question