Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
Stingray Foundation Library User's Guide

10.3 Device Contexts

The Device Context (DC) is the main abstraction used in GDI programming. The use of a Device Context allows the programmer to write output code that is device-independent. The same calls can be used to send output to the display and the printer, the specific details of each device are taken care of by a device driver with no intervention from the programmer.

The class that encapsulates a DC in the SFL Graphics package is CGraphicsContext. This class provides an inline wrapper method for every API function in the Win32 GDI. It also has methods for attaching and detaching a plain DC handle to a CGraphicsContext.

To use the CGraphicsContext class, you first have to provide a DC handle obtained somehow, as shown in Example 90. After that, you can call all the GDI functions you want.

Example 90: Using the CGraphicsContext class

10.3.1 Device Context Creation and Destruction

Noticeably absent from the CGraphicsContext public interface are methods for creation of a device context. There is a ReleaseHandle() method, but its implementation is a no-op.

The reason for this is that there is no single way to create and release device contexts in the Win32 API. The GDI API distinguishes multiple types of device contexts; each one of them has a different creation process, accompanied by the corresponding destruction process.

SFL provides several specializations of CGraphicsContext, each one corresponding to one of the DC types distinguished by the GDI. These are:

Each one of these classes publishes a Create() method that creates and initializes a new DC of the type corresponding to that class. The set of parameters taken by this method varies from class to class, since different types of DCs require a different set of initialization data.

SFL's plain CGraphicsContext class does not follow an ownership scheme like the GDI objects. An instance of CGraphicsContext never owns the DC handle it contains; therefore it never destroys it when the object instance gets destroyed.

An instance of any specialized Graphics Context class always owns the DC handles that it contains. This is because it was that instance which originally created the contained handle; and, therefore, it is the only one who has the knowledge of how to deallocate it.

As shown in Example 91, let's consider a handler for the WM_PAINT message:

Example 91: A handler for the WM_PAINT message

The code above paints a rectangle on the upper left corner of the window. Notice that no explicit destruction call is necessary; the device context is released appropriately when the dcPaint variable goes out of scope.

Below is Example 92, in which a Client DC is created for a window, and a compatible Memory DC is created to display a bitmap on the painting area of that window.

Example 92: Creating a Client DC and a Memory DC

10.3.2 MFC Compatibility

It is very likely that you already have some complex painting code in some MFC applications, and you would like to be able to migrate that code to your new SFL-based applications with the least amount of work possible.

In order to maintain source code level compatibility with legacy MFC code, SFL's Graphics package has a compatibility layer that enables you to do precisely that.

If you are not using MFC in conjunction with SFL's Graphics package (concretely, if the preprocessor flag _SFL_MFC_SUPPORT is not defined), the MFC names for GDI objects (i.e. CPen, CBrush, CDC, etc.) are defined as synonyms of the native SFL names described in the previous sections.

When you are using MFC in conjunction with SFL, the MFC names belong to MFC. If you wish to use the SFL classes, you will have to address them by their native names.

Most of the method names and signatures in MFC have been respected. However, there are some aspects where the behavior differs in both libraries. For example, calls to CDC::FromHandle() will not compile in SFL. SFL does not manage a global map of temporary objects like MFC does, therefore it is not capable of returning an instance that you have created elsewhere in the program. You have to keep track of your own objects in SFL, and manage temporary objects accordingly. Remember, however, that the plain CGraphicsContext class can be attached to any DC handle with no harm, since it does not release the handle when destroyed; this technique can be a substitute for the FromHandle() function.



Previous fileTop of DocumentContentsNo linkNext file

Copyright © Rogue Wave Software, Inc. All Rights Reserved.

The Rogue Wave name and logo, and Stingray, are registered trademarks of Rogue Wave Software. All other trademarks are the property of their respective owners.
Provide feedback to Rogue Wave about its documentation.