delphi – 使用DefineProperties替换TPersistent属性,例如TFont
发布时间:2020-12-15 04:13:23 所属栏目:大数据 来源:网络整理
导读:我正在更新组件中的一些属性.为了避免遗漏属性错误,我使用DefineProperties从流中读取旧属性.大多数属性很好,例如整数,但我无法获得基于TPersistent的属性来工作. TReader中的ReadProperty(TPersistent)过程受到保护,而不是公共过程,需要黑客才能访问它.即使
我正在更新组件中的一些属性.为了避免遗漏属性错误,我使用DefineProperties从流中读取旧属性.大多数属性很好,例如整数,但我无法获得基于TPersistent的属性来工作. TReader中的ReadProperty(TPersistent)过程受到保护,而不是公共过程,需要黑客才能访问它.即使这样,也永远不会调用ReadFontProperty过程,并且会发生缺失的属性异常.
我如何阅读TFont属性? 这是我试图做的一些示例代码. ... type TMyComponent = class(TComponent) strict private // Removed //FIntegerProperty: Integer; //FFontProperty: TFont; // New FNewIntegerProperty: Integer; FNewFontProperty: TFont; procedure ReadIntegerProperty(Reader: TReader); procedure ReadFontProperty(Reader: TReader); protected procedure DefineProperties(Filer: TFiler); override; published // Removed properties //property IntegerProperty: Integer read FIntegerProperty write FIntegerProperty; //property FontProperty: TFont read FFontProperty write SetFontProperty; // New properties property NewIntegerProperty: Integer read FNewIntegerProperty write FNewIntegerProperty; property NewFontProperty: TFont read FNewFontProperty write SetNewFontProperty; end; implementation procedure TMyComponent.DefineProperties(Filer: TFiler); begin inherited; // This works Filer.DefineProperty('IntegerProperty',ReadIntegerProperty,nil,FALSE); // This doesn't Filer.DefineProperty('FontProperty',ReadFontProperty,FALSE); end; procedure TMyComponent.ReadIntegerProperty(Reader: TReader); begin FNewIntegerProperty:= Reader.ReadInteger; end; type THackReader = class(TReader); procedure TMyComponent.ReadFontProperty(Reader: TReader); begin { TODO : This doesn't work. How do we read fonts? } THackReader(Reader).ReadProperty(FNewFontProperty); end; ... 更新1 使用以下代码尝试了David的建议: Filer.DefineProperty('Font.CharSet',ReadFontCharSet,False); … procedure TMyComponent.ReadFontCharSet(Reader: TReader); begin Reader.ReadInteger; end; 我收到无效的属性值错误.我想这与Charset属于TFontCharset类型(= System.UITypes.TFontCharset = 0..255)有关.我如何阅读这种类型的财产? 解决方法
为此,您需要使用TFont的每个单独发布的属性,您需要使用完全限定的名称.
Filer.DefineProperty('FontProperty.Name',ReadFontName,False); Filer.DefineProperty('FontProperty.Height',ReadFontHeight,False); Filer.DefineProperty('FontProperty.Size',ReadFontSize,False); // and so on for all the other published properties of TFont ReadFontName,ReadFontHeight等应该将旧属性值读入新命名的组件中. procedure TMyComponent.ReadFontName(Reader: TReader); begin FNewFontProperty.Name := Reader.ReadString; end; // etc. etc. 更新 您询问如何阅读Charset属性.这很复杂,因为它可以作为文本标识符(参见Graphics.pas中的FontCharsets常量)或纯整数值编写.以下是一些快速入侵的代码,可以读取您的Charset. procedure TMyComponent.ReadFontCharset(Reader: TReader); function ReadIdent: string; var L: Byte; LResult: AnsiString; begin Reader.Read(L,SizeOf(Byte)); SetString(LResult,PAnsiChar(nil),L); Reader.Read(LResult[1],L); Result := UTF8ToString(LResult); end; function ReadInt8: Shortint; begin Reader.Read(Result,SizeOf(Result)); end; function ReadInt16: Smallint; begin Reader.Read(Result,SizeOf(Result)); end; var Ident: string; CharsetOrdinal: Integer; begin Beep; case Reader.ReadValue of vaIdent: begin Ident := ReadIdent; if not IdentToCharset(Ident,CharsetOrdinal) then begin raise EReadError.Create('Could not read MyFont.Charset'); end; FNewFontProperty.Charset := CharsetOrdinal; end; vaInt8: FNewFontProperty.Charset := ReadInt8; vaInt16: FNewFontProperty.Charset := ReadInt16; else raise EReadError.Create('Could not read FontProperty.Charset'); end; end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |