2

これらの指示に従ってプログラムを作成しました。うまく機能しますが、その理由はわかりません。

http://docwiki.embarcadero.com/CodeExamples/XE3/en/ComponentToString_(Delphi) .

私のコードは次のとおりです。

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Image1: TImage;
    Image2: TImage;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

function ComponentToStringProc(Component: TComponent): string;
var
  BinStream:TMemoryStream;
  StrStream: TStringStream;
  s: string;
begin
  BinStream := TMemoryStream.Create;
  try
    StrStream := TStringStream.Create(s);
    try
      BinStream.WriteComponent(Component);
      BinStream.Seek(0, soFromBeginning);
      ObjectBinaryToText(BinStream, StrStream);
      StrStream.Seek(0, soFromBeginning);
      Result:= StrStream.DataString;
    finally
      StrStream.Free;
    end;
  finally
    BinStream.Free
  end;
end;

function StringToComponentProc(Value: string): TComponent;
var
  StrStream:TStringStream;
  BinStream: TMemoryStream;
begin
  StrStream := TStringStream.Create(Value);
  try
    BinStream := TMemoryStream.Create;
    try
      ObjectTextToBinary(StrStream, BinStream);
      BinStream.Seek(0, soFromBeginning);
      Result:= BinStream.ReadComponent(nil);
    finally
      BinStream.Free;
    end;
  finally
    StrStream.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Text:= ComponentToStringProc(Image1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var img:TImage;
begin
  img:= (StringToComponentProc(Memo1.Text) as TImage);
  img.Left:=200;
  img.Top:=96;
  img.Parent:=form1;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.Picture.Bitmap.Height:=Image1.Height;
  Image1.Picture.Bitmap.Width:=Image1.Width;
  Image1.Picture.Bitmap.Canvas.Rectangle(0,0,Image1.Width,Image1.Height);
end;
initialization

RegisterClass(TImage);
end.

私の質問は:なぜ私は持っているのですか

initialization


RegisterClass (TImage);

Image2 がフォーム 1 に配置されたビジュアル コンポーネントの場合は?

2 行が欠落している場合は、エラー 219 Invalid typecast と表示されます

4

1 に答える 1

2

ストリーミング フレームワークは、コンポーネント クラス名をクラスに変換できる必要があります。それが完了すると、正しいクラスのオブジェクトをインスタンス化できます。

コードの重要な行は次のとおりです。

Result := BinStream.ReadComponent(nil);

Resultタイプは ですがTComponent、実際のランタイム タイプは のサブクラスにすることができますTComponent。あなたの場合、TImage.

'TImage'そのため、文字列をメタ クラスに変換できるようにするにはTImage、クラスとその名前のレジストリ (つまりマップ) が必要です。そして、そのレジストリは への呼び出しによって設定されますRegisterClassTImageこの呼び出しがないと、ストリーミング フレームワークは という名前のメタクラスを見つけることができません'TImage'。そのため、コンポーネントでストリーミングできません。

あなたは FPC を扱っていますが、Delphi のドキュメントRegisterClassが役に立ちます。

于 2013-05-06T21:33:23.693 に答える