现在的位置: 首页 > 综合 > 正文

2008 November 11th Tuesday (十一月 十一日 火曜日)

2013年10月28日 ⁄ 综合 ⁄ 共 7015字 ⁄ 字号 评论关闭
 In the four keystroke messages (WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, and WM_SYSKEYUP), the wParam message parameter contains the
virtual key code, and the lParam message parameter contains other information useful in understanding the keystroke.

Repeat Count

  The repeat count is the number of keystrokes represented by the message. In most cases, this will be set to 1. However, if a key
is held down and your window procedure is not fast enough to process key-down messages at the typematic rate (which you can set in
the Keyboard applet in the Control Panel), Windows combines several WM_KEYDOWN or WM_SYSKEYDOWN messages into a single message and
increases the Repeat Count field accordingly. The Repeat Count is always 1 for a WM_KEYUP or WM_SYSKEYUP message.

  Because a Repeat Count greater than 1 indicates that typematic keystrokes are occurring faster than your program can process them,
you may want to ignore the Repeat Count when processing the keyboard messages. Almost everyone has had the experience of "overscrolling"
a word-processing document or spreadsheet because extra keystrokes have accumulated. If your program ignores the Repeat Count in cases
where your program spends some time processing each keystroke, you can eliminate this problem. However, in other cases you will want to
use the Repeat Count. You may want to try using the programs both ways and see which feels the most natural.

OEM Scan Code

  The OEM Scan Code is the code generated by the hardware of the keyboard. This is familiar to middle-aged assembly language programmers
as the value obtained from the ROM BIOS services of PC compatibles. (OEM refers to the Original Equipment Manufacturer of the PC and in
this context is synonymous with "IBM Standard.") We don't need this stuff anymore. Windows programs can almost always ignore the OEM Scan
Code except when dependent on the physical layout of the keyboard.

Extended Key Flag

  The Extended Key Flag is 1 if the keystroke results from one of the additional keys on the IBM enhanced keyboard. (The enhanced keyboard
has 101 or 102 keys. Function keys are across the top. Cursor movement keys are separate from the numeric keypad, but the numeric keypad
also duplicates the cursor movement keys.) This flag is set to 1 for the Alt and Ctrl keys at the right of the keyboard, the cursor movement
keys (including Insert and Delete) that are not part of the numeric keypad, the slash (/) and Enter keys on the numeric keypad, and the Num
Lock key. Windows programs generally ignore the Extended Key Flag.

Context Code

  The Context Code is 1 if the Alt key is depressed during the keystroke. This bit will always be 1 for the WM_SYSKEYUP and WM_SYSKEYDOWN
messages and 0 for the WM_KEYUP and WM_KEYDOWN messages, with two exceptions:

  * If the active window is minimized, it does not have the input focus. All keystrokes generate WM_SYSKEYUP and WM_SYSKEYDOWN messages.
  If the Alt key is not pressed, the Context Code field is set to 0. Windows uses WM_SYSKEYUP and WM_SYSKEYDOWN messages so that a minimized
  active window doesn't process these keystrokes.

  * On some foreign-language keyboards, certain characters are generated by combining Shift, Ctrl, or Alt with another key. In these cases,
  the Context Code is set to 1 but the messages are not system keystroke messages.

Previous Key State

  The Previous Key State is 0 if the key was previously up and 1 if the key was previously down. It is always set to 1 for a WM_KEYUP or
WM_SYSKEYUP message, but it can be 0 or 1 for a WM_KEYDOWN or WM_SYSKEYDOWN message. A 1 indicates second and subsequent messages that are
the result of typematic repeats.

Transition State

  The Transition State is 0 if the key is being pressed and 1 if the key is being released. The field is set to 0 for a WM_KEYDOWN or
WM_SYSKEYDOWN message and to 1 for a WM_KEYUP or WM_SYSKEYUP message.

Shift States

  When you process a keystroke message, you may need to know whether any of the shift keys (Shift, Ctrl, and Alt) or toggle keys (Caps Lock,
Num Lock, and Scroll Lock) are pressed. You can obtain this information by calling the GetKeyState function. For instance:

iState = GetKeyState (VK_SHIFT) ;

  The iState variable will be negative (that is, the high bit is set) if the Shift key is down. The value returned from

iState = GetKeyState (VK_CAPITAL) ;

has the low bit set if the Caps Lock key is toggled on. This bit will agree with the little light on the keyboard.

  Generally, you'll use GetKeyState with the virtual key codes VK_SHIFT, VK_CONTROL, and VK_MENU (which you'll recall indicates the Alt key).
You can also use the following identifiers with GetKeyState to determine if the left or right Shift, Ctrl, or Alt keys are pressed: VK_LSHIFT,
VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU, VK_RMENU. These identifiers are used only with GetKeyState and GetAsyncKeyState().

  Be careful with GetKeyState. It is not a real-time keyboard status check. Rather, it reflects the keyboard status up to and including the
current message being processed. For the most part, this is exactly what you want. If you need to determine if the user typed Shift-Tab, you
can call GetKeyState with the VK_SHIFT parameter while processing the WM_KEYDOWN message for the Tab key. If the return value of GetKeyState
is negative, you know that the Shift key was pressed before the Tab key. And it doesn't matter if the Shift key has already been released by
the time you get around to processing the Tab key. You know that the Shift key was down when Tab was pressed.

Control Character Processing

  The basic rule for processing keystroke and character messages is this: If you need to read keyboard character input in your window, you
process the WM_CHAR message. If you need to read the cursor keys, function keys, Delete, Insert, Shift, Ctrl, and Alt, you process the WM_KEYDOWN
message.

  But what about the Tab key? Or Enter or Backspace or Escape? Traditionally, these keys generate ASCII control characters, as shown in the
preceding table. But in Windows they also generate virtual key codes. Should these keys be processed during WM_CHAR processing or WM_KEYDOWN
processing?

  After a decade of considering this issue (and looking back over Windows code I've written over the years), I seem to prefer treating the Tab,
Enter, Backspace, and Escape keys as control characters rather than as virtual keys.

case WM_CHAR:
     [other program lines]
     switch (wParam)
     {
     case '/b':          // backspace
          [other program line
          break ;
     case '/t':          // tab
          [other program lines]
          break ;

     case '/n':          // linefeed
          [other program lines]
          break ;

     case '/r':          // carriage return
          [other program lines]
          break ;

     default:            // character codes
          [other program lines]
          break ;
     }
     return 0 ;

Dead-Character Messages

  Windows programs can usually ignore WM_DEADCHAR and WM_SYSDEADCHAR messages, but you should definitely know
what dead characters are and how they work.

  On some non-U.S. English keyboards, certain keys are defined to add a diacritic to a letter. These are called
"dead keys" because they don't generate characters by themselves. For instance, when a German keyboard is installed,
the key that is in the same position as the +/= key on a U.S. keyboard is a dead key for the grave accent (') when
shifted and the acute accent (´) when unshifted.

  When a user presses this dead key, your window procedure receives a WM_DEADCHAR message with wParam equal to ASCII
or Unicode code for the diacritic by itself. When the user then presses a letter key that can be written with this
diacritic (for instance, the A key), the window procedure receives a WM_CHAR message where wParam is the ANSI code
for the letter 'a' with the diacritic.

  Thus, your program does not have to process the WM_DEADCHAR message because the WM_CHAR message gives the program
all the information it needs. The Windows logic even has built-in error handling: If the dead key is followed by
a letter that can't take a diacritic (such as 's'), the window procedure receives two WM_CHAR messages in a row-the
first with wParam equal to the ASCII code for the diacritic by itself (the same wParam value delivered with the WM_DEADCHAR
message) and the second with wParam equal to the ASCII code for the letter 's'.

抱歉!评论已关闭.