ツリービューもコモンコントロールの一つです。
作り方はリストビューと良く似ています。
さて、TreeView_InsertItemマクロは次のようになっています。1.コモンコントロールの準備 commctrl.hのインクルード comctl32.libをプロジェクトに加える InitCommonControls関数を実行してコモンコントロールを初期化 2.クラス名をWC_TREEVIEWにしてCreateWindowEx関数を実行 3.親ウィンドウのサイズが変わったときの対策 4.TreeView_InsertItemマクロで親項目や子項目を追加する
hwndはツリービューのウィンドウハンドルです。HTREEITEM TreeView_InsertItem( hwnd, lpis );
hParentは親アイテムのハンドルです。これがTVI_ROOTまたはNULLの時は ツリービューコントロールのルートに挿入されます。typedef struct _TV_INSERTSTRUCT { //tvins HTREEITEM hParent; HTREEITEM hInsertAfter; TV_ITEM item; } TV_INSERTSTRUCT, FAR *LPTV_INSERTSTRUCT;
maskはどの構造体メンバが有効かを示します。 TVIF_TEXTだとpszTextメンバが有効となります。typedef struct _TV_ITEM { //tvi UINT mask; HTREEITEM hItem; UINT state; UINT stateMask; LPSTR pszText; int cchTextMax; int iImage; int iSelectedImage; int cChildren; LPARAM lParam; } TV_ITEM, FAR *LPTV_ITEM;
これだけでもっとも単純なツリービューが作れます。 早速プログラムを見てみましょう。
これは、いつもと同じです。// treevw01.cpp #define STRICT #include <windows.h> #include <commctrl.h> #define ID_MYTREE 100 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); void AddItem(HWND); char szClassName[] = "treevw01"; //ウィンドウクラス HINSTANCE hInst; int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
これもいつもと同じです。//ウィンドウ・クラスの登録 BOOL 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 hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; //インスタンスハンドルの保存 hWnd = CreateWindow(szClassName, "猫でもわかるツリービュー",//タイトルバーにこの名前が表示されます 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)コモンコントロールを 初期化します。そしてツリービューのウィンドウを作成します。 ツリービューのスタイルにはTVS_HASBUTTON, TVS_HASLINE, TVS_LINESATROOTなどがあります。TVS_HASBUTTONはプラスと マイナスのボタンを表示します。TVS_HASLINEは項目の階層を 破線で表示します。TVS_LINESATROOTはルートにある項目を 破線で結びます。これでよくわからないときは 各スタイルを付けたりはずしたりして実際にプログラムを 作って試してみてください。//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; static HWND hTree; switch (msg) { case WM_CREATE: InitCommonControls(); //コモンコントロールの初期化 hTree = CreateWindowEx(0, WC_TREEVIEW, "", WS_CHILD | WS_BORDER | WS_VISIBLE | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT, 0, 0, 0, 0, hWnd, (HMENU)ID_MYTREE, hInst, NULL); AddItem(hTree); break; case WM_SIZE: MoveWindow(hTree, 0, 0, LOWORD(lp), HIWORD(lp), TRUE); break; case WM_CLOSE: id = MessageBox(hWnd, "終了してもよいですか", "終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }
親の大きさが変わったら(WM_SIZE)ツリービューのウインドウの 大きさも矛盾のないようにします。
項目を挿入する関数です。項目の親子関係に注意してください。void AddItem(HWND hTree) { HTREEITEM hParent1, hParent2, hParent3, hChild1, hChild2; TV_INSERTSTRUCT tv; memset((char *)&tv, '\0', sizeof(tv)); tv.hInsertAfter = TVI_LAST; tv.item.mask = TVIF_TEXT; tv.hParent = TVI_ROOT; tv.item.pszText = "粂井"; hParent1 = TreeView_InsertItem(hTree, &tv); tv.item.pszText = "田中"; hParent2 = TreeView_InsertItem(hTree, &tv); tv.item.pszText = "佐藤"; hParent3 = TreeView_InsertItem(hTree, &tv); tv.hParent = hParent1; tv.item.pszText = "康孝"; hChild1 = TreeView_InsertItem(hTree, &tv); tv.item.pszText = "ひとみ"; hChild2 = TreeView_InsertItem(hTree, &tv); tv.hParent = hChild1; tv.item.pszText = "志麻"; TreeView_InsertItem(hTree, &tv); tv.hParent = hChild1; tv.item.pszText = "櫻都"; TreeView_InsertItem(hTree, &tv); tv.hParent = hParent2; tv.item.pszText = "マイケル"; TreeView_InsertItem(hTree, &tv); tv.hParent = hParent3; tv.item.pszText = "パトリシア"; TreeView_InsertItem(hTree, &tv); return; }
今回は単純でした。
Update Mar/05/1998 By Y.Kumei