如何在 Delphi 2010 中使用 IFont 和 IStrings?
How to use IFont and IStrings in Delphi 2010?
我想在 Delphi 2010 中编写一个 DCOM client/server,它使用 IStrings 在测试服务器中将 Memo1.Lines(作为 TStrings)作为 属性 传递。服务器有一个 TMemo 组件,我想通过服务器的 IMemoIntf 设置或获取它的 Memo1.Lines 属性。
1-在 RIDL 编辑器中,开箱即用的 Delphi 2010 不接受 IStrings。所以我先注册了 stdvcl40.dll 并将其添加到编辑器的 "uses" 部分以便能够添加 IStrings 类型的 属性。
2-然后我实现了两个函数Set_Text和Get_Text来设置和获取服务器的Memo1.Lines,如下:
procedure TMemoIntf.Set_Text(const Value: IStrings);
begin
SetOleStrings(Form1.GetText, Value);
end;
function TMemoIntf.Get_Text: IStrings;
begin
GetOleStrings(Form1.GetText, Result);
end;
IMemoIntf 是由TMemoIntf 实现的接口。它被自动定义如下:
// *********************************************************************//
// Interface: IMemoIntf
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {2B6BD766-5FB6-413F-B8E2-4AB05D87E669}
// *********************************************************************//
IMemoIntf = interface(IDispatch)
['{2B6BD766-5FB6-413F-B8E2-4AB05D87E669}']
function Get_Text: IStrings; safecall;
procedure Set_Text(const Value: IStrings); safecall;
property Text: IStrings read Get_Text write Set_Text;
end;
而TMemoIntf如下:
TMemoIntf = class(TAutoObject, IMemoIntf)
protected
function Get_Text: IStrings; safecall;
procedure Set_Text(const Value: IStrings); safecall;
end;
当我在客户端调用 fMemo.Set_Text 时,一切都很好并且工作正常,并且客户端将服务器 Memo1 内容设置为它自己的内容,但是当我调用 fMemo.Get_Text 时,要获取服务器 Memo1 内容,我收到以下错误消息。
Access violation at address ... in module 'combase.dll'.Read of address ...
客户端有一个显示服务器的私有字段 fMemo 和一个用于显示 Set/Get_Text 调用结果的 Memo1。
TForm2 = class(TForm)
...
btnSetText: TButton;
...
btnGetText: TButton;
Memo1: TMemo;
...
procedure btnSetTextClick(Sender: TObject);
...
procedure btnGetTextClick(Sender: TObject);
private
fMemo : IMemoIntf;
end;
// it gives me the error
procedure TForm2.btnGetTextClick(Sender: TObject);
var
Strings : IStrings;
begin
Strings := fMemo.Get_Text;
SetOleStrings(Memo1.Lines, Strings);
end;
// it works fine
procedure TForm2.btnSetTextClick(Sender: TObject);
var
Strings : IStrings;
begin
GetOleStrings(Memo1.Lines, Strings);
fMemo.Set_Text(Strings);
end;
同样的想法适用于 IFont,但是当我实现相同的功能以使用 TFont 和 TColor 时,OLE_COLOR 工作完美(我知道 OLE_COLOR 作为自动化编组类型被直接支持,并且两者不同)。
我做错了吗还是 Delphi 2010 年的事?
如何使用 IFont 和 IStrings 缓解 Delphi 2010 中的问题?
好的,我找到问题了,是我。
“.ridl”文件的定义非常重要。对于 "getter function","out" 参数应该是 "IStrings**",对于 "putter function",它应该是 "IStrings*"。编译器自动更新 "TLB" 文件并在接口定义中添加 属性,并且在 "IMemoIntf" 的先前实现中,双向一切正常。
希望对您有所帮助。我不知道如何追加,如果有人有兴趣告诉我如何追加完整的项目,看看我做了什么。
我想在 Delphi 2010 中编写一个 DCOM client/server,它使用 IStrings 在测试服务器中将 Memo1.Lines(作为 TStrings)作为 属性 传递。服务器有一个 TMemo 组件,我想通过服务器的 IMemoIntf 设置或获取它的 Memo1.Lines 属性。
1-在 RIDL 编辑器中,开箱即用的 Delphi 2010 不接受 IStrings。所以我先注册了 stdvcl40.dll 并将其添加到编辑器的 "uses" 部分以便能够添加 IStrings 类型的 属性。
2-然后我实现了两个函数Set_Text和Get_Text来设置和获取服务器的Memo1.Lines,如下:
procedure TMemoIntf.Set_Text(const Value: IStrings);
begin
SetOleStrings(Form1.GetText, Value);
end;
function TMemoIntf.Get_Text: IStrings;
begin
GetOleStrings(Form1.GetText, Result);
end;
IMemoIntf 是由TMemoIntf 实现的接口。它被自动定义如下:
// *********************************************************************//
// Interface: IMemoIntf
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {2B6BD766-5FB6-413F-B8E2-4AB05D87E669}
// *********************************************************************//
IMemoIntf = interface(IDispatch)
['{2B6BD766-5FB6-413F-B8E2-4AB05D87E669}']
function Get_Text: IStrings; safecall;
procedure Set_Text(const Value: IStrings); safecall;
property Text: IStrings read Get_Text write Set_Text;
end;
而TMemoIntf如下:
TMemoIntf = class(TAutoObject, IMemoIntf)
protected
function Get_Text: IStrings; safecall;
procedure Set_Text(const Value: IStrings); safecall;
end;
当我在客户端调用 fMemo.Set_Text 时,一切都很好并且工作正常,并且客户端将服务器 Memo1 内容设置为它自己的内容,但是当我调用 fMemo.Get_Text 时,要获取服务器 Memo1 内容,我收到以下错误消息。
Access violation at address ... in module 'combase.dll'.Read of address ...
客户端有一个显示服务器的私有字段 fMemo 和一个用于显示 Set/Get_Text 调用结果的 Memo1。
TForm2 = class(TForm)
...
btnSetText: TButton;
...
btnGetText: TButton;
Memo1: TMemo;
...
procedure btnSetTextClick(Sender: TObject);
...
procedure btnGetTextClick(Sender: TObject);
private
fMemo : IMemoIntf;
end;
// it gives me the error
procedure TForm2.btnGetTextClick(Sender: TObject);
var
Strings : IStrings;
begin
Strings := fMemo.Get_Text;
SetOleStrings(Memo1.Lines, Strings);
end;
// it works fine
procedure TForm2.btnSetTextClick(Sender: TObject);
var
Strings : IStrings;
begin
GetOleStrings(Memo1.Lines, Strings);
fMemo.Set_Text(Strings);
end;
同样的想法适用于 IFont,但是当我实现相同的功能以使用 TFont 和 TColor 时,OLE_COLOR 工作完美(我知道 OLE_COLOR 作为自动化编组类型被直接支持,并且两者不同)。
我做错了吗还是 Delphi 2010 年的事?
如何使用 IFont 和 IStrings 缓解 Delphi 2010 中的问题?
好的,我找到问题了,是我。
“.ridl”文件的定义非常重要。对于 "getter function","out" 参数应该是 "IStrings**",对于 "putter function",它应该是 "IStrings*"。编译器自动更新 "TLB" 文件并在接口定义中添加 属性,并且在 "IMemoIntf" 的先前实现中,双向一切正常。
希望对您有所帮助。我不知道如何追加,如果有人有兴趣告诉我如何追加完整的项目,看看我做了什么。