Home > Articles > Programming > Windows Programming

This chapter is from the book

Drawing on the Display Screen

The various System.Drawing classes in the .NET Compact Framework exist for two reasons. The first and most important reason is for output to the display screen. The second reason, which exists to support the first reason, is to enable drawing to bitmaps, which can later be displayed on the display screen.

Taken together, the various classes in the System.Drawing namespace support all three families of graphical output: text, raster, and vector. You can draw text onto the display screen using a variety of sizes and styles of fonts. You can draw with raster functions, including functions that draw icons, functions that draw bitmaps, and functions that fill regions [10] or the entire display screen. The third family of graphical functions, vector functions, supports the drawing of lines, polygons, rectangles, and ellipses on the display screen.

Accessing a Graphics Object

For a .NET Compact Framework program to draw on the display screen, it must have an instance of the Graphics class—meaning, of course, a Graphics object. A quick visit to the online documentation in the MSDN Library shows two interesting things about the Graphics class. First, this class provides no public constructors. Second, this class cannot be inherited by other classes. Thus you might wonder how to access a Graphics object.

Close study of the .NET Compact Framework classes reveals that there are three ways to access a Graphics object. Two are for drawing on a display screen, and one is for drawing on a bitmap. Table 15.5 summarizes three methods that are needed to gain access to a Graphics object. We include a fourth method in the table, Dispose, because you need to call that method to properly dispose of a Graphics object in some circumstances.

Table 15.5. .NET Compact Framework Methods for Accessing a Graphics Object

Namespace

Class

Method

Comment

System.Drawing

Graphics

FromImage

Creates a Graphics object for drawing onto a bitmap. When done drawing, clean up the Graphics object by calling the Dispose method.

 

Graphics

Dispose

Reclaims memory used by Graphics objects.

System.Windows.Forms

Control

CreateGraphics

Creates a Graphics object for drawing in the client area of a control. As indicated in Table 15.6 (see page 1058), only three control classes support this method. When done drawing, clean up the Graphics object by calling the Dispose method.

 

Control

Paint event handler

Obtains a Graphics object to handle a Paint event. As indicated in Table 15.6, only five control classes support this event. Do not call the Dispose method when done drawing.

Table 15.6. Support for Drawing in .NET Compact Framework Control Classes

Class

Paint Event

CreateGraphics Method

Control

Yes

Yes

DataGrid

Yes

Yes

Form

Yes

Yes

Panel

Yes

No

PictureBox

Yes

No

The display screen is a shared resource. A multitasking, multithreaded operating system like Windows CE needs to share the display screen and avoid conflicts between programs. For that reason, Windows CE uses the same mechanism used by Windows on the desktop: Drawing on a display screen is allowed only in a window (i.e., in a form or a control).

To draw on the display screen, a program draws in a control. You get access to a Graphics object for the display screen, then, through controls. Not just any control class can provide this access, however—only the control classes that derive from the Control class can.

One way to get a Graphics object for the display screen involves the Paint event. The Paint event plays a very important role in the design of the Windows CE user interface, a topic we discuss later in this chapter. Access to a Graphics object is provided to a Paint event handler method as a property of its PaintEventArgs parameter. Incidentally, when you get a Paint event, you are allowed to use the Graphics object while responding to the event. You are not allowed to hold onto a reference to the Graphics object because the .NET Compact Framework needs to recycle the contents of that Graphics object for other controls to use. [11]

A second way to get a Graphics object is by calling the CreateGraphics method, a method defined in the Control class (and therefore available to classes derived from the Control class). Using the Graphics object returned by this call, your program can draw inside a control's client area. Although the method name suggests that it is creating a Graphics object, this is not what happens. Instead, like the Graphics object that arrives with the Paint event, the Graphics object that is provided by the CreateGraphics method is loaned to you from a supply created and owned by the Windows CE window manager. Therefore, you are required to return this object when you are done by calling the Graphics object's Dispose method. Failure to make this call results in a program hanging.

Calling the Dispose Method for a Graphics Object

There are two ways to get a Graphics object, but you need to call the Dispose method for only one of those ways. You must call the Dispose method for Graphics objects that are returned by the CreateGraphics method. But you do not call Dispose for Graphics objects that are provided as a parameter to the Paint event handler.

The third way to get a Graphics object is by calling the Shared FromImage method in the Graphics class. On the desktop, the Image class is a MustInherit class that serves as the base class for the Bitmap and Metafile classes. Because metafiles are not supported in the .NET Compact Framework, the FromImage method can return only a Graphics object for a bitmap. You can use the resulting Graphics object to draw onto a bitmap in the same way that the Graphics object described earlier is used to draw on a display screen. We are going to discuss drawing to bitmaps later in this chapter; for now, we explore the subject of drawing in controls.

As we discussed in Chapter 7, a main theme for .NET Compact Framework controls is that "inherited does not mean supported." Of the 28 available .NET Compact Framework control classes, only 5 support drawing. To help understand what types of drawing are supported, we start by identifying the specific controls that you can draw onto. We then cover the most important control event for drawing, the Paint event. We then discuss how non–Paint event drawing differs from Paint event handling.

Drawing in Controls

In the desktop .NET Framework, a program can draw onto any type of control (including onto forms). This feature is sometimes referred to as owner-draw support, a feature first seen in native-code programming for just a few of the Win32 API controls. The implementers of the .NET Framework for the desktop seem to think that this feature is something that every control should support. On the desktop, every control supports the owner-draw feature. In other words, you can get a Graphics object for every type of control [12] and use that object to draw inside the client area of any control. Owner-draw support is widely available because it allows programmers to inherit from existing control classes and change the behavior and appearance of those classes. This support allows the creation of custom control classes from existing control classes.

Things are different in the .NET Compact Framework, for reasons that are directly attributable to the .NET Compact Framework design goals. As we discussed in detail in Chapter 7, the .NET Compact Framework itself was built to be as small as possible and also to allow .NET Compact Framework programs to run with reasonable performance. The result is a set of controls with the following qualities:

  • .NET Compact Framework controls rely heavily on the built-in, Win32 API control classes.

  • .NET Compact Framework controls do not support every PME inherited from the base Control [13] class.

The result is that only a few .NET Compact Framework controls provide owner-draw support. In particular, five control classes support the Paint event. Only three control classes support the CreateGraphics method. Table 15.6 summarizes the support for drawing in .NET Compact Framework control classes.

As suggested by the column headings in Table 15.6, there are two types of drawing: Paint event drawing and CreateGraphics method drawing. The clearest way to describe the difference is relative to events because of the unique role played by the Paint event and its associated Paint event handler method. From this perspective, the two types of drawing are better stated as Paint event drawing and drawing for other events. All five controls in Table 15.6 support Paint event drawing. We turn our attention now to the subject of the Paint event and its role in the Windows CE user interface.

Anywhere, Anytime Control Drawing

An early definition of .NET talked about "anywhere, anytime access to information." Arbitrary boundaries are annoying. It is odd, then, that you cannot draw onto your controls anywhere at any time. But wait—maybe you can?

If you are willing to step outside of the managed-code box, you can draw on any control at any time. The .NET Compact Framework team did a great job of giving us a small-footprint set of libraries with very good performance. That is why owner-draw support is so limited—not because of any belief on the part of the .NET Compact Framework team that you should not be allowed to draw inside controls.

Native-code drawing means using GDI calls, each of which requires you to have a handle to a device context (hdc). There are two types of device contexts: those used to draw inside windows and those that can draw anywhere on a display screen. To draw in a window, you first must get the window handle (set focus to a control and then call the native GetFocus function). Call the native GetDC function to retrieve a device context handle, and call the ReleaseDC function when you are done.

A second method for accessing a device context is by using this call: hdc = CreateDC(NULL, NULL, NULL, NULL). The device context that is returned provides access to the entire display screen, not just inside windows. Among its other uses, this type of device context is useful for taking screenshots of the display screen, which can be useful for creating documentation. When done with the device context, be sure to clean up after yourself by calling the DeleteDC function.

The hdc returned by either of these functions—GetDC or CreateDC—can be used as a parameter to any GDI drawing function. When done drawing, be sure to provide your own manual garbage collection. In other words, be sure to call the ReleaseDC or DeleteDC functions.

The Paint Event

To draw in a window—that is, in a form or in a control—you handle the Paint [14] event. This event is sent by the system to notify a window that the contents of the window need to be redrawn. In the parlance of Windows programmers, a window needs to be redrawn when some portion of its client area becomes invalid. To fix an invalid window, a control draws everything that it thinks ought to be displayed in the window.

Generating a Paint Event

The purpose of the Paint event is to centralize all the drawing for a window in one place. Before we look at more of the details of how to handle the Paint event, we need to discuss the circumstances under which a Paint event gets generated. A Paint event gets generated when the contents of a window become invalid. (We use the term window to mean a form or any control derived from the Control class.) But what causes a window to become invalid? There are several causes.

When a window is first created, its contents are invalid. When a form first appears, every control on the form is invalid. A Paint event is delivered to each control (which, in some cases, is handled by the native-code control that sits behind the managed-code control).

A window can also become invalid when it gets hidden. Actually, a hidden window is not invalid; it is just hidden. But when it gets uncovered, the window also becomes invalid. At that moment, a Paint event is generated by the system so that the window can repair itself.

A window can also become invalid when it gets scrolled. Every scroll operation causes three possible changes to the contents of a window. Some portion of the contents might disappear, which occurs when something scrolls off the screen. Nothing is required for that portion. Another portion might move because it has been scrolled up (or down, left, or right). Here again, nothing is required. The system moves that portion to the correct location. The third portion is the new content that is now visible to be viewed. This third portion must be drawn in response to a Paint event.

Finally, a Paint event is triggered when something in the logic of your program recognizes that the graphical display of a window does not match the program's internal state. Perhaps a new file was opened, or the user picked an option to zoom in (or out) of a view. Maybe the network went down (or came up), or the search for something ended.

To generate a Paint event for any window, a program calls one of the various versions of the Invalidate method for any Control-derived class. This method lets you request a Paint event for a portion of a window or for the entire window and optionally allows you to request that the background be erased prior to the Paint event.

This approach to graphical window drawing is not new to the .NET Compact Framework or even to the .NET environment. All GUI systems have a Paint event—from the first Apple Macintosh and the earliest versions of desktop Windows up to the current GUI systems shipping today. A window holds some data and displays a view of that data.

In one sense, drawing is simple: A window draws on itself using the data that it holds. And what happens if the data changes? In that case, a window must declare its contents to be invalid, which causes a Paint event to be generated. A control requests a Paint event by calling the Invalidate method. Two basic problems can be observed with the Paint event:

  1. Failing to request Paint events (which causes cold windows with stale contents)

  2. Requesting Paint events too often (which causes hot window flickers that annoy users)

These are different problems, but both involve calling the Invalidate method the wrong number of times. The first problem arises from not invalidating a window enough. The second problem arises from invalidating the window too often. A happy medium is needed: invalidating a window the right number of times and at just the right times.

To draw in response to a Paint event, a program adds a Paint event handler to a control. You can add a Paint event handler to any Control-derived class. But the handler is only going to get called for the five control classes listed in Table 15.6. This is just another example of the "inherited does not mean supported" behavior of .NET Compact Framework controls.

Here is an empty Paint event handler.

Private Sub FormMain_Paint( _
ByVal sender As Object, _
ByVal e As PaintEventArgs) Handles MyBase.Paint

   Dim g As Graphics = e.Graphics
   ' ...draw...

End Sub

The second parameter to the Paint event handler is an instance of PaintEventArgs. [15] A property of this class is a Graphics object, which provides the connection that we need to draw in the form. There is more to be said about the Graphics object, but first let us look at the case of drawing for events besides the Paint event.

Non–Paint Event Drawing

A window that contains any graphical output must handle the Paint event. Often, the only drawing that a window requires is the drawing for the Paint event. This is especially true if the contents of the window are somewhat static. For example, Label controls are often used to display text that does not change. For a Label control, drawing for the Paint event is all that is required. However, windows whose contents must change quickly might need to draw in response to events other than the Paint event. A program that displays some type of animation, for example, might draw in response to a Timer event. A program that echoes user input might draw in response to keyboard or mouse events.

Figure 15.1 shows the DrawRectangles program, a sample program we presented in Chapter 6. This program draws rectangles in the program's main form, using a pair of (x,y) coordinates. One coordinate pair is collected for the MouseDown event, and a second coordinate pair is collected for the MouseUp event. As the user moves the mouse (or a stylus on a Pocket PC), the program draws a stretchable rubber rectangle as the mouse/stylus is moved from the MouseDown point to the MouseUp point. The program accumulates rectangles as the user draws them.

15fig01.gifFigure 15.1 A stretchable rubber rectangle created in the DrawRectangles program

The DrawRectangles program uses both Paint and non–Paint event drawing. In response to the Paint event, the program draws each of the accumulated rectangles. In response to the MouseMove event, the stretchable rectangle is drawn to allow the user to preview the result before committing to a specific location.

The basic template for the code used in non–Paint event drawing appears here.

Dim g As Graphics = CreateGraphics()
' ...draw...
g.Dispose()

This follows a programming pattern familiar to some as the Windows sandwich. [16] The top and bottom lines of code make up the two pieces of bread—these are always the same. The filling in between the two slices of bread consists of the drawing, which is accomplished with the drawing methods from the Graphics class.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020