在 Delphi 2010 RIDL 编辑器中定义类型 function/procedure 指针的 属性
Defining property of type function/procedure pointer in Delphi 2010 RIDL editor
我想知道是否可以在 Delphi 2010 RIDL 编辑器中为接口定义定义 属性 类型 function/procedure 指针,这样当我创建一个实例时它的实现者使用它的 CoCreator,然后我可以在我的源代码中分配一个使用该接口定义的 function/procedure 到那个 属性。其实我想知道如何在下面填写“???”。
TLB 文件:
IComIntf = interface(IDispatch)
...
function Get_OnDoSomething : ??? safecall;
procedure Set_OnDoSomething(const New_Event : ???); safecall;
...
property OnDoSomething : ???;
...
implementation
uses ComObj;
class function CoComIntf.Create: IComInt;
...
begin
Result := CreateComObject(CLASS_ComIntf) as IComIntf;
end;
实现文件,ComIntfUnit.pas:
type
TOnDoSomething = function (Info: OleVariant): HResult of object;
TComIntf = class(TAutoObject, IComIntf)
private
fOnDoSomething : TDoSomething;
...
public
property OnDoSomething: TOnDoSomething read fOnDoSomething write fOnDoSomething;
...
客户表格:
uses ComIntfUnit;
type
TForm1 = class(TForm)
private
{ Private declarations }
fCom : IComIntf;
function DoSomething(Info: OleVariant): HResult;
public
{ Public declarations }
...
end;
...
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
fCom := CoComIntf.Create;
fCom.OnDoSomething := DoSomething;
...
提前致谢。
原始函数指针不是 COM 兼容类型。如果愿意,您当然可以使用 void 指针,但这并不符合 COM 的精神。
你在这里要做的是传递另一个接口。然后被调用者可以调用该接口上的函数并执行调用者的代码。
你的做法是错误的。实现它的正确方法是定义客户端实现并传递给您的 COM 对象的第二个接口。然后 COM 对象可以保留该接口并在需要时调用它的方法。这通常使用 Connection Points 作为事件接口来实现。
一个简单的实现方法,特别是因为您正在使用 IDispatch
,是使用 IDE 向导创建一个新的 Automation Object,并且请务必单击向导对话框中的 "Generate Event support code" 复选框。然后向导会生成2个接口,一个为对象本身,一个为对象的事件,并为你实现连接点逻辑。然后,您可以根据需要向 2 个接口添加方法,其中对象方法在需要时调用事件方法。
如果您随后编译、注册并将最终对象导入 IDE 并为其生成 VCL 包装器,生成的组件将具有内部连接到对象的连接点事件。
我想知道是否可以在 Delphi 2010 RIDL 编辑器中为接口定义定义 属性 类型 function/procedure 指针,这样当我创建一个实例时它的实现者使用它的 CoCreator,然后我可以在我的源代码中分配一个使用该接口定义的 function/procedure 到那个 属性。其实我想知道如何在下面填写“???”。
TLB 文件:
IComIntf = interface(IDispatch)
...
function Get_OnDoSomething : ??? safecall;
procedure Set_OnDoSomething(const New_Event : ???); safecall;
...
property OnDoSomething : ???;
...
implementation
uses ComObj;
class function CoComIntf.Create: IComInt;
...
begin
Result := CreateComObject(CLASS_ComIntf) as IComIntf;
end;
实现文件,ComIntfUnit.pas:
type
TOnDoSomething = function (Info: OleVariant): HResult of object;
TComIntf = class(TAutoObject, IComIntf)
private
fOnDoSomething : TDoSomething;
...
public
property OnDoSomething: TOnDoSomething read fOnDoSomething write fOnDoSomething;
...
客户表格:
uses ComIntfUnit;
type
TForm1 = class(TForm)
private
{ Private declarations }
fCom : IComIntf;
function DoSomething(Info: OleVariant): HResult;
public
{ Public declarations }
...
end;
...
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
fCom := CoComIntf.Create;
fCom.OnDoSomething := DoSomething;
...
提前致谢。
原始函数指针不是 COM 兼容类型。如果愿意,您当然可以使用 void 指针,但这并不符合 COM 的精神。
你在这里要做的是传递另一个接口。然后被调用者可以调用该接口上的函数并执行调用者的代码。
你的做法是错误的。实现它的正确方法是定义客户端实现并传递给您的 COM 对象的第二个接口。然后 COM 对象可以保留该接口并在需要时调用它的方法。这通常使用 Connection Points 作为事件接口来实现。
一个简单的实现方法,特别是因为您正在使用 IDispatch
,是使用 IDE 向导创建一个新的 Automation Object,并且请务必单击向导对话框中的 "Generate Event support code" 复选框。然后向导会生成2个接口,一个为对象本身,一个为对象的事件,并为你实现连接点逻辑。然后,您可以根据需要向 2 个接口添加方法,其中对象方法在需要时调用事件方法。
如果您随后编译、注册并将最终对象导入 IDE 并为其生成 VCL 包装器,生成的组件将具有内部连接到对象的连接点事件。