本帖最后由 -兔子- 于 2012-12-20 20:11 编辑
先说一下标准PS键盘接口的读取程序, 本程序短小精悍, 新手可以学学真正的工程软件的设计思路和考虑问题的方式。
首先说明一下为什么要这样读取按键内容, 因为好处大大滴。
首先响应快, 其次去掉了按键中断对主程序的打扰, 你就是一屁股坐键盘上也不会发出一连串讨厌的嘟嘟声:D,
同时可以将这个小程序放到其它公共调用例程或将其它公共调用例程嵌入到这个小程序中。
本例程工作的前提是在程序前先关闭系统的键盘中断。
Outp( 0x21, inp(0x21) | 0x02 );
有了这条语句, 键盘的控制权就完全拿到手了,除了你定义的按键操作, 其它的如:Ctrl+break, Ctrl+Alt+Del大 法统统失效。
也切断了通过按键中断进行程序破译和追踪的可能性。
另外, 直接可在表格中很方便的换码。
// ============== 键盘扫描码表==>键值码表转换 ======================
const uint near keyLL[ 96 ] =
{
// ESC 1 2 3 4 5 6
// [00] [01] [02] [03] [04] [05] [06] [07]
0x0000, 0x1B00, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036,
// 7 8 9 0 - = BackSpace Tab
// [08] [09] [0A] [0B] [0C] [0D] [0E] [0F]
0x0037, 0x0038, 0x0039, 0x0030, 0x002D, 0x003D, 0x003B, 0x0F00,
// Q W E R T Y U I
// [10] [11] [12] [13] [14] [15] [16] [17]
0x0051, 0x0057, 0x0045, 0x0052, 0x0054, 0x0059, 0x0055, 0x0049,
// O P [ ] Enter Ctrl A S
// [18] [19] [1A] [1B] [1C] [1D] [1E] [1F]
0x004F, 0x0050, 0x2300, 0x2500, 0x0D00, 0x1D00, 0x0041, 0x0053,
// D F G H J K L ;
// [20] [21] [22] [23] [24] [25] [26] [27]
0x0044, 0x0046, 0x0047, 0x0048, 0x004A, 0x004B, 0x004C, 0x2800,
// ' ` L_Shift \ Z X C V
// [28] [29] [2A] [2B] [2C] [2D] [2E] [2F]
0x2900, 0x0025, 0x2A00, 0x003A, 0x005A, 0x0058, 0x0043, 0x0056,
// B N M , . / R_Shift *
// [30] [31] [32] [33] [34] [35] [36] [37]
0x0042, 0x004E, 0x004D, 0x002C, 0x002E, 0x002F, 0x3600, 0x002A,
// Alt Sp F1 F2 F3 F4 F5
// [38] [39] [3A] [3B] [3C] [3D] [3E] [3F]
0x3800, 0x0020, 0x0000, 0x3B00, 0x3C00, 0x3D00, 0x3E00, 0x3F00,
// F6 F7 F8 F9 F10 NumLock Home
// [40] [41] [42] [43] [44] [45] [46] [47]
0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x002B, 0x0000, 0x4700,
// ↑ PgUp - ← 5_ → + End
// [48] [49] [4A] [4B] [4C] [4D] [4E] [4F]
0x4800, 0x4900, 0x4A00, 0x4B00, 0x003C, 0x4D00, 0x4E00, 0x4F00,
// ↓ PgDn Ins Del F11
// [50] [51] [52] [53] [54] [55] [56] [57]
0x5000, 0x5100, 0x5200, 0x5300, 0x0000, 0x0000, 0x0000, 0x5700,
// F12 L_Win R_Win
// [58] [59] [5A] [5B] [5C] [5D] [5E] [5F]
0x5800, 0x0000, 0x0000, 0x0028, 0x0029, 0x0000, 0x0000, 0x0000
};
/**************************************************************************
键盘扫描程序:
uint KEY_search( )
代入变量: 无
返回变量: 无
程序返回值: =0:无按键, =xxxx:按键值.
**************************************************************************/
uint KEY_search( )
{
static uint near keyn; // 保存上次调用返回键码值!
uchar keyc;
uint k;
keyc=inp(0x60); // 扫描键盘端口.
if ( keyc == 0xE0 ) return( keyn );
k = keyLL[ keyc ]; // 键码转换
if ( keyc <= 0x5F && k != 0 ) keyn = k; else keyn = 0;
return( keyn );
}
/**************************************************************************
键盘等待程序(判按键抬起有效)
uint KEY_wait( )
代入变量: 无
返回变量: 无
程序返回值: xxxx:按键值(非零值).
**************************************************************************/
uint KEY_wait( )
{
uint keyc;
while( TRUE )
{
keyc = KEY_search( );
if ( keyc != 0 )
{
do{ } while( KEY_search( ) == keyc );
break;
}
}
return( keyc );
}
声明下, 主程序退出时别忘了恢复中断, 否则就只好关机了。
|