DirTreeCtrl.cpp
上传用户:httpyym
上传日期:2007-01-02
资源大小:38k
文件大小:11k
源码类别:

TreeView控件

开发平台:

Visual C++

  1. // DirTreeCtrl.cpp: 
  2. // 
  3. // wrapped CTreeCtrl to select and or display folders and files (optional )
  4. // 
  5. #include "stdafx.h"
  6. #include "DirTreeCtrl.h"
  7. #include "SortStringArray.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CDirTreeCtrl
  15. CDirTreeCtrl::CDirTreeCtrl()
  16. {
  17. m_strRoot = "";      // Auf Leer setzen
  18. }
  19. CDirTreeCtrl::~CDirTreeCtrl()
  20. {
  21. m_imgList.Detach();
  22. }
  23. BEGIN_MESSAGE_MAP(CDirTreeCtrl, CTreeCtrl)
  24. //{{AFX_MSG_MAP(CDirTreeCtrl)
  25. ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
  26. //}}AFX_MSG_MAP
  27. END_MESSAGE_MAP()
  28. /////////////////////////////////////////////////////////////////////////////
  29. // Behandlungsroutinen f黵 Nachrichten CDirTreeCtrl 
  30. BOOL CDirTreeCtrl::DisplayTree(LPCTSTR strRoot, BOOL bFiles)
  31. {
  32. DWORD dwStyle = GetStyle();   // read the windowstyle
  33. if ( dwStyle & TVS_EDITLABELS ) 
  34. {
  35. // Don't allow the user to edit ItemLabels
  36. ModifyStyle( TVS_EDITLABELS , 0 );
  37. }
  38. // Display the DirTree with the Rootname e.g. C:
  39. // if Rootname == NULL then Display all Drives on this PC
  40.     // First, we need the system-ImageList
  41. DeleteAllItems();
  42. if ( !GetSysImgList() )
  43. return FALSE;
  44.     m_bFiles = bFiles;  // if TRUE, Display Path- and Filenames 
  45. if ( strRoot == NULL || strRoot[0] == '' )
  46. {
  47. if ( !DisplayDrives() )
  48. return FALSE;
  49. m_strRoot = "";
  50. }
  51.     else
  52. {
  53. m_strRoot = strRoot;
  54. if ( m_strRoot.Right(1) != '\' )
  55. m_strRoot += "\";
  56. HTREEITEM hParent = AddItem( TVI_ROOT, m_strRoot );
  57. DisplayPath( hParent, strRoot );
  58. }
  59. return TRUE;
  60. }
  61. /////////////////////////////////////////////////
  62. BOOL CDirTreeCtrl::GetSysImgList()
  63. /////////////////////////////////////////////////
  64. {
  65. SHFILEINFO shFinfo;
  66. HIMAGELIST hImgList = NULL;
  67. if ( GetImageList( TVSIL_NORMAL ) )
  68. m_imgList.Detach();
  69. hImgList = (HIMAGELIST)SHGetFileInfo( "C:\",
  70.   0,
  71.   &shFinfo,
  72.   sizeof( shFinfo ),
  73.   SHGFI_SYSICONINDEX | 
  74.   SHGFI_SMALLICON );
  75. if ( !hImgList )
  76. {
  77. m_strError = "Cannot retrieve the Handle of SystemImageList!";
  78. return FALSE;
  79. }
  80.     
  81. if ( !m_imgList.Attach( hImgList ) )
  82. {
  83. m_strError = "Cannot Attach SystemImageList-Handle";
  84. return FALSE;
  85. }
  86.     
  87. SetImageList( &m_imgList, TVSIL_NORMAL );
  88. return TRUE;   // OK
  89. }
  90. BOOL CDirTreeCtrl::DisplayDrives()
  91. {
  92. //
  93. // Displaying the Availible Drives on this PC
  94. // This are the First Items in the TreeCtrl
  95. //
  96. DeleteAllItems();
  97. char  szDrives[128];
  98. char* pDrive;
  99. if ( !GetLogicalDriveStrings( sizeof(szDrives), szDrives ) )
  100. {
  101. m_strError = "Error Getting Logical DriveStrings!";
  102. return FALSE;
  103. }
  104. pDrive = szDrives;
  105. while( *pDrive )
  106. {
  107. HTREEITEM hParent = AddItem( TVI_ROOT, pDrive );
  108. if ( FindSubDir( pDrive ) )
  109. InsertItem( "", 0, 0, hParent );
  110. pDrive += strlen( pDrive ) + 1;
  111. }
  112. return TRUE;
  113. }
  114. void CDirTreeCtrl::DisplayPath(HTREEITEM hParent, LPCTSTR strPath)
  115. {
  116. //
  117. // Displaying the Path in the TreeCtrl
  118. //
  119. CFileFind find;
  120. CString   strPathFiles = strPath;
  121. BOOL      bFind;
  122. CSortStringArray strDirArray;
  123. CSortStringArray strFileArray;
  124. if ( strPathFiles.Right(1) != "\" )
  125. strPathFiles += "\";
  126. strPathFiles += "*.*";
  127. bFind = find.FindFile( strPathFiles );
  128. while ( bFind )
  129. {
  130. bFind = find.FindNextFile();
  131. if ( find.IsDirectory() && !find.IsDots() )
  132. {
  133. strDirArray.Add( find.GetFilePath() );
  134. }
  135. if ( !find.IsDirectory() && m_bFiles )
  136. strFileArray.Add( find.GetFilePath() );
  137. }
  138.     
  139. strDirArray.Sort();
  140. SetRedraw( FALSE );
  141. CWaitCursor wait;
  142.     
  143. for ( int i = 0; i < strDirArray.GetSize(); i++ )
  144. {
  145. HTREEITEM hItem = AddItem( hParent, strDirArray.GetAt(i) );
  146. if ( FindSubDir( strDirArray.GetAt(i) ) )
  147. InsertItem( "", 0, 0, hItem );
  148. }
  149. if ( m_bFiles )
  150. {
  151. strFileArray.Sort();
  152. for ( i = 0; i < strFileArray.GetSize(); i++ )
  153. {
  154. HTREEITEM hItem = AddItem( hParent, strFileArray.GetAt(i) );
  155. }
  156. }
  157.     
  158. SetRedraw( TRUE );
  159. }
  160. HTREEITEM CDirTreeCtrl::AddItem(HTREEITEM hParent, LPCTSTR strPath)
  161. {
  162. // Adding the Item to the TreeCtrl with the current Icons
  163. SHFILEINFO shFinfo;
  164. int iIcon, iIconSel;
  165.     CString    strTemp = strPath;
  166.     
  167. if ( strTemp.Right(1) != '\' )
  168.  strTemp += "\";
  169. if ( !SHGetFileInfo( strTemp,
  170. 0,
  171. &shFinfo,
  172. sizeof( shFinfo ),
  173. SHGFI_ICON | 
  174.     SHGFI_SMALLICON ) )
  175. {
  176. m_strError = "Error Gettting SystemFileInfo!";
  177. return NULL;
  178. }
  179. iIcon = shFinfo.iIcon;
  180. if ( !SHGetFileInfo( strTemp,
  181. 0,
  182. &shFinfo,
  183. sizeof( shFinfo ),
  184. SHGFI_ICON | SHGFI_OPENICON |
  185.     SHGFI_SMALLICON ) )
  186. {
  187. m_strError = "Error Gettting SystemFileInfo!";
  188. return NULL;
  189. }
  190. iIconSel = shFinfo.iIcon;
  191. if ( strTemp.Right(1) == "\" )
  192. strTemp.SetAt( strTemp.GetLength() - 1, '' );
  193. if ( hParent == TVI_ROOT )
  194. return InsertItem( strTemp, iIcon, iIconSel, hParent );
  195. return InsertItem( GetSubPath( strTemp ), iIcon, iIconSel, hParent );
  196. }
  197. LPCTSTR CDirTreeCtrl::GetSubPath(LPCTSTR strPath)
  198. {
  199. //
  200. // getting the last SubPath from a PathString
  201. // e.g. C:tempreadme.txt
  202. // the result = readme.txt
  203. static CString strTemp;
  204. int     iPos;
  205. strTemp = strPath;
  206. if ( strTemp.Right(1) == '\' )
  207.  strTemp.SetAt( strTemp.GetLength() - 1, '' );
  208. iPos = strTemp.ReverseFind( '\' );
  209. if ( iPos != -1 )
  210.     strTemp = strTemp.Mid( iPos + 1);
  211. return (LPCTSTR)strTemp;
  212. }
  213. BOOL CDirTreeCtrl::FindSubDir( LPCTSTR strPath)
  214. {
  215. //
  216. // Are there subDirs ?
  217. //
  218. CFileFind find;
  219. CString   strTemp = strPath;
  220. BOOL      bFind;
  221. if (_tcslen(strPath) == 3 )
  222. {
  223. if (strPath[1] == ':' && strPath[2] =='\')
  224. strTemp += "*.*";
  225. else
  226. strTemp += "\*.*";
  227. }
  228. else strTemp += "\*.*";
  229. bFind = find.FindFile( strTemp );
  230. while ( bFind )
  231. {
  232. bFind = find.FindNextFile();
  233. if ( find.IsDirectory() && !find.IsDots() )
  234. {
  235. return TRUE;
  236. }
  237. if ( !find.IsDirectory() && m_bFiles && !find.IsHidden() )
  238. return TRUE;
  239. }
  240. return FALSE;
  241. }
  242. void CDirTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) 
  243. {
  244. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  245. CString strPath;
  246.  
  247. if ( pNMTreeView->itemNew.state & TVIS_EXPANDED )
  248. {
  249. //UINT uTest = TVIS_EXPANDEDONCE;
  250. ExpandItem( pNMTreeView->itemNew.hItem, TVE_EXPAND );
  251.     /*
  252. //
  253. // Delete All items
  254. // And display the subpath
  255. //
  256. HTREEITEM hChild = GetChildItem( pNMTreeView->itemNew.hItem );
  257. while ( hChild )
  258. {
  259. DeleteItem( hChild );
  260. hChild = GetChildItem( pNMTreeView->itemNew.hItem );
  261. }
  262.         
  263. strPath = GetFullPath( pNMTreeView->itemNew.hItem );
  264. DisplayPath( pNMTreeView->itemNew.hItem, strPath );
  265. */
  266. }
  267. else
  268. {
  269. //
  270. // Delete the Items, but leave one there, for 
  271. // expanding the item next time
  272. //
  273. HTREEITEM hChild = GetChildItem( pNMTreeView->itemNew.hItem );
  274. while ( hChild ) 
  275. {
  276. DeleteItem( hChild );
  277. hChild = GetChildItem( pNMTreeView->itemNew.hItem );
  278. }
  279. InsertItem( "", pNMTreeView->itemNew.hItem );
  280. }
  281. *pResult = 0;
  282. }
  283. CString CDirTreeCtrl::GetFullPath(HTREEITEM hItem)
  284. {
  285. // get the Full Path of the item
  286. CString strReturn;
  287. CString strTemp;
  288. HTREEITEM hParent = hItem;
  289. strReturn = "";
  290. while ( hParent )
  291. {
  292. strTemp  = GetItemText( hParent );
  293. strTemp += "\";
  294. strReturn = strTemp + strReturn;
  295. hParent = GetParentItem( hParent );
  296. }
  297.     if ( strReturn.Right(1) == '\' )
  298. strReturn.SetAt( strReturn.GetLength() - 1, '' );
  299.     return strReturn;
  300. }
  301. BOOL CDirTreeCtrl::SetSelPath(LPCTSTR strPath)
  302. {
  303. // Setting the Selection in the Tree
  304. HTREEITEM hParent  = TVI_ROOT;
  305. int       iLen    = strlen(strPath) + 2;
  306. char*     pszPath = new char[iLen];
  307. char*     pPath   = pszPath;
  308. BOOL      bRet    = FALSE;
  309.     
  310. if ( !IsValidPath( strPath ) )
  311. {
  312. delete [] pszPath; // this must be added 29.03.99
  313. return FALSE;
  314. }
  315. strcpy( pszPath, strPath );
  316. strupr( pszPath );
  317. if ( pszPath[strlen(pszPath)-1] != '\' )
  318. strcat( pszPath, "\" );
  319.     
  320. int iLen2 = strlen( pszPath );
  321. for (WORD i = 0; i < iLen2; i++ )
  322. {
  323. if ( pszPath[i] == '\' )
  324. {
  325. SetRedraw( FALSE );
  326. pszPath[i] = '';
  327. hParent = SearchSiblingItem( hParent, pPath );
  328. if ( !hParent )  // Not found!
  329. break;
  330. else
  331. {
  332. // Info:
  333. // the notification OnItemExpanded 
  334. // will not called every time 
  335. // after the call Expand. 
  336. // You must call Expand with TVE_COLLAPSE | TVE_COLLAPSERESET
  337. // to Reset the TVIS_EXPANDEDONCE Flag
  338. UINT uState;
  339. uState = GetItemState( hParent, TVIS_EXPANDEDONCE );
  340. if ( uState )
  341. {
  342. Expand( hParent, TVE_EXPAND );
  343. Expand( hParent, TVE_COLLAPSE | TVE_COLLAPSERESET );
  344. InsertItem("", hParent ); // insert a blank child-item
  345. Expand( hParent, TVE_EXPAND ); // now, expand send a notification
  346. }
  347. else
  348. Expand( hParent, TVE_EXPAND );
  349. }
  350. pPath += strlen(pPath) + 1;
  351. }
  352. }
  353. delete [] pszPath;
  354. if ( hParent ) // Ok the last subpath was found
  355. {
  356. SelectItem( hParent ); // select the last expanded item
  357. bRet = TRUE;
  358. }
  359. else
  360. {
  361. bRet = FALSE;
  362. }
  363. SetRedraw( TRUE );
  364.     return bRet;
  365. }
  366. HTREEITEM CDirTreeCtrl::SearchSiblingItem( HTREEITEM hItem, LPCTSTR strText)
  367. {
  368. HTREEITEM hFound = GetChildItem( hItem );
  369. CString   strTemp;
  370. while ( hFound )
  371. {
  372. strTemp = GetItemText( hFound );
  373.         strTemp.MakeUpper();
  374. if ( strTemp == strText )
  375. return hFound;
  376. hFound = GetNextItem( hFound, TVGN_NEXT );
  377. }
  378. return NULL;
  379. }
  380. void CDirTreeCtrl::ExpandItem(HTREEITEM hItem, UINT nCode)
  381. {
  382. CString strPath;
  383. if ( nCode == TVE_EXPAND )
  384. {
  385. HTREEITEM hChild = GetChildItem( hItem );
  386. while ( hChild )
  387. {
  388. DeleteItem( hChild );
  389. hChild = GetChildItem( hItem );
  390. }
  391.         
  392. strPath = GetFullPath( hItem );
  393. DisplayPath( hItem, strPath );
  394. }
  395. }
  396. BOOL CDirTreeCtrl::IsValidPath(LPCTSTR strPath)
  397. {
  398. // This function check the Pathname
  399. HTREEITEM hChild;
  400. CString   strItem;
  401. CString   strTempPath = strPath;
  402. BOOL      bFound = FALSE;
  403. CFileFind find;
  404. hChild = GetChildItem( TVI_ROOT );
  405. strTempPath.MakeUpper();
  406. while ( hChild )
  407. {
  408. strItem = GetItemText( hChild );
  409. strItem.MakeUpper();
  410. if ( strItem == strTempPath.Mid( 0, strItem.GetLength() ) )
  411. {
  412. bFound = TRUE;
  413. break;
  414. }
  415. hChild = GetNextItem( hChild, TVGN_NEXT );
  416. }
  417.     
  418. if ( !bFound )
  419. return FALSE;
  420. if ( find.FindFile( strPath ) )
  421. return TRUE;
  422.      
  423. return FALSE;
  424. }