难道就没人能实现保存ACTIVEXFORM的自定义属性吗 ( 积分: 100 )

  • 主题发起人 主题发起人 njlgg
  • 开始时间 开始时间
N

njlgg

Unregistered / Unconfirmed
GUEST, unregistred user!
我用D7做了一个ACTIVEXFORM控件,定义了一个自定义属性USERNAME,然后又在D7中使用该控件,在设计期间能看到并修改这个属性,运行期间也可以读写该属性.但问题是在设计期间保存工程后重新打开,控件的自定义属性值又全部丢失了.有没有高手能解决这个问题啊???
 
我用D7做了一个ACTIVEXFORM控件,定义了一个自定义属性USERNAME,然后又在D7中使用该控件,在设计期间能看到并修改这个属性,运行期间也可以读写该属性.但问题是在设计期间保存工程后重新打开,控件的自定义属性值又全部丢失了.有没有高手能解决这个问题啊???
 
你应该是没有实现 IPersistStorage;
参考我的
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3297371
我只是实现对文件流动操作。属性就不是这样保存的。
可以参考
var
stmData:IStream;
OS:TOleStream;
read:TReader;
elementcount:integer;
bty:array of byte;
begin
if SUCCEEDED(stg.OpenStream('PropData',nil, STGM_READWRITE or STGM_SHARE_EXCLUSIVE,0,stmData)) then
begin
OS:=TOleStream.Create(stmData);
try
read:=Treader.Create(oS,4096);
try
FUserName:=read.ReadWideString;
FDataTime:=read.ReadWideString ;
self.Height :=trunc(read.ReadSingle) ;
self.Width :=trunc(read.ReadSingle) ;
self.FLastTime:=trunc(read.ReadSingle );
finally
read.Free;
end;
finally
OS.Free;
end;
end;
Result := S_OK;
end;
 
我用了IPERSISTSTORAGE 和IPERSISTPROPERTYBAG,但都没能实现,不知是怎么回事
 
在定义属性的时候加上stored关键字,如:
property Caption: TCaption read GetText write SetText stored IsCaptionStored;
 
参考:
作者?: ycguser
标题?: ActiveX开发历程--控件数据的序列化
关键字:
分类?: 开发技巧
密级?: 公开
(评分: , 回复: 0, 阅读: 149) »»
刚开发开发此控件时,首先是想到此控件的数据要序列化到WORD文档中。
在建立工程时,我采用了ActiveXForm. 我在ActivexForm中加入一个USERNAME(String型)的属性后,将控件放到WORD中,发现USERNAME无法序列化到WORD文档中。这时我发现比较难办。如果这个基本的功能实现不了,那个这个控件根本无法开发下去。于是我查看了基类:TActiveXControl ,发现它已经实现了好几个序列化的接口。经过一天的调试跟踪,也没有搞明白它序列化方面的原理。现实的结果是在WORD中存不住数据。根据C++经验,只有自己去实现序列化的接口,但经过对系统支持的几个序列化接口试验以后,才发现只有实现IPersistStorage接口在WORD中才能序列化数据。
下面是是IPersistStorage实现的代码:
TCanvasForm = class(TActiveForm, ICanvasForm,IPersistStorage)
private
{ Private declarations }
FUserName:String; //用户名称
FDataTime:string; //取得笔迹数据的时间
FWriteTime:Integer; //返回的时间
FIndata:oleVariant; //笔迹数据变量 array of byte 的变量
FisScale:boolean; //记录图片是否比image大
FLastTime:Integer;
bdirty:Boolean; //是否保存标识
public
///////IPersistStorage
function IsDirty: HResult; stdcall;
function InitNew(const stg: IStorage): HResult; stdcall;
function Load(const stg: IStorage): HResult; stdcall;
function Save(const stgSave: IStorage; fSameAsLoad: BOOL): HResult;
stdcall;
function SaveCompleted(const stgNew: IStorage): HResult; stdcall;
function HandsOffStorage: HResult; stdcall;
function GetClassID(out classID: TCLSID): HResult; stdcall;
end;
////////////////////IPersistStoge
function TCanvasForm.IsDirty: HResult; stdcall;
begin
//if bdirty then
// Result := S_False
//else
result:=S_OK;
end;
function TCanvasForm.InitNew(const stg: IStorage): HResult; stdcall;
begin
Result := S_OK;
end;
function TCanvasForm.Load(const stg: IStorage): HResult; stdcall;
var
stmData:IStream;
OS:TOleStream;
read:TReader;
elementcount:integer;
bty:array of byte;
begin
if SUCCEEDED(stg.OpenStream('PropData',nil, STGM_READWRITE or STGM_SHARE_EXCLUSIVE,0,stmData)) then
begin
OS:=TOleStream.Create(stmData);
try
read:=Treader.Create(oS,4096);
try
FUserName:=read.ReadWideString;
FDataTime:=read.ReadWideString ;
self.Height :=trunc(read.ReadSingle) ;
self.Width :=trunc(read.ReadSingle) ;
self.FLastTime:=trunc(read.ReadSingle );
elementcount:=trunc(read.ReadSingle );
finally
read.Free;
end;
finally
OS.Free;
end;
end;
Result := S_OK;
end;

function TCanvasForm.Save(const stgSave: IStorage; fSameAsLoad: BOOL): HResult;
stdcall;
var
stmData:IStream;
OS:TOleStream;
write:TWriter;
arrayElement:integer;
p:pointer;
begin
// if not SUCCEEDED(stgSave.OpenStream('ss',nil, STGM_READWRITE or STGM_SHARE_EXCLUSIVE,0,stmData)) then
OleCheck(stgSave.CreateStream('PropData',STGM_CREATE or STGM_READWRITE or STGM_SHARE_EXCLUSIVE,0,0,stmData));
OS:=TOleStream.Create(stmData);
try
write:=TWriter.Create(OS,4096);
try
write.WriteWideString(FUserName);
write.WriteWideString(FDataTime);
write.WriteSingle(Height);
Write.WriteSingle(Width);
write.WriteSingle(FLastTime);
///////////// 开始写变体数据
if not VarIsEmpty(self.FIndata) then
begin
arrayElement:=VarArrayHighBound(Findata,1)+1;
write.WriteSingle(arrayElement);
p := VarArrayLock(Findata);
try
write.Write(p^, arrayElement);
finally
VarArrayUnlock(Findata);
end;
end
else
begin
arrayElement:=-1;
write.WriteSingle(arrayElement);
end;
finally
write.Free;
end;
finally
OS.Free;
end;
bdirty:=true;
Result := S_OK;
end;
function TCanvasForm.SaveCompleted(const stgNew: IStorage): HResult; stdcall;
begin
Result := S_OK;
end;
function TCanvasForm.HandsOffStorage: HResult; stdcall;
begin
Result := S_OK;
end;
function TCanvasForm.GetClassID(out classID: TCLSID): HResult; stdcall;
begin
classID:=Class_CanvasForm;
Result := S_OK;
end;
 
上面几位的方法我都试过了,还是不行啊.ACITVEX控件的属性不能写进控件所在单元的DFM文件中.
 
TO 寻路
你说在加上STORED关键字不行,在类库单元中修改成STORED TRUE后,一保存它又自动变成FALSE了,直接编译后也不行.
 
各位在这个网址下载我的控件在DELPHI中试试就知道怎么回事了,这个DELPHI开发的控件有四个自定义属性,在DELPHI中,属性的值老是不能保存,折磨了我一个月了.谁解决了我再加分,并送这个控件的修正该问题的正式版
 
刚才忘了写网址了,对不起各位.http://bbs.2ccc.com/attachments/2005/njlgg_2005121516574.rar
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
825
DelphiTeacher的专栏
D
后退
顶部