1.コモンコントロールの準備 2.リソースエジタでアイコンを作っておきます 3.ImageList_Createでイメージリストを作ります 4.ImageList_AddIconでアイコンをイメージリストに加えます 5.CreateWindowEx(0, WC_TREEVIEW,...)でツリービューを作ります 6.TreeView_SetImageListでツリービューにイメージリストをセットします 7.TV_INSERTSTRUCT構造体のメンバであるTV_ITEM構造体のmaskメンバに TVIF_IMAGE | TVIF_SELECTEDIMAGEを加えます 8.TV_ITEM構造体のiImagiとiSelectedImageメンバにイメージリストの インデックスを指定します 9.TreeView_InsertItemで項目をツリービューに加えていきます 10.終了時にImageList_Destroyでイメージリストを破棄する
hwndはツリービューのハンドルです。HIMAGELIST TreeView_SetImageList( hwnd, himl, iImage );
左の図のように選択された項目には「選」のアイコンが、
選択されていない項目には「未」のアイコンが付きます。
アイコンの大きさは16*16で作っておきます。
(アイコンの名前は "MYICONS" と "MYICONN" にしておきました)
単なるアイコンのリソースです。// treevw02.rcの一部 // 自前でリソース・スクリプトを書く人は参考にしてください //////////////////////////////////////////////////////////////// // // Icon // MYICONS ICON DISCARDABLE "myicons.ico" MYICONN ICON DISCARDABLE "myiconn.ico"
いつもと同じです。後のプログラムの簡略化のためインスタンスハンドルを コピーしておくグローバル変数を用意してあります。またcommctrl.hを インクルードするのを忘れないでください。それから、comctl32.libを プロジェクトに加えるのも忘れないでください。// treevw02.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[] = "treevw02"; //ウィンドウクラス 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_WINLOGO); 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メッセージのところです。最初の説明を 読めばわかりますね。//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; static HWND hTree; static HIMAGELIST hIList; switch (msg) { case WM_CREATE: InitCommonControls(); //コモンコントロールの初期化 hIList = ImageList_Create(16, 16, ILC_COLOR4 | ILC_MASK, 2, 0); ImageList_AddIcon(hIList, LoadIcon(hInst, "MYICONS")); ImageList_AddIcon(hIList, LoadIcon(hInst, "MYICONN")); if (hIList == NULL) MessageBox(hWnd, "イメージリスト作成失敗", "OK", MB_OK); 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); TreeView_SetImageList(hTree, hIList, TVSIL_NORMAL); 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: ImageList_Destroy(hIList); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; }
この関数も前回とほぼ同じですが、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 | TVIF_IMAGE | TVIF_SELECTEDIMAGE; tv.hParent = TVI_ROOT; tv.item.pszText = "粂井"; tv.item.iImage = 1; tv.item.iSelectedImage = 0; 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; }
tv.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tv.item.iImage = 1;
tv.item.iSelectedImage = 0;
が異なる点です。これも、最初の説明の通りです。
今回も簡単でした。
Update Mar/09/1998 By Y.Kumei