Note: Application has been compiled with the free Visual Studio
Express 2012 compiler.
The source/project may be
converted back to an older compiler with this
PROCEDURE.
Also, check out this
web site for a possible solution to the Form Applicaton issue:
c-cli-template-of-windows-form-application-in-visual-studio-express-2012
Welcome to the CSIG, a Special Interest Group of the ACGNJ. This is an exciting time for the C Language programming since Microsoft now has 4 different language compilers: C++, C++ Express, C-Sharp, and C-Sharp Express. These are all capable of creating Windows (tm) programs. (Some are FREE!)
Here's a brief synopsis of this month's meeting:
This month we will optimise the program code by benchmarking specific areas of
the program that seem to take too much time. This will involve examples of the
Microsoft "StopWatch" class and methods.
Last month continued a multi-part presentation of creating an application with a particular purpose. The first step is the algorithm. Next, this must be coded to verify the plan. The code presented last month created a Console type program.. There's no point in struggling with the Windows functions until the algorithm viability and performance has been verified. The "Top40" App used Microsoft's C++/CLI features and simply displays to a "DOS" box. Now that we have confidence in the approach, the program can then be converted into a Windows program using the normal user interface and dotnet functions. (Note: this will be a dotnet re-write of FSTAT presented in Csig2005.)
Object: to scan the entire C: drive and tabulate the statistics of all of the files. (The user may also choose other drives, subdirectories, flash, and network drives.) Stats include size and count totals, and percent relative to file extension. Directory functions will be used for the scanning and temperred with exception (error) handling code for special circumstances. There will be activity on the screen during scanning so that the user is kept informed. The internal working database is a System::Collections::Generic::List. The output is via a Form::ListView control and options have beed added to sort columns or to copy data to the clipboard. ( <=== Click FlowChart at left. )
The program uses a number of DOT NET Library functions including the following:abort | application | array | binarysearch | break |
clientrectangle | clientsize | clipboard | collection | default |
define | dialogresult | directory | doevents | doublebuffered |
EnumerateFiles | formclosing | gcnew | icomparable | icomparer |
icontainer | ienumerable | image | include | list |
listview | listviewitem | mainmenustrip | namespace | nullptr |
pathtoolong | progressbarstyle | public | queue | random |
record | rectangle | rectangletoscreen | recursive | EnumerateDirectories |
showdialog | tobitmap | topdirectoryonly | winlogo |
There are a number of ways to refer to Microsoft's latest compilers and code. Here's what Wikipedia says:
The Common Language Infrastructure (CLI) is an open specification developed by Microsoft that describes
the executable code and runtime environment that form the core of the Microsoft .NET Framework.
The specification defines an environment that allows multiple high-level languages to be used
on different computer platforms without being rewritten for specific architectures.
Microsoft .Net Framework 3.5, etc. |
C++ 9.0, etc. |
.Net 3.5, etc. |
CLI |
Common Language Infrastructure |
Managed |
Here's what Nishant Sivankumar (C++/CLI in Action) says:
The role
of C++/CLI C++ is a versatile programming language with a substantial number of
features that makes it the most powerful and flexible coding tool for a
professional developer. The Common Language Infrastructure (CLI) is an
architecture that supports a dynamic language-independent programming model
based on a Virtual Execution System. The most popular implementation of the CLI
is Microsoft’s .NET Framework for the Windows operating system. C++/CLI is a
binding between the standard C++ programming language and the CLI.
void Process(String ^ root) // Recursive file search
{
String ^mPath;
FSTATdata record;
mPath = root;
if (!mPath->EndsWith("\\")) mPath += "\\";
Application::DoEvents(); //check for messages in queue.
// Scan the files in this directory.
// --------------------------------
// MS: "EnumerateFiles can be more efficient than GetFiles for large tasks."
// MS: "This requires dotNet 4 (VS2010 and VS2012)."
try
{
System::Collections::Generic::IEnumerable<String ^> ^ iFiles =
Directory::EnumerateFiles(mPath, "*.*"); // default = TopDirectoryOnly
for each (String ^ fileName in iFiles)
{
if (gbl->Abort) break;
CatogorizeFile( fileName);
if (Metronome) UpdateActivity( fileName);
}
}
//// Land here if EnumerateFiles fails ...
catch ( System::UnauthorizedAccessException ^uae) { gbl->Permissions++ ; }
catch ( System::IO::PathTooLongException ^ptl) { gbl->PathTooLong++ ; }
catch ( ... ) { gbl->GeneralError++ ; }
// Scan the directories in this directory.
// --------------------------------------
try
{
System::Collections::Generic::IEnumerable<String ^> ^ iDirs =
Directory::EnumerateDirectories(mPath, "*.*");
for each (String ^ dirName in iDirs)
{
if (gbl->Abort) break;
++gbl->Loop;
Process( dirName); // RECURSIVE !!! RECURSIVE !!! RECURSIVE !!!
}
}
// Land here if EnumerateDirectories() fails ...
catch ( System::UnauthorizedAccessException ^uae) { gbl->Permissions++ ; }
catch ( System::IO::PathTooLongException ^ptl) { gbl->PathTooLong++ ; }
catch ( ... ) { gbl->GeneralError++ ; }
if (gbl->PathTooLong > MAXERRORS || gbl->FileErrors > MAXERRORS || gbl->GeneralError > MAXERRORS)
gbl->Abort = true;
}
/* *********************************************************************************************** */
// Decide whether or not to add file type into database.
void CatogorizeFile(String ^ filename)
{
// If Extension exists in mList, bump count & kbytes
// Else
// Add entry with a count of 1.
// Re-sort mList.
FileInfo ^ fstats;
try
{
fstats = gcnew FileInfo(filename);
}
catch(...)
{
gbl->FileErrors++ ; return; // Skip on any error.
}
FSTATdata ^record = gcnew FSTATdata();
record->KBytes = fstats->Length >> 10;
if ((fstats->Length & 0x3FF) > 511) ++record->KBytes; // round up.
record->Ext = fstats->Extension->ToUpper();
int idx = Stats->BinarySearch(record); // search for Ext
if (idx < 0)
{
record->Count=1;
Stats->Add(record);
Stats->Sort();
}
else
{
Stats[idx]->Count++ ;
Stats[idx]->KBytes += record->KBytes;
}
}
/////////////////////////////////////////////////////////////////////////////