Top Banner
1 Windows GDI Programming CIS 487/587 Bruce R. Maxim UM-Dearborn
32
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • Windows GDI ProgrammingCIS 487/587Bruce R. MaximUM-Dearborn

  • ValidatingWhenever either you or Windows disturbs a window a WM_PAINT message is sentThe area to be repainted is the invalid rectangleThe coordinates of the invalid rectangle are shipped with the WM_PAINT message as part of the validating process

  • Processing WM_PAINTBeginPaint( ) EndPaint( )Advantage: all needed validating done automaticallyDisadvantage: 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

  • Processing WM_PAINTGetDC( ) 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

  • Invalidating Entire Windowcase 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;

  • Validating Entire Windowcase 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;

  • Avoid Repaintcase 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 Surface BasicsResolutions in pixels

    640x480, 800x600, 1024x768, Color depth (# color bits per pixel)

    6, 16, 24, 32Color space (actual # available colors)

    8 bits = 256 colors, 16 bits = 65536

  • Display ModesRGB modeTrue RGB values are encoded for each pixel displayedPalletized modeColor indirection scheme256 colors availableValue 0 to 255 is stored with each pixelColor value looked up in CLUT

  • Color ObjectsWindows uses to data structuresCOLOREF: byte structure allows you to create colors on the flyPALETTEENTRY: all creation of pallets with control flag componentsComplete control of pallets is best done using DirectX

  • Drawing TextTextOut( )No formatting or processing of text string is done before it is displayedDrawText( )Allows justification, clipping, etc. prior to displaying text string

  • LaMothe Examples

  • TextOut Examplemain_window_handle = hwnd; // save main window handleHDC hdc = GetDC(hwnd); // get the dc and hold it

    // set the foreground color to randomSetTextColor(hdc, RGB(rand()%256,rand()%256,rand()%256));// set the background color to blackSetBkColor(hdc, RGB(0,0,0));// finally set the transparency mode to transparentSetBkMode(hdc, TRANSPARENT);

    // draw some text at a random locationTextOut(hdc,rand()%400,rand()%400, "GDI Text Demo!", strlen("GDI Text Demo!"));

    ReleaseDC(hwnd,hdc); // release the dc

  • What about WM_PAINT?case WM_PAINT: {// simply validate the windowhdc = BeginPaint(hwnd,&ps); // you would do all your painting here EndPaint(hwnd,&ps); // return successreturn(0);} break;

  • Additional IssuesYou should consider saving the old values for foreground, ground, and transparency so that you can restore them after you set themExample we might declare the following:

    COLORREF old_fcolor, // old foreground old_bcolor; // old backgroundint old_tmode; // old transparency

  • TextOut Example 2main_window_handle = hwnd; // save main window handleHDC hdc = GetDC(hwnd); // get the dc and hold it// save old attributes and set newold_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 locationTextOut(hdc, 120, 200, Hello", strlen(Hello"));// Restore the old valuesSetTextColor(hdc, old_fcolor);SetBkColor(hdc, old_bcolor);SetBkMode(hdc, old_tmode);ReleaseDC(hwnd,hdc); // release the dc

  • Text MetricsThe function GetTextMetrics can be used to query the system for things likeFont heightAverage widthMax widthFirst character defined in fontLast character defined in fontSet of values returned in fields of a parameter of type tagTEXTMETRIC

  • Drawing ShapesGDI allows you to draw things likePointsLinesCircles and ellipsesRectanglesCurvesPolygonsBitmapsMetafiles (instructions that can be replayed)

  • PensPens are GDI objects used to draw linesPens have two attributesRGB colorStyles likePS_DASH - - - -PS_DOT . . . .PS_DASHDOT _ . _ . PS_NULL

  • 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)

  • BrushesBrushes are used to fill in line objectsExamples

    // creating a solid brushHBRUSH blue_brush = CreateSolidBrush(RGB(0,0,255));// creating a patterned brushHBRUSH green_brush = CreateHatchBrush(HS_DIAGCROSS, RGB(0,255,0));// creating a bitmap brush (8x8)HBRUSH bitmap_brush = CreatePatternBrush(hBitMap);

  • Selecting and Destroying Brushes// select brush and save old brushHBRUSH old_brush = SelectObject(hdc, red_brush);

    // use the brush

    // restore old brushSelectObject(hdc, old_brush);DeleteObject(red_brush);

  • Plotting Pointshdc = GetDC(hwnd); // get the dc for the window

    // draw 1000 pixelsfor (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

  • 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 pointMoveToEx(hdc,rand()%WINDOW_WIDTH,rand()%WINDOW_HEIGHT,NULL);// draw the lineLineTo(hdc,rand()%WINDOW_WIDTH,rand()%WINDOW_HEIGHT);

  • Drawing Rectangleshdc = GetDC(hwnd); // get the graphics device context RECT rect; // used to hold rect info// create a random rectanglerect.left = rand()% WINDOW_WIDTH; rect.top = rand()% WINDOW_HEIGHT;rect.right = rand()% WINDOW_WIDTH;rect.bottom = rand()% WINDOW_HEIGHT;// create a random brushHBRUSH hbrush = CreateSolidBrush(RGB(100, 50, 80));// draw either a filled rect or a wireframe rectif ((rand()%2)==1) FillRect(hdc,&rect,hbrush);else FrameRect(hdc,&rect,hbrush);DeleteObject(hbrush); // now delete the brushReleaseDC(hwnd,hdc);// release the device context

  • Drawing Circles and EllipsesCircle is special case of ellipseTo 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);

  • Bouncing BallAn old computer animators trick is to Draw an object using the foreground colorErase object by redrawing in the background colorChange the object screen coordinates and draw again in the foreground colorWe can make use of this trick and use Ellipse to draw a bouncing ball

  • Bouncing Ballhdc = GetDC(hwnd);// create the pens and brushesHPEN white_pen = CreatePen(PS_SOLID, 1, RGB(255,255,255));HPEN black_pen = CreatePen(PS_SOLID, 1, RGB(0,0,0));HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0));HBRUSH black_brush = CreateSolidBrush(RGB(0,0,0));

    // starting position of ballint ball_x = WINDOW_WIDTH/2;int ball_y = WINDOW_HEIGHT/2;

    // initial velocity of ballint xv = -4+rand() % 8;int yv = -4+rand() % 8;

  • Bouncing Ball// ERASE the last position of the ball// first select the black pen and brush into contextSelectObject(hdc, black_pen);SelectObject(hdc, black_brush);// draw the ballEllipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);// MOVE the ballball_x+=xv;ball_y+=yv;// test for collisions, first x-axisif (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 objectsDeleteObject(white_pen);DeleteObject(black_pen);DeleteObject(green_brush);DeleteObject(black_brush);// release the device contextReleaseDC(hwnd,hdc);

  • Bouncing Ball// ERASE the last position of the ball

    // first select the black pen and brush into contextSelectObject(hdc, black_pen);SelectObject(hdc, black_brush);

    // draw the ballEllipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);

    // MOVE the ballball_x+=xv;ball_y+=yv;

  • Bouncing Ball// test for collisions, first x-axisif (ball_x < 0 || ball_x > WINDOW_WIDTH - 32) { xv=-xv; // invert x-velocity of ball ball_x+=xv; // push ball back } // end ifelse // 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

  • Bouncing Ball// select the green and white colors for brush and penSelectObject(hdc, white_pen);SelectObject(hdc, green_brush);

    // DRAW the ballEllipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);

    DeleteObject(white_pen); // delete all the objectsDeleteObject(black_pen); DeleteObject(green_brush);DeleteObject(black_brush);

    ReleaseDC(hwnd,hdc); // release the device context