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

📄 countlines.cpp

📁 在 Windows 的资源管理器窗口中
💻 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 + -