LeftView.cpp
上传用户:jorden
上传日期:2022-08-09
资源大小:83k
文件大小:12k
源码类别:

TreeView控件

开发平台:

Visual C++

  1. // LeftView.cpp : implementation of the CLeftView class
  2. //
  3. #include "stdafx.h"
  4. #include "explorer.h"
  5. #include "explorerDoc.h"
  6. #include "LeftView.h"
  7. #include "explorerView.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. ////////////////////////////////////////////////////////////////////////////
  14. // define my own data
  15. #define ILI_CDDRV     0
  16. #define ILI_CLSDFLD   1
  17. #define ILI_DRIVE     2 
  18. #define ILI_FLOPPYDRV 3 
  19. #define ILI_MYCOMP    4
  20. #define ILI_OPENFLD   5 
  21. #define ILI_TEXTFILE  6 
  22. #define MYCOMPUTER "My Computer"
  23. // define my own data
  24. ////////////////////////////////////////////////////////////////////////////
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CLeftView
  27. IMPLEMENT_DYNCREATE(CLeftView, CTreeView)
  28. BEGIN_MESSAGE_MAP(CLeftView, CTreeView)
  29. //{{AFX_MSG_MAP(CLeftView)
  30. ON_WM_DESTROY()
  31. ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
  32. ON_NOTIFY_REFLECT(TVN_SELCHANGING, OnSelchanging)
  33. //}}AFX_MSG_MAP
  34. // Standard printing commands
  35. ON_COMMAND(ID_FILE_PRINT, CTreeView::OnFilePrint)
  36. ON_COMMAND(ID_FILE_PRINT_DIRECT, CTreeView::OnFilePrint)
  37. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CTreeView::OnFilePrintPreview)
  38. END_MESSAGE_MAP()
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CLeftView construction/destruction
  41. CLeftView::CLeftView()
  42. {
  43. // TODO: add construction code here
  44. }
  45. CLeftView::~CLeftView()
  46. {
  47. }
  48. BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs)
  49. {
  50. // TODO: Modify the Window class or styles here by modifying
  51. //  the CREATESTRUCT cs
  52. cs.style |= TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES;
  53. return CTreeView::PreCreateWindow(cs);
  54. }
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CLeftView drawing
  57. void CLeftView::OnDraw(CDC* pDC)
  58. {
  59. CExplorerDoc* pDoc = GetDocument();
  60. ASSERT_VALID(pDoc);
  61. // TODO: add draw code for native data here
  62. }
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CLeftView printing
  65. BOOL CLeftView::OnPreparePrinting(CPrintInfo* pInfo)
  66. {
  67. // default preparation
  68. return DoPreparePrinting(pInfo);
  69. }
  70. void CLeftView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  71. {
  72. // TODO: add extra initialization before printing
  73. }
  74. void CLeftView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  75. {
  76. // TODO: add cleanup after printing
  77. }
  78. void CLeftView::OnInitialUpdate()
  79. {
  80. CTreeView::OnInitialUpdate();
  81. m_pImageList = new CImageList();
  82. CWinApp* pApp = AfxGetApp();
  83. // ASSERT(m_pImageList != NULL);    // serious allocation failure checking
  84. m_pImageList->Create(16, 16, ILC_COLOR8 | ILC_MASK,  9, 9);
  85. m_pImageList->Add(pApp->LoadIcon(ICO_CDDRV));
  86. m_pImageList->Add(pApp->LoadIcon(ICO_CLSDFLD));
  87. m_pImageList->Add(pApp->LoadIcon(ICO_DRIVE));
  88. m_pImageList->Add(pApp->LoadIcon(ICO_FLOPPYDRV));
  89. m_pImageList->Add(pApp->LoadIcon(ICO_MYCOMP));
  90. m_pImageList->Add(pApp->LoadIcon(ICO_OPENFLD));
  91. m_pImageList->Add(pApp->LoadIcon(ICO_TEXTFILE));
  92. GetTreeCtrl().SetImageList(m_pImageList , TVSIL_NORMAL);
  93. HTREEITEM hParent = GetTreeCtrl().InsertItem(MYCOMPUTER, ILI_MYCOMP, ILI_MYCOMP);
  94. InitTreeView(hParent);
  95. GetTreeCtrl().Expand(hParent, TVE_EXPAND);
  96. // TODO: You may populate your TreeView with items by directly accessing
  97. //  its tree control through a call to GetTreeCtrl().
  98. }
  99. /////////////////////////////////////////////////////////////////////////////
  100. // CLeftView diagnostics
  101. #ifdef _DEBUG
  102. void CLeftView::AssertValid() const
  103. {
  104. CTreeView::AssertValid();
  105. }
  106. void CLeftView::Dump(CDumpContext& dc) const
  107. {
  108. CTreeView::Dump(dc);
  109. }
  110. CExplorerDoc* CLeftView::GetDocument() // non-debug version is inline
  111. {
  112. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CExplorerDoc)));
  113. return (CExplorerDoc*)m_pDocument;
  114. }
  115. #endif //_DEBUG
  116. /////////////////////////////////////////////////////////////////////////////
  117. // CLeftView message handlers
  118. void CLeftView::InitTreeView(HTREEITEM hParent)
  119. {
  120. int nPos = 0;
  121.     UINT nCount = 0;
  122.     CString strDrive = "?:\";
  123.     DWORD dwDriveList = ::GetLogicalDrives ();
  124. CString cTmp;
  125.     while (dwDriveList) {
  126.         if (dwDriveList & 1) {
  127. cTmp = strDrive;
  128.             strDrive.SetAt (0, 0x41 + nPos);
  129.             if (AddDrives(strDrive , hParent))
  130.                 nCount++;
  131.         }
  132.         dwDriveList >>= 1;
  133.         nPos++;
  134.     }
  135.     return;
  136. }
  137. BOOL CLeftView::AddDrives(CString strDrive, HTREEITEM hParent)
  138. {
  139. HTREEITEM hItem;
  140.     UINT nType = ::GetDriveType ((LPCTSTR) strDrive);
  141.     UINT nDrive = (UINT) strDrive[0] - 0x41;
  142.     switch (nType) {
  143.     case DRIVE_REMOVABLE:
  144. hItem = GetTreeCtrl().InsertItem(strDrive, ILI_FLOPPYDRV, ILI_FLOPPYDRV, hParent);
  145. AddDummyNode(hItem);
  146.         break;
  147.     case DRIVE_FIXED:
  148. hItem = GetTreeCtrl().InsertItem(strDrive,  ILI_DRIVE, ILI_DRIVE, hParent);
  149. AddDummyNode(hItem);
  150.         break;
  151.     case DRIVE_REMOTE:
  152.         hItem = GetTreeCtrl().InsertItem(strDrive, ILI_DRIVE, ILI_DRIVE, hParent);
  153. AddDummyNode(hItem);
  154.         break;
  155.     case DRIVE_CDROM:
  156.         hItem = GetTreeCtrl().InsertItem(strDrive, ILI_CDDRV, ILI_CDDRV, hParent);
  157. AddDummyNode(hItem);
  158.         break;
  159.     case DRIVE_RAMDISK:
  160.         hItem = GetTreeCtrl().InsertItem(strDrive, ILI_CDDRV, ILI_CDDRV, hParent);
  161. AddDummyNode(hItem);
  162.         break;
  163.     default:
  164.         return FALSE;
  165.     }
  166. return true;
  167. }
  168. void CLeftView::OnDestroy() 
  169. {
  170. CTreeView::OnDestroy();
  171. // TODO: Add your message handler code here
  172. if(m_pImageList != NULL)
  173. m_pImageList = NULL;
  174. delete m_pImageList;
  175. }
  176. void CLeftView::AddDummyNode(HTREEITEM hItem)
  177. {
  178. GetTreeCtrl().InsertItem ("", 0, 0, hItem);
  179. }
  180. CString CLeftView::GetPathFromItem(HTREEITEM hItem)
  181. {
  182.     CString strPathName;
  183.     while (hItem != NULL) 
  184. {
  185. CString string = GetTreeCtrl().GetItemText (hItem);
  186.         if ((string.Right (1) != "\") && !strPathName.IsEmpty ())
  187.         string += "\";
  188. strPathName = string + strPathName;
  189.         hItem = GetTreeCtrl().GetParentItem (hItem);
  190.     }
  191. if(strPathName.Left(11) == MYCOMPUTER && strPathName.GetLength() > 11)
  192. strPathName = strPathName.Mid(12);
  193. return strPathName;
  194. }
  195. BOOL CLeftView::IsPathValid(CString &strPathName)
  196. {
  197.     if (strPathName.GetLength () == 3)
  198.         return TRUE;
  199.     HANDLE hFind;
  200.     WIN32_FIND_DATA fd;
  201.     BOOL bResult = FALSE;
  202.     if ((hFind = ::FindFirstFile ((LPCTSTR) strPathName, &fd)) !=
  203.         INVALID_HANDLE_VALUE) {
  204.             if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  205.                 bResult = TRUE;
  206.         ::CloseHandle (hFind);
  207.     }
  208.     return bResult;
  209. }
  210. BOOL CLeftView::IsMediaValid(CString &strPathName)
  211. {
  212.     // Return TRUE if the drive doesn't support removable media.
  213.     UINT nDriveType = GetDriveType ((LPCTSTR) strPathName);
  214.     if ((nDriveType != DRIVE_REMOVABLE) && (nDriveType != DRIVE_CDROM))
  215.       return TRUE;
  216. }
  217. HTREEITEM CLeftView::GetDriveNode(HTREEITEM hItem)
  218. {
  219.     HTREEITEM hParent;
  220.     do {
  221.         hParent = GetTreeCtrl().GetParentItem (hItem);
  222.         if (hParent != NULL)
  223.             hItem = hParent;
  224.     } while (hParent != NULL);
  225.     return hItem;
  226. }
  227. UINT CLeftView::DeleteChildren(HTREEITEM hItem)
  228. {
  229.     UINT nCount = 0;
  230.     HTREEITEM hChild = GetTreeCtrl().GetChildItem (hItem);
  231.     while (hChild != NULL) {
  232.         HTREEITEM hNextItem = GetTreeCtrl().GetNextSiblingItem (hChild);
  233.         GetTreeCtrl().DeleteItem (hChild);
  234.         hChild = hNextItem;
  235.         nCount++;
  236. // dwTreeItemCount--;
  237.     }
  238.     return nCount;
  239. }
  240. UINT CLeftView::AddDirectoryNodes(HTREEITEM hItem, CString &strPathName)
  241. {
  242.     HANDLE hFind;
  243.     WIN32_FIND_DATA fd;
  244.     UINT nCount = 0;
  245.     CString strFileSpec = strPathName;
  246.     if (strFileSpec.Right (1) != "\")
  247.         strFileSpec += "\";
  248.     strFileSpec += "*.*";
  249.     if ((hFind = ::FindFirstFile ((LPCTSTR) strFileSpec, &fd)) ==
  250.         INVALID_HANDLE_VALUE) {
  251.         if (IsDriveNode (hItem))
  252.             AddDummyNode (hItem);
  253.         return 0;
  254.     }
  255. CWaitCursor wait;
  256. CExplorerDoc* pDoc = GetDocument();
  257. pDoc->m_ExplorerView->DeleteAllItems();
  258.     do {
  259.         if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
  260. {
  261.             CString strFileName = (LPCTSTR) &fd.cFileName;
  262.             if ((strFileName != ".") && (strFileName != "..")
  263.  && (fd.dwFileAttributes != 22))
  264. {
  265.                 HTREEITEM hChild =
  266.                     GetTreeCtrl().InsertItem ((LPCTSTR) &fd.cFileName,
  267. ILI_CLSDFLD , ILI_OPENFLD , hItem , TVI_SORT);
  268.                 CString strNewPathName = strPathName;
  269.                 if (strNewPathName.Right (1) != "\")
  270.                     strNewPathName += "\";
  271.                 strNewPathName += (LPCTSTR) &fd.cFileName;
  272.                 SetButtonState (hChild, strNewPathName);
  273.                 nCount++;
  274.         }
  275. }
  276. else
  277. {
  278. pDoc->m_ExplorerView->AddToListView(&fd);
  279. }
  280.     } while (::FindNextFile (hFind, &fd));
  281.     ::FindClose (hFind);
  282.     return nCount;
  283. }
  284. void CLeftView::SetButtonState(HTREEITEM hItem, CString &strPathName)
  285. {
  286.     if (HasSubdirectory (strPathName))
  287.         AddDummyNode (hItem);
  288. }
  289. BOOL CLeftView::HasSubdirectory(CString &strPathName)
  290. {
  291.     HANDLE hFind;
  292.     WIN32_FIND_DATA fd;
  293.     BOOL bResult = FALSE;
  294.     CString strFileSpec = strPathName;
  295.     if (strFileSpec.Right (1) != "\")
  296.         strFileSpec += "\";
  297.     strFileSpec += "*.*";
  298.     if ((hFind = ::FindFirstFile ((LPCTSTR) strFileSpec, &fd)) !=
  299.         INVALID_HANDLE_VALUE) {
  300.         do {
  301.             if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  302.                 CString strFileName = (LPCTSTR) &fd.cFileName;
  303.                 if ((strFileName != ".") && (strFileName != ".."))
  304.                     bResult = TRUE;
  305.             }
  306.         } while (::FindNextFile (hFind, &fd) && !bResult);
  307.         ::FindClose (hFind);
  308.     }
  309.     return bResult;
  310. }
  311. BOOL CLeftView::IsDriveNode(HTREEITEM hItem)
  312. {
  313.     return (GetTreeCtrl().GetParentItem (hItem) == NULL) ? TRUE : FALSE;
  314. }
  315. void CLeftView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
  316. {
  317. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  318. // TODO: Add your control notification handler code here
  319.     HTREEITEM hItem = pNMTreeView->itemNew.hItem;
  320.     CString strPathName = GetPathFromItem (hItem);
  321.     if (!IsMediaValid (strPathName)) 
  322. {
  323.         HTREEITEM hRoot = GetDriveNode (hItem);
  324.         GetTreeCtrl().Expand (hRoot, TVE_COLLAPSE);
  325.         DeleteChildren (hRoot);
  326.         AddDummyNode (hRoot);
  327.         *pResult = TRUE;
  328.         return;
  329.     }
  330.     // Delete the item if strPathName no longer specifies a valid path.
  331.     if (!IsPathValid (strPathName)) 
  332. {
  333.         if(strPathName != MYCOMPUTER && strPathName != "")
  334. {
  335. GetTreeCtrl().DeleteItem (hItem);
  336.         *pResult = TRUE;
  337.     return;
  338. }
  339.     }
  340. CWaitCursor wait;
  341.     // If the item is expanding, delete the dummy item attached to it
  342.     // and add folder items. If the item is collapsing instead, delete
  343.     // its folder items and add a dummy item if appropriate.
  344.     if (pNMTreeView->action == TVE_EXPAND) 
  345. {
  346. if(strPathName != MYCOMPUTER)
  347. {
  348. DeleteChildren (hItem);
  349.         if (!AddDirectoryNodes (hItem, strPathName))
  350.         *pResult = TRUE;
  351. }
  352.     }
  353.     else {
  354. if(strPathName != MYCOMPUTER)
  355. {
  356. DeleteChildren (hItem);
  357.         if (IsDriveNode (hItem))
  358.         AddDummyNode (hItem);
  359. else
  360. SetButtonState (hItem, strPathName);
  361. }
  362.     }
  363. m_LocalPath = strPathName;
  364. *pResult = 0;
  365. }
  366. void CLeftView::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult) 
  367. {
  368. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  369. // TODO: Add your control notification handler code here
  370.     HTREEITEM hItem = pNMTreeView->itemNew.hItem;
  371.     CString strPathName = GetPathFromItem (hItem);
  372. *pResult = FALSE;
  373. if(strPathName == MYCOMPUTER)
  374. return;
  375.   CWaitCursor wait;
  376.     if (!AddDirectoryNodes (hItem, strPathName))
  377.        *pResult = TRUE;
  378. m_LocalPath = strPathName;
  379. *pResult = 0;
  380. }