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

📄 kbdjpn.cpp

📁 此代码为WCE5.0下键盘驱动的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

The basic pattern for each special key is to see if we are already sending
a virtual key and auto-repeat it or check if its particular modifier is
down and send the modified key or just send the unmodified key.

For modified keys, we need to make it look like the modifier key went up
and then the desired virtual key went down.  Additionally, when the
modifier is the Alt key, we need to send a null character before the Alt
up so that menus do not activate.

--*/
static
UINT
ATJpn2RemapVKeyDown(
	UINT32			VirtualKey,
	UINT32			ScanCode,
	KEY_STATE_FLAGS	KeyStateFlags,
	UINT32			*RemapVKeyBuf,
	UINT32			*RemapScanCodeBuf,
	KEY_STATE_FLAGS	*RemapKeyStateFlagsBuf
	)
{
	UINT32	vkDown;
	UINT32	scDown;
	UINT32	vkOnly = VirtualKey & 0xff;		//	Just the vkey
	UINT32	vkOther = VirtualKey & ~0xff;	//	Just the other stuff

	//	Normally, we just send the vkey that came in.
	vkDown = vkOnly;
	scDown = ScanCode;

	// If the incoming key is a shift modifier of some sort, turn off keyclick autorepeat by default.
	// We will allow the shift key to click on the first press, since many keyboards don't have built-in
	// sound generators and users appreciate audible feedback when they press a key.
	if(IsShiftModifier(vkOnly) || vkOnly == VK_CAPITAL || vkOnly == VK_NUMLOCK) {
		vkDown |= KEYBD_DEVICE_SILENT_REPEAT;
	}

    if ( vkOnly == VK_RCONTROL )
        {
        v_bRCtrlDown = TRUE;
        }
    else if ( vkOnly == VK_LCONTROL )
        {
        v_bLCtrlDown = TRUE;
        }
    else if ( vkOnly == VK_RMENU )
        {
        v_bRAltDown = TRUE;
        }
    else if ( vkOnly == VK_LMENU )
        {
        v_bLAltDown = TRUE;
        }
	else if ( vkOnly == VK_LSHIFT )
		{
		v_bLShiftDown = TRUE;
		}
	else if ( vkOnly == VK_RSHIFT )
		{
		v_bRShiftDown = TRUE;
		}
	else if ( vkOnly == VK_DBE_SBCSCHAR )
		{
		if ( v_vkFullHalfSent )
			{
			vkDown = v_vkFullHalfSent;
			scDown = v_scFullHalfSent;
			}
		else if ( ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() )
			{
			vkDown = v_vkFullHalfSent = VK_KANJI;
			v_scFullHalfSent = ScanCode;
			}
		else
			{
//	Don't use imm function if not configured.
//	The remapping won't work correctly but at least there won't be link errors.
			DWORD	fdwConversion;
			DWORD	fdwSentence;
			if ( ImmGetConversionStatus(NULL, &fdwConversion, &fdwSentence) )
				{
				if ( fdwConversion & IME_CMODE_FULLSHAPE )
					{
					vkDown = v_vkFullHalfSent = VK_DBE_SBCSCHAR;
					v_scFullHalfSent = ScanCode;
					}
				else
					{
					vkDown = v_vkFullHalfSent = VK_DBE_DBCSCHAR;
					v_scFullHalfSent = ScanCode;
					}
				}
			else
				{
				vkDown = v_vkFullHalfSent = VK_DBE_SBCSCHAR;
				v_scFullHalfSent = ScanCode;
				}
			}
		}
	else if ( vkOnly == VK_DBE_ALPHANUMERIC )
		{
		if ( v_vkAlphaNumSent )
			{
			vkDown = v_vkAlphaNumSent;
			scDown = v_scAlphaNumSent;
			}
		else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() )
			{
			vkDown = v_vkAlphaNumSent = VK_DBE_ALPHANUMERIC;
			v_scAlphaNumSent = ScanCode;
			}
		else
			{
			vkDown = v_vkAlphaNumSent = VK_CAPITAL;
			v_scAlphaNumSent = ScanCode;
			}
		}
	else if ( vkOnly == VK_DBE_HIRAGANA )
		{
		if ( v_vkHiraKataSent )
			{
			vkDown = v_vkHiraKataSent;
			scDown = v_scHiraKataSent;
			}
		else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() )
			{
			vkDown = v_vkHiraKataSent = VK_DBE_KATAKANA;
			v_scHiraKataSent = ScanCode;
			}
		else if ( !ANY_ALT_DOWN() && ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() )
			{
			vkDown = v_vkHiraKataSent = VK_KANA;
			v_scHiraKataSent = ScanCode;
			}
		else if ( ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() )
			{
			DWORD	fdwConversion;
			DWORD	fdwSentence;
			if ( ImmGetConversionStatus(NULL, &fdwConversion, &fdwSentence) )
				{
				if ( fdwConversion & IME_CMODE_ROMAN )
					{
					vkDown = v_vkHiraKataSent = VK_DBE_NOROMAN;
					v_scHiraKataSent = ScanCode;
					}
				else
					{
					vkDown = v_vkHiraKataSent = VK_DBE_ROMAN;
					v_scHiraKataSent = ScanCode;
					}
				}
			else
				{
				vkDown = v_vkHiraKataSent = VK_DBE_NOROMAN;
				v_scHiraKataSent = ScanCode;
				}
			}
		}

	//	Finally!  Send the key down.
	*RemapVKeyBuf = vkDown | vkOther;
	*RemapScanCodeBuf = scDown;
	*RemapKeyStateFlagsBuf = KeyStateDownFlag;

	return 1;
}



/*++

KeybdDriverRemapKeyUp:

On a key up, undo all of the virtual key re-mapping on the keyboard.


Notes:

When a special key is released, we send an up event for whatever virtual
key was original sent as going down.

If the special key's modifier key is still down, we send a down event for
it to keep the state consistent.  (We earlier sent an up event for the modifier
when the special key went down.).

We remember if the modifier key we are resending the down for is the Alt
key.  If it is, when it is really released, we send a null through the
system to keep menus from activating.  Otherwise, menus would see this
down followed directly by an Alt up and so would activate.

--*/
static
UINT
ATJpn2RemapVKeyUp(
	UINT32			VirtualKey,
	UINT32			ScanCode,
	KEY_STATE_FLAGS	KeyStateFlags,
	UINT32			*RemapVKeyBuf,
	UINT32			*RemapScanCodeBuf,
	KEY_STATE_FLAGS	*RemapKeyStateFlagsBuf
	)
{
	UINT32	vkUp;
	UINT32	scUp;
	UINT32	vkOnly = VirtualKey & 0xff;		// Just the vkey
	UINT32	vkOther = VirtualKey & ~0xff;	// Just the other stuff

	//	The key up we send is usually this.
	vkUp = vkOnly;
	scUp = ScanCode;

    if ( vkOnly == VK_RCONTROL )
        {
        v_bRCtrlDown = FALSE;
        }
    else if ( vkOnly == VK_LCONTROL )
        {
        v_bLCtrlDown = FALSE;
        }
    else if ( vkOnly == VK_RMENU )
        {
        v_bRAltDown = FALSE;
        }
    else if ( vkOnly == VK_LMENU )
        {
        v_bLAltDown = FALSE;
        }
	else if ( vkOnly == VK_LSHIFT )
		{
		v_bLShiftDown = FALSE;
		}
	else if ( vkOnly == VK_RSHIFT )
		{
		v_bRShiftDown = FALSE;
		}
	else if ( vkOnly == VK_DBE_SBCSCHAR )
		{
		vkUp = v_vkFullHalfSent;
		scUp = v_scFullHalfSent;
		v_vkFullHalfSent = 0;
		}
	else if ( vkOnly == VK_DBE_ALPHANUMERIC )
		{
		vkUp = v_vkAlphaNumSent;
		scUp = v_scAlphaNumSent;
		v_vkAlphaNumSent = 0;
		}
	else if ( vkOnly == VK_DBE_HIRAGANA )
		{
		vkUp = v_vkHiraKataSent;
		scUp = v_scHiraKataSent;
		v_vkHiraKataSent = 0;
		}

	//	Send the virtual key up.
	*RemapVKeyBuf = vkUp | vkOther;
	*RemapScanCodeBuf = scUp;
	*RemapKeyStateFlagsBuf = 0;

	return 1;
}


static
UINT
WINAPI
ATJpn2RemapVKey(
    const KEYBD_EVENT *pKbdEvents,
    UINT               cKbdEvents,
    KEYBD_EVENT       *pRmpKbdEvents,
    UINT               cMaxRmpKbdEvents
    )
{
    static const DWORD cMapping = 1; // 1 to 1 mapping
    PFN_KEYBD_REMAP pfnNumPadRemap = NULL;

    UINT (*pfnRemap)(UINT32, UINT32, KEY_STATE_FLAGS, 
        UINT32*, UINT32*, KEY_STATE_FLAGS*) = NULL;
    UINT cRmpKbdEvents;

    if (pRmpKbdEvents == NULL) {
        // 1 to 1 mapping for whatever NumPadRemapVKey returns
        ASSERT(cMaxRmpKbdEvents == 0);
        return cMapping * NumPadRemapVKey(pKbdEvents, cKbdEvents, NULL, 0);
    }
    
    ASSERT(pKbdEvents != NULL);

    // We know that we will only map one input to one output. Thus, we only
    // need for NumPadRemapVKey() to check the number of input events since
    // we will not use more than it does. If the buffer is not large enough
    // cRmpKbdEvents will be 0 and we will return 0.
    cRmpKbdEvents = NumPadRemapVKey(pKbdEvents, cKbdEvents, 
        pRmpKbdEvents, cMaxRmpKbdEvents);

    for (UINT ui = 0; ui < cRmpKbdEvents; ++ui) 
    {        
        if ((pRmpKbdEvents[ui].KeyStateFlags & KeyStateDownFlag) != 0) {
            pfnRemap = ATJpn2RemapVKeyDown;
        }
        else {
            pfnRemap = ATJpn2RemapVKeyUp;
        }

        PREFAST_ASSERT(pfnRemap != NULL);
        
        UINT cKeys = (*pfnRemap)(pRmpKbdEvents[ui].uiVk, pRmpKbdEvents[ui].uiSc, 
            pRmpKbdEvents[ui].KeyStateFlags, &pRmpKbdEvents[ui].uiVk,
            &pRmpKbdEvents[ui].uiSc, &pRmpKbdEvents[ui].KeyStateFlags);
        ASSERT(cKeys == cMapping);
    }
    
    return cRmpKbdEvents;
}
#ifdef DEBUG
// Verify function declaration against the typedef.
static PFN_KEYBD_REMAP v_pfnRemapVKey = ATJpn2RemapVKey;
#endif


static DEVICE_LAYOUT dlATJpn2 =
{
    sizeof(DEVICE_LAYOUT),
    PS2_AT_PDD | PS2_NOP_PDD,
    rgscvkATJpn2Tables,
    dim(rgscvkATJpn2Tables),
    ATJpn2RemapVKey,
};

extern "C"
BOOL
PS2_AT_00000411(
    PDEVICE_LAYOUT pDeviceLayout
    )
{
    PREFAST_ASSERT(pDeviceLayout != NULL);

    BOOL fRet = FALSE;

    if (pDeviceLayout->dwSize != sizeof(DEVICE_LAYOUT)) {
        RETAILMSG(1, (_T("PS2_AT_00000411: data structure size mismatch\r\n")));
        goto leave;
    }

    // Make sure that the Sc->Vk tables are the sizes that we expect
    ASSERT(dim(ScanCodeToVKeyTable  ) == (1 + ScanCodeTableLast   - ScanCodeTableFirst  ));
    ASSERT(dim(E0ScanCodeToVKeyTable) == (1 + E0ScanCodeTableLast - E0ScanCodeTableFirst));
    ASSERT(dim(E1ScanCodeToVKeyTable) == (1 + E1ScanCodeTableLast - E1ScanCodeTableFirst));

    *pDeviceLayout = dlATJpn2;

    fRet = TRUE;

leave:
    return fRet;
}
#ifdef DEBUG
// Verify function declaration against the typedef.
static PFN_DEVICE_LAYOUT_ENTRY v_pfnDLEntry = PS2_AT_00000411;
#endif

⌨️ 快捷键说明

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