News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How can I say "You pressed Down Arrow Key" ?

Started by frktons, August 07, 2010, 10:56:21 PM

Previous topic - Next topic

frktons

I'm trying to figure how to intercept some keys from keyboard
but I don't find any suitable simple way, except using a bunch
of APIs.

The inkey macro doesn't seem to return any value, and I
am not sure if an alternative way exists inside the MASM32 package.

Can somebody help me with a sample code to intercept a key from
the keyboard in a console program, for example the "ESC" key
or any other key, just to have an idea how to proceed?

A sample that prints "You pressed the xxx key" would be great.

Thanks

Frank
Mind is like a parachute. You know what to do in order to use it :-)

jj2007

include \masm32\MasmBasic\MasmBasic.inc
   Init
   Inkey "Press any key", Cr$
   .Repeat
      Inkey "That was ", Chr$(eax), ", try again", Cr$
   .Until eax==VK_ESCAPE
   Exit
end start

dedndave

Frank, the wait_key proc will do what you want, i think
it is in masm32\m32lib\wait_key.asm, if you want to see how it works
it uses crt__kbhit and crt__getch functions from the ms vc rt library

jj2007

wait_key works fine, but Masm32 chr$() won't work as chr$(eax)

frktons

Quote from: jj2007 on August 07, 2010, 11:09:03 PM
include \masm32\MasmBasic\MasmBasic.inc
   Init
   Inkey "Press any key", Cr$
   .Repeat
      Inkey "That was ", Chr$(eax), ", try again", Cr$
   .Until eax==VK_ESCAPE
   Exit
end start


Thanks Jochen. It seems working only for letters, not for special
keys, arrows, Fx and so on.  ::)

Quote from: dedndave on August 07, 2010, 11:10:37 PM
Frank, the wait_key proc will do what you want, i think
it is in masm32\m32lib\wait_key.asm, if you want to see how it works
it uses crt__kbhit and crt__getch functions from the ms vc rt library

I tried to use the inkey macro and assembled a small prog to test it:

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Keyboard scancode: displays the code returned by inkey
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

INCLUDE \masm32\include\masm32rt.inc

Scan_code    PROTO :DWORD
Display_code PROTO :DWORD


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Data Area
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

.DATA

code_entered        dd 0

pcode               dd code_entered


.DATA?


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Code Area
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

.CODE

_main   PROC

;Scan the keyboard for key pressed

scan_cycle:

        INVOKE  Scan_code, code_entered
        cmp     eax, 27
        je      end_scan
        INVOKE  Display_code, eax
        jmp     scan_cycle
end_scan:       
        exit

_main   ENDP

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; ; display results
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

Display_code PROC    numx:DWORD

        mov     numx, eax

        print   "Your key has code: "

        mov     eax, numx

        print   str$(eax),13,10,13,10
        ret

Display_code ENDP


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Scancode Routine
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

Scan_code PROC  key_press:DWORD

;Returns: EAX = key code


        inkey "Press a key or ESC to close: ",13,10
        ret

Scan_code ENDP

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
        END     _main
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««


But guess what? I always get a "2" printed  ::)

What I did wrong?
Mind is like a parachute. You know what to do in order to use it :-)

dedndave

the inkey macro destroys the contents of eax
    inkey MACRO user_text:VARARG
      IFDIF <user_text>,<NULL>                  ;; if user text not "NULL"
        IFNB <user_text>                        ;; if user text not blank
          print user_text                       ;; print user defined text
        ELSE                                    ;; else
          print "Press any key to continue ..." ;; print default text
        ENDIF
      ENDIF
      call wait_key
      print chr$(13,10)  ;<------------- destroys eax
    ENDM


just use wait_key

frktons

Quote from: dedndave on August 07, 2010, 11:35:27 PM
oops

I used a similar approach:


        mov     numx, eax

        print   "Your key has code: "

        mov     eax, numx

        print   str$(eax),13,10,13,10


as you can see from the code I posted.  :P but it doesn't work.  ::)
Mind is like a parachute. You know what to do in order to use it :-)

dedndave

yah - the mov numx,eax is a wasted line, as numx is already equal to eax
see my previous post (updated)

sinsi

Light travels faster than sound, that's why some people seem bright until you hear them.

dedndave

that's the hard way, sinsi
plus, the crt functions overcome part of the bug in windows console

frktons

Quote from: dedndave on August 07, 2010, 11:40:59 PM
yah - the mov numx,eax is a wasted line, as numx is already equal to eax
see my previous post (updated)

Well, I used getkey and it works a little bit better  :P

The only problem is the up arrow key, for example returns the
same code "72" of "H". That's not what I like to get.  ::)

Quote from: sinsi on August 07, 2010, 11:43:26 PM
ReadConsoleInput

I know sinsi, but it is quite a long way. If you have any preassembled routine
that does the job, feel free to post it.  :P
Mind is like a parachute. You know what to do in order to use it :-)

dedndave

i don't know what could be easier than...
        call    wait_key
it waits for a key then, when one is pressed, returns its' value in EAX
i think that's just what you want

frktons

Quote from: dedndave on August 07, 2010, 11:49:41 PM
i don't know what could be easier than...
        call    wait_key
it waits for a key then, when one is pressed, returns its' value in EAX

From my previous BASIC language experience, I recall that some special keys, like
the arrow keys, return two bytes not one. As far as I've seen in getkey description
the function returns only one byte, and it could not be enough for all the keys.

The return value is written in the low byte of the EAX register.
EAX is zero extended so that it can be tested either as a DWORD or as a BYTE.

Maybe Hutch that wrote the function/macro can give us some idea on how to
use or modify it to cover the whole range.

Mind is like a parachute. You know what to do in order to use it :-)

sinsi


include \masm32\include\masm32rt.inc

.data?
stdin   dd ?
howmany dd ?
buffer  INPUT_RECORD <>

.code
start:  invoke GetStdHandle,STD_INPUT_HANDLE
        mov stdin,eax

again:  invoke ReadConsoleInput,stdin,offset buffer,1,offset howmany
        cmp buffer.EventType,KEY_EVENT
        jnz again
        cmp buffer.KeyEvent.wVirtualKeyCode,VK_ESCAPE
        jz finish
        cmp buffer.KeyEvent.wVirtualKeyCode,VK_DOWN
        jnz again
        print "You "
        cmp buffer.KeyEvent.bKeyDown,0
        jnz @1
        print "released"
        jmp @2
@1:     print "pressed"
@2:     print " Down Arrow Key"
        print chr$(13,10)
        jmp again
finish: invoke ExitProcess,0

end start
Light travels faster than sound, that's why some people seem bright until you hear them.

hutch--

Frank,

From memory you can use combinations of the API GetAsynchKeyState() in a console app loop and this will allow you to trap any set of key combinations. The MSVCRT based algos do most things OK but for a specialised requirement you may have to code it differently.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php