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
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
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
wait_key works fine, but Masm32 chr$() won't work as chr$(eax)
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?
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
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. ::)
yah - the mov numx,eax is a wasted line, as numx is already equal to eax
see my previous post (updated)
ReadConsoleInput (http://msdn.microsoft.com/en-us/library/ms684961(VS.85).aspx)
that's the hard way, sinsi
plus, the crt functions overcome part of the bug in windows console
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
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
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.
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
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.
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. ::)
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.
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
try this one, Frank...
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
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
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
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
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
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
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
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...
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.
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?
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......
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
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.... ::)
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)
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?
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
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...
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)
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 PROCso 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
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
The actual version attached with the appropriate screen to display.
If you want to have a look :wink
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
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?
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
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
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
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.