I used to think that type safety in Delphi with regard to Interfaces is maintained by setting a unique (optional, but unique if filled in) GUID to it.
Then there came that question: Unspecified error when calling Word CentimetersToPoints via OLE
Little follow-up on it: http://pastebin.ca/2369858
And i started looking in stock Delphi TWordApplication
component (namely Word200.pas
unit). And there i see:
// *********************************************************************//
// Interface: _Application
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {00020970-0000-0000-C000-000000000046}
// *********************************************************************//
_Application = interface(IDispatch)
['{00020970-0000-0000-C000-000000000046}']
...
function CentimetersToPoints(Centimeters: Single): Single; safecall;
// *********************************************************************//
// DispIntf: _ApplicationDisp
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {00020970-0000-0000-C000-000000000046}
// *********************************************************************//
_ApplicationDisp = dispinterface
['{00020970-0000-0000-C000-000000000046}']
...
function CentimetersToPoints(Centimeters: Single): Single; dispid 371;
or similar:
// *********************************************************************//
// Interface: _Global
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {000209B9-0000-0000-C000-000000000046}
// *********************************************************************//
_Global = interface(IDispatch)
['{000209B9-0000-0000-C000-000000000046}']
...
function CentimetersToPoints(Centimeters: Single): Single; safecall;
// *********************************************************************//
// DispIntf: _GlobalDisp
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {000209B9-0000-0000-C000-000000000046}
// *********************************************************************//
_GlobalDisp = dispinterface
['{000209B9-0000-0000-C000-000000000046}']
...
function CentimetersToPoints(Centimeters: Single): Single; dispid 371;
And i feel totally lost here.
I used to think that dispinterface
is "subclass" of interface
like TPersistent
to TObject
is ? If yes, then how can be two interfaces with same GUID in same project ?
Or are they from different unrelated frameworks, like Delphi new class
types to inherited TurboPascal object
types ? Neither _GlobalDisp
nor _ApplicationDisp
seems to be used in Word200.pas
so are they just like appendix, auto-imported but never actually used ?
I made the project, using both _Application
and _ApplicationDisp
and it compiles. But then i only wonder how does Delphi typcast it, if they have the SAME GUID ?
procedure TForm4.Button1Click(Sender: TObject);
procedure show(const s: Single);
begin
ShowMessage(FloatToStr(s));
end;
begin
show( WordApplication1.CentimetersToPoints(1.0) );
show( WordApplication1.Application.CentimetersToPoints(2.0) );
show( WordApplication1.DefaultInterface.CentimetersToPoints(3.0) );
show( _ApplicationDisp(WordApplication1.Application).CentimetersToPoints(4.0) );
show( (WordApplication1.DefaultInterface as _ApplicationDisp).CentimetersToPoints(5.0) );
end;