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:
The object of this program is to demonstrate DOTNET Framework CLI Windows Forms with the following functionality: 1. Drag and Drop a folder of photos; 2. Load files from disk; 3. Create thumbnails and store in an array of images; 4. Display the thumbnails on the screen; 5. Perform error checking at each stage.
New for this month:
The following functionality has been added: 6. Increase
the maximum photo count to 1000; 7. Add a scroll bar and associated logic; 8.
Provide more accurate thumbnails that display the correct photo aspect ratio.
As can be seen in the screen shot above, the program displays photo
(jpg) thumbnails in a grid format. The window may be resized in order to
show more photos. A simple Drag/Drop algorithm from Windows Explorer is used to
start the process.
The program uses a number of DOT NET Library functions
including the following:
Array::Copy()
Array::Resize()
ClientRectangle()
Directory::Exists()
DoEvents()
Form1_DragDrop()
Form1_DragEnter()
Form1_Paint()
Form1_Resize()
g->DrawImage()
g->DrawRectangle()
GetDataPresent()
GetExtension()
Image::FromFile()
Image::FromStream()
ImageStage->GetThumbnailImage()
MessageBox::Show()
Rectangle()
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 |
C++ 9.0 |
.Net 3.5 |
CLI |
Common Language Infrastructure |
Managed |
//
// READ PHOTOS FROM DISK AND DISPLAY
//
private: System::Void getfolder(void)
{
int LocalPhotoCount = 0; // Use this count for memory loading.
String ^FolderName = dragFolder;
this->Cursor = Cursors::WaitCursor;
array<String^>^ filelist;
try
{
filelist = Directory::GetFiles( FolderName, "*.jpg" );
}
catch (Exception ^e)
{
MessageBox::Show(String::Format(
"Error Reading Count of Photo Files.\n\nHere are some tech notes:\n\n"
"The process (getfiles) failed:\n\n{0}", e->ToString()));
filelist = gcnew array<String ^> (0);
}
//
// Cluge: GetFiles allows longer extensions like jpgOTHER !!!!!
// Shift bad filenames out of array into never-never land.
//
for (int c=0; c<filelist->Length; )
{
if (!Path::GetExtension(filelist[c])->ToLower()->Equals(".jpg"))
{
Array::Copy( filelist, c+1, filelist, c, filelist->Length-c-1);
// 3...6 2 7-2-1
// assume array is 7 items.
// hit on 3rd ... index 2, copy [index 3 thru last] on top of 2.
Array::Resize(filelist, filelist->Length-1);
}
else
c++;
}
// end of cluge.
if (filelist->Length != 0)
{
//clear screen, clear global array, copy file names, place photos on screen.
this->label1->Visible = false; // turn off desktop message.
for (int i=0; i<photoCount; i++) // Clear old
{
delete photo[i]; // destruction
photo[i] = nullptr;
}
photoname->Clear(photoname, 0, photoCount);
photoCount = 0;
Refresh();
LocalPhotoCount = filelist->Length; // Get new
if (LocalPhotoCount >= MAXPHOTOS) LocalPhotoCount = MAXPHOTOS;
for (int i=0; i<LocalPhotoCount; i++)
{
Image ^ ImageStage;
photoname[i] = gcnew String(filelist[i]);
// Memory issue per MS Q311754. Don't use FromFile()
// photo[i] = Image::FromFile(photoname[i]);
FileStream ^fs = gcnew FileStream(photoname[i], FileMode::Open, FileAccess::Read);
try
{
ImageStage = Image::FromStream(fs);
// Shrink memory usage by storing only a thumbnail.
photo[i] = ImageStage->GetThumbnailImage(
IMAGESIZE, IMAGESIZE, nullptr, IntPtr::Zero);
delete ImageStage;
}
catch(...)
{
ImageStage = nullptr;
photo[i] = nullptr;
MessageBox::Show(
String::Format(
"There has been a file system error reading this photo:\n\n{0}\n\n",
photoname[i]), "FILE READ ERROR");
}
fs->Close();
this->Text = String::Format("Loading {0} / {1} ...", i, LocalPhotoCount);
photoCount = i; // update global
this->Refresh();
Application::DoEvents(); // Improve progress display and user interface. (polls message loop)
}
photoCount = LocalPhotoCount; // update global
this->Text = L"Thumbnails by B.Arnold 2012";
this->Refresh();
}
else
MessageBox::Show(String::Format(
"There were no JPG files found in\n{0}",FolderName),"NO PHOTOS");
}