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; }
WM_CREATEが来たらコモンコントロールを初期化します。 INITCOMMONCONTROLSEX構造体のdwICCメンバはICC_TREEVIEW_CLASSES にします。//ウィンドウプロシージャ 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; }
cyItemに項目の高さを指定します。ピクセル単位です。また偶数でなくてはいけません。 しかし、ツリービューのスタイルにTVS_NONEVENHEIGHTが指定されている場合は この限りではありません。TVM_SETITEMHEIGHT wParam = (WPARAM)(SHORT) cyItem; lParam = 0;
自作関数のMakeMyTree関数(後述)で新しいスタイルも一度に設定してしまいます。
ツリービューを作ったら自作関数InsertMyItemで項目を追加します。
WM_SIZEメッセージが来たらツリービューの大きさを親の クライアント領域と同じにしておきます。 この場合GetClientRect関数を使ってもよいのですがWM_SIZEメッセージの lParamがクライアント領域の大きさを表している (第59章参照)のでこれを利用します。
新しいスタイルもCreateWindowEx関数で一度に指定します。 WM_SIZEメッセージが来た時に位置、大きさが調整されるのでここでは (0,0)に幅、高さ0のツリービューを作ります。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; }
ツリービューに項目を追加する自作関数です。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; }
今回はツリービューの新しいスタイルが増えただけで特に目新しい ものはありませんでした。
Update 06/May/1999 By Y.Kumei