Welcome to the CSIG, a Special Interest Group of the ACGNJ. The subject for this month is a discussion about MFC Windows Programming using Microsoft Visual C++ version 6.0.
At the meeting, we are going to discuss a file copy program. Here's the background: I like to keep my VC6 C++ completed executable files in a "Core" folder so that they are easy to find and run. This month's program is called "CoreFold" and the compiler will create it as "C:\Program Files\Microsoft Visual Studio\Projects\Corefold\Release\corefold.exe". My "Core" folder is "H:\Core", and I usually use Windows Explorer to copy the file. Keeping 50-100 different projects up to date in this manner has become quite tedious and takes about a minute per project to copy the executable.
Therefore, here is the strategy. Build a list of potential source files and copy the newer files to the core folder. The manual operation which previously could take over an hour now takes less than a minute with this automated file scan and copy. To accomplish this, the program will require the following:
| MFC Dialog Box |
| Recursive File Scan |
| Algorithm to Parse the Complex Path |
| File Date Checking |
| File Copy and Error Reporting |
In addition to the above requirements, let's add some Bells and Whistles:
| Fields for Source and Destination |
| Browse Dialog for Selecting Folders |
| Deluxe Browse with Starting Location |
| Registry Access for Saving Locations |
| Test Mode, Without Really Copying |
| Abort Capability |
| Listing of Files Copied |
| Auto Scroll Bar Scaling |
The beginning of the evening (starting at 7:30pm) will be a RANDOM ACCESS discussion. The main presentation will present the program.
As always, the download site has code and programs from our meetings. ( Source Code Files )
Sample Code
===========
// *********************************************************************************
// Recusive file search routine.
int CCFDlg::GetRecursiveFileList(CString &sPath, CListBox *pLB)
{ 265
CFileFind finder;
CWaitCursor hourglass;
CString strWildcard;
strWildcard = sPath + "\\*.*";
270
BOOL bWorking = finder.FindFile(strWildcard);
while (bWorking)
{
bWorking = finder.FindNextFile(); 275
if (finder.IsDots()) continue;
CString str = finder.GetFilePath();
if (finder.IsDirectory())
{ 280
GetRecursiveFileList(str, pLB); // *** RECURSIVE ****** RECURSIVE ***
}
else
{
int len = str.GetLength(); 285
if (len > 3 && 0 == str.Mid(len-4).CompareNoCase(".exe"))
{
if ( AncestorsOK(str) )
{
pLB->AddString(str); 290
int idx = pLB->GetCount();
pLB->SetTopIndex(idx-1);
if (!m_FastFlag) Sleep(10);
}
} 295
}
}
finder.Close();
return 0;
} 300
// *********************************************************************************
// Ancestor Algorithm -- Second Ancestor must match base name.
BOOL CCFDlg::AncestorsOK(CString &sTest) // enter with full path and filename
{
CString sSub1, sSub2, sSub3, sBasename, sAncestor1, sAncestor2;
int iPoint, iSlash1, iSlash2, iSlash3;
// c:\msdev\projects\corefold\release\corefold.exe
iPoint = sTest.ReverseFind('.'); // 43 310
sSub1 = sTest.Left(iPoint); // c:\msdev\projects\corefold\release\corefold
iSlash1 = sSub1.ReverseFind('\\'); // 34
sSub2 = sSub1.Left(iSlash1); // c:\msdev\projects\corefold\release
iSlash2 = sSub2.ReverseFind('\\'); // 26
sSub3 = sSub2.Left(iSlash2); // c:\msdev\projects\corefold 315
iSlash3 = sSub3.ReverseFind('\\'); // 17
sBasename = sSub1.Mid(iSlash1+1); // corefold
sAncestor1 = sSub2.Mid(iSlash2+1); // release
sAncestor2 = sSub3.Mid(iSlash3+1); // corefold 320
if (0 != sAncestor1.CompareNoCase("Release")) return false;
if (0 != sAncestor2.CompareNoCase(sBasename)) return false;
return true;
} 325