Managed C++ and Windows Forms - Image Viewer






4.86/5 (18 votes)
Demonstrates adding menus, showing open-dialog boxes, showing images, scrolling.
Introduction
This is a sort of continuation of my introductory article on using Windows Forms from Managed C++ programs. In this article I'll show how you can add a menu to your form and how you can add menu handlers. I'll also show how you can show a file-open dialog box and we'll use that to select an image file [a jpeg in this case]. Then we'll draw it on the form and I'll show how you can get your form to scroll with just two lines of code.
The full source-listing is given below. To build the program, you must first use App Wizard to generate a generic Managed C++ application for you. Then replace the contents of your main .cpp file with the program I have listed down below. The screenshot below depicts what you are supposed to get once you've run the program and have opened a .jpg file.
Screenshot
Adding a menu
We make use of the MainMenu
class for creating our menu. This class is
derived from the more generic Menu
class. We use the property called MenuItems
which returns a pointer to a Menu.MenuItemCollection
object.
Creating our menu is very easy.
MainMenu *mmenu=new MainMenu();
Adding a top-level menu item is also pretty easy. We use the property
MenuItems
and call the Add function of the returned Menu.MenuItemCollection
object to add our item.
MenuItem *item = mmenu->MenuItems->Add("File");
Adding sub-items is also a piece of cake. We have the MenuItem
pointer for
the major item we just added. We use it's MenuItems property and add our
sub-menu item. We use an overload of Add() that takes the address of the event
handler as the second parameter. Thus we are instructing the CLR or whatever to
call our event handler every time a click is made on this sub-menu-item.
item->MenuItems->Add("Open...",new EventHandler(this,&NForm::OnOpen));
Likewise we add more menu items, sub-items, sub-items of sub-items, whatever... and finally we set our Form's Menu to this menu we just created.
this->Menu = mmenu;
Selecting an image file using a file-open dialog
We use the OpenFileDialog
class to show the file-open Common dialog box.
OpenFileDialog *opfdlg=new OpenFileDialog ();
We can use the Filter property to set our file type filter. In our case we only want .jpg files.
opfdlg->Filter="JPEG files (*.jpg;*.jpeg)|*.jpg;*.jpeg";
We show our file-open dialog box using
opfdlg->ShowDialog()
We can check ShowDialog
's
return value to see what the user clicked. If the return value is
DialogResult::OK
then we know that the user clicked on the OK button.
Showing an image
The Bitmap class encapsulates a GDI+ bitmap. Here we use it to hold our .jpg file.
String *s=opfdlg->FileName;
m_bitmap=new Bitmap(s);
If the image is too big for our form we'll need to have scrolling ability. We
set the form's AutoScroll
property to true.
We then use the AutoScrollMinSize
property to set the size of the screen allocated to the automatic scroll
bars. Just two lines of code and we have scrolling up and ready.
this->AutoScroll=true;
this->AutoScrollMinSize=m_bitmap->Size;
Now we call Invalidate
which invalidates the form and forces a
re-paint. Thus the OnPaint
handler gets called which we have overridden.
Invalidate();
Now take a look at our OnPaint
handler.
Graphics *g=e->Graphics;
First we get a pointer to the Graphics object associated with our form's
device context. The Graphics class encapsulates a GDI+ drawing surface. Once we
have the Graphics object pointer we can call DrawImage
to paint our .jpg on
the form.
g->DrawImage(m_bitmap,this->AutoScrollPosition.X,
this->AutoScrollPosition.Y,
m_bitmap->Width,m_bitmap->Height);
Full Program Listing
#include "stdafx.h"
#using <mscorlib.dll>
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::ComponentModel;
using namespace System::Drawing;
using namespace System::Windows::Forms;
__gc class NForm : public Form
{
public:
NForm();
protected:
void OnPaint(PaintEventArgs *e);
private:
//event handlers for menu item clicks
void OnExit (Object* sender, EventArgs *e);
void OnAbout (Object* sender, EventArgs *e);
void OnOpen (Object* sender, EventArgs *e);
//our member variable for the image
Bitmap *m_bitmap;
};
int __stdcall WinMain()
{
Application::Run(new NForm());
return 0;
}
NForm::NForm()
{
//set form title
Text = "More stuff with Windows Forms";
//create our menu
MainMenu *mmenu=new MainMenu();
//add File as a major item
MenuItem *item = mmenu->MenuItems->Add("File");
//Now add the sub-items and set their event handlers
item->MenuItems->Add("Open...",new EventHandler(this,&NForm::OnOpen));
item->MenuItems->Add("Exit",new EventHandler(this,&NForm::OnExit));
//Add another major item and it's sub-item
item = mmenu->MenuItems->Add("Help");
item->MenuItems->Add("About...",new EventHandler(this,&NForm::OnAbout));
//set the forms menu to the menu we just created
this->Menu=mmenu;
}
void NForm::OnExit(Object *sender, EventArgs *e)
{
//exit
this->Close();
}
void NForm::OnAbout(Object *sender, EventArgs *e)
{
//show an about box
MessageBox::Show("Well, this is the about box.","About this prog");
}
void NForm::OnOpen(Object *sender, EventArgs *e)
{
//we use OpenFileDialog to show a file-open dialog box
OpenFileDialog *opfdlg=new OpenFileDialog ();
//we only want jpg files
opfdlg->Filter="JPEG files (*.jpg;*.jpeg)|*.jpg;*.jpeg";
//if user has clicked on the OK button
if(opfdlg->ShowDialog()==DialogResult::OK)
{
//we get the selected jpg and assign it to our Bitmap member
String *s=opfdlg->FileName;
m_bitmap=new Bitmap(s);
//we need to scroll if the image is too big
this->AutoScroll=true;
this->AutoScrollMinSize=m_bitmap->Size;
//we do this to force a re-paint
Invalidate();
}
}
void NForm::OnPaint(PaintEventArgs *e)
{
if(m_bitmap)//chk and see if it is valid
{
//get the Graphics object associated with our form's device context
Graphics *g=e->Graphics;
//use the DrawImage function to show the image
g->DrawImage(m_bitmap,this->AutoScrollPosition.X,
this->AutoScrollPosition.Y,
m_bitmap->Width,m_bitmap->Height);
}
}