Windows GDI Programming

advertisement
Windows GDI Programming
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
2
Processing WM_PAINT
• BeginPaint( ) … EndPaint( )
– Advantage: all needed validating done
automatically
– Disadvantage: invalid rectangle is same as
clipping rectangle (can’t 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( )
• Note: With either method you need to be sure
that windows does not fill in your Background
to avoid losing your drawing
4
Invalidating Entire Window
case WM_PAINT:
{
// NULL is pointer to invalid rectangle
// meaning entire window
ValidateRect(hwnd,NULL);
// simply validate the window
hdc = BeginPaint(hwnd,&ps);
// fixes go here
EndPaint(hwnd,&ps); // end painting
return(0); // return success
} break;
5
Validating Entire Window
case WM_PAINT:
{
// NULL is pointer to invalid rectangle
// meaning entire window
ValidateRect(hwnd,NULL);
// simply validate the window without
// doing any drawing
return(0); // return success
} break;
6
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;
7
Display Surface Basics
• Resolutions in pixels
640x480, 800x600, 1024x768, …
• Color depth (# color bits per pixel)
6, 16, 24, 32
• Color space (actual # available colors)
8 bits = 256 colors, 16 bits = 65536
8
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
• Complete control of pallets is best done
using DirectX
10
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
What about WM_PAINT?
case WM_PAINT:
{
// simply validate the window
hdc = BeginPaint(hwnd,&ps);
// you would do all your painting here
EndPaint(hwnd,&ps);
// return success
return(0);
} break;
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
• Set of values returned in fields of a parameter
of type tagTEXTMETRIC
17
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
Selecting and Destroying
Brushes
// select brush and save old brush
HBRUSH old_brush = SelectObject(hdc, red_brush);
// use the brush
// restore old brush
SelectObject(hdc, old_brush);
DeleteObject(red_brush);
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;
{
COLORREF color =
RGB(rand()%255,rand()%255,rand()%255);
SetPixel(hdc, x,y, color);
} // end for index
ReleaseDC(hwnd, hdc); // release the dc
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
Drawing Circles and Ellipses
• Circle is special case of ellipse
• To draw a circle at (100, 100) with diameter 20
Ellipse(hdc, 90, 90,110, 110);
• To draw an ellipse centered at (100, 100) with major
axis 100 and minor axis 60
Ellipse(hdc, 100-50, 100-30, 100+50, 100+30);
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
• We can make use of this trick and use
Ellipse to draw a bouncing ball
27
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));
// starting position of ball
int ball_x = WINDOW_WIDTH/2;
int ball_y = WINDOW_HEIGHT/2;
// initial velocity of ball
int xv = -4+rand() % 8;
int yv = -4+rand() % 8;
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;
29
} // end if
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
Download