BCB/TreeView

TreeViewコンポーネントの基本的な使い方のメモ。(TreeViewは、エクスプローラのフォルダの階層構造のような表示が出来るコンポーネント)
サンプルプログラムを通して記録。

目次

フォーム設計

画面のイメージと設定値。

設計イメージ
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'TreeView'#12486#12473#12488
  ClientHeight = 220
  ClientWidth = 359
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object TreeView1: TTreeView
    Left = 24
    Top = 24
    Width = 169
    Height = 177
    DragMode = dmAutomatic
    HideSelection = False
    HotTrack = True
    Indent = 19
    ReadOnly = True
    TabOrder = 0
    OnDragDrop = TreeView1DragDrop
    OnDragOver = TreeView1DragOver
  end
  object Button1: TButton
    Left = 232
    Top = 24
    Width = 97
    Height = 25
    Caption = #12450#12452#12486#12512#36861#21152
    TabOrder = 1
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 232
    Top = 71
    Width = 97
    Height = 25
    Caption = #23376#12450#12452#12486#12512#36861#21152
    TabOrder = 2
    OnClick = Button2Click
  end
  object Button3: TButton
    Left = 232
    Top = 120
    Width = 97
    Height = 25
    Caption = #21066#38500
    TabOrder = 3
    OnClick = Button3Click
  end
end
実行イメージ

動作の仕様

  • アイテム追加で、アイテムが後ろに新規追加されていきます。
  • TreeView内でアイテムが選択されているならば、その手前に新規挿入されます。
  • 子アイテム追加で、選択されているアイテムの配下に子アイテムを新規追加します。
  • 削除で、選択されているアイテムを削除します。
  • アイテムをドラッグ&ドロップすることで、移動することが出来ます。

各動作の説明

アイテムの追加

//---------------------------------------------------------------------------
//                                                同階層にアイテムを追加する
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // 追加する
    TTreeNode *p = TreeView1->Selected;
    TTreeNode *x = TreeView1->Items->Add(p, ItemName("Item"));

    if (p != NULL) {
    	// 選択されていたら、そのアイテムの手前に移動する
    	x->MoveTo(p, naInsert);
    }
}
//---------------------------------------------------------------------------

TreeView1->Selectedプロパティは、選択中のアイテムへのポインタを返します。Addメソッドは指定ノードと同じリストに新しいノードを追加し、そのポインタを返します。

指定した場所にアイテムを追加するメソッドは無いので、追加した後にMoveToメソッドで移動&挿入しています。MoveToメソッドの第二引数の意味を下表に示します。

意味
naAdd 末尾に追加
naAddFirst 先頭に追加
naAddChild 子ノードの末尾に追加
naAddChildFirst 子ノードの先頭に追加
naInsert 後ろに追加

子アイテムの追加

//---------------------------------------------------------------------------
//                                                配下に子アイテムを追加する
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    TTreeNode *p = TreeView1->Selected;

    if (p != NULL) {
        // 選択されていたら、子アイテム追加
    	TreeView1->Items->AddChild(p, ItemName("Item"));
    	// 子ノードを展開する
        p->Expand(false);
    }

}
//---------------------------------------------------------------------------

AddChildメソッドにて、子アイテムを追加します。標準ではノードは折り畳まれているので、Expandメソッドにて展開させています。

アイテムの削除

//---------------------------------------------------------------------------
//                                              選択されたアイテムを削除する
void __fastcall TForm1::Button3Click(TObject *Sender)
{
    TTreeNode *p = TreeView1->Selected;

    if (p != NULL) {
        // 選択されていたら削除する.
        p->Delete();
    }

}
//---------------------------------------------------------------------------

Deleteメソッドにて選択されたアイテムを削除しています。

ドラッグ中の処理

//---------------------------------------------------------------------------
//                                                    ドロップ許可を決定する
// Dragを有効にするには、DragMode = dmAutomatic に設定する.
// 何かがDragされてきた時に許可/不許可を返す.
void __fastcall TForm1::TreeView1DragOver(TObject *Sender, TObject *Source,
      int X, int Y, TDragState State, bool &Accept)
{
    if (Source == TreeView1 && TreeView1->GetNodeAt(X,Y) != NULL) {
        // ドラッグ元が自分自身かつ、
        // 現在の座標下にノードが存在するなら許可
        Accept = true;
    }
    else {
        // 条件を満たさないドラッグであれば不許可
        Accept = false;
    }

    if (Y < 15) {
        // 上へスクロール
        SendMessage(TreeView1->Handle, WM_VSCROLL, SB_LINEUP, 0);
    } else if (TreeView1->Height-Y < 15) {
        // 下へスクロール
        SendMessage(TreeView1->Handle, WM_VSCROLL, SB_LINEDOWN, 0);
    }
}
//---------------------------------------------------------------------------

イベントの記述に先立ち、ドラッグ&ドロップの機能を有効にするためにTreeView1->DragMode = dmAutomaticとしておく必要があります。

このイベントはドラッグ中に常に発生します。ドロップ可能ならばAcceptにtrueを与えることでその旨を伝えます。GetNodeAtメソッドは座標(X,Y)にあるノードを返すメソッドです。自分自身からのドラッグで、かつ、ドロップ先にノードがある場合に許可しています。

また、ドロップ先が表示外だった場合に自動的にスクロールしません。プログラマが実装する必要があります。画面の上端・下端の場合に、スクロールメッセージを発行することで、スクロールさせます。

ドロップの処理

//---------------------------------------------------------------------------
//                                                          ドロップ時の処理
// ドロップ先に挿入する.
void __fastcall TForm1::TreeView1DragDrop(TObject *Sender, TObject *Source,
      int X, int Y)
{
    if (Sender == TreeView1 && Source == TreeView1) {

        TTreeNode *pFrom = TreeView1->Selected;
        TTreeNode *pTo   = TreeView1->GetNodeAt(X,Y);

        if (pFrom != pTo) {
            // ドラッグ先が選択中、つまり
            // ドラッグ元=ドラッグ先の場合は何もせず無視.
            pFrom->MoveTo(pTo, naInsert);

            // 移動後に子ノードが格納されてしまうので再展開する.
            pFrom->Expand(false);
        }
    }
}
//---------------------------------------------------------------------------

ドラッグ中と同様の情報が引数として与えられます。

その他

ノードにアイコンを付ける場合

  1. TTreeView->Imagesプロパティおよび->StateImagesに、アイコンのデータを持ったImageListコンポーネントを関連付けます。
  2. TTreeNodeのプロパティにImageListのイメージ番号を指定することでアイコンが表示されます。
プロパティ名 意味
ImageIndex 通常時のイメージ番号(Images)
SelectedIndex 選択時のイメージ番号(Images)
StateIndex 1〜15までのイメージ番号(StateImages)

Imagesを使った場合は強制的にアイコン表示となり、無効のイメージ番号を指定してもその分のスペースが表示されます。一方、StateImagesを使うと1から15までの15個しかイメージを使えませんが、-1など無効なイメージ番号を指定するとアイコンが表示されなくなります。

主なプロパティとメソッド

TTreeView

プロパティ名 説明
AutoExpand 選択されたノードを自動展開するか否か。
HideSelection フォーカスが別コントロールに移動したときに選択状態を表示するかどうか。
Items 表示されるTTreeNodesオブジェクト。
MultiSelect 複数のノードを選択できるようにするか。
ReadOnly ユーザが内容を変更できるか。
Selected 現在選択されているノードオブジェクト(TTreeNode)。
ShowButtons 子を持つノードの左側に[+][-]のマークを表示するか。
ShowLines 各ノードを繋ぐ線を表示するか。
ShowRoot ノードの親への線を表示するか。
SortType 自動的にソートするかどうかを指定。stNode=ソートしない。stData=TTreeNode->Dataの変更時にソート。stText=TTreeNode->Captionの変更時にソート。stBoth=stDataとstTextの両方。ソート時にはOnCompareイベントが発生するので比較用のコードを記述しておく。
メソッド名 説明
FullCollapse 全てのノードをたたむ。
FullExpand 全てのノードを展開する。
GetNodeAt 座標で示されるノードオブジェクトを返す。
LoadFromFile ファイルからツリービューを読み込む。
SaveToFile ツリービューをファイルへ書き出す。

TTreeNodes

プロパティ名 説明
Count ツリービュー内のノード数。
Item[n] n番目のノードへのアクセス。TTreeNodeオブジェクトを返す。
Owner 親となるツリービュー。
メソッド名 説明
Add 新しいノードを後尾に追加。
AddChild 新しい子ノードを追加。
AddFirst 新しいノードを先頭に追加。
Clear ツリービューの全てのノードを削除する。
Delete 指定ノードを削除する。
Insert 指定ノードの後にノードを挿入する。

TTreeNode

プロパティ名 説明
Count 子ノードの数。
Data ユーザデータ格納用のvoidポインタ。
Expanded このノードが展開されているか。
HashChildren 子ノードを持っているか。[+]マークはココを見ている。
ImageIndex 「ノードにアイコンを付ける場合」参照。
SelectedIndex 「ノードにアイコンを付ける場合」参照。
StateIndex 「ノードにアイコンを付ける場合」参照。
Index 同じ親を持つ階層のノードに振られる番号。
Item 子ノードへのアクセス。
Level ツリービュー内のノードのレベル。
Parent 親ノード。
Selected ノードが選択されているか。
Text ノードに表示されるテキスト。
メソッド名 説明
Collaspe 子ノードを折り畳む。
Delete ノードを削除する。
DeleteChildren 子ノードを全て削除する。
Expand 子ノードを展開する。
MoveTo ノードを移動する。「各動作の説明−アイテムの追加」参照。

サンプルのソース

  • 今回作成したプログラムのソース

参考リンク

参考図書

  • C++Builder 6コンポーネント活用ガイド&実践プログラミング(vol.1(基本コンポーネント)
  • 楽天amazon

2007-02-24 komina