Understanding Graphics Device Interface (GDI) and Private Device Contexts, Study notes of Computer Engineering and Programming

An in-depth look into graphics device interface (gdi) and its usage of device contexts, with a focus on private device contexts. Gdi acts as a buffer between applications and output devices, presenting a device-independent view to applications while interacting in a device-dependent format with devices. Gdi object creation, caching, and deletion, as well as the differences between device context types, such as common, private, and class device contexts. Private device contexts are recommended for windows that require many changes to the device context attributes and for performance considerations. The document also discusses the importance of releasing device contexts when they are no longer needed.

Typology: Study notes

2011/2012

Uploaded on 11/06/2012

ahsen
ahsen 🇵🇰

4.6

(88)

84 documents

1 / 25

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Chapter 13
13.1 GDI (GRAPHICS DEVICE INTERFACE) 2
13.2 GDI OBJECTS AND ITS API’S 3
GDI OBJECTS CREATION 3
WHAT HAPPENS DURING SELECTION? 4
MEMORY USAGE 6
CREATING VS. RECREATING 7
STOCK OBJECTS 7
ERROR HANDLING 8
DELETION OF GDI OBJECTS 9
UNREALIZEOBJECT 10
SPECIAL CASES 11
13.3 GDI FROM THE DRIVERS PERSPECTIVE (FOR ADVANCED USERS) 12
13.4 DEVICE CONTEXT (DC) 13
DISPLAY DEVICE CONTEXT CACHE 13
DISPLAY DEVICE CONTEXT DEFAULTS 14
COMMON DISPLAY DEVICE CONTEXT 15
PRIVATE DISPLAY DEVICE CONTEXT 16
CLASS DISPLAY DEVICE CONTEXT 17
WINDOW DISPLAY DEVICE CONTEXT 18
PARENT DISPLAY DEVICE CONTEXT 18
WINDOW UPDATE LOCK 19
ACCUMULATED BOUNDING RECTANGLE 19
13.5 STEPS INVOLVED IN OUTPUT OF A TEXT STRING IN THE CLIENT AREA OF THE
APPLICATION 20
PRINTING TEXT STRING (EXAMPLE) 20
13.6 GETDC 20
HWND 20
[IN] HANDLE TO THE WINDOW WHOSE DC IS TO BE RETRIEVED. IF THIS VALUE IS NULL,
GETDC RETRIEVES THE DC FOR THE ENTIRE SCREEN. 20
13.7 TEXTOUT 21
13.8 RELEASEDC 22
13.9 WM_PAINT 22
13.10 BEGINPAINT 23
13.11 ENDPAINT 23
13.12 WM_SIZING 24
13.13 CS_HREDRAW AND CS_VREDRAW 24
SUMMARY 24
EXERCISES 24
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19

Partial preview of the text

Download Understanding Graphics Device Interface (GDI) and Private Device Contexts and more Study notes Computer Engineering and Programming in PDF only on Docsity!

13.5 S TEPS INVOLVED IN OUTPUT OF A TEXT STRING IN THE CLIENT AREA OF THE

  • Chapter
  • 13.1 GDI (G RAPHICS DEVICE I NTERFACE )
  • 13.2 GDI OBJECTS AND ITS API’ S
  • GDI OBJECTS CREATION
  • WHAT HAPPENS DURING SELECTION?
  • MEMORY USAGE
  • CREATING VS. RECREATING
  • STOCK OBJECTS
  • ERROR HANDLING
  • DELETION OF GDI OBJECTS
  • UNREALIZEOBJECT
  • SPECIAL CASES
  • 13.3 GDI FROM THE DRIVER’ S P ERSPECTIVE ( FOR ADVANCED USERS )
  • 13.4 DEVICE CONTEXT (DC)
  • DISPLAY DEVICE CONTEXT CACHE
  • DISPLAY DEVICE CONTEXT DEFAULTS
  • COMMON DISPLAY DEVICE CONTEXT
  • P RIVATE D ISPLAY DEVICE CONTEXT
  • CLASS DISPLAY DEVICE CONTEXT
  • WINDOW DISPLAY DEVICE CONTEXT
  • P ARENT DISPLAY DEVICE CONTEXT
  • WINDOW UPDATE LOCK
  • ACCUMULATED BOUNDING RECTANGLE
  • APPLICATION
  • PRINTING TEXT STRING (EXAMPLE)
  • 13.6 GETDC
  • H WND
  • GETDC RETRIEVES THE DC FOR THE ENTIRE SCREEN. [ IN] HANDLE TO THE WINDOW WHOSE DC IS TO BE RETRIEVED. IF THIS VALUE IS NULL,
  • 13.7 TEXTOUT
  • 13.8 RELEASE DC
  • 13.9 WM_PAINT
  • 13.10 BEGINP AINT
  • 13.11 ENDP AINT
  • 13.12 WM_SIZING
  • 13.13 CS_HREDRAW AND CS_VREDRAW
  • S UMMARY
  • EXERCISES

13.1 GDI (Graphics Device Interface)

In previous lectures we have got some understanding about GDI. In this lecture, we will take a detail look on Graphics Device Interface and its Device independency.

The graphical component of the Microsoft® Windows™ graphical environment is the graphics device interface (GDI). It communicates between the application and the device driver, which performs the hardware-specific functions that generate output. By acting as a buffer between applications and output devices, GDI presents a device-independent view of the world for the application while interacting in a device-dependent format with the device.

In the GDI environment there are two working spaces—the logical and the physical. Logical space is inhabited by applications; it is the "ideal" world in which all colors are available, all fonts scale, and output resolution is phenomenal. Physical space, on the other hand, is the real world of devices, with limited color, strange output formats, and differing drawing capabilities. In Windows, an application does not need to understand the quirkiness of a new device. GDI code works on the new device if the device has a device driver.

GDI concepts mapped between the logical and the physical are objects (pens, brushes, fonts, palettes, and bitmaps), output primitives, and coordinates.

Objects are converted from logical objects to physical objects using the realization process. For example, an application creates a logical pen by calling CreatePen with the appropriate parameters. When the logical pen object is selected into a device context (DC) using SelectObject , GDI realizes the pen into a physical pen object that is used to communicate with the device. GDI passes the logical object to the device, and the device creates a device-specific object containing device-specific information. During realization, requested (logical) color is mapped to available colors, fonts are matched to the best available fonts, and patterns are prepared for output. Font selection is more complex than other realizations, and GDI, not the driver, performs most of the realization work. Similarly, palette realization (done at RealizePalette time as opposed to SelectPalette time) is done entirely within GDI. Bitmaps are an exception to the object realization process; although they have the device-independent bitmap (DIB) logical form, bitmap objects are always device specific and are never actually realized.

Output primitives are similarly passed as "logical" requests (to stretch the definition) to the device driver, which draws the primitive to the best of its ability and resolution. If the driver cannot handle a certain primitive—for example, it cannot draw an ellipse—GDI simulates the operation. For an Ellipse call, GDI calculates a polygon that represents a digitized ellipse. The resulting polygon can then be simulated as a polyline and a series of scanline fills if the device cannot draw polygons itself. The application, though, does not care what system component does the actual work; the primitive gets drawn.

Palette objects are created with the CreatePalette function. Unlike pens, brushes, fonts, and bitmaps, the logical palette created with this function can be altered later with the SetPaletteEntries function or, when appropriate, with the AnimatePalette function.

Regions can be created with the CreateRectRgn, CreateRectRgnIndirect, CreateRoundRectRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, and CreatePolyPolygonRgn functions. Internally, the region object that each function creates is composed of a union of rectangles with no vertical overlap. Regions created based on nonrectangular primitives simulate the complex shape with a series of rectangles, roughly corresponding to the scanlines that would be used to paint the primitive. As a result, an elliptical region is stored as many short rectangles (a bit fewer than the height of the ellipse), which leads to more cumbersome and slower region calculations and clipping. Coordinates used for creating regions are not specified in logical units as they are for other objects. The graphics device interface (GDI) uses them without transformation. GDI translates coordinates for clip regions to be relative to the upper-left corner of a window when applicable. Region objects can be altered with the CombineRgn and OffsetRgn functions.

What Happens During Selection

Selecting a logical object into a DC involves converting the logical object into a physical object that the device driver uses for output. This process is called realization. The principle is the same for all objects, but the actual operation is different for each object type. When an application changes the logical device mapping of a DC (by changing the mapping mode or the window or viewport definition), the system re-realizes the currently selected pen and font before they are used the next time. Changing the DCs coordinate mapping scheme alters the physical interpretation of the logical pens width and the logical fonts height and width by essentially reselecting the two objects.

Pens are the simplest of objects. An application can use three attributes to define a logical pen—width, style, and color. Of these, the width and the color are converted from logical values to physical values. The width is converted based on the current mapping mode (a width of 0 results in a pen with a one-pixel width regardless of mapping mode), and the color is mapped to the closest color the device can represent. The physical color is a solid color (that is, it has no dithering). If the pen style is set to PS_INSIDEFRAME and the physical width is not 1, however, the pen color can be dithered. The pen style is recorded in the physical object, but the information is not relevant until the pen is actually used for drawing.

Logical brushes have several components that must be realized to make a physical brush. If the brush is solid, a physical representation must be calculated by the device driver; it can be a dithered color (represented as a bitmap with multiple colors that when viewed by the human eye approximates a solid color that cannot be shown as a single pixel on the device), or it can be a solid color. Pattern brush realization involves copying the bitmap that defines the pattern and, for color patterns, ensuring that the color format is compatible with the device. Usually, the device driver also builds a monochrome version of a color pattern for use with monochrome bitmaps. With device-independent bitmap (DIB) patterns, GDI converts the DIB into a device-dependent bitmap using SetDIBits

before it passes a normal pattern brush to the device driver. The selection of a DIB pattern brush with a two-color DIB and DIB_RGB_COLORS into a monochrome DC is a special case; GDI forces the color table to have black as index 0 and white as index 1 to maintain foreground and background information. The device driver turns hatched brushes into pattern brushes using the specified hatch scheme; the foreground and background colors at the time of selection are used for the pattern. All brush types can be represented at the device-driver level as bitmaps (usually 8-by-8) that are repeatedly blted as appropriate. To allow proper alignment of these bitmaps, GDI realizes each physical brush with a brush origin. The default origin is (0,0) and can be changed with the SetBrushOrg function (discussed in more detail below).

The GDI component known as the font mapper examines every physical font in the system to find the one that most closely matches the requested logical font. The mapper penalizes any font property that does not match. The physical font chosen is the one with the smallest penalty. The possible physical fonts that are available are raster, vector, TrueType fonts installed in the system, and device fonts built into or downloaded to the output device. The logical values for height and width of the font are converted to physical units based on the current mapping mode before the font mapper examines them.

Selecting a bitmap into a memory DC involves nothing more than performing some error checking and setting a few pointers. If the bitmap is compatible with the DC and is not currently selected elsewhere, the bits are locked in memory and the appropriate fields are set in the DC. Most GDI functions treat a memory DC with a selected bitmap as a regular device DC; only the device driver acts differently, based on whether the output destination is memory or the actual device. The color format of the bitmap defines the color format of the memory DC. When a memory DC is created with CreateCompatibleDC, the default monochrome bitmap is selected into it, and the color format of the DC is monochrome. When an appropriate color bitmap (one whose color resolution matches that of the device) is selected into the DC, the color format of the DC changes to reflect this event. This behavior affects the result of the CreateCompatibleBitmap function, which creates a monochrome bitmap for a monochrome DC and a color bitmap for a color DC.

Palettes are not automatically realized during the selection process. The RealizePalette function must be explicitly called to realize a selected palette. If a palette is realized on a nonpalette device, nothing happens. On a palette device, the logical palette is color- matched to the hardware palette to get the best possible matching. Subsequent references to a color in the logical palette are mapped to the appropriate hardware palette color.

Nothing is actually realized when a clip region is selected into a DC. A copy of the region is made and placed in the DC. This new clip region is then intersected with the current visible region (computed by the system and defining how much of the window is visible on the screen), and the DC is ready for drawing. Calling SelectObject with a region is equivalent to using the SelectClipRgn function.

space. The font data stored for a single physical font ranges from 48 bytes for a hardware font to 120K for a large bitmapped font.

Physical pens and brushes are not deleted from the system until the corresponding object is deleted. The physical object that corresponds to a selected logical object is locked in GDIs heap. (It is unlocked upon deselection.) Similarly, a font "instance" is cached in the system to maintain a realization of a specific logical font on a specific device with a specific coordinate mapping. When the logical font is deleted, all of its instances are removed as well.

When the clip region intersects with the visible region, the resulting intersection is

roughly the same size as the initial clip region. This is always the case when the DC

belongs to the topmost window and the clip region is within the windows boundary.

Creating vs. Recreating

If an application uses an object repeatedly, should the object be created once and cached by the application, or should the application recreate the object every time it is needed and delete it when that part of the drawing is complete? Creating on demand is simpler and saves memory in GDIs heap (objects do not remain allocated for long). Caching the objects within an application involves more work, but it can greatly increase the speed of object selection and realization, especially for fonts and sometimes for palettes.

The speed gains are possible because GDI caches physical objects. Although realizing a new logical pen or brush simply involves calling the device driver, realizing a logical font involves a cumbersome comparison of the logical font with each physical font available in the system. An application that wants to minimize font-mapping time should cache logical font handles that are expected to be used again. All previous font-mapping information is lost when a logical font handle is deleted; a recreated logical font must be realized from scratch.

Applications should cache palette objects for two reasons (both of which apply only on palette devices). Most importantly, because bitmaps on palette devices are stored based on a specific logical bitmap, using a different palette alters the bitmaps coloration and meaning. The second reason is a speed issue; the foreground realization of a palette is cached by GDI and is not calculated after the first realization. A new foreground realization must be computed from scratch for a newly created palette (or a palette altered by the SetPaletteEntries function or unrealized with the UnrealizeObject function).

Stock Objects

During initialization, GDI creates a number of predefined objects that any application can use. These objects are called stock objects. With the exception of regions and bitmaps, every object type has at least one defined stock object. An application calls the GetStockObject function to get a handle to a stock object, and the returned handle is then used as a standard object handle. The only difference is that no new memory is used because no new object is created. Also, because the system owns the stock objects, an

application is not responsible for deleting the object after use. Calling the DeleteObject function with a stock object does nothing.

Several stock fonts are defined in the system, the most useful being SYSTEM_FONT. This font is the default selected into a DC and is used for drawing the text in menus and title bars. Because this object defines only a logical font, the physical font that is actually used depends on the mapping mode and on the resolution of the device. A screen DC with a mapping mode of MM_TEXT has the system font as the physical font, but if the mapping mode is changed or if a different device is used, the physical font is no longer guaranteed to be the same. A change of behavior for Windows version 3.1 is that a stock font is never affected by the current mapping mode; it is always realized as if MM_TEXT were being used. Note that a font created by an application as a copy of a stock font does not have this immunity to scaling.

No stock bitmap in the system is accessible by means of the GetStockObject function, but GDI uses a default one-by-one monochrome bitmap as a stock object. This default bitmap is selected into a memory DC during creation of that DC. The bitmaps handle can be obtained by selecting a bitmap into a freshly minted memory DC; the return value from the SelectObject function is the stock bitmap.

Error Handling

The two common types of errors associated with objects are failure to create and failure to select. Both are most commonly associated with low-memory conditions.

During the creation process, GDI allocates a block of memory to store the logical object information. When the heap is full, applications cannot create any more objects until some space is freed. Bitmap creation tends to fail not because GDIs heap is full but because available global memory is insufficient for storing the bits themselves. Palettes also have a block of global memory that must be allocated by GDI to hold the palette information. The standard procedure for handling a failed object creation is to use a corresponding stock object in its place, although a failed bitmap creation is usually more limiting. An application usually warns the user that memory is low when an object creation or selection fails.

Out-of-memory conditions can also occur when a physical object is being realized. Realization also involves GDI allocating heap memory, and realizing fonts usually involves global memory as well. If the object was realized in the past for the same DC, new allocation is unnecessary (see the "Creating vs. Recreating" section). If a call to SelectObject returns an error (0), no new object is selected into the DC, and the previously selected object is not deselected.

Another possible error applies only to bitmaps. Attempting to select a bitmap with a color format that does not match the color format of the DC results in an error. Monochrome bitmaps can be selected into any memory DC, but color bitmaps can be selected only into a memory DC of a device that has the same color format. Additionally, bitmaps can be selected only into memory DCs; they cannot be selected into a DC connected to an actual output device or into metafile DCs.

hNewPen = CreatePen(1, 1, RGB(255, 0, 0));

if (hNewPen)

{

if (SelectObject(hDC, hNewPen))

{

SelectObject(hDC, GetStockObject(BLACK_PEN));

}

DeleteObject(hDC, hNewPen);

}

Note: The rumor that an application should never delete a stock object is far from the

truth. Calling the DeleteObject function with a stock object does nothing. Consequently,

an application need not ensure that an object being deleted is not a stock object.

UNREALIZEOBJECT

The UnrealizeObject function affects only brushes and palettes. As its name implies, the

UnrealizeObject function lets an application force GDI to re-realize an object from

scratch when the object is next realized in a DC.

The UnrealizeObject function lets an application reset the origin of the brush. When a patterned, hatched, or dithered brush is used, the device driver handles it as an eight-by- eight bitmap. During use, the driver aligns a point in the bitmap, known as the brush origin, to the upper-left corner of the DC. The default brush origin is (0,0). If an application wants to change the brush origin, it uses the SetBrushOrg function. This function does not change the origin of the current brush; it sets the origin of the brush for the next time that the brush is realized. The origin of a brush that has never been selected into a DC can be set as follows:

// Create the brush.

hBrush = CreatePatternBrush(.....);

// Set the origin as needed.

SetBrushOrg(hDC, X, Y);

// Select (and realize) the brush with the chosen origin.

SelectObject(hDC, hBrush);

If, on the other hand, the brush is currently selected into a DC, calling the SetBrushOrg

function alone accomplishes nothing. Because the new origin does not take effect until

the brush is realized anew, the application must force this re-realization by using the

UnrealizeObject function before the brush is reselected into a DC. The following sample

code changes the origin of a brush that is initially selected into a DC:

// Deselect the brush from the DC.

hBrush = SelectObject(hDC, GetStockObject(BLACK_BRUSH));

// Set a new origin.

SetBrushOrg(hDC, X, Y);

// Unrealize the brush to force re-realization.

UnrealizeObject(hBrush);

// Select (and hence re-realize) the brush.

SelectObject(hDC, hBrush);

The UnrealizeObject function can also be called for a palette object, although the effect is

a bit more subtle. (As is common with the palette functions, nothing happens on a

nonpalette device.) The function forces the palette to be realized from scratch the next

time the palette is realized, thereby ignoring any previous mapping. This is useful in

situations in which an application expects that the palette will realize differently the next

time around, perhaps matching more effectively with a new system palette and not

forcing a system palette change. Any bitmaps created with the original realization of the

palette are no longer guaranteed to be valid.

Special Cases

Palette objects are selected into DCs using the SelectPalette function. The reason for this additional, seemingly identical, function is that palette selection has an additional parameter that defines whether the palette is being selected as a foreground or as a background palette, which affects palette realization on palette devices. Calling the SelectObject function with a palette returns an error. Palettes are deleted using the DeleteObject function.

A clip region can be selected into a DC by calling either the SelectClipRgn or the SelectObject function. Both functions perform identically with the exception of selecting a NULL handle in place of a region. SelectClipRgn can be used to clear the current clipping state by calling the function as follows:

Graphics Driver and GDI Interaction

More on GDI and its usage in Win32 environment contact Virtual University Resource.

13.4 Device Context (DC)

We have studied a lot about GDI and its objects and now, we will know how to display GDI objects using Device context. A device context is a structure that defines a set of graphic objects and their associated attributes, as well as the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations. The remainder of this section is divided into the following three areas.

Display Device Context Cache

The system maintains a cache of display device contexts that it uses for common, parent, and window device contexts. The system retrieves a device context from the cache whenever an application calls the GetDC or BeginPaint function; the system returns the DC to the cache when the application subsequently calls the ReleaseDC or EndPaint function.

There is no predetermined limit on the amount of device contexts that a cache can hold; the system creates a new display device context for the cache if none is available. Given this, an application can have more than five active device contexts from the cache at a time. However, the application must continue to release these device contexts after use. Because new display device contexts for the cache are allocated in the application's heap space, failing to release the device contexts eventually consumes all available heap space. The system indicates this failure by returning an error when it cannot allocate space for the new device context. Other functions unrelated to the cache may also return errors.

Display Device Context Defaults

Upon first creating a display device context, the system assigns default values for the attributes (that is, drawing objects, colors, and modes) that comprise the device context. The following table shows the default values for the attributes of a display device context.

Attribute Default value

Background color Background color setting from Control Panel (typically, white).

Background mode OPAQUE

Bitmap None

Brush WHITE_BRUSH

Brush origin (0,0)

Clipping region Entire window or client area with the update region clipped, as appropriate. Child and pop-up windows in the client area may also be clipped.

Palette DEFAULT_PALETTE

Current pen position (0,0)

Device origin Upper left corner of the window or the client area.

Drawing mode R2_COPYPEN

Font SYSTEM_FONT

Inter character spacing 0

Mapping mode MM_TEXT

Pen BLACK_PEN

Polygon-fill mode ALTERNATE

Stretch mode BLACKONWHITE

Text color Text color setting from Control Panel (typically, black).

Viewport extent (1,1)

Viewport origin (0,0)

Window extent (1,1)

Window origin (0,0)

An application can modify the values of the display device context attributes by using selection and attribute functions, such as SelectObject , SetMapMode , and SetTextColor.

Private Display Device Context

A private device context enables an application to avoid retrieving and initializing a display device context each time the application must draw in a window. Private device contexts are useful for windows that require many changes to the values of the attributes of the device context to prepare it for drawing. Private device contexts reduce the time required to prepare the device context and therefore the time needed to carry out drawing in the window.

An application directs the system to create a private device context for a window by specifying the CS_OWNDC style in the window class. The system creates a unique private device context each time it creates a new window belonging to the class. Initially, the private device context has the same default values for attributes as a common device context, but the application can modify these at any time. The system preserves changes to the device context for the life of the window or until the application makes additional changes.

An application can retrieve a handle to the private device context by using the GetDC function any time after the window is created. The application must retrieve the handle only once. Thereafter, it can keep and use the handle any number of times. Because a private device context is not part of the display device context cache, an application need never release the device context by using the ReleaseDC function.

The system automatically adjusts the device context to reflect changes to the window, such as moving or sizing. This ensures that any overlapping windows are always properly clipped; that is, no action is required by the application to ensure clipping. However, the system does not revise the device context to include the update region. Therefore, when processing a WM_PAINT message, the application must incorporate the update region either by calling BeginPaint or by retrieving the update region and intersecting it with the current clipping region. If the application does not call BeginPaint, it must explicitly validate the update region by using the ValidateRect or ValidateRgn function. If the application does not validate the update region, the window receives an endless series of WM_PAINT messages.

Because BeginPaint hides the caret if a window is showing it, an application that calls BeginPaint should also call the EndPaint function to restore the caret. EndPaint has no other effect on a private device context.

Although a private device context is convenient to use, it is expensive in terms of system resources, requiring 800 or more bytes to store. Private device contexts are recommended when performance considerations outweigh storage costs.

The system includes the private device context when sending the WM_ERASEBKGND message to the application. The current selections of the private device context, including mapping mode, are in effect when the application or the system processes these messages. To avoid undesirable effects, the system uses logical coordinates when erasing the background; for example, it uses the GetClipBox function to retrieve the logical

coordinates of the area to erase and passes these coordinates to the FillRect function. Applications that process these messages can use similar techniques. The system supplies a window device context with the WM_ICONERASEBKGND message regardless of whether the corresponding window has a private device context.

An application can use the GetDCEx function to force the system to return a common device context for the window that has a private device context. This is useful for carrying out quick touch-ups to a window without changing the current values of the attributes of the private device context.

Class Display Device Context

By using a class device context, an application can use a single display device context for every window belonging to a specified class. Class device contexts are often used with control windows that are drawn using the same attribute values. Like private device contexts, class device contexts minimize the time required to prepare a device context for drawing.

The system supplies a class device context for a window if it belongs to a window class having the CS_CLASSDC style. The system creates the device context when creating the first window belonging to the class and then uses the same device context for all subsequently created windows in the class. Initially, the class device context has the same default values for attributes as a common device context, but the application can modify these at any time. The system preserves all changes, except for the clipping region and device origin, until the last window in the class has been destroyed. A change made for one window applies to all windows in that class.

An application can retrieve the handle for the class device context by using the GetDC function any time after the first window has been created. The application can keep and use the handle without releasing it because the class device context is not part of the display device context cache. If the application creates another window in the same window class, the application must retrieve the class device context again. Retrieving the device context sets the correct device origin and clipping region for the new window. After the application retrieves the class device context for a new window in the class, the device context can no longer be used to draw in the original window without again retrieving it for that window. In general, each time it must draw in a window, an application must explicitly retrieve the class device context for the window.

Applications that use class device contexts should always call BeginPaint when processing a WM_PAINT message. The function sets the correct device origin and clipping region for the window, and incorporates the update region. The application should also call EndPaint to restore the caret if BeginPaint hide it. EndPaint has no other effect on a class device context.

The system passes the class device context when sending the WM_ERASEBKGND message to the application, permitting the current attribute values to affect any drawing carried out by the application or the system when processing this message. The system

parent window, the child window can potentially draw over the entire parent window, but the parent device context must not be used in this way.

The system ignores the CS_PARENTDC style if the parent window uses a private or class device context, if the parent window clips its child windows, or if the child window clips its child windows or sibling windows.

Window Update Lock

A window update lock is a temporary suspension of drawing in a window. The system uses the lock to prevent other windows from drawing over the tracking rectangle whenever the user moves or sizes a window. Applications can use the lock to prevent drawing if they carry out similar moving or sizing operations with their own windows.

An application uses the LockWindowUpdate function to set or clear a window update lock, specifying the window to lock. The lock applies to the specified window and all of its child windows. When the lock is set, the GetDC and BeginPaint functions return a display device context with a visible region that is empty. Given this, the application can continue to draw in the window, but all output is clipped. The lock persists until the application clears it by calling LockWindowUpdate, specifying NULL for the window. Although LockWindowUpdate forces a window's visible region to be empty, the function does not make the specified window invisible and does not clear the WS_VISIBLE style bit.

After the lock is set, the application can use the GetDCEx function, with the DCX_LOCKWINDOWUPDATE value, to retrieve a display device context to draw over the locked window. This allows the application to draw a tracking rectangle when processing keyboard or mouse messages. The system uses this method when the user moves and sizes windows. GetDCEx retrieves the display device context from the display device context cache, so the application must release the device context as soon as possible after drawing.

While a window update lock is set, the system creates an accumulated bounding rectangle for each locked window. When the lock is cleared, the system uses this bounding rectangle to set the update region for the window and its child windows, forcing an eventual WM_PAINT message. If the accumulated bounding rectangle is empty (that is, if no drawing has occurred while the lock was set), the update region is not set.

Accumulated Bounding Rectangle

The accumulated bounding rectangle is the smallest rectangle enclosing the portion of a window or client area affected by recent drawing operations. An application can use this rectangle to conveniently determine the extent of changes caused by drawing operations. It is sometimes used in conjunction with LockWindowUpdate to determine which portion of the client area must be redrawn after the update lock is cleared.

An application uses the SetBoundsRect function (specifying DCB_ENABLE) to begin accumulating the bounding rectangle. The system subsequently accumulates points for

the bounding rectangle as the application uses the specified display device context. The application can retrieve the current bounding rectangle at any time by using the GetBoundsRect function. The application stops the accumulation by calling SetBoundsRect again, specifying the DCB_DISABLE value.

13.5 Steps involved in output of a text string in the client area of

the application

The following points are adopted to output a text string.

  1. Get the handle to the Device Context for the window’s client area from the GDI.
  2. Use the Device Context for writing / painting in the client area of the window.
  3. Release the Device context.

Printing Text String (Example)

HDC hdc;

hdc = GetDC(hWnd); //Get the DC

char *str=”This is Gdi program”;

TextOut(hdc,10,10,str , strlen(str)); //output a text

ReleaseDC(hWnd,hdc); //release a DC

13.6 GetDC

The GetDC function retrieves a handle to a display device context (DC) for the client area of a specified window or for the entire screen. You can use the returned handle in subsequent GDI functions to draw in the DC.

hDC = GetDC( hWnd );

hWnd

Handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire screen.

The GetDC function retrieves a common, class, or private DC depending on the class style of the specified window. For class and private DCs, GetDC leaves the previously assigned attributes unchanged. However, for common DCs, GetDC assigns default attributes to the DC each time it is retrieved. For example, the default font is System, which is a bitmap font. Because of this, the handle for a common DC returned by GetDC