Professional Documents
Culture Documents
CIS 487/587
Bruce R. Maxim
UM-Dearborn
1
Validating
Whenever either you or Windows disturbs a
window a WM_PAINT message is sent
The area to be repainted is the invalid
rectangle
The coordinates of the invalid rectangle are
shipped with the WM_PAINT message as part
of the validating process
Processing WM_PAINT
BeginPaint( ) EndPaint( )
Advantage: all needed validating done
automatically
Disadvantage: invalid rectangle is same as
clipping rectangle (cant draw outside
invalid rectangle)
This approach fools Windows into believing
you fixed the invalid rectangle whether you
have drawn anything or not
3
Processing WM_PAINT
GetDC( ) ReleaseDC( )
Advantage:you can draw outside the invalid
rectangle
Disadvantage: you need to validate every
rectangle manually using ValidateRect( )
Avoid Repaint
case WM_PAINT:
{
hdc = GetDC(hwnd);
// do graphics here
ReleaseDC(hwnd,hdc);
// validate the window to clear message
ValidateRect(hwnd,hdc);
return(0); // return success
} break;
Display Modes
RGB mode
True RGB values are encoded for each
pixel displayed
Palletized mode
Color indirection scheme
256 colors available
Value 0 to 255 is stored with each pixel
Color value looked up in CLUT
9
Color Objects
Windows uses to data structures
COLOREF: byte structure allows you to
create colors on the fly
PALETTEENTRY: all creation of pallets
with control flag components
Drawing Text
TextOut( )
No formatting or processing of text string is
done before it is displayed
DrawText( )
Allows justification, clipping, etc. prior to
displaying text string
11
LaMothe Examples
12
TextOut Example
main_window_handle = hwnd; // save main window handle
HDC hdc = GetDC(hwnd);
// get the dc and hold it
// set the foreground color to random
SetTextColor(hdc, RGB(rand()%256,rand()%256,rand()%256));
// set the background color to black
SetBkColor(hdc, RGB(0,0,0));
// finally set the transparency mode to transparent
SetBkMode(hdc, TRANSPARENT);
// draw some text at a random location
TextOut(hdc,rand()%400,rand()%400,
"GDI Text Demo!", strlen("GDI Text Demo!"));
ReleaseDC(hwnd,hdc);
// release the dc
13
14
Additional Issues
You should consider saving the old
values for foreground, ground, and
transparency so that you can restore
them after you set them
Example we might declare the following:
COLORREF old_fcolor, // old foreground
old_bcolor; // old background
int old_tmode;
// old transparency
15
TextOut Example 2
main_window_handle = hwnd; // save main window handle
HDC hdc = GetDC(hwnd);
// get the dc and hold it
// save old attributes and set new
old_fcolor = SetTextColor(hdc,RGB(255,255,255));
old_bcolor = SetBkColor(hdc, RGB(0,0,0));
old_tmode= SetBkMode(hdc, TRANSPARENT);
// draw some text at a random location
TextOut(hdc, 120, 200, Hello", strlen(Hello"));
// Restore the old values
SetTextColor(hdc, old_fcolor);
SetBkColor(hdc, old_bcolor);
SetBkMode(hdc, old_tmode);
ReleaseDC(hwnd,hdc);
// release the dc
16
Text Metrics
The function GetTextMetrics can be used to
query the system for things like
Font height
Average width
Max width
First character defined in font
Last character defined in font
Drawing Shapes
GDI allows you to draw things like
Points
Lines
Circles and ellipses
Rectangles
Curves
Polygons
Bitmaps
Metafiles (instructions that can be replayed)
18
Pens
Pens are GDI objects used to draw lines
Pens have two attributes
RGB color
Styles like
PS_DASH
---PS_DOT
....
PS_DASHDOT _ . _ .
PS_NULL
19
Using a Pen
// get the graphics device context
hdc = GetDC(hwnd);
// create a red colored pen
HPEN red_pen = CreatePen(PS_SOLID,1,RGB(255, 0, 0));
// selecting pen and saving old value
HPEN old_hpen = (HPEN)SelectObject(hdc,red_pen);
// draw with pen
// deleting pen
SelectObject(hdc,old_hpen);
DeleteObject(red_ pen);
// release the device context
ReleaseDC(hwnd,hdc)
20
Brushes
Brushes are used to fill in line objects
Examples
// creating a solid brush
HBRUSH blue_brush = CreateSolidBrush(RGB(0,0,255));
// creating a patterned brush
HBRUSH green_brush =
CreateHatchBrush(HS_DIAGCROSS, RGB(0,255,0));
// creating a bitmap brush (8x8)
HBRUSH bitmap_brush =
CreatePatternBrush(hBitMap);
21
22
Plotting Points
hdc = GetDC(hwnd); // get the dc for the window
// draw 1000 pixels
for (int index=0; index < 1000; index++)
// get random position
int x = rand()%400;
int y = rand()%300;
23
Drawing Lines
// create pen
HPEN red_pen = CreatePen(PS_SOLID,1,RGB(255, 0, 0));
// selecting pen and saving old value
SelectObject(hdc,red_pen);
// move to starting point
MoveToEx(hdc,rand()%WINDOW_WIDTH,rand()%WINDOW_HEIGHT,NULL);
// draw the line
LineTo(hdc,rand()%WINDOW_WIDTH,rand()%WINDOW_HEIGHT);
24
Drawing Rectangles
hdc = GetDC(hwnd); // get the graphics device context
RECT rect; // used to hold rect info
// create a random rectangle
rect.left
= rand()% WINDOW_WIDTH;
rect.top
= rand()% WINDOW_HEIGHT;
rect.right = rand()% WINDOW_WIDTH;
rect.bottom = rand()% WINDOW_HEIGHT;
// create a random brush
HBRUSH hbrush = CreateSolidBrush(RGB(100, 50, 80));
// draw either a filled rect or a wireframe rect
if ((rand()%2)==1)
FillRect(hdc,&rect,hbrush);
else
FrameRect(hdc,&rect,hbrush);
DeleteObject(hbrush); // now delete the brush
ReleaseDC(hwnd,hdc);// release the device context
25
26
Bouncing Ball
An old computer animators trick is to
Draw an object using the foreground color
Erase object by redrawing in the
background color
Change the object screen coordinates and
draw again in the foreground color
Bouncing Ball
hdc = GetDC(hwnd);
// create the pens
HPEN
white_pen =
HPEN
black_pen =
HBRUSH green_brush
HBRUSH black_brush
and brushes
CreatePen(PS_SOLID, 1, RGB(255,255,255));
CreatePen(PS_SOLID, 1, RGB(0,0,0));
= CreateSolidBrush(RGB(0,255,0));
= CreateSolidBrush(RGB(0,0,0));
28
Bouncing Ball
// ERASE the last position of the ball
// first select the black pen and brush into context
SelectObject(hdc, black_pen);
SelectObject(hdc, black_brush);
// draw the ball
Ellipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);
// MOVE the ball
ball_x+=xv;
ball_y+=yv;
// test for collisions, first x-axis
if (ball_x < 0 || ball_x > WINDOW_WIDTH - 32)
{
// invert x-velocity of ball
xv=-xv;
// push ball back
ball_x+=xv;
} // end if
else
// test for y-axis collisions
if (ball_y < 0 || ball_y > WINDOW_HEIGHT - 32)
{
// invert y-velocity of ball
yv=-yv;
// push ball back
ball_y+=yv;
} // end if
// now select the green and white colors for brush and pen
SelectObject(hdc, white_pen);
SelectObject(hdc, green_brush);
// DRAW the ball
Ellipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);
// main game processing goes here
if (KEYDOWN(VK_ESCAPE))
SendMessage(hwnd, WM_CLOSE, 0,0);
// slow system down a little
Sleep(10);
} // end while
// delete all the objects
DeleteObject(white_pen);
DeleteObject(black_pen);
DeleteObject(green_brush);
DeleteObject(black_brush);
// release the device context
ReleaseDC(hwnd,hdc);
29
Bouncing Ball
// ERASE the last position of the ball
// first select the black pen and brush into context
SelectObject(hdc, black_pen);
SelectObject(hdc, black_brush);
// draw the ball
Ellipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);
// MOVE the ball
ball_x+=xv;
ball_y+=yv;
30
Bouncing Ball
// test for collisions, first x-axis
if (ball_x < 0 || ball_x > WINDOW_WIDTH - 32)
{
xv=-xv;
// invert x-velocity of ball
ball_x+=xv;
// push ball back
} // end if
else
// test for y-axis collisions
if (ball_y < 0 || ball_y > WINDOW_HEIGHT - 32)
{
yv=-yv;
// invert y-velocity of ball
ball_y+=yv;
// push ball back
} // end if
31
Bouncing Ball
// select the green and white colors for brush and pen
SelectObject(hdc, white_pen);
SelectObject(hdc, green_brush);
// DRAW the ball
Ellipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);
DeleteObject(white_pen); // delete all the objects
DeleteObject(black_pen);
DeleteObject(green_brush);
DeleteObject(black_brush);
ReleaseDC(hwnd,hdc); // release the device context
32