检测关键事件

时间:2013-04-13 23:02:36

标签: windows assembly fasm

我在尝试检测x86汇编语言中的关键事件时遇到问题。当我运行我的程序时,我得到了这个通用错误:

key.exe遇到问题需要关闭。我们对造成的不便很抱歉。

fasm,我的汇编程序,生成.bin文件,.exe文件和.com文件。如果我尝试运行.com文件,会弹出一个消息框,说明该图像文件有效,但是用于当前机器以外的机器类型。

这是我的代码:

include 'include/win32ax.inc'
section '.data' data readable writeable

inchar     DB ?
numwritten DD ?
numread    DD ?
outhandle  DD ?
inhandle   DD ?
char DB ?

     section '.text' code readable executable
     start:

    ;set up the console
invoke  AllocConsole
invoke  GetStdHandle,STD_OUTPUT_HANDLE
mov [outhandle],eax
invoke  GetStdHandle,STD_INPUT_HANDLE
mov [inhandle],eax

    ;get key press
mov ah,1h
int 21h
mov [char],AL

    ;print out the key pressed
invoke  WriteConsole,[outhandle],char,15,numwritten,0
invoke  ReadConsole,[inhandle],inchar,1,numread,0
invoke  ExitProcess,0

    .end start

我使用的是x64版本的windows xp,但它与32位应用程序兼容。

1 个答案:

答案 0 :(得分:1)

如果要创建Win32程序,则无法使用DOS API(int 21h)来获取按键。

您应该使用ReadConsoleInput功能并检查键盘事件。

以下是如何做到这一点:

include '%fasminc%/win32ax.inc'
section '.data' data readable writeable

struc KEY_EVENT_RECORD {
  .fKeyDown       dd  ?
  .Repeat         dw  ?
  .VirtKeyCode    dw  ?
  .VirtScanCode   dw  ?
  .res            dw  ?
  .char           dd  ?
  .ctrl           dd  ?
}

struc INPUT_RECORD {
  .type  dw ?
  .event KEY_EVENT_RECORD
}

KEY_EVENT = 1

inchar     DB ?
numwritten DD ?
numread    DD ?
outhandle  DD ?
inhandle   DD ?

input      INPUT_RECORD
count      dd ?


section '.text' code readable executable

start:

        ;set up the console
        invoke  AllocConsole
        invoke  GetStdHandle,STD_OUTPUT_HANDLE
        mov [outhandle],eax
        invoke  GetStdHandle,STD_INPUT_HANDLE
        mov [inhandle],eax


.loop:
        invoke  ReadConsoleInput, [inhandle], input, 1, count
        cmp     [count], 1
        jne     .loop
        cmp     [input.type], KEY_EVENT
        jne     .loop

            ;print out the key pressed
        invoke  WriteConsole,[outhandle],input.event.char,1,numwritten,0
        invoke  ReadConsole,[inhandle],inchar,1,numread,0
        invoke  ExitProcess,0

.end start