第198章 リストビューの拡張スタイル


IEの更新によりリストビューのスタイルも拡張されました。

リストビューについて忘れてしまった人は 第106章第110章を 復習しておいて下さい。



左の図のようにグリッドラインを入れることができます。
また、1行選択をしたり、チェックボックスをつけることができます。
さらに、ヘッダー部分をドラッグして列の順番を変更することもできます。



今回使用する拡張スタイルは
LVS_EX_CHECKBOXESチェックボックスをつけます
LVS_EX_FULLROWSELECT1行選択を可能にします
LVS_EX_GRIDLINESグリッド線を入れます
LVS_EX_HEADERDRAGDROPヘッダをドラッグ&ドロップ可能にします
上のいずれもComctl32.dllのバージョンが4.70以降であることが必要です。

CreateWindowEx関数で拡張スタイルを加えても無効です。 一旦従来のスタイルでリストビューを作って、その後拡張スタイルを加えます。 またこの時GetWindowLong関数を使って拡張スタイルの変更はできません。 ListView_GetExtendedListViewStyleや、ListView_SetExtendedListViewStyleマクロを使います。

DWORD ListView_GetExtendedListViewStyle( HWND hwndLV );

リストビューの拡張スタイルを取得します。hwndLVはリストビューのハンドルです。

void ListView_SetExtendedListViewStyle( HWND hwndLV, DWORD dwExStyle );

リストビューに拡張スタイルをセットします。
hwndLVリストビューのハンドルです。
dwExStyleセットされる拡張スタイルです。

では、プログラムを見てみましょう。

// newlist1.cpp #ifndef STRICT #define STRICT #endif #include <windows.h> #include <commctrl.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); HWND MakeMyList(HWND); void InsertMyColumn(HWND); void InsertMyItem(HWND); char szClassName[] = "newlist1"; //ウィンドウクラス HINSTANCE hInst;

いつもと変わり映えしません。コモンコントロールの準備を 忘れないでください。

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; hInst = hCurInst; if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //ウィンドウ・クラスの登録 ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; //プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst;//インスタンス wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; //メニュー名 wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, "猫でもわかるListView", //タイトルバーにこの名前が表示されます WS_OVERLAPPEDWINDOW, //ウィンドウの種類 CW_USEDEFAULT, //X座標 CW_USEDEFAULT, //Y座標 CW_USEDEFAULT, //幅 CW_USEDEFAULT, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドル、クラスメニューを使うときはNULL hInst, //インスタンスハンドル NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }

このへんはいつもと同じです。

//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; INITCOMMONCONTROLSEX ic; static HWND hList; RECT rc; switch (msg) { case WM_CREATE: ic.dwSize = sizeof(INITCOMMONCONTROLSEX); ic.dwICC = ICC_LISTVIEW_CLASSES; InitCommonControlsEx(&ic); hList = MakeMyList(hWnd); InsertMyColumn(hList); InsertMyItem(hList); break; case WM_SIZE: GetClientRect(hWnd, &rc); MoveWindow(hList, 0, 0, rc.right - rc.left, rc.bottom - rc.top, TRUE); break; case WM_CLOSE: id = MessageBox(hWnd, "終了してもよいですか", "終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { if (DestroyWindow(hList) == 0) MessageBox(hWnd, "ListView破棄失敗", "Error", MB_OK); DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

WM_CREATEが来たらコモンコントロールを初期化して リストビューを作り、リストビューにアイテムを追加します。

WM_SIZEメッセージが来たらリストビューを親のクライアント領域の 大きさに合わせます。

今回はプログラム終了時にリストビューをDestroyWindowしていますが 親が破棄されると自動的に子供も破棄されるので省略してもよいです。

HWND MakeMyList(HWND hWnd) { HWND hList; DWORD dwStyle; hList = CreateWindowEx(0, WC_LISTVIEW, "", WS_CHILD | WS_VISIBLE | LVS_REPORT, 0, 0, 0, 0, hWnd, (HMENU)100, hInst, NULL); dwStyle = ListView_GetExtendedListViewStyle(hList); dwStyle |= LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP; ListView_SetExtendedListViewStyle(hList, dwStyle); return hList; }

リストビューを作る関数です。

まず、大きさ0のリストビューを作り、拡張スタイルを 取得します。取得した拡張スタイルに今回付け加えたい スタイルを加えます。 リストビューに拡張スタイルをセットします。

ポイントは最初にも書いたようにCreateWindowEx関数で 拡張スタイルを指定しても無視される点です。 さらに、GetWindowLong関数では拡張スタイルを取得したり セットできない点です。

void InsertMyColumn(HWND hList) { LV_COLUMN lvcol; lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvcol.fmt = LVCFMT_LEFT; lvcol.cx = 100; lvcol.pszText = "名前"; lvcol.iSubItem = 0; ListView_InsertColumn(hList, 0, &lvcol); lvcol.cx = 50; lvcol.pszText = "性別"; lvcol.iSubItem = 1; ListView_InsertColumn(hList, 1, &lvcol); lvcol.cx = 200; lvcol.pszText = "住所"; lvcol.iSubItem = 2; ListView_InsertColumn(hList, 2, &lvcol); return; }

リストビューに新しいカラムを挿入する関数です。

void InsertMyItem(HWND hList) { LV_ITEM item; memset(&item, 0, sizeof(LV_ITEM)); item.mask = LVIF_TEXT; item.pszText = "粂井康孝"; item.iItem = 0; item.iSubItem = 0; ListView_InsertItem(hList, &item); item.pszText = "男"; item.iSubItem = 1; ListView_SetItem(hList, &item); item.pszText = "北海道旭川市"; item.iSubItem = 2; ListView_SetItem(hList, &item); item.pszText = "粂井ひとみ"; item.iItem = 1; item.iSubItem = 0; ListView_InsertItem(hList, &item); item.pszText = "女"; item.iSubItem = 1; ListView_SetItem(hList, &item); item.pszText = "東京都特許許可局"; item.iSubItem = 2; ListView_SetItem(hList, &item); item.pszText = "粂井志麻"; item.iItem = 2; item.iSubItem = 0; ListView_InsertItem(hList, &item); item.pszText = "女"; item.iSubItem = 1; ListView_SetItem(hList, &item); item.pszText = "空知郡妹背牛町"; item.iSubItem = 2; ListView_SetItem(hList, &item); return; }

リストビューにアイテムをセットする関数です。

今回は特に難しい点はありませんでした。


[SDK第2部 Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 28/Apr/1999 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。