windows系统下ASCII码与键值的转换

此文章中仅考虑键盘可直接打出的字符,不考虑特殊符号(如♂♀等)及汉字等非 ASCII 码字符。

我们可以简单地将键盘上的可显示字符分为以下几类:

一、大写字母(A~Z);

二、小写字母(a~z);

三、数字(0~9);

四、小键盘功能运算符(+-*/.);

五、数字区符号(!@#$%^&*());

六、标点区符号(-_=+[{]};:'",<.>/?\|以及空格、回车符号)

七、特殊符号(这里特指 Tilde符 `~);


根据上述分类,我们可以发现,对于每个字符的按键,我们可以将之划分属性如下:

一、字母类

1、大写字母:大写,字母

2、小写字母:小写,字母

二、非字母类

1、 shift + 标点区符号:shift,标点

2、 标点区符号:无shift,标点

3、shift+ 数字区或Tilde符号 :shift,数字或Tilde

(小键盘所有字符均可在主键盘区打出,故不计)

我们这时候可以定义一个数据体,用来记录ASCII转换后对应的按键属性。

typedef unsigned short Rc_bVK ;

每一个 RedContritio_bVK 共有16位二进制,我们使用低八位存储其键值,高八位用途分割如下:

0x8000 & bvk 表示该按键是否属于字母

0x4000 & bvk 当该按键是字母时,表示是否小写;当该按键非字母时,表示是否有shift。

0x2000 & bvk 表示该按键是否位于主键盘(在此程序无意义)

其余位空余,为将来可能的扩展预留。


由于我们已经知道大写字母的ASCII和键值相等,我们可以写出下面的转换代码:

	if( ascii >= 'A' && ascii <= 'Z' )
	{
		return (Rc_bVK)( 0xA000 | ascii );
	}
	if( ascii >= 'a' && ascii <= 'z' )
	{
		return (Rc_bVK)( 0xE000 | (ascii-0x20) );
	}
同样的,因为主键盘数字区的键值等于数字ASCII码,所以有
	if( ascii >= '0' && ascii <= '9' )
	{
		return (Rc_bVK)( 0x2000 | (ascii) );
	}
接下来就开始逐符号记录键值,根据度娘我们显然可以得到这张(种)图 (清晰度略低)

windows系统下ASCII码与键值的转换_第1张图片

综上,我们可以得到下面这个 ascii 向 键值记录体(RedContritio_bVK)转换的函数。

Rc_bVK atoRCv(unsigned char ascii)
{
	if( ascii >= 'A' && ascii <= 'Z' )
	{
		return (Rc_bVK)( 0xA000 | ascii );
	}
	if( ascii >= 'a' && ascii <= 'z' )
	{
		return (Rc_bVK)( 0xE000 | (ascii-0x20) );
	}
	if( ascii >= '0' && ascii <= '9' )
	{
		return (Rc_bVK)( 0x2000 | (ascii) );
	}
	switch( ascii )
	{
		case 0x0A :	return (Rc_bVK)( 0X2000 | VK_RETURN );
		case 0x20 :	return (Rc_bVK)( 0x2000 | VK_SPACE );
		case 0x21 :	return (Rc_bVK)( 0x6000 | 0x31 );
		case 0x22 :	return (Rc_bVK)( 0x6000 | VK_OEM_7 );
		case 0x23 :	return (Rc_bVK)( 0x6000 | 0x33 );
		case 0x24 :	return (Rc_bVK)( 0x6000 | 0x34 );
		case 0x25 :	return (Rc_bVK)( 0x6000 | 0x35 );
		case 0x26 :	return (Rc_bVK)( 0x6000 | 0x37 );
		case 0x27 :	return (Rc_bVK)( 0x2000 | VK_OEM_7 );
		case 0x28 :	return (Rc_bVK)( 0x6000 | 0x39 );
		case 0x29 :	return (Rc_bVK)( 0x6000 | 0x30 );
		case 0x2A :	return (Rc_bVK)( 0x6000 | 0x38 );
		case 0x2B :	return (Rc_bVK)( 0x6000 | VK_OEM_PLUS );
		case 0x2C :	return (Rc_bVK)( 0x2000 | VK_OEM_COMMA );
		case 0x2D :	return (Rc_bVK)( 0x2000 | VK_OEM_MINUS );
		case 0x2E :	return (Rc_bVK)( 0x2000 | VK_OEM_PERIOD );
		case 0x2F :	return (Rc_bVK)( 0x2000 | VK_OEM_2 );
		case 0x3A :	return (Rc_bVK)( 0x6000 | VK_OEM_1 );
		case 0x3B :	return (Rc_bVK)( 0x2000 | VK_OEM_1 );
		case 0x3C :	return (Rc_bVK)( 0x6000 | VK_OEM_COMMA );
		case 0x3D :	return (Rc_bVK)( 0x2000 | VK_OEM_PLUS );
		case 0x3E :	return (Rc_bVK)( 0x6000 | VK_OEM_PERIOD );
		case 0x3F :	return (Rc_bVK)( 0x6000 | VK_OEM_2 );
		case 0x40 :	return (Rc_bVK)( 0x6000 | 0x32 );
		case 0x5B :	return (Rc_bVK)( 0x2000 | VK_OEM_4 );
		case 0x5C :	return (Rc_bVK)( 0x2000 | VK_OEM_5 );
		case 0x5D :	return (Rc_bVK)( 0x2000 | VK_OEM_6 );
		case 0x5E :	return (Rc_bVK)( 0x6000 | 0x36 );
		case 0x5F :	return (Rc_bVK)( 0x6000 | VK_OEM_MINUS );
		case 0x60 :	return (Rc_bVK)( 0x2000 | VK_OEM_3 );
		case 0x7B :	return (Rc_bVK)( 0x6000 | VK_OEM_4 );
		case 0x7C :	return (Rc_bVK)( 0x6000 | VK_OEM_5 );
		case 0x7D :	return (Rc_bVK)( 0x6000 | VK_OEM_6 );
		case 0x7E :	return (Rc_bVK)( 0x6000 | VK_OEM_3 );
		default :	return (Rc_bVK)( 0x0000 & ascii );
	}
}
然后我们就可以通过分析返回的键值记录体获取字符的输入条件了

你可能感兴趣的:(windows系统下ASCII码与键值的转换)