- if (!m_dispatchPtr)
- return FALSE;
-
- // nonConstMember is necessary because the wxString class doesn't have enough consts...
- wxString nonConstMember(member);
-
- int ch = nonConstMember.Find('.');
- if (ch != -1)
- {
- // Use dot notation to get the next object
- wxString member2(nonConstMember.Left((size_t) ch));
- wxString rest(nonConstMember.Right(nonConstMember.Length() - ch - 1));
- wxAutomationObject obj;
- if (!GetObject(obj, member2))
- return FALSE;
- return obj.Invoke(rest, action, retValue, noArgs, args, ptrArgs);
- }
-
- VARIANTARG vReturn;
- ClearVariant(& vReturn);
-
- VARIANTARG* vReturnPtr = & vReturn;
-
- // Find number of names args
- int namedArgCount = 0;
- int i;
- for (i = 0; i < noArgs; i++)
- if (!INVOKEARG(i).GetName().IsNull())
- {
- namedArgCount ++;
- }
-
- int namedArgStringCount = namedArgCount + 1;
- BSTR* argNames = new BSTR[namedArgStringCount];
- argNames[0] = ConvertStringToOle(member);
-
- // Note that arguments are specified in reverse order
- // (all totally logical; hey, we're dealing with OLE here.)
-
- int j = 0;
- for (i = 0; i < namedArgCount; i++)
- {
- if (!INVOKEARG(i).GetName().IsNull())
- {
- argNames[(namedArgCount-j)] = ConvertStringToOle(INVOKEARG(i).GetName());
- j ++;
- }
- }
-
- // + 1 for the member name, + 1 again in case we're a 'put'
- DISPID* dispIds = new DISPID[namedArgCount + 2];
-
- HRESULT hr;
- DISPPARAMS dispparams;
- unsigned int uiArgErr;
- EXCEPINFO excep;
-
- // Get the IDs for the member and its arguments. GetIDsOfNames expects the
- // member name as the first name, followed by argument names (if any).
- hr = ((IDispatch*)m_dispatchPtr)->GetIDsOfNames(IID_NULL, argNames,
- 1 + namedArgCount, LOCALE_SYSTEM_DEFAULT, dispIds);
- if (FAILED(hr))
- {
-// ShowException(szMember, hr, NULL, 0);
- return FALSE;
- }
-
- // if doing a property put(ref), we need to adjust the first argument to have a
- // named arg of DISPID_PROPERTYPUT.
- if (action & (DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
- {
- namedArgCount = 1;
- dispIds[1] = DISPID_PROPERTYPUT;
- vReturnPtr = (VARIANTARG*) NULL;
- }
-
- // Convert the wxVariants to VARIANTARGs
- VARIANTARG* oleArgs = new VARIANTARG[noArgs];
- for (i = 0; i < noArgs; i++)
- {
- // Again, reverse args
- wxVariant& theVariant = INVOKEARG((noArgs-1) - i);
- if (!ConvertVariantToOle(theVariant, oleArgs[i]))
- return FALSE; // TODO: clean up memory at this point
- }
-
- dispparams.rgdispidNamedArgs = dispIds + 1;
- dispparams.rgvarg = oleArgs;
- dispparams.cArgs = noArgs;
- dispparams.cNamedArgs = namedArgCount;
-
- excep.pfnDeferredFillIn = NULL;
-
- hr = ((IDispatch*)m_dispatchPtr)->Invoke(dispIds[0], IID_NULL, LOCALE_SYSTEM_DEFAULT,
- action, &dispparams, vReturnPtr, &excep, &uiArgErr);
-
- for (i = 0; i < namedArgStringCount; i++)
- {
- SysFreeString(argNames[i]);
- }
- delete[] argNames;
- delete[] dispIds;
-
- for (i = 0; i < noArgs; i++)
- ReleaseVariant(& oleArgs[i]) ;
- delete[] oleArgs;
-
- if (FAILED(hr))
- {
- // display the exception information if appropriate:
-// ShowException((const char*) member, hr, &excep, uiArgErr);
-
- // free exception structure information
- SysFreeString(excep.bstrSource);
- SysFreeString(excep.bstrDescription);
- SysFreeString(excep.bstrHelpFile);
-
- if (vReturnPtr)
- ReleaseVariant(vReturnPtr);
- return FALSE;
- }
- else
- {
- if (vReturnPtr)
- {
- // Convert result to wxVariant form
- ConvertOleToVariant(vReturn, retValue);
- // Mustn't release the dispatch pointer
- if (vReturn.vt == VT_DISPATCH)
- {
- vReturn.pdispVal = (IDispatch*) NULL;
- }
- ReleaseVariant(& vReturn);
- }
- }
- return TRUE;
-}