Why break a trend I've set in the book? Here's "Hello, World!" again (see Listing 11-1). This time it's using GDI+ to render the "Hello World" text.
Listing 11-1: "Hello, World!" GDI+ Style
namespace HelloGDI { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; public __gc class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); } protected: void Dispose(Boolean disposing) { if (disposing && components) { components->Dispose(); } __super::Dispose(disposing); } private: System::ComponentModel::Container * components; void InitializeComponent(void) { this->ClientSize = System::Drawing::Size(300, 300); this->Name = S'Form1"; this->Text = S"Hello GDI+"; this->Paint += new System::Windows::Forms::PaintEventHandler(this, Form1_Paint); } private: System::Void Form1_Paint(System::Object * sender, System::Windows::Forms::PaintEventArgs * e) { Graphics *g = e->Graphics; g->DrawString(S"Hello World!", new Drawing::Font(S"Arial", 16), Brushes::Black, 75.0, 110.0); } }; }
Figure 11-1 shows the results of the program HelloGDI.exe.
Figure 11-1: Results of "Hello, World!" GDI+ style
As you can see, there is not much new here. The big differences are the addition of the PaintEventHandler event handler and the implementation of the Graphics class. The rest of the code is identical to that of any program you looked at in the previous two chapters.
All controls generate a Paint event when they determine that it needs to be updated. The Form class happens to also be a child of the Control class. A Paint event is triggered whenever the control is created, resized, or restored, or when another control that had overlaid it is moved, re-exposing a portion or all of the overlaid control. An exception to the last condition to triggering the Paint event is when MenuItems overlay a control. This does not create a Paint event. In truth, if you recall, this is not really an exception because a MenuItem is not a control, as it does not have the Control class as a parent. Instead, a MenuItem handles its own overlaying.
As was pointed out previously, this "Hello, World!" example differs from the previous two chapters in that it implements an event handler, PaintEventHandler, and uses a Graphics class. PaintEventHandler takes a template that has two parameters. The first parameter is the sender of the Paint event. In this case, it is the form, but it can be almost any control. The second parameter is a pointer to the PaintEventArgs class. It is from the PaintEventArgs class that you will get two important pieces of information: the Graphics class and the ClipRectangle or the area that needs to be updated on the form. You will learn about the ClipRectangle later in the chapter when you look at optimi-zation.
The Graphics class is the key to GDI+, but I delay exploration of the class until its own section a little later in the chapter. For the example, all you need to know is that the Graphics class has a member method, DrawString(), that you will use to draw the string to the display device. To get access to the Graphics class, you usually extract its pointer from the PaintEventHandler parameter:
System::Void Form1_Paint(System::Object * sender, System::Windows::Forms::PaintEventArgs * e) { Graphics *g = e->Graphics;
The final piece of this "Hello, World!" program is to actually render the "Hello World" string to the display device. The DrawString method takes a few parameters. This example shows rendering on the drawing surface, at location x equals 75 and y equals 100, in black, 16-point Arial font:
g->DrawString(S"Hello World!", new Drawing::Font(new FontFamily(S"Arial"), 16), Brushes::Black, 75.0, 110.0);
Something to note about rendering with GDI+ is that the location coordinates are based on the client area of the form or, more accurately, the control. Rendering to a location outside of the control will be clipped and won't be visible. Don't panic, you'll see how to add a scroll bar so you can scroll over and make hidden renderings visible.