gpt4 book ai didi

delphi - 使用 DefineProperties 替换 TPersistent 属性,例如字体

转载 作者:行者123 更新时间:2023-12-03 15:11:34 25 4
gpt4 key购买 nike

我正在更新组件中的一些属性。为了避免丢失属性错误,我使用 DefineProperties 从流中读取旧属性。大多数属性都工作正常,例如整数,但我无法使基于TPercient的属性发挥作用。 TReader 中的 ReadProperty(TPercient) 过程是 protected ,不是公开的,需要破解才能访问它。即使这样,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

使用以下代码尝试了大卫的建议:

Filer.DefineProperty('Font.CharSet', ReadFontCharSet, nil, False);

...

procedure TMyComponent.ReadFontCharSet(Reader: TReader);
begin
Reader.ReadInteger;
end;

我收到属性值无效错误。我想这与 Charset 类型为 TFontCharset (= System.UITypes.TFontCharset = 0..255) 有关。我如何阅读此类属性?

最佳答案

为了做到这一点,您需要使用 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 TFont

ReadFontNameReadFontHeight 等应将旧属性值读取到新命名的组件中。

procedure TMyComponent.ReadFontName(Reader: TReader);
begin
FNewFontProperty.Name := Reader.ReadString;
end;

// etc. etc.

更新

您询问如何读取 Charset 属性。这很复杂,因为它可以写为文本标识符(请参阅 Graphics.pas 中的 FontCharsets 常量),也可以写为普通整数值。这是一些快速拼凑在一起的代码,可以读取您的字符集。

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;

关于delphi - 使用 DefineProperties 替换 TPersistent 属性,例如字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11290413/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com