Click here to Skip to main content
15,886,519 members
Articles / Programming Languages / C++

CEnum - File Enumeration and File Globbing Class

Rate me:
Please Sign up or sign in to vote.
4.45/5 (5 votes)
6 Dec 2008CPOL12 min read 52.5K   1.2K   48  
CEnum is used for enumeration of files and directories using wildcard matching (globbing)
// CEnumeratorDlg.cpp : implementation file
//

#include "stdafx.h"
#include "CEnumerator.h"
#include "CEnumeratorDlg.h"
#include "CEnum.cpp"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CCEnumeratorDlg dialog




CCEnumeratorDlg::CCEnumeratorDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCEnumeratorDlg::IDD, pParent)
	, m_sPath(_T(""))
	, m_sExcPatternDirs(_T(""))
	, m_sExcPatternFiles(_T(""))
	, m_sIncPatternDirs(_T(""))
	, m_sIncPatternFiles(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCEnumeratorDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_ctlListCtrl);
	DDX_Text(pDX, IDC_EDIT1, m_sPath);
	DDX_Text(pDX, IDC_EDIT2, m_sExcPatternDirs);
	DDX_Text(pDX, IDC_EDIT3, m_sExcPatternFiles);
	DDX_Text(pDX, IDC_EDIT4, m_sIncPatternDirs);
	DDX_Text(pDX, IDC_EDIT5, m_sIncPatternFiles);
}

BEGIN_MESSAGE_MAP(CCEnumeratorDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_ENUMERATE, &CCEnumeratorDlg::OnEnumerate)
	ON_BN_CLICKED(IDC_TEST_COMPARE, &CCEnumeratorDlg::OnTestCompare)
	//ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CCEnumeratorDlg::OnOpenItem)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CCEnumeratorDlg::OnNMDblclkList1)
END_MESSAGE_MAP()


// CCEnumeratorDlg message handlers

BOOL CCEnumeratorDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here

	RECT clientArea;

	GetDlgItem(IDC_LIST1)->GetClientRect(&clientArea);
	m_ctlListCtrl.InsertColumn(0, _T("Files found"), LVCFMT_LEFT, clientArea.right - clientArea.left);

	m_ctlListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT);
	m_ctlListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES);

	((CButton *) GetDlgItem(IDC_RADIO1))->SetCheck(BST_CHECKED);

	//////////////////////////////////////////////
	TCHAR Buffer[MAX_PATH];
	::GetCurrentDirectory(MAX_PATH, Buffer);
	m_sPath = Buffer;


	UpdateData(FALSE);


	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CCEnumeratorDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CCEnumeratorDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CCEnumeratorDlg::OnEnumerate()
{
	CWaitCursor wait;		// display hourglass cursor

	HDITEM hdi;
	TCHAR  lpBuffer[256];	// 256 is the max value that can be displayed in CHeaderCtrl
	RECT clientArea;

	// delete all items, delete second column and change header text of first column
	m_ctlListCtrl.DeleteAllItems();
	m_ctlListCtrl.DeleteColumn(1);
	CHeaderCtrl * pHeader = m_ctlListCtrl.GetHeaderCtrl();
	
	hdi.mask		= HDI_TEXT;
	hdi.pszText		= lpBuffer;
	hdi.cchTextMax	= 256;

	pHeader->GetItem(0, &hdi);
	_tcscpy_s(hdi.pszText, 256, _T("Files found"));
	pHeader->SetItem(0, &hdi);

	// now that display is taken care of, lets read some file names :-)

	UpdateData(TRUE);

	CEnum enumerator;

	enumerator.sExcPatternDirs	= m_sExcPatternDirs;
	enumerator.sExcPatternFiles	= m_sExcPatternFiles;
	enumerator.sIncPatternDirs	= m_sIncPatternDirs;
	enumerator.sIncPatternFiles = m_sIncPatternFiles;
	
	enumerator.bNoCaseDirs	= (((CButton *) GetDlgItem(IDC_NO_CASE_DIRS) )->GetCheck() == BST_CHECKED );
	enumerator.bNoCaseFiles = (((CButton *) GetDlgItem(IDC_NO_CASE_FILES))->GetCheck() == BST_CHECKED );
	enumerator.bRecursive	= (((CButton *) GetDlgItem(IDC_RECURSIVE)	 )->GetCheck() == BST_CHECKED );
	enumerator.bFullPath	= (((CButton *) GetDlgItem(IDC_FULL_PATH)	 )->GetCheck() == BST_CHECKED );

	enumerator.EnumerateAll((LPCTSTR) m_sPath);
	
	list<basic_string<TCHAR> > * plstFiles = enumerator.GetFiles();

	// display total info
	CString sNbrFiles = _T("");
	sNbrFiles.Format(_T("Found %d files."), plstFiles->size());
	GetDlgItem(IDC_STATIC_NBR_FILES)->SetWindowTextW(sNbrFiles);

	// display items in CListCtrl
	list<basic_string<TCHAR> >::iterator iter = plstFiles->begin();
	int i = 1;
	for(; iter != plstFiles->end(); ++iter, ++i)
	{
		m_ctlListCtrl.InsertItem(i, iter->c_str());
	}

	// set width of the first column
	GetDlgItem(IDC_LIST1)->GetClientRect(&clientArea);
	m_ctlListCtrl.SetColumnWidth(0, clientArea.right - clientArea.left);
	
	UpdateData(FALSE);
}

void CCEnumeratorDlg::OnTestCompare()
{
	CWaitCursor wait;		// display hourglass cursor
	CString sLine	= _T("");
	CString sFirst	= _T("");
	CString sSecond	= _T("");
	CString sThird	= _T("");
	int iFirst		= 0;
	int iSecond		= 0;
	int iThird		= 0;
	int iFourth		= 0;
	int iIndex		= 0;
	bool bMatch		= false;
	HDITEM hdi;
	TCHAR  lpBuffer[256];	// 256 is the max value that can be displayed in CHeaderCtrl
	RECT clientArea;
	int iWidthOfSecondColumn = 55;
	int iScrollBarWidth		 = 0;
	CString sNbrTests		 = _T("");
	int iNbrTestsPassed		 = 0;
	int iNbrTestsFailed		 = 0;

	CStdioFile file(_T("..\\CEnumerator\\test.txt"), CFile::modeRead);
	
	//delete all items, resize first column, create second column and change header text of first column
	m_ctlListCtrl.DeleteAllItems();
	GetDlgItem(IDC_LIST1)->GetClientRect(&clientArea);
	if ( WS_VSCROLL == (m_ctlListCtrl.GetStyle() & WS_VSCROLL) )	
	{
		iScrollBarWidth = GetSystemMetrics(SM_CXVSCROLL);
	}
	m_ctlListCtrl.SetColumnWidth(0, clientArea.right - clientArea.left - GetSystemMetrics(SM_CXVSCROLL) - iWidthOfSecondColumn);
	m_ctlListCtrl.InsertColumn(1, _T("Result"), LVCFMT_LEFT, iWidthOfSecondColumn);
	CHeaderCtrl * pHeader = m_ctlListCtrl.GetHeaderCtrl();
	
	hdi.mask		= HDI_TEXT;
	hdi.pszText		= lpBuffer;
	hdi.cchTextMax	= 256;

	pHeader->GetItem(0, &hdi);

	_tcscpy_s(hdi.pszText, 256, _T("Test Case"));

	pHeader->SetItem(0, &hdi);

	while(file.ReadString(sLine))
	{
		if( sLine.IsEmpty() || sLine[0] == '#' ) 
		{
			m_ctlListCtrl.InsertItem(m_ctlListCtrl.GetItemCount(), sLine);
			continue;
		}

		iFirst	= sLine.Find('"', 0);
		iSecond = sLine.Find('"', iFirst + 1);
		iThird	= sLine.Find('"', iSecond + 1);
		iFourth = sLine.Find('"', iThird + 1);

		sFirst	= sLine.Mid(iFirst + 1, iSecond - iFirst - 1);
		sSecond	= sLine.Mid(iThird + 1, iFourth - iThird - 1);
		sThird	= sLine.Mid(iFourth + 1, sLine.GetLength()).Trim();

		bMatch = ( sThird.Compare(_T("true")) == 0 );

		iIndex = m_ctlListCtrl.InsertItem(m_ctlListCtrl.GetItemCount(), sLine);
		if( bMatch == CEnum::CompareStrings(sFirst, sSecond, false) )
		{
			m_ctlListCtrl.SetItemText(iIndex, 1, _T("passed"));
			iNbrTestsPassed++;
		}
		else
		{
			m_ctlListCtrl.SetItemText(iIndex, 1, _T("failed"));
			iNbrTestsFailed++;
		}
	}

	sNbrTests.Format(_T("Passed: %d tests. Failed: %d tests."), iNbrTestsPassed, iNbrTestsFailed);
	GetDlgItem(IDC_STATIC_NBR_FILES)->SetWindowTextW(sNbrTests);

	file.Close();
}

void CCEnumeratorDlg::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	CListCtrl * pListCtrl = (CListCtrl *) CWnd::FromHandle(pNMHDR->hwndFrom);
	CString sFileToOpen = pListCtrl->GetItemText(pListCtrl->GetSelectionMark(), 0);
	CString sOpenCommand = _T("");

	if (BST_CHECKED == ((CButton *) GetDlgItem(IDC_RADIO1))->GetCheck())
	{
		sOpenCommand = _T("open");	// open a file using default editor
	}
	else
	{
		sOpenCommand = _T("explore");	// open directory containing the file
		sFileToOpen = sFileToOpen.Left(sFileToOpen.ReverseFind('\\'));
	}
	
	ShellExecute(this->m_hWnd, sOpenCommand, sFileToOpen, _T(""), _T(""), SW_SHOW );

	*pResult = 0;
}
void CCEnumeratorDlg::OnOK()
{
    // this is needed, so pressing enter wouldn't close the dilaog
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Croatia Croatia
Nothing to brag about.
Just another engineer who works as a software developer last couple of years.

Comments and Discussions