简体   繁体   中英

Detecting Key Events

I am having trouble trying to detect key events in the x86 assembly language. When I run my program, I get this generic error:

key.exe has encountered a problem and needs to close. We are sorry for the inconvenience.

fasm, my assembler, generates a .bin file, a .exe file, and a .com file. If I try running the .com file, a message box pops up saying that the image file is valid, but is for a machine type other than the current machine.

Here is my code:

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

I am using a x64 edition of windows xp, but it is compatible with 32-bit applications.

If you are creating Win32 program, you can't use DOS API ( int 21h ) in order to get pressed keys.

You should use ReadConsoleInput function and check for keyboard events.

Here is how this can be done:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM