Member Name
|
Description
|
GetDispID
|
Used to map a member name to its DISPID. This method can also be used to add members to the object. This method can be case-sensitive.
|
InvokeEx
|
Invokes a member of the object. The flag DISPATCH_CONSTRUCT indicates that the member is being used as a constructor. A this pointer may be passed to the member via the named parameter DISPID_THIS.
|
DeleteMemberByName
|
Removes a member from the object by name.
|
DeleteMemberByDispID
|
Removes a member from the object by DISPID.
|
GetMemberProperties
|
Describes the member's capabilities, whether it can fire events, is a property or method, and so on.
|
GetMemberName
|
Returns the name of the member mapped to a specified DISPID.
|
GetNextDispID
|
Used to enumerate the DISPIDs of the object's members. The caller can request all members or the default set (determined by the object).
|
GetNameSpaceParent
|
Allows the caller to get the IUnknown of the object's parent namespace.
|
Figure 3 IDispatchEx Features
Dynamic Composition
|
Adding (GetDispID) members to the object using the fdexNameEnsure option.
|
Deleting members by their name (DeleteMemberByName) or DISPID (DeleteMemberByDispID).
|
Member Introspection
|
Enumerating a member's DISPIDs (GetNextDispID).
|
Determining a member's properties (GetMemberProperties).
|
Looking up a member's name via the DISPID (GetMemberName).
|
Case-sensitivity when determining the DISPID of a member (GetDispID).
|
Member Invocation (InvokeEx)
|
Passing a this pointer to an invoked member via the named parameter DISPID_THIS.
|
Object construction via the DISPATCH_CONSTRUCT flag.
|
Namespaces
|
Querying the namespace of an object (GetNameSpaceParent), which is used in dynamic object models.
|
Figure 5 IDispatchExImpl Method Descriptions
Method
|
Description
|
GetEntryByName
|
Finds the CDynamicDispatchEntry for a given name. The search can be either case-sensitive or case-insensitive. Defaults to case-insensitive.
|
CreateNewEntry
|
Creates and populates a CDynamicDispatchEntry with the member attributes specified. Adds the new entry to the map classes. Determines what the next DISPID should be for a new dynamic member. |
GetStartDispID
|
Finds the first nondeleted entry in the dynamic member map and retrieves its DISPID.
|
GetNextDispID
|
Gets the DISPID of the next valid (nondeleted) entry in the map.
|
GetVariantByDispID
|
Copies the contents of a dispatch entry with the supplied DISPID into an outbound VARIANT. This can be either a property or a function pointer (LPDISPATCH). If this is a static member (a member that is part of an interface that derives from IDispatchEx, one that is not added dynamically), then the call returns S_FALSE, telling the InvokeEx method to use the ITypeInfo interface to process the request.
|
SetVariantByDispID
|
Copies the contents of the supplied VARIANT into the dispatch entry specified by the DISPID. This also returns S_FALSE for an ITypeInfo item and processes as above.
|
AddTypeInfoDispIDs
|
Using the ITypeInfo interface pointer, enumerates the static members (ones that are not added dynamically) of the derived interface, creates a new dynamic dispatch entry, and adds it to the map classes. This method is not present if the macro IDISPATCHEX_NO_TYPEINFO is defined.
|
InvokeByDispID
|
This method is responsible for forwarding calls onto dynamic methods. This is done by calling Invoke on the LPDISPATCH housed in the dynamic entry's VARIANT with a DISPID of zero. |
Get
|
This method is not supplied in either IDispatch or IDispatchEx. It is there to allow access to dynamic members via their name, as in objVar = objVar2.Get-("IndexCollection"). This method is not supplied if the IDISPATCHEX_NO_TYPEINFO macro is defined. |
put_Set
|
See the description for Get. The funny naming convention is used because left-hand items (on the left side of the = operator) are considered "put" properties. This method allows the setting of an item by name, as in objVar.Set("Name") = "John Doe".
|
IDispatchExImpl
|
This is the default constructor, which initializes the ITypeInfo pointer to NULL and sets the starting point for dynamic DISPIDs. The ITypeInfo pointer is not a member of the class if the IDISPATCHEX_NO_TYPEINFO macro is defined.
|
~IDispatchExImpl
|
Walks the dynamic dispatch map, freeing the allocated CDynamicDispatchEntries. It releases the ITypeInfo pointer
if declared and not NULL. |
GetTypeInfoCount
|
This IDispatch method returns the number of ITypeInfo interfaces supported by this object. This is 1 or zero depending on whether the class has ITypeInfo support turned on. |
GetTypeInfo
|
Fetches the ITypeInfo pointer of the derived class or NULL depending on whether type information is enabled.
|
GetIDsOfNames
|
Determines the DISPIDs for a list of member names by calling the IDispatchEx::GetDispID method for each name in the array. |
Invoke
|
This call is forwarded to the IDispatchEx::InvokeEx method.
|
DeleteMemberByDispID
|
Marks a dynamic entry in the map as deleted. Any property held within the VARIANT of the entry is cleared (released for interface pointers). Calls to that DISPID will return DISP_E_MEMBERNOTFOUND until the member becomes valid again by the consumer adding it again.
|
DeleteMemberByName
|
Similar to DeleteMemberByDispID, but searches for the member by name instead of DISPID. This may or may not be case-sensitive.
|
GetDispID
|
Returns the DISPID of the specified member. If there is not a member with the given name and the consumer has indicated fdexNameEnsure, a new dynamic dispatch is created. If there is a deleted member that matches the name and the caller passed in fdexNameEnsure, the DISPID of the entry is returned. Otherwise, DISP_E_UNKNOWNNAME is returned and the outgoing DISPID is set to DISPID_UNKNOWN. |
GetMemberName
|
Returns the name of the member that maps to the passed in DISPID.
|
GetMemberProperties
|
This method returns grfdexPropCanAll for any member DISPID.
|
GetNameSpaceParent
|
This method is not used by this class and returns E_NOTIMPL.
|
GetNextDispID
|
If the start DISPID specified by the caller is DISPID_STARTENUM, this function returns the first active DISPID in the map. Otherwise, it returns the next active DISPID in the map.
|
InvokeEx
|
Provides the processing of member calls. If the caller has specified DISPATCH_PROPERTYGET, InvokeEx calls the GetVariantBy- DispID helper method to copy the contents of the VARIANT held by the entry. If the caller specifies DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF, the method calls SetVariantBy- DispID to copy the contents of the first VARIANT in the DISPPARAMS structure into the dynamic entry's VARIANT. If the caller specifies DISPATCH_METHOD, the call is forwarded to InvokeByDispID. If any of the three helper functions return S_FALSE, the InvokeEx call is forwarded to the ITypeInfo interface for processing.
|
Figure 6 CDynamicOnly
class CDynamicOnly :
public IDispatchExImpl<CDynamicOnly,IDynamicOnly,
&IID_IDynamicOnly,&LIBID_TESTDISPATCHEXLib>,
public ISupportErrorInfo,
public CComObjectRoot,
public CComCoClass<CDynamicOnly,&CLSID_DynamicOnly>
{
public:
CDynamicOnly() {}
BEGIN_COM_MAP(CDynamicOnly)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IDispatchEx)
COM_INTERFACE_ENTRY(IDynamicOnly)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
DECLARE_NOT_AGGREGATABLE(CDynamicOnly)
DECLARE_CLASSFACTORY_DISPATCHEX(CDynamicOnly)
DECLARE_REGISTRY_RESOURCEID(IDR_DynamicOnly)
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
// IDynamicOnly
public:
};
Figure 7 DynamicOnly & TestDispatchEx
var objTest = new ActiveXObject("TestDispatchEx.TestDispatchEx");
var objDynamicOnly = new ActiveXObject("TestDispatchEx.DynamicOnly");
// Test the processing of properties by name
objTest.Set("Number") = 5;
alert(objTest.Get("number"));
// Add a new property to it
objTest.Foo = "Foo";
alert(objTest.Foo);
// Set and call the function pointer
// Change this value to one of the three methods below to see the
// effect
objTest.FuncPtr = TestFunc2;
objTest.FuncPtr("This is a cool function pointer of ");
alert(objTest.AnotherProp);
// Check to see if the prop is set
alert(objDynamicOnly.DynamicProp);
// Call the ITestDispatchEx members
alert(objTest.Number);
objTest.Square();
alert(objTest.Number);
objTest.Number = 4;
objTest.Square();
alert(objTest.Number);
function TestFunc2(strTest)
{
objTest.AnotherProp = strTest + "TestFunc2";
objDynamicOnly.DynamicProp = "A purely dynamic property";
}