TreeView コンポーネントで、選択されたアイテムの ItemID を取得するには?

解決


オン赤  2002-09-22 22:55:50  No: 1567

お世話になっています。 いくつか同時に抱えている疑問がちっとも解決しないのに、また一つ分からない点が。。。

WebBrowser コンポーネントと一緒に使ってブラウザのブックマーク設定のためにTreeView コンポーネントで、選択されたアイテムの ItemID を取得したいのですが、戻り値を格納する変数 selectedItemID 
をどう定義したらいいのかわかりません。次のようにすると「未定義の識別子 HTreeItem]とエラーが出ます。定義の初歩的な知識がないのでお恥ずかしいのですが。どなたかお教え下さい。
(そもそも、ブックマーク、あるいは「お気に入り」を保存したり、削除、移動するために、このユニークItemIDにURLをつなげようと構想しているのですが、もっといい方法がある気がします。ついでにこれもお教え下さるとありがたいのですが。)

var aa:integer;
     selectedItemID : HTreeItem;
begin
  aa:=TreeView1.Selected.AbsoluteIndex;
  selectedItemID:=t.Item[aa].ItemId;


オン赤  2002-09-23 00:00:25  No: 1568

すみません、書き落としていました。
var t. TTreenodes ←  忘れていました。正しいかどうかは怪しいんですが
    aa:integer;  
    selectedItemID :HTreeItem;

今 試行錯誤的しながらですが
selectedItemID : integer; と定義変えて

      selectedItemID :=integer(t.Item[aa].ItemId)

としたら、これはOKでしたが、t.Item[aa].ItemID ってヘンですね。


オン赤  2002-09-23 00:24:42  No: 1569

何度も補足してすみません。
上記の HTreeeItem の型はそもそも何ですか?
また、上記のような integer への変換は成り立つのでしょうか。また
逆に、integer でツリーノード一個一個にユニークなItemID を保存できたとして、その逆、つまり、integer 値から コンポーネント TreeView 上のある一個のノードを特定できるのでしょうか?そのためにはどのようにしたらよろしいのでしょうか?


にしの  2002-09-23 02:45:00  No: 1570

たぶん、HTreeItemを使うと破綻しますよ。
理由は、HTreeItemハンドルから、TTreeItemオブジェクトを受け取ることができないからです。

たとえば、Captionが"TEST"、というTreeItem1オブジェクトがあったとします。
このハンドルが、HTreeItem1という変数に入っているハンドルだったします。
このとき、HTreeItem1は、自分自身がTreeItem1のハンドルであることはわかりません。もちろん、Captionが"TEST"であることはわかりますし、子ノードのハンドル、親ノードのハンドルもわかります。
VCLとしての、TTreeItemオブジェクトがわからないのです。
もし、ハンドルを使って認識するのであれば、完全にハンドルでデータの管理をしなければならなくなると思います。
# TTreeItemには、Dataプロパティがありますが、これも使えません

以上のことを知った上で、HTreeItemを使用するのであれば、TreeView_???というAPI群を使用して、選択された項目のハンドルを得ることができます。
TreeView_???のAPI群の内容は、単純にメッセージを送信してそのResultを受けるだけです。
選択項目は確か、TreeView_GetSelectionだったと思います。
TreeView_GetSelection(TreeView1.Handle);で、HTreeItemが取得できます。

一応、ハンドルはIntegerでも納まります。
> integer 値から コンポーネント TreeView 上のある一個のノードを特定できるのでしょうか?
しかし、これはできません。
やるとしたら、すべてのノードのTTreeNode.ItemIdを比較するしかないと思います。
速度を求めるためにやるのであれば、完全にハンドルのみで管理するか、VCLのみで管理するかどちらかにしたほうがいいですよ。


にしの  2002-09-23 02:53:00  No: 1571

HTreeItemの定義ですが、Commctrlに定義されています。


オン赤  2002-09-23 05:52:12  No: 1572

にしのさま、ありがとうございます。
「破綻」とは、なんと恐ろしいことでしょう!
戦線後退しまして、バックグランドにもういちまいのツリービューを張り付けてお茶を濁すことにします。これだったら頭も使わないのでラクですし。。
済みません、せっかくアドバイスいただいたのに、挫折がこわくて
逃げちゃいました。
ありがとうございました。


にしの  2002-09-23 06:47:29  No: 1573

いえいえ。
僕も前にやりました^^;
卵が先か、鶏が先か、という状態に陥りましたよ(苦笑)
TCanvasやTPenなどなら、ハンドルを入れ替えてやれば動くのですが、HTreeItemはできないのです。
# 僕の場合、他アプリのTREEVIEWを、TTreeViewとして使えないか、というところでしたが

2つのTreeViewを用意するということは、1つのTreeItemに対する隠れたTreeItemを用意するということですよね?
TreeItemには、Dataという項目があるので、ここにオブジェクトを入れてやれば使えますよ。
TTreeView.OnDeletionイベントで、Dataを解放してやればOKです。


オン赤  2002-09-23 20:39:35  No: 1574

にしのさま、
<2つのTreeViewを用意するということは、1つのTreeItemに対する隠れた<TreeItemを用意するということですよね?
はい、そうです、が、けっこう頭がいるんですよね。Item を移動させると二枚のTreeView間での連繋が分かんなくなっちゃったりして。MoveTo が起こす移動を裏で認識できないで、意外と手こずってます。
>TreeItemには、Dataという項目があるので、ここにオブジェクトを入れてやれば使えますよ。
TTreeView.OnDeletionイベントで、Dataを解放してやればOKです。

ポインタですか。。昔パスカル時代にさんざんやりましたけど、もう歳のせいもあって、自信がありません。が、URL 情報を手放すことなくアイテムの移動をTreeView.Items[i].Data にさせることができそうですね。はて?ちょっと御指南を、またしてもですが、お願いできませんか?


にしの  2002-09-24 07:55:23  No: 1575

メモリ確保などが面倒なので、PCharは使いたくないですね。
URL情報は文字列だけでしょうか。クラスを定義して、Dataプロパティに設定すると、作成・解放が、Create,Freeでできて楽です。

たとえば、
  TURLString=class
  private
    FText: string;
  public
    property Text: string read FText write FText;
  end;
というようなクラスを用意しておき、
  Item := TreeView1.Items.AddChild(TreeView1.Selected, Edit1.Text);
  url := TURLString.Create;
  url.Text := Edit2.Text;
  Item.Data := url;
というような感じに追加します。

解放は、
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
  if Node.Data = nil then exit;
  TURLString(Node.Data).Free;
end;
で行います。

アイテムの移動は、Nodeを移動させるだけですので、Dataプロパティもついていきます。
ただ、アイテムのコピーの場合、Dataプロパティは同じポインタをあらわしてしまいますので、こちらも再度作成する必要が出てきます。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加