TreeViewのNodeパスの取得

解決


森田  2003-07-13 00:29:12  No: 4122

TreeViewを使用したプログラムを組んでいます。
エクスプローラと同じようなことをしたいと思っているのですが、
選択しているnodeまでのフルパス?をしるにはどうするのでしょうか?

エクスプローラのアドレスに出るようなことをしたいんです。

たとえば
testTV
  abc
    bbc
     ccc
  zzz
   yyy

のツリーがあったとき、cccを選択するとtestTV\abc\bbc\cccの文字列を
取得したい。

ヘルプを見たのですが、今一判りませんでした。
すみませんが、わかる方よろしくご教授願います。


Halbow  URL  2003-07-13 07:38:58  No: 4123

Halbow です。

これは簡単です。Parent を遡るだけです。

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
var
  TN:TTreeNode;
  s:string;
begin
  s := Node.text;
  TN := Node.Parent;
  while Assigned(TN) do begin
    s := TN.Text+'\'+s;
    TN := TN.Parent;
  end;
    Label1.Caption := s;
end;


平蔵  2003-07-13 10:21:59  No: 4124

nodeのParentをさかのぼる方法が基本です。
しかしそれだと効率がよくないので、Node追加時にフルパスの情報を
持たせてやるのがベターだと思われます。
具体的にはヘルプのAddChildObject メソッド (TTreeNodes)と
AddChildObejectを見て下さい。
ヘルプ中にあるPtrパラメータはNodeの固有情報として保持しておきたい
情報を自分で決めて定義すればよいのです。
御自分で調べられて、ちょっと難しいなと感じられるようでしたら
今回はParentをさかのぼる方法をお薦めします。


平蔵  2003-07-13 10:24:39  No: 4125

>具体的にはヘルプのAddChildObject メソッド (TTreeNodes)と
>AddChildObejectを見て下さい。

は、具体的にはヘルプのAddObject メソッド (TTreeNodes)と
AddChildObejectを見て下さい。

の誤りです。すいません。


にしの  2003-07-13 18:42:53  No: 4126

速度効率をとる場合、代償はメモリ効率の低下・開発効率の低下です。
平蔵さんの方法をとると、深いツリー構造であればあるほど、速度効率は上がります。
その代わり、単純にツリーに追加するだけでなく、そのアイテムに対してデータを用意しなければなりません。
ツリーアイテムが増えれば増えるほど、メモリ使用量は増加します。たとえば、3文字のフォルダ名(終端文字列を含めて4バイト)で、3階層まであった場合、
1つの親に対し、3つの子供があり、さらに3つずつ(全9つ)の孫がある
とすると、
1+3+9=13。
3つの親があるので、39。
それぞれが3文字であるので、終端文字を含めれば、1つあたり4バイト。合計156バイト。

これを、それぞれにフルパスを持たせると、
親の数は3。文字数は12。
子供の数は9。文字数は(フォルダ名3+区切り文字1+フォルダ名3+終端文字列1=8)。72。
孫の数は27。文字数は、(フォルダ名3+区切り文字1+フォルダ名3+区切り文字1+フォルダ名3+終端文字列1=12)。324。
この合計なので、408バイト。

親をたどる場合、すでにキャプションにこの文字列が含まれていることから、フルパスにすると(この例では)408バイト余分に使われることになります。
ハードディスク内をツリーにする場合には、もっと容量が必要になるので、このことも考慮しなければなりません。
メモリは有限ですから。


にしの  2003-07-13 18:48:47  No: 4127

間違えました。
速度効率とメモリ効率の比較に、開発効率はありませんでした。
今回の場合、単純な方法であれば、メモリを操作しないため、メモリ効率も下がることはありませんし、余分なコーディングがないため開発効率は落ちません。
速度効率を考え、メモリに格納した場合、メモリ操作に対する開発工程が発生するため、開発効率が落ちる、というものです。
すでにメモリ操作に関するルーチンを作成し、十分なテストをすませてあれば、それほど開発効率に響くことはありません。


平蔵  2003-07-13 22:32:13  No: 4128

にしのさんのおっしゃること、もっともです。
私が発言した"効率"とは速度に関してです。
またメモリに関しても、全ノードを展開するという可能性が
低いのであれば、ノードを閉じたときには子ノードとそれに伴う
メモリを解放し、子ノードを展開するときに、そのぶんだけのメモリを
確保することになるので、それほど大量のメモリ負荷にならないと思います。
また今回のテーマはエクスプローラと同等の動作ということですので、
全ツリーを最初にTreeViewにセットするということは、通常この手のソフトではとりません。展開するときにその子フォルダを取得して
ノードにセットしていく方がメモリ的にも速度的にも効率がいいのではないでしょうか。
このあたりは、ソフトの使い方と考え方になるので、その人ごとの設計思想に
よるところが大きいのではないでしょうか。


森田  2003-07-14 06:07:33  No: 4129

Halbowさん
平蔵さん
にしのさん

ありがとうございました。
遡って調べるしかないのだろうと思っていましたが、
AddChildObejectでも出来るようですね。
TreeViewは他のコンポーネントとなんとなく違う感じがして、
なかなか使いづらく感じています。
イロイロとありがとうございました。


Halbow  URL  2003-07-14 09:23:56  No: 4130

Halbow です。

> TreeViewは他のコンポーネントとなんとなく違う感じがして、
> なかなか使いづらく感じています。

この感覚はよくわかります。
TListView もそうですが、TListBox や TMemo とは異なり、
メソッドやプロパティーの返すモノがオブジェクトになって
いるんですよね。はじめは戸惑いますが、すこし慣れると、
この実装がいかに優れたものであるか分かってきます。

健闘を祈ります。


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

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






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