今回は、リストビューをダブルクリック(もしくは、リストを選択)すると、そのデータを取得して、 ダイアログを表示するようにします。
リストビュー1 - インコのWindowsSDK で作成したソースを修正します。
流れ
WM_NOTIFY
WM_NOTIFYメッセージを取得します。
項目を選択したときに発生する LVN_ITEMCHANGEDメッセージか、 項目をダブルクリックしたときに発生する NM_DBLCLKメッセージ を取得します。
1.GetCursorPos()でマウスカーソルの位置を取得。
BOOL GetCursorPos( LPPOINT lpPoint // カーソルの位置 );
LV_HITTESTINFO構造体のメンバptにカーソルの位置が格納されています。
typedef struct tagLVHITTESTINFO{ POINT pt; // カーソルの位置 UINT flags; int iItem; // アイテム int iSubItem; // サブアイテム } LVHITTESTINFO, FAR* LPLVHITTESTINFO;
flags | データを取得できる場所 |
LVHT_ONITEMICON | リストビューアイコンの上 |
LVHT_ONITEMLABEL | リストビュー文字列の上 |
LVHT_ONITEMSTATEICON | リストビューイメージの上 |
LVHT_ONITEM | (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON) |
2.ScreenToClient()で、スクリーン座標から、指定されたウィンドウのクライアント座標に変換します。
BOOL ScreenToClient( HWND hwnd, // ウィンドウハンドル PPOINT ppt // スクリーン座標 );
3.ListView_SetImageList()で、リストビューのアイテムを取得。
HIMAGELIST ListView_SetImageList( HWND hwnd, // リストビューのハンドル HIMAGELIST himl, // リストビューに関連付けるイメージリストのハンドル int iImageList // LV_HITTESTINFO構造体のポインタ );
ListView_SetImageList()の代わりに、LVM_HITTESTメッセージでも、リストビューのアイテムを取得することができます。
lResult = SendMessage( (HWND) hWndControl, // リストビューのハンドル (UINT) LVM_HITTEST, 0, // 0固定 (LPARAM) lParam // LV_HITTESTINFO構造体のポインタ );
4.クリックされた場所が、指定された場所(ここでは、LVHT_ONITEM)ならば、 LVITEM構造体から データを取得。
5.ListView_GetItem()で、リストビューのデータを取得。
BOOL ListView_GetItem( HWND hwnd, // リストビューのハンドル LVITEM FAR* pitem // LV_HITTESTINFO構造体のポインタ );
ソースコードの入力
ソースコードは下記のように入れてください。
#include <windows.h> #include <commctrl.h> #include "resource.h" #pragma comment(lib, "comctl32.lib") #define T_BUFFER 128 // リストビューのテキストバッファ LPTSTR strItem0[] = { TEXT("TILTE1"), TEXT("TILTE2") }; int CX[] = { 80, 160 }; LPTSTR strItem1[] = { TEXT("LIST11"), TEXT("LIST12") }; LPTSTR strItem2[] = { TEXT("LIST21"), TEXT("LIST22") }; // このコード モジュールに含まれる関数の宣言を転送します: BOOL CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow ) { DialogBox(hInstance, TEXT("DIALOG_BOX"), NULL, DialogProc); return 0; } BOOL CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { LVCOLUMN lvcol; LVITEM item; UINT i; static HWND hList; LV_HITTESTINFO lvinfo; TCHAR buf[T_BUFFER]; switch (msg) { case WM_INITDIALOG: InitCommonControls(); hList = GetDlgItem(hWnd, IDC_LIST1); lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvcol.fmt = LVCFMT_LEFT; for(i = 0; i < 2; i++) { lvcol.cx = CX[i]; // 表示位置 lvcol.pszText = strItem0[i]; // 見出し lvcol.iSubItem = i; // サブアイテムの番号 ListView_InsertColumn(hList, i, &lvcol); } item.mask = LVIF_TEXT; for(i = 0; i < 2; i++) { item.pszText = strItem1[i]; // テキスト item.iItem = i; // 番号 item.iSubItem = 0; // サブアイテムの番号 ListView_InsertItem(hList, &item); item.pszText = strItem2[i]; // テキスト item.iItem = i; // 番号 item.iSubItem = 1; // サブアイテムの番号 ListView_SetItem(hList, &item); } break; case WM_NOTIFY: switch(((LPNMHDR)lParam)->idFrom) { case IDC_LIST1: switch (((LPNMLISTVIEW)lParam)->hdr.code) { // case LVN_ITEMCHANGED: // 項目を選択 case NM_DBLCLK: // 項目をダブルクリック GetCursorPos((LPPOINT)&lvinfo.pt); ScreenToClient(((LPNMLISTVIEW)lParam)->hdr.hwndFrom, &lvinfo.pt); ListView_HitTest(((LPNMLISTVIEW)lParam)->hdr.hwndFrom, &lvinfo); if ((lvinfo.flags & LVHT_ONITEM) != 0) { item.mask = TVIF_HANDLE | TVIF_TEXT; item.iItem = lvinfo.iItem; item.iSubItem = 0; //取得するサブアイテムの番号 item.pszText = buf; //格納するテキストバッファ item.cchTextMax = T_BUFFER; //バッファ容量 ListView_GetItem(((LPNMLISTVIEW)lParam)->hdr.hwndFrom, &item); MessageBox(hWnd, buf, TEXT("選択したデータ"), MB_OK); } break; } break; default: break; } break; case WM_CLOSE: EndDialog(hWnd, IDOK); break; default: break; } return FALSE; }
#define IDC_LIST1 400 #ifndef IDC_STATIC #define IDC_STATIC -1 #endif
Reseditで作成した場合は、これとは異なるソースコードになります。
上記の太線で示している箇所のみ追加です。
#include <windows.h> #include <commctrl.h> #include "resource.h" ///////////////////////////////////////////////////////////////////////////// // // ダイアログ // DIALOG_BOX DIALOG 0, 0, 170, 62 FONT 9, "MS UI Gothic" CAPTION "ダイアログ" BEGIN CONTROL "", IDC_LIST1, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_ICON, 2, 2, 166, 58 END
Reseditで作成した場合は、これとは異なるソースコードになります。
上記の太線で示している箇所のみ追加です。