获得键盘扫描码
2007-01-13 20:13:53 来源:WEB开发网核心提示:概述:在编制键盘输入程序时常常要用到一个键的扫描码或ASC码,如用到 Foxpro 的 inkey() 函数,获得键盘扫描码,以及用到 BIOS 的 INT 16H时,但找一个编码表不太容易,可读性也大大增强了,如果要继续添加分支时,只需在表中加上一项就行,有时候找到的编码表又不全,无法查到组合键的编码
概述:
在编制键盘输入程序时常常要用到一个键的扫描码或ASC码,如用到 Foxpro 的 inkey() 函数,以及用到 BIOS 的 INT 16H时,但找一个编码表不太容易,有时候找到的编码表又不全,无法查到组合键的编码,本程序就是一个随时用来显示按键的ASC码及扫描码的程序,可以用 16 进制和 10 进制同时显示一个键按下和放开的扫描码,以及ASC码,同样也支持组合键。这里是编译好的可执行文件:scancode.com
在本程序中,查表的编程方法可用做参考,一般来说,如果程序有以下的结构:
...
cmp al,value1
jz offset1
cmp al,value2
jz offset2
cmp al,value3
jz offset3
...
且要比较的值很多时,可以考虑查表的方法。程序改为以下结构后,修改起来很容易,可读性也大大增强了,如果要继续添加分支时,只需在表中加上一项就行。
...
table db value1,value2,value3 ...
table1 dw offset1,offset2,offset3 ...
mov di,offset table
mov cx,table的长度
repnz scasb
jnz not_found
dec di
sub di,offset table ;取出表的地址
mov si,di
shl si,1 ;x2
add si,offset table1
jmp [si] ;跳转到表中的地址
...
源程序:
; Scan code viewer
; Aug 3,1995
; by Luo Yun Bin
.286
CODE SEGMENT
ASSUME CS:CODE,DS:CODE
ORG 100H
start:
jmp install
KEY_BUFF DB ? ;INT 9H中按下一个键产生的扫描码
KEY_BUFF1 DB ? ;INT 9H中松开一个键产生的扫描码
AAH DB ?
AAL DB ?
D_COPYRIGHT DB "<< ScanCode viewer >>",0dh,0ah
DB '(C) Copyright by Luo Yun Bin, May 26,1996',0dh,0ah
DB 'Phone: 0576-4114689.',0dh,0ah,0ah
DB "Press any key to view it's scan code...",0dh,0ah
DB 'or press Esc key to return DOS...',0dh,0ah,0ah,24h
D_MES1 DB 'Scan Code: %02shh (%2sd) ... '
DB 'Release: %02shh (%3sd) ... Key: ',0
DW KEY_BUFF,KEY_BUFF,KEY_BUFF1,KEY_BUFF1
D_MES2 DB 0dh,0ah,0
D_MES3 DB 'Key value: %02sh%02shh ...... '
DB '(AH=%sd,AL=%sd)',0dh,0ah,0ah,0
DW AAH,AAL,AAH,AAL
D_MES4 DB 'This is Scan Code viewer by LYB.',0dh,0ah,24h
;键盘扫描码编码表
; 0123456789abcdef ;
KEY_TABLE DB '??1234567890-=??' ;0
DB 'QWERTYUIOP[]??AS' ;1
DB "DFGHJKL;'`?XCV" ;2
DB 'BNM,./?*????????' ;3
DB '??????????-?5?+?' ;4
DB '????????????????' ;5
DB '????????????????' ;6
DB '????????????????' ;7
;特殊键的说明字符串编码表
KEY_TABLE1 DB 3bh,3ch,3dh,3eh,3fh,40h,41h,42h,43h,44h,57h,58h
DB 0eh,0fh,3ah,2ah,1dh,38h,36h,1ch,39h,1
DB 52h,53h,47h,4fh,49h,51h,48h,50h,4bh,4dh,46h,45h
;对应上表
KEY_TABLE1_END EQU THIS BYTE
DW f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12
DW bks,tab,cap,lsh,ctr,alt,rsh,ent,spa,_esc
DW _ins,del,hom,_end,pgu,pgd,up,dow,lef,rig,sco,num
;特殊键的说明字符串
f1 db 'F1',0 ;
f2 db 'F2',0
f3 db 'F3',0
f4 db 'F4',0
f5 db 'F5',0
f6 db 'F6',0
f7 db 'F7',0
f8 db 'F8',0
f9 db 'F9',0
f10 db 'F10',0
f11 db 'F11',0
f12 db 'F12',0
bks db 'Back Space',0
tab db 'Table',0
cap db 'Caps Lock',0
lsh db 'Left Shift',0
ctr db 'Ctrl',0
alt db 'Alt',0
rsh db 'Right Shift',0
ent db 'Enter',0
spa db 'Space',0
_ins db 'Insert',0
del db 'Delete',0
hom db 'Home',0
_end db 'End',0
pgu db 'Page Up',0
pgd db 'Page Down',0
up db 'Up',0
dow db 'Down',0
lef db 'Left',0
rig db 'Right',0
sco db 'Scroll Lock',0
num db 'Num Lock',0
_esc db 'Esc',0
PRINT_KEY PROC
mov bl,key_buff ;取扫描码到BL
xor bh,bh
mov al,key_table [bx] ;查扫描码表
cmp al,'?' ;如果为?则继续查特殊码表
jz pk1
pk0:
call prt_to_scr
ret
pk1:
mov al,key_buff ;在特殊码表内扫描
mov di,offset key_table1
mov cx,offset key_table1_end-offset key_table1
repnz scasb
jnz pk0
dec di
sub di,offset key_table1 ;取出说明字符串地址
mov si,di
shl si,1
add si,offset key_table1_end
mov si,[si]
call printf ;显示到屏幕
ret
PRINT_KEY ENDP
;新的 INT 09H 键盘中断程序
int9:
pushf
pusha
push ds
push es
push cs
pop ds
push cs
pop es
in al,60h ;读入扫描码
mov key_buff,al
test al,80h ;如果>80H则为放开一个键
jnz int9_quit
or al,80h
mov key_buff1,al
mov si,offset d_mes1
call printf
call print_key
mov si,offset d_mes2
call printf
int9_quit:
pop es
pop ds
popa
popf
DB 0EAH
OFF9 DW ?
SEG9 DW ?
install:
mov ah,9 ;显示版权信息
mov dx,offset d_copyright
int 21h
mov ax,3509h ;保留INT 09H的中断向量
int 21h
mov off9,bx
mov seg9,es
mov ax,2509h ;把INT 09H指到 offset int9
mov dx,offset int9
int 21h
push cs
pop es
lop:
mov ah,10h ;扩展键盘输入
int 16h
mov aah,ah ;显示键盘输入的编码
mov aal,al
mov si,offset d_mes3
call printf
cmp key_buff,1 ;如果非按下Esc,继续循环
jnz lop
lds dx,dword ptr off9 ;恢复INT 09H中断向量
mov ax,2509h
int 21h
push cs
pop ds
mov ah,9
mov dx,offset d_mes4
int 21h
int 20h
INCLUDEPRINTF.ASM ;一个公用的显示子程序
CODE ENDS
END START
更多精彩
赞助商链接