⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vktochar.cpp

📁 EP931X系列的WinCE键盘鼠标驱动源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

	@doc	EXTERNAL DRIVERS

	@module	vkremap.cpp |

This file implements the character generation part of the platform
independent code of the keyboard driver.  This is provided as a sample to
platform driver writers.  Note that most of the tables are UINT8 in order to
save space.  Returning Unicode characters > 255 will require UINT16 tables.

*/

#include <windows.h>
#include <memory.h>
#include <nkintr.h>
#include <keybddr.h>
#include <keybdpdd.h>


#define C_VIRTUAL_KEYS     			256

//	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_0	0x30
#define VK_9	0x39

#define VK_A	0x41
#define VK_F	0x46

#define VK_X	0x58




//      @doc    EXTERNAL DRIVERS
/*      @struct TO_UNICODE_STATE |

State info needed by the driver to convert virtual keys to Unicode.

@xref
	<tab><f KeybdDriverGetDeviceInfo><nl>
	<tab><f KeybdDriverInitStates><nl>
	<tab><f KeybdDriverVKeyToUnicode><nl>


@comm This struct would be used by the driver to maintain any state
information needed between key events in order to generate Unicode
characters from virtual keys.

@comm This structure is not visible outside of the driver.  The driver
provides information on its size via the <f KeybdDriverGetDeviceInfo>
function.  The input system allocates a buffer for the structure and
passes it in when it calls <f KeybdDriverVKeyToUnicode>.

@comm In the sample driver code, it is used to convert Alt+Num keys to a
unicode character.

*/

#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;
}



BOOL
AltNumOkToStart(
	KEY_STATE_FLAGS	ShiftFlags
	)
{
	if ( ShiftFlags & ( KeyShiftAnyCtrlFlag		|
						KeyShiftLeftWinFlag		|
						KeyShiftRightWinFlag	|
						KeyShiftAnyShiftFlag ) )
		return FALSE;
	return TRUE;
}





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_0 ) && ( vk <= VK_9 ) )
							{
							vk -= VK_0;
							}
						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_0 ) && ( VirtualKey <= VK_9 ) )
			{
			//	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;

}



extern "C"
//      @doc EXTERNAL DRIVERS
/*      @func

Initializes the virtual key state and driver specific state.

@xref

	<tab><t KEY_STATE><nl>
	<tab><t TO_UNICODE_STATE><nl>
	<tab><f KeybdDriverGetInfo><nl>
	<tab><c KBDI_VKEY_TO_UNICODE_INFO_ID><nl>
	<tab><t KBDI_VKEY_TO_UNICODE_INFO><nl>

@comm After calling <f KeybdDriverGetInfo> and allocating its required
memory, the input system calls this function to allow the driver to
initialize the memory.

@comm The pKeybdDriverToUnicodeState is a pointer to a piece of memory of
at least cbToUnicodeState bytes as reported by the <f KeybdDriverGetInfo>
function in the <t KBDI_VKEY_TO_UNICODE_INFO> structure.  If
cbToUnicodeState was reported as 0, this parameter may be NULL.

@comm This function must be re-entrant since it is exposed by the input
system via the <f KeybdInitStates> function and may be called by multiple
threads.

*/
BOOL KeybdDriverInitStates(
	INT			iKeybdId,						// @parm Id of the keyboard to initialize keystate data for.
	KEY_STATE   KeyState,                       // @parm Key state to initialize.
	void        *pKeybdDeviceToUnicodeState     // @parm Keyboard specific state to initialize.
	)
{
	TO_UNICODE_STATE	*pDemoState = (TO_UNICODE_STATE*)pKeybdDeviceToUnicodeState;
	int	i;

	//	We have some state, so check for it.
	if ( pDemoState == NULL )
		{
		SetLastError(ERROR_INVALID_PARAMETER);
		return FALSE;
		}

	for ( i = 0; i < COUNT_VKEYS; i++ )
		{
		KeyState[i] = 0;
		}

	return TRUE;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_INIT_STATES v_pfnInitStatesTest = KeybdDriverInitStates;
#endif




/*++

MapLRVKeys:

Map left and right virtual keys to their common vkey.


Return Value:

The common vkey.

--*/
UINT32
MapLRVKeys(
	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.

--*/
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.


--*/
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;

//  Set the low order bits to reflect the current key.
	*pShiftStateFlags = ShiftFlags | KeyState[VKey];
	return;
}






/*
   The following defines will be used for converting the key pressed
   into a Unicode character using the context information (the state
   of other keys). We are assuming here that the count of bytes required
   for state info for Unicode character generation (cbToUnicodeState
   field in KEYBD_DRIVER_INFO structure) is zero, ie the driver does
   not maintain any state information (besides CAPS, SHIFT, ALT and
   CONTROL state) for Unicode character generation.
   The Unicode character generated depends on the key pressed and
   the state of the following keys: CAPS, SHIFT, ALT and CONTROL. Hence
   for every Virtual key generated by  the PDD, there can be a total of
   16 different Unicode Characters  in the worst case. Since there are
   a total of 256 different virtual keys  possible, storing all possible
   states would require a lot of memory. Hence rows which are together
   have been grouped and columns which have the same corresponding values
   in every row of the group have been merged together to minimise storage.
   */

#define NO_CHAR         255
#define FIRST_COLUMN    0
#define SECOND_COLUMN   1
#define THIRD_COLUMN    2
#define FOURTH_COLUMN   3

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -