Tagプロパティの真価

 何気にフラグ立てに使われているTagプロパティ。変数代わりに使っている方が多数だと思います。TagプロパティはTComponentを継承したコンポーネントには大抵存在します(つまり、ほぼすべてに存在する、という事です)。

 Helpには、

Tag プロパティの機能は,あらかじめ定義されていません。開発者の便宜を図るために用意されています。Tag プロパティを使って追加の整数値を格納したり,Tag プロパティをコンポーネント参照またはポインタなどの 32 バイト値に型キャストしたりできます。

 と書かれています。重要なのは後半部分です。「
ポインタなどの 32 バイト値に型キャストしたり」...これがミソです。"たった一つのInteger型"ですが、一つあれば充分です。「TStringList のススメ」で書いた事に近い事ができます。

type
  TDataStruct =
     record
      Code :Integer;
      Name :String;
      DATA1:String;
      DATA2:String;
      DATA3:String;
      DATA4:String;
      DATA5:String;
    end;
  PDataStruct = ^TDataStruct;

 最初に構造体を定義しておきます。すると、

procedure TForm1.FormCreate(Sender: TObject);
var
  PDS:PDataStruct;
begin
  New(PDS);
  PDS^.Code := 123;
  PDS^.Name := 'ABC';
  { 処理 }
  Tag := Integer(PDS);
end; 

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Dispose(PDataStruct(Pointer(Tag))); // 破棄するのを忘れずに 
end;

 このような事が可能になります。この例の場合、フォームが破棄されるまでは「PDataStruct(Pointer(Tag))^.Code」のような感じで構造体にアクセスできます。フォームの場合にはプロパティやグローバル変数が使えるのであまり恩恵は得られないのですが、動的に作成するコンポーネントには効果は絶大です。動的作成したコンポーネントに構造体をぶらさげておくと、動的作成したコンポーネントの削除と同時に構造体を破棄する事が可能です。

 動的作成したコンポーネントに使う
構造体をTStringListや動的配列で管理しようとすると、コンポーネントの追加と削除時に非常に面倒な事になります。また、コンポーネントとそのコンポーネント用構造体の不一致が起きる場合があります。Tagプロパティを使った場合では不一致は起こり得ません。最悪の場合でもメモリリークするだけ(!)で済みます。
 BACK