To go over a little background:
There are two times when you need to "paint" your form.
One is when the window manager tells you that you must. It will do this
whenever it detects that there is a change to that portion of the desktop
enclosed by your form. For example when your form is first created the
window manager realizes that what was "under" your form before should now
be replaced by something of your application's choosing. Or as another
example, when the user moves a window that uncovers your form the window
manager realizes that there is an update that needs to be made to the
form.
At the level of the API, the window manager sends a WM_PAINT message to a
window. At the managed code level, the window manager calls the OnPaint()
method of the form. It is there where you need to implement the bulk your
paint algorithm.
The other time to paint is when your application knows that its form needs
a new paint job. As Tomas has already pointed out, you can do that at any
time by calling CreateGraphics().
To simplify an application's code, sometimes only the first case is
actually implemented. To deal with application / user requested paints an
application can simply call the Invlidate() method of the Form class. This
causes the window manager to dispatch a WM_PAINT message natively or the
OnPaint() method on the .Net platform.
Of course, in your case, your application must keep track of all the
lines, ellipses etc that it needs to paint. The window manager can't
possibly do that.
In case you are new to this stuff, I've pasted the code to a managed
application that draws some text, a line and an ellipse. I'm not sure
posting it is wise because it is a little off the beaten path.
You see I am going to listen to Charles Petzold (
http://www.charlespetzold.com/ ) speak this week on the topic of whether
using the wizards in Visual Studio rots the mind.
I've thought about
that in the past have been thinking about it more in advance of his talk.
So my little sample does WinForms in Managed C++ _without_ using _any_ of
the wizards in VS.
To do that, I choose to create an _empty_ WIN32 APPLICATION and then I set
the "Use Managed Extensions" option manually.
Regards,
Will
// Class implementation Po2.cpp
#include "po2.h"
void HelloWorld::Main()
{
Application::Run( new HelloWorld() );
}
HelloWorld::HelloWorld()
{
Text = "Hello, world!";
BackColor = Color::White;
penRed = new Pen(Color::Red);
penBlue = new Pen(Color::Blue);
}
void HelloWorld::OnPaint(PaintEventArgs *pea)
{
Graphics __gc *grfx = pea->Graphics;
Rectangle rc;
grfx->DrawString("Hello, World!", Font, Brushes::Black, 0, 0);
rc = get_ClientRectangle();
rc.Width -= 1;
rc.Height -= 1;
grfx->DrawLine(penRed, 0, 0, rc.Width, rc.Height);
grfx->DrawEllipse(penBlue, rc);
}
// Hack avoids including <windows.h>
int __stdcall WinMain(int, int, int, int)
{
HelloWorld::Main();
return 0;
}
// Class declaration po2.h
#using <System.dll>
#using <mscorlib.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System:
rawing;
using namespace System::Windows::Forms;
using namespace System::ComponentModel;
public __gc class HelloWorld : public Form
{
private:
Pen __gc *penRed;
Pen __gc *penBlue;
public:
HelloWorld();
static void Main();
protected:
void OnPaint(PaintEventArgs __gc *);
};