185 lines
5.7 KiB
C
185 lines
5.7 KiB
C
|
// CMSEventBinder.h : Declaration of the CMSEventBinder
|
||
|
|
||
|
#ifndef __MSEVENTBINDER_H_
|
||
|
#define __MSEVENTBINDER_H_
|
||
|
|
||
|
#include <map>
|
||
|
#include <Mshtml.h>
|
||
|
#include <activscp.h>
|
||
|
#include <Atlctl.h>
|
||
|
#include <Exdisp.h>
|
||
|
#include <objectwithsiteimplsec.h>
|
||
|
#include "segimpl.h"
|
||
|
#include "seg.h"
|
||
|
#include "resource.h" // main symbols
|
||
|
#include "mslcid.h"
|
||
|
|
||
|
typedef CComQIPtr<IActiveScriptSite> PQIASSite;
|
||
|
typedef CComQIPtr<IActiveScript> PQIAScript;
|
||
|
/////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
class __declspec(uuid("FCBF24F7-FB97-4fa3-B57E-97BCB5AF1D26")) ATL_NO_VTABLE CMSEventHandlerBase:
|
||
|
public CComObjectRootEx<CComSingleThreadModel>,
|
||
|
public IObjectWithSiteImplSec<CMSEventHandlerBase>,
|
||
|
public IDispatchImpl<IDispatch, &IID_IDispatch>
|
||
|
{
|
||
|
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<IConnectionPoint> cancelPoint;
|
||
|
|
||
|
// IDispatch where the handler function is from
|
||
|
CComQIPtr<IDispatch> 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<CMSEventHandlerBase>
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
typedef CComObject<CMSEventHandlerBase> 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<IDispatch> pdispRet(static_cast<IDispatch *>(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<DWORD, CComQIPtr<IDispatch> > CancelMap;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CMSEventBinder
|
||
|
class ATL_NO_VTABLE __declspec(uuid("577FAA18-4518-445E-8F70-1473F8CF4BA4")) CMSEventBinder :
|
||
|
public CComObjectRootEx<CComSingleThreadModel>,
|
||
|
public CComCoClass<CMSEventBinder, &__uuidof(CMSEventBinder)>,
|
||
|
public IObjectWithSiteImplSec<CMSEventBinder>,
|
||
|
public ISupportErrorInfo,
|
||
|
public IObjectSafetyImpl<CMSEventBinder, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA>,
|
||
|
public IProvideClassInfo2Impl<&CLSID_MSEventBinder, &IID_IMSEventBinder, &LIBID_MSVidCtlLib>,
|
||
|
public IDispatchImpl<IMSEventBinder, &IID_IMSEventBinder, &LIBID_MSVidCtlLib>
|
||
|
{
|
||
|
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_
|