前回はリストビューの作成と、アイテムの追加についてを説明しました。今回は、作成されたリストビューからアイテムの内容を取得して、それを表示できるようにしてみましょう。また、アイテムの削除についてや、アイテムを検索する方法についてもやってみます。
リストビューのアイテムの内容を取得するには、 LVITEM 構造体に必要な情報を格納しておいてから、その構造体のアドレスをパラメータとしてリストビューに LVM_GETITEM メッセージを送信します。
前回も示しましたが、 LVITEM 構造体は以下のように定義されています。
typedef struct _LVITEM { UINT mask; // 有効メンバを示すフラグ int iItem; // アイテムのインデックス int iSubItem; // サブアイテムインデックス UINT state; // アイテムの状態・イメージ UINT stateMask; // state のフラグ LPTSTR pszText; // アイテムの文字列 int cchTextMax; // pszTextのサイズ int iImage; // イメージのインデックス LPARAM lParam; // アイテムの持つ32ビット値 } LVITEM, FAR *LPLVITEM;
mask メンバは、この構造体の有効メンバを示すフラグです。アイテム(またはサブアイテム)の文字列を取得したい場合は 0x0001 (LVIF_TEXT) を指定しておきます。 0x0008 (LVIF_STATE) を指定すると、アイテムの状態を取得することもできます。これらのフラグは値を組み合わせて指定します。
iItem メンバには、状態を取得したいアイテムの位置のインデックスを指定します。
iSubItem メンバには、アイテムの文字列(1列目のカラムの文字列)や状態を取得する場合には 0 を指定します。また、サブアイテムの文字列(2列目以降のカラムの文字列)を取得したい場合には、 1 以降のサブアイテムのインデックスを指定します。
mask メンバで 0x0001 (LVIF_TEXT) を指定した場合は、pszText メンバに取得した文字列を格納するバッファのアドレスを、 cchTextMax メンバにはそのバッファのサイズを格納しておかなければなりません。
LVITEM 構造体に必要な情報を格納したら、リストビューに LVM_GETITEM メッセージを送信します。
#define LVM_GETITEM 0x1005 LVM_GETITEM wParam = 0; lParam = pitem;
pitem パラメータには、情報を格納した LVITEM 構造体のアドレスを指定します。情報の取得が成功すると、 LVITEM 構造体のそれぞれのメンバに情報が格納され、戻り値として 0 以外の値が返ります。情報の取得に失敗した場合は 0 が返ります。
次は、アイテムを削除する方法です。
アイテムを削除するには、リストビューに LVM_DELETEITEM メッセージを送信します。
#define LVM_DELETEITEM 0x1008 LVM_DELETEITEM wParam = iItem; lParam = 0;
iItem パラメータには、削除するアイテムのインデックスを指定します。削除に成功すると、戻り値として 0 以外の値が、失敗すると 0 が返ります。
最後に、アイテムを検索する方法です。
アイテムを検索するのには2つのタイプがあり、それによって検索の方法も異なってきます。
まず、特殊な状態を持つアイテムを検索する場合についてです。
特殊な状態を持つアイテムを検索するには、リストビューに LVM_GETNEXTITEM メッセージを送ります。
#define LVM_GETNEXTITEM 0x100C LVM_GETNEXTITEM wParam = iStart; lParam = flags;
iStart パラメータには、検索を開始するアイテムのインデックスを指定します。指定されたアイテム自身は検索の対象にはなりません。リストの最初から検索をする場合には -1 を指定します。
flags パラメータには、検索する方向と、どの状態のアイテムを検索するのかを示すフラグを指定します。これは以下の値になります。
値 | 意味 |
---|---|
0x0000 (LVNI_ALL) | 指定されたアイテムの後に続くアイテムを検索します。(デフォルト) |
0x0001 (LVNI_FOCUSED) | フォーカスを持つアイテムを検索します。 |
0x0002 (LVNI_SELECTED) | 選択されているアイテムを検索します。 |
0x0004 (LVNI_CUT) | カット・アンド・ペーストの対象としてマークされているアイテムを検索します。 |
0x0008 (LVNI_DROPHILITED) | ドラッグ・アンド・ドロップのターゲットとしてハイライト表示されているアイテムを検索します。 |
0x0100 (LVNI_ABOVE) | 指定されたアイテムの上にあるアイテムを検索します。 |
0x0200 (LVNI_BELOW) | 指定されたアイテムの下にあるアイテムを検索します。 |
0x0400 (LVNI_TOLEFT) | 指定されたアイテムの左にあるアイテムを検索します。 |
0x0800 (LVNI_TORIGHT) | 指定されたアイテムの右にあるアイテムを検索します。 |
該当するアイテムがあった場合、戻り値としてそのアイテムのインデックスが返ります。該当するアイテムがなかった場合は、-1 が返ります。
次に、指定された文字列を持つアイテムなどを検索する場合についてです。
この場合、 LVFINDINFO 構造体に検索のための情報を格納した上で、その構造体のアドレスをパラメータとして、リストビューに LVM_FINDITEM メッセージを送ります。
typedef struct tagLVFINDINFO { UINT flags; // 検索のタイプを示すフラグ LPCTSTR psz; // 文字列のアドレス LPRARAM lParam; // アイテムの持つ32ビット値 POINT pt; // アイテムの位置 UINT vkDirection; // 検索方向を示す仮想キーコード } LVFINDINFO, FAR* LPFINDINFO;
この構造体についての説明はここでは省きます。
#define LVM_FINDITEM 0x100D LVM_FINDITEM wParam = iStart; lParam = plvfi;
iStart パラメータには、検索を開始するアイテムのインデックスを指定します。指定されたアイテム自身は検索の対象にはなりません。リストの最初から検索をする場合には -1 を指定します。
plvfi パラメータには、検索に必要な情報を格納した LVFINDINFO 構造体のアドレスを指定します。
該当するアイテムが見つかった場合、戻り値としてそのアイテムのインデックスが返ります。該当するアイテムが見つからなかった場合は、-1 が返ります。
さて、実際にスクリプトを書いてみることにしましょう。
前回のスクリプトに、アイテム文字列取得・アイテム削除・選択アイテム取得のためのモジュール命令が追加されています。
このスクリプトでは、マウスクリックなどによって選択されたアイテムの情報表示や削除を行なっています。[Alt]キーや[Shift]キーなどを押しながら選ぶことによって複数のアイテムが同時に選択された場合でも対応できるようにしてあります。
#include "llmod.as" #module ;============= リストビュー操作モジュール =============== ;---------------------------------------------------------------- ; CreateListView リストビュー作成 ;---------------------------------------------------------------- #deffunc CreateListView int, int, int, int mref cx, 0 ; x座標 mref cy, 1 ; y座標 mref sx, 2 ; 幅 mref sy, 3 ; 高さ mref bmscr, 67 ; 描画中ウィンドウのBMSCR構造体 mref stt, 64 ; stat ; コモンコントロールライブラリ初期化 dllproc "InitCommonControls", pm, 0, D_COMCTL@ ; リストビューコントロールの作成 pm.0 = cx, cy, sx, sy ; 座標、サイズ pm.4 = 0x50000001 ; WS_VISIBLE | WS_CHILD | LVS_REPORT pm.5 = 0 ; 親ウィンドウ(0のとき描画中ウィンドウ) pm.6 = 0 ; 拡張スタイル _makewnd pm, "SysListView32" stt = pm.0 ; stat にリストビューのハンドルを格納 return ;---------------------------------------------------------------- ; AddListColumn リストビューにカラムを追加 ;---------------------------------------------------------------- #deffunc AddListColumn str, int, int, int, int mref setText, 32 ; ヘッダ文字列 mref hList, 1 ; リストビューのハンドル mref index, 2 ; カラムのインデックス mref alm, 3 ; 配置(0:左 1:右 2:中央) mref wid, 4 ; カラムの幅 sdim szText, 256 szText = setText ; いったん別の変数に移しておく ; LVCOLUMN 構造体 lvcolumn.0 = 0x000F ; LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ; | LVCF_SUBITEM lvcolumn.1 = alm lvcolumn.2 = wid getptr lvcolumn.3, szText lvcolumn.4 = 0 lvcolumn.5 = index ; LVM_INSERTCOLUMN メッセージ送信 pm = hList, 0x101B, index getptr pm.3, lvcolumn sendmsg pm return ;---------------------------------------------------------------- ; AddListItem リストビューにアイテム追加 ;---------------------------------------------------------------- #deffunc AddListItem str, int, int mref setText, 32 ; 文字列 mref hList, 1 ; リストビューのハンドル mref index, 2 ; アイテムのインデックス sdim szText, 256 szText = setText ; いったん別の変数に移しておく ; LVITEM 構造体 lvitem.0 = 0x0001 ; LVIF_TEXT lvitem.1 = index ; インデックス lvitem.2 = 0 getptr lvitem.5, szText ; LVM_INSERTITEM メッセージ送信 pm = hList, 0x1007, 0 getptr pm.3, lvitem sendmsg pm return ;---------------------------------------------------------------- ; SetListItem リストビューのサブアイテム設定 ;---------------------------------------------------------------- #deffunc SetListItem str, int, int, int mref setText, 32 ; サブアイテム文字列 mref hList, 1 ; リストビューのハンドル mref index, 2 ; アイテムのインデックス mref indexsub, 3 ; サブアイテムのインデックス sdim szText, 256 szText = setText ; いったん別の変数に移しておく ; LVITEM 構造体 lvitem.0 = 0x0001 ; LVIF_TEXT lvitem.1 = index ; インデックス lvitem.2 = indexsub getptr lvitem.5, szText ; LVM_SETITEM メッセージ送信 pm = hList, 0x1006, 0 getptr pm.3, lvitem sendmsg pm return ;================================================================ ; GetListItem リストビューアイテムの文字列取得 ;================================================================ #deffunc GetListItem val, int, int, int, int mref retText, 24 ; 取得文字列を格納する文字列変数 mref hList, 1 ; リストビューのハンドル mref index, 2 ; アイテムのインデックス mref indexsub, 3 ; サブアイテムのインデックス mref cch, 4 ; バッファサイズ ; LVITEM 構造体 lvitem.0 = 0x0001 ; LVIF_TEXT lvitem.1 = index ; アイテムのインデックス lvitem.2 = indexsub ; サブアイテムインデックス getptr lvitem.5, retText ; バッファのアドレス lvitem.6 = cch ; バッファのサイズ ; LVM_GETITEM メッセージ送信 pm = hList, 0x1005, 0 getptr pm.3, lvitem sendmsg pm return ;================================================================ ; DelListItem リストビューアイテムの削除 ;================================================================ #deffunc DelListItem int, int mref hList, 0 ; リストビューのハンドル mref index, 1 ; アイテムのインデックス ; LVM_DELETEITEM メッセージ送信 pm = hList, 0x1008, index, 0 sendmsg pm return ;================================================================ ; GetSelListItem 選択されているリストアイテムの取得 ;================================================================ #deffunc FindSelListItem int, int mref hList, 0 ; リストビューのハンドル mref index, 1 ; アイテムのインデックス ; LVM_GETNEXTITEM メッセージ送信 pm = hList, 0x100C pm.2 = index ; 検索開始インデックス pm.3 = 0x0002 ; LVNI_ALL | LVNI_SELECTED sendmsg pm return #global ;================= モジュール終わり ===================== objsize winx/2, 25 : objmode 1 pos 0, 0 : button "選択アイテムの情報表示", *lb_mesitem pos winx/2, 0 : button "選択アイテム削除", *lb_delitem CreateListView 0, 25, winx, winy-25 hList = stat AddListColumn "名前", hList, 0, 0, 100 AddListColumn "読み", hList, 1, 0, 100 AddListItem "在原業平", hList, 0 SetListItem "ありわらのなりひら", hList, 0, 1 AddListItem "僧正遍昭", hList, 1 SetListItem "そうじょうへんじょう", hList, 1, 1 AddListItem "喜撰法師", hList, 2 SetListItem "きせんほうし", hList, 2, 1 AddListItem "大伴黒主", hList, 3 SetListItem "おおとものくろぬし", hList, 3, 1 AddListItem "文屋康秀", hList, 4 SetListItem "ふんやのやすひで", hList, 4, 1 AddListItem "小野小町", hList, 5 SetListItem "おののこまち", hList, 5, 1 stop *lb_mesitem ; 選択されているアイテムの情報を表示 sdim buf1, 256 ; アイテムの文字列を格納する変数 sdim buf2, 256 ; サブアイテムの文字列を格納する変数 ; 複数のアイテムが選択されている場合に対応 idx = -1 repeat FindSelListItem hList, idx idx = stat if idx == -1 : break GetListItem buf1, hList, idx, 0, 128 GetListItem buf2, hList, idx, 1, 128 buf1 += "\n"+buf2 dialog buf1, 0, "情報表示" loop stop *lb_delitem ; 選択されているアイテムをリストビューから削除 ; 複数のアイテムが選択されている場合に対応 idx = -1 repeat FindSelListItem hList, idx idx = stat if idx == -1 : break DelListItem hList, idx idx-- ; アイテム削除によるインデックスのずれを補正 loop stop