第200章 ツリービューの新しいスタイル


今回はComctl32.dllのバージョンが4.71(一部4.70)以降のツリービューの 新しいスタイルについて解説します。

4.70以前のツリービューについては 第111章から第116章までを 参照して下さい。

TVS_CHECKBOXES(4.70以降)は項目にチェックボックスをつけます。

TVS_FULLROWSELECT(4.71以降)は選択した項目を含む行がまるまる 色が変わります。TVS_HASLINESが設定されていると無効です。

TVS_SINGLEEXPAND(4.71以降)は選択された項目は展開されて そうでない項目は縮められます。(実際に操作してみるとすぐわかります)

TVS_TRACKSELECTはマウスでポイントされている項目の色が変わり、 下線がつきます。また、マウスカーソルが指型に変わります。

さて、これらの新しいスタイルはCreateWindowEx関数でツリービューを 作る時に最初から指定できます。また、一般のウィンドウスタイルのように SetWindowLong関数を使って設定することもできます。リストビューとかツールバーよりは 扱いが少し楽であると言えます。

「四国」がTVS_FULLROWSELECTIONで選択された時の外観を示しています。

「イギリス」は現在マウスでポイントされているので色が変わり下線がついています。



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

// newtree1.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 MakeMyTree(HWND); void InsertMyItem(HWND); char szClassName[] = "newtree1"; //ウィンドウクラス 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, "猫でもわかるTree View", //タイトルバーにこの名前が表示されます 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; static HWND hTree; INITCOMMONCONTROLSEX ic; int wx, wy; switch (msg) { case WM_CREATE: ic.dwSize = sizeof(INITCOMMONCONTROLSEX); ic.dwICC = ICC_TREEVIEW_CLASSES; InitCommonControlsEx(&ic); hTree = MakeMyTree(hWnd); SendMessage(hTree, TVM_SETITEMHEIGHT, (WPARAM)16, 0); InsertMyItem(hTree); break; case WM_SIZE: wx = LOWORD(lp); wy = HIWORD(lp); MoveWindow(hTree, 0, 0, wx, wy, TRUE); break; case WM_CLOSE: id = MessageBox(hWnd, "終了してもよいですか", "終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { DestroyWindow(hTree); DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

WM_CREATEが来たらコモンコントロールを初期化します。 INITCOMMONCONTROLSEX構造体のdwICCメンバはICC_TREEVIEW_CLASSES にします。
筆者の環境ではそのままでは項目の高さが低くチェックボックスの 一部が切れてしまうのでTVM_SETITEMHIEGHTメッセージで項目の 高さを調整しています。

TVM_SETITEMHEIGHT wParam = (WPARAM)(SHORT) cyItem; lParam = 0;

cyItemに項目の高さを指定します。ピクセル単位です。また偶数でなくてはいけません。 しかし、ツリービューのスタイルにTVS_NONEVENHEIGHTが指定されている場合は この限りではありません。

自作関数のMakeMyTree関数(後述)で新しいスタイルも一度に設定してしまいます。

ツリービューを作ったら自作関数InsertMyItemで項目を追加します。

WM_SIZEメッセージが来たらツリービューの大きさを親の クライアント領域と同じにしておきます。 この場合GetClientRect関数を使ってもよいのですがWM_SIZEメッセージの lParamがクライアント領域の大きさを表している (第59章参照)のでこれを利用します。

HWND MakeMyTree(HWND hWnd) { HWND hTree; hTree = CreateWindowEx(0, //拡張スタイル WC_TREEVIEW, //ウィンドウクラス "", //ウィンドウの名前 WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_CHECKBOXES | TVS_SINGLEEXPAND | TVS_FULLROWSELECT | TVS_TRACKSELECT,//ウィンドウスタイル 0, 0, 0, 0,//位置、大きさ hWnd,//親ウィンドウ (HMENU)100,//ID hInst,//インスタンスハンドル NULL); return hTree; }

新しいスタイルもCreateWindowEx関数で一度に指定します。 WM_SIZEメッセージが来た時に位置、大きさが調整されるのでここでは (0,0)に幅、高さ0のツリービューを作ります。

void InsertMyItem(HWND hTree) { HTREEITEM hAsia, hEurope, hJapan; TV_INSERTSTRUCT tv; ZeroMemory(&tv, sizeof(TV_INSERTSTRUCT)); tv.hInsertAfter = TVI_LAST; tv.item.mask = TVIF_TEXT; tv.hParent = TVI_ROOT; tv.item.pszText = "アジア"; hAsia = TreeView_InsertItem(hTree, &tv); tv.item.pszText = "ヨーロッパ"; hEurope = TreeView_InsertItem(hTree, &tv); tv.hParent = hAsia; tv.item.pszText = "日本"; hJapan = TreeView_InsertItem(hTree, &tv); tv.hParent = hAsia; tv.item.pszText = "中華人民共和国"; TreeView_InsertItem(hTree, &tv); tv.hParent = hEurope; tv.item.pszText = "イギリス"; TreeView_InsertItem(hTree, &tv); tv.hParent = hEurope; tv.item.pszText = "ドイツ"; TreeView_InsertItem(hTree, &tv); tv.hParent = hEurope; tv.item.pszText = "オランダ"; TreeView_InsertItem(hTree, &tv); tv.hParent = hJapan; tv.item.pszText = "北海道"; TreeView_InsertItem(hTree, &tv); tv.hParent = hJapan; tv.item.pszText = "本州"; TreeView_InsertItem(hTree, &tv); tv.hParent = hJapan; tv.item.pszText = "四国"; TreeView_InsertItem(hTree, &tv); tv.hParent = hJapan; tv.item.pszText = "九州"; TreeView_InsertItem(hTree, &tv); tv.hParent = hJapan; tv.item.pszText = "沖縄"; TreeView_InsertItem(hTree, &tv); return; }

ツリービューに項目を追加する自作関数です。

今回はツリービューの新しいスタイルが増えただけで特に目新しい ものはありませんでした。


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

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