14.1 PAINTING IN A WINDOW 2
14.1.1 WHEN
TO DRAW
IN A WINDOW
3
14.1.2 THE
WM_PAINT MESSAGE
3
14.1.3 DRAWING
WITHOUT
THE WM_PAINT MESSAGE
4
14.1.4 WINDOW
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 STRUCTURE
8
14.8 OTHER GDI TEXT OUTPUT FUNCTIONS 9
14.8.1 DRAWTEXT
9
14.8.2 TABBEDTEXTOUT
14
14.9 PRIMITIVE SHAPES 15
14.9.1 LINES
15
14.9.2 RECTANGLE
16
14.9.3 POLYGON
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.
|