1.效果图:


这个软件主要的功能就是点击选择目录,然后点击开始复制,就会把选中目录下的所有文件和文件夹复制到可移动磁盘中。如果你插入多个U盘或者手机什么的,就会多线程进行复制。


MFC 多线程的一个例子_git



2.关于MFC中的多线程。


我参考的是《MFC Windows 程序设计》的第17章中的17.1.11 “您的第一个多线程应用程序”,推荐读者下载下这书的电子版看下这章。这章的例子是一个多线程计算素数。我这例子是多线程复制文件非常类似。


//有几个可移动磁盘,就用几条线程进行复制
for(int i = 0; i < strDriver.size(); ++i){
THREADPARMS *ptp = new THREADPARMS;//传的参数
ptp->mOriDir = m_FileDir;
ptp->hWnd = m_hWnd;
ptp->mDestinationDir = strDriver[i];
AfxBeginThread(ThreadFunc,ptp);
}


UINT ThreadFunc(LPVOID pParam)
{
THREADPARMS *ptp = (THREADPARMS*)pParam;//重新转换回来
CString mOriDir = ptp->mOriDir;
CString mDestinationDir = ptp->mDestinationDir;
HWND hWnd = ptp->hWnd;
delete ptp;

CopyDir(mOriDir,mDestinationDir);//进行复制工作
::PostMessage(hWnd, WM_USER_THREAD_FINISHED, (WPARAM)(new CString(mDestinationDir)), 0);//复制完毕,发送message
return 0;
}

LONG CMultiCopyDlg::OnThreadFinished(WPARAM wParam, LPARAM lParam)
{

CString *pstrGet = (CString *)wParam;
m_ListResult.InsertItem(m_nItemCount,*pstrGet + _T("复制完毕"));
++m_nItemCount;
delete pstrGet;
//复制完毕把控件设置为可用
if(m_nItemCount == m_nDiskCount){
GetDlgItem(IDOK)->EnableWindow(TRUE);
GetDlgItem(IDC_SELECTDIR)->EnableWindow(TRUE);
}
return 0;
}


这里只是部分关键代码,读者还是下载整个程序慢慢研究。


3.一些MFC文件操作函数


3.1MFC得到所有可移动磁盘名字


vector<CString> GetReMovableDrive(void)
{
vector<CString> strDriver;
DWORD id = GetLogicalDrives();
for (int i = 1; i < 26; i++)//尝试26个字母
{
if ((id & (1 << i)) != 0)
{
CString strDrv = CString(char('A' + i)) + ":";
if (GetDriveType(strDrv) == DRIVE_REMOVABLE)
{
strDriver.push_back(strDrv);
}
}
}
return strDriver;
}



3.2复制所有文件和目录


//拷贝目录
BOOL CopyDir(CString strSrcPath, CString strDstPath)
{ //创建目标文件夹
CreateDirectory(strDstPath,NULL);
CFileFind finder;
//打开指定的文件夹进行搜索
BOOL bWorking = finder.FindFile(strSrcPath + "\\" + "*.*");
while(bWorking)
{
// 从当前目录进行搜索
bWorking = finder.FindNextFile();
CString strFileName = finder.GetFileName();
CString strSrc = strSrcPath + "\\" + strFileName;
CString strDst = strDstPath + "\\" + strFileName;
// 判断搜索到的目录是不是"." 和".."目录
if(!finder.IsDots())
{
// 判断是否是文件夹
if(finder.IsDirectory())
{
// 如果是文件夹,进行递归
if(!CopyDir(strSrc, strDst))
return false;
}
else
{
//如果是文件,进行复制
if(!CopyFile(strSrc, strDst, FALSE))
return false;
}
}
}
return true;
}