W
wfzha
Unregistered / Unconfirmed
GUEST, unregistred user!
to nkiller
下面这几个调用方式及调用结果你看了一定感兴趣:
var
Form1: TForm1;
implementation
uses Project3_TLB;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
Var
MyCtrl, MySubCtrl : Variant;
Str : String;
begin
MyCtrl := CreateOleObject('Project3.MyTest');
MySubCtrl := MyCtrl.subctrl;
Str := MyCtrl.Test
//IMyCtrl自身的属性可以访问,问题是现在的MySubCtrl应该是IMySubTest
caption:=str;
end;
procedure TForm1.Button2Click(Sender: TObject);
Var
MyCtrl, MySubCtrl : Variant;
Str : String;
begin
MyCtrl := CreateOleObject('Project3.MyTest');
MyCtrl.subctrl:=myctrl;
MySubCtrl := MyCtrl.subctrl;
Str := MysubCtrl.name
//出错,//IMySubCtrl自身的属性不能访问,现在的MySubCtrl应该是IMySubTest
caption:=str;
end;
//以上两个调用,说明虽然我们指定了TMyTest的类型为IMySubTest,但函数返回的仍是IMyTest,没有返回子接口
procedure TForm1.Button3Click(Sender: TObject);
var MyCtrl, MySubCtrl : Variant;
Str : String;
begin
MyCtrl := CreateOleObject('Project3.MyTest');
MySubCtrl := MyCtrl.SubCtrl;
Str := MySubCtrl.Testb
//这里可以执行,这个属性是IMyTest的,起代码如下:
// Result:=(Self as IMySubTest).name;
//这说明在com内部转换成功
caption:=str;
end;
procedure TForm1.Button4Click(Sender: TObject);
var MyCtrl, MySubCtrl : Variant;
Str : String;
begin
str:=(CreateOleObject('Project3.MyTest') as IMySubTest).name
//成功执行
//引用Project3_TLB后,可以强制转换MyTest为IMySubTest
caption:=str;
end;
end.
*********************************************************************
另外,你的com代码也有问题,应该象下面这样写:
type
TMyTest = class(TASPObject, IMyTest, IMySubTest)
protected
FSubCtrl:IMySubTest;
procedure Initialize;override;
procedure OnEndPage
safecall;
procedure OnStartPage(const AScriptingContext: IUnknown)
safecall;
function Get_test: OleVariant
safecall;
function Get_Name: OleVariant
safecall;
function Get_SubCtrl: IMySubTest
safecall;
function Get_Testb: OleVariant
safecall;
end;
implementation
uses ComServ;
procedure TMyTest.OnEndPage;
begin
inherited OnEndPage;
end;
procedure TMyTest.OnStartPage(const AScriptingContext: IUnknown);
begin
inherited OnStartPage(AScriptingContext);
end;
function TMyTest.Get_test: OleVariant;
begin
Result:='Test';
end;
function TMyTest.Get_Name: OleVariant;
begin
Result:='Name';
end;
function TMyTest.Get_SubCtrl: IMySubTest;
begin
Result:=FSubCtrl;
end;
procedure TMyTest.Initialize
//com中的初始化函数
begin
inherited;
FSubCtrl:=Self as IMySubTest
//通过变量访问借口,实际上不行,返回的还是IMyTest
end;
function TMyTest.Get_Testb: OleVariant;
begin
Result:=(Self as IMySubTest).name;
end;
procedure TMyTest.Set_Testb(Value: OleVariant);
begin
end;
initialization
TAutoObjectFactory.Create(ComServer, TMyTest, Class_MyTest,
ciMultiInstance, tmApartment);
end.
**********************************************************************
上面的例子不能解决你的问题,但说明下面几个观点
1、你的这种实现方式返回的是两个并列的接口,不是子接口。
2、这种方式好象你能用IDispatch接口调用,不能用于Variant的调用方法。
另外,我有新的发现,正在研究中......
下面这几个调用方式及调用结果你看了一定感兴趣:
var
Form1: TForm1;
implementation
uses Project3_TLB;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
Var
MyCtrl, MySubCtrl : Variant;
Str : String;
begin
MyCtrl := CreateOleObject('Project3.MyTest');
MySubCtrl := MyCtrl.subctrl;
Str := MyCtrl.Test
//IMyCtrl自身的属性可以访问,问题是现在的MySubCtrl应该是IMySubTest
caption:=str;
end;
procedure TForm1.Button2Click(Sender: TObject);
Var
MyCtrl, MySubCtrl : Variant;
Str : String;
begin
MyCtrl := CreateOleObject('Project3.MyTest');
MyCtrl.subctrl:=myctrl;
MySubCtrl := MyCtrl.subctrl;
Str := MysubCtrl.name
//出错,//IMySubCtrl自身的属性不能访问,现在的MySubCtrl应该是IMySubTest
caption:=str;
end;
//以上两个调用,说明虽然我们指定了TMyTest的类型为IMySubTest,但函数返回的仍是IMyTest,没有返回子接口
procedure TForm1.Button3Click(Sender: TObject);
var MyCtrl, MySubCtrl : Variant;
Str : String;
begin
MyCtrl := CreateOleObject('Project3.MyTest');
MySubCtrl := MyCtrl.SubCtrl;
Str := MySubCtrl.Testb
//这里可以执行,这个属性是IMyTest的,起代码如下:
// Result:=(Self as IMySubTest).name;
//这说明在com内部转换成功
caption:=str;
end;
procedure TForm1.Button4Click(Sender: TObject);
var MyCtrl, MySubCtrl : Variant;
Str : String;
begin
str:=(CreateOleObject('Project3.MyTest') as IMySubTest).name
//成功执行
//引用Project3_TLB后,可以强制转换MyTest为IMySubTest
caption:=str;
end;
end.
*********************************************************************
另外,你的com代码也有问题,应该象下面这样写:
type
TMyTest = class(TASPObject, IMyTest, IMySubTest)
protected
FSubCtrl:IMySubTest;
procedure Initialize;override;
procedure OnEndPage
safecall;
procedure OnStartPage(const AScriptingContext: IUnknown)
safecall;
function Get_test: OleVariant
safecall;
function Get_Name: OleVariant
safecall;
function Get_SubCtrl: IMySubTest
safecall;
function Get_Testb: OleVariant
safecall;
end;
implementation
uses ComServ;
procedure TMyTest.OnEndPage;
begin
inherited OnEndPage;
end;
procedure TMyTest.OnStartPage(const AScriptingContext: IUnknown);
begin
inherited OnStartPage(AScriptingContext);
end;
function TMyTest.Get_test: OleVariant;
begin
Result:='Test';
end;
function TMyTest.Get_Name: OleVariant;
begin
Result:='Name';
end;
function TMyTest.Get_SubCtrl: IMySubTest;
begin
Result:=FSubCtrl;
end;
procedure TMyTest.Initialize
//com中的初始化函数
begin
inherited;
FSubCtrl:=Self as IMySubTest
//通过变量访问借口,实际上不行,返回的还是IMyTest
end;
function TMyTest.Get_Testb: OleVariant;
begin
Result:=(Self as IMySubTest).name;
end;
procedure TMyTest.Set_Testb(Value: OleVariant);
begin
end;
initialization
TAutoObjectFactory.Create(ComServer, TMyTest, Class_MyTest,
ciMultiInstance, tmApartment);
end.
**********************************************************************
上面的例子不能解决你的问题,但说明下面几个观点
1、你的这种实现方式返回的是两个并列的接口,不是子接口。
2、这种方式好象你能用IDispatch接口调用,不能用于Variant的调用方法。
另外,我有新的发现,正在研究中......