COM C++
Much of the COM C++ example was generated automatically using the > menu in the Microsoft Visual C++ IDE followed by Implement Interface on the CListener class added by New ATL Object. This was edited so both the raw methods and the method wrappers were created by the #import statement.
The listener class declaration is:
#ifndef __LISTENER_H_
#define __LISTENER_H_
#include "resource.h" // main symbols
#import "epic.exe" raw_native_types, no_namespace, named_guids
class ATL_NO_VTABLE CListener :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IDOMEventListener,
&IID_IDOMEventListener, &LIBID_Epic>
{
public:
CListener()
{
}
DECLARE_NO_REGISTRY()
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CListener)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IDOMEventListener)
END_COM_MAP()
public:
STDMETHOD(raw_handleEvent)(IDOMEvent * evt);
};
#endif //__LISTENER_H_
The listener implementation class is:
#include "stdafx.h"
#include "Listener.h"
#include <string>
typedef std::basic_string< unsigned short > DOMString;
STDMETHODIMP CListener::raw_handleEvent( IDOMEvent *rawEvent)
{
IDOMEventPtr pEvent = rawEvent;
IDOMNode3Ptr pNode = pEvent->target;
DOMString context;
while (pNode)
{
if (pNode->nodeType == NODE_ELEMENT)
{
context.insert(0, pNode->nodeName);
context.insert(0, L"(");
}
pNode = pNode->parentNode;
}
_Application3Ptr pEpic(__uuidof(Application));
context += L"\n";
pEpic->Print(_variant_t(context.c_str()));
pEvent->stopPropagation();
return S_OK;
}
The method that creates and attaches the listener is:
void AttachListener()
{
CListener *pListener = new CComObject<CListener>;
IDOMEventListenerPtr pIntfc;
if (pListener)
{
pListener->QueryInterface(IID_IDOMEventListener,
(void **) &pIntfc);
_Application3Ptr pEpic(__uuidof(Application));
IDOMEventTargetPtr pDocTarget;
pDocTarget = pEpic->ActiveDocument;
pDocTarget->addEventListener(_bstr_t("click"), pIntfc, true);
}
}