📄 vkchengus1.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <nkintr.h>
#include <keybd.h>
#include <keybddr.h>
#include <keybdpdd.h>
// Languages besides English may return more than one character.
// It is usually a dead char and another character.
#define MAX_TO_UNICODE_CHARACTERS 2
#define VK_A 0x41
#define VK_F 0x46
#define VK_6 0x36
#define VK_X 0x58
#define C_ALT_NUM_VK 5
struct TO_UNICODE_STATE
{
BOOL bAltNumAltDownTransition;
BOOL bAltNumInProgress;
BOOL bAltNumHex;
int cAltNumVk;
unsigned int vkAltNum[C_ALT_NUM_VK];
};
void
VKeyToUnicodeInfo(
KBDI_VKEY_TO_UNICODE_INFO *pInfo
)
{
pInfo -> cbToUnicodeState = sizeof(TO_UNICODE_STATE);
pInfo -> cMaxToUnicodeCharacters = MAX_TO_UNICODE_CHARACTERS;
return;
}
static
BOOL
AltNumOkToStart(
KEY_STATE_FLAGS ShiftFlags
)
{
if ( ShiftFlags & ( KeyShiftAnyCtrlFlag |
KeyShiftLeftWinFlag |
KeyShiftRightWinFlag |
KeyShiftAnyShiftFlag ) )
return FALSE;
return TRUE;
}
static
BOOL
AltNumKeyEvent(
UINT32 VirtualKey,
KEY_STATE_FLAGS KeyEvent,
TO_UNICODE_STATE *pToUnicodeState,
KEY_STATE_FLAGS *pShiftFlags,
UINT32 *pCharacterBuffer
)
{
KEY_STATE_FLAGS ShiftFlags = *pShiftFlags;
BOOL bGeneratedCharacter = FALSE;
UINT32 chGenerated;
unsigned int uiBase;
int i;
UINT32 vk;
if ( VirtualKey == VK_MENU )
{
if ( KeyEvent & KeyStateDownFlag )
{
// Down transition with no other keys?
if ( !( KeyEvent & KeyStatePrevDownFlag ) &&
( AltNumOkToStart(ShiftFlags) ) )
{
// Now armed to looked for number keys.
pToUnicodeState -> bAltNumAltDownTransition = TRUE;
pToUnicodeState -> bAltNumInProgress = FALSE;
pToUnicodeState -> bAltNumHex = FALSE;
pToUnicodeState -> cAltNumVk = 0;
}
}
else // Alt key up
{
pToUnicodeState -> bAltNumAltDownTransition = FALSE;
if ( pToUnicodeState -> bAltNumInProgress )
{
pToUnicodeState -> bAltNumInProgress = FALSE;
if ( pToUnicodeState -> cAltNumVk > 1 )
{
chGenerated = 0;
if ( pToUnicodeState -> bAltNumHex )
{
uiBase = 16;
}
else
{
uiBase = 10;
}
for ( i = 0;
i < pToUnicodeState -> cAltNumVk;
i++ )
{
vk = pToUnicodeState -> vkAltNum[i];
if ( ( vk >= VK_NUMPAD0 ) && ( vk <= VK_NUMPAD9 ) )
{
vk -= VK_NUMPAD0;
}
else if ( pToUnicodeState -> bAltNumHex &&
( ( vk >= VK_A ) && ( vk <= VK_F ) ) )
{
vk -= VK_A;
vk += 10;
}
else
{
break; // bad character
}
chGenerated *= uiBase;
chGenerated += vk;
}
bGeneratedCharacter = TRUE;
*pCharacterBuffer = chGenerated;
}
else
{
// Alt+N app startup here.
}
}
}
}
else if ( ( pToUnicodeState -> bAltNumAltDownTransition ) &&
( KeyEvent & KeyStateDownFlag ) )
{
if ( ( VirtualKey >= VK_NUMPAD0 ) && ( VirtualKey <= VK_NUMPAD9 ) )
{
// We were armed to look for number keys and we found one, so now we
// are actually in progress.
pToUnicodeState -> bAltNumInProgress = TRUE;
if ( pToUnicodeState -> cAltNumVk < C_ALT_NUM_VK )
{
pToUnicodeState -> vkAltNum[pToUnicodeState -> cAltNumVk++] = VirtualKey;
}
}
else if ( ( pToUnicodeState -> bAltNumHex ) &&
( ( VirtualKey >= VK_A ) && ( VirtualKey <= VK_F ) ) )
{
// Hex characters are split out separately for convenience in case the design changes.
pToUnicodeState -> bAltNumInProgress = TRUE;
if ( pToUnicodeState -> cAltNumVk < C_ALT_NUM_VK )
{
pToUnicodeState -> vkAltNum[pToUnicodeState -> cAltNumVk++] = VirtualKey;
}
}
else if ( ( pToUnicodeState -> bAltNumInProgress ) &&
( VirtualKey == VK_X ) )
{
pToUnicodeState -> bAltNumHex = TRUE;
}
else if ( pToUnicodeState -> bAltNumInProgress )
{
// If we are in progress, ignore unknown keys.
}
else
{
// If we see a key we can't handle when not in progress, disarm
pToUnicodeState -> bAltNumAltDownTransition = FALSE;
}
}
if ( pToUnicodeState -> bAltNumInProgress )
{
ShiftFlags |= KeyShiftUseVKNullFlag | KeyShiftNoCharacterFlag;
}
*pShiftFlags = ShiftFlags;
return pToUnicodeState -> bAltNumInProgress || bGeneratedCharacter;
}
static
UINT32
MapCommonVKeyToLVKey(
UINT32 vkey
)
{
if ( vkey == VK_SHIFT )
vkey = VK_LSHIFT;
else if ( vkey == VK_CONTROL )
vkey = VK_LCONTROL;
else if ( vkey == VK_MENU )
vkey = VK_LMENU;
return vkey;
}
/*++
MapLRVKeyToCommonVKey:
Map left and right virtual keys to their common vkey.
Return Value:
The common vkey.
--*/
static
UINT32
MapLRVKeyToCommonVKey(
UINT32 vkey
)
{
if ( ( vkey == VK_LCONTROL ) ||
( vkey == VK_RCONTROL ) )
return VK_CONTROL;
if ( ( vkey == VK_LMENU ) ||
( vkey == VK_RMENU ) )
return VK_MENU;
if ( ( vkey == VK_LSHIFT ) ||
( vkey == VK_RSHIFT ) )
return VK_SHIFT;
// VK_LWIN and VK_RWIN do not have a merged key.
return vkey;
}
/*++
NewKeyStateFlags:
Figure out the new key state flags based on the current state and the
event.
Return Value:
The new flag settings.
--*/
static
UINT32
NewKeyStateFlags(
KEY_STATE_FLAGS CurrentState,
KEY_STATE_FLAGS KeyEventFlags
)
{
// Just interested in down/up flag.
KeyEventFlags &= KeyStateDownFlag;
// First update the key state for the specific key.
// Remember the previous state.
if ( KeyStateIsDown(CurrentState) )
CurrentState |= KeyStatePrevDownFlag;
else
CurrentState &= ~KeyStatePrevDownFlag;
// Set the new state.
if ( KeyEventFlags )
CurrentState |= KeyStateDownFlag | KeyStateGetAsyncDownFlag;
else
CurrentState &= ~KeyStateDownFlag;
// Toggle flag only changes on down transition, not auto repeat.
if ( KeyStateIsDownTransition(CurrentState) )
CurrentState ^= KeyStateToggledFlag;
return CurrentState;
}
/*++
KeybdDriverKeyStateToShiftFlags:
Collapse the shift state from a given key state array into a single
element.
Notes:
For the given virtual key, the current flags from the key state array are
put into the low bits of the output flags.
--*/
static
void
KeybdDriverKeyStateToShiftFlags(
KEY_STATE KeyState, // Key state array.
UINT32 VKey, // Virtual key.
KEY_STATE_FLAGS *pShiftStateFlags // Location to put collapsed shift state.
)
{
KEY_STATE_FLAGS ShiftFlags = 0;
// Add the standard keys.
if ( KeyStateIsDown(KeyState[VK_CONTROL]) )
{
ShiftFlags |= KeyShiftAnyCtrlFlag;
}
if ( KeyStateIsDown(KeyState[VK_LCONTROL]) )
{
ShiftFlags |= KeyShiftLeftCtrlFlag;
}
if ( KeyStateIsDown(KeyState[VK_RCONTROL]) )
{
ShiftFlags |= KeyShiftRightCtrlFlag;
}
if ( KeyStateIsDown(KeyState[VK_SHIFT]) )
{
ShiftFlags |= KeyShiftAnyShiftFlag;
}
if ( KeyStateIsDown(KeyState[VK_LSHIFT]) )
{
ShiftFlags |= KeyShiftLeftShiftFlag;
}
if ( KeyStateIsDown(KeyState[VK_RSHIFT]) )
{
ShiftFlags |= KeyShiftRightShiftFlag;
}
if ( KeyStateIsDown(KeyState[VK_MENU]) )
{
ShiftFlags |= KeyShiftAnyAltFlag;
}
if ( KeyStateIsDown(KeyState[VK_LMENU]) )
{
ShiftFlags |= KeyShiftLeftAltFlag;
}
if ( KeyStateIsDown(KeyState[VK_RMENU]) )
{
ShiftFlags |= KeyShiftRightAltFlag;
}
if ( KeyStateIsDown(KeyState[VK_LWIN]) )
{
ShiftFlags |= KeyShiftLeftWinFlag;
}
if ( KeyStateIsDown(KeyState[VK_RWIN]) )
{
ShiftFlags |= KeyShiftRightWinFlag;
}
if ( KeyStateIsToggled(KeyState[VK_CAPITAL]) )
{
ShiftFlags |= KeyShiftCapitalFlag;
}
if ( KeyStateIsToggled(KeyState[VK_NUMLOCK]) )
{
ShiftFlags |= KeyShiftNumLockFlag;
}
// Set the low order bits to reflect the current key.
*pShiftStateFlags = ShiftFlags | KeyState[VKey];
return;
}
#define BASE_FLAG 0x00
#define CAPS_FLAG 0x01
#define SHIFT_FLAG 0x02
#define ALT_FLAG 0x04
#define CONTROL_FLAG 0x08
static
const
UINT16
Column_Base[COUNT_VKEYS] =
{
/* 00 */ 0,
/* 01 VK_LBUTTON */ 0,
/* 02 VK_RBUTTON */ 0,
/* 03 VK_CANCEL */ 0,
/* 04 VK_MBUTTON */ 0,
/* 05 */ 0,
/* 06 */ 0,
/* 07 */ 0,
/* 08 VK_BACK */ 0x08,
/* 09 VK_TAB */ 0x09,
/* 0A */ 0,
/* 0B */ 0,
/* 0C VK_CLEAR */ 0,
/* 0D VK_RETURN */ 0x0d,
/* 0E */ 0,
/* 0F */ 0,
/* 10 VK_SHIFT */ 0,
/* 11 VK_CONTROL */ 0,
/* 12 VK_MENU */ 0,
/* 13 VK_PAUSE */ 0,
/* 14 VK_CAPITAL */ 0,
/* 15 */ 0,
/* 16 */ 0,
/* 17 */ 0,
/* 18 */ 0,
/* 19 */ 0,
/* 1A */ 0,
/* 1B VK_ESCAPE */ 0x1b,
/* 1C */ 0,
/* 1D */ 0,
/* 1E */ 0,
/* 1F */ 0,
/* 20 VK_SPACE */ TEXT(' '),
/* 21 VK_PRIOR */ 0,
/* 22 VK_NEXT */ 0,
/* 23 VK_END */ 0,
/* 24 VK_HOME */ 0,
/* 25 VK_LEFT */ 0,
/* 26 VK_UP */ 0,
/* 27 VK_RIGHT */ 0,
/* 28 VK_DOWN */ 0,
/* 29 VK_SELECT */ 0,
/* 2A VK_PRINT */ 0,
/* 2B VK_EXECUTE */ 0,
/* 2C VK_SNAPSHOT */ 0,
/* 2D VK_INSERT */ 0,
/* 2E VK_DELETE */ 0,
/* 2F VK_HELP */ 0,
/* 30 VK_0 */ TEXT('0'),
/* 31 VK_1 */ TEXT('1'),
/* 32 VK_2 */ TEXT('2'),
/* 33 VK_3 */ TEXT('3'),
/* 34 VK_4 */ TEXT('4'),
/* 35 VK_5 */ TEXT('5'),
/* 36 VK_6 */ TEXT('6'),
/* 37 VK_7 */ TEXT('7'),
/* 38 VK_8 */ TEXT('8'),
/* 39 VK_9 */ TEXT('9'),
/* 3A */ 0,
/* 3B */ 0,
/* 3C */ 0,
/* 3D */ 0,
/* 3E */ 0,
/* 3F */ 0,
/* 40 */ 0,
/* 41 */ TEXT('a'),
/* 42 */ TEXT('b'),
/* 43 */ TEXT('c'),
/* 44 */ TEXT('d'),
/* 45 */ TEXT('e'),
/* 46 */ TEXT('f'),
/* 47 */ TEXT('g'),
/* 48 */ TEXT('h'),
/* 49 */ TEXT('i'),
/* 4A */ TEXT('j'),
/* 4B */ TEXT('k'),
/* 4C */ TEXT('l'),
/* 4D */ TEXT('m'),
/* 4E */ TEXT('n'),
/* 4F */ TEXT('o'),
/* 50 */ TEXT('p'),
/* 51 */ TEXT('q'),
/* 52 */ TEXT('r'),
/* 53 */ TEXT('s'),
/* 54 */ TEXT('t'),
/* 55 */ TEXT('u'),
/* 56 */ TEXT('v'),
/* 57 */ TEXT('w'),
/* 58 */ TEXT('x'),
/* 59 */ TEXT('y'),
/* 5A */ TEXT('z'),
/* 5B VK_LWIN */ 0,
/* 5C VK_RWIN */ 0,
/* 5D VK_APPS */ 0,
/* 5E */ 0,
/* 5F */ 0,
/* 60 VK_NUMPAD0 */ TEXT('0'),
/* 61 VK_NUMPAD1 */ TEXT('1'),
/* 62 VK_NUMPAD2 */ TEXT('2'),
/* 63 VK_NUMPAD3 */ TEXT('3'),
/* 64 VK_NUMPAD4 */ TEXT('4'),
/* 65 VK_NUMPAD5 */ TEXT('5'),
/* 66 VK_NUMPAD6 */ TEXT('6'),
/* 67 VK_NUMPAD7 */ TEXT('7'),
/* 68 VK_NUMPAD8 */ TEXT('8'),
/* 69 VK_NUMPAD9 */ TEXT('9'),
/* 6A VK_MULTIPLY */ TEXT('*'),
/* 6B VK_ADD */ TEXT('+'),
/* 6C VK_SEPARATOR */ 0,
/* 6D VK_SUBTRACT */ TEXT('-'),
/* 6E VK_DECIMAL */ TEXT('.'),
/* 6F VK_DIVIDE */ TEXT('/'),
/* 70 VK_F1 */ 0,
/* 71 VK_F2 */ 0,
/* 72 VK_F3 */ 0,
/* 73 VK_F4 */ 0,
/* 74 VK_F5 */ 0,
/* 75 VK_F6 */ 0,
/* 76 VK_F7 */ 0,
/* 77 VK_F8 */ 0,
/* 78 VK_F9 */ 0,
/* 79 VK_F10 */ 0,
/* 7A VK_F11 */ 0,
/* 7B VK_F12 */ 0,
/* 7C VK_F13 */ 0,
/* 7D VK_F14 */ 0,
/* 7E VK_F15 */ 0,
/* 7F VK_F16 */ 0,
/* 80 */ 0,
/* 81 */ 0,
/* 82 */ 0,
/* 83 */ 0,
/* 84 */ 0,
/* 85 */ 0,
/* 86 */ 0,
/* 87 */ 0,
/* 88 */ 0,
/* 89 */ 0,
/* 8A */ 0,
/* 8B */ 0,
/* 8C */ 0,
/* 8D */ 0,
/* 8E */ 0,
/* 8F */ 0,
/* 90 VK_NUMLOCK */ 0,
/* 91 VK_SCROLL */ 0,
/* 92 */ 0,
/* 93 */ 0,
/* 94 */ 0,
/* 95 */ 0,
/* 96 */ 0,
/* 97 */ 0,
/* 98 */ 0,
/* 99 */ 0,
/* 9A */ 0,
/* 9B */ 0,
/* 9C */ 0,
/* 9D */ 0,
/* 9E */ 0,
/* 9F */ 0,
/* A0 VK_LSHIFT */ 0,
/* A1 VK_RSHIFT */ 0,
/* A2 VK_LCONTROL */ 0,
/* A3 VK_RCONTROL */ 0,
/* A4 VK_LMENU */ 0,
/* A5 VK_RMENU */ 0,
/* A6 */ 0,
/* A7 */ 0,
/* A8 */ 0,
/* A9 */ 0,
/* AA */ 0,
/* AB */ 0,
/* AC */ 0,
/* AD */ 0,
/* AE */ 0,
/* AF */ 0,
/* B0 */ 0,
/* B1 */ 0,
/* B2 */ 0,
/* B3 */ 0,
/* B4 */ 0,
/* B5 */ 0,
/* B6 */ 0,
/* B7 */ 0,
/* B8 */ 0,
/* B9 */ 0,
/* BA VK_SEMICOLON */ TEXT(';'),
/* BB VK_EQUAL */ TEXT('='),
/* BC VK_COMMA */ TEXT(','),
/* BD VK_HYPHEN */ TEXT('-'),
/* BE VK_PERIOD */ TEXT('.'),
/* BF VK_SLASH */ TEXT('/'),
/* C0 VK_BACKQUOTE */ TEXT('`'),
/* C1 */ 0,
/* C2 */ 0,
/* C3 */ 0,
/* C4 */ 0,
/* C5 */ 0,
/* C6 */ 0,
/* C7 */ 0,
/* C8 */ 0,
/* C9 */ 0,
/* CA */ 0,
/* CB */ 0,
/* CC */ 0,
/* CD */ 0,
/* CE */ 0,
/* CF */ 0,
/* D0 */ 0,
/* D1 */ 0,
/* D2 */ 0,
/* D3 */ 0,
/* D4 */ 0,
/* D5 */ 0,
/* D6 */ 0,
/* D7 */ 0,
/* D8 */ 0,
/* D9 */ 0,
/* DA */ 0,
/* DB VK_LBRACKET */ TEXT('['),
/* DC VK_BACKSLASH */ TEXT('\\'),
/* DD VK_RBRACKET */ TEXT(']'),
/* DE VK_APOSTROPHE */ TEXT('\''),
/* DF VK_OFF */ 0,
/* E0 */ 0,
/* E1 */ 0,
/* E2 */ 0,
/* E3 */ 0,
/* E4 */ 0,
/* E5 */ 0,
/* E6 */ 0,
/* E7 */ 0,
/* E8 */ 0,
/* E9 */ 0,
/* EA */ 0,
/* EB */ 0,
/* EC */ 0,
/* ED */ 0,
/* EE */ 0,
/* EF */ 0,
/* F0 */ 0,
/* F1 */ 0,
/* F2 */ 0,
/* F3 */ 0,
/* F4 */ 0,
/* F5 */ 0,
/* F6 */ 0,
/* F7 */ 0,
/* F8 */ 0,
/* F9 */ 0,
/* FA */ 0,
/* FB */ 0,
/* FC */ 0,
/* FD */ 0,
/* FE */ 0,
/* FF */ 0
};
static
const
UINT16
Column_Shift[COUNT_VKEYS] =
{
/* 00 */ 0,
/* 01 VK_LBUTTON */ 0,
/* 02 VK_RBUTTON */ 0,
/* 03 VK_CANCEL */ 0,
/* 04 VK_MBUTTON */ 0,
/* 05 */ 0,
/* 06 */ 0,
/* 07 */ 0,
/* 08 VK_BACK */ 0x08,
/* 09 VK_TAB */ 0x09,
/* 0A */ 0,
/* 0B */ 0,
/* 0C VK_CLEAR */ 0,
/* 0D VK_RETURN */ 0x0d,
/* 0E */ 0,
/* 0F */ 0,
/* 10 VK_SHIFT */ 0,
/* 11 VK_CONTROL */ 0,
/* 12 VK_MENU */ 0,
/* 13 VK_PAUSE */ 0,
/* 14 VK_CAPITAL */ 0,
/* 15 */ 0,
/* 16 */ 0,
/* 17 */ 0,
/* 18 */ 0,
/* 19 */ 0,
/* 1A */ 0,
/* 1B VK_ESCAPE */ 0x1b,
/* 1C */ 0,
/* 1D */ 0,
/* 1E */ 0,
/* 1F */ 0,
/* 20 VK_SPACE */ TEXT(' '),
/* 21 VK_PRIOR */ 0,
/* 22 VK_NEXT */ 0,
/* 23 VK_END */ 0,
/* 24 VK_HOME */ 0,
/* 25 VK_LEFT */ 0,
/* 26 VK_UP */ 0,
/* 27 VK_RIGHT */ 0,
/* 28 VK_DOWN */ 0,
/* 29 VK_SELECT */ 0,
/* 2A VK_PRINT */ 0,
/* 2B VK_EXECUTE */ 0,
/* 2C VK_SNAPSHOT */ 0,
/* 2D VK_INSERT */ 0,
/* 2E VK_DELETE */ 0,
/* 2F VK_HELP */ 0,
/* 30 VK_0 */ TEXT(')'),
/* 31 VK_1 */ TEXT('!'),
/* 32 VK_2 */ TEXT('@'),
/* 33 VK_3 */ TEXT('#'),
/* 34 VK_4 */ TEXT('$'),
/* 35 VK_5 */ TEXT('%'),
/* 36 VK_6 */ TEXT('^'),
/* 37 VK_7 */ TEXT('&'),
/* 38 VK_8 */ TEXT('*'),
/* 39 VK_9 */ TEXT('('),
/* 3A */ 0,
/* 3B */ 0,
/* 3C */ 0,
/* 3D */ 0,
/* 3E */ 0,
/* 3F */ 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -