📄 vktochar.cpp
字号:
#define FIFTH_COLUMN 4
#define SIXTH_COLUMN 5
#define SAME_VALUE_COLUMN 16
const UINT8 VKeyToUnicodeSpecialMappingTable[8] =
// mapping table for VK_BACK , VK_TAB and VK_RETURN
{
SAME_VALUE_COLUMN, // only key
SAME_VALUE_COLUMN, // key + shift
SAME_VALUE_COLUMN, // key + caps
SAME_VALUE_COLUMN, // key + shift + caps
FIRST_COLUMN , // key + control
NO_CHAR , // key + shift + control
SECOND_COLUMN , // key + caps + control
NO_CHAR // key + shift + caps + control
};
const UINT8 VKeyToUnicodeSpecialTable[6][2] =
{
{
127, // back + Control
8 // back + Control + Caps
},
{
NO_CHAR, // tab + Control
NO_CHAR // tab + Control + Caps
},
{
NO_CHAR, // unused VKey
NO_CHAR // unused VKey
},
{
NO_CHAR, // unused VKey
NO_CHAR // unused VKey
},
{
NO_CHAR, // unused VKey
NO_CHAR // unused VKey
},
{
10, // return + control
10 // return + control + Caps
}
};
const UINT8 VKeyToUnicodeEscapeMappingTable[8] =
// mapping table for VK_ESCAPE
{
SAME_VALUE_COLUMN, // only key
SAME_VALUE_COLUMN, // key + shift
SAME_VALUE_COLUMN, // key + caps
SAME_VALUE_COLUMN, // key + shift + caps
SAME_VALUE_COLUMN, // key + control
SAME_VALUE_COLUMN, // key + shift + control
NO_CHAR , // key + caps + control
NO_CHAR // key + shift + caps + control
};
const UINT8 VKeyToUnicodeSpaceMappingTable[8] =
// mapping table for VK_SPACE
{
SAME_VALUE_COLUMN, // only key
SAME_VALUE_COLUMN, // key + shift
SAME_VALUE_COLUMN, // key + caps
SAME_VALUE_COLUMN, // key + shift + caps
SAME_VALUE_COLUMN, // key + control
NO_CHAR , // key + shift + control
SAME_VALUE_COLUMN, // key + caps + control
NO_CHAR // key + shift + caps + control
};
const UINT8 VKeyToUnicodeNumbersMappingTable[8] =
{
SAME_VALUE_COLUMN, // only key
FIRST_COLUMN , // key + shift
SAME_VALUE_COLUMN, // key + caps
FIRST_COLUMN , // key + shift + caps
NO_CHAR , // key + control
SECOND_COLUMN , // key + shift + control
NO_CHAR , // key + caps + control
SECOND_COLUMN // key + shift + caps + control
};
const UINT8 VKeyToUnicodeNumbersTable[10][2] =
{
{
')' , // SHIFT + 0
NO_CHAR // SHIFT + 0 +Control
},
{
'!' , // SHIFT + 1
NO_CHAR // SHIFT + 1 +Control
},
{
'@' , // SHIFT + 2
0 // SHIFT + 2 +Control
},
{
'#' , // SHIFT + 3
NO_CHAR // SHIFT + 3 +Control
},
{
'$' , // SHIFT + 4
NO_CHAR // SHIFT + 4 +Control
},
{
'%' , // SHIFT + 5
NO_CHAR // SHIFT + 5 +Control
},
{
'^' , // SHIFT + 6
30 // SHIFT + 6 +Control
},
{
'&' , // SHIFT + 7
NO_CHAR // SHIFT + 7 +Control
},
{
'*' , // SHIFT + 8
NO_CHAR // SHIFT + 8 +Control
},
{
'(' , // SHIFT + 9
NO_CHAR // SHIFT + 9 +Control
}
};
const UINT8 VKeyToUnicodeAlphabetsMappingTable[8] =
{
FIRST_COLUMN, // only key
SAME_VALUE_COLUMN, // key + shift
SAME_VALUE_COLUMN, // key + caps
FIRST_COLUMN, // key + shift + caps
SECOND_COLUMN , // key + control
SECOND_COLUMN , // key + shift + control
SECOND_COLUMN , // key + caps + control
SECOND_COLUMN // key + shift + caps + control
};
const UINT8 VKeyToUnicodePunctuation1MappingTable[8] =
{
FIRST_COLUMN , // only key
SECOND_COLUMN , // key + shift
FIRST_COLUMN , // key + caps
SECOND_COLUMN , // key + shift + caps
NO_CHAR , // key + control
THIRD_COLUMN , // key + shift + control
NO_CHAR , // key + caps + control
THIRD_COLUMN // key + shift + caps + control
};
const UINT8 VKeyToUnicodePunctuation1Table[7][3] =
{
{
';' , // semi colon
':' , // semi colon +shift
NO_CHAR // semi colon +shift +control
},
{
'=' , // equal
'+' , // equal +shift
NO_CHAR // equal +shift +control
},
{
',' , // comma
'<' , // comma +shift
NO_CHAR // comma +shift +control
},
{
'-' , // hyphen
'_' , // hyphen +shift
31 // hyphen +shift +control
},
{
'.' , // period
'>' , // period +shift
NO_CHAR // period +shift +control
},
{
'/' , // slash
'?' , // slash +shift
NO_CHAR // slash +shift +control
},
{
'`' , // backquote
'~' , // backquote +shift
NO_CHAR // backquote +shift +control
}
};
const UINT8 VKeyToUnicodePunctuation2MappingTable[8] =
{
FIRST_COLUMN , // only key
SECOND_COLUMN , // key + shift
FIRST_COLUMN , // key + caps
SECOND_COLUMN , // key + shift + caps
THIRD_COLUMN , // key + control
NO_CHAR , // key + shift + control
THIRD_COLUMN , // key + caps + control
NO_CHAR // key + shift + caps + control
};
const UINT8 VKeyToUnicodePunctuation2Table[4][3] =
{
{
'[' , // lsquarebracket
'{' , // lsquarebracket +shift
27 // lsquarebracket +control
},
{
'\\', // backslash
'|' , // backslash +shift
28 // backslash +control
},
{
']' , // rsquarebracket
'}' , // rsquarebracket +shift
29 // +control
},
{
'\'' , // apostrophe
'"' , // apostrophe +shift
NO_CHAR // apostrophe +control no char
}
};
#define ALT_INDEX 8
#define CONTROL_INDEX 4
#define CAPS_INDEX 2
#define SHIFT_INDEX 1
/*++
VKeyToUnicode:
Return Value:
Errors:
Notes:
--*/
UINT16
VKeyToUnicode(
UINT32 VirtualKey, // Virtual Key causing the event.
KEY_STATE_FLAGS *ShiftFlags // State of Shift, control, caps and alt keys.
)
{
UINT32 index=0;
UINT8 column,return_value = NO_CHAR;
if ( *ShiftFlags & KeyShiftAnyCtrlFlag)
index += CONTROL_INDEX;
if ( *ShiftFlags & KeyShiftCapitalFlag)
{
index += CAPS_INDEX;
}
if ( *ShiftFlags & KeyShiftAnyShiftFlag)
index += SHIFT_INDEX;
if (( *ShiftFlags & KeyShiftAnyAltFlag) &&
( *ShiftFlags & KeyShiftAnyCtrlFlag) )
{
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
}
if ((VirtualKey >= VK_0) && (VirtualKey <= VK_9) )
{
column = VKeyToUnicodeNumbersMappingTable[index];
switch (column)
{
case SAME_VALUE_COLUMN:
return VirtualKey;
case NO_CHAR:
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
default:
return_value = VKeyToUnicodeNumbersTable[VirtualKey - VK_0][column];
}
}
if ((VirtualKey >= 'A') && (VirtualKey <= 'Z') )
{
// NKDbgPrintfW(1, (L"index %d\r\n",index ));
column = VKeyToUnicodeAlphabetsMappingTable[index];
switch (column)
{
case SAME_VALUE_COLUMN:
return VirtualKey;
case NO_CHAR:
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
case FIRST_COLUMN:
return VirtualKey + 'a' - 'A' ;
case SECOND_COLUMN:
return VirtualKey - 'A' + 1 ;
}
}
if ((VirtualKey >= VK_SEMICOLON) && (VirtualKey <= VK_BACKQUOTE) )
{
column = VKeyToUnicodePunctuation1MappingTable[index];
switch (column)
{
case SAME_VALUE_COLUMN:
return VirtualKey;
case NO_CHAR:
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
default:
return_value = VKeyToUnicodePunctuation1Table
[VirtualKey - VK_SEMICOLON][column];
}
}
if ((VirtualKey >= VK_LBRACKET) && (VirtualKey <= VK_APOSTROPHE) )
{
column = VKeyToUnicodePunctuation2MappingTable[index];
switch (column)
{
case SAME_VALUE_COLUMN:
return VirtualKey;
case NO_CHAR:
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
default:
return_value = VKeyToUnicodePunctuation2Table
[VirtualKey - VK_LBRACKET][column];
}
}
if ((VirtualKey >= VK_BACK) && (VirtualKey <= VK_RETURN) )
{
column = VKeyToUnicodeSpecialMappingTable[index];
switch (column)
{
case SAME_VALUE_COLUMN:
return VirtualKey;
case NO_CHAR:
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
default:
return_value = VKeyToUnicodeSpecialTable
[VirtualKey - VK_BACK][column];
}
}
if (VirtualKey == VK_ESCAPE )
{
column = VKeyToUnicodeEscapeMappingTable[index];
switch (column)
{
case SAME_VALUE_COLUMN:
return VirtualKey;
case NO_CHAR:
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
}
}
if (VirtualKey == VK_SPACE )
{
column = VKeyToUnicodeSpaceMappingTable[index];
switch (column)
{
case SAME_VALUE_COLUMN:
return VirtualKey;
case NO_CHAR:
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
}
}
if (return_value == NO_CHAR) {
*ShiftFlags |= KeyShiftNoCharacterFlag;
return NO_CHAR;
} else {
return return_value;
}
}
extern "C"
// @doc EXTERNAL DRIVERS
/* @func
Generates the appropriate Unicode characters and shift state flags given a
virtual key, key state array and driver state.
@xref
<tab><t KEY_STATE_FLAGS><nl>
<tab><t KEY_STATE><nl>
<tab><t TO_UNICODE_STATE><nl>
<tab><f KeybdDriverGetInfo><nl>
<tab><f KeybdDriverInitStates>
@comm If KeyState is NULL, the driver must fill in the character which
corresponds to the unshifted state for the virtual key and return.
@comm In all other cases, this function must at least update the key state
array and fill in the shift state determined from the key state array and,
if necessary, update the <t TO_UNICODE_STATE>. This means that the count
of characters generated will always be at least 1. See <t
KEY_STATE_FLAGS> in order to generate the shift state without a
corresponding character.
@comm Each character should have a corresponding shift state entered into
the shift state buffer, even if it is the same as the preceding shift
state.
@comm Each entry in the character buffer is 32-bits whereas a Unicode
character is 16 bits. The driver should clear the high order 16-bits.
<tab>*((UINT16*)pCharacterBuffer) = Unicode character; // NO doesn't clear high bits.<nl>
<nl>
<tab>*pCharacterBuffer = Unicode character; // YES<nl>
*/
UINT32
KeybdDriverVKeyToUnicode(
UINT32 VirtualKey, // @parm Virtual Key causing the event.
KEY_STATE_FLAGS KeyEvent, // @parm KeyStateDownFlag set or cleared.
KEY_STATE KeyState, // @parm Key State.
void *pKeybdDriverToUnicodeState, // @parm Driver specific <t TO_UNICODE_STATE>.
UINT32 cBufferSize, // @parm Count of 32-bit entries in each buffer.
UINT32 *pcCharacters, // @parm Count of characters generated.
KEY_STATE_FLAGS *pShiftStateBuffer, // @parm Location to put shift state info.
UINT32 *pCharacterBuffer // @parm Location to put characters.
)
{
KEY_STATE_FLAGS ShiftFlags;
UINT32 VKeyCommon;
VirtualKey &= 0xff;
// Do special case for MapVirtualKey here.
if ( KeyState == NULL )
{
if ( pCharacterBuffer )
*pCharacterBuffer = towlower(VirtualKey);
return ERROR_SUCCESS;
}
// Check parameters.
if ( ( pKeybdDriverToUnicodeState == NULL ) ||
( cBufferSize != MAX_TO_UNICODE_CHARACTERS ) ||
( pcCharacters == NULL ) ||
( pShiftStateBuffer == NULL ) ||
( pCharacterBuffer == NULL ) )
{
SetLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER;
}
// Update the virtual key state.
KeyState[VirtualKey] = NewKeyStateFlags(KeyState[VirtualKey], KeyEvent);
// Now check the keys which have L and R versions and update their common
// vkey state.
VKeyCommon = MapLRVKeys(VirtualKey);
if ( VKeyCommon != VirtualKey )
{
KeyState[VKeyCommon] = NewKeyStateFlags(KeyState[VKeyCommon], KeyEvent);
VirtualKey = VKeyCommon;
}
// Figure out the new shift state flags.
KeybdDriverKeyStateToShiftFlags(KeyState, VirtualKey, &ShiftFlags);
// Always return the shift state which counts for one entry.
*pcCharacters = 1;
// Note that ShiftFlags holds the current state of the keyboard when it is
// passed to the next routines. They will look at the current state and
// possibly update it depending on whether or not they generate a character.
if ( AltNumKeyEvent(
VirtualKey,
KeyEvent,
(TO_UNICODE_STATE*)pKeybdDriverToUnicodeState,
&ShiftFlags,
pCharacterBuffer) )
{
// If part of Alt+Num sequence, no more to do.
}
else if ( KeyEvent & KeyStateDownFlag )
{
*pCharacterBuffer = VKeyToUnicode(VirtualKey, &ShiftFlags);
}
else
{
// We don't normally generate characters on a key up.
ShiftFlags |= KeyShiftNoCharacterFlag;
}
*pShiftStateBuffer = ShiftFlags;
return ERROR_SUCCESS;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_VKEY_TO_UNICODE v_pfnVKeyToUnicodeTest = KeybdDriverVKeyToUnicode;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -