385 lines
8.3 KiB
C++
385 lines
8.3 KiB
C++
#include "JSAPI_CallbackParameters.h"
|
|
#include "JSAPI.h"
|
|
|
|
JSAPI::CallbackParameters::CallbackParameters()
|
|
{
|
|
refCount = 1;
|
|
}
|
|
|
|
JSAPI::CallbackParameters::~CallbackParameters()
|
|
{
|
|
//for (size_t p=0;p!=params.size();p++)
|
|
//{
|
|
// ParameterList::value_type &property = params.at(p);
|
|
// // some types need to be specifically destroyed or released
|
|
// switch(property.second.vt)
|
|
// {
|
|
// case VT_DISPATCH: // add a reference if it's an IDispatch
|
|
// property.second.pdispVal->Release();
|
|
// break;
|
|
// case VT_BSTR: // re-allocate
|
|
// SysFreeString(property.second.bstrVal);
|
|
// break;
|
|
// }
|
|
//}
|
|
for (auto ¶m : params)
|
|
{
|
|
// some types need to be specifically destroyed or released
|
|
switch(param.second.vt)
|
|
{
|
|
case VT_DISPATCH: // add a reference if it's an IDispatch
|
|
param.second.pdispVal->Release();
|
|
break;
|
|
case VT_BSTR: // re-allocate
|
|
SysFreeString(param.second.bstrVal);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
|
|
{
|
|
bool unknowns = false;
|
|
for (unsigned int i = 0;i != cNames;i++)
|
|
{
|
|
rgdispid[i] = DISPID_UNKNOWN;
|
|
const wchar_t *propertyName = rgszNames[i];
|
|
|
|
bool found=false;
|
|
//for (size_t p=0;p!=params.size();p++)
|
|
size_t p = 0;
|
|
for(auto it = params.begin(); it != params.end(); it++, p++)
|
|
{
|
|
//ParameterList::value_type &property = params.at(p);
|
|
if (!wcscmp(it->first.c_str(), propertyName))
|
|
{
|
|
found=true;
|
|
rgdispid[i] = (DISPID)p;
|
|
break;
|
|
}
|
|
}
|
|
if (!found)
|
|
unknowns=true;
|
|
}
|
|
|
|
if (unknowns)
|
|
return DISP_E_UNKNOWNNAME;
|
|
else
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
|
|
{
|
|
JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0);
|
|
size_t index = (size_t)dispid;
|
|
if (index>=params.size())
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
if (wFlags & DISPATCH_PROPERTYGET)
|
|
{
|
|
if (pvarResult)
|
|
{
|
|
//ParameterList::value_type &property = params.at(index);
|
|
auto it = params.begin();
|
|
while (index--)
|
|
{
|
|
it++;
|
|
}
|
|
|
|
*pvarResult = it->second;
|
|
// do any type-specific allocations that are necessary
|
|
switch(pvarResult->vt)
|
|
{
|
|
case VT_DISPATCH: // add a reference if it's an IDispatch
|
|
pvarResult->pdispVal->AddRef();
|
|
break;
|
|
case VT_BSTR: // re-allocate
|
|
pvarResult->bstrVal = SysAllocString(pvarResult->bstrVal);
|
|
break;
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
else
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
}
|
|
|
|
|
|
HRESULT JSAPI::CallbackParameters::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::GetTypeInfoCount(unsigned int FAR * pctinfo)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP JSAPI::CallbackParameters::QueryInterface(REFIID riid, PVOID *ppvObject)
|
|
{
|
|
if (!ppvObject)
|
|
return E_POINTER;
|
|
|
|
else if (IsEqualIID(riid, IID_IDispatch))
|
|
*ppvObject = (IDispatch *)this;
|
|
else if (IsEqualIID(riid, IID_IUnknown))
|
|
*ppvObject = this;
|
|
else if (IsEqualIID(riid, IID_IDispatchEx))
|
|
*ppvObject = (IDispatchEx *)this;
|
|
else
|
|
{
|
|
*ppvObject = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG JSAPI::CallbackParameters::AddRef(void)
|
|
{
|
|
return InterlockedIncrement(&refCount);
|
|
}
|
|
|
|
|
|
ULONG JSAPI::CallbackParameters::Release(void)
|
|
{
|
|
LONG lRef = InterlockedDecrement(&refCount);
|
|
if (lRef == 0) delete this;
|
|
return lRef;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid)
|
|
{
|
|
//for (size_t p=0;p!=params.size();p++)
|
|
//{
|
|
// ParameterList::value_type &property = params.at(p);
|
|
// if (!wcscmp(property.first.c_str(), bstrName))
|
|
// {
|
|
// *pid= (DISPID)p;
|
|
// return S_OK;
|
|
// }
|
|
//}
|
|
size_t p = 0;
|
|
for (auto it = params.begin(); it != params.end(); it++, p++)
|
|
{
|
|
if (!wcscmp(it->first.c_str(), bstrName))
|
|
{
|
|
*pid = (DISPID)p;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
|
{
|
|
JSAPI_VERIFY_PARAMCOUNT(pdp, 0);
|
|
size_t index = (size_t)id;
|
|
if (index>=params.size())
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
if (wFlags & DISPATCH_PROPERTYGET)
|
|
{
|
|
if (pvarRes)
|
|
{
|
|
//ParameterList::value_type &property = params.at(index);
|
|
auto it = params.begin();
|
|
while (index--)
|
|
{
|
|
it++;
|
|
}
|
|
|
|
*pvarRes = it->second;
|
|
// do any type-specific allocations that are necessary
|
|
switch(pvarRes->vt)
|
|
{
|
|
case VT_DISPATCH: // add a reference if it's an IDispatch
|
|
pvarRes->pdispVal->AddRef();
|
|
break;
|
|
case VT_BSTR: // re-allocate
|
|
pvarRes->bstrVal = SysAllocString(pvarRes->bstrVal);
|
|
break;
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
else
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::DeleteMemberByName(BSTR bstrName, DWORD grfdex)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::DeleteMemberByDispID(DISPID id)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::GetMemberName(DISPID id, BSTR *pbstrName)
|
|
{
|
|
if (id >= 0 && (size_t)id < params.size())
|
|
{
|
|
auto it = params.begin();
|
|
while (id--)
|
|
{
|
|
it++;
|
|
}
|
|
*pbstrName = SysAllocString(it->first.c_str());
|
|
return S_OK;
|
|
}
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::GetNextDispID(DWORD grfdex, DISPID id, DISPID *pid)
|
|
{
|
|
if (grfdex == fdexEnumDefault)
|
|
{
|
|
if (id == DISPID_UNKNOWN)
|
|
{
|
|
if (params.size() == 0)
|
|
return S_FALSE;
|
|
else
|
|
{
|
|
*pid = 0;
|
|
return S_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
size_t index = id+1;
|
|
if (index >= params.size())
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
*pid = (DISPID)index;
|
|
return S_OK;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT JSAPI::CallbackParameters::GetNameSpaceParent(IUnknown **ppunk)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
void JSAPI::CallbackParameters::AddProperty(const wchar_t *name, const VARIANT &property)
|
|
{
|
|
params[name]=property;
|
|
}
|
|
|
|
void JSAPI::CallbackParameters::AddString(const wchar_t *name, const wchar_t *value)
|
|
{
|
|
VARIANT bstrVar;
|
|
V_VT(&bstrVar) = VT_BSTR;
|
|
V_BSTR(&bstrVar) = SysAllocString(value);
|
|
AddProperty(name, bstrVar);
|
|
}
|
|
|
|
void JSAPI::CallbackParameters::AddDispatch(const wchar_t *name, IDispatch *disp)
|
|
{
|
|
VARIANT dispVar;
|
|
V_VT(&dispVar) = VT_DISPATCH;
|
|
V_DISPATCH(&dispVar) = disp;
|
|
disp->AddRef();
|
|
AddProperty(name, dispVar);
|
|
}
|
|
|
|
void JSAPI::CallbackParameters::AddLong(const wchar_t *name, LONG value)
|
|
{
|
|
VARIANT i4Var;
|
|
V_VT(&i4Var) = VT_I4;
|
|
V_I4(&i4Var) = value;
|
|
AddProperty(name, i4Var);
|
|
}
|
|
|
|
void JSAPI::CallbackParameters::AddBoolean(const wchar_t *name, bool value)
|
|
{
|
|
VARIANT boolVar;
|
|
V_VT(&boolVar) = VT_BOOL;
|
|
V_BOOL(&boolVar) = value?VARIANT_TRUE:VARIANT_FALSE;
|
|
AddProperty(name, boolVar);
|
|
}
|
|
|
|
size_t JSAPI::CallbackParameters::AddPropertyIndirect(const JSAPI::CallbackParameters::PropertyTemplate *entries, size_t count)
|
|
{
|
|
if (NULL == entries) return 0;
|
|
|
|
size_t inserted = 0;
|
|
VARIANT val;
|
|
|
|
for (size_t i = 0; i < count; i++)
|
|
{
|
|
const PropertyTemplate *ppt = &entries[i];
|
|
if (NULL == ppt->name)
|
|
continue;
|
|
|
|
switch(ppt->type)
|
|
{
|
|
case typeBool:
|
|
V_VT(&val) = VT_BOOL;
|
|
V_BOOL(&val) = (FALSE != ((BOOL)ppt->value)) ? VARIANT_TRUE : VARIANT_FALSE;
|
|
break;
|
|
case typeString:
|
|
V_VT(&val) = VT_BSTR;
|
|
V_BSTR(&val) = SysAllocString((LPCWSTR)ppt->value);
|
|
break;
|
|
case typeLong:
|
|
V_VT(&val) = VT_I4;
|
|
V_I4(&val) = (ULONG)ppt->value;
|
|
break;
|
|
case typeDispatch:
|
|
V_VT(&val) = VT_DISPATCH;
|
|
V_DISPATCH(&val) = (IDispatch*)ppt->value;
|
|
if (NULL != val.pdispVal)
|
|
val.pdispVal->AddRef();
|
|
break;
|
|
default:
|
|
continue;
|
|
break;
|
|
}
|
|
AddProperty(ppt->name, val);
|
|
inserted++;
|
|
}
|
|
|
|
return inserted;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------------- */
|
|
HRESULT JSAPI::InvokeEvent(JSAPI::CallbackParameters *parameters, IDispatch *invokee)
|
|
{
|
|
unsigned int ret;
|
|
DISPPARAMS params;
|
|
VARIANTARG arguments[1];
|
|
|
|
VariantInit(&arguments[0]);
|
|
V_VT(&arguments[0]) = VT_DISPATCH;
|
|
V_DISPATCH(&arguments[0]) = parameters;
|
|
parameters->AddRef();
|
|
|
|
params.cArgs = 1;
|
|
params.cNamedArgs = 0;
|
|
params.rgdispidNamedArgs = NULL;
|
|
params.rgvarg = arguments;
|
|
|
|
HRESULT hr = invokee->Invoke(0, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, 0, 0, &ret);
|
|
|
|
VariantClear(&arguments[0]);
|
|
|
|
return hr;
|
|
}
|
|
|