<Previous Lesson

Visual Programming

Next Lesson>

Lesson#14

Painting and Drawing

14.1 PAINTING IN A WINDOW 2
14.1.1 WHEN TO DRAW IN A WINDOW 3
14.1.2 T
HE WM_PAINT MESSAGE 3
14.1.3 D
RAWING WITHOUT THE WM_PAINT MESSAGE 4
14.1.4 W
INDOW BACKGROUND 5
14.2 WINDOW COORDINATE SYSTEM 6
14.3 WINDOW REGIONS 7
14.4 CONDITION IN WHICH PAINT MESSAGE IS SENT (IN SHORT) 7
14.5 CONDITION IN WHICH PAINT MESSAGE MAY BE SENT 7
14.6 CONDITION IN WHICH PAINT MESSAGE NEVER SENT 7
14.7 PAINT REFERENCE 8
14.7.1 INVALIDATERECT FUNCTION 8
14.7.2 PAINTSTRUCT S
TRUCTURE 8
14.8 OTHER GDI TEXT OUTPUT FUNCTIONS 9
14.8.1 DRAWTEXT 9
14.8.2 T
ABBEDTEXTOUT 14
14.9 PRIMITIVE SHAPES 15
14.9.1 LINES 15
14.9.2 R
ECTANGLE 16
14.9.3 P
OLYGON 16
14.10 STOCK OBJECTS 16
14.10.1 GETSTOCKOBJECT FUNCTION 16
14.11 SELECTOBJECT 18
14.12 EXAMPLE 19
SUMMARY 19
EXERCISES 20
Painting and Drawing 2

14.1 Painting in a Window

The WM_PAINT message is sent when the system or another application makes a request
to paint a portion of an application's window. The message is sent by the
DispatchMessage function to a window procedure when the application obtains a
WM_PAINT message from message Queue by using the GetMessage or PeekMessage
functions.
A window receives this message through its WindowProc function.
Windows always specifies invalid area of any window in terms of a least bounding
rectangle; hence, the entire window is not repainted.
WM_PAINT message is generated by the system only when any part of application
window becomes invalid.
The WM_PAINT message is generated by the system and should not be sent by an
application.
The DefWindowProc function validates the update region. The function may also send
the WM_NCPAINT message to the window procedure if the window frame must be
painted and send the WM_ERASEBKGND message if the window background must be
erased.
The system sends this message when there are no other messages in the application's
message queue. DispatchMessage determines where to send the message; GetMessage
determines which message to dispatch. GetMessage returns the WM_PAINT message
when there are no other messages in the application's message queue, and
DispatchMessage sends the message to the appropriate window procedure.
A window may receive internal paint messages as a result of calling RedrawWindow with
the RDW_INTERNALPAINT flag set. In this case, the window may not have an update
region. An application should call the GetUpdateRect function to determine whether the
window has an update region. If GetUpdateRect returns zero, the application should not
call the BeginPaint and EndPaint functions.
An application must check for any necessary internal painting by looking at its internal
data structures for each WM_PAINT message, because a WM_PAINT message may
have been caused by both a non-NULL update region and a call to RedrawWindow with
the RDW_INTERNALPAINT flag set.
The system sends an internal WM_PAINT message only once. After an internal
WM_PAINT message is returned from GetMessage or PeekMessage or is sent to a
window by UpdateWindow, the system does not post or send further WM_PAINT
messages until the window is invalidated or until RedrawWindow is called again with the
RDW_INTERNALPAINT flag set.
Painting and Drawing 3
For some common controls, the default WM_PAINT message processing checks the
wParam parameter. If wParam is non-NULL, the control assumes that the value is an
HDC and paints using that device context.

14.1.1 When to Draw in a Window

An application draws in a window at a variety of times: when first creating a window,
when changing the size of the window, when moving the window from behind another
window, when minimizing or maximizing the window, when displaying data from an
opened file, and when scrolling, changing, or selecting a portion of the displayed data.
The system manages actions such as moving and sizing a window. If an action affects the
content of the window, the system marks the affected portion of the window as ready for
updating and, at the next opportunity, sends a WM_PAINT message to the window
procedure of the window. The message is a signal to the application to determine what
must be updated and to carry out the necessary drawing.
Some actions are managed by the application, such as displaying open files and selecting
displayed data. For these actions, an application can mark for updating the portion of the
window affected by the action, causing a WM_PAINT message to be sent at the next
opportunity. If an action requires immediate feedback, the application can draw while the
action takes place, without waiting for WM_PAINT. For example, a typical application
highlights the area the user selects rather than waiting for the next WM_PAINT message
to update the area.
In all cases, an application can draw in a window as soon as it is created. To draw in the
window, the application must first retrieve a handle to a display device context for the
window. Ideally, an application carries out most of its drawing operations during the
processing of WM_PAINT messages. In this case, the application retrieves a display
device context by calling the BeginPaint function. If an application draws at any other
time, such as from within WinMain or during the processing of keyboard or mouse
messages, it calls the GetDC or GetDCEx function to retrieve the display DC.

14.1.2 The WM_PAINT Message

Typically, an application draws in a window in response to a WM_PAINT message. The
system sends this message to a window procedure when changes to the window have
altered the content of the client area. The system sends the message only if there are no
other messages in the application message queue.
Upon receiving a WM_PAINT message, an application can call BeginPaint to retrieve
the display device context for the client area and use it in calls to GDI functions to carry
out whatever drawing operations are necessary to update the client area. After completing
the drawing operations, the application calls the EndPaint function to release the display
device context.
Painting and Drawing 4
Before BeginPaint returns the display device context, the system prepares the device
context for the specified window. It first sets the clipping region for the device context to
be equal to the intersection of the portion of the window that needs updating and the
portion that is visible to the user. Only those portions of the window that have changed
are redrawn. Attempts to draw outside this region are clipped and do not appear on the
screen.
The system can also send WM_NCPAINT and WM_ERASEBKGND messages to the
window procedure before BeginPaint returns. These messages direct the application to
draw the nonclient area and window background. The nonclient area is the part of a
window that is outside of the client area. The area includes features such as the title bar,
window menu (also known as the System menu), and scroll bars. Most applications rely
on the default window function, DefWindowProc, to draw this area and therefore pass
the WM_NCPAINT message to this function. The window background is the color or
pattern that a window is filled with before other drawing operations begin. The
background covers any images previously in the window or on the screen under the
window. If a window belongs to a window class having a class background brush, the
DefWindowProc function draws the window background automatically.
BeginPaint fills a PAINTSTRUCT structure with information such as the dimensions of
the portion of the window to be updated and a flag indicating whether the window
background has been drawn. The application can use this information to optimize
drawing. For example, it can use the dimensions of the update region, specified by the
rcPaint member, to limit drawing to only those portions of the window that need
updating. If an application has very simple output, it can ignore the update region and
draw in the entire window, relying on the system to discard (clip) any unneeded output.
Because the system clips drawing that extends outside the clipping region, only drawing
that is in the update region is visible.
BeginPaint sets the update region of a window to NULL. This clears the region,
preventing it from generating subsequent WM_PAINT messages. If an application
processes a WM_PAINT message but does not call BeginPaint or otherwise clear the
update region, the application continues to receive WM_PAINT messages as long as the
region is not empty. In all cases, an application must clear the update region before
returning from the WM_PAINT message.
After the application finishes drawing, it should call EndPaint. For most windows,
EndPaint releases the display device context, making it available to other windows.
EndPaint also shows the caret, if it was previously hidden by BeginPaint. BeginPainthides the caret to prevent drawing operations from corrupting it.

14.1.3 Drawing Without the WM_PAINT Message

Although applications carry out most drawing operations while the WM_PAINT in a window without relying on the WM_PAINT message. This can be useful when the
Painting and Drawing 5
user needs immediate feedback, such as when selecting text and dragging or sizing an
object. In such cases, the application usually draws while processing keyboard or mouse
messages.
To draw in a window without using a WM_PAINT message, the application uses the
GetDC or GetDCEx function to retrieve a display device context for the window. With
the display device context, the application can draw in the window and avoid intruding
into other windows. When the application has finished drawing, it calls the ReleaseDCfunction to release the display device context for use by other applications.
When drawing without using a WM_PAINT message, the application usually does not
invalidate the window. Instead, it draws in such a fashion that it can easily restore the
window and remove the drawing. For example, when the user selects text or an object,
the application typically draws the selection by inverting whatever is already in the
window. The application can remove the selection and restore the original contents of the
window by simply inverting again.
The application is responsible for carefully managing any changes it makes to the
window. In particular, if an application draws a selection and an intervening
WM_PAINT message occurs, the application must ensure that any drawing done during
the message does not corrupt the selection. To avoid this, many applications remove the
selection, carry out usual drawing operations, and then restore the selection when
drawing is complete.

14.1.4 Window Background

The window background is the color or pattern used to fill the client area before a
window begins drawing. The window background covers whatever was on the screen
before the window was moved there, erasing existing images and preventing the
application's new output from being mixed with unrelated information.
The system paints the background for a window or gives the window the opportunity to
do so by sending it a WM_ERASEBKGND message when the application calls
BeginPaint. If an application does not process the message but passes it to
DefWindowProc, the system erases the background by filling it with the pattern in the
background brush specified by the window's class. If the brush is not valid or the class
has no background brush, the system sets the fErase member in the PAINTSTRUCTstructure that BeginPaint returns, but carries out no other action. The application then
has a second chance to draw the window background, if necessary.
If it processes WM_ERASEBKGND, the application should use the message's wParam
parameter to draw the background. This parameter contains a handle to the display device
context for the window. After drawing the background, the application should return a
nonzero value. This ensures that BeginPaint does not erroneously set the fErase member
of the PAINTSTRUCT structure to a nonzero value (indicating the background should
be erased) when the application processes the subsequent WM_PAINT message.
Painting and Drawing 6
An application can define a class background brush by assigning a brush handle or a
system color value to the hbrBackground member of the WNDCLASS structure when
registering the class with the RegisterClass function. The GetStockObject or
CreateSolidBrush function can be used to create a brush handle. A system color value
can be one of those defined for the SetSysColors function. (The value must be increased
by one before it is assigned to the member.)
An application can process the WM_ERASEBKGND message even though a class
background brush is defined. This is typical in applications that enable the user to change
the window background color or pattern for a specified window without affecting other
windows in the class. In such cases, the application must not pass the message to
DefWindowProc.
It is not necessary for an application to align brushes, because the system draws the brush
using the window origin as the point of reference. Given this, the user can move the
window without affecting the alignment of pattern brushes.

14.2 Window Coordinate System

The coordinate system for a window is based on the coordinate system of the display
device. The basic unit of measure is the device unit (typically, the pixel). Points on the
screen are described by x- and y-coordinate pairs. The x-coordinates increase to the right;
y-coordinates increase from top to bottom. The origin (0,0) for the system depends on the
type of coordinates being used.
The system and applications specify the position of a window on the screen in screen
coordinates
. For screen coordinates, the origin is the upper-left corner of the screen. The
full position of a window is often described by a RECT structure containing the screen
coordinates of two points that define the upper-left and lower-right corners of the
window.
The system and applications specify the position of points in a window by using client
coordinates
. The origin in this case is the upper-left corner of the window or client area.
Client coordinates ensure that an application can use consistent coordinate values while
drawing in the window, regardless of the position of the window on the screen.
The dimensions of the client area are also described by a RECT structure that contains
client coordinates for the area. In all cases, the upper-left coordinate of the rectangle is
included in the window or client area, while the lower-right coordinate is excluded.
Graphics operations in a window or client area are excluded from the right and lower
edges of the enclosing rectangle.
Occasionally, applications may be required to map coordinates in one window to those of
another window. An application can map coordinates by using the MapWindowPoints
 function. If one of the windows is the desktop window, the function effectively converts
Painting and Drawing 7
screen coordinates to client coordinates and vice versa; the desktop window is always
specified in screen coordinates.

14.3 Window Regions

In addition to the update region, every window has a visible region that defines the
window portion visible to the user. The system changes the visible region for the window
whenever the window changes size or whenever another window is moved such that it
obscures or exposes a portion of the window. Applications cannot change the visible
region directly, but the system automatically uses the visible region to create the clipping
region for any display device context retrieved for the window.
The clipping region determines where the system permits drawing. When the application
retrieves a display device context using the BeginPaint, GetDC, or GetDCEx function,
the system sets the clipping region for the device context to the intersection of the visible
region and the update region. Applications can change the clipping region by using
functions such as SetWindowRgn, SelectClipPath and SelectClipRgn, to further limit
drawing to a particular portion of the update area.
The WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles further specify how the
system calculates the visible region for a window. If a window has one or both of these
styles, the visible region excludes any child window or sibling windows (windows having
the same parent window). Therefore, drawing that would otherwise intrude in these
windows will always be clipped.
14.4 Condition in which PAINT message is sent (briefly)
Any hidden part of window becomes visible Window is resized (and
CS_VREDRAW, CS_HREDRAW style bits were set while registering the
window class).
Program scrolls its window.
InvalidateRect or InvalidateRgn is called by the application.

14.5 Condition in which PAINT message may be sent

A dialog is dismissed.
A drop-down menu disappears.
A tool tip is displayed and then it hides.

14.6 Condition in which PAINT message never sent

An icon is dragged over the window.
The mouse cursor is moved
Painting and Drawing 8

14.7 PAINT Reference
14.7.1 InvalidateRect Function

InvalidateRect function is used to make window or part of it, invalidate.
BOOL InvalidateRect(
HWND hWnd, // handle to window
CONST RECT *lpRect, // rectangle coordinates
BOOL bErase // erase state
);
hWnd: Handle to the window whose update region has changed. If this parameter is
NULL, the system invalidates and redraws all windows, and sends the
WM_ERASEBKGND and WM_NCPAINT messages to the window procedure before
the function returns.
lpRect: Pointer to a RECT structure that contains the client coordinates of the rectangle
to be added to the update region. If this parameter is NULL, the entire client area is added
to the update region.
bErase: Specifies whether the background within the update region is to be erased when
the update region is processed. If this parameter is TRUE, the background is erased when
the BeginPaint function is called. If this parameter is FALSE, the background remains
unchanged.
Return Values: If the function succeeds, the return value is nonzero.If the function fails,
the return value is zero.

14.7.2 PAINTSTRUCT Structure

The PAINTSTRUCT structure contains information for an application. This information
can be used to paint the client area of a window owned by that application.
typedef struct tagPAINTSTRUCT {
HDC hdc; //Handle to the Device context
BOOL fErase; /*erase back ground of this parameter is true*/
RECT rcPaint; /*rectangle to the invalidate region*/
BOOL fRestore;
BOOL fIncUpdate; //updation true/false
BYTE rgbReserved[32]; //rgb values
} PAINTSTRUCT, *PPAINTSTRUCT;

hdc

Handle to the display DC to be used for painting.

fErase

Specifies whether the background must be erased. This value is nonzero if the
application should erase the background. The application is responsible for
Painting and Drawing 9
erasing the background if a window class is created without a background brush.
For more information, see the description of the hbrBackground member of the

WNDCLASS structure.

rcPaint

Specifies a RECT structure that specifies the upper left and lower right corners of
the rectangle in which the painting is requested, in device units relative to the
upper-left corner of the client area.

fRestore

Reserved; used internally by the system.

fIncUpdate

Reserved; used internally by the system.

rgbReserved

Reserved; used internally by the system.

14.8 Other GDI Text Output Functions
14.8.1 DrawText

The DrawText function draws formatted text in the specified rectangle. It formats the text
according to the specified method (expanding tabs, justifying characters, breaking lines,
and so forth).

int DrawText(
HDC
hDC, // handle to DC

LPCTSTR lpString, // text to draw

int nCount, // text length

LPRECT lpRect, // formatting dimensions

UINT uFormat // text-drawing options

);

hDC: Handle to the device context.
lpString: Pointer to the string that specifies the text to be drawn. If the nCount parameter
is –1, the string must be null-terminated.
If uFormat includes DT_MODIFYSTRING, the function could add up to four
additional characters to this string. The buffer containing the string should be
large enough to accommodate these extra characters.
nCount: Specifies the length of the string. For the ANSI function it is a BYTE count and
for the Unicode function it is a WORD count. Note that for the ANSI function,
characters in SBCS code pages take one byte each, while most characters in DBCS code
pages take two bytes; for the Unicode function, most currently defined Unicode
characters (those in the Basic Multilingual Plane (BMP)) are one WORD while Unicode
surrogates are two WORDs. If nCount is –1, then the lpString parameter is assumed to be
a pointer to a null-terminated string and DrawText computes the character count
automatically.
Painting and Drawing 10
lpRect: Pointer to a RECT structure that contains the rectangle (in logical coordinates)
in which the text is to be formatted.
uFormat: Specifies the method of formatting the text. This parameter can be one or more
of the following values.

Value Description

DT_BOTTOM Justifies the text to the bottom of the
rectangle. This value is used only with the
DT_SINGLELINE value.
DT_CALCRECT Determines the width and height of the
rectangle. If there are multiple lines of text,
DrawText uses the width of the rectangle
pointed to by the lpRect parameter and
extends the base of the rectangle to bound
the last line of text. If the largest word is
wider than the rectangle, the width is
expanded. If the text is less than the width
of the rectangle, the width is reduced. If
there is only one line of text, DrawTextmodifies the right side of the rectangle so
that it bounds the last character in the line.
In either case, DrawText returns the height
of the formatted text but does not draw the
text.
DT_CENTER Centers text horizontally in the rectangle.
DT_EDITCONTROL Duplicates the text-displaying
characteristics of a multiline edit control.
Specifically, the average character width is
calculated in the same manner as for an
edit control, and the function does not
display a partially visible last line.
DT_END_ELLIPSIS For displayed text, if the end of a string
does not fit in the rectangle, it is truncated
and ellipses are added. If a word that is not
at the end of the string goes beyond the
limits of the rectangle, it is truncated
without ellipses.
The string is not modified unless the
DT_MODIFYSTRING flag is specified.
Compare with DT_PATH_ELLIPSIS and
DT_WORD_ELLIPSIS.
DT_EXPANDTABS Expands tab characters. The default
Painting and Drawing 11
number of characters per tab is eight. The
DT_WORD_ELLIPSIS,
DT_PATH_ELLIPSIS, and
DT_END_ELLIPSIS values cannot be
used with the DT_EXPANDTABS value.
DT_EXTERNALLEADING Includes the font external leading in line
height. Normally, external leading is not
included in the height of a line of text.
DT_HIDEPREFIX Windows 2000/XP: Ignores the
ampersand (&) prefix character in the text.
The letter that follows will not be
underlined, but other mnemonic-prefix
characters are still processed. For example:
input string: "A&bc&&d"
normal: "Abc&d"
DT_HIDEPREFIX: "Abc&d"
Compare with DT_NOPREFIX and
DT_PREFIXONLY.
DT_INTERNAL Uses the system font to calculate text
metrics.
DT_LEFT Aligns text to the left.
DT_MODIFYSTRING Modifies the specified string to match the
displayed text. This value has no effect
unless DT_END_ELLIPSIS or
DT_PATH_ELLIPSIS is specified.
DT_NOCLIP Draws without clipping. DrawText is
somewhat faster when DT_NOCLIP is
used.
DT_NOFULLWIDTHCHARBREAK Windows 98/Me, Windows 2000/XP:

Prevents a line break at a DBCS (doublewide
character string), so that the line
breaking rule is equivalent to SBCS
strings. For example, this can be used in
Korean windows, for more readability of
icon labels. This value has no effect unless
DT_WORDBREAK is specified.
DT_NOPREFIX Turns off processing of prefix characters.
Normally, DrawText interprets the
mnemonic-prefix character & as a directive
to underscore the character that follows,
and the mnemonic-prefix characters && as
a directive to print a single &. By
specifying DT_NOPREFIX, this
processing is turned off. For example,
Painting and Drawing 12
input string: "A&bc&&d"
normal: "Abc&d"
DT_NOPREFIX: "A&bc&&d"
Compare with DT_HIDEPREFIX and
DT_PREFIXONLY.
DT_PATH_ELLIPSIS For displayed text, replaces characters in
the middle of the string with ellipses so
that the result fits in the specified
rectangle. If the string contains backslash
(\) characters, DT_PATH_ELLIPSIS
preserves as much as possible of the text
after the last backslash.
The string is not modified unless the
DT_MODIFYSTRING flag is specified.
Compare with DT_END_ELLIPSIS and
DT_WORD_ELLIPSIS.
DT_PREFIXONLY Windows 2000/XP: Draws only an
underline at the position of the character
following the ampersand (&) prefix
character. Does not draw any other
characters in the string. For example,
input string: "A&bc&&d"
normal: "Abc&d"
DT_PREFIXONLY: " _ "
Compare with DT_HIDEPREFIX and
DT_NOPREFIX.
DT_RIGHT Aligns text to the right.
DT_RTLREADING Layout in right-to-left reading order for bidirectional
text when the font selected into
the hdc is a Hebrew or Arabic font. The
default reading order for all text is left-toright.
DT_SINGLELINE Displays text on a single line only.
Carriage returns and line feeds do not
break the line.
DT_TABSTOP Sets tab stops. Bits 15–8 (high-order byte
of the low-order word) of the uFormat
parameter specify the number of characters
for each tab. The default number of
characters per tab is eight. The
DT_CALCRECT,
DT_EXTERNALLEADING,
Painting and Drawing 13
DT_INTERNAL, DT_NOCLIP, and
DT_NOPREFIX values cannot be used
with the DT_TABSTOP value.
DT_TOP Justifies the text to the top of the rectangle.
DT_VCENTER Centers text vertically. This value is used
only with the DT_SINGLELINE value.
DT_WORDBREAK Breaks words. Lines are automatically
broken between words if a word would
extend past the edge of the rectangle
specified by the lpRect parameter. A
carriage return-line feed sequence also
breaks the line.
If this is not specified, output is on one
line.
DT_WORD_ELLIPSIS Truncates any word that does not fit in the
rectangle and adds ellipses.
Compare with DT_END_ELLIPSIS and
DT_PATH_ELLIPSIS.
Return Values: If the function succeeds, the return value is the height of the text in
logical units. If DT_VCENTER or DT_BOTTOM is specified, the return value is the
offset from
lpRect-> top to the bottom of the drawn text
If the function fails, the return value is zero.
The DrawText function uses the device context's selected font, text color, and
background color to draw the text. Unless the DT_NOCLIP format is used, DrawText

clips the text so that it does not appear outside the specified rectangle. Note that text with
significant overhang may be clipped, for example, an initial "W" in the text string or text
that is in italics. All formatting is assumed to have multiple lines unless the
DT_SINGLELINE format is specified.
If the selected font is too large for the specified rectangle, the DrawText function does
not attempt to substitute a smaller font.
The DrawText function supports only fonts whose escapement and orientation are both
zero.
The text alignment mode for the device context must include the TA_LEFT, TA_TOP,
and TA_NOUPDATECP flags.
Painting and Drawing 14

14.8.2 TabbedTextOut

The TabbedTextOut function writes a character string at a specified location, expanding
tabs to the values specified in an array of tab-stop positions. Text is written in the
currently selected font, background color, and text color.
LONG TabbedTextOut(
HDC hDC, // handle to DC
int X, // x-coord of start
int
Y, // y-coord of start
LPCTSTR lpString, // character string
int nCount, // number of characters
int nTabPositions, // number of tabs in array
CONST LPINT lpnTabStopPositions, // array of tab positions
int nTabOrigin // start of tab expansion

);

hDC: Handle to the device context.
X: Specifies the x-coordinate of the starting point of the string, in logical units.
Y: Specifies the y-coordinate of the starting point of the string, in logical units.
lpString: Pointer to the character string to draw. The string does not need to be zeroterminated,
since nCount specifies the length of the string.
nCount: Specifies the length of the string pointed to by lpString. For the ANSI function it
is a BYTE count and for the Unicode function it is a WORD count. Note that for the
ANSI function, characters in SBCS code pages take one byte each, while most characters
in DBCS code pages take two bytes; for the Unicode function, most currently defined
Unicode characters (those in the Basic Multilingual Plane (BMP)) are one WORD while
Unicode surrogates are two WORDs.
nTabPositions: Specifies the number of values in the array of tab-stop positions.
lpnTabStopPositions: Pointer to an array containing the tab-stop positions, in logical
units. The tab stops must be sorted in increasing order; the smallest x-value should be the
first item in the array.
nTabOrigin: Specifies the x-coordinate of the starting position from which tabs are
expanded, in logical units.
Return Values: If the function succeeds, the return value is the dimensions, in logical
units, of the string. The height is in the high-order word and the width is in the low-order
word.
If the function fails, the return value is zero.
Painting and Drawing 15
If the nTabPositions parameter is zero and the lpnTabStopPositions parameter is NULL,
tabs are expanded to eight times the average character width.
If nTabPositions is 1, the tab stops are separated by the distance specified by the first
value in the lpnTabStopPositions array.
If the lpnTabStopPositions array contains more than one value, a tab stop is set for each
value in the array, up to the number specified by nTabPositions.
The nTabOrigin parameter allows an application to call the TabbedTextOut function
several times for a single line. If the application calls TabbedTextOut more than once
with the nTabOrigin set to the same value each time, the function expands all tabs
relative to the position specified by nTabOrigin.
By default, the current position is not used or updated by the TabbedTextOut function.
If an application needs to update the current position when it calls TabbedTextOut, the
application can call the SetTextAlign function with the wFlags parameter set to
TA_UPDATECP. When this flag is set, the system ignores the X and Y parameters on
subsequent calls to the TabbedTextOut function, using the current position instead.

14.9 Primitive Shapes

Primitive shapes include: Lines and Curves, filled shapes like:
Ellipse, Chord, Pie, Polygon, Rectangles

14.9.1 Lines

Line can be drawn using MoveToEx and LineTo Function.
MoveToEx function moves the points at specified location.
Note: MoveToEx effects all drawing functions.
The LineTo function draws a line from the current position up to, but not including, the
specified point.
BOOL LineTo(
HDC
hdc, // device context handle
int nXEnd, // x-coordinate of ending point
int nYEnd // y-coordinate of ending point
);hdc: Handle to a device context.
nXEnd: Specifies the x-coordinate, in logical units, of the line's ending point.
nYEnd: Specifies the y-coordinate, in logical units, of the line's ending point.
Return Values: If the function succeeds, the return value is nonzero. If the function fails,
the return value is zero.
Painting and Drawing 16

14.9.2 Rectangle

The Rectangle() function draws a rectangle. The rectangle is outlined by using the
current pen and filled by using the current brush.
The rectangle is outlined using currently selected pen and filled using the
currently selected brush of n the window's device context.
BOOL Rectangle(
HDC hdc, // handle to DC
int nLeftRect, // x-coord of upper-left corner of rectangle
int nTopRect, // y-coord of upper-left corner of rectangle
int nRightRect, // x-coord of lower-right corner of rectangle
int nBottomRect // y-coord of lower-right corner of rectangle
);

14.9.3 Polygon

The Polygon() function draws a polygon consisting of two or more vertices connected by
straight lines. The polygon is outlined by using the current pen and filled by using the
current brush and polygon fill mode.
BOOL Polygon(
HDC hdc, // handle to DC
CONST POINT *lpPoints, // polygon vertices
int Count // count of polygon vertices
);

14.10 Stock Objects

Pre-defined GDI objects in Windows are:
Pens
Brushes
Fonts
Palettes

14.10.1 GetStockObject Function

The GetStockObject function retrieves a handle to one of the stock pens, brushes, fonts,
or palettes.

HGDIOBJ GetStockObject(
int
fnObject // stock object type

);

Painting and Drawing
17
fnObject: Specifies the type of stock object. This parameter can be one of the following
values.

Value Meaning

BLACK_BRUSH Black brush.
DKGRAY_BRUSH Dark gray brush.
DC_BRUSH Windows 2000/XP: Solid color brush. The default
color is white. The color can be changed by using
the SetDCBrushColor function. For more
information, see the Remarks section.
GRAY_BRUSH Gray brush.
HOLLOW_BRUSH Hollow brush (equivalent to NULL_BRUSH).
LTGRAY_BRUSH Light gray brush.
NULL_BRUSH Null brush (equivalent to HOLLOW_BRUSH).
WHITE_BRUSH White brush.
BLACK_PEN Black pen.
DC_PEN Windows 2000/XP: Solid pen color. The default
color is white. The color can be changed by using
the SetDCPenColor function. For more
information, see the Remarks section.
WHITE_PEN White pen.
ANSI_FIXED_FONT Windows fixed-pitch (monospace) system font.
ANSI_VAR_FONT Windows variable-pitch (proportional space)
system font.
DEVICE_DEFAULT_FONT Windows NT/2000/XP: Device-dependent font.
DEFAULT_GUI_FONT Default font for user interface objects such as
menus and dialog boxes. This is MS Sans Serif.
Compare this with SYSTEM_FONT.
OEM_FIXED_FONT Original equipment manufacturer (OEM) dependent
fixed-pitch (monospace) font.
SYSTEM_FONT System font. By default, the system uses the system
font to draw menus, dialog box controls, and text.

Windows 95/98 and Windows NT: The system
font is MS Sans Serif.
Windows 2000/XP: The system font is Tahoma
SYSTEM_FIXED_FONT Fixed-pitch (monospace) system font. This stock
object is provided only for compatibility with 16-bit
Windows versions earlier than 3.0.
DEFAULT_PALETTE Default palette. This palette consists of the static
colors in the system palette.
Painting and Drawing 18
Return Values: If the function succeeds, the return value is a handle to the requested
logical object. If the function fails, the return value is NULL.
Use the DKGRAY_BRUSH, GRAY_BRUSH, and LTGRAY_BRUSH stock objects
only in windows with the CS_HREDRAW and CS_VREDRAW styles. Using a gray
stock brush in any other style of window can lead to misalignment of brush patterns after
a window is moved or sized. The origins of stock brushes cannot be adjusted.
The HOLLOW_BRUSH and NULL_BRUSH stock objects are equivalent.
The font used by the DEFAULT_GUI_FONT stock object could change. Use this stock
object when you want to use the font that menus, dialog boxes, and other user interface
objects use.

14.11 SelectObject

The SelectObject function selects an object into the specified device context (DC). The
new object replaces the previous object of the same type.

HGDIOBJ SelectObject(
HDC
hdc, // handle to DC

HGDIOBJ hgdiobj // handle to object

);

hdc: Handle to the DC.
Hgdiobj: Handle to the object to be selected. The specified object must have been created
by using one of the following functions.

Object Functions

Bitmap Created by any bitmap function like CreateBitmap,
CreateCompatibleBitmap and CreateDIBSection etc.
(Bitmaps can be selected for memory DCs only, and for only one DC
at a time.)
Brush Created by CreateBrushIndirect or CreateSolidBrushFont Created by CreateFont function
Pen Created by CreatePen

Region Created by any region function e.g. CreatePolygonRgn,

CreateRectRgn, CreateRectRgnIndirect

Return Values: If the selected object is not a region and the function succeeds, the return
value is a handle to the object being replaced.
If an error occurs and the selected object is not a region, the return value is
NULL. Otherwise, it is HGDI_ERROR.
Painting and Drawing 19
This function returns the previously selected object of the specified type. An application
should always replace a new object with the original, default object after it has finished
drawing with the new object.
An application cannot select a bitmap into more than one DC at a time.

14.12 Example

SelectObject(hdc,GetStockObject(DC_PEN));
SetDCPenColor(hdc,RGB(00,0xff,00);
Rectangle(0,0,20,20);
SetDCPenColor(hdc,RGB(00,00,0xff));
Rectangle(0,0,20,20)
/* The brush color can be changed in a similar manner. SetDCPenColor
and SetDCBrushColor can be used interchangeably with GetStockObject
to change the current color.
*/
SelectObject(hDC,GetStockObject(DC_BRUSH));
SetDCBrushColor(hDC,0x0)
// Provides the same flexibility as:
SelectObject(hDC,GetStockOBject(BLACK_BRUSH));
// It is not necessary to call DeleteObject to delete stock objects.

Summary

In this lecture, we studied about painting in windows, for painting we used an
important message i.e. WM_PAINT. This message is always sent when windows need to
paint its portion or region that was previously invalidated. Windows paint only its region
when it become invalidates otherwise it is not sent WM_PAINT message. In some cases,
WM_PAINT messages are not sent—when menu drops down or small dialog boxes
appear. We also studied about invalidation and validation of a region. If region is
invalidated then it will be receiving WM_PAINT messages until it become validate.
At the end of the lecture we studied about sending and posting of messages. Messages
can be sent to windows procedure directly or it can be posted to message queue. All the
sent messages are not returned until the message is processed but the posted messages are
returned after posting the message in queue.

Tips

All GDI Objects create handles, these handles can be of bitmaps, regions, or fonts
handle. These handles must be deleted after using these objects. Keep it in mind and
make a practice to delete all the objects when they are left unused.
Painting and Drawing 20

Exercises

1. Create a round rectangular region and paint it using your own created
hatched brush. Also write the text which should be clipped to the region.
2. On pressing the mouse left button in region, region must show message

box, bearing text you have pressed mouse in region.

<Previous Lesson

Visual Programming

Next Lesson>

Home

Lesson Plan

Topics

Go to Top

Next Lesson
Previous Lesson
Lesson Plan
Topics
Home
Go to Top