I came across the implementation of the IDispatch interface. There are four methods, and, fortunately, 3 of them are easy:
function TIEEventsSink.GetTypeInfoCount(...): HResult; { Result := E_NOTIMPL; } function TIEEventsSink.GetTypeInfo(...): HResult; { Result := E_NOTIMPL; } function TIEEventsSink.GetIDsOfNames(...): HResult; { Result := E_NOTIMPL; }
This is the last method, Invoke , which is complicated. Here I am faced with the need to actually use DispID and call the appropriate method; unmarhsalling parameters from an array variant.
function Invoke( dispIdMember: DISPID; riid: REFIID; lcid: LCID; wFlags: WORD; var pDispParams: DISPPARAMS; var pVarResult: VARIANT; var pExcepInfo: EXCEPINFO; var puArgErr: DWORD ): HRESULT;
Not wanting to write all the tedious code of the template, I will probably get errors, I went googling - instead of doing any work.
I found this snippet on the MSDN IDispatch.Invoke documentation :
Generally, you should not implement Invoke directly.
Excellent! I still did not want to implement it! Continuing reading:
Instead, use the submit interface to create the CreateStdDispatch and DispInvoke functions . For more information, see CreateStdDispatch , DispInvoke , Creating an IDispatch Interface and Exposing ActiveX Objects .
Creating an IDispatch interface says:
You can implement IDispatch in any of the following ways:
- [incision]
- Call the CreateStdDispatch function. This approach is the simplest, but it does not provide rich error handling or several national languages.
- [incision]
Great, CreateStdDispatch :
Creates a standard implementation of the IDispatch interface through a single function call. This makes it easy to expose objects through Automation.
HRESULT CreateStdDispatch( IUnknown FAR* punkOuter, void FAR* pvThis, ITypeInfo FAR* ptinfo, IUnknown FAR* FAR* ppunkStdDisp );
I was going to call him like:
CreateStdDispatch( myUnk,
What I cannot understand is how the Windows API implementation of CreateStdDispatch knows which methods to call on my object, especially since CreateStdDispatch does not know which object-oriented language I use, or its calling conventions.
How CreateStdDispatch knows
- what method to call for this
dispid ? - calling convention of my language?
- How to handle exceptions from the language in which an object-oriented object is written?
Note : I have no choice but to implement dispinterface ; I did not define the interface . I wish this was a simple early border of IUnknown , but it is not.