树状结构类的封装CDirTreeCtrl

  1 // DirTreeCtrl.cpp : implementation file
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "DirTreeCtrl.h"
  6 
  7 #ifdef _DEBUG
  8 #define new DEBUG_NEW
  9 #undef THIS_FILE
 10 static char THIS_FILE[] = __FILE__;
 11 #endif
 12 
 13 /////////////////////////////////////////////////////////////////////////////
 14 // CDirTreeCtrl
 15 
 16 CDirTreeCtrl::CDirTreeCtrl()
 17 {
 18 }
 19 
 20 CDirTreeCtrl::~CDirTreeCtrl()
 21 {
 22 }
 23 
 24 
 25 BEGIN_MESSAGE_MAP(CDirTreeCtrl, CTreeCtrl)
 26     //{{AFX_MSG_MAP(CDirTreeCtrl)
 27     ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
 28     //}}AFX_MSG_MAP
 29 END_MESSAGE_MAP()
 30 
 31 /////////////////////////////////////////////////////////////////////////////
 32 // CDirTreeCtrl message handlers
 33 HTREEITEM CDirTreeCtrl::AddItem( HTREEITEM hParent, CString strPath)
 34 {
 35     SHFILEINFO shFinfo;
 36     int nIcon, nSelIcon;
 37     CString strTemp = strPath;
 38 
 39     if( strTemp.Right(1) != '\\' )
 40         strTemp += '\\';
 41 
 42     if( !SHGetFileInfo( strTemp,
 43                         0,
 44                         &shFinfo,
 45                         sizeof(shFinfo),
 46                         SHGFI_ICON | SHGFI_SMALLICON ) )
 47     {
 48         m_strError = "Error Gettting SystemFileInfo!";
 49         return NULL;
 50     }
 51     nIcon = shFinfo.iIcon;
 52 
 53     DestroyIcon( shFinfo.hIcon );
 54 
 55     if( !SHGetFileInfo( strTemp,
 56                         0,
 57                         &shFinfo,
 58                         sizeof(shFinfo),
 59                         SHGFI_ICON | SHGFI_OPENICON |
 60                         SHGFI_SMALLICON ) )
 61     {
 62         m_strError = "Error Getting SystemFileError!";
 63         return NULL;
 64     }
 65     nSelIcon = shFinfo.iIcon;
 66     DestroyIcon( shFinfo.hIcon );
 67 
 68     strTemp.TrimRight('\\');
 69     m_strGloble = strTemp;
 70 
 71     if( hParent == TVI_ROOT )
 72         return InsertItem( strTemp, nIcon, nSelIcon, hParent );
 73 
 74     return InsertItem( GetSubPath( strTemp ), nIcon, nSelIcon, hParent );
 75 }
 76 //HTREEITEM CDirTreeCtrl::AddItem( HTREEITEM hParent, LPCTSTR strPath)
 77 //{
 78 //    SHFILEINFO shFinfo;
 79 //    int nIcon, nSelIcon;
 80 //    CString strTemp = strPath;
 81 //
 82 //    if( strTemp.Right(1) != '\\' )
 83 //        strTemp += '\\';
 84 //
 85 //    if( !SHGetFileInfo( strTemp,
 86 //                        0,
 87 //                        &shFinfo,
 88 //                        sizeof(shFinfo),
 89 //                        SHGFI_ICON | SHGFI_SMALLICON ) )
 90 //    {
 91 //        m_strError = "Error Gettting SystemFileInfo!";
 92 //        return NULL;
 93 //    }
 94 //    nIcon = shFinfo.iIcon;
 95 //
 96 //    DestroyIcon( shFinfo.hIcon );
 97 //
 98 //    if( !SHGetFileInfo( strTemp,
 99 //                        0,
100 //                        &shFinfo,
101 //                        sizeof(shFinfo),
102 //                        SHGFI_ICON | SHGFI_OPENICON |
103 //                        SHGFI_SMALLICON ) )
104 //    {
105 //        m_strError = "Error Getting SystemFileError!";
106 //        return NULL;
107 //    }
108 //    nSelIcon = shFinfo.iIcon;
109 //    DestroyIcon( shFinfo.hIcon );
110 //
111 //    strTemp.TrimRight('\\');
112 //
113 //    if( hParent == TVI_ROOT )
114 //        return InsertItem( strTemp, nIcon, nSelIcon, hParent );
115 //
116 //    return InsertItem( GetSubPath( strTemp ), nIcon, nSelIcon, hParent );
117 //}
118 BOOL CDirTreeCtrl::DisplayDrives()
119 {
120     DeleteAllItems();
121 
122     char szDrives[128];
123     char *pDrive;
124     //LPWSTR LPDriveStr = CA2W(szDrives);
125     if( !GetLogicalDriveStringsA( sizeof(szDrives), szDrives)) //byy
126     {
127         m_strError = " Error Getting Logical DriveStrings!";
128         return FALSE;
129     }
130     pDrive = szDrives;
131     while( *pDrive )
132     {
133         ////LPCTSTR lptstr = (LPCTSTR)pDrive;
134         //int charlength = strlen(pDrive);
135         //int len = MultiByteToWideChar(CP_ACP, 0, pDrive, charlength, NULL, 0);
136         //wchar_t *pWChar = new wchar_t[len + 1]; //为宽字节字符数申请空间,  
137         //MultiByteToWideChar(CP_ACP, 0, pDrive, charlength, pWChar, len); //多字节编码转换成宽字节编码  
138         //pWChar[len] = '\0';  
139         ////将wchar_t数组转换为CString  
140         CString str;  
141         str.Append(pDrive); 
142     
143         HTREEITEM hParent = AddItem( TVI_ROOT, str); //-byy
144         if (FindSubDir(str))
145             InsertItem(_T(""), 0, 0, hParent);
146         pDrive += strlen( pDrive ) + 1;
147         //  [7/11/2016 B01974]
148         //delete[] pWChar;
149     }
150     
151     return TRUE;
152 
153 }
154 
155 //
156 
157 BOOL CDirTreeCtrl::FindSubDir(CString strPath)
158 {
159     CFileFind finder;
160     //CString strTemp = strPath;
161     CString strTemp = m_strGloble;
162     BOOL bContinue;
163 
164     if (strTemp[strTemp.GetLength()-1] == '\\')
165         strTemp += "*.*";
166     else
167         strTemp += "\\*.*";
168 
169     bContinue = finder.FindFile(strTemp);
170     
171     while(bContinue)
172     {
173         bContinue = finder.FindNextFile();
174 
175         if ( finder.IsDirectory() && !finder.IsDots() )
176             return TRUE;
177         
178 
179         if ( !finder.IsDirectory() && m_bFiles && !finder.IsDots() )
180             return TRUE;
181     }
182 
183     finder.Close();
184     return FALSE;
185 
186 }
187 
188 //
189 
190 BOOL CDirTreeCtrl::DisplayTree(LPCTSTR strRoot, BOOL bFiles)
191 {
192     DWORD dwStyle = GetStyle();
193     if ( dwStyle & TVS_EDITLABELS )
194     {
195         ModifyStyle( TVS_EDITLABELS, 0 );
196     }
197 
198     DeleteAllItems();
199 
200     if ( !GetSysImgList() )
201         return FALSE;
202 
203     m_bFiles = bFiles;
204 
205     if ( strRoot == NULL || strRoot[0] == '\0' )
206     {
207         if ( !DisplayDrives() )
208             return FALSE;
209         m_strRoot = "";
210     }
211     else
212     {
213         m_strRoot = strRoot;
214 
215         if ( m_strRoot.Right(1) != '\\' )
216             m_strRoot += "\\";
217         //  [4/18/2018 baiyangyang]
218         HTREEITEM hParent = AddItem( TVI_ROOT, m_strRoot );
219         //HTREEITEM hParent;
220         //SetCurrentPath(hParent, m_strRoot);
221         DisplayPath( hParent, strRoot );
222     }
223     return TRUE;
224 }
225 void CDirTreeCtrl::DisplayPath( HTREEITEM hParent, LPCTSTR strPath)
226 {
227     CFileFind finder;
228     CString strTempPath = strPath;
229     BOOL bContinue;
230 
231     CStringArray strDirArray;
232     CStringArray strFileArray;
233 
234     if ( strTempPath.Right(1) != '\\' )
235         strTempPath += "\\*.*";
236     else
237         strTempPath += "*.*";
238 
239     bContinue = finder.FindFile( strTempPath );
240 
241     while ( bContinue )
242     {
243         bContinue = finder.FindNextFile();
244 
245         if ( finder.IsDirectory() && !finder.IsDots() )
246         {
247             strDirArray.Add( finder.GetFilePath() );
248             TRACE(finder.GetFilePath()+"\n");
249         }
250 
251         if ( !finder.IsDirectory() && m_bFiles && !finder.IsDots())
252             strFileArray.Add( finder.GetFilePath() );
253     }
254 
255     SetRedraw( FALSE );
256     CWaitCursor wait;
257 
258     for ( int i = 0; i < strDirArray.GetSize(); i++ )
259     {
260         HTREEITEM hItem = AddItem( hParent, strDirArray.GetAt(i) );
261 
262         if ( FindSubDir( strDirArray.GetAt(i)))
263             InsertItem(_T(""), 0, 0, hItem );
264     }
265 
266     if ( m_bFiles )
267     {
268         for (int i = 0; i < strFileArray.GetSize(); i++ )
269         {
270             AddItem( hParent, strFileArray.GetAt(i) ) ;
271         }
272     }
273 
274     SetRedraw( TRUE );
275 
276     finder.Close();
277 }
278 
279 LPCTSTR CDirTreeCtrl::GetSubPath(LPCTSTR strPath)
280 {
281     static CString strTemp;
282     int nPos;
283 
284     strTemp = strPath;
285     
286     if ( strTemp.GetAt( strTemp.GetLength() - 1) == '\\' )
287         strTemp.SetAt( strTemp.GetLength() - 1,'\0' );
288 
289     nPos = strTemp.ReverseFind('\\');
290 
291     if ( nPos != -1 )
292         strTemp = strTemp.Mid( nPos + 1 );
293 
294     return (LPCTSTR)strTemp;
295 }
296 
297 //
298 
299 BOOL CDirTreeCtrl::GetSysImgList()
300 {
301     SHFILEINFO shFinfo;
302     HIMAGELIST hImgList = NULL;
303     
304     if ( GetImageList( TVSIL_NORMAL ) )
305         m_imgList.Detach();
306 
307     hImgList = (HIMAGELIST)SHGetFileInfo(_T("C:\\"),
308                                             0,
309                                             &shFinfo,
310                                             sizeof( shFinfo ),
311                                             SHGFI_SYSICONINDEX |
312                                             SHGFI_SMALLICON );
313 
314     if ( !hImgList )
315     {
316         m_strError = "Cannot retrieve the Handle of SystemImageList";
317         return FALSE;
318     }
319 
320 
321     m_imgList.m_hImageList = hImgList;
322     
323     SetImageList( &m_imgList, TVSIL_NORMAL );
324     return TRUE;
325 
326 }
327 
328 CString CDirTreeCtrl::GetFullPath(HTREEITEM hItem)
329 {
330     CString strReturn = _T(""), strTemp;
331 
332     HTREEITEM hParent = hItem;
333 
334     while( hParent )
335     {
336         strTemp = GetItemText( hParent );
337         strTemp += "\\";
338         strReturn = strTemp + strReturn;
339         hParent = GetParentItem( hParent );
340     }
341     
342     strReturn.TrimRight( '\\' );
343 
344     return strReturn;
345 }
346 
347 //
348 BOOL CDirTreeCtrl::SetSelPath(LPCTSTR strPath)
349 {
350     HTREEITEM hParent  = TVI_ROOT;
351     int       iLen    = strlen(strPath) + 2;
352     char*     pszPath = new char[iLen];
353     char*     pPath   = pszPath;
354     BOOL      bRet    = FALSE;
355 
356     if ( !IsValidPath( strPath ) )
357     {
358         delete [] pszPath; // this must be added 29.03.99
359         return FALSE;
360     }
361     strcpy( pszPath, strPath );
362     _strupr( pszPath);
363 
364     if ( pszPath[strlen(pszPath)-1] != '\\' )
365         strcat( pszPath, "\\" );
366 
367     int iLen2 = strlen( pszPath );
368 
369     for (WORD i = 0; i < iLen2; i++ )
370     {
371         if ( pszPath[i] == '\\' )
372         {
373             SetRedraw( FALSE );
374             pszPath[i] = '\0';
375             hParent = SearchSiblingItem( hParent, pPath );
376             if ( !hParent )  // Not found!
377                 break;
378             else
379             {                
380                 // Info:
381                 // the notification OnItemExpanded 
382                 // will not called every time 
383                 // after the call Expand. 
384                 // You must call Expand with TVE_COLLAPSE | TVE_COLLAPSERESET
385                 // to Reset the TVIS_EXPANDEDONCE Flag
386 
387                 UINT uState;
388                 uState = GetItemState( hParent, TVIS_EXPANDEDONCE );
389                 if ( uState )
390                 {
391                     Expand( hParent, TVE_EXPAND );
392                     Expand( hParent, TVE_COLLAPSE | TVE_COLLAPSERESET );
393                     InsertItem("", hParent ); // insert a blank child-item
394                     Expand( hParent, TVE_EXPAND ); // now, expand send a notification
395                 }
396                 else
397                     Expand( hParent, TVE_EXPAND );
398             }
399             pPath += strlen(pPath) + 1;
400         }
401     }
402 
403     delete [] pszPath;
404 
405     if ( hParent ) // Ok the last subpath was found
406     {        
407         SelectItem( hParent ); // select the last expanded item
408         bRet = TRUE;
409     }
410     else
411     {
412         bRet = FALSE;
413     }
414 
415     SetRedraw( TRUE );
416 
417     return bRet;
418 }
419 
420 void CDirTreeCtrl::ExpandItem( HTREEITEM hItem, UINT nCode)
421 {
422     CString strPath;
423     
424     if ( nCode == TVE_EXPAND )
425     {
426         HTREEITEM hChild = GetChildItem( hItem );
427         while ( hChild )
428         {
429             DeleteItem( hChild );
430             hChild = GetChildItem( hItem );
431         }
432 
433         strPath = GetFullPath( hItem );
434         DisplayPath( hItem, strPath );
435     }
436 }
437 
438 void CDirTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) 
439 {
440     NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
441     // TODO: Add your control notification handler code here
442     CString strPath;
443 
444     if ( pNMTreeView->itemNew.state & TVIS_EXPANDED )
445     {
446         ExpandItem( pNMTreeView->itemNew.hItem, TVE_EXPAND );
447     }
448     else
449     {
450         HTREEITEM hChild = GetChildItem( pNMTreeView->itemNew.hItem );
451 
452         while ( hChild )
453         {
454             DeleteItem( hChild );
455             hChild = GetChildItem( pNMTreeView->itemNew.hItem );
456         }
457 
458         InsertItem(_T(""), pNMTreeView->itemNew.hItem );
459     }
460     *pResult = 0;
461 }
462 HTREEITEM CDirTreeCtrl::SearchSiblingItem( HTREEITEM hItem, LPCTSTR strText)
463 {
464     HTREEITEM hFound = GetChildItem( hItem );
465     CString   strTemp;
466     while ( hFound )
467     {
468         strTemp = GetItemText( hFound );
469         strTemp.MakeUpper();
470         if ( strTemp == strText )
471             return hFound;
472         hFound = GetNextItem( hFound, TVGN_NEXT );
473     }
474 
475     return NULL;
476 }
477 BOOL CDirTreeCtrl::IsValidPath(LPCTSTR strPath)
478 {
479     // This function check the Pathname
480 
481     HTREEITEM hChild;
482     CString   strItem;
483     CString   strTempPath = strPath;
484     BOOL      bFound = FALSE;
485     CFileFind find;
486 
487     hChild = GetChildItem( TVI_ROOT );
488     strTempPath.MakeUpper();
489     strTempPath.TrimRight('\\');
490 
491     while ( hChild )
492     {
493         strItem = GetItemText( hChild );
494         strItem.MakeUpper();
495         if ( strItem == strTempPath.Mid( 0, strItem.GetLength() ) )
496         {
497             bFound = TRUE;
498             break;
499         }
500         hChild = GetNextItem( hChild, TVGN_NEXT );
501     }
502 
503     if ( !bFound )
504         return FALSE;
505 
506     strTempPath += "\\nul";
507     if ( find.FindFile( strTempPath ) )
508         return TRUE;
509 
510     return FALSE;
511 }
View Code

 

 1 #if !defined(AFX_DIRTREECTRL_H__0F2536D9_CBE2_4DF2_83F4_621FFD9593C9__INCLUDED_)
 2 #define AFX_DIRTREECTRL_H__0F2536D9_CBE2_4DF2_83F4_621FFD9593C9__INCLUDED_
 3 
 4 #if _MSC_VER > 1000
 5 #pragma once
 6 #endif // _MSC_VER > 1000
 7 // DirTreeCtrl.h : header file
 8 //
 9 
10 /////////////////////////////////////////////////////////////////////////////
11 // CDirTreeCtrl window
12 
13 class CDirTreeCtrl : public CTreeCtrl
14 {
15 // Construction
16 public:
17     CDirTreeCtrl();
18     
19 // Attributes
20 private:
21     LPCTSTR GetSubPath(LPCTSTR strPath);
22     BOOL m_bFiles;
23     CString m_strError;
24     CString m_strRoot;
25     CImageList m_imgList;
26     void ExpandItem( HTREEITEM hItem, UINT nCode);
27     void DisplayPath( HTREEITEM hParent, LPCTSTR strPath);
28     BOOL DisplayDrives();
29     void GetFormatList(CString csPath, CStringArray &aryDwBitmaps);
30     //HTREEITEM AddItem( HTREEITEM hParent, LPCTSTR strPath );
31     HTREEITEM AddItem( HTREEITEM hParent, CString strPath);
32     //BOOL FindSubDir( LPCTSTR strPath );
33     BOOL FindSubDir( CString strPath );
34     BOOL GetSysImgList();
35     CString m_strGloble;
36 
37     
38 // Operations
39 public:
40 
41 // Overrides
42     // ClassWizard generated virtual function overrides
43     //{{AFX_VIRTUAL(CDirTreeCtrl)
44     //}}AFX_VIRTUAL
45 
46 // Implementation
47 public:
48     BOOL SetSelPath(LPCTSTR strPath);
49     BOOL DisplayTree(LPCTSTR strRoot, BOOL bFiles);
50     CString GetFullPath(HTREEITEM hItem);
51     virtual ~CDirTreeCtrl();
52 
53     // Generated message map functions
54 protected:
55     BOOL IsValidPath( LPCTSTR strPath );
56     HTREEITEM SearchSiblingItem( HTREEITEM hItem, LPCTSTR strText );
57     //{{AFX_MSG(CDirTreeCtrl)
58     afx_msg void OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult);
59     //}}AFX_MSG
60 
61     DECLARE_MESSAGE_MAP()
62 };
63 
64 /////////////////////////////////////////////////////////////////////////////
65 
66 //{{AFX_INSERT_LOCATION}}
67 // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
68 
69 #endif // !defined(AFX_DIRTREECTRL_H__0F2536D9_CBE2_4DF2_83F4_621FFD9593C9__INCLUDED_)
View Code

目前很多项目用到的基础类代码,供大家学习

posted @ 2018-05-22 11:27  Jane_bai  阅读(413)  评论(0编辑  收藏  举报