我正在更新组件中的一些属性。为了避免丢失属性错误,我使用DefineProperties从流中读取旧属性。大多数属性运行良好,例如Integer,但我无法使基于TPersistent的属性工作。ReadProperty(TPersistent)过程在TReader中是受保护的,而不是公共的,需要黑客才能访问它。即使这样,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, nil, 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, nil, False);..。
procedure TMyComponent.ReadFontCharSet(Reader: TReader);
begin
Reader.ReadInteger;
end;我得到一个无效属性值错误。我想这与TFontCharset类型的字符集有关(= System.UITypes.TFontCharset = 0..255)。我如何阅读这种类型的财产?
发布于 2012-07-02 09:44:41
为了做到这一点,您需要使用TFont的每个已发布的属性,并且需要使用完全限定的名称。
Filer.DefineProperty('FontProperty.Name', ReadFontName, nil, False);
Filer.DefineProperty('FontProperty.Height', ReadFontHeight, nil, False);
Filer.DefineProperty('FontProperty.Size', ReadFontSize, nil, False);
// and so on for all the other published properties of TFontReadFontName、ReadFontHeight等应该将旧属性值读入新命名的组件中。
procedure TMyComponent.ReadFontName(Reader: TReader);
begin
FNewFontProperty.Name := Reader.ReadString;
end;
// etc. etc.更新
您将询问如何读取字符集属性。这很复杂,因为可以将其写入文本标识符(请参阅FontCharsets常量Graphics.pas),也可以编写为普通整数值。以下是一些快速破解的代码,将读取您的字符集。
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;https://stackoverflow.com/questions/11290413
复制相似问题