Author: Deborah Pate
What is a DispInterface?
Answer:
Short answer: it is a specification for an IDispatch interface. Long answer: The
IDispatch interface is the basis of all automation. It has two methods that allow
pointerless scripting languages to call methods by name, instead of using method
pointers: GetIDsOfNames, and Invoke. GetIdsOfNames retrieves the numerical ID of a
method with a given name (provided that the object implements another interface
that has method with that name). Invoke uses the numerical ID of a method to call
that method. The numerical ID of a method is called the DispID. For example,
suppose you create an interface that looks like this:
1 IMyIntf = interface(IDispatch)
2 ['{4D733280-C514-11D4-8481-A68F52CBDB56}']
3 procedure DoThis;
4 end;
5
6 //and an object that implements it that looks like this:
7
8 TMyDispatchObj = class(TAutoObject, IMyIntf)
9 public
10 procedure DoThis;
11 end;
Delphi will call both GetIDSOfNames and Invoke for you - all you need to do is use
a variant. Like this:
12 { ... }
13 var
14 AVar: OleVariant;
15 { ... }
16
17 { ... }
18 AVar := CreateComObject(CLASS_TMyAutoObj) as IDispatch;
19 AVar.DoThis;
20 { ... }
Every time you call a method of an variant referencing an IDispatch interface,
GetIDsOfNames and Invoke are called for you behind the scenes. However, calling
GetIdsOfNames for every method is quite slow. And since all it does is find a
numerical ID for a given method name, it might be nice if you could look up that ID
in advance and pass it to Invoke directly, rather than go through GetIdsOfNames
every time. Enter the DispInterface:
21 IMyDispInterface = dispinterface
22 ['{4D733284-C514-11D4-8481-A68F52CBDB56}']
23 procedure DoThis; dispid 1;
24 end;
This declaration tells Delphi the DispID of each method in an interface. So if you
use a DispInterface variable, rather than a variant, Delphi can call Invoke
directly using that, rather than go through GetIdsOfNames:
25 { ... }
26 var
27 Disp: IDispatch;
28 Dispint: IMyDispInterface;
29 { ... }
30 Disp := CreateComObject(CLASS_TMyAutoObj) as IDispatch;
31 Dispint := IMyDispInterface(Disp);
32 Dispint.DoThis;
33 { ... }
A DispInterface is not a true interface. When you use a DispInterface, you are actually using the IDispatch interface of an object, just as you are when you use a variant. That's why you can cast an IDispatch interface directly to a dispinterface, as in the second line above. All you're doing here is telling the compiler that you already know what other methods a particular object will implement, and what DispID's can be used to invoke them with.
|