ファイルをバイナリ形式で表示する (C/C++編)
ディレクトリが展開されるときに、展開されるディレクトリ直下のファイルのリストを取得してディレクトリのみをツリービューに追加します。
ツリービューでノードが展開されるときにイベントが発生するので、該当するイベントにイベントハンドラを追加して、ディレクトリの展開処理を行います。
ディレクトリツリーのノードが展開されるとき、または、閉じられるときに呼び出されるイベント処理です。
ディレクトリツリーのノード(ディレクトリ)が展開されるときのイベント処理を追加します。
「クラスウィザード」を開いて、「CFileTreeView」クラスに「メッセージ」タブから「TVN_ITEMEXPANDED」を選択してイベントハンドラ「OnTvnItemexpanded()」を追加します。
ディレクトリツリーが展開されるときに以下の処理を行います。
-
展開されるノードにはダミーで1個だけサブディレクトリの子ノードがあるはずなので、一旦削除します。
(そうしないと、同じサブディレクトリのノードが2個できてしまいます。) 展開されるノードに対応したディレクトリの絶対パスを取得します。
-
絶対パスがある場合は、ドライブ名かディレクト名のノードなので、展開するノードにディレクトリ名のリストを子ノードとして追加します。
(AddDirectory()を呼び出します。) -
絶対パスがない場合、展開するノードはルートノードなので、展開するノードにドライブ名のリストを子ノードとして追加します。
(AddDriveName()を呼び出します。)
ソースコード [FileTreeView.cpp]
/****************************************************************************/
/*!
* @brief ディレクトリツリーのディレクトリが展開されるときのイベント処理.
*
* @param [in] pNMHDR 通知メッセージ(NMHDR)構造体のポインタ.
* @param [out] pResult 戻り値を格納する領域のポインタ.
*
* @retval なし.
*/
void CFileTreeView::OnTvnItemexpanded( NMHDR *pNMHDR, LRESULT *pResult )
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR);
if( pNMTreeView->action & TVE_EXPAND ){
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
CTreeCtrl& treeCtrl = GetTreeCtrl();
//! 展開されるディレクトリのサブディレクトリを一旦クリアする.
DeleteChildItems( treeCtrl, hItem );
CString path = GetAbsolutePath( treeCtrl, hItem );
if( path.GetLength() > 0 ){
//! 展開されるディレクトリのサブディレクトリを表示する.
AddDirectory( treeCtrl, hItem, path, FALSE );
}else{
//! フルパス名が無い場合はルートの展開なのでドライブ名を表示する.
AddDriveName( treeCtrl, hItem );
}
}
*pResult = 0;
}
指定されたノードの直下にある子ノードを全て取り出して解放します。
ソースコード [FileTreeView.cpp]
/****************************************************************************/
/*!
* @brief 指定されたノードの子ノードを削除する.
*
* @param [in] treeCtrl ツリービューのオブジェクト.
* @param [in] hItem 子ノードを削除するノード.
*
* @retval なし.
*/
void CFileTreeView::DeleteChildItems( CTreeCtrl& treeCtrl, HTREEITEM hItem )
{
if( treeCtrl.ItemHasChildren( hItem ) ){
HTREEITEM hChild = treeCtrl.GetChildItem( hItem );
while( hChild != NULL ){
HTREEITEM hNext = treeCtrl.GetNextItem( hChild, TVGN_NEXT );
treeCtrl.DeleteItem( hChild );
hChild = hNext;
}
}
}
DeleteItem()で解放するノードの子ノード・孫ノードは自動的に解放されるので直下の子ノードのみアプリケーションで解放を指示します。
(ノード毎に動的にメモリを確保していたりすると、子ノード・孫ノードまで全て探索して解放しないとダメなのですが、今回は特にメモリの割り付けとかは行っていないので、そこまでは行いません。)
ノードに子ノードが存在するかどうかを調べるにはCTreeCtrlのItemHasChildren()メソッドを呼び出します。
BOOL CTreeCtrl::ItemHasChildren( HTREEITEM hItem ) const;
引数 | 説明 |
---|---|
hItem | 子ノードが存在するかどうかを調べるノードのハンドル。 |
戻り値 | 子ノードが存在する場合 TRUE を返す。 |
ツリービューからノードを削除するにはCTreeCtrlのDeleteItem()メソッドを呼び出します。
BOOL CTreeCtrl::DeleteItem( HTREEITEM hItem );
引数 | 説明 |
---|---|
hItem | 削除するノードのハンドル。 |