コモンコントロールを使うので、comctl32.libのリンクとコモンコントロールの初期化が必要である。
#pragma comment (lib, "comctl32.lib")InitCommonControls();ツリーコントロールを作成するにはCreateWindow()を呼び出す。
hTree = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, 0, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, 0, 0, 10, 10, hWnd, (HMENU)1, ((LPCREATESTRUCT)lp)->hInstance, NULL );ノードを追加するにはTreeView_InsertItem()を呼び出す。
TVINSERTSTRUCT tvi; tvi.hParent = TVI_ROOT; tvi.hInsertAfter = TVI_SORT; tvi.item.mask = TVIF_TEXT; tvi.item.pszText = kRootText; HTREEITEM hTreeRoot = TreeView_InsertItem(hTree, &tvi);これで最上位にノードが追加される。最上位ノードは複数作成可能である。
また、pszTextメンバは変数で定数ではないので注意。ノードを追加しただけでは再描画されないので、InvalidateRect(hWnd, NULL, TRUE);を実行するなど再描画する。
コードの続きで、hTreeRootの下に子ノードを追加する。
tvi.hParent = hTreeRoot; tvi.item.pszText = kChildText; TreeView_InsertItem(hTree, &tvi);続いて、ウィンドウプロシージャでノード選択時の通知を受け取る。
static HTREEITEM s_hSelectedItem = NULL; static HTREEITEM s_hTreeRoot = NULL; ・・・ case WM_NOTIFY: unsigned int c = ((LPNMHDR)lp)->code; if (c == TVN_SELCHANGED) {// || c == NM_CLICK) {//case NM_CLICK: TVITEMEX item; item.mask = TVIF_HANDLE | TVIF_TEXT; item.hItem = ((LPNMTREEVIEW)lp)->itemNew.hItem; item.pszText = s_SelectedItemText; item.cchTextMax = sizeof(s_SelectedItemText) / sizeof(TCHAR); TreeView_GetItem(s_hTree, &item); s_hSelectedItem = ((LPNMTREEVIEW)lp)->itemNew.hItem; } return 0;s_SelectedItemTextにはノードのテキスト、HTREEITEM型のs_hSelectedItemにはアイテムハンドルを格納する。
クリックを通知するNM_CLICKは、まだノードが選択されていない段階であるため、ノードの取得には使えないことに注意。
TreeView_DeleteItem(s_hTree, s_hSelectedItem);でノードを削除する。
次に、ノードを列挙してみよう。
void EnumTree(HWND hWnd, HWND hTree, HTREEITEM hItem){ hItem = TreeView_GetNextItem(hTree, hItem, TVGN_CHILD); TVITEMEX item; TCHAR szBuf[256] = TEXT(""); while (hItem != NULL) { item.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_CHILDREN; item.hItem = hItem; item.pszText = szBuf; item.cchTextMax = sizeof(szBuf) / sizeof(TCHAR); TreeView_GetItem(hTree, &item); MessageBox(hWnd, szBuf, TEXT("EnumTree"), MB_OK); if (item.cChildren > 0) { EnumTree(hWnd, hTree, hItem); } hItem = TreeView_GetNextItem(hTree, hItem, TVGN_NEXT); }}EnumTree(hWnd, s_hTree, TVI_ROOT);と呼び出す。第3引数が列挙する親ノードで、第3引数のノードは含まず列挙するが、TVI_ROOTを指定した場合は最上位ノードすべてを列挙していく。