The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: frktons on August 07, 2010, 10:56:21 PM

Title: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 07, 2010, 10:56:21 PM
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
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: 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
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: 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
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: jj2007 on August 07, 2010, 11:20:17 PM
wait_key works fine, but Masm32 chr$() won't work as chr$(eax)
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 07, 2010, 11:26:18 PM
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?
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 07, 2010, 11:35:27 PM
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
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 07, 2010, 11:37:34 PM
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.  ::)
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: 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)
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: sinsi on August 07, 2010, 11:43:26 PM
ReadConsoleInput (http://msdn.microsoft.com/en-us/library/ms684961(VS.85).aspx)
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 07, 2010, 11:44:45 PM
that's the hard way, sinsi
plus, the crt functions overcome part of the bug in windows console
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 07, 2010, 11:48:25 PM
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 (http://msdn.microsoft.com/en-us/library/ms684961(VS.85).aspx)

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
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: 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
i think that's just what you want
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 07, 2010, 11:54:19 PM
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.

Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: sinsi on August 08, 2010, 12:16:01 AM

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
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: hutch-- on August 08, 2010, 12:22:13 AM
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.
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 08, 2010, 12:33:46 AM
Quote from: sinsi on August 08, 2010, 12:16:01 AM

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


Thanks sinsi. So we have to resort to API calling, as I suspected.  :P
This examples is really great. It shows how many API to call in order
to build a simple SWITCH/CASE proc based on key pressed by the user.  :U

Quote from: hutch-- on August 08, 2010, 12:22:13 AM
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.

Thanks Hutch, I didn't know that the C runtime library had this kind of function
inside. Probably if we knew more about it, we could realize that it has already everything
we are talking about.  ::)
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: GregL on August 08, 2010, 01:11:05 AM
frktons,

You can use the CRT function _getch (http://msdn.microsoft.com/en-us/library/078sfkak%28v=VS.80%29.aspx), if it is an extended key the return will be 0 or 0E0h and you must call _getch again. It then returns the scan code (http://msdn.microsoft.com/en-us/library/aa299374%28VS.60%29.aspx) for the extended key.

Here's an example of how you would do this:

INVOKE crt__getch
.IF (eax == 0) || (eax == 0E0h)
    INVOKE crt__getch
.ENDIF


The ret_key procedure in MASM32 uses this method. The getkey macro calls ret_key.
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: Ghandi on August 08, 2010, 01:12:56 AM
Quote
Thanks sinsi. So we have to resort to API calling, as I suspected.  

You are surprised Frank, when Win32 world has us abstracted from Interrupts and such, instead relyiing on the API to interface between userland and OS for the majority of things. Example, open a file handle without  using API.... Create a window.... Sure, we have control over our ASM code, but when it comes to interfacing with the OS, we're restricted to API. This is not taking in to account the glaringly obvious that of course, you could reverse engineer the operating system and recode the whole thing yourself, but that is not the question at hand.

HR,
Ghandi
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 08, 2010, 01:37:04 AM
try this one, Frank...
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 08, 2010, 03:42:57 AM
Quote from: Greg Lyon on August 08, 2010, 01:11:05 AM
frktons,

You can use the CRT function _getch (http://msdn.microsoft.com/en-us/library/078sfkak%28v=VS.80%29.aspx), if it is an extended key the return will be 0 or 0E0h and you must call _getch again. It then returns the scan code (http://msdn.microsoft.com/en-us/library/aa299374%28VS.60%29.aspx) for the extended key.

Here's an example:

.586
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE

INCLUDE windows.inc
INCLUDE kernel32.inc
INCLUDE msvcrt.inc

.CODE

GetKey PROC

    INVOKE crt__getch
    .IF (eax == 0) || (eax == 0E0h)
        INVOKE crt__getch
    .ENDIF
     
    ret
GetKey ENDP 

END


Thanks Greg, this function albeit not standard is present both in Pelles'C
and in MS C/C++ compiler, it could be a valid wrap on the underlying API.  :U

Quote from: Ghandi on August 08, 2010, 01:12:56 AM

Sure, we have control over our ASM code, but when it comes to interfacing with the OS, we're restricted to API.

HR,
Ghandi

Yes my friend, this is the world we are apparentely living in.  :bg

Quote from: dedndave on August 08, 2010, 01:37:04 AM
try this one, Frank...


Good enough, maybe this version covers all the keystrokes. At least all the ones I
tried have given reliable codes.  :U
I've to spend some time on it trying to understand what the two called functions
do and how can I customize them for my potential needs.  :P
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 08, 2010, 05:32:29 AM
well - just as Greg mentioned earlier....
if you call crt__getch and the lower byte of the return value is 0 or 0E0h, it means it is an "extended key"
that means you have to call the crt__getch function again to get the scancode
in my routine, i indicate this by placing it in the high byte of the word, instead of the low byte
also - my routine returns hex values instead of decimal (easier to understand)
so - when you see a value like "4300" or "43E0", it means it is an extended key, like an arrow or function key
when you see a value like "0043", it means it is not an extended key, and typically may be interpreted as normal ASCII

Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: jj2007 on August 08, 2010, 07:51:52 AM
Quote from: frktons on August 07, 2010, 11:26:18 PM
Thanks Jochen. It seems working only for letters, not for special
keys, arrows, Fx and so on.  ::)

include \masm32\MasmBasic\MasmBasic.inc
   Init
   Print "Press any key", Cr$
   call ret_key
   .Repeat
      .if ecx
         Print "That was an extended key with code ", Str$(eax), ", try again", Cr$
      .else
         Print "That was ", Chr$(eax), ", try again", Space$(27), Cr$
      .endif
      call ret_key
   .Until eax==VK_ESCAPE
   Exit
end start
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 08, 2010, 11:49:51 AM
there are some keys that do not work
but, i guess that is a characteristic of crt__getch
when you hold down the Alt key and enter a decimal with the ten-key pad,
it is supposed to generate that decimal key upon release of the Alt key - don't see that working
maybe i am doing something wrong - i may play with it, later, to see if i can get those keys
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 08, 2010, 04:43:52 PM
well - crt__getch must filter out the Alt-ten-key-pad characters
if you want to read those, you'll have to use ReadConsoleInput or one of the other less attractive methods
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 19, 2010, 12:28:43 AM
Here we have an example of key management similar to the ones I'll use in
my future console based MENUSYS.

It actually works only for arrow keys, F1, ESC, HOME, END keys
that will presumably be the ones I'll use the most in a menu'.

Attached the source code.

Any comment, improvement is welcome.  :bg
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 19, 2010, 01:35:30 AM
that is really the hard way to go, Frank
there are a number of issues that must be dealt with if you want to use ReadConsoleInput
first of all, not all event records that come into that function are keyboard presses
and, while ignoring the others may work for simple tests, it may not be what you want for a full program
that is because in practical use, you may have to handle some of the non-keyboard events, as well

second - and this is probably the big one
in order to fully interpret a key code, you must examine the state of the shift, alt, control, and windows keys
you may then need filtering code (maybe something like a look-up table) to determine what the actual keypress means
your code simply examines all key presses and ignores all key releases
that may not be what you want, either
you may want to filter out the shift/alt/control key presses, as well
because the state of these keys when another key is pressed is what counts
(there is a value in the structure for reading the state of these keys: dwControlKeyState)

that is why i suggested using kbhit and getch
much simpler, because the crt lib takes care of all this stuff for you

but, if you want to stick with that method, one function you may find interesting is PeekConsoleInput
it allows you to see if an input event record is in the queue, without calling ReadConsoleInput function
this may be used to allow your program to do other tasks while waiting for a keypress

i was thinking about how i might write a routine, if i wanted to capture the alt-ten-key-pad input
it might be easiest to code by using a hybrid of the 2 methods
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 19, 2010, 11:20:35 AM
Yes Dave, this is the hard way, but I think it's better to know something about it
before deciding to leave it or to use it and how.
I purposefully ignored the mouse events and key released, because at the moment
I'm only thinking about some keys to use in a Menu. If I had to manage the all
thing [mouse events, CTRL keys, ALT keys and so on] the routine would be bigger
than the program itself.  :bg      Well, a look-up table could help as well.

Maybe in a future time I'll need all these keys to manage an input byte by byte for
getting only numbers, or only letters, or only a fixed number of characters or
whatever. An input routine built this way could be quite hard indeed.  :lol

In the Vertical Menu I'm dreaming about the arrow keys would move from one choice
to the next or to the previous, or to the first or the last, and the ENTER key will
execute the choice, while the ESCAPE key will terminate the menu, or go back
to a previous one. And last but not least F1 will display some help about the choice
that is actually highlighted.

With this in my mind I made some choices in building the routine, but of course
it can, and probably will, change along the process. I'd like to build the MenuV
proc in different ways, learning from their different styles and needs, and deciding
which of them suits better the needs of the particular task I will undertake.  :P

If you feel like, build it your own way, and confronting the results and the limits
of various versions we'll see what happens.  :thumbu

PS: better if I post ASAP an Imagine, I mean a screen that you can display
with the routine we just realized elsewhere in order to make my idea a little bit clearer.

Posting soon...
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 19, 2010, 12:33:36 PM
Well, an imagine could explain better than 100 words  :P
This imagine is a complete console screen and needs the program
attached in order to be displayed.

This is a sample screen of the menu I have in mind. Time permitting
I'll post the code to manage it before going abroad for holydays.
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 01:13:06 AM
I'm preparing the menusys program, and I've reorganized it a little.
Apparently I've done something wrong:



;----------------------------------------------------------------------
; Reads a file containing a console screen format into an array
; of structure CHAR_INFO totalling 8000 bytes, and INVOKE the API
; to display it all at once: WriteConsoleOutput(). Wait a key and
; terminates the program.
;----------------------------------------------------------------------
; Input file: menusys.scn
;----------------------------------------------------------------------
; Author: frktons @ MASM32 forum
; Date: 20/aug/2010.
;----------------------------------------------------------------------


include \masm32\include\masm32rt.inc


Main        PROTO
ConsoleSize PROTO
GetConsole  PROTO
DisplayFmt  PROTO
InitProc    PROTO
AnyKey      PROTO
ShowCursor  PROTO
HideCursor  PROTO



;----------------------------------------------------------------------

BufRows EQU 25                 ;buffer height (rows)
BufCols EQU 80                 ;buffer width (columns)
BufLen  EQU BufRows*BufCols    ;string length (tchars)

;----------------------------------------------------------------------


.data


    ConTitle  db "       **  Win32 Console Menu System  **", 0   
    inpbyte   DWORD  1
    FmtName   db "menusys.scn",0 
         
         

.data?

    menusys CHAR_INFO 2000 dup (<>)
   

    hFile     HANDLE ?
    cci       CONSOLE_CURSOR_INFO <>       


    wHnd      HANDLE ?
    rHnd      HANDLE ?

    windowSize SMALL_RECT <>
    bufferSize COORD      <>
    startPoint COORD      <>

    howmany dd ?
    buffer  INPUT_RECORD <>


.code

start:

Main PROC

    INVOKE InitProc

    INVOKE ConsoleSize

    INVOKE GetConsole

    INVOKE DisplayFmt
       
    INVOKE AnyKey

    CALL   ShowCursor

finish: INVOKE ExitProcess,0

        ret

Main ENDP

; -------------------------------------------------------------------------   

ConsoleSize PROC

    INVOKE SetConsoleTitle, ADDR ConTitle
 
    CALL   HideCursor

    INVOKE SetConsoleWindowInfo, wHnd, TRUE, ADDR windowSize

    INVOKE SetConsoleScreenBufferSize, wHnd, DWORD PTR bufferSize

    ret

ConsoleSize ENDP

; -------------------------------------------------------------------------

GetConsole PROC

    mov hFile, fopen(DWORD PTR FmtName)

    mov ebx, fread(hFile, offset menusys, BufLen)
   
    fclose hFile

    ret
   
GetConsole ENDP

; -------------------------------------------------------------------------

ShowCursor PROC

    INVOKE GetConsoleCursorInfo,wHnd,addr cci
    mov cci.bVisible,TRUE
    INVOKE SetConsoleCursorInfo,wHnd,addr cci
    ret
   
ShowCursor ENDP

; -------------------------------------------------------------------------
   


HideCursor PROC

    INVOKE GetConsoleCursorInfo,wHnd,addr cci
    mov cci.bVisible,FALSE
    INVOKE SetConsoleCursorInfo,wHnd,addr cci
    ret
   
HideCursor ENDP

; -------------------------------------------------------------------------

InitProc PROC

    INVOKE GetStdHandle, STD_INPUT_HANDLE
    mov rHnd,eax

    INVOKE GetStdHandle, STD_OUTPUT_HANDLE
    mov wHnd,eax 

    mov windowSize.Left, 0
    mov windowSize.Right, 79
    mov windowSize.Top, 0
    mov windowSize.Bottom, 24
   

    mov bufferSize.x, 80
    mov bufferSize.y, 25

    mov startPoint.x, 0
    mov startPoint.y, 0


    ret

InitProc ENDP

; -------------------------------------------------------------------------

DispalyFmt PROC

    INVOKE WriteConsoleOutput, wHnd, offset menusys, DWORD PTR bufferSize,
           DWORD PTR startPoint, offset windowSize

    ret

DispalyFmt ENDP

; -------------------------------------------------------------------------
;Returns: key code in buffer.KeyEvent.wVirtualKeyCode WORD size
; -------------------------------------------------------------------------

Anykey PROC

again: 

    INVOKE ReadConsoleInput,rHnd,offset buffer,1,offset howmany
    cmp buffer.EventType,KEY_EVENT
    jnz again

    cmp buffer.KeyEvent.bKeyDown,0
    jz again

    ret

Anykey ENDP

; -------------------------------------------------------------------------

end start



When I try to Assemble it I get this error message:


Microsoft (R) Macro Assembler Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

Assembling: C:\masm32\examples\viewfmt\menusys.asm
C:\masm32\examples\viewfmt\menusys.asm(123) : error A2111:conflicting parameter
definition
_
Assembly Error


and the line where it gives this error is:


ShowCursor PROC  <----------- here it is

    INVOKE GetConsoleCursorInfo,wHnd,addr cci
    mov cci.bVisible,TRUE
    INVOKE SetConsoleCursorInfo,wHnd,addr cci
    ret
   
ShowCursor ENDP


So I presume it refers to the next line. But I don't think I changed anything.

Any clue?
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 01:53:12 AM
well - things are a little confusing with regard to INVOKE/CALL and the use of PROTO
if you are going to CALL a function, you do not need a PROTO
also, if the function has no parameters, it is simpler to leave the PROTO out and just use CALL
it makes the code easier to understand
however, i don't think it is the cause of the error
let me look at it a little......
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 01:56:21 AM
ok - the issue is this
in the user32.inc file (and DLL), the name ShowCursor is already PROTO'd with a DWORD parm   :bg
just modify the name a little
ShwCursor
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 02:08:50 AM
Thanks Dave, I found this one and some syntax errors like dispaly instead of display.
By the way, I got rid of the PROTO, corrected the syntax error and used ShowTheCursor
instead of ShowCursor.
Now it compiles, but if freezes when it has to dispaly the screen.
I think it depends on:

GetConsole PROC

    mov hFile, fopen(DWORD PTR FmtName)

    mov ebx, fread(hFile, offset menusys, BufLen)
   
    fclose hFile

    ret
   
GetConsole ENDP


I should pass the string name to fopen() macro, but I passed a DWORD PTR to it.
Maybe this is another error....  ::)
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 02:13:38 AM
pass the address (pointer) to the string name
then, you will want to use INVOKE and PROTO for that function (don't have to do it that way if you don't want)
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 02:18:26 AM
Well I tryed with

BufLen  EQU BufRows*BufCols*4  ;string length (tchars)


I didn't multiply by four  :red

and I used the string name instead of the DWORD PTR to it,
maybe the MACRO doesn't like anything different than a string literal.

Now it works.  :U

What do you suggest? Instead of using the MACRO fopen() I could
use something similar but not the MACRO? a function?
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 02:22:50 AM
no - what i meant was - you may want to use that function to open and read different screen data files
so, pass a parameter to that PROC that is a pointer to the filename string
that way, you can...
INVOKE GetConsole,offset Filename1
.
.
INVOKE GetConsole,offset Filename2
.
.
INVOKE GetConsole,offset Filename3
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 02:24:41 AM
Quote from: dedndave on August 20, 2010, 02:22:50 AM
no - what i meant was - you may want to use that function to open and read different screen data files
so, pass a parameter to that PROC that is a pointer to the filename string
that way, you can...
INVOKE GetConsole,offset Filename1
.
.
INVOKE GetConsole,offset Filename2
.
.
INVOKE GetConsole,offset Filename3


Well, this was my original intent, but apparentely it doesn't work.
Let me try again...
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 02:25:06 AM
GetConsole PROTO :DWORD



GetConsole PROC szFileName:DWORD

   mov hFile, fopen(szFileName)

   mov ebx, fread(hFile, offset menusys, BufLen)
 
   fclose hFile

   ret
 
GetConsole ENDP


not sure about fopen - i usually write my own function for that
you may have to get the pointer into a register, first
GetConsole PROC szFileName:DWORD

   mov eax,szFileName
   mov hFile, fopen(eax)
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 02:39:28 AM
Quote from: dedndave on August 20, 2010, 02:25:06 AM
GetConsole PROTO :DWORD



GetConsole PROC szFileName:DWORD

   mov hFile, fopen(szFileName)

   mov ebx, fread(hFile, offset menusys, BufLen)
 
   fclose hFile

   ret
 
GetConsole ENDP


not sure about fopen - i usually write my own function for that
you may have to get the pointer into a register, first
GetConsole PROC szFileName:DWORD

   mov eax,szFileName
   mov hFile, fopen(eax)


Well, it works both ways, with and without eax.  :U

OK! the original intent is now fulfilled. Thanks Master once again  :P

A last thing: what do you think of the overall prog organization?
I've tryed to write it in a modular way in order to use it as a base
for the complete program. Any comment/suggestion?

Something I had to generalize was the DisplayFmt PROC
so I rewrote it this way:

; -------------------------------------------------------------------------

DisplayFmt PROC szFmtName:DWORD

    INVOKE WriteConsoleOutput, wHnd, szFmtName, DWORD PTR bufferSize,
           DWORD PTR startPoint, offset windowSize

    ret

DisplayFmt ENDP


Now I can use DisplayFmt to display any screen passing its offset.  :U
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 02:49:17 AM
well - as far as the way things are split up, it is ok
you can look at mine for a little guiidance, although mine was just something to get it working
thing is - you will have a better feel for how it can be modularized as you get closer to finishing it
pieces of code that you use again and again can made into be PROC's
in some cases, taking some code out of a PROC makes it usable for more things
you may not have a feel for this until you get some code going - lol
this is especially true for beginners
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 02:51:28 AM
The actual version attached with the appropriate screen to display.
If you want to have a look  :wink
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 02:58:36 AM
well - one thing i would probably change...
DisplayFmt PROC szFmtName:DWORD

    INVOKE WriteConsoleOutput, wHnd, szFmtName, DWORD PTR bufferSize,
           DWORD PTR startPoint, offset windowSize

    ret

DisplayFmt ENDP


i wouldn't make that a PROC at all
just INVOKE the function inline
Main PROC

    CALL   InitProc

    CALL   ConsoleSize

    INVOKE GetConsole, offset FmtName

    INVOKE WriteConsoleOutput, wHnd, szFmtName, DWORD PTR bufferSize,
           DWORD PTR startPoint, offset windowSize
       
    CALL   AnyKey

    CALL   ShowTheCursor

finish: INVOKE ExitProcess,0

        ret

Main ENDP
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 03:07:25 AM
Quote from: dedndave on August 20, 2010, 02:58:36 AM
well - one thing i would probably change...
DisplayFmt PROC szFmtName:DWORD

    INVOKE WriteConsoleOutput, wHnd, szFmtName, DWORD PTR bufferSize,
           DWORD PTR startPoint, offset windowSize

    ret

DisplayFmt ENDP


i wouldn't make that a PROC at all
just INVOKE the function inline
Main PROC

    CALL   InitProc

    CALL   ConsoleSize

    INVOKE GetConsole, offset FmtName

    INVOKE WriteConsoleOutput, wHnd, szFmtName, DWORD PTR bufferSize,
           DWORD PTR startPoint, offset windowSize
       
    CALL   AnyKey

    CALL   ShowTheCursor

finish: INVOKE ExitProcess,0

        ret

Main ENDP


Sorry Master, but I think this time I have to disagree, maybe.
Let me explain. I'll use DisplayFmt PROC in many places in the
program to display various screen.
If I don't make it a PROC I'll have to rewrite the:

    INVOKE WriteConsoleOutput, wHnd, szFmtName, DWORD PTR bufferSize,
           DWORD PTR startPoint, offset windowSize

many times, and repeat the same code dozens of times.
If I got what you mean, of course. Maybe I didn't understand.
Can you please explain why do you suggest this change?
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 03:16:27 AM
well - by making it a PROC, you add the overhead of a CALL and a RET, as well as the PUSH for the parm
if you want to save typing, make a macro out of it   :U
or do like me and use copy/paste - lol
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 03:22:53 AM
Quote from: dedndave on August 20, 2010, 03:16:27 AM
well - by making it a PROC, you add the overhead of a CALL and a RET, as well as the PUSH for the parm
if you want to save typing, make a macro out of it   :U

In order to spare some cycle you suggest to inflate the size of the program?
Well. For the time being I think the PROC is the clean solution I need.
The MACRO could be a good compromise, but I'm actually not able to write it,
even if I suppose it is not that difficult  :P

Anyway I'll think about it.  :wink
And I'll study the MACRO as well, but after my holydays, maybe from the end
of september  :bg
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: dedndave on August 20, 2010, 03:42:22 AM
well - you're right about the clock cycles - that isn't going to make any difference
i hadn't thought about the byte-count for pushing all the parms
i suppose it depends on how many times you are going to use it
Title: Re: How can I say "You pressed Down Arrow Key" ?
Post by: frktons on August 20, 2010, 04:27:03 AM
Quote from: dedndave on August 20, 2010, 03:42:22 AM
well - you're right about the clock cycles - that isn't going to make any difference
i hadn't thought about the byte-count for pushing all the parms
i suppose it depends on how many times you are going to use it

In the real program I'll develop along the way, maybe I'll call it 200-300 times,
I mean the program will have to manage 200-300 screens, more or less.