The dispinterface
is really just a convenient way to use IDispatch
for an automation interface. That's why they have the same GUID – they are exactly the same thing behind the scenes.
When you use IDispatch
to invoke a method you typically have to call GetIdsOfNames
to obtain the dispatch ID for your method. But since these are static, you can save time by skipping that step, if you know the dispatch ID. And that's what a dispinterface
allows you to do.
When you call a method on a dispinterface
you still end up calling Invoke
on the IDispatch
, but you skip the call to GetIdsOfNames
.
When you use QueryInterface
with an interface, you'll get the IDispatch
. You can then cast it to its corresponding dispinterface
. It's still the same interface, but when you invoke methods on the dispinterface
you'll save that call to GetIdsOfNames
.
So, if you have an IDispatch
for the Word application object, say, you can write code like this:
var
WordApp: Variant;
WordDisp: _ApplicationDisp;
....
WordApp := CreateOleObject('Word.Application');
WordDisp := _ApplicationDisp(IDispatch(WordApp));
The _ApplicationDisp()
cast is nothing more than a call to IntfCopy
. Which in turn is nothing more than a call to _AddRef
. And you can then write:
Writeln(WordApp.ProductCode);
Writeln(WordDisp.ProductCode);
Both produce the same output. The former first calls GetIdsOfNames
before calling Invoke
. The latter goes straight to Invoke
.