Tricks of the Windows Game Programming Gurus:Advanced Windows Programming

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

Based on the resource script and header file (which must be included in the main app), let’s take a look at the code excerpts of `DEMO3_4.CPP` loading each resource. First, the loading of the main menu, icon, and cursor:

    winclass.hCursor = LoadCursor(hinstance,

                          MAKEINTRESOURCE(CURSOR_CROSSHAIR));

    winclass.lpszMenuName = "SoundMenu";

    winclass.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(ICON_T3DX));

    winclass.hIconSm= LoadIcon(hinstance, MAKEINTRESOURCE(ICON_T3DX));

And now the fun part—the processing of the `WM_COMMAND` message that plays each sound, along with the handling of the Exit menu item and the display of the About box under Help. For brevity, I’ll just show the `WM_COMMAND` message handler, since you’ve seen the entire `WinProc()` enough by now:

    case WM_COMMAND:

           {

           switch(LOWORD(wparam))

                 {

                 // handle the FILE menu

                 case MENU_FILE_ID_EXIT:

                 {

                 // terminate window

                 PostQuitMessage(0);

                 } break;

                 // handle the HELP menu

                 case MENU_HELP_ABOUT:

                 {

                 // pop up a message box

                 MessageBox(hwnd, "Menu Sound Demo",

                                  "About Sound Menu",

                                  MB_OK | MB_ICONEXCLAMATION);

                 } break;

                 // handle each of sounds

                 case MENU_PLAY_ID_ENERGIZE:

                 {

                 // play the sound

                 PlaySound(MAKEINTRESOURCE(SOUND_ID_ENERGIZE),

                           hinstance_app, SND_RESOURCE | SND_ASYNC);

                 } break;

                 case MENU_PLAY_ID_BEAM:

                 {

                 // play the sound

                 PlaySound(MAKEINTRESOURCE(SOUND_ID_BEAM),

                           hinstance_app, SND_RESOURCE | SND_ASYNC);

                 } break;

                 case MENU_PLAY_ID_TELEPORT:

                 {

                 // play the sound

                 PlaySound(MAKEINTRESOURCE(SOUND_ID_TELEPORT),

                            hinstance_app, SND_RESOURCE | SND_ASYNC);

                 } break;

                 case MENU_PLAY_ID_WARP:

                 {

                 // play the sound

                 PlaySound(MAKEINTRESOURCE(SOUND_ID_WARP),

                           hinstance_app, SND_RESOURCE | SND_ASYNC);

                 } break;

                 default: break;

                 } // end switch wparam

           } break; // end WM_COMMAND

And that’s all I have to say about that.

As you can see, resources can do a lot and are fun to work with. Now let’s take a break from resources and take an introductory crash course on the `WM_PAINT` message and basic GDI manipulation.

### Introduction to GDI

Thus far, the only experience you’ve had with GDI is the processing of the `WM_PAINT` message in the main event handler. Remember that GDI, or the Graphics Device Interface, is how all graphics are drawn under Windows when DirectX is not in use. Alas, you haven’t yet learned how to actually draw anything on the screen with GDI, but this is very key because rendering on the screen is one of the most important parts of writing a video game. Basically, a game is just logic that drives a video display. In this section, I’m going to revisit the `WM_PAINT` message, cover some basic video concepts, and teach you how to draw text within your window. The next chapter will focus more heavily on GDI.

Understanding the `WM_PAINT` message is very important for standard GDI graphics and Windows programming because most Windows programs’ displays revolve around this single message. In a DirectX game this isn’t true, because DirectX, or more specifically DirectDraw or Direct3D, will do the drawing, but you still need to know GDI to write Windows applications.

#### The WM_PAINT Message Once Again

The `WM_PAINT` message is sent to your window’s `WinProc()` whenever the window’s client area needs repainting. Until now, you haven’t done much processing on this event. Here’s the standard `WM_PAINT` handler you have been using:

    PAINTSTRUCT   ps;    // used in WM_PAINT

    HDC        hdc;   // handle to a device context

    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;

Refer to Figure 3.12 for the following explanation. When a window is moved, resized, or in some way graphically obscured by another window or event, some or all of the window’s client area must be redrawn. When this happens, a `WM_PAINT` message is sent and you must deal with it.

Figure 3.12 The `WM_PAINT` message.

In the case of the preceding code example, the calls to `BeginPaint()` and `EndPaint()` accomplish a couple of tasks. First, they validate the client area, and second, they fill the background of your window with the background brush defined in the Windows class that the window was originally created with.

Now, if you want to do your own graphics within the `BeginPaint()`—`EndPaint()` call, you can. However, there is one problem: You will only have access to the portion of the window’s client area that actually needs repainting. The coordinates of the invalid rectangle are stored in the `rcPaint` field of the `ps (PAINSTRUCT)` returned by the call to `BeginPaint()`:

    typedef struct tagPAINTSTRUCT

            {

            HDC hdc;         // graphics device context

            BOOL fErase;     // if TRUE then you must draw background

            RECT rcPaint;    // the RECT containing invalid region

            BOOL fRestore;   // internal

            BOOL fIncUpdate; // internal

            BYTE rgbReserved[32]; // internal

            } PAINTSTRUCT;

And to refresh your memory, here’s the definition of `RECT`:

    typedef struct _RECT

            {

            LONG left;   // left edge if rectangle

            LONG top;    // upper edge of rectangle

            LONG right;  // right edge of rectangle

            LONG bottom; // bottom edge of rectangle

            } RECT;

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.