2

このノード データ レコードがあるとします。

Type
  PPerson = ^TPerson;
  TPerson = record
   Name: String;
   Age: Integer;
   SomeBool: Boolean;
  end;

VirtualStringTree を設定するには、次のようにします。

Procedure AddToTree(Person: TPerson);
Var
 Node: PVirtualNode;
 Data: PPerson;
Begin
 Node := VT.AddChild(nil);
 Data := VT.GetNodeData(Node);
 Data.Name := Person.Name;
 Data.Age  := Person.Age;
 Data.SomeBool := Person.SomeBool;
End;

Procedure TMyForm.MyButtonClick(Sender: TObject);
Var
 Person: TPerson;
Begin
 Person.Name := 'Jeff';
 Person.Age := 16;
 Person.SomeBool := False;
 AddToTree(Person);

End:

これで問題なく動作しますが、簡単にしたいので、レコードに新しいフィールドを追加するたびに AddToTree メソッドを変更する必要はありません。

だから私はこれを試しました:

Procedure AddToTree(Person: TPerson);
Begin
 VT.AddChild(nil,@Person);
End;

これはコンパイルされますが、VT何も表示してPVirtualNodeいないため、データを取得していないように見えます。また、OnGetText イベントを中断すると、変数が空であることがわかります。

私は何を間違っていますか?:)

4

4 に答える 4

3

あなたはマニュアルを読んでいません:)

OK、この場合、ソースはマニュアルです -AddChild()ソースからの引用:

UserData を使用して、ユーザー データ領域の最初の 4 バイトを、OnInitNode で使用できる初期値に設定することができます。これにより、ノードがまだ「公式」になっていない場合でも、OnFreeNode イベント (<> nil の場合) がトリガーされます。初期化されました。

IOWは、あなたがそれを使用している/動作することを期待している方法で使用することを意図したものではありません.

ところで、なぜデータをコピーするのですか? 持っていない理由

type
  PTreeData = ^TTreeData;
  TTreeData = record
   Data: PPerson;
  end;

それらをツリーに保持してレコードを割り当てNew()、次にDispose()ツリーがクリアされたときにレコードを割り当てますか?

于 2011-08-05T18:58:57.357 に答える
3

レコードをデータホルダーとして使用する場合に VTV にデータを格納する最良の方法は、レコードへのポインターのみを格納し、レコード自体はリスト/配列に個別に格納することです。これは、ビジュアル コンポーネントが実際にデータを所有していない場合の仮想および MVC パラダイムにも対応します。IOW、レコードを追加するスキームは次のとおりです。

  • AllocMem、New、... を使用して、レコード (!) にメモリを割り当てます。
  • そのフィールドを埋める
  • リスト/配列に追加します
  • NodeData = PNewRecord で新しいノードを VTV に追加します

レコードを削除するスキームは次のとおりです。

  • 対応するノードを VTV から削除する
  • Finalize (!) を使用してレコードをファイナライズし、ref-counted フィールドでのメモリ リークを回避します。
  • FreeMem、Dispose などを使用して、割り当てられたメモリを破棄します。
  • リスト/配列から項目を削除
于 2012-09-25T14:42:43.953 に答える
0

さらに別の「質問してから2分後に答えが見つかりました」-なんて屈辱的... :(

とにかく、これは次のように CopyMemory を使用して実現できます。

Procedure AddToTree(Person: TPerson);
Var
 Data: PPerson;
 Node: PVirtualNode;
Begin
 // add node
 Node := VT.AddChild(nil);
 // Get data of the node
 Data := VT.GetNodeData(Node);
 // Copy the Person stuff to the Node's data.
 CopyMemory(Data,@Person,SizeOf(Person));
End;
于 2011-08-05T18:58:08.310 に答える