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

📄 rapidfinder.cpp

📁 一个文件查找工具的VC++源码 一个文件查找工具的VC++源码
💻 CPP
字号:
// RapidFinder.cpp: implementation of the CRapidFinder class.
//
/*===================================================================

作者:Kelvin U.V
时间:2002-9-15
功能:多线程文件查找
版本:1.0

/===================================================================*/
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RapidFinder.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


const int CRapidFinder::HIGHEST_PRIORITY=2;
const int CRapidFinder::ABOVE_NORMAL=1;
const int CRapidFinder::NORMAL_PRIORITY=0;
const int CRapidFinder::BELOW_NORMAL=-1;
const int CRapidFinder::LOWEST_PRIORITY=-2;

const LPCTSTR ErrMsg[]={
						{"未指定查找路径!"},
						{"程序结束错误 !"},
						{"未找到目标文件!"}
						};
//---------------------------------------------------------------

CRapidFinder::CRapidFinder()
{
    m_hThrds=NULL;
	InitializeCriticalSection(&m_gCriticalSection);
	ThreadSet();
}
CRapidFinder::CRapidFinder(HWND MainHwnd,CString MatchName,CString MatchDir)
{
	m_hThrds=NULL;
	InitializeCriticalSection(&m_gCriticalSection);
	ThreadSet();
	FinderSet(MainHwnd,MatchName,MatchDir);
}
CRapidFinder::~CRapidFinder()
{
	DeleteCriticalSection(&m_gCriticalSection);  
	if(m_hExitEvent)CloseHandle(m_hExitEvent);
}

//———————————————————————————————————
void CRapidFinder::FinderSet(HWND MainHwnd,CString MatchName,CString MatchDir)
{
    FinderReset();
	m_MainhWnd=MainHwnd;

	if(!MatchName.IsEmpty())
	{	
		MatchName.MakeUpper();MatchDir.MakeUpper();
		m_strFileName=MatchName;
		m_Option|=OP_FILENAME;
	}
	m_strFileDir=MatchDir;
	
	m_hExitEvent=CreateEvent(NULL,TRUE,FALSE,"RAPIDFINDER");
	CreatePathList();
}
void CRapidFinder::ThreadSet(LONG MaxThreadCount,int priority)
{
	m_Priority=priority;
	m_ActiveCount=m_MaxThreadCount=MaxThreadCount;
    if(m_hThrds)delete []m_hThrds;//释放线程句柄数组
	m_hThrds=new HANDLE[MaxThreadCount];

}
void CRapidFinder::FindWithText(LPCTSTR lpText,int count)
{
	if(!count)return ;
	m_TextSize=count;
	if(m_lpText)delete []m_lpText;
    m_Option|=OP_FILETEXT;
	m_lpText=new BYTE[count];
	memcpy(m_lpText,lpText,count);
	if(m_NextVal)delete []m_NextVal;
	m_NextVal=new int[count];

	CalNextPos();
}
void CRapidFinder::FinderReset()
{
	m_lpText=NULL;
	m_NextVal=NULL;
	m_Option=0;
	m_strFileName="";
	m_strFileDir="";
	m_DirList.RemoveAll();
	ResetEvent(m_hExitEvent);
	m_ExitCode=ERR;
}
void CRapidFinder::CreatePathList()
{
	Trim(m_strFileDir);

	if(m_strFileDir.IsEmpty())
	{
		SetErrNo(0);return ;
	}

	int np=0,op=0;
    CString str;
    while((np=m_strFileDir.Find(';',op))!=-1)
	{
		str=Trim(m_strFileDir.Mid(op,np-op));
		str.TrimRight('\\');
		if(!str.IsEmpty())m_DirList.AddTail((LPCTSTR)str);
		op=np+1;
	}
    str=Trim(m_strFileDir.Mid(op,m_strFileDir.GetLength()-op));
	str.TrimRight('\\');
	if(!str.IsEmpty())m_DirList.AddTail((LPCTSTR)str);
}
//----------------------------------------------------------------------
BOOL CRapidFinder::StartFinder()
{

	if(m_DirList.IsEmpty()){SetErrNo(0);return FALSE;}
  	PostMessage(m_MainhWnd,WM_THREADCOUNT,(WPARAM)m_ActiveCount,NULL);

	DWORD ThreadID;
    //创建主线程
	HANDLE hMainThread=CreateThread(NULL,0,MainThreadProc,(LPVOID)this,CREATE_SUSPENDED,&ThreadID);
	ASSERT(hMainThread);
    BOOL re=SetThreadPriority(hMainThread,m_Priority);//调整优先级
	ASSERT(re);
	ResumeThread(hMainThread);
	CloseHandle(hMainThread);
	
	return TRUE;
}
void CRapidFinder::PauseFinder()
{
	if(m_ExitCode==PAUSE)return ;
	m_ExitCode=PAUSE;
	SetEvent(m_hExitEvent);
	Sleep(40);
}
void CRapidFinder::ResumeFinder()
{ 
	SetEvent(m_hExitEvent);  
}
void CRapidFinder::StopFinder()
{
	if(m_ExitCode==STOP)return ;
	if(m_ExitCode==PAUSE)
	{
		ResumeFinder();
        Sleep(40);//延时
	}
		m_ExitCode=STOP;
	    SetEvent(m_hExitEvent);
}
//----------------------------------------------------------------------------------------------------
HANDLE CRapidFinder::StartThread(LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParam)
{
	DWORD ThreadID;
	CRapidFinder *finder=(CRapidFinder *)lpParam;

	HANDLE htmp=CreateThread(NULL,0,lpStartAddress,lpParam,CREATE_SUSPENDED,&ThreadID);
	BOOL re=SetThreadPriority(htmp,finder->m_Priority);
	ASSERT(re);
	ResumeThread(htmp);
	return htmp;
}
//------------------------------------------------------------------------------------------------------
DWORD WINAPI CRapidFinder::MainThreadProc(LPVOID lpParam)
{
   CRapidFinder *finder=(CRapidFinder *)lpParam;

resume:
   //Reset
   ResetEvent(finder->m_hExitEvent);
   finder->m_ExitCode=ERR;
   finder->m_ActiveCount=finder->m_MaxThreadCount;
   
   PostMessage(finder->m_MainhWnd,WM_THREADCOUNT,(WPARAM)(finder->m_ActiveCount),NULL);
   for(int i=0;i<finder->m_MaxThreadCount;i++)
	   finder->m_hThrds[i]=StartThread(ThreadProc,lpParam);

   WaitForMultipleObjects(finder->m_MaxThreadCount,finder->m_hThrds,TRUE,INFINITE);

   for(i=0;i<finder->m_MaxThreadCount;i++)
	   CloseHandle(finder->m_hThrds[i]); //关闭所有线程句柄
   
   
   //查看线程退出原因
   switch(finder->m_ExitCode)
   {
   case PAUSE:SendMessage(finder->m_MainhWnd,WM_THREADPAUSE,NULL,NULL);
	          ResetEvent(finder->m_hExitEvent);
			  //等待继续查找
	          WaitForSingleObject(finder->m_hExitEvent,INFINITE);
	          goto resume;
   case EXIT:SendMessage(finder->m_MainhWnd,WM_THREADEXIT,EXIT,NULL);
	         finder->FinderReset();
	         break;;
   case STOP:SendMessage(finder->m_MainhWnd,WM_THREADEXIT,STOP,NULL);
	         finder->FinderReset();
	         break;
   default:finder->SetErrNo(1);return 0;
   }	
	return 1;
}
//----------------------------------------------------------------------------------
DWORD WINAPI CRapidFinder::ThreadProc(LPVOID lpParam)
{
   CRapidFinder *finder=(CRapidFinder *)lpParam;
   CFileFind  filefinder;
   CStringList filelist;
   CString PathStr;
   CString CurPath;
   int re;
   BYTE bNewActive=1,bOldActive;
   CString *lpFolder=new CString;
   while(1)
   {
	   bOldActive=bNewActive;
	   if(WaitForSingleObject(finder->m_hExitEvent,0)!=WAIT_TIMEOUT)
	   {
		   if(bOldActive)InterlockedDecrement(&finder->m_ActiveCount);
		   PostMessage(finder->m_MainhWnd,WM_THREADCOUNT,(WPARAM)finder->m_ActiveCount,NULL);
		   break;
	   }
       
	   if(!finder->m_ActiveCount)
	   {
		   SetEvent(finder->m_hExitEvent);
		   finder->m_ExitCode=finder->EXIT;
		   break;
	   }

  	   //进入临界区
	   EnterCriticalSection(&finder->m_gCriticalSection);
	   if(finder->m_DirList.IsEmpty())bNewActive=0;
	   else 
	   {
	        bNewActive=1;
		    *lpFolder=finder->m_DirList.RemoveHead();
		    CurPath=*lpFolder+_T("\\*.*");
	   }
	   LeaveCriticalSection(&finder->m_gCriticalSection);
	   //离开临界区
	  
	  if(bNewActive!=bOldActive)
	  {
		  bNewActive?InterlockedIncrement(&finder->m_ActiveCount):InterlockedDecrement(&finder->m_ActiveCount);
		  PostMessage(finder->m_MainhWnd,WM_THREADCOUNT,(WPARAM)finder->m_ActiveCount,NULL);
	  }
      else if(!bNewActive)continue;
       
      SendMessage(finder->m_MainhWnd,WM_FINDERFOLDER,(WPARAM)lpFolder,NULL);

       if(filefinder.FindFile(LPCTSTR(CurPath)))
	   {
		   do 
		   {
			   re=filefinder.FindNextFile();
			   if(filefinder.IsDots())continue;
			   PathStr=filefinder.GetFilePath();

			   if(filefinder.IsDirectory())
			   {
			       EnterCriticalSection(&finder->m_gCriticalSection);
				   finder->m_DirList.AddTail(PathStr);
				   LeaveCriticalSection(&finder->m_gCriticalSection);
			   }
			   else filelist.AddTail(PathStr);
		   }while(re);
	   }
	   while(!filelist.IsEmpty())
	   {
		   PathStr=filelist.RemoveHead();
		   if(finder->MatchProc(PathStr))
			   SendMessage(finder->m_MainhWnd,WM_FINDERITEM,(WPARAM)&PathStr,NULL);
	   }
   }
delete lpFolder;
filefinder.Close();
return 0;
}
//--------------------------------------------------------------------
BOOL __fastcall CRapidFinder::MatchProc(CString &findpath)
{
    CString fname(findpath);
    int pos=fname.ReverseFind('\\');
	fname.MakeUpper();
	if((m_Option&OP_FILENAME)&&(fname.Find(m_strFileName,pos+1)==-1))return false;
	if((m_Option&OP_FILETEXT)&&!FindTextFromFile(findpath))return false;
	return true;
}
BOOL __fastcall CRapidFinder::FindTextFromFile(CString &findpath)
{
    CFile file;
	if(NULL==file.Open(findpath.GetBuffer(0),CFile::modeRead|CFile::typeBinary))return false;
	BYTE *Buffer=new BYTE[512];
	int nRead;
	if(!(nRead=file.Read(Buffer,512))){file.Close();return false;}
	int i=0,j=0;

    while(j<m_TextSize)
	if(j==-1||Buffer[i]==m_lpText[j])	
	{	
	   if(++i==nRead)
	   {
		/*PeekAndPump();*/
       	if(!(nRead=file.Read(Buffer,512))){file.Close();return false;}
		i=0;
	   }
	   j++;
	}
	else j=m_NextVal[j];
    file.Close();
    return true;	
}
int*  CRapidFinder::CalNextPos()
{
 int j=0,k=-1;
  m_NextVal[0]=-1;
  while(j<m_TextSize-1)
	  if((k==-1)||(m_lpText[j]==m_lpText[k]))
	  {
		  j++;k++;
		  if(m_lpText[j]!=m_lpText[k])m_NextVal[j]=k;
		  else m_NextVal[j]=m_NextVal[k];
	  }
	  else k=m_NextVal[k];
  return m_NextVal;
}

⌨️ 快捷键说明

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