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:
void OnExit (Object* sender, EventArgs *e);
void OnAbout (Object* sender, EventArgs *e);
void OnOpen (Object* sender, EventArgs *e);
Bitmap *m_bitmap;
};
int __stdcall WinMain()
{
Application::Run(new NForm());
return 0;
}
NForm::NForm()
{
Text = "More stuff with Windows Forms";
MainMenu *mmenu=new MainMenu();
MenuItem *item = mmenu->MenuItems->Add("File");
item->MenuItems->Add("Open...",new EventHandler(this,&NForm::OnOpen));
item->MenuItems->Add("Exit",new EventHandler(this,&NForm::OnExit));
item = mmenu->MenuItems->Add("Help");
item->MenuItems->Add("About...",new EventHandler(this,&NForm::OnAbout));
this->Menu=mmenu;
}
void NForm::OnExit(Object *sender, EventArgs *e)
{
this->Close();
}
void NForm::OnAbout(Object *sender, EventArgs *e)
{
MessageBox::Show("Well, this is the about box.","About this prog");
}
void NForm::OnOpen(Object *sender, EventArgs *e)
{
OpenFileDialog *opfdlg=new OpenFileDialog ();
opfdlg->Filter="JPEG files (*.jpg;*.jpeg)|*.jpg;*.jpeg";
if(opfdlg->ShowDialog()==DialogResult::OK)
{
String *s=opfdlg->FileName;
m_bitmap=new Bitmap(s);
this->AutoScroll=true;
this->AutoScrollMinSize=m_bitmap->Size;
Invalidate();
}
}
void NForm::OnPaint(PaintEventArgs *e)
{
if(m_bitmap)
{
Graphics *g=e->Graphics;
g->DrawImage(m_bitmap,this->AutoScrollPosition.X,
this->AutoScrollPosition.Y,
m_bitmap->Width,m_bitmap->Height);
}
}