Home

Introduction to GDI+

 

Device Contexts

 

Introduction to GDI

Microsoft Windows is a graphics-oriented operating system. It uses shapes, pictures, lines, colors, and various types of variations to convey the impression of physical objects. When we stare at a flat screen built in front of a monitor filled with insignificant wires, we believe that we are looking at physical buildings or real people. This is done through smart and effective representations that have made computer use nowadays become fun and useful.

To support the ability to represent pictures and other visual features, Microsoft in the beginning provided a library called the Graphical Device Interface or GDI. To face the new requirements as computer use became more and more demanding, Microsoft upgraded the GDI with GDI+. GDI+ is the graphical library used in the .NET Framework.

You use GDI by drawing shapes or displaying pictures in your application.

Human Being

Introduction to Device Contexts

To draw something, you need a platform on which to draw and one or a few tools to draw with. The most common platform on which to draw is probably a piece of paper. Besides such a platform, you may need a pen or a brush that would show the evolution of the drawing work on the platform. Since a pen can have or use only one color, depending on your goal, one pen may not be sufficient, in which case you would end up with quite a few of them.

A device context is an ensemble of the platform you draw on and the tools you need to draw with. It also includes the dimensioning of the platform, the orientation and other variations of your drawing, the colors, and various other accessories that you can use to express your imagination.

When using a computer, you certainly cannot position tools on the table or desktop to use as needed. To help with drawing on the Windows operating system, Microsoft created the Graphical Device Interface, abbreviated as GDI. It is a set of classes, functions, variables, and constants that group all or most of everything you need to draw on an application. GDI is provided as a library called Gdi.dll and is already installed on your computer.

The GDI+ Library

GDI+ is the system used to perform drawing and other related graphics operations for the Microsoft Windows family of operating systems. Its predecessor was the Graphical Device Interface (GDI), which has therefore been replaced, namely with the new operating systems such as Windows XP, Windows Server 2003, or Windows Vista. The + in GDI+ indicates that it provides a significant improvement to GDI. It adds new features that were not available in GDI and were therefore difficult to produce. GDI+ allows you to create device-independent applications without worrying about the hardware on which the application would run.

GDI+ is inherently installed in Microsoft Windows XP, Windows Server 2003, and Windows Vista. To use it on previous operating systems, it must be explicitly distributed. GDI+ provides its functionality through three fronts:

  • Vector Graphics
    This is the area that consists of drawing and manipulating geometric-based and related figures including lines, combinations of lines, round and quadrilateral shapes. These are treated as sets of points on a screen or other device. To perform these types of operations, the GDI+ system provides various classes that perform different assignments. For example, one class can be in charge of creating or preparing tools used to draw. Another class can be used to perform the actual drawing, using the provided tools
  • Imaging
    While it may appear easy to create vector graphics that are made of easily recognizable colors, advanced pictures present a challenge to display or draw them on a device. For these reasons, imaging is the area used to deal with such complex operations
  • Typography
     
    Typography consists of creating, manipulating or making fonts available to an application

Basic Tools of GDI+

 

Introduction

To support GDI+ graphics and their features, the .NET Framework provides the System::Drawing namespace that is is created in the System.Drawing.dll library. This namespace also contains classes to draw or define a font in an application. To enhance the aspects of a drawing, the .NET Framework provides additional classes in the System::Drawing::Drawing2D namespace. This namespace also is defined in the System.Drawing.dll assembly. To support addition manipulation techniques that can applied to a picture, the .NET Framework provides some other classes in the System::Drawing::Imaging namespace, which is also part of the System.Drawing.dll library.

The Graphics Platform

To draw in GDI, you have to obtain a handle to the device context. This is done by declaring a variable or a pointer to HDC then calling a function such as BeginPaint() to initialize the device context. You also have to create the tools needed to draw. For example, you have to create a pen and/or a brush. Once the tools are ready, you have to select them into the device context to make them available. After drawing, it is suggested that you release the device context.

To draw in GDI+, you use an object referred to as graphic.

The Color To Fill

The color is one of the most fundamental objects that enhances the aesthetic appearance of an object. The color is a non-spatial object that is added to an object to modify some of its visual aspects. To support colors, the GDI+ library provides the Color structure. The Color structure is defined in the System::Drawing namespace.

A color is created as a combination of four 8-bit values. The first value is referred to as alpha but it is mostly used internally. The second is called red. The third is called green. The fourth is called blue:

Bits
Alpha
7 6 5 4 3 2 1 0
Red 
7 6 5 4 3 2 1 0
Green 
7 6 5 4 3 2 1 0
Blue 
7 6 5 4 3 2 1 0

Converted to decimal, each one of the red, green, and blue numbers would produce:

27 + 26 + 25 + 24 + 23 + 22 + 21 + 20 

= 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1

= 255

Therefore, each number can have a value that ranges from 0 to 255 in the decimal system. The alpha section is reserved for the operating system. The other three numbers are combined to produce a single value as follows:

Color 
23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Blue Green Red
Value

Converted to decimal, this number has a value of 255 * 255 * 255 = 16581375. This means that we can have approximately 16 million colors available. The question that comes to mind is how we use these colors, to produce what effect.

You computer monitor has a surface that resembles a series of tinny horizontal and vertical lines. The intersection of a horizontal line and a vertical line is called a pixel. This pixel holds, carries, or displays one color:

As the pixels close to each other have different colors, the effect is a wonderful distortion that creates an aesthetic picture. It is by changing the colors of pixels that you produce the effect of color variances seen on pictures and other graphics.

To make color selection easier, the Color structure is equipped with various properties that each represents a name for a color. Therefore, to use any of these colors, call the Color structure followed by the "::" operator, followed by the desired color. All the popular names of colors are recognized and they are represented in the Color structure by static properties. These include Red, Green, Blue, Black, White, Yellow, Fuchsia, Silver, Gray, Brown, and Khaki, etc, just to name a few. There are many other colors that are not necessarily popular. Here is an example:

System::Void button1_Click(System::Object ^  sender,
			   System::EventArgs ^  e)
{
    BackColor = Color::Turquoise;
}

If none of the pre-defined colors suits you, you can define your own color as a combination of red, green, and blue values. To create a color using this approach, you can declare a variable of type Color. To specify the characters of the color, the Color structure provides the FromArgb() static method overloaded in four versions as follows:

public:
    static Color FromArgb(int argb);
    static Color FromArgb(int alpha, Color baseColor);
    static Color FromArgb(int red, int green, int blue);
    static Color FromArgb(int alpha, int red, int green, int blue);

The third version, which is the most used allows you to specify three values that each ranges from 0 to 255. Here is an example:

System::Void button1_Click(System::Object ^  sender, 
			   System::EventArgs ^  e)
{
    BackColor = Color::FromArgb(26, 69, 174);
}

This would produce:

Whether a color was initialized with one of the Color pre-defined color properties or using the FromArgb() methods, if you want to retrieve the red, green, and blue values of a color, you can use the R, the G, or the B properties to extract the value of each. Each one of these properties is of a byte type. Alternatively, you can call the Color::ToArgb() method. Its syntax is:

public:
    int ToArgb();

This method returns an integer.

The Pen

The most basic tool you can use is the pen. The GDI+ library provides a pen through the Pen class. To obtain a pen, you can declare a Pen handle. The primary piece of information you must specify about a pen is its color. To do this, you can use the following constructor: 

public:
    Pen(Color color);

Here is an example:

System::Void button1_Click(System::Object ^  sender,
			   System::EventArgs ^  e)
{
    Color clrBlue = Color::Blue;
    Pen ^ penRed = gcnew Pen(clrBlue);
}

If you have already created a pen, to change its color, you can assign the desired color name or color value to the Pen::Color property.

The Pen class provides more details about a pen than that. For now, we can use a pen as simple as this one.

The Graphics Object

 

Introduction

The main object on which you will perform most drawings is called a graphic. In most cases, this object is not readily available when you need it: you must request it from the object on which you want to draw or you must create it. Both operations are highly easy.

Getting a Graphic Object

In GDI+, a graphic object is based on a class called Graphics. This class is defined in the System::Drawing namespace. Before drawing, you should obtain a graphic object. Fortunately, every Windows control, that is, every object based on the Control class automatically inherits a method called CreateGraphics(), which gives you access to the graphic part of a control. The syntax of the Control::CreateGraphics() method is:

public:
    Graphics ^ CreateGraphics();

As you can see, the CreateGraphics() method returns the Graphics object of the variable you call it from. Here is an example of getting the Graphics object of a form:

System::Void button1_Click(System::Object ^  sender,
			   System::EventArgs ^  e)
{
    Graphics ^ graph = this->CreateGraphics();
}

Another technique you can use to get the Graphics object of a control is to call the Graphics::FromHwnd() static method. Its syntax is:

public:
    static Graphics ^ FromHwnd(IntPtr hwnd);

Remember that this method is static. The argument passed to it must be a handle to the object whose Graphics object you want to access. Every Windows control has a handle called Handle. Here is an example of using it to get the Graphics part of a form:

System::Void button1_Click(System::Object ^  sender,
			   System::EventArgs ^  e)
{
    Graphics ^ graph = Graphics::FromHwnd(this->Handle);
}

If you are using the Paint event of a window, it provides a readily available Graphics object from its PaintEventArgs argument. You can access the Graphics object as follows:

System::Void Form1_Paint(System::Object ^  sender,
			 System::Windows::Forms::PaintEventArgs ^  e)
{
    e->Graphics . . .
} 

The Color Dialog Box

 

Description

To provide the selection of colors on Microsoft Windows applications, the operating system provides a common dialog box appropriate for such tasks. You can use the Color dialog box for various reasons such as letting the user set or change a color of an object or specifying the background color of a control or the color used to paint an object. When it displays, by default, the dialog box appears as follows:

The Color Dialog Box

This displays a constant list of colors to the user. If none of the available colors is appropriate for the task at hand, the user can click the Define Custom Colors >> button to expand the dialog box:

The Expanded Dialog Box

The expanded Color dialog box allows the user either to select one of the preset colors or to custom create a color by specifying its red, green, and blue values.

The user can change the color in four different areas. The top left section displays a list of 48 predefined colors. If the desired color is not in that section, the user can click and drag the mouse in the multi-colored palette. The user can also drag the right bar that displays a range based on the color of the palette; the user can scroll up and down by dragging the arrow. For more precision, the user can type the Red, Green and Blue values. Each uses an integral value that ranges from 1 to 255.

Making a Color Dialog Box Available

To provide the Color dialog box to your application, on the Toolbox, you can click the ColorDialog button and click anywhere on the form. The Color dialog box is implemented through the ColorDialog class, which is based on the CommonDialog class that is the ancestor to all Windows common dialog boxes of the .NET Framework. To display the dialog box to the user, call the CommonDialog::ShowDialog() method. Here is an example:

System::Void button1_Click(System::Object ^  sender, 
			   System::EventArgs ^  e)
{
    this->colorDialog1->ShowDialog();
}

The Characteristics of the Color Dialog Box

The most important and most obvious property of the Color dialog box is the selected color once the user has made a choice. This selected color is represented by the ColorDialog::Color property. When you are setting up a ColorDialog control for your application, if you want to specify the default color, in the Properties windows, you can click the arrow of the Color property. This would give you the option to select a color from three available tabs:

At run time, you can set the color programmatically by assigning it a valid known name of a color:

System::Void Form1_Load(System::Object ^  sender, 
			System::EventArgs ^  e)
{
    this->colorDialog1->Color = Color::Green;
}

When the user has finished using the Color dialog box and clicks OK, you can find out what color was selected by retrieving the value of the ColorDialog::Color property.

By default, the Color dialog box comes up in its regular (small) size. This allows the user to select one of the preset colors. If the desired color is not available, as mentioned already, the user can click the Define Custom Colors >> button. If you want to control the user's ability to expand the dialog box, use the Boolean AllowFullOpen property. When this property is set to True, which is its default value, the dialog box appears in its regular size but with the Define Custom Colors >> button enabled. If you want the user to be able to select only one of the preset colors and not have the ability to expand the dialog box, set the AllowFullOpen property to False. With this value, when the Color dialog box comes up, it is in its regular size but the Define Custom Colors >> button is disabled:

The Color dialog box that cannot be expanded

As mentioned already, by default, the Color dialog box displays in its regular size. You can control the regular or full size of the dialog using the Boolean FullOpen property. When its value is False, which is the default, the dialog appears regularly. If you want it to appear in its full size, set this property to True.

The Process of Drawing

 

Getting a Device Context

As mentioned above, before drawing, make sure you have a Graphics object, which depends on your approach to drawing. To actually perform the drawing, the Graphics class provides various methods adapted for different shapes. Each method used to draw something has a name that starts with Draw... Also, each method that is used to draw a known shape requires a Pen argument. Therefore, when drawing, your first decision will be based on the shape or type of figure you want to draw. Probably the second decision will consist on specifying the color of the border.

Two other pieces of information are particularly important with regards to any figure or shape you will need to draw: its location and dimensions.

The Starting Point of a Shape or Figure

To keep track of the various drawings, the object on which you draw uses a coordinate system that has its origin (0, 0) on its top-left corner. If you are drawing on a form, this origin is positioned just under the title bar to the left:

How you specify the values of the starting point of a shape or figure depends on the shape.

Icons

 

Introduction

Like a bitmap, an icon is used to display graphics on window objects. While a bitmap can have any dimension the window needs, the size of an icon is limited. This is because icons assume different roles on an application.

Icons are used to represent folders in Windows Explorer and My Computer:

Windows Explorer or My Computer
 

Creating Icons

To create an icon, once again, you can use any application that has the capability. Normally, you can use Microsoft Visual Studio 2005 to create or design an icon. To do this

  • In the Solution Explorer, you can right- click Resource Files -> Add -> Resource...
  • In the Resource View, you can right-click the name of the project -> Add -> Resource...

This would open the Add Resource dialog box. In the Add Resource dialog box, you can select Icon:

And click New.

When you start designing an icon, you would be presented with a drawing area whose dimensions are 32 x 32 pixels. This is the size of the icon that displays as Large Icon. Here is an example from the New File dialog box of Microsoft Visual Studio 2005 in the Templates list:

In some cases, you may allow the user to display smaller icons, which are 16x16 pixels:

To make this possible, you can associate a second icon to the 32x32 one. The application you use to design your icon should make it simple for you to add this second icon. To do this in Microsoft Visual Studio 2005, while the icon is displaying:

  • On the main menu, you can click Image -> New Image Type...
  • You can right-click an empty area in the icon window and click New Image Type...

When the New Icon Image Type dialog box comes up, you can click 16x16, 16 colors and click OK.

Whether you create only one or both versions of the icon, both are stored in a single file whose extension is .ico

Practical Learning Practical Learning: Creating Icons

  1. In the Solution Explorer, right-click Resource Files -> Add -> Resource...
  2. In the Add Resource dialog box, double-click Icon
  3. On the Image Editor toolbar, click the Fill Tool , and right-click the green area to make it white
  4. On the Image Editor toolbar, click the Line button 
  5. In the Colors Palette, click the blue color
  6. In the empty drawing area, count 15 small boxes from the top left to the right. In the 16th box, click and drag right and down for an angle of 45˚ for 7 boxes. Release the mouse
  7. Click the next small box on the right side of the top blue box then drag left and down at 45˚ for 7 boxes:
     
    Icon Design
  8. Using the tools of Image Editor toolbar, complete the design as follows:
     
    Icon Design
  9. In the Colors Palette, click the picture that has the small monitor Icon Background Color
  10. In the Image Editor toolbar, click the Fill tool Fill and click a white area in the drawing area
     
  11. To design the 16x16 pixel version of the icon, right-click a white area in the drawing section and click New Image Type
  12. In the New Icon Image Type dialog box, click 16x16, 16 Colors if necessary and click OK
     
    New Icon
  13. Design the icon as follows:
     
  14. In the Resource View tab, click the IDI_ICON1 node
  15. In the Properties window, change the FileName to Diamong.icon
  16. Change the ID to IDI_DIAMOND

Using an Icon

To support icons, the GDI+ library provides the Icon class, which is defined in the System::Drawing namespace. To use an icon in your application, you can first declare an Icon handle using one of the class' constructors. If the icon is stored in a file, the simplest constructor to use it has the following syntax:

public:
    Icon(String ^ filename);

With this constructor, the name of, or the path to, the icon file is passed as argument. After creating the icon, if you want to use only one size version, you can use one the following constructors to declare the variable:

public:
    Icon(Icon ^ original, Size size);
    Icon(Icon ^ original, int width, int height);

After initializing an Icon variable, if you want to get its dimensions, you can access its Width and its Height properties, or its Size property.

As mentioned already, there are various ways an icon can be used. For example, you can display it in a control by drawing it. To do this, you can call the Graphics::DrawIcon() method which is overloaded with two versions whose syntaxes are:

public:
    void DrawIcon(Icon ^ icon, Rectangle targetRect);
    void DrawIcon(Icon ^ icon, int x, int y);

The first version allows you to specify the location and dimensions of the icon. The second version allows you to specify only the location of the icon.

Practical Learning Practical Learning: Using an Icon

  1. Display the form and double-click the middle of its body
  2. To display the icon in the title bar, implement the event as follows:
     
    System::Void Form1_Load(System::Object ^  sender, System::EventArgs ^  e)
    {
        Drawing::Icon ^ icoMain = gcnew Drawing::Icon(L"Diamond.ico");
        Icon = icoMain;
    }
  3. Execute the application
     
    An icon
  4. Close the form and return to your programming environment

Cursors

 

Introduction

A cursor is a small picture that represents the position of the mouse on a Windows screen. Because Microsoft Windows is a graphic-oriented operating system, when it installs, it creates a set of standard or regularly used icons. These can be seen by opening the Control Panel window and double-clicking the Mouse icon. This opens the Mouse Properties dialog box where you can click the Pointers tab to see a list of standard cursors installed by Windows:

Mouse Properties

Microsoft Visual Studio 2005 provides a rich collections of cursors you can easily use in your application. You can apply them to any control as you wish. To do this, access the properties of the control and open the Cursor field. If those cursors are not enough, which is not unusual, you can use your own cursors..

Practical Learning Practical Learning: Introducing Cursors

  1. Start a new Windows Forms Application named Resources2
  2. Change the Text property of the form to GDI+ Resources
  3. On the Toolbox, click the ListBox control and click the upper-left section of the form
  4. Again, on the Toolbox, click the Panel control and click the upper-right section of the form
  5. Once again, on the Toolbox, click the TreeView control and click the lower-left section of the form
  6. On the Toolbox, click the RichTextBox control and click the upper-right section of the form
     

Creating Cursors

To create and design your own cursor, you can use use Microsoft Visual Studio. To do this:

  • In the Solution Explorer, you can right- click Resource Files -> Add -> Resource...
  • In the Resource View, you can right-click the name of the project -> Add -> Resource

Then, in the Add New Item dialog box, you can select Cursor File, give it a name and click Open.

A cursor is a Windows file that has the extension .cur.

Practical Learning Practical Learning: Creating a Cursor

  1. Display the Resource View window.
    To create a new cursor, in the Resource View, right-click Resources2 -> Add -> Resource...
  2. In the Add Resource dialog box, click Cursor and click New
  3. In the Resource View tab, click the new IDC_CURSOR1
  4. In the Properties window, change the Filename to Push.cur and change the ID to IDC_PUSH
  5. On the Image Editor toolbar, click the Line tool . In the Colors window, make sure the black color is selected
  6. Draw a vertical line from the pixel on the 6th column and 2nd row from top
  7. Draw a diagonal line at 45˚ from the top border of the new line to the lower-right until the line is at 5 pixels from the right border of the drawing area
     
    Cursor Design
  8. Draw a horizontal line from the lower border of the dialog line to half-left
  9. Draw a diagonal line from the lower border of the vertical line to the left border of the horizontal line:
     
    Cursor Design 2
  10. Draw another diagonal line from the top corner of the current shape to the intersection of horizontal and left diagonal line:
     
    Cursor Design 3
  11. On the Image Editor toolbar, click Fill
  12. In the Colors window, click the button with a pink monitor Monitor
  13. In the drawing area, click the right triangle.
  14. In the Colors window, click the white color
  15. On the drawing area, click in the left triangle
     
    Cursor Design 4
  16. To set the position of the cursor pointer, on the Image Editor toolbar, click the Set Hot Spot Tool
  17. Click the tip of the cursor at the intersection of vertical and the the diagonal lines in the top-left section
     
    Set Hot Spot Tool
  18. Save the icon

Using Cursors

There are two main ways you can use a cursor in your application. The easiest cursors are listed in the Cursor field of the Properties window for the control whose cursor you want to change. The available cursors are:

Cursor 1 Cursor 2 Cursor 3 Cursor 4

You can select one of these cursors in the Properties window and assign it to a control. These cursors are defined in a class called Cursors. This simple class mostly contains only a list of available cursors as properties. All these cursors are represented as static properties. Therefore, to use one of these cursors, call the name of the class, Cursors, followed by the class access operator "::", followed by the name of the cursor as it appears in the above list.

Another technique consists of using a cursor not listed in the Properties window. A cursor is based on the Cursor class. Both the Cursors and the Cursor classes are defined in the System::Windows::Forms namespace that is part of the System.Windows.Forms.dll library.

The Cursor class provides four constructors. One of them allows you to specify the path where the cursor is located. This constructor has the following syntax:

public:
    Cursor(String ^ filename);

The argument passed to this constructor is the name or the location of the cursor as a file. After calling this constructor to initialize a Cursor variable, the cursor is ready. You can then use it as you see fit. For example, you can assign it to the Cursor property of a control.

When the cursor of a control has been changed, the control fires a CursorChanged event. This event is of type EventArgs.

If at any time you want to hide a cursor, you can call the Cursor::Hide() method. Its syntax is:

public:
    static void Hide();

To display the cursor again, you can call the Cursor::Show() method. Its syntax is:

public:
    static void Show();

Practical Learning Practical Learning: Using Cursors

  1. Display the form. Click the control on the upper-left section of the form
  2. In the Properties window, click the arrow of the combo box of the Cursor field and select PanNorth
  3. Double-click an unoccupied area of the form to access its Load event
  4. To programmatically assign cursors, implement the event as follows:
     
    System::Void Form1_Load(System::Object^  sender, 
    			System::EventArgs^  e)
    {
        System::Windows::Forms::Cursor ^ curPush = 
    		gcnew System::Windows::Forms::Cursor(L"Push.cur");
        this->panel1->Cursor = Cursors::NoMove2D;
        this->treeView1->Cursor = curPush;
        this->richTextBox1->Cursor = Cursors::PanSE;
    }
  5. Execute the application to test it
     
  6. Close the form and return to your programming environment
 
 

Previous Copyright 2007, yevol.com Next