📄 countlines.cpp
字号:
// CountLines.cpp : Implementation of CCountLines
#include "stdafx.h"
#include "assert.h"
#include "SrcCount.h"
#include "stdio.h"
#include "CountLines.h"
/////////////////////////////////////////////////////////////////////////////
// CCountLines
STDMETHODIMP CCountLines::GetFolderLines(BSTR *pFolderPath, int *lines)
{
// TODO: Add your implementation code here
int totalLines = 0;
WIN32_FIND_DATA fd;
TCHAR szFile[MAX_PATH] = {0};
TCHAR szTempFile[MAX_PATH] = {0};
lstrcpy(szFile, (LPCTSTR)pFolderPath);
lstrcpy((TCHAR *)szTempFile, szFile);
lstrcat(szFile, _T("\\*.*"));
HANDLE hFind = FindFirstFile(szFile, &fd);
if (INVALID_HANDLE_VALUE == hFind)
{
return S_FALSE;
}
while (hFind)
{
BOOL bFind = FindNextFile(hFind, &fd);
if (!bFind && ERROR_NO_MORE_FILES == GetLastError())
{
// Find all files
*lines = totalLines;
FindClose(hFind);
return S_OK;
}
if (0 == lstrcmp(_T("."), fd.cFileName) || 0 == lstrcmp(_T(".."), fd.cFileName))
{
continue;
}
TCHAR szCurFile[MAX_PATH] = {0};
lstrcpy(szCurFile, szTempFile);
lstrcat(szCurFile, _T("\\"));
lstrcat(szCurFile, fd.cFileName);
// Get file or folder attribute
DWORD dwAttrib = GetFileAttributes(szCurFile);
if (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)
{
// The sub-folder
int tempLines = 0;
GetFolderLines((BSTR *)&szCurFile, &tempLines);
totalLines += tempLines;
}
else
{
// Stat. the specific type file
BOOL bFlag0 = 0 == lstrcmpi(_T("h"), GetFileSuffix(fd.cFileName));
BOOL bFlag1 = 0 == lstrcmpi(_T("c"), GetFileSuffix(fd.cFileName));
BOOL bFlag2 = 0 == lstrcmpi(_T("cpp"), GetFileSuffix(fd.cFileName));
if (bFlag0 || bFlag1 || bFlag2)
{
int tempLines = 0;
GetFileLines((BSTR *)&szCurFile, &tempLines);
totalLines += tempLines;
}
}
}
FindClose(hFind);
*lines = totalLines;
return S_OK;
}
STDMETHODIMP CCountLines::GetFileLines(BSTR *pFilePath, int *lines)
{
// TODO: Add your implementation code here
int totalLine = 0;
HANDLE hFile = CreateFile((TCHAR *)pFilePath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ((HANDLE)-1 == hFile)
{
*lines = -1;
return S_FALSE;
}
DWORD dwFileSize = GetFileSize(hFile, NULL);
BYTE *lpBuffer = new BYTE[dwFileSize];
memset(lpBuffer, 0, dwFileSize);
DWORD dwRead = 0;
BOOL bReadFile = ReadFile(hFile, lpBuffer, dwFileSize, &dwRead, NULL);
assert(bReadFile && dwRead == dwFileSize);
// We only count by character '\n', and you can add your rules here
for (unsigned i = 0; i < dwFileSize; i++)
{
if (lpBuffer[i] == '\n')
{
totalLine++;
}
}
delete []lpBuffer;
CloseHandle(hFile);
*lines = totalLine + 1;
return S_OK;
}
TCHAR *CCountLines::GetFileSuffix(TCHAR *pFile)
{
for (TCHAR *p = pFile + lstrlen(pFile) - 1; p >= pFile; p--)
{
if (*p == '.')
{
break;
}
}
return p + 1;
}
HRESULT CCountLines::Initialize(LPCITEMIDLIST pIDFolder,
LPDATAOBJECT pDataObj,
HKEY hRegKey)
{
// Store the PIDL
if (pIDFolder)
{
m_pIDFolder = pIDFolder;
}
// If Initializie has already been called, release the old IDataObject pointer
if (m_pDataObj)
{
m_pDataObj->Release();
m_pDataObj = NULL;
}
// If a data object pointer was passed in, save it and extract the file name
if (pDataObj)
{
m_pDataObj = pDataObj;
pDataObj->AddRef();
STGMEDIUM medium;
FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
UINT uFileCount = 0;
if (SUCCEEDED(m_pDataObj->GetData(&fe, &medium)))
{
// Get the file name from the CF_HDROP.
uFileCount = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0);
if (uFileCount)
{
DragQueryFile((HDROP)medium.hGlobal, 0, m_pszPath, sizeof(m_pszPath));
}
ReleaseStgMedium(&medium);
}
}
// Duplicate the registry handle.
if (hRegKey)
{
RegOpenKeyEx(hRegKey,
NULL,
0L,
MAXIMUM_ALLOWED,
&m_hRegKey);
}
return S_OK;
}
HRESULT CCountLines::GetCommandString(UINT idCmd,
UINT uFlags,
UINT *pwReserved,
LPSTR pszName,
UINT cchMax)
{
TCHAR szDes[MAX_PATH] = {0};
LPWSTR wszDes = NULL;
LoadString(_Module.GetModuleInstance(), IDS_SRC_COUNT, szDes, MAX_PATH);
HRESULT hr = E_INVALIDARG;
if (idCmd != IDM_SRC_COUNT)
{
return hr;
}
switch (uFlags)
{
case GCS_HELPTEXTA:
lstrcpynA(pszName, (char *)szDes, cchMax);
hr = S_OK;
break;
case GCS_HELPTEXTW:
MultiByteToWideChar(CP_ACP, 0, (char *)szDes, -1, wszDes, MAX_PATH);
lstrcpynW((LPWSTR)pszName, wszDes, cchMax);
hr = S_OK;
break;
case GCS_VERBA:
lstrcpynA(pszName, "Stat.", cchMax);
hr = S_OK;
break;
case GCS_VERBW:
lstrcpynW((LPWSTR)pszName, L"Stat.", cchMax);
hr = S_OK;
break;
default:
hr = S_OK;
break;
}
return hr;
}
HRESULT CCountLines::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
{
BOOL bEx = FALSE;
BOOL bUnicode = FALSE;
if (pici->cbSize = sizeof(CMINVOKECOMMANDINFOEX))
{
bEx = TRUE;
if ((pici->fMask & CMIC_MASK_UNICODE))
{
bUnicode = TRUE;
}
}
// The struct's lpVerb or lpVerbW has two ways to idenfity commands:
// The command's verb string or command ID offset
if (!bUnicode && HIWORD(pici->lpVerb))
{
if(StrCmpIA(pici->lpVerb, "Stat."))
{
return E_FAIL;
}
}
else if (bUnicode && HIWORD(((CMINVOKECOMMANDINFOEX *) pici)->lpVerbW))
{
if(StrCmpIW(((CMINVOKECOMMANDINFOEX *)pici)->lpVerbW, L"Stat."))
{
return E_FAIL;
}
}
else if (LOWORD(pici->lpVerb) != IDM_SRC_COUNT)
{
return E_FAIL;
}
else
{
assert(0 == HIWORD(pici->lpVerb));
int lines = 0;
TCHAR szTitle[MAX_PATH] = {0};
TCHAR szMsg[MAX_PATH] = {0};
TCHAR szFormat[MAX_PATH] = {0};
memset(szMsg, 0, MAX_PATH);
// Store current cursor and set wait cursor
HCURSOR hOldCursor = GetCursor();
HCURSOR hNewCursor = LoadCursor(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDC_COUNT_WAIT));
assert(hNewCursor);
SetCursor(hNewCursor);
// Set message string format
TCHAR szTemp[MAX_PATH] = {0};
LoadString(_Module.GetModuleInstance(), IDS_TOTAL_LINES, szFormat, MAX_PATH);
if (SUCCEEDED(GetFolderLines((BSTR *)&m_pszPath, &lines)))
{
wsprintf(szMsg, szFormat, (LPTSTR)m_pszPath, lines);
}
// Retrieve the default cursor
SetCursor(hOldCursor);
// Show message
LoadString(_Module.GetModuleInstance(), IDS_TITLE, szTitle, MAX_PATH);
MessageBox(pici->hwnd, szMsg, szTitle, MB_OK | MB_ICONINFORMATION);
}
return S_OK;
}
HRESULT CCountLines::QueryContextMenu(HMENU hmenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
if(!(CMF_DEFAULTONLY & uFlags))
{
TCHAR szMenu[MAX_PATH] = {0};
LoadString(_Module.GetModuleInstance(), IDM_SRC_COUNT, szMenu, MAX_PATH);
InsertMenu(hmenu, indexMenu, MF_STRING | MF_BYPOSITION, idCmdFirst + IDM_SRC_COUNT, szMenu);
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_SRC_COUNT + 1));
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -