// フォルダをツリーコントロールとして追加する // (C)2003 Yutaka Wada, AirparkLab // [注意] // 相対パスで読み込めるように便宜上ヘッダファイルにしている。 // インクルードするのは唯一のソースファイルのみとし、他はextern宣言して使用すること。 #ifndef __CREATE_FOLDER_TREE_H__ #define __CREATE_FOLDER_TREE_H__ // プロトタイプ宣言 void CreateFolderTree( CString *pDir, CTreeCtrl *pTree, HTREEITEM hParent, CStringArray *pItemArray ); // フォルダをツリーコントロールとして追加する(再帰関数) void CreateFolderTree( CString *pDir, CTreeCtrl *pTree, HTREEITEM hParent, CStringArray *pItemArray ) { HANDLE hFile; // 検索ハンドル WIN32_FIND_DATA data; // 発見ファイル情報を受ける変数 CString Path; // 検索パス名 CString Filename; // 検索ファイル(ディレクトリ)名 CString Folder; // 検索フォルダ(末尾の'\'あり) // 末尾の'\'処理(SJISコード対応) int nLen = pDir->GetLength(); if( nLen >= 2 && (unsigned char)((*pDir)[nLen-2]) < 0x81 && (*pDir)[nLen-1] == '\\' ) Folder = *pDir; else if( nLen >= 3 && (unsigned char)((*pDir)[nLen-3]) >= 0x81 && (*pDir)[nLen-1] == '\\' ) Folder = *pDir; else Folder = *pDir + "\\"; Path.Format( "%s*.*", (LPCSTR)Folder ); // フォルダを検索 hFile = FindFirstFile( (LPCSTR)Path, &data ); if( hFile != INVALID_HANDLE_VALUE ){ do{ if( strcmp( ".", data.cFileName ) && strcmp( "..", data.cFileName ) ){ // フォルダなら再帰的にフォルダアイテムを作成 if( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ){ HTREEITEM hItem = pTree->InsertItem( TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM, data.cFileName, 0, 1, NULL, NULL, pItemArray->GetSize(), hParent, TVI_SORT ); Filename.Format( "%s%s", (LPCSTR)Folder, data.cFileName ); pItemArray->Add( Filename ); CreateFolderTree( &Filename, pTree, hItem, pItemArray ); } } } while( FindNextFile( hFile, &data ) ); // 次のファイルを検索 FindClose( hFile ); // ハンドルの後始末 } } #endif /* 実行サンプル [メンバ変数] CStringArray m_TreeArray; // アイテムデータを添字として持つフルパスフォルダ名配列 CTreeCtrl m_TreeCtrl; // ツリーコントロール CImageList m_ImageList; // アイコンイメージリスト CString Path = "C:\WINDOWS\FAVORITE"; // 検索パス [初期化処理] // アイコンイメージリストの作成 m_ImageList.Create( 16, 16, FALSE, 2, 0 ); m_ImageList.Add( AfxGetApp()->LoadIcon( IDI_FOLDER_CLOSE ) ); m_ImageList.Add( AfxGetApp()->LoadIcon( IDI_FOLDER_OPEN ) ); // ツリーコントロールにアイコンイメージを登録 m_TreeCtrl.SetImageList( &m_ImageList, TVSIL_NORMAL ); [ツリーを作成するタイミング] // 一旦全てのアイテムを削除 m_TreeArray.RemoveAll(); m_TreeCtrl.DeleteAllItems(); // 最下位フォルダ名をラベルとしてツリーコントロールに登録(サブフォルダも含む) // GetElementName()は別ファイルで定義されている自作関数です。 char *pLabel = GetElementName( (LPSTR)(LPCTSTR)Path ); HTREEITEM hItem = m_TreeCtrl.InsertItem( TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM, pLabel, 0, 1, NULL, NULL, 0, TVI_ROOT, TVI_SORT ); m_TreeArray.Add( Path ); CreateFolderTree( &Path, &m_TreeCtrl, hItem, &m_TreeArray ); // 作成後に展開 m_TreeCtrl.Expand( hItem, TVE_EXPAND ); [アイテムが選択された時] // ツリーコントロール アイテム選択(TVN_SELCHANGED)ハンドラ void CEGZcDlg::OnSelchangedTreeDstdir(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; if( pNMTreeView->action != TVC_BYKEYBOARD && pNMTreeView->action != TVC_BYMOUSE ) return; // 有効なサブフォルダが選択された時 HTREEITEM hItem = pNMTreeView->itemNew.hItem; if( hItem ){ // サブフォルダのフルパスを取得 CString Path = m_TreeArray[m_TreeCtrl.GetItemData( hItem )]; } *pResult = 0; } 各フォルダはツリーコントロールに登録されると同時に CStringArray オブジェクトに そのフルパスが保存されるので、アイテム選択ハンドラでは選択されたアイテムのハンドル値から アイテムデータを取得し、それを添字として CStringArray をアクセスすることによって 選択項目のフルパス名を得ることができます。 */