// CMSEventBinder.h : Declaration of the CMSEventBinder #ifndef __MSEVENTBINDER_H_ #define __MSEVENTBINDER_H_ #include #include #include #include #include #include #include "segimpl.h" #include "seg.h" #include "resource.h" // main symbols #include "mslcid.h" typedef CComQIPtr PQIASSite; typedef CComQIPtr PQIAScript; ///////////////////////////////////////////////////// class __declspec(uuid("FCBF24F7-FB97-4fa3-B57E-97BCB5AF1D26")) ATL_NO_VTABLE CMSEventHandlerBase: public CComObjectRootEx, public IObjectWithSiteImplSec, public IDispatchImpl { BEGIN_COM_MAP(CMSEventHandlerBase) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IObjectWithSite) END_COM_MAP() protected: CMSEventHandlerBase(){} // Cookie for canceling the advise DWORD cancelCookie; public: virtual ~CMSEventHandlerBase(){ if(cancelCookie!=-1){ Cancel(cancelCookie); } } // Id of the handler function DISPID ID_handler; // The DISPID of the event DISPID ID_event; // GUID of the Interface whose event we want to know about GUID gEventInf; // Connection Point that the advise is on CComQIPtr cancelPoint; // IDispatch where the handler function is from CComQIPtr pDScript; // Override invoke to throw events on up STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr){ if(dispidMember == ID_event) { return pDScript->Invoke(ID_handler, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); } else { return E_NOTIMPL; } } // Unadvise STDMETHOD(Cancel)(DWORD dwCancel){ HRESULT hr = E_INVALIDARG; if(dwCancel == cancelCookie && cancelCookie != -1){ hr = cancelPoint->Unadvise(dwCancel); if (SUCCEEDED(hr)){ cancelPoint.Release(); pDScript.Release(); cancelCookie = -1; } } return hr; } DWORD getCookie(){ return cancelCookie; } STDMETHOD(setCookie)(DWORD newValue){ HRESULT hr = E_FAIL; if(cancelCookie==-1){ cancelCookie = newValue; hr = S_OK; } return hr; } }; class __declspec(uuid("C092B145-B318-41a7-B890-C77C5DA41CFD")) CMSEventHandler : public CComObject { public: typedef CComObject base; CMSEventHandler(DISPID handler, DISPID event, GUID gInf, IDispatch* IDispSite){ ID_handler = handler; ID_event = event; gEventInf = gInf; pDScript = IDispSite; cancelCookie = -1; } STDMETHOD(QueryInterface) (REFIID iid, void **pp) { try { if (iid == gEventInf) { CComQIPtr pdispRet(static_cast(this)); pdispRet.CopyTo(pp); pdispRet.Release(); return NOERROR; } return base::QueryInterface(iid, pp); } catch(...) { return E_NOINTERFACE; } } virtual ~CMSEventHandler() { if(cancelCookie!=-1){ Cancel(cancelCookie); } } }; typedef std::map > CancelMap; ///////////////////////////////////////////////////////////////////////////// // CMSEventBinder class ATL_NO_VTABLE __declspec(uuid("577FAA18-4518-445E-8F70-1473F8CF4BA4")) CMSEventBinder : public CComObjectRootEx, public CComCoClass, public IObjectWithSiteImplSec, public ISupportErrorInfo, public IObjectSafetyImpl, public IProvideClassInfo2Impl<&CLSID_MSEventBinder, &IID_IMSEventBinder, &LIBID_MSVidCtlLib>, public IDispatchImpl { public: CMSEventBinder(){} virtual ~CMSEventBinder(){ CleanupConnection(); } REGISTER_AUTOMATION_OBJECT(IDS_PROJNAME, IDS_REG_MSEVENTBINDER_PROGID, IDS_REG_MSEVENTBINDER_DESC, LIBID_MSVidCtlLib, __uuidof(CMSEventBinder)); DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CMSEventBinder) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IMSEventBinder) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY(IObjectSafety) COM_INTERFACE_ENTRY(IProvideClassInfo) COM_INTERFACE_ENTRY(IProvideClassInfo2) COM_INTERFACE_ENTRY(IObjectWithSite) END_COM_MAP() // IMSEventBinder public: // ISupportsErrorInfo STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid); STDMETHOD(Bind)(LPDISPATCH pEventObject, BSTR EventName, BSTR EventHandler, LONG *CancelCookie); STDMETHOD(Unbind)(DWORD CancelCookie); protected: HRESULT CleanupConnection(); private: CancelMap m_CancelMap; // map of cookies to CMSEventHandlers }; #endif //__MSEVENTBINDER_H_