// Copyright (c) Agilent Technologies, 2002 ////////////////////////////////////////////////////////////////////////// // Usage: // 1. Derive your class off of CPNAEventCatcher, and override the methods that you want to // catch. // 2. Call SubscribeCatcher, and pass a pointer to the AgilentPNA835x::IApplication // 3. Make sure to call IApplication::DisallowAllEvents and IApplication::AllowEventMessage // to activate your events // 4. When done receiving, either destroy your CPNACatcher, or call Release() on it. ///////////////////////////////////////////////////////////////////////// #pragma once #include "assert.h" struct __declspec(uuid("16d3c689-5f97-11d2-bc1f-0060b0b52ea7")) Catcher_Library; struct __declspec(uuid("D768D89A-DF15-11d3-B44D-001083344685")) Catcher__INetworkAnalyzerEvents; template class ATL_NO_VTABLE EventHandler: public CComObjectRootEx, public IDispatchImpl, // 2,3 parameters can be NULL without problem public IDispEventImpl<1, EventHandler, &__uuidof(Catcher__INetworkAnalyzerEvents), &__uuidof(Catcher_Library), 1, 0> { public: EventHandler(T& t):m_pT(&t){} void ReleasePointer() {m_pT = NULL;} private: T* m_pT; long FromVariant(VARIANT v){ assert(v.vt == VT_I4); return v.lVal;} BEGIN_COM_MAP(EventHandler) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() void __stdcall SCPIEvent(VARIANT eventid) { if (m_pT) m_pT->OnSCPIEvent(FromVariant(eventid)); } void __stdcall MeasurementEvent(VARIANT eventid, VARIANT measurementNumber) { if (m_pT) m_pT->OnMeasurementEvent(FromVariant(eventid),FromVariant(measurementNumber)); } void __stdcall ChannelEvent(VARIANT eventid, VARIANT ch) { if (m_pT) m_pT->OnChannelEvent(FromVariant(eventid),FromVariant(ch)); } void __stdcall HardwareEvent(VARIANT eventid) { if (m_pT) m_pT->OnHardwareEvent(FromVariant(eventid)); } void __stdcall CalEvent(VARIANT eventid, VARIANT channelNumber, VARIANT measurementNumber) { if (m_pT) m_pT->OnCalEvent(FromVariant(eventid),FromVariant(channelNumber),FromVariant(measurementNumber)); } void __stdcall UserEvent(VARIANT eventid) { if (m_pT) m_pT->OnUserEvent(FromVariant(eventid)); } void __stdcall DisplayEvent(VARIANT eventid, VARIANT windowNumber, VARIANT traceNumber) { if (m_pT) m_pT->OnDisplayEvent(FromVariant(eventid),FromVariant(windowNumber),FromVariant(traceNumber)); } void __stdcall SystemEvent(VARIANT eventid) { if (m_pT) m_pT->OnSystemEvent(FromVariant(eventid)); } BEGIN_SINK_MAP(EventHandler) SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Catcher__INetworkAnalyzerEvents), /*dispid =*/ 1, SCPIEvent) SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Catcher__INetworkAnalyzerEvents), /*dispid =*/ 2, MeasurementEvent) SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Catcher__INetworkAnalyzerEvents), /*dispid =*/ 3, ChannelEvent) SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Catcher__INetworkAnalyzerEvents), /*dispid =*/ 4, HardwareEvent) SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Catcher__INetworkAnalyzerEvents), /*dispid =*/ 5, CalEvent) SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Catcher__INetworkAnalyzerEvents), /*dispid =*/ 6, UserEvent) SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Catcher__INetworkAnalyzerEvents), /*dispid =*/ 7, DisplayEvent) SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Catcher__INetworkAnalyzerEvents), /*dispid =*/ 8, SystemEvent) END_SINK_MAP() }; template class EventHandlerChild : public EventHandler { public: EventHandlerChild(T& t):EventHandler(t){} STDMETHODIMP QueryInterface(REFIID riid,void **ppv){return _InternalQueryInterface(riid,ppv);} STDMETHODIMP_(ULONG) AddRef() {return InternalAddRef();} STDMETHODIMP_(ULONG) Release() { ULONG l = InternalRelease(); if (!l) delete this; return l; } }; class CPNAEventCatcher { private: // Not copiable CPNAEventCatcher(const CPNAEventCatcher&); CPNAEventCatcher& operator=(CPNAEventCatcher); public: CPNAEventCatcher():m_EventCatcher(new EventHandlerChild(*this)) { } HRESULT SubscribeCatcher(IUnknown * pUnk) { HRESULT hr = m_EventCatcher->DispEventAdvise(pUnk); if (SUCCEEDED(hr)) m_pUnk = pUnk; return hr; } void Release() { m_EventCatcher->ReleasePointer(); if (m_pUnk) { m_EventCatcher->DispEventUnadvise(m_pUnk); m_pUnk.Release(); } } virtual ~CPNAEventCatcher() { Release(); } virtual void OnSCPIEvent(long eventID) {} virtual void OnMeasurementEvent(long eventID,long measurementNumber) {} virtual void OnChannelEvent(long eventID,long ch) {} virtual void OnHardwareEvent(long eventID){} virtual void OnCalEvent(long eventID,long channelNumber,long measurementNumber){} virtual void OnUserEvent(long eventID){} virtual void OnDisplayEvent(long eventID,long windowNumber,long traceNumber){} virtual void OnSystemEvent(long eventID){} private: CComPtr m_pUnk; CComPtr > m_EventCatcher; };