首页 > 代码库 > MFC程序(c++)之搜索所有文件和文件夹

MFC程序(c++)之搜索所有文件和文件夹

效果图



//MySearchDlg.h

// MySearchDlg.h : 头文件
//

#pragma once


// CMySearchDlg 对话框
class CMySearchDlg : public CDialogEx
{
// 构造
public:
	CMySearchDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_MYSEARCH_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持

	void OnOK();
// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnDropFiles(HDROP hDropInfo);
	afx_msg void OnDblclkListbox();
	afx_msg void OnEnChangeEdit1();
	afx_msg void OnBnClickedOk();
	afx_msg void OnBnClickedCancel();
	afx_msg void OnLbnSelchangeList1();
	afx_msg void OnBnClickedOk2();
};

MySearchDlg.cpp

// MySearchDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "MySearch.h"
#include "MySearchDlg.h"
#include "afxdialogex.h"
//#include <sys/stat.h>
//#include <direct.h>
//#include <iostream>  
#include<fstream>  
//#include <shlwapi.h>
//#pragma comment(lib,"Shlwapi.lib") //如果没有这行,会出现link错误
using namespace std;  

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

int findCount = 0;
CListBox *list = NULL;
bool isContent = true;

char *wtoc(wchar_t *wText);
wchar_t *ctow(char *sText);
char *cstoc(CString cs);

//bool isDir(const char* path);  
unsigned myFind(const string& filename, const string& tofind);  
void findInDir(const char *path, const string& tofind);  
//void findInDir(const char *path, const string& tofind, int recursive);

char *wtoc(wchar_t *wText)
{
	DWORD dwNum = WideCharToMultiByte(CP_ACP, NULL, wText, -1,NULL, 0, NULL, FALSE);//把第五个参数设成NULL的到宽字符串的长度包括结尾符
	char *psText = NULL;
	psText = new char[dwNum];
	if(!psText)
	{
		delete []psText;
		psText = NULL;
	}
	WideCharToMultiByte (CP_ACP, NULL, wText, -1,psText, dwNum, NULL, FALSE);
	return psText;
}
wchar_t *ctow(char *sText)
{
	DWORD dwNum = MultiByteToWideChar (CP_ACP,  0, sText, -1, NULL, 0);//把第五个参数设成NULL的到宽字符串的长度包括结尾符
 
	wchar_t *pwText = NULL;
	pwText = new wchar_t[dwNum];
	if(!pwText)
	{
		delete []pwText;
		pwText = NULL;
	}
	unsigned nLen = MultiByteToWideChar (CP_ACP, 0, sText, -1, pwText, dwNum+10);
	if (nLen >= 0)
	{pwText[nLen] = 0;}
	return pwText;
}
char *cstoc(CString cs)
{
	wchar_t *t1 =cs.GetBuffer(cs.GetLength());  
	cs.ReleaseBuffer();  
	return wtoc(t1);
}

unsigned myFind(const string& filename, const string& tofind)  
{  
    ifstream fin(filename.c_str(),ios_base::binary);  
    string str(1024*1024*2,0);  
    fin.read(&str[0],2*1024*1024);  
    fin.close();  
      
    string::size_type beg = 0;  
    string::size_type pos = -1;  
    string::size_type find_size = tofind.size();  
    if(0 == find_size)  
    {return 0;}  
      
    unsigned count = 0;  
    while((pos=str.find(tofind,beg))!=string::npos)  
    {  
        beg=pos+find_size;  
        count++;  
    }  
    return count;
}  

//bool isDir(const char* path)  
//{  
//	CString str_cap(path);
//	return PathIsDirectory((const WCHAR *)(str_cap.AllocSysString()));
//}  

//遍历文件夹的驱动函数  
void findInDir(const char *path, const string& tofind)  
{  
	CString strDir(path);
    if(strDir == _T(""))
     {
         return;
     }
     else
     {
         if(strDir.Right(1) != _T("//"))
              strDir += L"//";
         strDir =strDir+_T("*.*");
     }
     CFileFind finder;
     CString strPath;
     BOOL bWorking = finder.FindFile(strDir);
     while(bWorking)
     {
         bWorking = finder.FindNextFile();
         strPath = finder.GetFilePath();
         if(finder.IsDirectory() && !finder.IsDots())
              findInDir(cstoc(strPath), tofind); //递归调用
         else if(!finder.IsDirectory() && !finder.IsDots())
		 {
			 if(!isContent)
			 {
				wchar_t *wc = ctow((char*)tofind.c_str());
				 int dote = strPath.ReverseFind('\\');
				 CString dst = strPath.Right(strPath.GetLength() - dote - 1);

				 if(dst.Find(wc, 0) != -1)
				 {
					 findCount++;
					 if(findCount > 1000)
						 return;
					 list->AddString(strPath);
				 }
			 }
			 else
			 {
				 std::string strTemp = cstoc(strPath);
				 int c = -1;
				 if((c = myFind(strTemp, tofind)) != 0)
				 {
					  findCount++;
					  if(findCount > 1000)
						 return;
					 CString str;
					 str.Format(L"找到%d个:%s", c, strPath);
					 list->AddString(str);
				 }
			 }
         }
 
     }
}
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMySearchDlg 对话框



CMySearchDlg::CMySearchDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CMySearchDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMySearchDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMySearchDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_EN_CHANGE(IDC_EDIT1, &CMySearchDlg::OnEnChangeEdit1)
	ON_BN_CLICKED(IDOK, &CMySearchDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDCANCEL, &CMySearchDlg::OnBnClickedCancel)
	ON_WM_DROPFILES() 
	ON_LBN_SELCHANGE(IDC_LIST1, &CMySearchDlg::OnLbnSelchangeList1)
	ON_BN_CLICKED(IDOK2, &CMySearchDlg::OnBnClickedOk2)
	ON_LBN_DBLCLK(IDC_LIST1, OnDblclkListbox)
	ON_WM_SIZE()
END_MESSAGE_MAP()


// CMySearchDlg 消息处理程序

BOOL CMySearchDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	CButton *btn = (CButton *)GetDlgItem(IDOK);
	btn->SetFocus();
	list  = (CListBox *)GetDlgItem(IDC_LIST1);
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CMySearchDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

void CMySearchDlg::OnDblclkListbox()
{
	int index = list->GetCurSel();
	if(index == -1)
	{return;}

	CString str;
	list->GetText(index, str);
	int tmp = str.Find(':');
	CString strFilePath = str.Right(str.GetLength() - 1 - tmp);

	// 打开“打开方式->选择程序...”对话框
	int nRet = (int)ShellExecute( this->m_hWnd, _T("open"), strFilePath, NULL, NULL, SW_SHOWNORMAL );
	if ( SE_ERR_NOASSOC == nRet ) // 没有相关的程序能够打开该文件
	{
		CString strCmd;
		strCmd.Format( _T("shell32, OpenAs_RunDLL  %s"), strFilePath );
		ShellExecute( NULL, _T("open"), _T("rundll32.exe"), strCmd, NULL, SW_SHOWNORMAL );
	}

	CString strParam(_T("/select,"));
	strParam += strFilePath;

	tmp = strFilePath.ReverseFind('\\');
	CString strDir = strFilePath.Left(tmp);
	ShellExecute(0,_T("open"),_T("Explorer.exe"),strParam,0,SW_NORMAL);
	ShellExecute( this->m_hWnd, _T("open"), strDir, NULL, NULL, SW_SHOWNORMAL );
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CMySearchDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}


//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMySearchDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMySearchDlg::OnSize(UINT nType, int cx, int cy)
{
	CWnd *pWnd = GetDlgItem(IDC_LIST1);     //获取控件句柄
	CRect rect;   //获取控件变化前大小
	pWnd->GetWindowRect(&rect);
	 ScreenToClient(&rect);
	 pWnd->MoveWindow(rect.left, rect.top, cx - 25, cy - 100);
}

void CMySearchDlg::OnDropFiles(HDROP hDropInfo)
{
	 // TODO: Add your message handler code here and/or call default
	 WCHAR szFileName[MAX_PATH + 1] = {0};//被拖拽的文件的绝对路径
	 UINT nFiles = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0); //被拖拽的文件的个数
	 for(UINT i=0; i<nFiles; i++)
	 {
		DragQueryFile(hDropInfo, i, szFileName, MAX_PATH);//拖拽的文件名
		CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT1);
		edit->SetWindowTextW(szFileName);
		break;
	 }
	 // 结束此次拖拽操作,并释放分配的资源
	 CDialog::OnDropFiles(hDropInfo);
}

void CMySearchDlg::OnEnChangeEdit1()
{
	// TODO:  如果该控件是 RICHEDIT 控件,它将不
	// 发送此通知,除非重写 CDialogEx::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask(),
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
}


void CMySearchDlg::OnBnClickedOk()
{
	isContent = true;
	findCount = 0;
	list->ResetContent();
	this->SetWindowTextW(L"查找文件或文件夹");
	// TODO: 在此添加控件通知处理程序代码
 	CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT1);
	CString str1;
	edit->GetWindowTextW(str1);
	if(str1.IsEmpty())
	{
		MessageBox(L"请拖入要查找的文件或文件夹");
		return;
	}

	CString str2;
	edit = (CEdit *)GetDlgItem(IDC_EDIT2);
	edit->GetWindowTextW(str2);
	if(str2.IsEmpty())
	{
		MessageBox(L"请输入要查找的内容");
		return;
	}

	findInDir(cstoc(str1), cstoc(str2));

	if(findCount == 0)
	{
		CString str;
		str.Format(L"没有找到%s", ctow(cstoc(str2)));
		if(findCount == 0)
		{this->SetWindowTextW(str);}
	}
}


void CMySearchDlg::OnBnClickedCancel()
{
	// TODO: 在此添加控件通知处理程序代码
	CDialogEx::OnCancel();
}


void CMySearchDlg::OnLbnSelchangeList1()
{
	// TODO: 在此添加控件通知处理程序代码
}


void CMySearchDlg::OnBnClickedOk2()
{
	isContent = false;
	findCount = 0;
	list->ResetContent();
	this->SetWindowTextW(L"查找文件或文件夹");

	// TODO: 在此添加控件通知处理程序代码
 	CEdit *edit = (CEdit *)GetDlgItem(IDC_EDIT1);
	CString str1;
	edit->GetWindowTextW(str1);
	if(str1.IsEmpty())
	{
		MessageBox(L"请拖入要查找的文件或文件夹");
		return;
	}

	CString str2;
	edit = (CEdit *)GetDlgItem(IDC_EDIT2);
	edit->GetWindowTextW(str2);
	if(str2.IsEmpty())
	{
		MessageBox(L"请输入要查找的文件");
		return;
	}
	findInDir(cstoc(str1), cstoc(str2));
	if(findCount == 0)
	{
		CString str;
		str.Format(L"没有找到%s", ctow(cstoc(str2)));
		if(findCount == 0)
		{this->SetWindowTextW(str);}
	}
}

void CMySearchDlg::OnOK()
{ //里面什么也不写
}


效果图

MFC程序(c++)之搜索所有文件和文件夹