在Delphi中使用dispInterface而没有classid

时间:2014-02-04 21:52:14

标签: delphi com

我已经将类型库导入Delphi XE2,它有许多调度接口。他们中的大多数都有自动创建的coclass和相应的delphi T接口自动创建。

但是,我需要处理的一些调度接口没有classid;我已经尝试过我在网上找到的每个例子来利用有问题的调度接口。这是界面的样子:

DIID_ITableListener: TGUID = '{83D42EA5-2C18-46EB-823B-262D62DF8CF1}';
... 
ITableListener = dispinterface;
...
// *********************************************************************//
// DispIntf:  ITableListener
// Flags:     (4096) Dispatchable
// GUID:      {83D42EA5-2C18-46EB-823B-262D62DF8CF1}
// *********************************************************************//
ITableListener = dispinterface
  ['{83D42EA5-2C18-46EB-823B-262D62DF8CF1}']
  procedure Added(const rowID: WideString; const rowDataObj: IRow); dispid 1610743809;
  procedure Changed(const rowID: WideString; const rowDataObj: IRow); dispid 1610743810;
  procedure Deleted(const rowID: WideString; const rowDataObj: IRow); dispid 1610743811;
  procedure StatusChanged(status: TableStatus); dispid 1610743812;
end;

以下是使用此调度接口的类型库包装器中的另一个接口的示例:

procedure subscribeUpdate(updateType: TableUpdateType; const listenerObj: ITableListener);

这是一个VB.NET示例,它解释了如何使用dispinterface:

' If you want to use methods of the ITableListener interface, you must create a 
' class that+ implements the interface. For example,

public class TableListener implements ITableListener { }

' In your application you must create an instance of the class that implements  
' the interface. For example,

TableListener tableListener = new TableListener();

没有ClassID我如何在Delphi中实现它?我该如何进行实例化?我认为它与实现IDispatch接口后代有关,但是再次没有ClassID,我找不到让它工作的方法。

帮助!

感谢。

2 个答案:

答案 0 :(得分:1)

所以我浏览了the link中提供的示例,并将您的接口替换为链接中的接口,并提出了这个:

ITableListener = dispinterface
  ['{83D42EA5-2C18-46EB-823B-262D62DF8CF1}']
  procedure Added(const rowID: WideString; const rowDataObj: IRow); dispid 1610743809;
  procedure Changed(const rowID: WideString; const rowDataObj: IRow); dispid 1610743810;
  procedure Deleted(const rowID: WideString; const rowDataObj: IRow); dispid 1610743811;
  procedure StatusChanged(status: TableStatus); dispid 1610743812;
end;

IMyTableListener = interface(IDispatch)
  ['{INSERT ARBITRARY GUID HERE}']
  procedure Added(const rowID: WideString; const rowDataObj: IRow); 
  procedure Changed(const rowID: WideString; const rowDataObj: IRow); 
  procedure Deleted(const rowID: WideString; const rowDataObj: IRow);
  procedure StatusChanged(status: TableStatus);
end;


TMyTableListener = class (TAutoObject, IMyTableListener)
public
  procedure Added(const rowID: WideString; const rowDataObj: IRow); 
  procedure Changed(const rowID: WideString; const rowDataObj: IRow); 
  procedure Deleted(const rowID: WideString; const rowDataObj: IRow);
  procedure StatusChanged(status: TableStatus);
end;

{ ... }
var
Disp: IDispatch;
Dispint: ITableListener;
{ ... }
// this may require that TMyTableListener is registered...
Disp := CreateComObject(TMyTableListener) as IDispatch;
// alternatively, try this (not sure about syntax):
Disp := new TMyTableListener as IDispatch;
Disp.AddRef();   // in C++, at least, creating the class via new() results in a 0 refcount, so you need to AddRef() so that releasing the object destroys the object appropriately...
Dispint := ITableListener(Disp);
subscribeUpdate(updateType, Dispint);
{ ... }

答案 1 :(得分:0)

此问题已解决。请参阅Troubleshooting COM error "The parameter is incorrect"

非常感谢@EricBrown和@RemyLebeau的帮助。