C:\Documents and Settins\Administrator\Favorites\链接
C:\Documents and Settins\Administrator\My Documents
......转成
C:.
+---Documents and Settings
| +---Administrator
| | +---Favorites
| | | \---链接
| | +---My Documents
.....
C:\Documents and Settins\Administrator\My Documents
......转成
C:.
+---Documents and Settings
| +---Administrator
| | +---Favorites
| | | \---链接
| | +---My Documents
.....
void LoadFileToTreeCtrl( CTreeCtrl& theDirTree, const CString& strFilePath )
{
// 1. 判断树型控件是否已经创建了,如果没有创建,那么返回
if( FALSE == ::IsWindow( theDirTree.GetSafeHwnd() ) )
{
AfxMessageBox( _T("没有指定有效的控件") );
return;
} // 2. 判断文件是否存在
if( _access( strFilePath, 0 ) != 0 )
{
CString strErrMsg;
strErrMsg.Format( _T("找不到该文件:%s"), strFilePath );
AfxMessageBox( strErrMsg );
return;
} // 3. 打开文件
FILE* pf = fopen( strFilePath, "rt" );
if( pf == NULL )
{
CString strErrMsg;
strErrMsg.Format( _T("该文件:%s被其他进程占用,无法打开"), strFilePath );
AfxMessageBox( strErrMsg );
return;
} // 4. 逐个读取每条记录,解析每条记录
char szOneRec[1024]="";
while( fgets( szOneRec, 1023, pf ) != 0 )
{
// 去掉最后一个\n
if( szOneRec[strlen(szOneRec)-1] == '\n' || szOneRec[strlen(szOneRec)-1] == '\r' )
szOneRec[strlen(szOneRec)-1] = 0;
// 4.1 将字符串解析成 盘符, 路径,文件名 3个部分
char szDisk[8], szDir[1024], szFile[512], szExtName[16];
_splitpath( szOneRec, szDisk, szDir, szFile, szExtName );
char szFileName[512];
sprintf( szFileName, "%s%s", szFile, szExtName );
// 4.2 在树形控件的根节点中查找是否存在改盘符,如果没有,那么添加
HTREEITEM hItem = theDirTree.GetRootItem();
if( szDisk[0] == NULL )
break;
hItem = CreateSubItem( theDirTree, NULL, szDisk );
// 4.4 解析路径
HTREEITEM hSubItem = NULL;
char * szToken = strtok( szDir, "\\" );
while( szToken != NULL && szToken[0] != 0 )
{
// 4.5 逐渐定位子节点
hSubItem = CreateSubItem( theDirTree, hItem, szToken );
szToken = strtok( NULL, "\\" );
}
// 解析文件名
hItem = hSubItem;
if( szFileName[0] == 0 )
continue;
hSubItem = CreateSubItem( theDirTree, hItem, szFileName );
if( hSubItem == NULL )
{
// 如果没有,那么创建一个节点
hSubItem = theDirTree.InsertItem( szFileName , hItem );
}
}
fclose( pf );
}HTREEITEM CreateSubItem( CTreeCtrl& tree, HTREEITEM item, const CString& strItem )
{
HTREEITEM hItem = NULL;
if( item != NULL )
hItem = tree.GetNextItem( item, TVGN_CHILD );
else
hItem = tree.GetRootItem();
for( ; hItem != NULL; hItem = tree.GetNextItem( hItem, TVGN_NEXT ) )
{
CString strItemName = tree.GetItemText( hItem );
if( strItemName == strItem )
break;
} // 4.3 判断是否找到了节点
if( hItem == NULL )
{
// 如果没有找到,就创建一个
hItem = tree.InsertItem( strItem, item );
}
return hItem;
}
C:\Documents and Settings\All Users\Application Data\Microsoft\OFFICE\DATA.2
C:\Documents and Settings\All Users\Application Data\Microsoft\OFFICE\DATA.3
C:\Documents and Settings\All Users\Application Data\Microsoft\OFFICE\DATA.4
C:\Documents and Settings\All Users\Application Data\Microsoft\OFFICE\DATA.5
C:\Documents and Settings\All Users\Application Data\Microsoft\OFFICE\DATA.6
C:\Documents and Settings\All Users\Application Data\Microsoft\OFFICE\DATA.7
C:\Documents and Settings\All Users\Application Data\Microsoft\OFFICE\DATA.8
C:\Documents and Settings\All Users\Application Data\Microsoft\OFFICE\DATA.9....如果我的文件有这样的记录N条,每一次都要从头找结点的话,效率不高
谢谢你的代码不过你的代码只适合Tree控件,我想要的是一种通用解决方案
就是说定义Tree数据结构,生成树信息,可以赋值给任何控件,也可直接输出.
很多时候,界面与功能最后不要掺杂在一起,这样复用,移植都很方便.
做个几个接口就行了
// ==== 移植的时候,只要实现这个类中的接口就可以了 =============================
class CParsPathTree
{
public:
CParsPathTree();
virtual ~CParsPathTree();
virtual BOOL LoadItemsToArr() = 0; // 实现把源读到arrItems中
void ParasTree(); // 这个就是刚才那个转换函数,稍作改动即可。
protected:
CStringArray arrItems;
virtual DWORD FindSubItem( DWORD dwParentId, void* pData ) = 0; // 实现在树中查找父节点是由dwParentId标识的节点,本节点中的数据"等于"void* pData。如果找不到这样的节点,返回0
virtual DWORD CreateSubItem( DWORD dwParentId, void* pData ) = 0;// 实现创建一个节点,该一个数据为pData中指向的内容,父节点是由dwParentId标识的节点.
virtual DWORD CreateRootItem( void* pData ); // 实现能够创建一个根节点。
};
// =======================================================================