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

📄 countingdlg.cpp

📁 一个完整的源代码统计器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		}
		if(listPaths.IsEmpty())
			break;

		strFolder = listPaths.RemoveHead();
		strPath = strFolder + "\\*.*";
		finder.Close();
	}while(pThis->m_CountingStatus==COUNTING);

	if(pThis->m_nTimer!=NULL)
	{
		pThis->KillTimer(pThis->m_nTimer);
		pThis->m_nTimer = NULL;
	}

	CString str1;
	if(pThis->m_CountingStatus==STOP)
		str1.LoadString(IDS_ABORT); //用户强行终止
	else
		str1.LoadString(IDS_COUNTINGSTOP);
	pThis->GetDlgItem(IDC_PATH_COUNTING)->SetWindowText(str1);

	pThis->m_CountingStatus = STOP;

	pThis->m_btnCount.SetIcon(IDI_COUNT);
	CString str;
	str.LoadString(IDS_COUNT);
	pThis->m_btnCount.SetWindowText(str);

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

	return 0;
}

////////////////////////////////////////////////////////////
//modify a path with file name to without file name
// such as: 
//   modify:  d:\\temp\\countingdlg.cpp
//        to:   d:\\temp
//
////////////////////////////////////////////////////////////
CString CCountingDlg::GetPurePath(CString strPath)
{
	int nLast = strPath.ReverseFind('\\');
	return strPath.Left(nLast);
}

/******************************************************************
*  往一字符串strText中追加空格,使其长度达到num
*  bAtEnd : TRUE表示在字符串后面追加空格
*			  FALSE表示在字符串前面追加空格
*    若strText的长度本来就大于num,则将最后三个字符改为...
*******************************************************************/
CString CCountingDlg::TextAppendSpace(CString strText, int num, BOOL bAtEnd)
{
	CString str;
	if(strText.GetLength()>=num)
	{
		str = strText.Left(num-3);
		str += "...";
	}
	else
	{
		str = strText;
		for(int i=strText.GetLength(); i<num; i++)
		{
			if(bAtEnd)
				str +=" ";
			else
				str = " "+str;
		}
	}

	return str;
}
/*****************************************************************
	strFileName是否为我们要统计的文件类型
*****************************************************************/
BOOL CCountingDlg::IsSearchingFor(CString strFileName)
{
	CString strExts = m_strComboExt;
	strExts.MakeLower();
	strFileName.MakeLower();

	CString strOneOfExts; // get one extension in strExts
	while(ExtractExtension(strOneOfExts, strExts))
	{
		if(CompareMarkString(strOneOfExts, strFileName))
			return TRUE;
	}

	return FALSE;
}

/*****************************************************************
	比较strFile是否为inputFile的文件类型
*****************************************************************/
BOOL CCountingDlg::CompareMarkString(CString inputFile, CString strFile)
{
	strFile = strFile.Right(strFile.GetLength()-strFile.ReverseFind('\\')-1);
	int nLength1 = strFile.GetLength(); 
	int nLength2 = inputFile.GetLength();

	for(int i=0, j=0; i<nLength1&&j<nLength2; i++, j++)
	{
		if(inputFile[j]=='*')
		{
			j++;
			if(j==nLength2)
				return TRUE;
			while(j<nLength2&&inputFile[j]=='?')
			{
				i++;
				j++;
			}
			if(j>=nLength2)
				return TRUE;

			while(i<nLength1&&inputFile[j]!=strFile[i])
				i++;
			if(i>=nLength1)
				return FALSE;

			continue;
		}
		if(inputFile[j]=='?')
		{
			continue;
		}
		if(inputFile[j]==strFile[i])
		{
			continue;
		}
		else
			return FALSE;
	}

	if(i==nLength1&&j==nLength2)
		return TRUE;
	else
		return FALSE;
}

/*****************************************************************
	统计开始后动态显示图标,表示统计进行中
*****************************************************************/

void CCountingDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent != (UINT)m_nTimer)
		return;

	static int icons[] =
	{ IDI_BIG_ICON1, IDI_BIG_ICON2, IDI_BIG_ICON3, IDI_BIG_ICON4, IDI_BIG_ICON5, IDI_BIG_ICON6, 
	IDI_BIG_ICON7};
	
	static long index = 0;

	HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(icons[index++%7]),
		IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);//SM_CXICON 
	m_ctrlCountingIcon.SendMessage(STM_SETICON, (WPARAM)hIcon, 0);
}


/*****************************************************************
	确定是否退出
*****************************************************************/
void CCountingDlg::OnQuit() 
{
	// TODO: Add your control notification handler code here
	CString str1, str2;
	str1.LoadString(IDS_TOQUIT);
	str2.LoadString(IDS_MESSAGE);
	if(MessageBox(str1, str2, MB_YESNO)==IDNO)
	{
		return ;
	}
	CDialog::OnCancel();
}

/*********************************************************
	统计c++文件
*********************************************************/
int CCountingDlg::GetCppFileLines(LPCTSTR strFileName, int* pnLength, int* pnCommentLines, int* pnBlankLines)
{
	//there are two methods to count lines in files, by CStdioFile or CFile
	*pnLength = 0;
	*pnCommentLines = 0;
	*pnBlankLines = 0;

	CStdioFile file;
	if(file.Open(strFileName, CFile::modeRead)==FALSE)
		return 0;

	int nLines = 0;
	int nCommentLines = 0;
	int nBlankLines = 0;

	BOOL bCommentSet = FALSE; //注释行统计标识 有"/*"时TRUE, "*/"时FALSE

	int nLength = file.GetLength();
	*pnLength = nLength;

	CString bufRead;

	int nLineCommentBegin = 0;
	while(file.ReadString(bufRead)!=FALSE)
	{
		nLines++;

		bufRead.TrimLeft(); //先将文件头的空格或制表符去掉

		if(bufRead.GetLength()==0) //为空白行
		{
			nBlankLines++;
			continue;
		}

		if(bufRead.Find("//")==0 && !bCommentSet)
		{
			nCommentLines++;
			continue;
		}

		int nStartComment = bufRead.Find("/*");
		if(nStartComment == 0  && !bCommentSet ) // "/*" is the first two chars
		{
			bCommentSet = TRUE;
//			nLineCommentBegin = nLines;
		}
		else if(nStartComment != -1 &&!bCommentSet) // "/*" is not the first two chars though found. so it's a code line
		{
			bCommentSet = TRUE;
			nLineCommentBegin = nLines;
			nCommentLines --;
			if(bufRead.Find("\"")!=-1) //防止/*在两个"之间,如 "...../*.....",这种/*不是注释符
			{
				CString strTemp = bufRead.Left(nStartComment);
				int nCountQuota=0;
				int i=1;
				if(strTemp[0]=='\"')nCountQuota++;
				while((strTemp[i]=='\"'&&strTemp[i-1]!='\\')&&i<strTemp.GetLength() )
				{
					nCountQuota++;
					i++;
				}
				if((nCountQuota/2)*2 != nCountQuota)//nCountQuota为奇数,还原bCoommentSet
				{
					bCommentSet = FALSE;
					nCommentLines ++;
				}
			}
		}

		bufRead.TrimRight();

		int nEndComment = bufRead.Find("*/");
		if(bufRead.GetLength()>=2 && (nEndComment == (bufRead.GetLength()-2)) && bCommentSet)
		{
			bCommentSet = FALSE;
			nCommentLines ++;  
		}
		else if(nEndComment != -1 && bCommentSet)
		{
			bCommentSet = FALSE;
			if(nLineCommentBegin == nLines) // /* */ on the same line
				nCommentLines++;
			bufRead = bufRead.Right(bufRead.GetLength()-nEndComment-2);
			if(bufRead.Find("//")!=-1) //it is very strange!  such as  "code */ (code or blank) // code"
			{
				bufRead.TrimLeft();
				if(bufRead.Find("//")==0)
					nCommentLines++;
			}
			else if(nLineCommentBegin != nLines && bufRead.GetLength()==0)
				nCommentLines++;
		}

		if(bCommentSet)
			nCommentLines++;
	}

	*pnCommentLines = nCommentLines;
	*pnBlankLines = nBlankLines;

	file.Close();

	return nLines;

	//the following is not so good. sometimes it may obtain a wrong result

/*	CFile file;

	file.Open(strFileName, CFile::modeRead);

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

	BOOL bLastSplash = FALSE;
	BOOL bDoubleSplash = FALSE;
	BOOL bLastStar = FALSE;
	BOOL bCommentCount = FALSE;
	BOOL bBlankCount = TRUE;

	int nLength = file.GetLength();
	m_nSize += nLength;
	*pnLength = nLength;

	char buf[255];
	int nRead = 0;
	while(nLength>0)
	{
		nRead = file.Read(buf, 250);
		
		if(buf[0] == '*' && bLastSplash)
		{
			bLastSplash = FALSE;
			bCommentCount = TRUE;
		}

		if(buf[0] == '/' && bLastSplash && !bCommentCount && bBlankCount && !bDoubleSplash)
		{
			bLastSplash = FALSE;
			bDoubleSplash = TRUE;
		}

		if(buf[0] == '/' && bLastStar)
		{
			bLastStar = FALSE;
			bCommentCount = FALSE;
			nCommentLines++;
		}

		for(int i=0; i<nRead; i++)
		{
			if(buf[i] == '/')
			{
				if(i<nRead-1 && buf[i+1]=='*' && !bDoubleSplash )
					bCommentCount = TRUE;
				if(i<nRead-1 && buf[i+1]=='/' && !bCommentCount && bBlankCount  && !bDoubleSplash)
					bDoubleSplash = TRUE;
				if(i==nRead-1)
					bLastSplash=TRUE;
			}


			if(buf[i] == '*')
			{
				if(i<nRead-1 && buf[i+1]=='/')
				{
					bCommentCount = FALSE;
					nCommentLines++;
				}
				if(i==nRead-1)
					bLastStar=TRUE;
			}
			
			if( buf[i]!=' ' && buf[i]!='\t' && buf[i]!='\r' && buf[i]!='\n')//&& bBlankCount)
				bBlankCount = FALSE;

			if(buf[i]=='\n')
			{
				nLines++;
				if(bBlankCount)nBlankLines++;
				if(bBlankCount && bCommentCount)nCommentLines--;
				if(bDoubleSplash)
				{
					nCommentLines++;
					bDoubleSplash = FALSE;
				}

				bBlankCount = TRUE;
				
				if(bCommentCount) nCommentLines++;
			}
		}
		nLength -= nRead;
	}

	if(buf[nRead-1]!='\n')
		nLines++;
	if(bDoubleSplash)
		nCommentLines++;

	*pnCommentLines = nCommentLines;
	*pnBlankLines = nBlankLines;

	file.Close();

	return nLines;
*/
}

/*****************************************************************
	统计SQL文件的行数

*****************************************************************/

int CCountingDlg::GetSqlFileLines(LPCTSTR strFileName, int *pnLength, int *pnCommentLines, int *pnBlankLines)
{
	*pnLength = 0;
	*pnCommentLines = 0;
	*pnBlankLines = 0;

	CStdioFile file;
	if(file.Open(strFileName, CFile::modeRead)==FALSE)
		return 0;

	int nLines = 0;
	int nCommentLines = 0;
	int nBlankLines = 0;

	BOOL bCommentSet = FALSE;

	int nLength = file.GetLength();
	m_nSize += nLength;
	*pnLength = nLength;

	CString bufRead;

	while(file.ReadString(bufRead)!=FALSE)
	{
		nLines++;

⌨️ 快捷键说明

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