Microsoft Windows CE 3.0  

IDispatch::Invoke

Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

This method provides access to properties and methods exposed by an object.

HRESULT Invoke(
DISPID
dispIdMember
,
REFIID
riid
,
LCID
lcid
,
WORD
wFlags
,
DISPPARAMS FAR *
pDispParams
,
VARIANT FAR *
pVarResult
,
EXCEPINFO FAR *
pExcepInfo
,
unsigned int FAR *
puArgErr
);

Parameters

dispIdMember
Identifies the member. Use GetIDsOfNamesor the object's documentation to obtain the dispatch identifier.
riid
Reserved for future use; set to IID_NULL.
lcid
The locale context in which to interpret parameters. The lcidis used by the GetIDsOfNamesfunction, and is also passed to Invoketo allow the object to interpret its parameters specific to a locale.

Applications that do not support multiple national languages can ignore this parameter.

wFlags
Flags describing the context of the Invokecall. It is one of the following values:
Value Description
DISPATCH_METHOD The member is invoked as a method. If a property has the same name, both this and the DISPATCH_PROPERTYGET flag may be set.
DISPATCH_PROPERTYGET The member is retrieved as a property or data member.
DISPATCH_PROPERTYPUT The member is changed as a property or data member.
DISPATCH_PROPERTYPUTREF The member is changed by a reference assignment, rather than a value assignment. This flag is valid only when the property accepts a reference to an object.
pDispParams
Pointer to a structure that contains an array of parameters, an array of parameter DISPIDs for named parameters, and counts for the number of elements in the arrays. See the Remarks section that follows for a description of the DISPPARAMSstructure.
pVarResult
Pointer to the location where the result is to be stored, or NULL if the caller expects no result. This parameter is ignored if DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF is specified.
pExcepInfo
Pointer to a structure that contains exception information. This structure should be filled in if DISP_E_EXCEPTION is returned. Can be NULL.
puArgErr
The index within rgvargof the first parameter that has an error. Arguments are stored in pDispParams->rgvargin reverse order, so the first parameter is the one with the highest index in the array. This parameter is returned only when the resulting return value is DISP_E_TYPEMISMATCH or DISP_E_PARAMNOTFOUND. For details, see "Returning Errors" in the following Remarks section.

Return Values

One of the values described in the following table is returned.

Value Description
S_OK Success.
DISP_E_BADPARAMCOUNT The number of elements provided to DISPPARAMS is different from the number of parameters accepted by the method or property.
DISP_E_BADVARTYPE One of the parameters in rgvargis not a valid variant type.
DISP_E_EXCEPTION The application needs to raise an exception. In this case, the structure passed in pExcepInfoshould be filled in.
DISP_E_MEMBERNOTFOUND The requested member does not exist, or the call to Invoketried to set the value of a read-only property.
DISP_E_NONAMEDARGS This implementation of IDispatchdoes not support named parameters.
DISP_E_OVERFLOW One of the parameters in rgvargcould not be coerced to the specified type.
DISP_E_PARAMNOTFOUND One of the parameter DISPIDs does not correspond to a parameter on the method. In this case, puArgErrshould be set to the first parameter that contains the error.
DISP_E_TYPEMISMATCH One or more of the parameters could not be coerced. The index within rgvargof the first parameter with the incorrect type is returned in the puArgErrparameter.
DISP_E_UNKNOWNINTERFACE The interface identifier passed in riidis not IID_NULL.
DISP_E_UNKNOWNLCID The member being invoked interprets string parameters according to the LCID, and the LCID is not recognized. If the LCID is not needed to interpret parameters, this error should not be returned.
DISP_E_PARAMNOTOPTIONAL A required parameter was omitted.

In 16-bit versions, you can define your own errors using the MAKE_SCODE value macro.

Remarks

Generally, you should not implement Invokedirectly. Instead, use the dispatch interface create functions CreateStdDispatchand DispInvoke.

If some application-specific processing needs to be performed before calling a member, the code should perform the necessary actions, and then call ITypeInfo::Invoketo invoke the member. ITypeInfo::Invokeacts exactly like IDispatch::Invoke. The standard implementations of IDispatch::Invokecreated by CreateStdDispatchand DispInvokedefer to ITypeInfo::Invoke.

In an ActiveX client, IDispatch::Invokeshould be used to get and set the values of properties, or to call a method of an ActiveX object. The dispIdMemberparameter identifies the member to invoke. The DISPIDs that identify members are defined by the implementor of the object and can be determined by using the object 's documentation, the IDispatch::GetIDsOfNamesfunction, or the ITypeInfointerface.

The information that follows addresses developers of ActiveX clients and others who use code to expose ActiveX objects. It describes the behavior that users of exposed objects should expect.

Requirements

Runs on Versions Defined in Include Link to
Windows CE OS 2.0 and later Oaidl.h    
Note   This API is part of the complete Windows CE OS package as provided by Microsoft. The functionality of a particular platform is determined by the original equipment manufacturer (OEM) and some devices may not support this API.

Calling a Method With No Arguments

The simplest use of Invokeis to call a method that does not have any parameters. You only need to pass the DISPID of the method, a LCID, the DISPATCH_METHOD flag, and an empty DISPPARAMSstructure.

Most methods, however, take one or more parameters. To invoke these methods, the DISPPARAMSstructure should be filled in, as described in "Passing Parameters" later in this chapter.

Automation defines special DISPIDs for invoking an object's Valueproperty (the default), and the members _ NewEnum, and Evaluate.

Getting and Setting Properties

Properties are accessed in the same way as methods, except you specify DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT instead of DISPATCH_METHOD. Some languages cannot distinguish between retrieving a property and calling a method. In this case, you should set the flags DISPATCH_PROPERTYGET and DISPATCH_METHOD.

Use the DISPATCH_PROPERTYPUTREF flag to indicate a property or data member that should be set by reference.

Passing Parameters

Arguments to the method or property being invoked are passed in the DISPPARAMS structure. This structure consists of a pointer to an array of parameters represented as variants, a pointer to an array of DISPIDs for named parameters, and the number of parameters in each array.

The parameters are passed in the array rgvarg[ ], with the number of parameters passed in cArgs. The parameters in the array should be placed from last to first, so rgvarg[0] has the last parameter and rgvarg[ cArgs-1] has the first parameter. The method or property may change the values of elements within the array rgvarg, but only if it has set the VT_BYREF flag. Otherwise, consider the elements as read-only.

A dispatch invocation can have named parameters as well as positional parameters. If cNamedArgsis 0, all the elements of rgvarg[ ] represent positional parameters. If cNamedArgsis not 0, each element of rgdispidNamedArgs[ ] contains the DISPID of a named parameter, and the value of the parameter is in the matching element of rgvarg[ ]. The DISPIDs of the named parameters are always contiguous in rgdispidNamedArgs, and their values are in the first cNamedArgselements of rgvarg. Named parameters cannot be accessed positionally, and positional parameters cannot be named.

The DISPID of an parameter is its zero-based position in the parameter list.

If you include the DISPID with each named parameter, you can pass the named parameters to Invokein any order.

For example, if a method is to be invoked with two positional parameters, followed by three named parameters ( A, B,and C), using the following hypothetical syntax, then cArgswould be 5, and cNamedArgswould be 3.

object.method("arg1", "arg2", A := "argA", B :="argB", C := "argC")

The first positional parameter would be in rgvarg[4]. The second positional parameter would be in rgvarg[3]. The ordering of named parameters is not important to the IDispatchimplementation, but these parameters are generally passed in reverse order. The parameter Awould be in rgvarg[2], with the DISPID of Ain rgdispidNamedArgs[2]. The parameter Bwould be in rgvarg[1], with the corresponding DISPID in rgdispidNamedArgs[1]. The parameter Cwould be in rgvarg[0], with the DISPID corresponding to Cin rgdispidNamedArgs[0].

You can also use Invokeon members with optional parameters, but all optional parameters must be of type VARIANT. As with required parameters, the contents of the parameter vector depend on whether the parameters are positional or named. The invoked member must ensure that the parameters are valid. Invokemerely passes the DISPPARAMS structure it receives.

Omitting named parameters is straightforward. You would pass the parameters in rgvargand their DISPIDs in rgdispidNamedArgs. To omit the parameter named B(in the preceding example) you would set rgvarg[0] to the value of C, with its DISPID in rgdispidNamedArgs[0]; and rgvarg[1] to the value of A,with its DISPID in rgdispidNamedArgs[1]. The subsequent positional parameters would occupy elements 2 and 3 of the arrays. In this case, cArgsis 4 and cNamedArgsis 2.

If the parameters are positional (unnamed), you would set cArgsto the total number of possible parameters, cNamedArgsto 0, and pass VT_ERROR as the type of the omitted parameters, with the status code DISP_E_PARAMNOTFOUND as the value.

The calling code is responsible for releasing all strings and objects referred to by rgvarg[ ] or placed in *pVarResult. As with other parameters that are passed by value, if the invoked member must maintain access to a string after returning, you should copy the string. Similarly, if the member needs access to a passed-object pointer after returning, it must call the AddReffunction on the object. A common example occurs when an object property is changed to refer to a new object, using the DISPATCH_PROPERTYPUTREF flag.

For those implementing IDispatch::Invoke, Automation provides the DispGetParamfunction to retrieve parameters from the parameter vector and coerce them to the proper type. For details, see "DispGetParam" later in this chapter.

Indexed Properties

When you invoke indexed properties of any dimension, you must pass the indexes as additional parameters. To set an indexed property, place the new value in the first element of the rgvarg[ ] vector, and the indexes in the subsequent elements. To get an indexed property, pass the indexes in the first nelements of rgvarg, and the number of indexes in cArg. Invokereturns the value of the property in pVarResult.

Automation stores array data in column-major order, which is the same ordering scheme used by Visual Basic and FORTRAN, but different from C, C++, and Pascal. If you are programming in C, C++, or Pascal, you must pass the indexes in the reverse order. The following code example shows how to fill the DISPPARAMS structure in C++.

dispparams.rgvarg[0].vt = VT_I2;
dispparams.rgvarg[0].iVal = 99; dispparams.rgvarg[1].vt = VT_I2;
dispparams.rgvarg[1].iVal = 2; dispparams.rgvarg[2].vt = VT_I2;
dispparams.rgvarg[2].iVal = 1; dispparams.rgdispidNamedArgs =
DISPID_PROPERTYPUT; dispparams.cArgs = 3; dispparams.cNamedArgs =
1;

The example changes the value of Prop[1,2] to 99. The new property value is passed in rgvarg[0]. The right-most index is passed in rgvarg[1], and the next index in rgvarg[2]. The cArgsmember specifies the number of elements of rgvarg[ ] that contain data, and cNamedArgsis 1, that indicates the new value for the property.

Property collections are an extension of this feature.

Raising Exceptions During Invoke

When you implement IDispatch::Invoke, errors can be communicated either through the normal return value or by raising an exception. An exception is a special situation that is normally handled by jumping to the nearest routine enclosing the exception handler.

To raise an exception, IDispatch::Invokereturns DISP_E_EXCEPTION and fills the structure passed through pExcepInfowith information about the cause of the exception or error. You can use the information to understand the cause of the exception and proceed as necessary.

The exception information structure includes an error code number that identifies the kind of exception (a string that describes the error in a human-readable way). It also includes a Help file and a Help context number that can be passed to Windows Help for details about the error. At a minimum, the error code number must be filled with a valid number.

If you consider IDispatchanother way to call C++ methods in an interface, EXCEPINFO models the raising of an exception or longjmp()call by such a method.

Returning Errors

Invokereturns DISP_E_MEMBERNOTFOUND if one of the following conditions occurs:

  • A member or parameter with the specified DISPID and matching cArgscannot be found ,and the parameter is not optional.
  • The member is a void function, and the caller did not set pVarResultto NULL.
  • The member is a read-only property, and the caller set wFlagsto DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF.

    If Invokefinds the member, but uncovers errors in the parameter list, it returns one of several other errors. DISP_E_BAD_PARAMCOUNT means that the DISPPARAMS structure contains an incorrect number of parameters for the property or method. DISP_E_NONAMEDARGS means that Invokereceived named parameters, but they are not supported by the member.

    DISP_E_PARAMNOTFOUND means that the correct number of parameters was passed, but the DISPID for one or more parameters was incorrect. If Invokecannot convert one of the parameters to the desired type, it returns DISP_E_TYPEMISMATCH. In these two cases, if it can identify which parameter is incorrect, Invokesets * puArgErrto the index within rgvargof the parameter with the error. For example, if an Automation method expects a reference to a double-precision number as an parameter, but receives a reference to an integer, the parameter is coerced. However, if the method receives a date, IDispatch::Invokereturns DISP_E_TYPEMISMATCH and sets *puArgErrto the index of the integer in the parameter array.

    Automation provides functions to perform standard conversions of VARIANT, and these functions should be used for consistent operation. DISP_E_TYPEMISMATCH is returned only when these functions fail.