BOOL test(IDispatchEx *pdexScript)
{
HRESULT hr;
VARIANT var;
DISPID dispid, putid;
BOOL retval = FALSE;
BSTR bstrName = NULL;
IDispatch *pdispObj = NULL, *pdispCat = NULL;
IDispatchEx *pdexObj = NULL;
DISPPARAMS dispparams, dispparamsNoArgs = {NULL, NULL, 0, 0};
// Get dispatch pointer for "cat"
bstrName = SysAllocString(OLESTR("cat"));
if (bstrName == NULL) goto LDone;
hr = pdexScript->GetDispID(bstrName, 0, &dispid);
if (FAILED(hr)) goto LDone;
SysFreeString(bstrName);
bstrName = NULL;
hr = pdexScript->InvokeEx(dispid, LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET, &dispparamsNoArgs,
&var, NULL, NULL);
if (FAILED(hr)) goto LDone;
pdispCat = var.pdispVal;
// Create object by calling "Object" constructor
bstrName = SysAllocString(OLESTR("Object"));
if (NULL == bstrName) goto LDone;
hr = pdexScript->GetDispID(bstrName, 0, &dispid);
if (FAILED(hr)) goto LDone;
SysFreeString(bstrName);
bstrName = NULL;
hr = pdexScript->InvokeEx(dispid, LOCALE_USER_DEFAULT,
DISPATCH_CONSTRUCT, &dispparamsNoArgs,
&var, NULL, NULL);
if (FAILED(hr)) goto LDone;
pdispObj = var.pdispVal;
hr = pdispObj->QueryInterface(IID_IDispatchEx, (void **)&pdexObj);
if (FAILED(hr)) goto LDone;
// Create new element in object
bstrName = SysAllocString(OLESTR("Elem"));
if (NULL == bstrName) goto LDone;
hr = pdexObj->GetDispID(bstrName, fdexNameEnsure, &dispid);
if (FAILED(hr)) goto LDone;
SysFreeString(bstrName);
bstrName = NULL;
// Assign "cat" dispatch pointer to element
putid = DISPID_PROPERTYPUT;
var.vt = VT_DISPATCH;
var.pdispVal = pdispCat;
dispparams.rgvarg = &var;
dispparams.rgdispidNamedArgs = &putid;
dispparams.cArgs = 1;
dispparams.cNamedArgs = 1;
hr = pdexObj->InvokeEx(dispid, LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYPUTREF, &dispparams,
NULL, NULL, NULL);
if (FAILED(hr)) goto LDone;
// Invoke method with "this" pointer
putid = DISPID_THIS;
var.vt = VT_DISPATCH;
var.pdispVal = pdispObj;
dispparams.rgvarg = &var;
dispparams.rgdispidNamedArgs = &putid;
dispparams.cArgs = 1;
dispparams.cNamedArgs = 1;
hr = pdexObj->InvokeEx(dispid, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, &dispparams,
NULL, NULL, NULL);
if (FAILED(hr)) goto LDone;
// Confirm that new element "Bar" is in object
hr = pdexObj->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid);
while (hr == NOERROR)
{
hr = pdexObj->GetMemberName(dispid, &bstrName);
if (FAILED(hr)) goto LDone;
retval = !wcscmp(bstrName, OLESTR("Bar"));
SysFreeString(bstrName);
bstrName = NULL;
if (retval) goto LDone;
hr = pdexObj->GetNextDispID(fdexEnumAll, dispid, &dispid);
}
LDone:
SysFreeString(bstrName);
if (pdispCat != NULL)
pdispCat->Release();
if (pdispObj != NULL)
pdispObj->Release();
if (pdexObj != NULL)
pdexObj->Release();
return retval;
}