📄 countingdlg.cpp
字号:
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_nSysTimer)
{//左上角动态图标
static int icons[] =
{ IDI_ICON1, IDI_ICON2, IDI_ICON3, IDI_ICON4, IDI_ICON5, IDI_ICON6,
IDI_ICON7, IDI_ICON8, IDI_ICON9, IDI_ICON10, IDI_ICON10};
static long index = 0;
index = ++index%10;
HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(icons[index]),
IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);//SM_CXICON
HICON hPrevIcon = (HICON)AfxGetMainWnd()->SendMessage(WM_SETICON,ICON_SMALL,(LPARAM)hIcon);
return;
}
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 *pnCodeLines, int* pnCommentLines, int* pnBlankLines)
{
//there are two methods to count lines in files, by CStdioFile or CFile
*pnLength = 0;
*pnCodeLines = 0;
*pnCommentLines = 0;
*pnBlankLines = 0;
CStdioFile file;
if(file.Open(strFileName, CFile::modeRead)==FALSE)
return 0;
int nLines = 0;
int nCodeLines = 0;
int nCommentLines = 0;
int nBlankLines = 0;
BOOL bCommentSet = FALSE; //注释行统计标识 有"/*"时TRUE, "*/"时FALSE
BOOL bQuatoSet = FALSE; //字符串统计标识 首次一行有奇数个"时TRUE, 下一行有奇数个"时FALSE
int nLength = file.GetLength();
*pnLength = nLength;
CString bufRead;
int nLineCommentBegin = 0;
while(file.ReadString(bufRead)!=FALSE)
{
BOOL bStatedComment = FALSE;//本行作为注释行是否已统计过
BOOL bStatedCode = FALSE; //本行作为代码行是否已统计过
nLines++;
bufRead.TrimLeft(); //先将文件头的空格或制表符去掉
if(bufRead.GetLength()==0) //为空白行
{
nBlankLines++;
continue;
}
if(bCommentSet && bufRead.Find("*/")==-1)
{
nCommentLines++;
continue;
}
if(bufRead.Find("//")==-1 && bufRead.Find("/*")==-1 && bufRead.Find("*/")==-1)
{//如果本行根本就无注释符,则要不是注释符,要不是代码行
if(bCommentSet)
{
nCommentLines++; continue;
}
else
{
if(bufRead.Find('"')==-1)
{
nCodeLines++; continue;
}
}
}
if(bufRead.Find("//")==0 && !bCommentSet && !bQuatoSet)
{
nCommentLines++;
continue;
}
BOOL bDoubleSplashFound = FALSE;
BOOL bSplashStarFound = FALSE;
for(int i=0; i<bufRead.GetLength()-1; i++)
{
char cTemp = bufRead[i];
if(bufRead[i]=='/' && bufRead[i+1]=='/' && !bCommentSet && !bQuatoSet)
{
if(!bStatedComment && (m_nStatMethod==1 || m_nStatMethod ==2))
{
bStatedComment = TRUE;
nCommentLines++;
}
bDoubleSplashFound = TRUE;
//i++;//应该+1,但也没有什么用处
break;
}
else if(bufRead[i]=='/' && bufRead[i+1]=='*' && !bCommentSet && !bQuatoSet)
{
if(!bStatedComment && (m_nStatMethod==1 || m_nStatMethod ==2))
{
bStatedComment = TRUE;
nCommentLines++;
}
bCommentSet = TRUE;
bSplashStarFound = TRUE;
i++;
}
//计算代码行必须在bCommentSet关闭之前
else if(bufRead[i]!=' ' && bufRead[i]!='\t' && !bCommentSet)
{
if(!bStatedCode)
{
bStatedCode = TRUE;
nCodeLines++;
}
if(bufRead[i]=='\\')
{//\之后的字符要跳过
i++;
continue;
}
if(bufRead[i]=='\'')
{
if(bufRead[i+1]=='\\')
i+=2;
else
i+=1;
continue;
}
if(bufRead[i]=='"')
{//"必须引起重视,感谢ltzhou
bQuatoSet = !bQuatoSet;
}
}
else if(bufRead[i]=='*' && bufRead[i+1]=='/' && bCommentSet && !bQuatoSet)
{
if(!bStatedComment && (m_nStatMethod==1 || m_nStatMethod ==2))
{
bStatedComment = TRUE;
nCommentLines++;
}
bCommentSet = FALSE;
bSplashStarFound = TRUE;
i++;
}
}
if(bDoubleSplashFound)
{
if(m_nStatMethod==2 && bStatedCode) //如果统计方法为第三种,且同时有代码行与注释行,则只计注释行
{
nCodeLines--;
}
if(m_nStatMethod==0 && !bStatedCode)//如果统计方法为第一种,且未作为代码行统计过,那么必为注释行
{
nCommentLines++;
}
continue;
}
if(bufRead[bufRead.GetLength()-1]=='"'&&!bCommentSet)
{//若某行最后一个是",则必定用来关闭bQuatoSet,记代码行一行,否则报错
bQuatoSet = !bQuatoSet;
if(!bQuatoSet)
{
if(!bStatedCode)
{
bStatedCode = TRUE;
nCodeLines++;
}
}
else
{
CStdioFile fileLog;
if(fileLog.Open(m_strLogFile, CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate)==TRUE)
{
CString strMsg;
if(fileLog.GetLength()==0)
{
strMsg.Format("文件\t行\t问题\n", strFileName, nLines);
fileLog.WriteString(strMsg);
}
strMsg.Format("%s\t%d\t字符串换行未用\\\n", strFileName, nLines);
fileLog.WriteString(strMsg);
fileLog.Close();
}
}
continue;
}
if(bufRead[bufRead.GetLength()-1]!=' ' && bufRead[bufRead.GetLength()-1]!='\t' && !bCommentSet
&& bufRead[bufRead.GetLength()-2]!='*' && bufRead[bufRead.GetLength()-1]!='/')
{//如果最后一个字符非空格或制表符,且前面无/*,最后两个字符不是*/,则为代码行
if(!bStatedCode)
{
bStatedCode = TRUE;
nCodeLines++;
}
}
if(bSplashStarFound)
{
if(m_nStatMethod==2 && bStatedCode) //如果统计方法为第三种,且同时有代码行与注释行,则只计注释行
{
nCodeLines--;
}
if(m_nStatMethod==0 && !bStatedCode && !bStatedComment) //若该行无代码如 /*abc*/ //222
//但是统计方法是第一种,则需要追加注释行计数一次
{
bStatedComment = TRUE;
nCommentLines++;
}
}
if(!bStatedComment && bCommentSet)//可能是前面有/*,在第一种统计方法中,未作为代码行计算过,那么本行肯定是注释行
{
if(m_nStatMethod==0 && !bStatedCode)
{
bStatedComment = TRUE;
nCommentLines++;
}
}
// if(bQuatoSet && bufRead[bufRead.GetLength()-1]=='"')
// {
// bQuatoSet = FALSE;
// }
if(bQuatoSet && bufRead[bufRead.GetLength()-1]!='\\')
{
CStdioFile fileLog;
if(fileLog.Open(m_strLogFile, CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate)==TRUE)
{
CString strMsg;
if(fileLog.GetLength()==0)
{
strMsg.Format("文件\t行\t问题\n", strFileName, nLines);
fileLog.WriteString(strMsg);
}
strMsg.Format("%s\t%d\t字符串换行未用\\\n", strFileName, nLines);
fileLog.WriteString(strMsg);
fileLog.Close();
}
}
}
*pnCodeLines = nCodeLines;
*pnCommentLines = nCommentLines;
*pnBlankLines = nBlankLines;
file.Close();
return nLines;
}
/*********************************************************
统计c++文件
*********************************************************/
int CCountingDlg::GetCppFileLines_1_0_5(LPCTSTR strFileName, int* pnLength, int *pnCodeLines, 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 nCodeLines = 0;
int nCommentLines = 0;
int nBlankLines = 0;
BOOL bCommentSet = FALSE; //注释行统计标识 有"/*"时TRUE, "*/"时FALSE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -