⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dirlistview.cpp

📁 这些源代码
💻 CPP
字号:
// DirListView.cpp : implementation of the CDirListView class
//

#include "stdafx.h"
#include "DirList.h"

#include "DirListDoc.h"
#include "DirListView.h"

#include	"struct.h"
#include	"proto.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDirListView

IMPLEMENT_DYNCREATE(CDirListView, CListView)

BEGIN_MESSAGE_MAP(CDirListView, CListView)
	//{{AFX_MSG_MAP(CDirListView)
	ON_WM_DESTROY()
	ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
	ON_WM_LBUTTONDBLCLK()
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDirListView construction/destruction

CDirListView::CDirListView()
{
	// TODO: add construction code here

}

CDirListView::~CDirListView()
{
}

BOOL CDirListView::PreCreateWindow(CREATESTRUCT& cs)
{
//
//	Set the list control for report view and
//	add ownerdraw style.
	cs.style &= ~LVS_TYPEMASK;
	cs.style |= LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS;
	return CListView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CDirListView drawing

void CDirListView::OnDraw(CDC* pDC)
{
	CDirListDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

void CDirListView::OnInitialUpdate()
{
CFont		font;
LV_COLUMN	lc;
int			sub;
CListCtrl&	cc = GetListCtrl();
LISTHEADER Titles[] =
	{
	"File Name",	140,	LVCFMT_LEFT,
	"File Type",	120,	LVCFMT_LEFT,
	"Size",			80,		LVCFMT_RIGHT,
	"Created",		110,	LVCFMT_LEFT,
	"Modified",		110,	LVCFMT_LEFT
	};

#define		TITLES		(sizeof (Titles) / sizeof (LISTHEADER))

	CListView::OnInitialUpdate();

	while (cc.DeleteColumn(0))
		;
	lc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;	
	for (sub = 0; sub < TITLES; ++sub)
	{
		lc.pszText = Titles[sub].Title;
		lc.cx = Titles[sub].Width;
		lc.fmt = Titles[sub].Format;
		lc.iSubItem = sub;
		cc.InsertColumn (sub, &lc);
	}

	m_DirectoryName = GetCurrentDirectory ();
	if (m_LargeIcons.m_hImageList != NULL)
		m_LargeIcons.Detach ();
	LoadSystemImageList (SHGFI_LARGEICON);
	cc.SetImageList (&m_LargeIcons, LVSIL_NORMAL);
	if (m_SmallIcons.m_hImageList != NULL)
		m_SmallIcons.Detach ();
	LoadSystemImageList (SHGFI_SMALLICON);
	cc.SetImageList (&m_SmallIcons, LVSIL_SMALL);
	ListDirectory ();
}

/////////////////////////////////////////////////////////////////////////////
// CDirListView printing

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CDirListView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CDirListView message handlers

void CDirListView::OnDestroy() 
{
	FreeItemMemory();
	m_SmallIcons.Detach ();
	m_LargeIcons.Detach ();

	CListView::OnDestroy();
}

void CDirListView::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult) 
{
CString		string;
PITEMINFO	pItem;
CTime		Now;
static int count = 0;

	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
	pItem = (PITEMINFO) pDispInfo->item.lParam;

	if (pDispInfo->item.mask & LVIF_TEXT)
	{
		switch (pDispInfo->item.iSubItem)
		{
			case 0:			//	Need file name
				if (!strcmp ((LPCSTR) pItem->fdFile.cFileName, _T("..")))
				{
				CListCtrl& cc = GetListCtrl();
					if (!(cc.GetStyle() & (LVS_OWNERDRAWFIXED)))
					{
						::lstrcpy (pDispInfo->item.pszText, (LPCSTR) _T("UP-DIR"));
						break;
					}
				}
				::lstrcpy (pDispInfo->item.pszText, (LPCSTR) pItem->fdFile.cFileName);
				break;
			case 1:			// Needs DOS file name
				{
					CString strFileType;
					strFileType = pItem->strFileType;
//					GetFileType (pItem->fdFile, strFileType);
					if (strFileType.IsEmpty ())
					{
						if (pItem->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
							strFileType = "File Folder";
						else
						{
							char *s;
							if ((s = strchr (pItem->fdFile.cFileName, '.')) != NULL)
							{
								++s;
								strFileType = s;
								strFileType += ' ';
							}
							strFileType += "File";
						}
					}
					::lstrcpy (pDispInfo->item.pszText, (LPCSTR) strFileType);
				}
				break;
			case 2:			// Needs file size;
				if (pItem->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				{
					if (!strcmp ((LPCSTR) pItem->fdFile.cFileName, ".."))
						string = "UP-DIR";
					else
						string = "SUB-DIR";
				}
				else
				{
					FormatNumber (string, pItem->fdFile.nFileSizeLow);
				}
				::lstrcpy (pDispInfo->item.pszText, (LPCSTR) string);
				break;
			case 3:			// Needs created date
				Now = pItem->fdFile.ftCreationTime;
				string.Format ("%02d/%02d/%02d %02d:%02d",
					Now.GetMonth(), Now.GetDay(), Now.GetYear() % 100,
					Now.GetHour(), Now.GetMinute());
				::lstrcpy (pDispInfo->item.pszText, (LPCSTR) string);
				break;
			case 4:			// Needs modified time
				Now = pItem->fdFile.ftLastWriteTime;
				string.Format ("%02d/%02d/%02d %02d:%02d",
					Now.GetMonth(), Now.GetDay(), Now.GetYear() % 100,
					Now.GetHour(), Now.GetMinute());
				::lstrcpy (pDispInfo->item.pszText, (LPCSTR) string);
				break;
		}
	}
	
	*pResult = 0;
	if (pDispInfo->item.mask & LVIF_IMAGE)
	{
		pDispInfo->item.iImage = pItem->nIcon;
	}
	*pResult = 0;
}

void CDirListView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
ITEMINFO *pItem;
LV_ITEM lvItem;

	memset (&lvItem, '\0', sizeof (LV_ITEM));
	POSITION pos = GetListCtrl().GetFirstSelectedItemPosition();
	if (pos == NULL)
		return;
	int nItem = GetListCtrl().GetNextSelectedItem(pos);
	pItem = (ITEMINFO *) (GetListCtrl().GetItemData (nItem));
	if (!(pItem->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
	{
		CListView::OnLButtonDblClk(nFlags, point);
		return;
	}
	CString OldDir = m_DirectoryName;
	CString strDir;
	if (!(strcmp(pItem->fdFile.cFileName, "..")))
	{
		int nIndex = OldDir.ReverseFind (_T('\\'));
		if (nIndex > 0)
		{
			strDir = OldDir.Left(nIndex);
//
//	Are we at the root? we need to add the backslash if so
//
			nIndex = strDir.Find (_T('\\'));
			if (nIndex < 0)
				strDir += '\\';
		}
	}
	else
	{
		strDir = OldDir;
//
//	Add a backslash only if the directory name doesn't
//	already end with a backslash (as at the root directory)
		if (strDir.GetAt (strDir.GetLength() - 1) != '\\')
			strDir += '\\';
		strDir += pItem->fdFile.cFileName;
	}
//
//	Save the new directory
	m_DirectoryName = strDir;
//	And change to it
	SetCurrentDirectory ((LPCSTR) m_DirectoryName);
//	Show it in the list control
	ListDirectory ();	
}

void CDirListView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	GetListCtrl().SortItems (CompareItems, pNMListView->iSubItem);
	
	*pResult = 0;
}

void CDirListView::OnKillFocus(CWnd* pNewWnd) 
{
	CListView::OnKillFocus(pNewWnd);
	
	// TODO: Add your message handler code here
	
}

void CDirListView::OnSetFocus(CWnd* pOldWnd) 
{
	CListView::OnSetFocus(pOldWnd);
	
	// TODO: Add your message handler code here
	
}

BOOL CDirListView::LoadSystemImageList(UINT uiImageList)
{
	SHFILEINFO sfiInfo;
	memset(&sfiInfo, 0, sizeof(SHFILEINFO));
	HIMAGELIST hImages = (HIMAGELIST) (
		SHGetFileInfo (
			"C:\\", 
			0, 
			&sfiInfo,
			sizeof(sfiInfo), 
			SHGFI_SYSICONINDEX | uiImageList)
	);
	if (hImages == NULL)
		return (FALSE);
	switch (uiImageList)
	{
		case SHGFI_LARGEICON:
			m_LargeIcons.Attach (hImages);
			break;
		case SHGFI_SMALLICON:
			m_SmallIcons.Attach (hImages);
			break;
	}
	return (TRUE);
}

CString & CDirListView::GetCurrentDirectory()
{
static CString strCurrentPath;

	strCurrentPath.Empty ();
	int nBytes = ::GetCurrentDirectory (0, NULL);
	char *szDir = new char [nBytes + 1];
	::GetCurrentDirectory (nBytes + 1, szDir);
	strCurrentPath = szDir;
	delete [] szDir;
	return (strCurrentPath);
}

int CALLBACK CDirListView::CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
int	nResult;
time_t time1, time2;

	ITEMINFO *pItem1 = (ITEMINFO *) lParam1;
	ITEMINFO *pItem2 = (ITEMINFO *) lParam2;
	switch (lParamSort)
	{
		case 0:				// Sort by name
//
//	The following tests force the UP-DIR item to always
//	land on top of the list.
//
			if (!strcmp ((LPCSTR) pItem1->fdFile.cFileName, ".."))
				return (-1);
			if (!strcmp ((LPCSTR) pItem2->fdFile.cFileName, ".."))
				return (1);
//
//	The following tests cause SUB-DIR items to always
//	stay above normal file items.
//
			if ((pItem1->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
				!(pItem2->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				return (-1);
			if (!(pItem1->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
				(pItem2->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				return (1);
//
//	The remaining tests compare directory/directory or
//	file/file names.
//
			nResult = strcmpi ((LPCSTR) pItem1->fdFile.cFileName,
							  (LPCSTR) pItem2->fdFile.cFileName);
			break;
		case 1:				// Sort by file type
//
//	If a directory is involved, sort by name.
//
			if ((pItem1->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
				(pItem2->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				return (CompareItems (lParam1, lParam2, 0));
			nResult = (int) (strcmp ((LPCSTR) pItem1->strFileType, (LPCSTR) pItem2->strFileType));
			break;
		case 2:				// Sort by size
//
//	If a directory is involved, sort by name.
//
			if ((pItem1->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
				(pItem2->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				return (CompareItems (lParam1, lParam2, 0));
			nResult = (int) (pItem1->fdFile.nFileSizeLow - pItem2->fdFile.nFileSizeLow);
			break;
		case 3:				// Sort by creation time
//
//	If a directory is involved, sort by name.
//
			if ((pItem1->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
				(pItem2->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				return (CompareItems (lParam1, lParam2, 0));
			time1 = FileTimeToUnixTime (&pItem1->fdFile.ftCreationTime);
			time2 = FileTimeToUnixTime (&pItem2->fdFile.ftCreationTime);
			nResult = (int) (time1 - time2);
			break;
		case 4:				// Sort by modified time
//
//	If a directory is involved, sort by name.
//
			if ((pItem1->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
				(pItem2->fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				return (CompareItems (lParam1, lParam2, 0));
			time1 = FileTimeToUnixTime (&pItem1->fdFile.ftLastWriteTime);
			time2 = FileTimeToUnixTime (&pItem2->fdFile.ftLastWriteTime);
			nResult = (int) (time1 - time2);
			break;
	}
	return (nResult);
}

void CDirListView::ListDirectory()
{
	ListDirectory (m_DirectoryName);
}

void CDirListView::ListDirectory(CString &strDir)
{
CListCtrl&	cc = GetListCtrl();
CString		OldDir, FindSpec;
WIN32_FIND_DATA	fData;
HANDLE		hFind;
CString		FileName;
int			sub;

	m_DirectoryName = strDir;
	OldDir = m_DirectoryName;
	if (strDir.IsEmpty())
		strDir = OldDir;

	FindSpec = strDir;
	sub = FindSpec.GetLength();
	if (sub)
	{
		if (FindSpec.GetAt (sub - 1) == '\\')
			FindSpec += "*.*";
		else
			FindSpec += "\\*.*";
	}
	FreeItemMemory();
	hFind = FindFirstFile(FindSpec, &fData);
	if (hFind == INVALID_HANDLE_VALUE)
		return;

	int i = 0;
	do
	{
		if (!strcmp (fData.cFileName, "."))
			continue;
		if (!AddItem(i, &fData))
			break;
		++i;
	} while (FindNextFile(hFind, &fData));
	FindClose (hFind);
	cc.SortItems (CompareItems, 0);
	cc.RedrawItems (0, cc.GetItemCount() - 1);
}

void CDirListView::FreeItemMemory()
{
CListCtrl&	cc = GetListCtrl();

	int nCount = cc.GetItemCount ();
	for (int i = 0; i < nCount; ++i)
		delete (ITEMINFO *) cc.GetItemData (i);
	cc.DeleteAllItems ();
}

bool CDirListView::AddItem(int nIndex, WIN32_FIND_DATA *pfd)
{
ITEMINFO	*pItem;
LV_ITEM		lvitem;

	memset ((char *) &lvitem, '\0', sizeof (LV_ITEM));
	try
	{
		pItem = new ITEMINFO;
	}
	catch (CMemoryException *e)
	{
		e->Delete ();
		return (false);
	}
	memcpy (&pItem->fdFile, pfd, sizeof (WIN32_FIND_DATA));
	GetFileType (pItem->fdFile, pItem->strFileType);
	UINT uiOpen = 0;
	if (!strcmp (pItem->fdFile.cFileName, ".."))
		uiOpen = SHGFI_OPENICON;
	pItem->nIcon = GetIconIndex (pItem->fdFile, uiOpen);

#undef STATEMASK
#define		STATEMASK	LVIS_CUT|LVIS_DROPHILITED|LVIS_FOCUSED|LVIS_SELECTED

	lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
	lvitem.stateMask = STATEMASK;
	lvitem.iItem = nIndex;
	lvitem.iSubItem = 0;
	lvitem.iImage = I_IMAGECALLBACK;
	lvitem.pszText = LPSTR_TEXTCALLBACK;
	lvitem.lParam = (LPARAM) pItem;

	if (GetListCtrl ().InsertItem (&lvitem) < 0)
		return (false);
	return (true);
}

int CDirListView::GetIconIndex(WIN32_FIND_DATA &fd, UINT uiOpen)
{
	SHFILEINFO sfi;
	memset(&sfi, 0, sizeof(sfi));
	CString strFilePath = m_DirectoryName;
	if (strFilePath.GetAt (strFilePath.GetLength() -1) != '\\')
		strFilePath += '\\';
	strFilePath += fd.cFileName;
	if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
	{
		SHGetFileInfo (strFilePath, FILE_ATTRIBUTE_DIRECTORY,
			&sfi, sizeof(sfi), 
			SHGFI_SMALLICON | SHGFI_SYSICONINDEX |
            SHGFI_USEFILEATTRIBUTES | uiOpen);
		return (sfi.iIcon);
	}
	else
	{
		SHGetFileInfo (strFilePath, FILE_ATTRIBUTE_NORMAL, 
			&sfi, sizeof(sfi), 
			SHGFI_SMALLICON | SHGFI_SYSICONINDEX |
            SHGFI_USEFILEATTRIBUTES);
		return (sfi.iIcon);
	}
	return (-1);
}

int CDirListView::GetFileType(WIN32_FIND_DATA &fd, CString &strFileType)
{

	SHFILEINFO sfi;
	memset(&sfi, 0, sizeof(sfi));
	CString strFilePath = m_DirectoryName;
	strFilePath += '\\';
	strFilePath += fd.cFileName;
	SHGetFileInfo (
		strFilePath, 
		FILE_ATTRIBUTE_NORMAL,
		&sfi, 
		sizeof(sfi), 
		SHGFI_TYPENAME);
	strFileType = sfi.szTypeName;
	return (0);
}

void CDirListView::SetDirectoryName(char *dir)
{

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -