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 ASCII code, on the other hand, is cooked data. This means that if you press the A key on the keyboard but the Shift key is not pressed or the Caps Lock key is not engaged, you see an `a` character. Similarly, if you press Shift+A, you see an `A`. The `WM_CHAR` message sends these kinds of messages.

You can use either technique—it’s up to you. For example, if you were writing a word processor, you would probably want to use the `WM_CHAR` message because the character case matters and you want ASCII codes, not virtual scan codes. On the other hand, if you’re making a game and `F` is fire, `S` is thrust, and the Shift key is the shields, who cares what the ASCII code is? You just want to know if a particular button on the keyboard is up or down.

The final method of reading the keyboard is to use the Win32 function `GetAsynKeyState()`, which tracks the last known keyboard state of the keys in a state table—like an array of Boolean switches. This is the method I prefer because you don’t have to write a keyboard handler.

Now that you know a little about each method, let’s cover the details of each one in order, starting with the `WM_CHAR` message.

The `WM_CHAR` message has the following parameterization:

  `wparam`—Contains the ASCII code of the key pressed.
  `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.7.

Table 3.7 Bit Encoding for the Key State Vector

Bits | Description
--- | ---

0–15 | Contains the repeat count, which is the number of times the keystroke is repeated as a result of the user holding down the key.
16–23 | Contains the scan code. The value depends on the original equipment manufacturer (OEM).
24 | Boolean; extended key flag. If it’s `1`, the key is an extended key, such as the right-hand Alt and Ctrl keys that appear on an enhanced 101- or 102-key keyboard.
29 | Boolean; indicates whether the Alt key is down.
30 | Boolean; indicates the previous key state. It’s useless.
31 | Boolean; indicates the key transition state. If the value is `1`, the key is being released; otherwise, the key is being pressed.

To process the `WM_CHAR` message, all you have to do is write a message handle for it, like this:

    case WM_CHAR:

    {

    // extract ascii code and state vector

    int ascii_code = wparam;

    int key_state = lparam;

    // take whatever action

    } break;

And of course, you can test for various state information that might be of interest. For example, here’s how you would test for the Alt key being pressed down:

    // test the 29th bit of key_state to see if it’s true

    #define ALT_STATE_BIT 0x20000000

    if (key_state & ALT_STATE_BIT)

       {

       // do something

       } // end if

And you can test for the other states with similar bitwise tests and manipulations.

As an example of processing the `WM_CHAR` message, I have created a demo that prints out the character and the state vector in hexadecimal form as you press keys. The program is called `DEMO3_11.CPP`, and the executable is of course `DEMO3_11.EXE`. Try pressing weird key combinations and see what happens. The code that processes and displays the `WM_CHAR` information is shown here, excerpted from the `WinProc()`:

    case WM_CHAR:

             {

             // get the character

             char ascii_code = wparam;

             unsigned int key_state = lparam;

             // get a graphics context

             hdc = GetDC(hwnd);

             // set the foreground color to green

             SetTextColor(hdc, RGB(0,255,0));

             // set the background color to black

             SetBkColor(hdc, RGB(0,0,0));

             // set the transparency mode to OPAQUE

             SetBkMode(hdc, OPAQUE);

             // print the ascii code and key state

             sprintf(buffer,"WM_CHAR: Character = %c ",ascii_code);

             TextOut(hdc, 0,0, buffer, strlen(buffer));

             sprintf(buffer,"Key State = 0X%X ",key_state);

             TextOut(hdc, 0,16, buffer, strlen(buffer));

             // release the dc back

             ReleaseDC(hwnd, hdc);

             } break;

The next keyboard event message, `WM_KEYDOWN`, is similar to `WM_CHAR`, except that the information is not “cooked.” The key data sent during a `WM_KEYDOWN` message is the virtual scan code of the key rather than the ASCII code. The virtual scan codes are similar to the standard scan codes generated by any keyboard, except that virtual scan codes are guaranteed to be the same for any keyboard. For example, it’s possible that the scan code for a particular key on your 101 AT-style keyboard is 67, but on another manufacturer’s keyboard, it might be 69. See the problem?

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.