ツリービューを作成してみる ACT-2

今回はツリービューコントロールのアイテムの削除や、現在選択されているアイテムの取得を行なってみましょう。

選択されているアイテムの取得

ツリービューで現在選択されているアイテムを取得するには、ツリービューに TVM_GETNEXTITEM メッセージを送信します。

#define  TVM_GETNEXTITEM     0x110A

TVM_GETNEXTITEM
    wParam = flag;
    lParam = hitem;

このメッセージは、指定されたアイテムに対して、指定された関係を持っているアイテムを取得するためのもので、例えば、このメッセージを繰り返し送信することで、リストビューコントロールが持つすべてのアイテムを取得することなどもできるようになっています。

flag パラメータには、hitem パラメータで指定されるアイテムとどのようなアイテムを取得するのかを指定します。今回は選択されているアイテムを取得するので、 9 (TVGN_CARET) を指定します。

hitem パラメータにはアイテムハンドルを指定するのですが、選択されているアイテムを取得する場合には 0 (NULL) を指定しておきます。

アイテムの削除

ツリービューが持つアイテムを削除するには、ツリービューに TVM_DELETEITEM メッセージを送信します。

#define  TVM_DELETEITEM    0x1101

TVM_DELETEITEM
    wParam = 0;
    lParam = hitem;

hitem パラメータには、削除するアイテムのハンドルを指定します。このとき、指定されたアイテムが持っている子アイテムもすべて削除されます。また、このパラメータに 0xFFFF0000 (TVI_ROOT) を指定すると、ツリービューが持つすべてのアイテムが削除されます。

サンプルスクリプト

さて、実際にスクリプトを書いてみます。今回使用する画像は前回と同じものです。

(treeicon.bmp)

ビットマップファイルのダウンロード

サンプルスクリプト main.as

    #include "llmod.as"

    #module ;###### ビットマップオブジェクト作成モジュール #########

    ;===============================================================
    ; 描画中ウィンドウのイメージからビットマップオブジェクト(DIB)作成
    ; CreateDIB  p1, p2, p3, p4
    ;     p1 : HSPウィンドウx座標
    ;     p2 : HSPウィンドウy座標
    ;     p3 : 幅
    ;     p4 : 高さ
    ;   stat : ビットマップのハンドルが返る
    ;===============================================================
    #deffunc CreateDIB int, int, int, int
    mref px, 0              ; HSPウィンドウx座標
    mref py, 1              ; HSPウィンドウy座標
    mref sx, 2              ; xサイズ
    mref sy, 3              ; yサイズ
    mref stt, 64            ; stat
    mref bmscr, 67          ; 描画中ウィンドウのBMSCR構造体

    ; DIBセクションオブジェクト作成
    pm = bmscr.4, sx, sy
    dllproc "CreateCompatibleBitmap", pm, 3, D_GDI@
    hbitmap = stat          ; ビットマップオブジェクトのハンドル

    ; メモリデバイスコンテキスト作成
    pm = bmscr.4
    dllproc "CreateCompatibleDC", pm, 1, D_GDI@
    hdcMemory = stat        ; メモリデバイスコンテキストのハンドル

    ; ビットマップをデバイスコンテキストに選択
    pm = hdcMemory, hbitmap
    dllproc "SelectObject", pm, 2, D_GDI@

    ; HSPウィンドウからビットマップにイメージをコピー
    pm = hdcMemory, 0, 0, sx, sy, bmscr.4, px, py, $CC0020
    dllproc "BitBlt", pm, 9, D_GDI@

    ; デバイスコンテキストを削除
    dllproc "DeleteDC", hdcMemory, 1, D_GDI@

    stt = hbitmap           ; ビットマップオブジェクトのハンドル
    return

    #global ;############# モジュール終わり ########################

    #module ;######### イメージリスト操作モジュール ################

    ;===============================================================
    ; イメージリストの作成
    ; CreateImageList  p1, p2, p3, p4
    ;     p1 : イメージの幅
    ;     p2 : イメージの高さ
    ;     p3 : イメージリストのタイプ
    ;     p4 : イメージの数
    ;   stat : イメージリストのハンドルが返る
    ;===============================================================
    #deffunc CreateImageList int, int, int, int
    mref sx, 0              ; イメージの幅
    mref sy, 1              ; イメージの高さ
    mref flags, 2           ; イメージリストのタイプ
    mref num, 3             ; イメージの数

    ; イメージリストの作成
    pm.0 = sx
    pm.1 = sy
    pm.2 = flags
    pm.3 = num
    pm.4 = 0
    dllproc "ImageList_Create", pm, 5, D_COMCTL@
    return

    ;===============================================================
    ; イメージリストに描画中ウィンドウのイメージ追加
    ; AddImageList  p1, p2, p3, p4, p5
    ;     p1 : イメージリストのハンドル
    ;     p2 : HSPウィンドウx座標
    ;     p3 : HSPウィンドウy座標
    ;     p4 : 幅
    ;     p5 : 高さ
    ;     p6 : マスクに用いる色
    ;   stat : イメージのインデックスが返る
    ;===============================================================
    #deffunc AddImageList int, int, int, int, int, int
    mref himl, 0            ; イメージリストのハンドル
    mref cx, 1              ; x座標
    mref cy, 2              ; y座標
    mref sx, 3              ; xサイズ
    mref sy, 4              ; yサイズ
    mref crmask, 5          ; マスク生成に用いる色
    mref stt, 64            ; stat

    ; DIBオブジェクトの作成
    CreateDIB  cx, cy, sx, sy
    hbitmap = stat          ; ビットマップハンドル

    ; ビットマップをイメージリストに追加
    pm.0 = himl
    pm.1 = hbitmap
    pm.2 = crmask
    dllproc "ImageList_AddMasked", pm, 3, D_COMCTL@
    index = stat            ; 最初のイメージのインデックス

    ; ビットマップオブジェクトを削除
    dllproc "DeleteObject", hbitmap, 1, D_GDI@

    stt = index             ; イメージのインデックスをstatに格納
    return

    ;===============================================================
    ; イメージリストの破棄
    ; DestroyImageList  p1
    ;     p1 : イメージリストのハンドル
    ;===============================================================
    #deffunc DestroyImageList int
    mref himl, 0            ; イメージリストのハンドル

    ; イメージリストを破棄
    pm.0 = himl
    dllproc "ImageList_Destroy", pm, 1, D_COMCTL@
    return

    #global ;############# モジュール終わり ########################

    #module ;########### ツリービュー操作モジュール ##################

    ;===============================================================
    ; 描画中ウィンドウにツリービュー作成
    ; CreateTreeView  p1, p2, p3, p4
    ;     p1 : x座標
    ;     p2 : y座標
    ;     p3 : 幅
    ;     p4 : 高さ
    ;   stat : ツリービューのハンドルが返る
    ;===============================================================
    #deffunc CreateTreeView int, int, int, int
    mref cx, 0              ; x
    mref cy, 1              ; y
    mref sx, 2              ; 幅
    mref sy, 3              ; 高さ
    mref stt, 64            ; stat

    ; コモンコントロールライブラリ初期化
    dllproc "InitCommonControls", pm, 0, D_COMCTL@

    ; ツリービュー作成
    pm = cx, cy, sx, sy     ; 座標、サイズ
    pm.4 = 0x50800007       ; WS_VISIBLE | WS_BORDER | WS_CHILD
                            ;  | TVS_HASBUTTONS | TVS_HASLINES
                            ;  | TVS_LINESATROOT
    pm.5 = 0, 0
    _makewnd pm, "SysTreeView32"
    stt = pm                ; ツリービューのハンドル
    return

    ;===============================================================
    ; ツリービューにイメージリストを設定
    ; SetTreeImageList  p1, p2
    ;     p1 : ツリービューのハンドル
    ;     p2 : イメージリストのハンドル
    ;===============================================================
    #deffunc SetTreeImageList  int, int
    mref hTree, 0           ; ツリービューのハンドル
    mref himl, 1            ; イメージリストのハンドル

    ; TVM_SETIMAGELIST メッセージ送信
    pm = hTree, 0x1109, 0, himl
    sendmsg pm
    return

    ;===============================================================
    ; ツリービューにアイテム追加
    ; AddTreeItem  p1, p2, p3, p4, p5
    ;     p1 : ツリービューのハンドル
    ;     p2 : 表示するテキスト
    ;     p3 : イメージのインデックス
    ;     p4 : 親アイテムのハンドル
    ;     p5 : 挿入位置のアイテムハンドルまたは以下の値
    ;          $FFFF0001 : リストの最初の位置
    ;          $FFFF0002 : リストの最後の位置
    ;          $FFFF0003 : リストをアルファベット順にソート
    ;===============================================================
    #deffunc AddTreeItem  int, str, int, int, int
    mref hTree, 0           ; ツリービューのハンドル
    mref setText, 33        ; 表示するテキスト
    mref iImage, 2          ; イメージのインデックス
    mref hParent, 3         ; 親アイテムのハンドル
    mref hIns, 4            ; 挿入位置のアイテムハンドル

    dim bufText, 256
    bufText = setText           ; いったん別の変数に移しておく

    ; TVINSERTSTRUCT 構造体
    dim tvins, 12
    tvins.0 = hParent           ; 親アイテムのハンドル
    tvins.1 = hIns              ; 挿入位置のアイテムハンドル
    tvins.2 = 0x0023            ; TVIF_TEXT | TVIF_IMAGE
                                ;  | TVIF_SELECTEDIMAGE
    getptr tvins.6, bufText     ; 文字列のアドレス
    tvins.8 = iImage            ; イメージインデックス(非選択時)
    tvins.9 = iImage            ; イメージインデックス(選択時)

    ; TVM_INSERTITEM メッセージ送信
    pm = hTree, 0x1100, 0
    getptr pm.3, tvins
    sendmsg pm
    return

    ;===============================================================
    ; 選択されているツリービューアイテムを取得
    ; GetSelTreeItem  p1
    ;     p1 : ツリービューのハンドル
    ;   stat : 選択されているアイテムのハンドルが返る
    ;===============================================================
    #deffunc GetSelTreeItem  int
    mref hTree, 0           ; ツリービューのハンドル

    ; TVM_GETNEXTITEM メッセージ送信
    pm = hTree, 0x110A, 9, 0          ; TVGN_CARET
    sendmsg pm
    return

    ;===============================================================
    ; ツリービューアイテムを削除
    ; DelTreeItem  p1
    ;     p1 : ツリービューのハンドル
    ;     p2 : アイテムハンドル
    ;===============================================================
    #deffunc DelTreeItem  int, int
    mref hTree, 0           ; ツリービューのハンドル
    mref hitem, 1           ; アイテムのハンドル

    ; TVM_DELETEITEM メッセージ送信
    pm = hTree, 0x1101, 0, hitem
    sendmsg pm
    return

    #global ;############# モジュール終わり ########################


    objsize winx/2, 24
    button "子アイテム追加", *lb_additem        ; Object ID=0
    pos winx/2, 0
    button "ルートアイテム追加", *lb_additem    ; Object ID=1
    pos 0, 24
    button "アイテム削除", *lb_deleteitem       ; Object ID=2
    pos winx/2, 24
    button "全アイテム削除", *lb_deleteitem     ; Object ID=3


    ; イメージリスト作成 (16×16×4, 24bit, マスクあり)
    CreateImageList 16, 16, 25, 4
    himl = stat                 ; イメージリストのハンドル

    ; イメージリスト作成用バッファウィンドウ
    buffer 2,,,0
    picload "treeicon.bmp"      ; ビットマップの読み込み

    ; イメージリストにイメージを追加
    AddImageList himl, 0, 0, 16*4, 16, 0x00F0CAA6

    ; ツリービュー作成
    gsel 0
    CreateTreeView  0, 48, winx, winy-48
    hTree = stat                ; ツリービューのハンドル

    ; ツリービューのイメージリストを設定
    SetTreeImageList hTree, himl

    stop

*lb_additem
    if stat == 0 {
        ; 子アイテム追加
        ; 選択アイテム取得
        GetSelTreeItem hTree
        hitem = stat
    } else {
        ; ルートアイテム追加
        hitem = 0
    }
    screen 3, 200, 150
    title "アイテム追加"
    sdim itemtext, 260
    pos 10, 10 : mes "アイテム文字列"
    input itemtext, 160
    pos 10, 60 : mes "イメージインデックス"
    combox imgidx,, "0\n1\n2\n3"
    pos 30, 120 : button "OK", *lb_ok
    pos 120, 120 : button "Cansel", *lb_cansel
    stop

*lb_ok
    ; ツリービューのアイテム追加
    AddTreeItem  hTree, itemtext, imgidx, hitem, $FFFF0002

*lb_cansel
    gsel 3, -1
    stop

*lb_deleteitem
    if stat == 2 {
        ; ツリービューのアイテム削除
        ; 選択アイテム取得
        GetSelTreeItem hTree
        hitem = stat
    } else {
        ; ツリービューの全アイテム削除
        hitem = $FFFF0000             ; TVI_ROOT
    }
    DelTreeItem hitem
    stop