Reputation: 1132
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.
Upvotes: 0
Views: 521
Reputation: 7051
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
Upvotes: 1