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

Trivial, ooh, trivial! For an example of mouse tracking, take a look at `DEMO3_13.CPP` on the CD-ROM and the associated executable. The program prints out the position of the mouse and the state of the buttons using the preceding code as a starting point. Take note of how the button changes only when the mouse is moving. This is as you would expect because the message is sent when the mouse moves rather than when the buttons are pressed.

Now for some details. The `WM_MOUSEMOVE` is not guaranteed to be sent all the time. You may move the mouse too quickly for it to track. Therefore, don’t assume that you’ll be able to track individual mouse movements that well—for the most part, it’s not a problem, but keep it in mind. Also, you should be scratching your head right now, wondering how to track if a mouse button was pressed without a mouse move. Of course, there is a whole set of messages just for that. Take a look at Table 3.10.

Table 3.10 Mouse Button Messages

Message | Description
--- | ---

`WM_LBUTTONDBLCLK` | The left mouse button was double-clicked.
`WM_LBUTTONDOWN` | The left mouse button was pressed.
`WM_LBUTTONUP` | The left mouse button was released.
`WM_MBUTTONDBLCLK` | The middle mouse button was double-clicked.
`WM_MBUTTONDOWN` | The middle mouse button was pressed.
`WM_MBUTTONUP` | The middle mouse button was released.
`WM_RBUTTONDBLCLK` | The right mouse button was double-clicked.
`WM_RBUTTONDOWN` | The right mouse button was pressed.
`WM_RBUTTONUP` | The right mouse button was released.

The button messages also have the position of the mouse encoded just as they were for the `WM_MOUSEMOVE` message—in the `wparam` and `lparam`. For example, to test for a left button double-click, you would do this:

    case WM_LBUTTONDBLCLK:

         {

         // extract x,y and buttons

         int mouse_x = (int)LOWORD(lParam);

         int mouse_y = (int)HIWORD(lParam);

         // do something intelligent

         // tell windows you handled it

         return(0);

         } // break;

Killer! I feel powerful, don’t you? Windows is almost at our feet!

### Sending Messages Yourself

The last subject I want to talk about is sending messages yourself. There are two ways to do this:

  `SendMessage()`—Sends a message to the window immediately for processing. The function returns after the `WinProc()` if the receiving window has processed the message.
  `PostMessage()`—Sends a message to the window’s message queue and returns immediately. Use this if you don’t care if there’s a delay until your message is processed, or your message is a low priority.

The prototypes for both functions are similar, as shown here:

    LRESULT SendMessage(HWND hWnd, // handle of destination window

                        UINT Msg, // message to send

                        WPARAM wParam,  // first message parameter

                        LPARAM lParam); // second message parameter

The return value of `SendMessage()` is the value returned by the `WinProc()` of the window you sent it to.

    BOOL PostMessage(HWND hWnd, // handle of destination window

                     UINT Msg, // message to post

                     WPARAM wParam,  // first message parameter

                     LPARAM lParam ); // second message parameter

If `PostMessage()` is successful, it returns a nonzero value. Notice that this is different than `SendMessage()`. Why? Because `SendMessage()` actually calls the `WinProc()`, whereas `PostMessage()` simply places a message in the message queue of the receiving window without any processing.

You might be wondering why you would ever want to send a message yourself. There are millions of reasons—literally. This is something that the designers of Windows want you to do, and it’s how you make things happen in a windowed environment. For example, in the next chapter, when I talk about window controls like buttons, sending messages is the only way to talk to a control window! But if you’re like me, you like something a little more concrete.

In all of the demos thus far, you’ve terminated them by double-clicking the close box or pressing Alt+F4. Wouldn’t be nice if you could programmatically kill the window?

You know that either a `WM_CLOSE` or `WM_DESTROY` will do the job. If you use `WM_CLOSE`, it gives your application a little warning, whereas `WM_DESTROY` is a little tighter. But either way you go, you just do something like this:

    SendMessage(hwnd, WM_DESTROY,0,0);

Or if you want a little delay and don’t mind if your message is queued, use `PostMessage()`:

    PostMessage(hwnd, WM_DESTROY,0,0);

In both cases, the application will terminate—unless there is steering logic in the `WM_DESTROY` handler, of course. But the next question is when to launch the message. Well, that’s up to you. In a game, you might track the Esc key and exit on that. Here’s how you would do that using the `KEYDOWN()` macro in the main event loop:

    if (KEYDOWN(VK_ESCAPE)

        SendMessage(hwnd,WM_CLOSE,0,0);

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.