|
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.
|
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.
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 |
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.
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 additional manipulation
techniques that can be 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 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.
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 Function CreateGraphics As Graphics
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:
Imports System.Drawing
Imports System.Windows.Forms
Module Exercise
Public Class Starter
Inherits Form
Friend WithEvents btnPaint As Button
Dim components As System.ComponentModel.Container
Public Sub New()
InitializeComponent()
End Sub
Public Sub InitializeComponent()
btnPaint = New Button
btnPaint.Location = New Point(12, 12)
btnPaint.Text = "Validate"
Controls.Add(btnPaint)
End Sub
Private Sub PaintClicked(ByVal sender As Object, _
ByVal e As EventArgs) _
Handles btnPaint.Click
Dim graph As Graphics = CreateGraphics()
End Sub
End Class
Function Main() As Integer
Dim frmStart As Starter = New Starter
Application.Run(frmStart)
Return 0
End Function
End Module
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 Shared Function FromHwnd(hwnd As IntPtr) As Graphics
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:
Private Sub PaintClicked(ByVal sender As Object, _
ByVal e As EventArgs) _
Handles btnPaint.Click
Dim graph As Graphics = Graphics.FromHwnd(Handle)
End Sub
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:
Imports System.Drawing
Imports System.Windows.Forms
Module Exercise
Public Class Starter
Inherits Form
Dim components As System.ComponentModel.Container
Public Sub New()
InitializeComponent()
End Sub
Public Sub InitializeComponent()
End Sub
Private Sub FormPaint(ByVal sender As Object, _
ByVal e As PaintEventArgs) _
Handles MyBase.Paint
e.Graphics()...
End Sub
End Class
Function Main() As Integer
Dim frmStart As Starter = New Starter
Application.Run(frmStart)
Return 0
End Function
End Module
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.
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.
An icon is used to display graphics on window objects.
While a picture can have any dimension, 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:
To create an icon, 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, on the main menu, you can click Project ->
Add New Item... In the Templates list, you can click Icon, give it a name,
and click Add. You would then receive a platform to design an icon.
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: Introducing GDI+ Resources
|
|
- Start Microsoft Visual Basic and create a new Windows Application
named Resources1
- On the main menu, click Project -> Add New Item...
- In the Templates list, click Icon File
- Set the name to diamond and click Add
- On the main menu, click File -> Save diamond.ico As...
- Locate and display the bin sub-folder of your project
- Double-click Debug to select that folder
- Click Save
- If the Colors window is not displaying, on the main menu, click
Image -> Show Colors Window.
On the Colors window, click the small green monitor
- On the Image Editor toolbar, click the Erase Tool
and
wipe the whole drawing area
- On the Image Editor toolbar, click the Line button
- In the Colors Palette, click the blue color
- 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
- Click the next small box on the right side of the top blue box then
drag left and down at 45˚ for 7 boxes:
- Using the tools of Image Editor toolbar, complete the design as
follows:
- To design the 16x16 pixel version of the icon, right-click a white
area in the drawing section and click New Image Type
- In the New Icon Image Type dialog box, click 16x16, 16 Colors if
necessary and click OK
- Design the icon as follows:

- Save the file
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 a variable of type Icon
using one of the class' constructors. If the icon is stored in a file, the
simplest constructor to use has the following syntax:
Public Sub New(fileName As String)
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 Sub New(original As Icon, size As Size)
Public Sub New(original As Icon, width As Integer, height As Integer)
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 Sub DrawIcon(icon As Icon, targetRect As Rectangle)
Public Sub DrawIcon(icon As Icon, x As Integer, y As Integer)
The first version allows you to specify the location and
dimensions of the icon. Here is an example of calling it:
Imports System.Drawing
Imports System.Windows.Forms
Module Exercise
Public Class Starter
Inherits Form
Dim components As System.ComponentModel.Container
Public Sub New()
InitializeComponent()
End Sub
Public Sub InitializeComponent()
End Sub
Private Sub FormPaint(ByVal sender As Object, _
ByVal e As PaintEventArgs) _
Handles MyBase.Paint
Dim ico As System.Drawing.Icon = New Icon("sample.ico")
Dim graph As Graphics = CreateGraphics()
graph.DrawIcon(ico, New Rectangle(10, 10, 42, 42))
End Sub
End Class
Function Main() As Integer
Dim frmStart As Starter = New Starter
Application.Run(frmStart)
Return 0
End Function
End Module
The second version allows you to specify only the
location of the icon.
|
Practical Learning: Using an Icon
|
|
- Display the form and double-click the middle of its body
- To display the icon in the title bar, implement the event as
follows:
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
Dim icoMain As Icon = New Icon("diamond.ico")
Icon = icoMain
End Sub
|
- Execute the application

- Close the form and return to your programming environment
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:
Microsoft Visual Studio 2005 provides a rich collection
of cursors you can easily use in your application. You can apply them to any
control as you wish.
To support cursors, the .NET Framework provides two
classes. One of the classes used for cursors is called Cursors. This
sealed class mostly contains a list of available cursors as properties.
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.
|
Practical Learning: Introducing Cursors
|
|
- From the Common Controls section of the Toolbox, click the ListBox
control
and click the upper-left section of the form
- From the Containers section of the Toolbox, click the Panel control
and click the upper-right section of the form
- Once again, from the Common Controls section of the Toolbox, click
the TreeView control
and click the lower-left section of the form
- From the Common Controls section of the Toolbox, click the
RichTextBox control
and click the lower-right section of the form

A cursor is primarily represented in Microsoft Windows
as a (resource) file. This means that, to get a cursor, you can design one.
Fortunately, Microsoft Windows and the .NET Framework provides many cursors
ready to be used. Otherwise, you can create and design your own.
To create a cursor, you can use use Microsoft Visual
Studio. To start, on the main menu, you can click Project -> Add New Item...
In the Templates list, you can click Cursor File, give it a name, and click
Add.
A cursor is a Windows file that has the extension .cur.
|
Practical Learning: Creating a Cursor
|
|
- On the main menu, you can click Project -> Add New Item...
- In the Templates list, click Cursor File
- Change the Filename to push and click Add
- On the main menu, click File -> Save push.cur As...
- Locate and display the bin sub-folder of your project
- Double-click Debug to select that folder
- Click Save
- On the Image Editor toolbar, click the Line tool
.
In the Colors window, make sure the black color is selected
- Draw a vertical line from the pixel on the 6th column and 2nd row
from top
- 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
- Draw a horizontal line from the lower border of the dialog line to
half-left
- Draw a diagonal line from the lower border of the vertical line to
the left border of the horizontal line:
- Draw another diagonal line from the top corner of the current shape
to the intersection of horizontal and left diagonal line:
- On the Image Editor toolbar, click Fill
- In the Colors window, click the button with a pink monitor
- In the drawing area, click the right triangle.
- In the Colors window, click the white color
- On the drawing area, click in the left triangle
- Save the file
|
Characteristics of a Cursor
|
|
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:
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
Shared 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.
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 Sub New(fileName As String)
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.
|
Practical Learning: Using Cursors
|
|
- Display the form. Click the control on the upper-left section of the
form
- In the Properties window, click the arrow of the combo box of the
Cursor field and select PanNorth
- Right-click the form and click View Code
- To programmatically assign cursors, change the Load event as
follows:
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
Dim icoMain As Icon = New Icon("diamond.ico")
Icon = icoMain
Dim curPush As Cursor = New Cursor("push.cur")
Panel1.Cursor = Cursors.NoMove2D
TreeView1.Cursor = curPush
RichTextBox1.Cursor = Cursors.PanSE
End Sub
|
- Execute the application to test it
- Close the form and return to your programming environment
Besides showing the current position of the mouse,
depending on the application, at one time, the user may need to click.
Because a cursor is primarily confined to a rectangular shape, a cursor must
specify which one of its sections would lead the clicking. The area that
directs or holds the clicking on a cursor is referred to as its hot spot.
The person who designs a cursor must also specify its hot spot. This means
that the hot spots have already been specified for all the built-in cursors
of Microsoft Windows and the cursor that ship with the .NET Framework.
If you are visually creating a cursor, to specify its
hot spot, on the Image Editor toolbar, you can click the Set Hot Spot
.
Then, on the cursor, click the point that will act as the hot spot.
On an existing cursor, to know the coordinates of the
hot spot, access the value of its HotSpot property. The
Cursor.HotSpot property is of type Point.
|
Practical Learning: Creating a Hot Spot for a Cursor
|
|
- Display the cursor you were designing
- To set the position of the cursor pointer, on the Image Editor
toolbar, click the Set Hot Spot Tool
- Click the tip of the cursor at the intersection of vertical and the
the diagonal lines in the top-left section
- Save and close the cursor window
- Right-click the form and click View Code
- In the Class Name combo box, select (Form1 Events)
- In the Method Name combo box, select MouseMove
- Implement the event as follows:
Private Sub Form1_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles Me.MouseMove
Text = "Hot Spot: F(" & Cursor.HotSpot.X.ToString() & _
", " & Cursor.HotSpot.Y & ")"
End Sub
|
- In the Class Name combo box, select ListBox1
- In the Method Name combo box, select MouseMove
- Implement the event as follows:
Private Sub ListBox1_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles ListBox1.MouseMove
Text = "Hot Spot: L(" & ListBox1.Cursor.HotSpot.X.ToString() & _
", " & ListBox1.Cursor.HotSpot.Y & ")"
End Sub
|
- In the Class Name combo box, select Panel1
- In the Method Name combo box, select MouseMove
- Implement the event as follows:
Private Sub Panel1_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles Panel1.MouseMove
Text = "Hot Spot: P(" & Panel1.Cursor.HotSpot.X.ToString() & _
", " & Panel1.Cursor.HotSpot.Y & ")"
End Sub
|
- In the Class Name combo box, select TreeView1
- In the Method Name combo box, select MouseMove
- Implement the event as follows:
Private Sub TreeView1_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles TreeView1.MouseMove
Text = "Hot Spot: T(" & TreeView1.Cursor.HotSpot.X.ToString() & _
", " & TreeView1.Cursor.HotSpot.Y & ")"
End Sub
|
- In the Class Name combo box, select RichTextBox1
- In the Method Name combo box, select MouseMove
- Implement the event as follows:
Private Sub RichTextBox1_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles RichTextBox1.MouseMove
Text = "Hot Spot: R(" & RichTextBox1.Cursor.HotSpot.X.ToString() & _
", " & RichTextBox1.Cursor.HotSpot.Y & ")"
End Sub
|
- Execute the application to see the results:
- Close the form and return to your programming environment
A cursor is a picture of size 32 x 32 pixels. To know
the size of an existing cursor, you can get the value of the Size
property of the Cursor object. The Cursor.Size property is of
type Size.
To specify the rectangle in which the cursor much be
confined, you can create a Rectangle object and assign it to the
Clip property of a cursor. To know the rectangle in which a cursor is
confined, get the value of its Clip property. The Cursor.Clip
property is of type Rectanble.
While the user is moving the mouse on a control, the
cursor moves also, which, by its purpose, is designed to show the current
position of the mouse. In some application, at one particular time, you may
want to know the coordinates of the mouse position. To provide you with this
information, the Cursor class is equipped with a property named Position.
The Position property is of type Point, which gives you to left (X) and the
top (Y) coordinates of the mouse. Here is an example that displays the
position of the mouse on the title bar of a form:
Private Sub Form1_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles Me.MouseMove
Text = CStr(Cursor.Position.X) & _
", " & CStr(Cursor.Position.Y)
End Sub
|
Showing or Hiding a Cursor
|
|
If at any time you want to hide a cursor, you can call
the Cursor.Hide() method. Its syntax is:
Public Shared Sub Hide
To display the cursor again, you can call the
Cursor.Show() method. Its syntax is:
Public Shared Sub Hide Show
- Create an application named Drawer
- Configure it as follows:
- The default cursor of the form is Default
- If/when the user is simply/regularly moving the mouse
on the form, the default cursor is Default
- If the user clicks the body of the form, holds down the
mouse and starts dragging, the cursor becomes Cross
|
|