5

コンポーネントのいくつかのプロパティを更新しています。プロパティの欠落エラーを回避するために、DefinePropertiesを使用してストリームから古いプロパティを読み取ります。Integerなど、ほとんどのプロパティは正常に機能しますが、 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, 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;

無効なプロパティ値エラーが発生します。これは、 CharsetのタイプがTFontCharset(= System.UITypes.TFontCharset = 0..255)であることに関係していると思います。このタイプのプロパティを読み取るにはどうすればよいですか?

4

1 に答える 1

5

これを行うには、の個々の公開プロパティを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

ReadFontNameなどは、ReadFontHeight古いプロパティ値を新しい名前のコンポーネントに読み込む必要があります。

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

// etc. etc.

アップデート

Charsetプロパティの読み方を尋ねます。FontCharsetsこれは、テキスト識別子( Graphics.pasの定数を参照)または単純な整数値のいずれかとして記述できるため、複雑です。これは、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;
于 2012-07-02T09:44:41.963 に答える