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

As an example, let’s create three pens, each 1 pixel wide, with solid style:

    // the red pen, notice the use of the RGB macro

    HPEN red_pen = CreatePen(PS_SOLID, 1, RGB(255,0,0));

    // the green pen, notice the use of the RGB macro

    HPEN green_pen = CreatePen(PS_SOLID, 1, RGB(0,255,0));

    // the blue pen, notice the use of the RGB macro

    HPEN blue_pen = CreatePen(PS_SOLID, 1, RGB(0,0,255));

And let’s also make a white dashed pen:

    HPEN white_dashed_pen = CreatePen(PS_DASHED, 1, RGB(255,255,255));

Simple enough? Now, that we have a little to work with, let’s take a look at how to select pens into the graphics device context. We still don’t know how to draw anything, but now is a good time to see the concept.

To select any GDI object into the graphics device context use the `SelectObject()` function shown here:

    HGDIOBJ SelectObject(HDC hdc,          // handle of device context

                         HGDIOBJ hgdiobj); // handle of object

`SelectObject()` takes the handle to the graphics context along with the object to be selected. Notice that `SelectObject()` is polymorphic, meaning that it can take many different handle types. The reason for this is that all handles to graphics objects are also subclasses of the data type HGDIOBJs (handles to GDI objects), so everything works out. Also, the function returns the current handle of the object you are de-selecting from the context. In other words, if you select a new pen into the context, obviously you must select the old one out. Therefore, you can save the old handle and restore it later if you wish. Here’s an example of selecting a pen into the context and saving the old one:

    HDC hdc; // the graphics context, assume valid

    // create the blue

    HPEN blue_pen = CreatePen(PS_SOLID, 1, RGB(0,0,255));

    HPEN old_pen = NULL; // used to store old pen

    // select the blue pen in and save the old pen

    old_pen = SelectObject(hdc, blue_pen);

    // do drawing…

    // restore the old pen

    SelectObject(hdc, old_pen);

And then finally, when you are done with pens that you have created either with `GetStockObject()` or `CreatePen()`, you must destroy them. This is accomplished with `DeleteObject()`, which, similar to `SelectObject()`, is polymorphic and can delete many object types. Here’s its prototype:

    BOOL DeleteObject(HGDIOBJ hObject); // handle to graphic object

> Warning: Be careful when you destroy pens. If you delete an object that is currently selected or try to select an object that is currently deleted chances are you will cause an error and possibly a GP Fault.

> Note: I haven’t been doing too much error checking, but obviously this is an issue. In a real program, you should always check the return type of your function calls to see if they are successful; otherwise, there could be trouble.

The next question is when to actually call `DeleteObject()` on graphics objects. Typically, you will do this at the end of the program. However, if you create hundreds of objects, use them, and won’t use them for the remainder of the program, you should delete them then and there. This is because Windows GDI only has limited resources. As an example, here’s how to release and destroy the group of pens we created in the earlier example:

    DeleteObject(red_pen);

    DeleteObject(green_pen);

    DeleteObject(blue_pen);

    DeleteObject(white_dashed_pen);

> Warning: Try not to delete objects you have already deleted. It can cause unpredictable results.

#### Painting with Brushes

Let’s talk more about brushes. Brushes are similar to pens in most ways except how they look. Brushes are used to fill in graphic objects, whereas pens are used to outline objects or draw simple lines. However, all the same principles are in flux. The handle to a brush is called an `HBRUSH`. And to define a blank brush object you would do something like:

    HBRUSH brush_1 = NULL;

To actually make the brush look like something you can either use a stock brush type from Table 4.1 via `GetStockObject()` or define one yourself. For example, here’s how to create a light gray stock brush:

    brush_1 = GetStockObject(LTGRAY_BRUSH);

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.