Tricks of the Windows Game Programming Gurus:The Windows Programming Model

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

The difference is in the last parameter, which controls how the messages should be retrieved from the message queue. The valid flags for `wRemoveMsg` are

  • `PM_NOREMOVE`—Messages are not removed from the queue after processing by `PeekMessage()`.
  • `PM_REMOVE`—Messages are removed from the queue after processing by `PeekMessage()`.

Taking these two possibilities into consideration, you can do one of two things: Use `PeekMessage()` with `PM_NOREMOVE` and, ``if there is a message, call `GetMessage()`; or use `PM_REMOVE` and use `PeekMessage()` itself to retrieve a message if there is one. Use the latter. Here’s the core logic, changed to reflect this new technique in the main event loop:

    while(TRUE)

        {

        // test if there is a message in queue, if so get it

        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

           {

           // test if this is a quit

              if (msg.message == WM_QUIT)

                 break;

           // translate any accelerator keys

           TranslateMessage(&msg);

           // send the message to the window proc

           DispatchMessage(&msg);

           } // end if

           // main game processing goes here

           Game_Main();

        } // end while

I’ve highlighted important points in the code. The first section in bold is

    if (msg.message == WM_QUIT) break;

This is how you must detect to bail out of the infinite `while(TRUE)` loop. Remember, when a `WM_DESTROY` message is processed in the WinProc, it’s your job to send a `WM_QUIT` message via the call to `PostQuitMessage()`. The `WM_QUIT` then trickles through the event queue, and you can detect it so you can bail out of the main loop.

The last section of highlighted code simply indicates where you would put the call to your main game code loop. But remember, the call to `Game_Main()`—or whatever you call it—must return after one frame of animation or game logic. Otherwise, messages won’t be processed by the main Windows event loop.

For an example of this new real-time structure that is more appropriate for game logic processing, take a look at the source `DEMO2_4.CPP` and the associated `DEMO2_4.EXE` on the CD-ROM. This structure will in fact be our model for the remainder of the book.

### Opening More Windows

Before finishing up this chapter, I want to cover one more quick topic that you might be wondering about—how do you open more than one window. Actually, this is trivial, and you already know how to do it. All you need to do is make two or more calls to `CreateWindowEx()` to create the windows, and that’s it. However, there are some caveats to this.

First, remember that when you create a window, it’s based on a Windows class. This class, among other things, defines the WinProc or event handler for the entire class. This is a very important detail, so pay attention. You can make as many windows as you want with the same class, but all the messages for them will be sent to the same WinProc, as defined by the event handler pointed to by the `lpfnWndProc` field of the `WINCLASSEX` structure. To see this, take a look at Figure 2.11. It depicts the message flow in this case.

Figure 2.11 The message flow for multiple windows with the same Windows class.

This may or may not be want you want. If you want a different WinProc for each window, you must create more than one Windows class and create each window with a different class. Hence, a different WinProc is sent messages for each class window. Figure 2.12 shows this setup.

Figure 2.12 Multiple Windows classes with multiple windows.

With that in mind, here’s the code to create two windows based on the same class:

    // create the first window

    if (!(hwnd = CreateWindowEx(NULL,                  // extended style

                    WINDOW_CLASS_NAME,     // class

                    "Window 1 Based on WINCLASS1", // title

                    WS_OVERLAPPEDWINDOW | WS_VISIBLE,

                     0,0,      // initial x,y

                    400,400,  // initial width, height

                    NULL,     // handle to parent

                    NULL,     // handle to menu

                    hinstance,// instance of this application

                    NULL)))   // extra creation parms

    return(0);

    // create the second window

    if (!(hwnd = CreateWindowEx(NULL,                  // extended style

                   WINDOW_CLASS_NAME,     // class

                    "Window 2 Also Based on WINCLASS1", // title

                    WS_OVERLAPPEDWINDOW | WS_VISIBLE,

                     100,100,  // initial x,y

                    400,400,  // initial width, height

                    NULL,     // handle to parent

                    NULL,     // handle to menu

                    hinstance,// instance of this application

                    NULL)))   // extra creation parms

    return(0);

Of course, you might want to track each window handle in different variables rather than the same one, as is the case with `hwnd`, but you get the idea. For an example of opening two windows at once, take a look at `DEMO2_5.CPP` and the associated executable, `DEMO2_5.EXE`. When you run the `.EXE`, you should see something like Figure 2.13. Notice that when you close either window, they both close and the application terminates. See if you can figure out a way to close only one window at a time. (Hint: Create two Windows classes, and don’t send a `WM_QUIT` message until both windows have been closed.)

Figure 2.13 The multiple-window program `DEMO2_5.EXE`.

### Summary

I don’t know about you, but I’m really excited! At this point, you have everything you need to start understanding much more complex Windows programming. You know about the architecture of Windows and multitasking, and you know how to create Window classes, register classes, create windows, write event loops and handlers, and a lot more! So pat yourself on the back (or, for my alien readers, lick your eyeballs). You have done a most excellent job <BG>.

In the next chapter, we’re going to cover some more Windows-related stuff, like using resources, creating menus, working with dialogs, and getting information.

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.