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

The solution used in Windows was to virtualize the real scan codes to virtual scan code with a lookup table. As programmers, we use the virtual scan codes and let Windows do the translation. Thanks, Windows! With that in mind, here are the details of the `WM_KEYDOWN` message:

Message: `WM_KEYDOWN`

`wparam`—Contains the virtual key code of the key pressed. Table 3.8 contains a list of the most common keys that you might be interested in.

`lparam`—Contains a bit-encoded state vector that describes other special control keys that may be pressed. The bit encoding is shown in Table 3.8.

Table 3.8 Virtual Key Codes

Symbol | Value (hexadecimal) | Description
--- | --- | ---

`VK_BACK` | 08 | Backspace key
`VK_TAB` | 09 | Tab key
`VK_RETURN` | 0D | Enter key
`VK_SHIFT` | 10 | Shift key
`VK_CONTROL` | 11 | Ctrl key
`VK_PAUSE` | 13 | Pause key
`VK_ESCAPE` | 1B | Esc key
`VK_SPACE` | 20 | Spacebar
`VK_PRIOR` | 21 | Page Up key
`VK_NEXT` | 22 | Page Down key
`VK_END` | 23 | End key
`VK_HOME` | 24 | Home key
`VK_LEFT` | 25 | Left-arrow key
`VK_UP` | 26 | Up-arrow key
`VK_RIGHT` | 27 | Right-arrow key
`VK_INSERT` | 2D | Ins key
`VK_DELETE` | 2E | Del key
`VK_HELP` | 2F | Help key
No `VK_`Code | 30–39 | 0–9 keys
No `VK_`Code | 41–5A | A–Z keys
`VK_F1 - VK_F12` | 70–7B | F1–F12 keys

Note: The keys A–Z and 0–9 have no `VK_` codes. You must use the numeric constants or define your own.

In addition to the `WM_KEYDOWN` message, there is `WM_KEYUP`. It has the same parameterization—that is, `wparam` contains the virtual key code, and `lparam` contains the key state vector. The only difference is that `WM_KEYUP` is sent when a key is released.

For example, if you’re using the `WM_KEYDOWN` message to control something, take a look at the code here:

    case WM_KEYDOWN:

         {

         // get virtual key code and data bits

         int virtual_code = (int)wparam;

         int key_state = (int)lparam;

         // switch on the virtual_key code to be clean

         switch(virtual_code)

                {

                case VK_RIGHT:{ } break;

                case VK_LEFT: { } break;

                case VK_UP: { } break;

                case VK_DOWN: { } break;

                // more cases…

                default: break;

                } // end switch

         // tell windows that you processed the message

         return(0);

         } break;

As an experiment, try modifying the code in `DEMO3_11.CPP` to support the `WM_KEYDOWN` message instead of `WM_CHAR`. When you’re done, come back and we’ll talk about the last method of reading the keyboard.

The final method of reading the keyboard is to make a call to one of the keyboard state functions: `GetKeyboardState()`, `GetKeyState()`, or `GetAsyncKeyState()`. We’ll focus on `GetAsyncKeyState()` because it works for a single key, which is what you’re usually interested in rather than the entire keyboard. If you’re interested in the other functions, you can always look them up in the Win32 SDK. Anyway, `GetAsyncKeyState()` has the following prototype:

    SHORT GetAsyncKeyState(int virtual_key);

You simply send the function the virtual key code that you want to test, and if the high bit of the return value is `1`, the key is pressed. Otherwise, it’s not. I have written some macros to make this easier:

    #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

    #define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

The beauty of using `GetAsyncKeyState()` is that it’s not coupled to the event loop. You can test for keypresses anywhere you want. For example, say that you’re writing a game and you want to track the arrow keys, spacebar, and maybe the Ctrl key. You don’t want to have to deal with the `WM_CHAR` or `WM_KEYDOWN` messages; you just want to code something like this:

    if (KEYDOWN(VK_DOWN))

       {

       // move ship down, whatever

       } // end if

    if (KEYDOWN(VK_SPACE))

       {

       // fire weapons maybe?

       } // end if

    // and so on

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.