Tricks of the Windows Game Programming Gurus:Windows GDI, Controls, and Last-Minute Gift Ideas

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

Bam, baby! Too easy, huh? To create more interesting brushes you can select the fill pattern type and color just as you can for pens. Unfortunately GDI broke brushes up into two classes: solid and hatched. I think this is stupid—GDI should allow all brushes to be hatched and then simply have a solid type, but whatever! The function to create a solid fill brush is called `CreateSolidBrush()` and is shown here:

    HBRUSH CreateSolidBrush(COLORREF crColor); // brush color

To create a green solid brush all you have to do is this:

    HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0));

To select it into the graphics device context, do this:

    HBRUSH old_brush = NULL;

    old_brush = SelectObject(hdc, green_brush);

    // draw something with brush

    // restore old brush

    SelectObject(hdc, old_brush);

At the end of your program you would delete the brush object like this:

    DeleteObject(green_brush);

Starting to all make sense? In a nutshell, you create an object, select it, use it, delete it. Okay, let’s next see how to create patterned or hatched brushes.

To create a hatch brush, use the `CreateHatchBrush()` function shown here:

    HBRUSH CreateHatchBrush(int fnStyle,      // hatch style

                            COLORREF clrref); // color value

The style of the brush can be one of the values listed in Table 4.3.

Table 4.3 Style Values for `CreateHatchBrush()`

Value | Description
--- | ---

`HS_BDIAGONAL` | 5-degree downward left-to-right hatch
`HS_CROSS` | Horizontal and vertical crosshatch
`HS_DIAGCROSS` | 45-degree crosshatch
`HS_FDIAGONAL` | 45-degree upward left-to-right hatch
`HS_HORIZONTAL` | Horizontal hatch
`HS_VERTICAL` | Vertical hatch

As a final example of brushes, let’s create a cross-hatched red brush:

    HBRUSH red_hbrush = CreateHatchBrush(HS_CROSS, RGB(255,0,0));

Select it into the device context:

    HBRUSH old_brush = SelectObject(hdc, red_hbrush);

Finally, restore the old brush and delete the red brush we created:

    SelectObject(hdc, old_brush);

    DeleteObject(red_hbrush);

Of course, we still aren’t doing anything with the pens or brushes, but we will <BG>.

### Points, Lines, Polygons, and Circles

Now that you have the concept of pens and brushes under your belt, it’s time to see how these entities are used in real programs to draw objects. Let’s start with the simplest of all graphic objects—the point.

#### Straight to the Point

Drawing points with GDI is trivial and doesn’t require a pen or a brush. That’s because a point is a single pixel and selecting a pen or brush wouldn’t have much of an effect. To draw a point within the client area of your window, you need the HDC to your window along with the coordinates and the color you wish to draw it with. However, you don’t need to select the color or anything like that—you simply make a function call to `SetPixel()` with all this information. Take a look:

    COLORREF SetPixel(HDC hdc, // the graphics context

                      int x,   // x-coordinate

                      int y,   // y-coordinate

                      COLORREF crColor); // color of pixel

The function takes the HDC to the window along with the (x,y) coordinate and the color. The function then plots the pixel and returns the color actually plotted. You see, if you are in a 256 color mode and request an RGB color that doesn’t exist, GDI will plot a closest match to the color for you, and either way return the RGB color that was actually plotted. If you’re a little uneasy about the exact meaning of the (x,y) coordinates that you send the function, take a look at Figure 4.2. The figure depicts a window and the coordinate system that Windows GDI uses, which is an inverted Quadrant I Cartesian system—meaning that the x increases from right to left and y increases from top to bottom.

Figure 4.2 Windows coordinates in relation to standard Cartesian coordinates.

Technically, GDI has other mapping modes, but this is the default and the one to use for all GDI and DirectX. Notice that the origin (0,0) is in the upper-left corner of the window’s client area. It’s possible to get an HDC for the entire window with `GetWindowDC()` rather than `GetDC()`. The difference is that if you use `GetWindowDC()` to retrieve an HDC, the graphics device context is for the whole window. With an HDC retrieved with `GetDC()`, you can draw over everything including the window controls, not just the client area. Here’s an example of drawing 1000 randomly positioned and colored pixels on a window that we know is 400×400:

    HWND hwnd; // assume this is valid

    HDC hdc;   // used to access window

    // get the dc for the window

    hdc = GetDC(hwnd);

    for (int index=0; index<1000; index++)

        {

        // get random position

        int x = rand()%400;

        int y = rand()%400;

        COLORREF color = RGB(rand()%255,rand()%255,rand()%255));

        SetPixel(hdc, x,y, color);

        } // end for index

As an example of plotting pixels, take a look at `DEMO4_1.CPP` and `DEMO4_1.EXE`. They illustrate the preceding code, but in a continuous loop. Figure 4.3 is a screen shot of the program running.

Figure 4.3 Demo of pixel plotting program `DEMO4_1.EXE`.

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.