I have written a class (Windows Form) in Managed C++ that accepts an
array of image filenames and will display them sequentially. All images
will be the same size. I got it to work, but I know something is not
right because of the way I am using Application::DoEvents() (ref:
http://www.codinghorror.com/blog/archives/000159.html and
http://www.codinghorror.com/blog/archives/000370.html ), along with the
fact that I get a crash when I try to close the window (I get a
NullReferenceException referring to the PlotDisplayWindow).
I tried adding a System::Windows::Forms::Timer and using that to trigger
a change in picture, but I could not figure out how to pass the
PaintEventArgs argument of my form's Paint handler to the event handler
that gets triggered when the timer goes off, so I removed the code for
that.
So, how should I approach this problem?
#pragma once
namespace FSBSGui2
{
/// <summary>
/// Summary for PlotDisplayWindow
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
/// </summary>
public __gc class PlotDisplayWindow : public System::Windows::Forms::Form
{
public:
PlotDisplayWindow(System::String* filename, bool rotate)
: filenames_(new System::String*[1])
, images_(new System::Drawing::Bitmap*[1])
, sleep_time_ms(1000)
, cycle(false)
, image_number(0)
{
using System::Drawing::RotateFlipType;
using System::Windows::Forms::PictureBoxSizeMode;
InitializeComponent();
if (images_[0] != 0) {
images_[0]->Dispose();
}
filenames_[0] = filename;
images_[0] = new System::Drawing::Bitmap(filenames_[0]);
picturebox->SizeMode = PictureBoxSizeMode::CenterImage;
picturebox->Image = __try_cast<System::Drawing::Image*>(images_[0]);
Text = filenames_[0];
if (rotate) {
images_[0]->RotateFlip(RotateFlipType::Rotate90FlipNone);
}
ClientSize = images_[0]->Size;
AutoScrollMinSize = images_[0]->Size;
}
PlotDisplayWindow([System::ParamArray] System::String* filenames[], bool rotate)
: filenames_(new System::String*[filenames->Length])
, images_(new System::Drawing::Bitmap*[filenames->Length])
, sleep_time_ms(1000)
, cycle(true)
, image_number(0)
{
using System::Drawing::RotateFlipType;
using System::Windows::Forms::PictureBoxSizeMode;
InitializeComponent();
if (images_[0] != 0) {
for (int i = 0; i < images_->Length; ++i) {
images_[i]->Dispose();
}
}
for (int i = 0; i < filenames_->Length; ++i) {
filenames_[i] = filenames[i];
images_[i] = new System::Drawing::Bitmap(filenames_[i]);
if (rotate) {
images_[0]->RotateFlip(RotateFlipType::Rotate90FlipNone);
}
}
picturebox->SizeMode = PictureBoxSizeMode::CenterImage;
picturebox->Image = __try_cast<System::Drawing::Image*>(images_[0]);
Text = filenames_[0];
ClientSize = images_[0]->Size;
AutoScrollMinSize = images_[0]->Size;
}
__property int get_SleepTime() { return sleep_time_ms; }
__property void set_SleepTime(int ms) { sleep_time_ms = ms; }
protected:
void Dispose(System::Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private:
System::String* filenames_[];
System::Drawing::Bitmap* images_[];
int sleep_time_ms;
bool cycle;
int image_number;
private: System::Windows::Forms::PictureBox * picturebox;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container* components;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->picturebox = new System::Windows::Forms::PictureBox();
this->SuspendLayout();
//
// picturebox
//
this->picturebox->Dock = System::Windows::Forms::DockStyle::Fill;
this->picturebox->Location = System::Drawing::Point(0, 0);
this->picturebox->Name = S"picturebox";
this->picturebox->Size = System::Drawing::Size(292, 273);
this->picturebox->TabIndex = 0;
this->picturebox->TabStop = false;
//
// PlotDisplayWindow
//
this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
this->AutoScroll = true;
this->ClientSize = System::Drawing::Size(292, 273);
this->Controls->Add(this->picturebox);
this->Name = S"PlotDisplayWindow";
this->ShowInTaskbar = false;
this->Text = S"PlotDisplayWindow";
this->Activated += new System::EventHandler(this, PlotDisplayWindow_Activated);
this->Paint += new System::Windows::Forms::PaintEventHandler(this, PlotDisplayWindow_Paint);
this->Deactivate += new System::EventHandler(this, PlotDisplayWindow_Deactivate);
this->ResumeLayout(false);
}
private:
System::Void PlotDisplayWindow_Paint(System::Object* /*sender*/, System::Windows::Forms::PaintEventArgs* e)
{
using System::Drawing::Graphics;
using System::Threading::Thread;
Graphics* g = e->Graphics;
if (filenames_->Length > 1) {
while (cycle) {
picturebox->Image = __try_cast<System::Drawing::Image*>(images_[image_number]);
Text = filenames_[image_number];
g->DrawImage(images_[image_number], AutoScrollPosition.X, AutoScrollPosition.Y, images_[image_number]->Width, images_[image_number]->Height);
System::Windows::Forms::Application::DoEvents();
Thread::Sleep(sleep_time_ms);
++image_number;
if (image_number == filenames_->Length) {
image_number = 0;
}
}
}
else {
g->DrawImage(images_[0], AutoScrollPosition.X, AutoScrollPosition.Y, images_[0]->Width, images_[0]->Height);
}
}
private:
System::Void PlotDisplayWindow_Activated(System::Object* sender, System::EventArgs* e)
{
if (filenames_->Length > 1) {
cycle = true;
}
}
private:
System::Void PlotDisplayWindow_Deactivate(System::Object* sender, System::EventArgs* e)
{
if (filenames_->Length > 1) {
cycle = false;
image_number = 0;
}
}
};
}
--
Marcus Kwok
Replace 'invalid' with 'net' to reply