News:

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

Pause function

Started by MaynardG_Krebs, March 03, 2007, 06:31:21 PM

Previous topic - Next topic

MaynardG_Krebs

I am playing around with Win32 console functions and obviously don't know what I am doing. The following code seems to assemble and link alright but when I try to run it the console window flashes on the screen and disappears.

Is there another function or procedure I need to call to get the window to pause before exiting to the operating system?


include \masm32\include\masm32rt.inc
   
    .data?
        bytesWritten DWORD ?    ; number of bytes written

    .data
        endl EQU <0dh,0ah>      ;end of line
        mesg BYTE "Hello World",0,endl
        messagesz = ($-mesg)
   
        consoleHandle DWORD 0

    .code

start:

    INVOKE GetStdHandle, STD_OUTPUT_HANDLE
    mov consoleHandle, eax

    INVOKE WriteConsole,
        consoleHandle,
        ADDR mesg,
        messagesz,
        ADDR bytesWritten,
        0

    INVOKE ExitProcess, 0

end start


Thanks

TNick

Maybe you should see how inkey macro works (\masm32\macros\macros.asm). This is the one that does the job in my console programs.

Nick

dsouza123

A couple of options inkey or wait_key

As Nick wrote inkey


   inkey
   INVOKE ExitProcess, 0



   wait_key
   INVOKE ExitProcess, 0


The difference, inkey writes the message
Press any key to continue ...
wait_key doesn't show a message,

inkey uses wait_key to wait for a key press.

MaynardG_Krebs

Thanks TNick and dsouza123 that makes it do what I wanted. :U
I'll take a look at the macros to see how they work.

Ehtyar

inkey is a rather nasty hack IMO, and requires the crt and a loop function. I would recommend setting the console mode to ENABLE_PROCESSED_INPUT and reading a single character from stdin. That requires only winapi and no loop.

Ehtyar.

MichaelW

Quote
inkey is a rather nasty hack IMO, and requires the crt and a loop function. I would recommend setting the console mode to ENABLE_PROCESSED_INPUT and reading a single character from stdin. That requires only winapi and no loop.

To duplicate even most of the functionality of wait_key your method would require calls to GetStdHandle, SetConsoleMode, FlushConsoleInputBuffer, and ReadConsole or ReadFile, plus a buffer, and additional code to move the returned character into EAX. And after all of this it still would not respond to the escape, function, or navigation keys as wait_key does.
eschew obfuscation

PBrennick

Which is...


ConsoleIn proc lpbuffer:DWORD,bufflen:DWORD

  ; -----------------------------------------------------------
  ; lpbuffer should be 260 bytes on win2k and later os versions
  ; -----------------------------------------------------------
    LOCAL stdhandle :DWORD
    LOCAL readcount :DWORD

    invoke GetStdHandle,STD_INPUT_HANDLE
    mov stdhandle, eax

    invoke SetConsoleMode,stdhandle,ENABLE_LINE_INPUT or \
                                    ENABLE_ECHO_INPUT or \
                                    ENABLE_PROCESSED_INPUT

    invoke ReadFile,stdhandle,lpbuffer,bufflen,ADDR readcount,NULL

  ; ---------------
  ; strip CRLF pair
  ; ---------------
    mov eax, lpbuffer
    sub eax, 1
  @@:
    add eax, 1
    cmp BYTE PTR [eax], 0
    jz @F
    cmp BYTE PTR [eax], 13
    je @F
    cmp BYTE PTR [eax], 10
    ja @B

  @@:
    mov BYTE PTR [eax], 0
    sub eax, lpbuffer

    ret

ConsoleIn endp


Not too bad, in my opinion. It is in my library. All the user has to supply is a buffer and its length.  :U
Paul

The GeneSys Project is available from:
The Repository or My crappy website

sinsi

How about
WaitForKey PROC uses edi
    invoke GetStdHandle,STD_INPUT_HANDLE
    mov edi,eax
    invoke WaitForSingleObject,edi,INFINITE
    invoke FlushConsoleInputBuffer,edi
    ret
WaitForKey ENDP

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

GregL

Quote from: Ehtyarinkey is a rather nasty hack IMO, and requires the crt and a loop function.

I disagree. There's nothing wrong with using the CRT, it's just another Windows DLL that can be called. No different than calling the Windows API. Granted, the CRT functions aren't the best for speed, but for functionality and stability they are pretty darn good. The CRT has withstood the test of time.


Ehtyar

Quote from: sinsi on March 04, 2007, 12:51:34 AM
How about
WaitForKey PROC uses edi
    invoke GetStdHandle,STD_INPUT_HANDLE
    mov edi,eax
    invoke WaitForSingleObject,edi,INFINITE
    invoke FlushConsoleInputBuffer,edi
    ret
WaitForKey ENDP
Well i sure as hell love that, thanks sinsi, that is some awesome code :)
Quote from: MichaelW on March 03, 2007, 09:17:34 PM
Quoteinkey is a rather nasty hack IMO, and requires the crt and a loop function. I would recommend setting the console mode to ENABLE_PROCESSED_INPUT and reading a single character from stdin. That requires only winapi and no loop.
To duplicate even most of the functionality of wait_key your method would require calls to GetStdHandle, SetConsoleMode, FlushConsoleInputBuffer, and ReadConsole or ReadFile, plus a buffer, and additional code to move the returned character into EAX. And after all of this it still would not respond to the escape, function, or navigation keys as wait_key does.
You'll forgive me if i was a little vague. What i mean to say is that if you're not using the crt to begin with (i almost never do, thus my bias in this case) it's not very nice to have to include extra dependencies just for a function this simple. (and why is a loop required if you're not using the return value anyway?)

Ehtyar.

sinsi

Quote from: Ehtyar on March 04, 2007, 03:40:59 AM
Well i sure as hell love that, thanks sinsi, that is some awesome code :)
Why thankyou  :bg
I was looking for something as simple as "sub ah,ah; int 16h" and a few beers later up it popped :bdg
Light travels faster than sound, that's why some people seem bright until you hear them.

zooba

Quote from: Greg on March 04, 2007, 01:27:25 AM
Quote from: Ehtyarinkey is a rather nasty hack IMO, and requires the crt and a loop function.

I disagree. There's nothing wrong with using the CRT, it's just another Windows DLL that can be called. No different than calling the Windows API. Granted, the CRT functions aren't the best for speed, but for functionality and stability they are pretty darn good. The CRT has withstood the test of time.

The CRT simply calls the Win32 API functions. It's not 'just another Windows DLL', it's a wrapper around the Windows API and some extra functionality which isn't part of the API. If you desperately want this extra functionality, go ahead. If you don't, the Windows API route is much more efficient.

Sinsi,

Love your code, that's even better than my variant. I've thrown it into ASM Runtime if that's okay with you?

Cheers,

Zooba :U

sinsi

Quote from: zooba on March 04, 2007, 05:32:26 AM
Sinsi,

Love your code, that's even better than my variant. I've thrown it into ASM Runtime if that's okay with you?

Cheers,

Zooba :U

No, this is my own personal code...heh heh.
Of course you can use it - anyone can do anything they want with it (except blame me) :U
Go for it!
Light travels faster than sound, that's why some people seem bright until you hear them.

MichaelW

Quote from: sinsi on March 04, 2007, 12:51:34 AM
How about
WaitForKey PROC uses edi
    invoke GetStdHandle,STD_INPUT_HANDLE
    mov edi,eax
    invoke WaitForSingleObject,edi,INFINITE
    invoke FlushConsoleInputBuffer,edi
    ret
WaitForKey ENDP


Good idea, but I see two problems. The first is that the input buffer is not being flushed before the call to WaitForSingleObject, so the code will not wait if there is anything in the input buffer. The second is that WaitForSingleObject responds to the key-release event. If you do two calls to the procedure without a significant delay between the calls, even with a call to FlushConsoleInputBuffer placed ahead of the call to WaitForSingleObject, the second call will not wait.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
WaitForKey PROC uses edi
    invoke GetStdHandle,STD_INPUT_HANDLE
    mov edi,eax
    invoke FlushConsoleInputBuffer,edi
    invoke WaitForSingleObject,edi,INFINITE
    invoke FlushConsoleInputBuffer,edi
    ret
WaitForKey ENDP
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke WaitForKey
    print "1",13,10
    invoke WaitForKey
    print "2",13,10
    invoke wait_key
    print "1",13,10
    invoke wait_key
    print "2",13,10
    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start

eschew obfuscation

hutch--

I have seen these odd purist comments before about predispositions of which system DLLs should be used and which should be ignored but its hard to argue a case of efficiency when an application is doing no more than waiting on a keystroke. MSVCRT.DLL has been a Windows component since win95b and it is very reliable.

Contrary to popular opinion, a polling loop with a published wait function (Sleep) is extremely efficient in terms of processor usage as it only does a periodic test for the keystroke and yields to the OS for the rest of the time. If this was a performance critical issue you would look for the most efficient way to perform the task but it is still no more than waiting for a keystroke and as its doubtful that anyone can hit any key fast enough to beat the keyboard repeat rate let alone do something that actually changes the processor usage.

I am in debt to Greg for his original design work from MSVCRT for the procedure that is simple, fast and reliable.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php