比较高档点的做法:
------转载
使用 IStream (2002年5月20日)
本站更新 分类:杂类 作者: 推荐: 阅读次数:380
( http://www.tommstudio.com )
--------------------------------------------------------------------------------
有许多技巧文档讲述如何将任意一种数据转化成 variant 的数据类型以将它们传递给一个COM接口。
不管怎么样,许多VCL构件都有以流的方式工作的方法和属性。关键就是 TOLEStream 和 TStreamAdapter 的使用。
IStream 被定义在 ActiveX 单元,TStreamAdapter 被定义在 Classes 单元,TOLEStream 则被定义在 Axctrls 单元中。
下面的包裹类将为你提供你所需要的全部东西。(注意:不要将这些函数转化成属性,这样做可能会让你企图调用 IStream 方法,尽管它不是中读的,但是至少我这样做就遇到访问冲突的错误)
Uses Classes, ActiveX, Axctrls
Type TInterfaceStream = Class ( TMemoryStream )
Public
Procedure LoadFromIStream(Source : IStream)
Function GetIStream : IStream
end
Procedure TInterfaceStream.LoadFromIStream(Source : IStream)
var
Adapt : TOLEStream
Buff : Byte
I : Integer
begin
ADapt := TOLEStream.Create(Source)
Adapt.Position := 0
Self.Clear
Self.Position := 0
For I := 0 to Adapt.Size do
begin
Adapt.Read(Buff, 1)
Self.Write(Buff, 1)
end
Self.Position := 0
end
Function TInterfaceStream.GetIStream : IStream
var
Adapt : TStreamAdapter
tPos : Int64
begin
Adapt := TStreamAdapter.Create(Self)
Adapt.Seek(0, 0, tPos)
Result := Adapt as IStream
end
现在我们可以很简单地使用 IStream. 假如,你有一个 COM 对象方法需要返回一个 IStream,
那你只需要简单地声明一个private的 TInterfaceStream 成员变量。( 这里我们估且将称它为 FStream ),
在 initialize 时初始化它, 然后照下面的做法实现自己的方法:
Function TSampleCOMObj.Mehtod1 : IStream
begin
// Here's where you load whatever actually goes into the stream
result := FStream.GetIStream
end
将 TInterfaceStream 作为局部变量可能有些棘手。因为可能存在应用程序使用它之前它的内存就已经被释放掉的隐患。因此将它声明成一个 private 成员会更安全.
应用程序中只需要做下面的事
Procedure Form1.Button1OnClick(Sender : TObject)
var
Server : ISampleCOMObj
temp : IStream
ResultStream : TInterfaceStream
begin
Server := CreateCOMObject(Class_TSampleCOMObj) as ISampleComObj
temp := Server.method1
ResultStream := TinterfaceStream.Create
ResultStream.Clear
resultStream.Position := 0
resultstream.LoadFromIStream(Temp)
// do whatever it is you want with the data in the stream
end