Win32控制台程序写的游戏
奖励分:50-结算时间:2006-10-4 20:55。
我现在在编一个键盘测试软件(tc),这些键我都可以测试,但是只有那些特殊的键,比如WINDOWS键,测试不了。我问过老师,老师说我会调用DOS中断,但是我不知道怎么调用DOS中断。
那个专家给我写了个例子,或者加我QQ: 11567373。
解决这个问题我要给你加分!
问题补充:只需按下键盘上的一个键,然后显示在屏幕上的模拟键盘上。现在有五个特殊键不能考。请专家帮忙解答。如何通过DOS使它们中断,然后显示出来?
发问者:克拉克086-学者II
最佳答案
PC的键盘是智能键盘,相当于一台完整的电脑。键盘中有一个Intel 8048(或8049)单片机(处理器)来管理整个键盘上的字符键、功能键、控制键和组合键。当键盘上的某个按键被按下时,键盘上的处理器首先向电脑主机发出硬件中断请求,然后将该按键的扫描码以串行方式传输给电脑主机。在硬件中断的作用下,电脑主机调用INT 09H硬件中断读取键盘发送的扫描码并转换成ASCII码存储在键盘缓冲区。按下一个键发送关闭代码,松开该键时,发送断开代码。键盘处理中断程序从键盘I/O端口(端口地址为60H)读取一个字节的数据。如果读取数据的第七位是1,则表示该键已被释放(发送断开码)。如果第七位为0,表示按键被按下(发送关闭码),数据位0-6为0。键盘上的每个按键对应一个扫码,根据扫码可以唯一确定一个按键。键盘缓冲区位于0040:001EH -4000:003EH之间的BIOS数据区,长度为34字节,为FIFO循环队列。使用PC原有的键盘处理程序可以很方便的处理键盘,但是因为调用BIOS,所以响应比较慢。另外,当我们要同时处理几个键的时候(比如同时按下向上箭头键和向左箭头键来对角移动),原来的键盘中断程序是不能满足要求的,所以需要编写一个适合我们要求的键盘中断程序。
编写一个新的键盘中断程序来完成以下工作:
1.进入键盘中断程序。
2.从键盘I/O口60H读取一个字节的键码,存储在一个全局变量中,供主程序处理,或者将键码存储在数据表中。
3.读取控制寄存器61H,并在82h内完成一次OR运算。
4.将结果写回控制寄存器端口61H。
5.用7fh对控制寄存器完成一个AND运算,从而复位键盘触发器,告诉硬件已经处理了一个键,可以读取下一个键。
6.复位中断控制器8259,并向端口20h写入一个20h。
7.退出键盘中断程序。
先定义一组宏常量记录键值,包括128键盘扫描码:
#define KEY_A 0x1E
#define KEY_B 0x30
#define KEY_C 0x2e
#define KEY_D 0x20
#define KEY_E 0x12
#define KEY_F 0x21
#define KEY_G 0x22
#define KEY_H 0x23
#define KEY_I 0x17
#define KEY_J 0x24
#define KEY_K 0x25
#define KEY_L 0x26
#define KEY_M 0x32
#define KEY_N 0x31
#define KEY_O 0x18
#define KEY_P 0x19
#define KEY_Q 0x10
#define KEY_R 0x13
#define KEY_S 0x1f
#define KEY_T 0x14
#define KEY_U 0x16
#define KEY_V 0x2f
#define KEY_W 0x11
#define KEY_X 0x2d
#define KEY_Y 0x15
#define KEY_Z 0x2c
#define KEY_1 0x02
#定义关键字_2 0x03
#定义关键字_3 0x04
#定义关键字_4 0x05
#定义关键字_5 0x06
#定义关键字_6 0x07
#定义关键字_7 0x08
#定义关键字_8 0x09
#定义键_9 0
#define KEY_0 0x0b
#define KEY_DASH 0x0c /* _- */
#define KEY_EQUAL 0x0d /* += */
# define KEY _ lbrack 0x 1a/* {[*/
# define KEY _ rbrack 0x 1b/* }]*/
# define KEY _分号0x 27/*:;*/
# define KEY _ RQUOTE 0x 28/* ' */
#define KEY_LQUOTE 0x29 /* ~` */
# define KEY _ PERIOD 0x 33/* & gt;。*/
# define KEY _ COMMA 0x 34/* & lt;, */
#define KEY_SLASH 0x35 /*?/ */
# define KEY _反斜杠0x2b /* |\ */
#define KEY_F1 0x3b
#define KEY_F2 0x3c
#define KEY_F3 0x3d
#定义键_F4 0x3e
#define KEY_F5 0x3f
#定义键_F6 0x40
#定义键_F7 0x41
#定义键_F8 0x42
#定义键_F9 0x43
#define KEY_F10 0x44
#define KEY_ESC 0x01
#定义KEY_BACKSPACE 0x0e
#define KEY_TAB 0x0f
#define KEY_ENTER 0x1c
#define KEY_CONTROL 0x1d
#define KEY_LSHIFT 0x2a
#define KEY_RSHIFT 0x36
#define KEY_PRTSC 0x37
#define KEY_ALT 0x38
#定义键空间0x39
#define KEY_CAPSLOCK 0x3a
#define KEY_NUMLOCK 0x45
#define KEY_SCROLLLOCK 0x46
#define KEY_HOME 0x47
#define KEY_UP 0x48
#define KEY_PGUP 0x49
#define KEY_MINUS 0x4a
#define KEY_LEFT 0x4b
#define KEY_CENTER 0x4c
#define KEY_RIGHT 0x4d
#define KEY_PLUS 0x4e
#define KEY_END 0x4f
#define KEY_DOWN 0x50
#define KEY_PGDOWN 0x51
#define KEY_INS 0x52
#define KEY_DEL 0x53
然后定义两个字符数组来保存键盘状态:
char key_state[128],key _ pressed[128];
其中key_state[128]用于表示按键的当前状态,保存在key_pressed[128]中的值表示按下了哪些按键,1表示按下,0表示释放。
在挂起新的键盘中断之前,保存原键盘中断程序的地址,以便在程序运行后恢复。我们定义一个中断指针来存储原始地址:
void中断far(* old int 9 handler)();
1.安装新键盘中断程序的功能:
void安装键盘(void)
{
int I;
for(I = 0;我& lt128;i++)
key _ state[I]= key _ pressed[I]= 0;
old int 9 handler = get vect(9);
setvect(9,new int 9);
}
2.恢复旧键盘中断程序的功能:
键盘(void)
{
setvect(9,old int 9 handler);
}
3.新的键盘中断程序:
void远中断NewInt9(void)
{
无符号字符扫描码,temp
scan code = in portb(0x 60);
temp = inport b(0x 61);
outportb(0x61,temp | 0x 80);
outportb(0x61,temp & amp0x7f);
if(扫描码& amp0x80)
{
扫描代码和。= 0x7f
key _ state[scan code]= 0;
}
其他
{
key _ state[scan code]= 1;
key _ pressed[scan code]= 1;
}
outportb(0x20,0x 20);
}
4.读取按键状态的函数(在游戏中调用以确定哪些按键被按下):
int GetKey(int ScanCode)
{
int res
RES = key _ state[ScanCode]| key _ pressed[ScanCode];
key _ pressed[ScanCode]= 0;
返回res
}
例如:
if(GetKey(KEY_UP))
{
....
}
用于确定是否按下向上键。
-
信息来源于网络。
-
不过有个问题,就是这个程序可能还是检测不到win键,因为win键不是键盘的标准键。
响应者:无效的昵称-二级助理12-28 19:02
其他答案*** 2
让我从这里开始:
首先,启动Quick Basic时必须添加/l参数。如果你是4.5版,输入qb/l,如果你是7.1版,输入qbx/l,在程序开头写一行:' $ include:' QB . bi '(4.5版)' $ include:' qBx.bi' (7.65433)。
QB调用中的中断:
1.中断号,输入参数和返回参数。
2.InterruptX中断号、输入参数和返回参数。
注意:如果中断号为0~255,如果鼠标为51,则参数为REGTYPE。
这些词可以得到DOS的当前版本:
将reg DIM作为RegTypeX
Regs.ax = &H3000
中断& ampH21,规则,规则
dos version $ = LTRIM $(STR $(regs . ax MOD 256))+" "+ LTRIM$(STR$(INT(Regs.ax / 256)))
下面可以得到软驱的信息:
DIM reg AS RegType
注册= & ampH100
中断和。H13,注册,注册
IF reg.ax MOD 256 & lt& gt那么0
DEF SEG = 0
N% = PEEK。H43E)
定义分段
如果N%和1 & lt;& gt0,则Count% = 1
如果N%和2 & lt& gt0那么Count% = Count% + 1
SoftDiskCount% =计数%
如果…就会结束
受访者:
我和花王有点关系,QQ: 504988247
让我从这里开始:
首先,启动Quick Basic时必须添加/l参数。如果你是4.5版,输入qb/l,如果你是7.1版,输入qbx/l,在程序开头写一行:' $ include:' QB . bi '(4.5版)' $ include:' qBx.bi' (7.65433)。
QB调用中的中断:
1.中断号,输入参数和返回参数。
2.InterruptX中断号、输入参数和返回参数。
注意:如果中断号为0~255,如果鼠标为51,则参数为REGTYPE。
这些词可以得到DOS的当前版本:
将reg DIM作为RegTypeX
Regs.ax = &H3000
中断& ampH21,规则,规则
dos version $ = LTRIM $(STR $(regs . ax MOD 256))+" "+ LTRIM$(STR$(INT(Regs.ax / 256)))
下面可以得到软驱的信息:
DIM reg AS RegType
注册= & ampH100
中断和。H13,注册,注册
IF reg.ax MOD 256 & lt& gt那么0
DEF SEG = 0
N% = PEEK。H43E)
定义分段
如果N%和1 & lt;& gt0,则Count% = 1
如果N%和2 & lt& gt0那么Count% = Count% + 1
SoftDiskCount% =计数%
如果…就会结束
被调查人:陈_ k _ y-经理四级12-27 01:45
-
PC的键盘是智能键盘,相当于一台完整的电脑。键盘中有一个Intel 8048(或8049)单片机(处理器)来管理整个键盘上的字符键、功能键、控制键和组合键。当键盘上的某个按键被按下时,键盘上的处理器首先向电脑主机发出硬件中断请求,然后将该按键的扫描码以串行方式传输给电脑主机。在硬件中断的作用下,电脑主机调用INT 09H硬件中断读取键盘发送的扫描码并转换成ASCII码存储在键盘缓冲区。按下一个键发送关闭代码,松开该键时,发送断开代码。键盘处理中断程序从键盘I/O端口(端口地址为60H)读取一个字节的数据。如果读取数据的第七位是1,则表示该键已被释放(发送断开码)。如果第七位为0,表示按键被按下(发送关闭码),数据位0-6为0。键盘上的每个按键对应一个扫码,根据扫码可以唯一确定一个按键。键盘缓冲区位于0040:001EH -4000:003EH之间的BIOS数据区,长度为34字节,为FIFO循环队列。使用PC原有的键盘处理程序可以很方便的处理键盘,但是因为调用BIOS,所以响应比较慢。另外,当我们要同时处理几个键的时候(比如同时按下向上箭头键和向左箭头键来对角移动),原来的键盘中断程序是不能满足要求的,所以需要编写一个适合我们要求的键盘中断程序。
编写一个新的键盘中断程序来完成以下工作:
1.进入键盘中断程序。
2.从键盘I/O口60H读取一个字节的键码,存储在一个全局变量中,供主程序处理,或者将键码存储在数据表中。
3.读取控制寄存器61H,并在82h内完成一次OR运算。
4.将结果写回控制寄存器端口61H。
5.用7fh对控制寄存器完成一个AND运算,从而复位键盘触发器,告诉硬件已经处理了一个键,可以读取下一个键。
6.复位中断控制器8259,并向端口20h写入一个20h。
7.退出键盘中断程序。
先定义一组宏常量记录键值,包括128键盘扫描码:
#define KEY_A 0x1E
#define KEY_B 0x30
#define KEY_C 0x2e
#define KEY_D 0x20
#define KEY_E 0x12
#define KEY_F 0x21
#define KEY_G 0x22
#define KEY_H 0x23
#define KEY_I 0x17
#define KEY_J 0x24
#define KEY_K 0x25
#define KEY_L 0x26
#define KEY_M 0x32
#define KEY_N 0x31
#define KEY_O 0x18
#define KEY_P 0x19
#define KEY_Q 0x10
#define KEY_R 0x13
#define KEY_S 0x1f
#define KEY_T 0x14
#define KEY_U 0x16
#define KEY_V 0x2f
#define KEY_W 0x11
#define KEY_X 0x2d
#define KEY_Y 0x15
#define KEY_Z 0x2c
#define KEY_1 0x02
#定义关键字_2 0x03
#定义关键字_3 0x04
#定义关键字_4 0x05
#定义关键字_5 0x06
#定义关键字_6 0x07
#定义关键字_7 0x08
#定义关键字_8 0x09
#定义键_9 0
#define KEY_0 0x0b
#define KEY_DASH 0x0c /* _- */
#define KEY_EQUAL 0x0d /* += */
# define KEY _ lbrack 0x 1a/* {[*/
# define KEY _ rbrack 0x 1b/* }]*/
# define KEY _分号0x 27/*:;*/
# define KEY _ RQUOTE 0x 28/* ' */
#define KEY_LQUOTE 0x29 /* ~` */
# define KEY _ PERIOD 0x 33/* & gt;。*/
# define KEY _ COMMA 0x 34/* & lt;, */
#define KEY_SLASH 0x35 /*?/ */
# define KEY _反斜杠0x2b /* |\ */
#define KEY_F1 0x3b
#define KEY_F2 0x3c
#define KEY_F3 0x3d
#定义键_F4 0x3e
#define KEY_F5 0x3f
#定义键_F6 0x40
#定义键_F7 0x41
#定义键_F8 0x42
#定义键_F9 0x43
#define KEY_F10 0x44
#define KEY_ESC 0x01
#定义KEY_BACKSPACE 0x0e
#define KEY_TAB 0x0f
#define KEY_ENTER 0x1c
#define KEY_CONTROL 0x1d
#define KEY_LSHIFT 0x2a
#define KEY_RSHIFT 0x36
#define KEY_PRTSC 0x37
#define KEY_ALT 0x38
#定义键空间0x39
#define KEY_CAPSLOCK 0x3a
#define KEY_NUMLOCK 0x45
#define KEY_SCROLLLOCK 0x46
#define KEY_HOME 0x47
#define KEY_UP 0x48
#define KEY_PGUP 0x49
#define KEY_MINUS 0x4a
#define KEY_LEFT 0x4b
#define KEY_CENTER 0x4c
#define KEY_RIGHT 0x4d
#define KEY_PLUS 0x4e
#define KEY_END 0x4f
#define KEY_DOWN 0x50
#define KEY_PGDOWN 0x51
#define KEY_INS 0x52
#define KEY_DEL 0x53
然后定义两个字符数组来保存键盘状态:
char key_state[128],key _ pressed[128];
其中key_state[128]用于表示按键的当前状态,保存在key_pressed[128]中的值表示按下了哪些按键,1表示按下,0表示释放。
在挂起新的键盘中断之前,保存原键盘中断程序的地址,以便在程序运行后恢复。我们定义一个中断指针来存储原始地址:
void中断far(* old int 9 handler)();
1.安装新键盘中断程序的功能:
void安装键盘(void)
{
int I;
for(I = 0;我& lt128;i++)
key _ state[I]= key _ pressed[I]= 0;
old int 9 handler = get vect(9);
setvect(9,new int 9);
}
2.恢复旧键盘中断程序的功能:
键盘(void)
{
setvect(9,old int 9 handler);
}
3.新的键盘中断程序:
void远中断NewInt9(void)
{
无符号字符扫描码,temp
scan code = in portb(0x 60);
temp = inport b(0x 61);
outportb(0x61,temp | 0x 80);
outportb(0x61,temp & amp0x7f);
if(扫描码& amp0x80)
{
扫描代码和。= 0x7f
key _ state[scan code]= 0;
}
其他
{
key _ state[scan code]= 1;
key _ pressed[scan code]= 1;
}
outportb(0x20,0x 20);
}
4.读取按键状态的函数(在游戏中调用以确定哪些按键被按下):
int GetKey(int ScanCode)
{
int res
RES = key _ state[ScanCode]| key _ pressed[ScanCode];
key _ pressed[ScanCode]= 0;
返回res
}
例如:
if(GetKey(KEY_UP))
{
....
}
用于确定是否按下向上键。