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

📄 countingdlg.cpp

📁 一个完整的源代码统计器
💻 CPP
📖 第 1 页 / 共 4 页
字号:

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

		SendMessage(WM_ICONERASEBKGND, (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 to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CCountingDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

/***********************************************************
* 当按下ESC键时,确认是否退出
***********************************************************/
void CCountingDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	CString str1, str2;
	str1.LoadString(IDS_TOQUIT);
	str2.LoadString(IDS_MESSAGE);
	if(MessageBox(str1, str2, MB_YESNO)==IDNO)
	{
		return ;
	}
	CDialog::OnCancel();
}

/***********************************************************
* 将统计保存为文本文件和csv文件
***********************************************************/
void CCountingDlg::OnSave() 
{
	// TODO: Add your control notification handler code here
	if(0==m_ctlResult.GetItemCount())
	{
		CString str1, str2;
		str1.LoadString(IDS_UNSTARTED);
		str2.LoadString(IDS_MESSAGE);
		MessageBox(str1, str2);
		return;
	}

	if(m_CountingStatus == COUNTING)
	{
		CString str1, str2;
		str1.LoadString(IDS_WAITING);
		str2.LoadString(IDS_MESSAGE);
		MessageBox(str1, str2);
		return;
	}

	CString str3;
	str3.LoadString(IDS_SAVETYPE);
	CFileDialog dlgFile(
		FALSE, _T("*.txt"), NULL,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		((LPCTSTR)str3));
	if (dlgFile.DoModal() == IDCANCEL)
		return ;

	CString sPath = dlgFile.GetPathName();
	CString sExt = dlgFile.GetFileExt();
	sExt.MakeLower();

	if(sExt == "txt")
		SaveAsTextFile((LPCTSTR)sPath);
	else if(sExt == "csv")
		SaveAsCSVFile((LPCTSTR)sPath);
	else
	{
		CString str1, str2;
		str1.LoadString(IDS_WRONGTYPE);
		str2.LoadString(IDS_MESSAGE);
		MessageBox(str1, str2);
	}

	CString str1, str2;
	str1.LoadString(IDS_SAVEOVER);
	str2.Format("%s:%s", str1, sPath);
	GetDlgItem(IDC_PATH_COUNTING)->SetWindowText(str2);
}

/*******************************************************
点击“统计”按钮,开始统计
********************************************************/
void CCountingDlg::OnCount() 
{
	// TODO: Add your control notification handler code here
	if(m_CountingStatus == COUNTING)
	{
		m_CountingStatus = STOP;
		return;
	}
	UpdateData(TRUE);

	if(m_strComboExt.Find(_T("**")) != -1||m_strComboFolder.Find(_T("**")) != -1)
	{
		CString str1, str2;
		str1.LoadString(IDS_INVALIDFILE);
		str2.LoadString(IDS_MESSAGE);
		MessageBox(str1, str2);
		return;
	}

	if(m_strComboExt.IsEmpty())
	{
		CString str1, str2;
		str1.LoadString(IDS_INPUT_FILE);
		str2.LoadString(IDS_MESSAGE);
		MessageBox(str1, str2);
		return;
	}

	if(m_strComboFolder.IsEmpty())
	{
		CString str1, str2;
		str1.LoadString(IDS_COUNTING_PATH);
		str2.LoadString(IDS_MESSAGE);
		MessageBox(str1, str2);
		return;
	}

	if(m_ctlFolder.FindStringExact(-1, m_strComboFolder)==CB_ERR)
	{
		m_ctlFolder.AddToMRU((LPCTSTR)m_strComboFolder);
	}

	m_btnCount.SetIcon(IDI_COUNTSTOP);
	CString str;
	str.LoadString(IDS_STOP);
	m_btnCount.SetWindowText(str);
	
	m_imageList.DeleteImageList();
	m_imageList.Create(16, 16, ILC_MASK|ILC_COLORDDB, 1, 100);
	m_ctlResult.SetImageList(&m_imageList, LVSIL_SMALL);

	m_ctlResult.DeleteAllItems();
	m_nItemCountSet = 1000;
	m_ctlResult.SetItemCount(m_nItemCountSet);

	char strCurrentDirectory[_MAX_PATH];
	GetCurrentDirectory(_MAX_PATH, strCurrentDirectory);
	m_strCurrentDir = strCurrentDirectory; //保存当前路径以便线程结束后恢复

	SetCurrentDirectory(m_strComboFolder);//set directory to count

	m_nTotalLines = 0;//initialize
	m_nCodeLines = 0;
	m_nCommentLines = 0;
	m_nBlankLines = 0;
	m_nFiles = 0;
	m_nSize = 0;

	m_nTimer = SetTimer(COUNTING_TIMER, 200, NULL);
	m_CountingStatus = COUNTING;

	HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_BIG_ICON2),
		IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);//SM_CXICON 
	m_ctrlCountingIcon.SendMessage(STM_SETICON, (WPARAM)hIcon, 0);

	char buf[_MAX_PATH];
	GetCurrentDirectory(_MAX_PATH, buf);
	//开始线程
	CWinThread* pThread = AfxBeginThread(CountThread, this);
}

/*******************************************************************
* Extract one extension from strExtension, and assign it to strOneOfExt
* for example: strExtension = "*.cpp;*.c;*.h"
*	then,	1st time: strOneOfExt = "*.cpp", 
*			2nd time: strOneOfExt = "*.c",
*			3rd time: strOneOfExt = "*.h",
*	return: TRUE: extracted successfully
*			FALSE: strExtension is empty. 
*********************************************************************/
BOOL CCountingDlg::ExtractExtension(CString & strOneOfExt, CString & strExtension)
{
	strExtension.TrimLeft();

	if(strExtension.IsEmpty())
		return FALSE;

	int nLength = strExtension.GetLength();

	int nFirst = strExtension.FindOneOf(";,:");
	if(nFirst == -1) //there may be only one extension in strExtsion
		nFirst = nLength;
	strOneOfExt = strExtension.Left(nFirst);

	if(nFirst == nLength)
		strExtension.Empty();
	else
		strExtension = strExtension.Right(nLength-1-nFirst);//rest

	strOneOfExt.TrimLeft();//trim whitespace
	strOneOfExt.TrimRight();

	return TRUE;
}

/*******************************************************************
* find file type according to its extension
* for example: strExtension = "xiaogi.c"
*	return: TYPE_C
*********************************************************************/
int CCountingDlg::FindFileType(CString strFile)
{
	int nLast = strFile.ReverseFind('.');
	CString extNoDot = strFile.Right(strFile.GetLength()-nLast-1);

	for(int i=0; i<m_structExtention.arrayType.GetSize(); i++)
	{
		if(extNoDot.CompareNoCase(m_structExtention.arrayType[i])==0)
			return m_structExtention.nType[i];
	}

	return -1;
}

/*********************************************************
	选择需统计的文件夹
*********************************************************/
void CCountingDlg::OnBrowseFolder() 
{
	// TODO: Add your control notification handler code here
	CFolderDialog dlg("", BIF_RETURNONLYFSDIRS, this);
	if(dlg.DoModal()==IDOK)
	{
		CString strPath = dlg.GetPathName();
		m_ctlFolder.SetWindowText((LPCTSTR)strPath);
	}
}

/*********************************************************
	选择需统计的文件
*********************************************************/
void CCountingDlg::OnBrowseExt() 
{
	// TODO: Add your control notification handler code here
	CFileDialog dlgFile(TRUE, "", NULL, 
		OFN_ALLOWMULTISELECT|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
		NULL, this);

	dlgFile.m_ofn.lStructSize = sizeof(OPENFILENAME);
//	dlgFile.m_ofn.hwndOwner = GetSafeHwnd();
	static char BASED_CODE szFilter[]
		= "C++ Files (.c;.cpp;.cxx;.tli;.h;.tlh;.rc)\0*.c;*.cpp;*.h;*.rc\0\
Web Files(.htm;.html;.htx;.asp;.alx;.stm;.shtml)\0*.htm;*.html\0\
C++ Source Files(.c;.cpp;.cxx;.tli)\0*.c; *.cpp\0\
C++ Include Files(.h;.hpp;.hxx;.inl;.tlh)\0*.h\0\
Resource Files(.rc;.rct;.res)\0*.rc\0\
Java Source Files(.java)\0*.java\0\
ASP Source Files(.asp)\0*.asp\0\
JSP Source Files(.jsp)\0*.jsp\0\
PL*sql Files(.sql)\0*.sql\0\
VB Source Files(.frm;.bas;.ctl;.cls)\0*.frm;*.bas;*.ctl;*.cls\0\
Text File(.txt)\0*.txt\0\
All Files (*.*)\0*.*\0\0";

	dlgFile.m_ofn.lpstrFilter = szFilter;
	char FileName[640];
	memset(FileName, 0, sizeof(FileName));
	dlgFile.m_ofn.lpstrFile = FileName;
	dlgFile.m_ofn.nMaxFile = 640;

	CString strFiles = "";
	CString strPath = "";
	if(dlgFile.DoModal()==IDOK)
	{
		CString sFile = dlgFile.GetFileName();
		CString sPath = dlgFile.GetPathName();
		if(sFile.IsEmpty())
		{
			strPath = sPath;
		}
		else
		{
	 		strPath = GetPurePath(sPath);
		}

		POSITION pos = dlgFile.GetStartPosition();
		while(pos!=NULL)
		{
			CString strPathName = dlgFile.GetNextPathName(pos);
			int nFind = strPathName.ReverseFind('\\');
			strFiles += strPathName.Right(strPathName.GetLength()-nFind-1);
			strFiles += ";";
		}
		strFiles = strFiles.Left(strFiles.GetLength()-1);
		m_ctlExtension.SetWindowText((LPCTSTR)strFiles);
		m_ctlFolder.SetWindowText((LPCTSTR)strPath);
	}
}

/*********************************************************
	统计主线程
*********************************************************/
UINT CCountingDlg::CountThread(LPVOID lpvData)
{
	CCountingDlg* pThis = (CCountingDlg*)lpvData;
	CStringList listPaths;
	CString  strPath;
	CString  strFolder;

	CFileFind finder;
	BOOL bWorking;

	if(pThis->m_strComboFolder[pThis->m_strComboFolder.GetLength()-1]=='\\')
		strPath = pThis->m_strComboFolder + "*.*";
	else
		strPath = pThis->m_strComboFolder + "\\*.*";

	do{
		bWorking = finder.FindFile(strPath);
		while(bWorking  && pThis->m_CountingStatus==COUNTING)
		{
			bWorking = finder.FindNextFile();
			CString strFilePath = finder.GetFilePath();
			if(finder.IsDots())
				continue;

			CString str1, str2;
			str1.LoadString(IDS_COUNTINGFILE);
			str2.Format("%s:%s", str1, strFilePath);
			pThis->GetDlgItem(IDC_PATH_COUNTING)->SetWindowText(str2);

			if(finder.IsDirectory())
			{
				if(pThis->m_bIncludeSubfolder)
					listPaths.AddHead(strFilePath);
				continue;
			}
			else
			{
				if(pThis->IsSearchingFor(strFilePath))
				{
					int nType;
					nType = pThis->FindFileType(strFilePath);
					if(nType == -1)
						nType = TYPE_OTH;

					int nLines=0;
					int nCodeLines=0;
					int nCommentLines=0;
					int nBlankLines=0;
					int nLength=0;

					switch(nType)
					{
					case TYPE_C:
					case TYPE_CPP:
					case TYPE_H:
					case TYPE_JSP:
					case TYPE_JAVA:
						nLines = pThis->GetCppFileLines((LPCTSTR)strFilePath, &nLength, &nCommentLines, &nBlankLines);
						break;
					case TYPE_VB:
					case TYPE_ASP:
						nLines = pThis->GetVBFileLines((LPCTSTR)strFilePath, &nLength, &nCommentLines, &nBlankLines);
						break;
					case TYPE_SQL:
						nLines = pThis->GetSqlFileLines((LPCTSTR)strFilePath, &nLength, &nCommentLines, &nBlankLines);
						break;
					default:
						nLines = pThis->GetTxtFileLines((LPCTSTR)strFilePath, &nLength, &nCommentLines, &nBlankLines);
						break;
					}

					nCodeLines = nLines - nCommentLines - nBlankLines;

					int pos=strFilePath.ReverseFind('\\');

					if(pThis->m_nFiles > pThis->m_nItemCountSet)
						pThis->m_nItemCountSet += 1000;
					pThis->m_ctlResult.SetItemCount(pThis->m_nItemCountSet);

					SHFILEINFO sfi;
					if (::SHGetFileInfo (strFilePath, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO),SHGFI_USEFILEATTRIBUTES | SHGFI_DISPLAYNAME | SHGFI_TYPENAME |SHGFI_ICON|SHGFI_SMALLICON ))
					{	
						CString str;
						pThis->m_imageList.Add(sfi.hIcon);
						pThis->m_ctlResult.InsertItem(pThis->m_nFiles,sfi.szDisplayName,pThis->m_nFiles);

     					pThis->m_ctlResult.SetItemText(pThis->m_nFiles, 1, strFilePath.Mid(0,pos));
						str.Format("%d", nLines);
    					pThis->m_ctlResult.SetItemText(pThis->m_nFiles, 2, str);
						str.Format("%d", nCodeLines);
    					pThis->m_ctlResult.SetItemText(pThis->m_nFiles, 3, str);
						str.Format("%d", nCommentLines);
    					pThis->m_ctlResult.SetItemText(pThis->m_nFiles, 4, str);
						str.Format("%d", nBlankLines);
    					pThis->m_ctlResult.SetItemText(pThis->m_nFiles, 5, str);
						pThis->m_ctlResult.SetItemText(pThis->m_nFiles, 6, sfi.szTypeName);
					}

					pThis->m_ctlResult.Update(pThis->m_nFiles);

					pThis->m_nFiles++;
					pThis->m_nSize += nLength;
					pThis->m_nTotalLines += nLines;
					pThis->m_nCodeLines += nCodeLines;
					pThis->m_nCommentLines += nCommentLines;
					pThis->m_nBlankLines += nBlankLines;

					pThis->UpdateResult();
				}
			}

⌨️ 快捷键说明

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