利用VC打造自己的资源浏览器

2010-08-28 10:48:35来源:西部e网作者:

    Windows的资源管理器想必大家都用过,该程序的窗口一分为二,左边的窗口显示本机当前所有驱动器以及驱动器中的所有文件夹,当用户单击文件夹后,如果该文件夹下面还有子文件夹,则上层文件夹展开显示下级的文件夹;否则,右边的窗口显示选择文件夹下的文件。那么这个程序是如何实现的呢?为了说明这个问题,本实例打造了一个简易的资源管理器,它实现了Windows资源管理器的主要功能,在显示文件的属性(如文件的文件名、文件的大小、文件的创建时间)的同时,还可以改变文件显示的方式,如大小图标方式、列表方式等。对于Visual C++初学者来说,这个实例和《实例2:打造自己的IE浏览器》要结合起来细细的学习、消化,这两个实例包含了Visual C++编程中的很多细节知识,如工具栏的处理、树型控件/列表控件的使用、窗口的拆分、字符串的处理等,相信读者朋友可以从中学到很多知识点。本实例代码编译运行后的界面效果如图一所示:


图一、资源管理器界面效果图


  一、 实现方法

  从上面的界面效果图可以看出,在程序中使用了拆分窗口,在拆分的过程中,左边窗口为CTreeView 类的子类CLeftView,右边的窗口为CListView类的子类CdriveExplorerView。窗口的拆分和CTreeView、CListView类不是本实例讲述的重点,相关的知识在本书的实例中都有介绍,读者朋友可以参阅上述内容及实例的原代码,这里主要介绍程序中一些具体的细节知识。

  资源管理器中一个重要的问题是如何得到本机中的驱动器信息,微软提供的有关驱动器的API函数有GetLogicalDrives(),GetDriveType()。

  对于喜欢操作位和字节的汇编语言使用者来说,GetLogicalDrives()是个很好用的API函数。它以位掩码的形式返回逻辑驱动器。即在一个DWORD类型的返回值中,位0(最小的一位)表示驱动器A,位1表示驱动器B,以此类推。每一个位的状态如果是on,则表示对应的逻辑驱动器存在;否则状态为off,表示对应的逻辑驱动器不存在。大家知道DWORD是一个32位的值,足以包括所有的英文字母,也就是说最多可有26个盘符。

  为了确定某个逻辑驱动器的类型,必须调用GetDriveType()函数。它以路径名作为参数(如C:\),返回DRIVE_FIXED,DRIVE_REMOVABLE,或DRIVE_UNKNOWN。下面列出了所有可能返回的值:这些值在winbase.h定义

#define DRIVE_UNKNOWN 0 // 无效路径名
#define DRIVE_NO_ROOT_DIR 1 // 无效路经,如无法找到的卷标
#define DRIVE_REMOVABLE 2 // 可移动驱动器(如磁盘驱动器,光驱等)
#define DRIVE_FIXED 3 // 固定的驱动器 (如 通常的硬盘)
#define DRIVE_REMOTE 4 // 网络驱动器
#define DRIVE_CDROM 5 // CD-ROM
#define DRIVE_RAMDISK 6 // 随机存取(RAM) 磁盘

  有了驱动器的信息,就可以使用FindFirstFile()、FindNextFile()等函数来获取驱动器下面的文件或文件夹信息(相关内容参加《实例:修改文件或文件夹的属性》),然后分别添加到树型视图和列表视图中。

  最后要说明的一点是需要根据不同的状态和文件类型在视图中显示不同的图表,这些可以通过设置列表视图的窗口风格、树状视图的项目条的图标来实现,具体参见代码部分。

  二、编程步骤

  1、 启动Visual C++6.0,生成一个单文档视图的应用程序,视图类的基类选择CListView,项目命名为"DriveExplorer",同时在项目中添加图标资源、菜单和菜单响应函数(详细内容参见原代码);

  2、 使用Class Wizard为项目添加新类CLeftView类,其基类选择CtreeView;

  3、 添加代码,编译运行程序。


    三、程序代码

/////////////////////////////////////////////////////// LeftView.h : interface of the CLeftView class
#if !defined(AFX_LEFTVIEW_H__29F66875_4E46_11D6_9693_B383368EF622__INCLUDED_)
#define AFX_LEFTVIEW_H__29F66875_4E46_11D6_9693_B383368EF622__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CDriveExplorerDoc;

class CLeftView : public CTreeView
{
protected: // create from serialization only
 CLeftView();
 DECLARE_DYNCREATE(CLeftView)
 // Attributes
public:
 CDriveExplorerDoc* GetDocument();
 CImageList* m_pImageList;
 CString m_LocalPath;
 // Operations
public:
 BOOL HasSubdirectory(CString &strPathName);
 BOOL IsDriveNode(HTREEITEM hItem);
 void SetButtonState(HTREEITEM hItem, CString &strPathName);
 UINT AddDirectoryNodes(HTREEITEM hItem, CString &strPathName);
 BOOL IsMediaValid(CString &strPathName);
 HTREEITEM GetDriveNode(HTREEITEM hItem);
 UINT DeleteChildren(HTREEITEM hItem);
 BOOL IsPathValid(CString &strPathName);
 CString GetPathFromItem(HTREEITEM hItem);
 void AddDummyNode(HTREEITEM hItem);
 void InitTreeView(HTREEITEM hParent);
 BOOL AddDrives(CString strDrive, HTREEITEM hParent);
 // Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CLeftView)
public:
 virtual void OnDraw(CDC* pDC); // overridden to draw this view
 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
 virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
 virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
 virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
 virtual void OnInitialUpdate(); // called first time after construct
//}}AFX_VIRTUAL
// Implementation
public:
 virtual ~CLeftView();
 #ifdef _DEBUG
  virtual void AssertValid() const;
  virtual void Dump(CDumpContext& dc) const;
 #endif
protected:
 // Generated message map functions
protected:
 //{{AFX_MSG(CLeftView)
  // NOTE - the ClassWizard will add and remove member functions here.
  // DO NOT EDIT what you see in these blocks of generated code !
  afx_msg void OnDestroy();
  afx_msg void OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult);
  afx_msg void OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult);
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in LeftView.cpp
 inline CDriveExplorerDoc* CLeftView::GetDocument()
 { return (CDriveExplorerDoc*)m_pDocument; }
#endif
#endif

////////////////////////////////////////////////////////// CLeftView
#include "stdafx.h"
#include "DriveExplorer.h"
#include "DriveExplorerDoc.h"
#include "LeftView.h"
#include "DriveExplorerView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ILI_CDDRV 0
#define ILI_CLSDFLD 1
#define ILI_DRIVE 2
#define ILI_FLOPPYDRV 3
#define ILI_MYCOMP 4
#define ILI_OPENFLD 5
#define ILI_TEXTFILE 6
#define MYCOMPUTER "My Computer"
IMPLEMENT_DYNCREATE(CLeftView, CTreeView)
BEGIN_MESSAGE_MAP(CLeftView, CTreeView)
//{{AFX_MSG_MAP(CLeftView)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
ON_WM_DESTROY()
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
ON_NOTIFY_REFLECT(TVN_SELCHANGING, OnSelchanging)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CTreeView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CTreeView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CTreeView::OnFilePrintPreview)
END_MESSAGE_MAP()

///////////////////////////////////// CLeftView construction/destruction
CLeftView::CLeftView()
{
 // TODO: add construction code here
}

CLeftView::~CLeftView()
{}

BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying the CREATESTRUCT cs
cs.style |= TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES;
 return CTreeView::PreCreateWindow(cs);
}
void CLeftView::OnDraw(CDC* pDC)
{
 CDriveExplorerDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here
}

BOOL CLeftView::OnPreparePrinting(CPrintInfo* pInfo)
{
 // default preparation
 return DoPreparePrinting(pInfo);
}

void CLeftView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
 // TODO: add extra initialization before printing
}

void CLeftView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
 // TODO: add cleanup after printing
}

void CLeftView::OnInitialUpdate()
{
 CTreeView::OnInitialUpdate();
 m_pImageList = new CImageList();
 CWinApp* pApp = AfxGetApp();
 // ASSERT(m_pImageList != NULL); // serious allocation failure checking
 m_pImageList->Create(16, 16, ILC_COLOR8 | ILC_MASK, 9, 9);
 m_pImageList->Add(pApp->LoadIcon(ICO_CDDRV));
 m_pImageList->Add(pApp->LoadIcon(ICO_CLSDFLD));
 m_pImageList->Add(pApp->LoadIcon(ICO_DRIVE));
 m_pImageList->Add(pApp->LoadIcon(ICO_FLOPPYDRV));
 m_pImageList->Add(pApp->LoadIcon(ICO_MYCOMP));
 m_pImageList->Add(pApp->LoadIcon(ICO_OPENFLD));
 m_pImageList->Add(pApp->LoadIcon(ICO_TEXTFILE));
 GetTreeCtrl().SetImageList(m_pImageList , TVSIL_NORMAL);
 HTREEITEM hParent = GetTreeCtrl().InsertItem(MYCOMPUTER,
 ILI_MYCOMP, ILI_MYCOMP);
 InitTreeView(hParent);
 GetTreeCtrl().Expand(hParent, TVE_EXPAND);
}

#ifdef _DEBUG
void CLeftView::AssertValid() const
{
 CTreeView::AssertValid();
}

void CLeftView::Dump(CDumpContext& dc) const
{
 CTreeView::Dump(dc);
}

CDriveExplorerDoc* CLeftView::GetDocument() // non-debug version is inline
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDriveExplorerDoc)));
 return (CDriveExplorerDoc*)m_pDocument;
}
#endif //_DEBUG

void CLeftView::InitTreeView(HTREEITEM hParent)
{
 int nPos = 0;
 UINT nCount = 0;
 CString strDrive = "?:\\";
 DWORD dwDriveList = ::GetLogicalDrives ();
 CString cTmp;
 while (dwDriveList) {
  if (dwDriveList & 1) {
   cTmp = strDrive;
   strDrive.SetAt (0, 0x41 + nPos);
   if (AddDrives(strDrive , hParent))
    nCount++;
  }
  dwDriveList >>= 1;
  nPos++;
 }
 return;
}

BOOL CLeftView::AddDrives(CString strDrive, HTREEITEM hParent)
{
 HTREEITEM hItem;
 UINT nType = ::GetDriveType ((LPCTSTR) strDrive);
 UINT nDrive = (UINT) strDrive[0] - 0x41;
 switch (nType) {
  case DRIVE_REMOVABLE:
   hItem = GetTreeCtrl().InsertItem(strDrive, ILI_FLOPPYDRV, ILI_FLOPPYDRV, hParent);
   AddDummyNode(hItem);
   break;
  case DRIVE_FIXED:
   hItem = GetTreeCtrl().InsertItem(strDrive, ILI_DRIVE, ILI_DRIVE, hParent);
   AddDummyNode(hItem);
   break;
  case DRIVE_REMOTE:
   hItem = GetTreeCtrl().InsertItem(strDrive, ILI_DRIVE, ILI_DRIVE, hParent);
   AddDummyNode(hItem);
   break;
  case DRIVE_CDROM:
   hItem = GetTreeCtrl().InsertItem(strDrive, ILI_CDDRV, ILI_CDDRV, hParent);
   AddDummyNode(hItem);
   break;
  case DRIVE_RAMDISK:
   hItem = GetTreeCtrl().InsertItem(strDrive, ILI_CDDRV, ILI_CDDRV, hParent);
   AddDummyNode(hItem);
   break;
  default:
   return FALSE;
 }
 return true;
}

void CLeftView::OnDestroy()
{
 CTreeView::OnDestroy();
 // TODO: Add your message handler code here
 if(m_pImageList != NULL)
  m_pImageList = NULL;
  delete m_pImageList;
}

void CLeftView::AddDummyNode(HTREEITEM hItem)
{
 GetTreeCtrl().InsertItem ("", 0, 0, hItem);
}

CString CLeftView::GetPathFromItem(HTREEITEM hItem)
{
 CString strPathName;
 while (hItem != NULL)
 {
  CString string = GetTreeCtrl().GetItemText (hItem);
  if ((string.Right (1) != "\\") && !strPathName.IsEmpty ())
   string += "\\";
  strPathName = string + strPathName;
  hItem = GetTreeCtrl().GetParentItem (hItem);
 }
 if(strPathName.Left(11) == MYCOMPUTER && strPathName.GetLength() > 11)
  strPathName = strPathName.Mid(12);
 return strPathName;
}

BOOL CLeftView::IsPathValid(CString &strPathName)
{
 if (strPathName.GetLength () == 3)
  return TRUE;
 HANDLE hFind;
 WIN32_FIND_DATA fd;
 BOOL bResult = FALSE;
 if ((hFind = ::FindFirstFile ((LPCTSTR) strPathName, &fd)) !=INVALID_HANDLE_VALUE) {
  if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
   bResult = TRUE;
   ::CloseHandle (hFind);
 }
 return bResult;
}

BOOL CLeftView::IsMediaValid(CString &strPathName)
{
 // Return TRUE if the drive doesn't support removable media.
 UINT nDriveType = GetDriveType ((LPCTSTR) strPathName);
 if ((nDriveType != DRIVE_REMOVABLE) && (nDriveType != DRIVE_CDROM))
  return TRUE;
}

HTREEITEM CLeftView::GetDriveNode(HTREEITEM hItem)
{
 HTREEITEM hParent;
 do {
  hParent = GetTreeCtrl().GetParentItem (hItem);
  if (hParent != NULL)
   hItem = hParent;
 } while (hParent != NULL);
 return hItem;
}

UINT CLeftView::DeleteChildren(HTREEITEM hItem)
{
 UINT nCount = 0;
 HTREEITEM hChild = GetTreeCtrl().GetChildItem (hItem);
 while (hChild != NULL) {
  HTREEITEM hNextItem = GetTreeCtrl().GetNextSiblingItem (hChild);
  GetTreeCtrl().DeleteItem (hChild);
  hChild = hNextItem;
  nCount++;
 }
 return nCount;
}

UINT CLeftView::AddDirectoryNodes(HTREEITEM hItem, CString &strPathName)
{
 HANDLE hFind;
 WIN32_FIND_DATA fd;
 UINT nCount = 0;
 CString strFileSpec = strPathName;
 if (strFileSpec.Right (1) != "\\")
  strFileSpec += "\\";
 strFileSpec += "*.*";
 if ((hFind = ::FindFirstFile ((LPCTSTR) strFileSpec, &fd)) ==INVALID_HANDLE_VALUE)
 {
  if (IsDriveNode (hItem))
   AddDummyNode (hItem);
  return 0;
 }
 CWaitCursor wait;
 CDriveExplorerDoc* pDoc = GetDocument();
 pDoc->m_ExplorerView->DeleteAllItems();
 do {
  if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  {
   CString strFileName = (LPCTSTR) &fd.cFileName;
   if ((strFileName != ".") && (strFileName != "..")&& (fd.dwFileAttributes != 22))
   {
    HTREEITEM hChild =GetTreeCtrl().InsertItem ((LPCTSTR) &fd.cFileName,ILI_CLSDFLD , ILI_OPENFLD , hItem , TVI_SORT);
    CString strNewPathName = strPathName;
    if (strNewPathName.Right (1) != "\\")
     strNewPathName += "\\";
     strNewPathName += (LPCTSTR) &fd.cFileName;
     SetButtonState (hChild, strNewPathName);
     nCount++;
   }
  }
  else
  {
   pDoc->m_ExplorerView->AddToListView(&fd);
  }
 } while (::FindNextFile (hFind, &fd));
 ::FindClose (hFind);
 return nCount;
}

void CLeftView::SetButtonState(HTREEITEM hItem, CString &strPathName)
{
 if (HasSubdirectory (strPathName))
  AddDummyNode (hItem);
}

BOOL CLeftView::HasSubdirectory(CString &strPathName)
{
 HANDLE hFind;
 WIN32_FIND_DATA fd;
 BOOL bResult = FALSE;
 CString strFileSpec = strPathName;
 if (strFileSpec.Right (1) != "\\")
  strFileSpec += "\\";
 strFileSpec += "*.*";
 if ((hFind = ::FindFirstFile ((LPCTSTR) strFileSpec, &fd)) !=INVALID_HANDLE_VALUE)
 {
  do {
   if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
   {
    CString strFileName = (LPCTSTR) &fd.cFileName;
    if ((strFileName != ".") && (strFileName != ".."))
     bResult = TRUE;
   }
  } while (::FindNextFile (hFind, &fd) && !bResult);
   ::FindClose (hFind);
 }
 return bResult;
}

BOOL CLeftView::IsDriveNode(HTREEITEM hItem)
{
 return (GetTreeCtrl().GetParentItem (hItem) == NULL) ? TRUE : FALSE;
}

void CLeftView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
 NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
 HTREEITEM hItem = pNMTreeView->itemNew.hItem;
 CString strPathName = GetPathFromItem (hItem);
 if (!IsMediaValid (strPathName))
 {
  HTREEITEM hRoot = GetDriveNode (hItem);
  GetTreeCtrl().Expand (hRoot, TVE_COLLAPSE);
  DeleteChildren (hRoot);
  AddDummyNode (hRoot);
  *pResult = TRUE;
  return;
 }
 // Delete the item if strPathName no longer specifies a valid path.
 if (!IsPathValid (strPathName))
 {
  if(strPathName != MYCOMPUTER && strPathName != "")
  {
   GetTreeCtrl().DeleteItem (hItem);
   *pResult = TRUE;
   return;
  }
 }
 CWaitCursor wait;
 if (pNMTreeView->action == TVE_EXPAND)
 {
  if(strPathName != MYCOMPUTER)
  {
   DeleteChildren (hItem);
   if (!AddDirectoryNodes (hItem, strPathName))
    *pResult = TRUE;
  }
 }
 else {
  if(strPathName != MYCOMPUTER)
  {
   DeleteChildren (hItem);
   if (IsDriveNode (hItem))
    AddDummyNode (hItem);
   else
    SetButtonState (hItem, strPathName);
  }
 }
 m_LocalPath = strPathName;
 *pResult = 0;
}

void CLeftView::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult)
{
 NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
 // TODO: Add your control notification handler code here
 HTREEITEM hItem = pNMTreeView->itemNew.hItem;
 CString strPathName = GetPathFromItem (hItem);
 *pResult = FALSE;
 if(strPathName == MYCOMPUTER)
  return;
 CWaitCursor wait;
 if (!AddDirectoryNodes (hItem, strPathName))
  *pResult = TRUE;
 m_LocalPath = strPathName;
 *pResult = 0;
}

////////////////////////////////////// DriveExplorerView.h : interface of the CDriveExplorerView class
#if !defined(AFX_DRIVEEXPLORERVIEW_H__29F66873_4E46_11D6_9693_B383368EF622__INCLUDED_)
#define AFX_DRIVEEXPLORERVIEW_H__29F66873_4E46_11D6_9693_B383368EF622__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CDriveExplorerView : public CListView
{
 protected: // create from serialization only
  CDriveExplorerView();
  DECLARE_DYNCREATE(CDriveExplorerView)
  // Attributes
 public:
  CDriveExplorerDoc* GetDocument();
  CImageList* m_pImageList;
  CImageList* m_pImageListL;
  // Operations
 public:
  // Overrides
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CDriveExplorerView)
   public:
    virtual void OnDraw(CDC* pDC); // overridden to draw this view
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
   protected:
    virtual void OnInitialUpdate(); // called first time after construct
    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
  //}}AFX_VIRTUAL
  // Implementation
 public:
  void SetupImages(CImageList* mImageList, int iSize);
  UINT GetListViewIcon(CString s);
  CString GetFileType(CString s);
  LPTSTR GetNTS(CString cString);
  void AddToListView(WIN32_FIND_DATA* fd);
  void DeleteAllItems();
  virtual ~CDriveExplorerView();
  #ifdef _DEBUG
   virtual void AssertValid() const;
   virtual void Dump(CDumpContext& dc) const;
  #endif
 protected:
  // Generated message map functions
 protected:
  //{{AFX_MSG(CDriveExplorerView)
   afx_msg void OnDestroy();
   afx_msg void OnSize(UINT nType, int cx, int cy);
  //}}AFX_MSG
  afx_msg void OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct);
  DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in DriveExplorerView.cpp
inline CDriveExplorerDoc* CDriveExplorerView::GetDocument()
{ return (CDriveExplorerDoc*)m_pDocument; }
#endif
#endif

//////////////////////////////// DriveExplorerView.cpp : implementation of the CDriveExplorerView class
#include "stdafx.h"
#include "DriveExplorer.h"
#include "DriveExplorerDoc.h"
#include "DriveExplorerView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ICI_ACCESSFILE 0
#define ICI_C_SOURCE 1
#define ICI_CDDRV 2
#define ICI_CLSDFLD 3
#define ICI_CURSORFILE 4
#define ICI_DRIVE 5
#define ICI_DRIVERSFILE 6
#define ICI_ERROR 7
#define ICI_EXCELFILE 8
#define ICI_EXCLAMATION 9
#define ICI_EXEFILE 10
#define ICI_FLOPPYDRV 11
#define ICI_FONTFILE 12
#define ICI_FOXPROFILE 13
#define ICI_GENERALFILE 14
#define ICI_HEADERFILE 15
#define ICI_HELPFILE 16
#define ICI_HTMLDOC 17
#define ICI_HTMLHELP 18
#define ICI_IMAGEFILE 19
#define ICI_INFO 20
#define ICI_JAVABEAN 21
#define ICI_JAVACLASSES 22
#define ICI_JAVASOURCE 23
#define ICI_MYCOMPUTER 24
#define ICI_OPENFLD 25
#define ICI_PDFFILE 26
#define ICI_QUESTION 27
#define ICI_REGISTRYFILE 28
#define ICI_SETUPFILE 29
#define ICI_SOUNDFILE 30
#define ICI_TEXTFILE 31
#define ICI_TRASHFILE 32
#define ICI_UNINSTALLFILE 33
#define ICI_VIDEOFILE 34
#define ICI_WINDOWSFILE 35
#define ICI_WORDDOC 36
#define ICI_ZIPFILE 37
#define ICI_CDUP 38

///////////////////////////////////////////////////////////// CDriveExplorerView
IMPLEMENT_DYNCREATE(CDriveExplorerView, CListView)
BEGIN_MESSAGE_MAP(CDriveExplorerView, CListView)
//{{AFX_MSG_MAP(CDriveExplorerView)
 ON_WM_DESTROY()
 ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CDriveExplorerView::CDriveExplorerView()
{
 // TODO: add construction code here
}

CDriveExplorerView::~CDriveExplorerView()
{}

BOOL CDriveExplorerView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 // the CREATESTRUCT cs
 cs.style |= LVS_REPORT;
 return CListView::PreCreateWindow(cs);
}

void CDriveExplorerView::OnDraw(CDC* pDC)
{
 CDriveExplorerDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 CListCtrl& refCtrl = GetListCtrl();
 refCtrl.InsertItem(0, "Item!");
 // TODO: add draw code for native data here
}

void CDriveExplorerView::OnInitialUpdate()
{
 CListView::OnInitialUpdate();
 CDriveExplorerDoc* pDoc = GetDocument();
 pDoc->m_ExplorerView = this;
 CRect rect;
 GetClientRect(&rect);
 GetListCtrl().InsertColumn(0, "File Name", LVCFMT_LEFT , rect.right / 2 , -1);
 GetListCtrl().InsertColumn(1, "Size", LVCFMT_LEFT , rect.right / 4 , -1);
 GetListCtrl().InsertColumn(2, "Date", LVCFMT_LEFT , rect.right / 4 , -1);
 m_pImageList = new CImageList();
 m_pImageListL = new CImageList();
 SetupImages(m_pImageList, 16);
 SetupImages(m_pImageListL, 32);
 GetListCtrl().SetImageList(m_pImageList, LVSIL_SMALL);
 GetListCtrl().SetImageList(m_pImageListL, LVSIL_NORMAL);
}

#ifdef _DEBUG
void CDriveExplorerView::AssertValid() const
{
 CListView::AssertValid();
}

void CDriveExplorerView::Dump(CDumpContext& dc) const
{
 CListView::Dump(dc);
}

CDriveExplorerDoc* CDriveExplorerView::GetDocument() // non-debug version is inline
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDriveExplorerDoc)));
 return (CDriveExplorerDoc*)m_pDocument;
}
#endif //_DEBUG

void CDriveExplorerView::OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
{
 //TODO: add code to react to the user changing the view style of your window
}

void CDriveExplorerView::DeleteAllItems()
{
 GetListCtrl().DeleteAllItems();
}

void CDriveExplorerView::AddToListView(WIN32_FIND_DATA *fd)
{
 LV_ITEM lvitem;
 char sNumBuff[100];
 int iActualItem;
 CString sText;
 lvitem.mask = LVIF_TEXT | LVIF_IMAGE;
 lvitem.iItem = 0;
 lvitem.iSubItem = 0;
 lvitem.pszText = GetNTS(fd->cFileName); // fd.cFileName;
 lvitem.iImage = GetListViewIcon(fd->cFileName); //SetFileIcon(fd->GetFileName());
 iActualItem = GetListCtrl().InsertItem(&lvitem);
 // Add Attribute column
 lvitem.mask = LVIF_TEXT;
 lvitem.iItem = iActualItem;
 lvitem.iSubItem = 1;
 lvitem.pszText = GetNTS(GetFileType(fd->cFileName));
 GetListCtrl().SetItem(&lvitem);
 // Add Size column
 if(fd->nFileSizeLow != 0)
  ltoa((long)fd->nFileSizeLow,sNumBuff,10);
 else
  strcpy(sNumBuff,"");
  lvitem.mask = LVIF_TEXT;
  lvitem.iItem = iActualItem;
  lvitem.iSubItem = 2;
  lvitem.pszText = sNumBuff;
  GetListCtrl().SetItem(&lvitem);
  // Add Time column
  CTime refTime;
  refTime = fd->ftCreationTime;
  sText = refTime.Format( "%b-%d-%Y" );
  lvitem.mask = LVIF_TEXT;
  lvitem.iItem = iActualItem;
  lvitem.iSubItem = 3;
  lvitem.pszText = sText.GetBuffer(sText.GetLength());
  GetListCtrl().SetItem(&lvitem);
}

LPTSTR CDriveExplorerView::GetNTS(CString cString)
{
 LPTSTR lpsz = new TCHAR[cString.GetLength()+1];
 _tcscpy(lpsz, cString);
 return lpsz;
}

CString CDriveExplorerView::GetFileType(CString s)
{
 CString cResult;
 int nFoundAt = s.Find("." , 0);
 s.MakeUpper();
 if(nFoundAt == 0)
  return s + " File";
 CString ext = s.Mid(nFoundAt);
 if(ext == ".PDF") return "PDF File";
 if(ext == ".CPP") return "VC Source";
 if(ext == ".H") return "Header File";
 if(ext == ".C") return "C Source";
 else if(s == "SETUP.EXE") return "SETUP File";
 else if(s == "ISUNINST.EXE") return "UNINSTALL File";
 else if(ext == ".TXT" || ext == ".LOG") return "TEXT File";
 else if(ext == ".ZIP" || ext == ".ARJ" || ext == ".TGZ" || ext == ".RAR" || ext == ".TAR" || ext == ".LZH" ||
ext == ".LZA" || ext == ".CAB")
  return "ZIP File";
 else if(ext == ".EXE" || ext == ".COM" || ext == ".BAT")
  return "Application";
 else if(ext == ".AU" || ext == ".WAV" || ext == ".MP3")
  return "SOUND File";
 else if(ext == ".HTM" || ext == ".HTML") return "HTML Document";
 else if(ext == ".DOC") return "WORD Document";
 else if(ext == ".MPG" || ext == ".MPEG" || ext == ".AVI")
  return ICI_VIDEOFILE;
 else if(ext == ".HLP") return "HELP File";
 else if(ext == ".BMP") return "Bitmap File";
 else if(ext == ".ICO") return "Icon File";
 else if(ext == ".DBF" || ext == ".DBT" || ext == ".MEM")
  return "FOXPRO File";
 else if(ext == ".DLL" || ext == ".SYS" || ext == ".OCX" ||ext == ".VXD" || ext == ".INI" ||ext == ".DRV")
  return "DRIVERS File";
 else if(ext == ".JPG" || ext == ".GIF" || ext == ".JPEG" || ext == ".AIS" || ext == ".EMF" || ext == ".IFF" ||
ext == ".KDC" || ext == ".PCD" || ext == ".PCX" ||ext == ".PIC" || ext == ".PIX" || ext == ".PNG" ||
ext == ".PSD" || ext == ".SGI" || ext == ".TIF" ||ext == ".TIFF" || ext == ".WMF")
  return "Picture File";
 else if(ext == ".TSK" || ext == ".CPX" || ext == ".ROM" ||ext == ".CFG" || ext == ".STF" || ext == ".LST" ||
ext == ".INF")
  return "WINDOWS File";
 else if(ext == ".CUR" || ext == ".ANI") return "CURSOR File";
 else if(ext == ".FON") return "FONT File";
 else if(ext == ".BAK") return "Backup File";
 else if(ext == ".JAVA") return "JAVA Source";
 else if(ext == ".CLASS") return "JAVA Class";
 else if(ext == ".BEAN") return "JAVA Bean";
 else if(ext == ".REG") return "REGISTRY File";
 else if(ext == ".MDB") return "ACCESS Database";
 else if(ext == ".XLS") return "EXCEL File";
 else if(ext == ".CHM") return "HTML Help";
 else
 {
  ext = ext.Mid( (ext.Find('.',0) != -1 ? 1 : 0));
  return ext + " File";
 }
 return cResult;
}

UINT CDriveExplorerView::GetListViewIcon(CString s)
{
 int nFoundAt = s.Find("." , 1);
 s.MakeUpper();
 if(nFoundAt == 0)
  return ICI_GENERALFILE;
  CString ext = s.Mid(nFoundAt);
  // Set some standard icon types
  if(ext == ".PDF") return ICI_PDFFILE;
  else if(s == "SETUP.EXE") return ICI_SETUPFILE;
  else if(s == "ISUNINST.EXE") return ICI_UNINSTALLFILE;
  else if(ext == ".TXT" || ext == ".LOG") return ICI_TEXTFILE;
  else if(ext == ".ZIP" || ext == ".ARJ" || ext == ".TGZ" || ext == ".RAR" || ext == ".TAR" || ext == ".LZH" ||
ext == ".LZA" || ext == ".CAB")
   return ICI_ZIPFILE;
  else if(ext == ".EXE" || ext == ".COM" || ext == ".BAT")
   return ICI_EXEFILE;
  else if(ext == ".AU" || ext == ".WAV" || ext == ".MP3")
   return ICI_SOUNDFILE;
  else if(ext == ".HTM" || ext == ".HTML") return ICI_HTMLDOC;
  else if(ext == ".DOC") return ICI_WORDDOC;
  else if(ext == ".MPG" || ext == ".MPEG" || ext == ".AVI")
   return ICI_VIDEOFILE;
  else if(ext == ".HLP") return ICI_HELPFILE;
  else if(ext == ".BMP") return ICI_IMAGEFILE;
  else if(ext == ".ICO") return ICI_IMAGEFILE;
  else if(ext == ".DBF" || ext == ".DBT" || ext == ".MEM")
   return ICI_FOXPROFILE;
  else if(ext == ".DLL" || ext == ".SYS" || ext == ".OCX" ||ext == ".VXD" || ext == ".INI" ||ext == ".DRV")
   return ICI_DRIVERSFILE;
  else if(ext == ".JPG" || ext == ".GIF" || ext == ".JPEG" || ext == ".AIS" || ext == ".EMF" || ext == ".IFF" ||
ext == ".KDC" || ext == ".PCD" || ext == ".PCX" ||ext == ".PIC" || ext == ".PIX" || ext == ".PNG" ||
ext == ".PSD" || ext == ".SGI" || ext == ".TIF" ||ext == ".TIFF" || ext == ".WMF")
   return ICI_IMAGEFILE;
  else if(ext == ".TSK" || ext == ".CPX" || ext == ".ROM" ||ext == ".CFG" || ext == ".STF" || ext == ".LST" ||
ext == ".INF")
   return ICI_WINDOWSFILE;
  else if(ext == ".CUR" || ext == ".ANI") return ICI_CURSORFILE;
  else if(ext == ".FON") return ICI_FONTFILE;
  else if(ext == ".BAK") return ICI_TRASHFILE;
  else if(ext == ".JAVA") return ICI_JAVASOURCE;
  else if(ext == ".CLASS") return ICI_JAVACLASSES;
  else if(ext == ".BEAN") return ICI_JAVABEAN;
  else if(ext == ".REG") return ICI_REGISTRYFILE;
  else if(ext == ".MDB") return ICI_ACCESSFILE;
  else if(ext == ".XLS") return ICI_EXCELFILE;
  else if(ext == ".CHM") return ICI_HTMLHELP;
  else
   return ICI_GENERALFILE;
}

void CDriveExplorerView::SetupImages(CImageList* mImageList, int iSize)
{
 CWinApp* pApp = AfxGetApp();
 // ASSERT(m_pImageList != NULL); // serious allocation failure checking
 mImageList->Create(iSize, iSize, ILC_COLOR8 | ILC_MASK, 9, 9);
 mImageList->Add(pApp->LoadIcon(ICO_ACCESSFILE));
 mImageList->Add(pApp->LoadIcon(ICO_C_SOURCE));
 mImageList->Add(pApp->LoadIcon(ICO_CDDRV));
 mImageList->Add(pApp->LoadIcon(ICO_CLSDFLD));
 mImageList->Add(pApp->LoadIcon(ICO_CURSORFILE));
 mImageList->Add(pApp->LoadIcon(ICO_DRIVE));
 mImageList->Add(pApp->LoadIcon(ICO_DRIVERSFILE));
 mImageList->Add(pApp->LoadIcon(ICO_ERROR));
 mImageList->Add(pApp->LoadIcon(ICO_EXCELFILE));
 mImageList->Add(pApp->LoadIcon(ICO_EXCLAMATION));
 mImageList->Add(pApp->LoadIcon(ICO_EXEFILE));
 mImageList->Add(pApp->LoadIcon(ICO_FLOPPYDRV));
 mImageList->Add(pApp->LoadIcon(ICO_FONTFILE));
 mImageList->Add(pApp->LoadIcon(ICO_FOXPROFILE));
 mImageList->Add(pApp->LoadIcon(ICO_GENERALFILE));
 mImageList->Add(pApp->LoadIcon(ICO_HEADERFILE));
 mImageList->Add(pApp->LoadIcon(ICO_HELPFILE));
 mImageList->Add(pApp->LoadIcon(ICO_HTMLDOC));
 mImageList->Add(pApp->LoadIcon(ICO_HTMLHELP));
 mImageList->Add(pApp->LoadIcon(ICO_IMAGEFILE));
 mImageList->Add(pApp->LoadIcon(ICO_INFO));
 mImageList->Add(pApp->LoadIcon(ICO_JAVABEAN));
 mImageList->Add(pApp->LoadIcon(ICO_JAVACLASSES));
 mImageList->Add(pApp->LoadIcon(ICO_JAVASOURCE));
 mImageList->Add(pApp->LoadIcon(ICO_MYCOMP));
 mImageList->Add(pApp->LoadIcon(ICO_OPENFLD));
 mImageList->Add(pApp->LoadIcon(ICO_PDFFILE));
 mImageList->Add(pApp->LoadIcon(ICO_QUESTION));
 mImageList->Add(pApp->LoadIcon(ICO_REGISTRYFILE));
 mImageList->Add(pApp->LoadIcon(ICO_SETUPFILE));
 mImageList->Add(pApp->LoadIcon(ICO_SOUNDFILE));
 mImageList->Add(pApp->LoadIcon(ICO_TEXTFILE));
 mImageList->Add(pApp->LoadIcon(ICO_TRASHFILE));
 mImageList->Add(pApp->LoadIcon(ICO_UNINSTALLFILE));
 mImageList->Add(pApp->LoadIcon(ICO_VIDEOFILE));
 mImageList->Add(pApp->LoadIcon(ICO_WINDOWSFILE));
 mImageList->Add(pApp->LoadIcon(ICO_WORDDOC));
 mImageList->Add(pApp->LoadIcon(ICO_ZIPFILE));
 mImageList->Add(pApp->LoadIcon(ICO_CDUP));
 return ;
}

void CDriveExplorerView::OnDestroy()
{
 CListView::OnDestroy();
 // TODO: Add your message handler code here
 if(m_pImageList != NULL)
  m_pImageList = NULL;
 if(m_pImageListL != NULL)
  m_pImageListL = NULL;
 delete m_pImageList;
 delete m_pImageListL;
}

void CDriveExplorerView::OnSize(UINT nType, int cx, int cy)
{
 CListView::OnSize(nType, cx, cy);

 // TODO: Add your message handler code here
 if(GetListCtrl().GetSafeHwnd())
 {
  GetListCtrl().SetColumnWidth(0, cx / 2);
  GetListCtrl().SetColumnWidth(1, cx / 4);
  GetListCtrl().SetColumnWidth(2, cx / 4);
 }
}

///////////////////////////////////////////////////////////////////////////////////
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext)
{
 // create splitter window
 if (!m_wndSplitter.CreateStatic(this, 1, 2))
  return FALSE;
 if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView),
CSize(100, 100), pContext) ||!m_wndSplitter.CreateView(0, 1,
RUNTIME_CLASS(CDriveExplorerView), CSize(100, 100), pContext))
 {
  m_wndSplitter.DestroyWindow();
  return FALSE;
 }
 m_wndSplitter.SetColumnInfo(0, 200, 100);
 return TRUE;
}

CDriveExplorerView* CMainFrame::GetRightPane()
{
 CDriveExplorerView* pView=(CDriveExplorerView*)m_wndSplitter.GetPane(0, 1);
 return pView;
}

void CMainFrame::OnUpdateViewStyles(CCmdUI* pCmdUI)
{
 CDriveExplorerView* pView = GetRightPane();
 if (pView == NULL)
  pCmdUI->Enable(FALSE);
 else
 {
  DWORD dwStyle = pView->GetStyle() & LVS_TYPEMASK;
  if (pCmdUI->m_nID == ID_VIEW_LINEUP)
  {
   if (dwStyle == LVS_ICON || dwStyle == LVS_SMALLICON)
    pCmdUI->Enable();
   else
    pCmdUI->Enable(FALSE);
  }
  else
  {
   // otherwise, use dots to reflect the style of the view
   pCmdUI->Enable();
   BOOL bChecked = FALSE;
   switch (pCmdUI->m_nID)
   {
    case ID_VIEW_AS_DETAILS:
     bChecked = (dwStyle == LVS_REPORT);
     break;
    case ID_VIEW_AS_SMALLICONS:
     bChecked = (dwStyle == LVS_SMALLICON);
     break;
    case ID_VIEW_AS_LARGEICONS:
     bChecked = (dwStyle == LVS_ICON);
     break;
    case ID_VIEW_AS_LIST:
     bChecked = (dwStyle == LVS_LIST);
     break;
    default:
     bChecked = FALSE;
     break;
   }
   pCmdUI->SetRadio(bChecked ? 1 : 0);
  }
 }
}

void CMainFrame::OnViewStyle(UINT nCommandID)
{
 CDriveExplorerView* pView = GetRightPane();
 if (pView != NULL)
 {
  DWORD dwStyle = -1;
  switch (nCommandID)
  {
   case ID_VIEW_LINEUP:
   {
    // ask the list control to snap to grid
    CListCtrl& refListCtrl = pView->GetListCtrl();
    refListCtrl.Arrange(LVA_SNAPTOGRID);
   }
   break;
   // other commands change the style on the list control
   case ID_VIEW_AS_DETAILS:
    dwStyle = LVS_REPORT;
    break;
   case ID_VIEW_AS_SMALLICONS:
    dwStyle = LVS_SMALLICON;
    break;
   case ID_VIEW_AS_LARGEICONS:
    dwStyle = LVS_ICON;
    break;
   case ID_VIEW_AS_LIST:
    dwStyle = LVS_LIST;
    break;
  }
  // change the style; window will repaint automatically
  if (dwStyle != -1)
   pView->ModifyStyle(LVS_TYPEMASK, dwStyle);
 }
}


  四、小结

  上述代码实现的仅仅是资源管理器的主要功能,只要能够对CListView、CtreeView等类灵活运用,在此基础上添加些代码还可以在左右两个视之间实现文件或文件夹的拖动功能,这时两个视都应该有它们自己的实现函数来进行拖放操作。只要不设置"SetCapture()、ReleaseCapture()",被拖放的条目就能从原来的视拖放到目的视。如果被拖的条目(鼠标下的)离开了原来的视,那么目的视的WM_MOUSEMOVE消息就获得了该条目的控制条件。具体实现时要注意保证不同的视(原来的视以及目的视)能访问相同的成员变量,解决的办法是在app类里面定义一些共用的成员变量。
关键词:VC资源浏览器

赞助商链接: