BCB/ListView

ListViewコンポーネントの基本的な使い方の情報収集しつつ、作ったサンプルプログラムのメモ。不十分な箇所もあるかも。

目次

フォーム設計

フォームをこんな感じに配置。

イメージリストにアイコン画像を登録します。ImageList1は32x32、ImageList2は16x16。サンプルで使用してるアイコンは下記にインストールされているもを使いました。

C:\Program Files\Common Files\Borland Shared\Images\GlyFX\Icons\BMP

以下、フォームのデザインデータ。

object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'ListView'#12486#12473#12488
  ClientHeight = 287
  ClientWidth = 433
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object ListView1: TListView
    Left = 8
    Top = 24
    Width = 289
    Height = 185
    Columns = <
      item
        Caption = #21517#21069
        Width = 100
      end
      item
        Caption = #35443#32048
        Width = 150
      end>
    DragMode = dmAutomatic
    HideSelection = False
    LargeImages = ImageList1
    MultiSelect = True
    SmallImages = ImageList2
    TabOrder = 0
    OnChange = ListView1Change
    OnDragDrop = ListView1DragDrop
    OnDragOver = ListView1DragOver
    OnSelectItem = ListView1SelectItem
    OnStartDrag = ListView1StartDrag
  end
  object RadioGroup1: TRadioGroup
    Left = 312
    Top = 24
    Width = 106
    Height = 113
    Caption = 'ViewStyle'
    Items.Strings = (
      'vsIcon'
      'vsList'
      'vsReport'
      'vsSmallIcon')
    TabOrder = 1
    OnClick = RadioGroup1Click
  end
  object RadioGroup2: TRadioGroup
    Left = 312
    Top = 143
    Width = 106
    Height = 66
    Caption = 'CheckBoxes'
    Items.Strings = (
      'true'
      'false')
    TabOrder = 2
    OnClick = RadioGroup2Click
  end
  object LabeledEdit1: TLabeledEdit
    Left = 8
    Top = 240
    Width = 121
    Height = 21
    EditLabel.Width = 24
    EditLabel.Height = 13
    EditLabel.Caption = #21517#21069
    TabOrder = 3
    OnChange = LabeledEdit1Change
  end
  object LabeledEdit2: TLabeledEdit
    Left = 135
    Top = 240
    Width = 153
    Height = 21
    EditLabel.Width = 24
    EditLabel.Height = 13
    EditLabel.Caption = #35443#32048
    TabOrder = 4
    OnChange = LabeledEdit1Change
  end
  object Button1: TButton
    Left = 294
    Top = 238
    Width = 49
    Height = 25
    Caption = #36861#21152
    Default = True
    TabOrder = 5
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 367
    Top = 238
    Width = 51
    Height = 25
    Caption = #21066#38500
    TabOrder = 6
    OnClick = Button2Click
  end
  object ImageList1: TImageList
    Height = 32
    Width = 32
    Left = 40
    Top = 40
    Bitmap = {
      〜略〜
      }
  end
  object ImageList2: TImageList
    Left = 104
    Top = 40
    Bitmap = {
      〜略〜
      }
  end
end

動作の仕様

  • 名前と詳細の2つの情報を持ったアイテムを表示する。
  • 名前と詳細を入力し追加ボタンを押すとアイテムが追加される。
  • 削除ボタンを押すと選択されたアイテムが削除される。
  • 表示スタイルをラジオボタンで設定する。
  • チェックボックスの有無をラジオボタンで設定する。
  • チェックを入れたらアイコンもチェック入りに変わる。

各動作の説明

表示スタイルの切替

//---------------------------------------------------------------------------
//                                                       ViewStyleの設定変更
void __fastcall TForm2::RadioGroup1Click(TObject *Sender)
{

    switch(RadioGroup1->ItemIndex) {
        case 1: // vsList
                ListView1->ViewStyle = vsList;
                break;
        case 2: // vsReport
                ListView1->ViewStyle = vsReport;
                break;
        case 3: // vsSmallIcon
                ListView1->ViewStyle = vsSmallIcon;
                break;
        case 0: // vsIcon
        default:
                ListView1->ViewStyle = vsIcon;
                RadioGroup1->ItemIndex = 0;
                break;
    }
}
//---------------------------------------------------------------------------

RadioGroup1のOnClickイベントに記述します。ラジオボタンの設定値によってListViewのViewStyleプロパティを設定。ラジオボタンがどれも設定されていない状態の場合は強制的にvsIconとしてます。

チェックボックスの表示

//---------------------------------------------------------------------------
//                                                      CheckBoxesの設定変更
void __fastcall TForm2::RadioGroup2Click(TObject *Sender)
{
    switch(RadioGroup2->ItemIndex) {
        case 0: // true
                ListView1->Checkboxes = true;
                break;
        case 1: // false
        default:
                ListView1->Checkboxes = false;
                RadioGroup2->ItemIndex = 1;
                break;
    }
}
//---------------------------------------------------------------------------

RadioGroup2のOnClickイベントに記述します。ラジオボタンの設定値によってListViewのCheckboxesプロパティを設定。どれも設定されていない場合はfalseとします。

追加ボタンのオンオフ

//---------------------------------------------------------------------------
//                                                      追加ボタンのオンオフ
void __fastcall TForm2::LabeledEdit1Change(TObject *Sender)
{
    Button1->Enabled = (LabeledEdit1->Text != "");
}
//---------------------------------------------------------------------------

LabeledEdit1およびLabeledEdit2のOnChangeイベントに記述します。名前欄に何か記述があれば追加ボタンを有効に。

アイテムの追加

//---------------------------------------------------------------------------
//                                                                項目の追加
void __fastcall TForm2::Button1Click(TObject *Sender)
{
    TListItem *item = ListView1->Items->Add();
    item->Caption = LabeledEdit1->Text;
    item->SubItems->Add(LabeledEdit2->Text);
    item->Checked = false;

    LabeledEdit1->Text = "";
    LabeledEdit2->Text = "";
}
//---------------------------------------------------------------------------

Button1のOnClickイベントに記述します。新しくアイテムを追加。1つめの項目はCaptionに直接代入。2つ目以上の項目はSubItemsに追加します。

削除ボタンのオンオフ

//---------------------------------------------------------------------------
//                                                      削除ボタンのオンオフ
void __fastcall TForm2::ListView1SelectItem(TObject *Sender, TListItem *Item,
      bool Selected)
{
    Button2->Enabled = (ListView1->SelCount > 0);
}
//---------------------------------------------------------------------------

ListView1のOnSelectItemイベントに記述します。アイテムが選択されていれば削除ボタンを有効に。

選択アイテムの削除

//---------------------------------------------------------------------------
//                                                        選択アイテムの削除
void __fastcall TForm2::Button2Click(TObject *Sender)
{
    TListItems *items = ListView1->Items;

    for(int i=0; i<items->Count;) {
        if (items->Item[i]->Selected) {
            items->Delete(i);
        } else {
            i++;
        }
    }
}
//---------------------------------------------------------------------------

Button2のOnClickイベントに記述します。総当りでアイテムの選択状態をチェックして、選択されているなら削除します。

チェック状態をアイコンに反映

//---------------------------------------------------------------------------
//                                            チェックの状態をアイコンに反映
void __fastcall TForm2::ListView1Change(TObject *Sender, TListItem *Item,
      TItemChange Change)
{
    Item->ImageIndex = (Item->Checked) ? 1 : 0;
}
//---------------------------------------------------------------------------

ListView1のOnChangeイベントに記述します。アイコンに変化があった場合にイベントが発生しますので、チェックの有無を見てアイコンを切り替えます。

ドラッグの開始

//---------------------------------------------------------------------------
//                                                        ドラッグ開始の処理
void __fastcall TForm2::ListView1StartDrag(TObject *Sender,
      TDragObject *&DragObject)
{
    ListView1->DragCursor = (ListView1->SelCount == 1) ? crDrag : crMultiDrag;
}
//---------------------------------------------------------------------------

一つ選択の場合と複数選択の場合でアイコンを切り替えてます。

ドラッグ中の処理

//---------------------------------------------------------------------------
//                                                          ドラッグ中の処理
void __fastcall TForm2::ListView1DragOver(TObject *Sender, TObject *Source,
      int X, int Y, TDragState State, bool &Accept)
{
    Accept = (Source == ListView1);

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

ListView1のOnDragOverイベントに記述します。ListView1からのドラッグであれば許可とし、上端・下端の場合はスクロールメッセージを発行します。

ドロップ時の処理

//---------------------------------------------------------------------------
//                                                          ドロップ時の処理
void __fastcall TForm2::ListView1DragDrop(TObject *Sender, TObject *Source,
      int X, int Y)
{
    TListItems *items = ListView1->Items;
    TListItem *toItem = ListView1->GetItemAt(X,Y);
    TListItem *fromItem = NULL;

    while(1) {
        int i;
        // 選択中のものを探す
        for(i=0; i<items->Count; i++) {
            if (items->Item[i]->Selected)  break;
        }

        // 選択中のものが見つからないなら終わり
        if (i == items->Count) break;

        fromItem = items->Item[i];

        // ドロップ先のアイテムの位置に新しくアイテムを生成
        TListItem *x = items->AddItem(NULL, items->IndexOf(toItem));

        // コピー元の選択状態を解除して新しいアイテムへコピー
        fromItem->Selected = false;
        x->Assign(fromItem);

        // コピー元を削除
        fromItem->Delete();

        // これを選択中のアイテムが無くなるまで繰り返す
    }
}
//---------------------------------------------------------------------------

ListView1のOnDragDropイベントに記述します。選択した(ドラッグ中の)アイテムをドロップ地点に挿入します。複数のアイテムを同時に移動しようとしてるのでちょっとややこしくなってます。

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

ListView

プロパティ名 説明
CheckBoxes リスト項目の横にチェックボックスを表示するか
Colums vsReport表示の時のヘッダーの設定
GridLines vsReport, vsList表示の時にグリッド線を表示するか
HideSelection フォーカスが他へ移動したときに選択状態を隠すかどうか
HotTrack マウスカーソルがアイテム上に来た時、それを表示するか
ItemIndex 選択されたアイテムの番号を返す。0〜
Items TListItemsオブジェクト。アイテムの情報を保持。
LargeImages アイコン表示するときの画像データ保持
MultiSelect 複数選択を許可するか
SelCount 選択されているアイテムの数
Selected 現在選択されているTListItemオブジェクト。
SmallImages スモールアイコン表示のときに使われる画像データを保持。
ViewStyle アイテムの表示方法を指定する。vsIcon, vsSmallIcon, vsList, vsReportから選択
メソッド名 説明
GetItemAt 座標(X,Y)にあるアイテムのTListItemオブジェクトポインタを返す
GetNearestItem 最も近いアイテムのTListItemオブジェクトポインタを返す。探索方向として、sdLeft(左), sdRight(右), sdAbove(上), sdBelow(下), sdAll(一番近い)から選択
Scroll リストビューを(DX,DY)だけスクロールさせる
StringWidth 指定文字列の表示に必要な幅を返す。カラム幅の調整などに利用可

ListItems

プロパティ名 説明
Count アイテム数
Item[n] n番目のアイテム(TListItemオブジェクト)
Owner 親となるリストビューを指す
メソッド名 説明
Add 新しいアイテムを追加する
AddItem 指定した位置にアイテムを追加する
Clear アイテムを全て削除
Delete 指定のアイテムを削除
Insert 指定アイテムの次に新アイテムを追加する

ListItem

プロパティ名 説明
Caption アイテムの名前
Checked チェックされているかどうか。
Cut アイコンを淡色で表示するかどうか
Data void*ポインタ。任意のデータを保持させることが可能
Forcused アイテムに入力フォーカスが指定されているかを示す。逆に設定も可能
ImageIndex イメージリストの中のどの画像を表示するか
Index このアイテムが何番目の項目なのか
Selected 選択されているか
SubItems 詳細項目の保持。TStringオブジェクト
メソッド名 説明
Assign 別のアイテムからプロパティをコピーする
Delete アイテムを削除する
MakeVisible 指定アイテムが見える位置に来るように強制スクロールする

サンプルソース

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

参考図書

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

2007-03-03 komina