From: Herbert Kleebauer on
I need a simple Win32 console program which waits for a single
key press within a given time-out (like the 16 bit choice.com).

Therefore I either need a read with a time-out (seems only to
work with device handles, but not with the stdin console) or
a non blocking getc. I have done an ugly hack, but I think there
must be a cleaner way. I remove any message in the queue except
a key down message (even a key release message). This works as
long as you don't press any non ascii key. Does anybody know
a link to information how to do it correctly?



winmain::
jsr.l (GetCommandLine)

; skip program name
eor.l r1,r1 ; not within ""
dec.l r0
_20: inc.l r0
cmp.b #0,(r0)
beq.b _10
cmp.b #'"',(r0)
bne.b _30
not.l r1
_30: or.l r1,r1
bne.b _20
cmp.b #' ',(r0)
bne.b _20
inc.l r0
_10:


get_number:
bclr.w #10,sr
move.l r0,r5
eor.l r4,r4
eor.l r0,r0

_10: move.b (r5)+-,r0
or.b r0,r0
beq.b _50
sub.b #'0',r0
bcs.b _20
cmp.b #9,r0
bhi.b _20
mulsq.l #10,r4,r4
add.l r0,r4
move.l #_50,_30
br.b _10
_20: jmp.l (_30)
_30: dc.l _10
_50: lsl.l #2,r4 ; number of 250 ms


moveq.l #-10,-(sp)
jsr.l (GetStdHandle)
move.l r0,r3
move.l r0,-(sp) ; mode variable
move.l r7,-(sp) ; address of mode
move.l r3,-(sp) ; handle
jsr.l (GetConsoleMode)
and.b #%11100001,(r7){s7} ; don't wait for <CR>
move.l r3,-(sp) ; handle
jsr.l (SetConsoleMode)


loop: move.l #250,-(sp) ; wait 1/4 second
jsr.l (Sleep)
_70: move.l r0,-(sp) ; lpTotalBytesAvail variable
move.l r7,-(sp) ; address of lpTotalBytesAvail
move.l r3,-(sp) ; handle
jsr.l (GetNumberOfConsoleInputEvents)
move.l (sp)+,r0
cmpq.l #0,r0
bne.b _80 ; input available
dec.l r4
bpl.b loop
moveq.l #0,-(sp)
br.b _100

_80: subq.l #20+4,r7 ; size of INPUT_RECORD + lpNumberOfEventsRead
lea.l 4.b(r7),r5 ; address of INPUT_RECORD
move.l r7,-(sp) ; address of lpNumberOfEventsRead
moveq.l #1,-(sp) ; read 1 event
move.l r5,-(sp) ; address of INPUT_RECORD
move.l r3,-(sp) ; handle
jsr.l (PeekConsoleInput)
or.l r0,r0
beq.b _110
cmpq.w #1, 4.b(r7){s7} ; key event
bne.b _90 ; no, remove it
cmpq.l #1, 8.b(r7){s7} ; key down
bne.b _90 ; no, remove it
addq.l #20+4,r7
br.b _60

_90: move.l r7,-(sp) ; address of lpNumberOfEventsRead
moveq.l #1,-(sp) ; read 1 event
move.l r5,-(sp) ; address of INPUT_RECORD
move.l r3,-(sp) ; handle
jsr.l (ReadConsoleInput)
or.l r0,r0
beq.b _110
addq.l #20+4,r7
br.b _70


_60: moveq.l #0,-(sp) ; read buffer
move.l r7,r0 ; address of read buffer
moveq.l #0,-(sp) ; read count variable
move.l r7,r1 ; address of read count
moveq.l #0,-(sp) ; no lpOverlapped
move.l r1,-(sp) ; address of read count
moveq.l #1,-(sp) ; read one byte
move.l r0,-(sp) ; address of read buffer
move.l r3,-(sp) ; handle
jsr.l (ReadFile)
or.l r0,r0
beq.b _110
move.l (sp)+,r1 ; count
dec.l r1
beq.b _100
_110: moveq.l #-1,-(sp)
_100: jsr.l (ExitProcess) ; exit program





@echo off
echo hD1X-s0P_kUHP0UxGWX4ax1y1ieimnfeinklddmemkjanmndnadmndnpbbn>sleep2.com
echo hhpbbnpljhoxolnhaigidpllnbkdnhlkfhlflefblffahfUebdfahhfkokh>>sleep2.com
echo wvPp0wvW3k9C5/R/pN0d0uzW37bwo1Yi(a)GEWtbGov5//B6mkuMEo0IL0l/w>>sleep2.com
echo ef2iC57R/pNEA/jeefHhC5AR/pNEA/juefXgC5ER/phCfDM(a)m042knfuurO>>sleep2.com
echo U3HMl4Bd4M03k33Alzz(a)0M0QF0/RV7UCV2Tcf2/EP1B61i0kInVsIOXJ57o>>sleep2.com
echo x57hJKNo0mQjpKNWx5Nt0mRcx57dB67nFLOgl57pBLOiR573xoIgoU1WJ6R>>sleep2.com
echo UUKOn01QmxqNm4KPU7LNlJLOmJqQUQJOiBXAioU1Y//I480H03//EZLdqQl>>sleep2.com
echo 0U2k20gE/4k//3QF1y3l3EA07K/Y3EAV/GEk45Ek46/m31QF02Q00E703K/>>sleep2.com
echo V3EQF0EQV1g/V3cQlIE70(a)LcV@oJ5SoBVA1A03HEk31QF2U70sLwXXE70bE>>sleep2.com
echo 7VfE7VhE7VlE7VoE70tE7VxE7V1F7V6FQF0W0l48E43H/l4JgIFGtIFABXA>>sleep2.com
echo iE5Pg8VXE70bE7VfE7VhE7VlE7VoE70tE7VxE7V1F7V6FQl04VLOo0ZQjBK>>sleep2.com
echo NnBr36J5R2xKPh4aPYlIOiJKEHA4PZJ5QHQINoB4RYVIMiF5PZNVIZ45N5Z>>sleep2.com
echo 5PZNlFZFrEjtqQjlKNBx5NZNlIZFrEjtqQjlKNBx5NZN0IZJqO2xaPnx5PZ>>sleep2.com
echo ZYPkJ6R0BVIZ45N2xaPnx5PZZYPkJ6R0BlFZFbHppaMZ8rHaBoPiBrPgJKG>>sleep2.com
echo i0LRoJYRZt5Rn0kzJE/3/0EAGX3E/W2/o40Us7GR1Qjo87RRj27CUIbu/lT>>sleep2.com
echo W56Hvl/Af7/ARXk1AmJ0D8QL3fpi10Iwl4YM3/0EXF/3/f(a)yzZYM3/0ENF/>>sleep2.com
echo 3/0Li/eNzzJk/3/0EW224JHxT4I/0E//78Y3yIzL05E/3/cdz3zL01E/3/E>>sleep2.com
echo FpIzL08E/3/MB7y/Ir0BZrse0kuRB7vMo7RYE/Je4UJHxT4Q/0E/Y/koJYN>>sleep2.com
echo 2m6833ERAA7TYUE/pJkU3XluIEZO0MpIzL07E/3/8/ARWA7lMgCfe0EWUf5>>sleep2.com
echo /89iO/7ZO0/pIzL03E/3/8/AR3cZGo8UOzzT4//0ELwz4Czz4.>>sleep2.com
sleep2.com >sleep2.exe
del sleep2.com
echo press any key to continue or wait 60 seconds
echo %time%
sleep2.exe 60
echo %time%
echo key pressed: %errorlevel%
del sleep2.exe
From: Rod Pemberton on
"Herbert Kleebauer" <klee(a)unibwm.de> wrote in message
news:48F3B178.AE09A50B(a)unibwm.de...
> I need a simple Win32 console program which waits for a single
> key press within a given time-out (like the 16 bit choice.com).
>
> Therefore I either need a read with a time-out (seems only to
> work with device handles, but not with the stdin console) or
> a non blocking getc. I have done an ugly hack, but I think there
> must be a cleaner way. I remove any message in the queue except
> a key down message (even a key release message). This works as
> long as you don't press any non ascii key. Does anybody know
> a link to information how to do it correctly?
>

Sorry, all I can recommend is looking at the output of a Win32 compiler for
C functions like setbuf() or setmode() which should allow stdin or stdout to
be switched to non-blocking.


RP

From: Michael Tippach on
Herbert Kleebauer wrote:
> I need a simple Win32 console program which waits for a single
> key press within a given time-out (like the 16 bit choice.com).
>
> Therefore I either need a read with a time-out (seems only to
> work with device handles, but not with the stdin console)

WaitForSingleObject works with a CONIN$ handle.
From: NathanCBaker on
On Oct 13, 4:37 pm, Herbert Kleebauer <k...(a)unibwm.de> wrote:
> I need a simple Win32 console program which waits for a single
> key press within a given time-out (like the 16 bit choice.com).
>
> Therefore I either need a read with a time-out (seems only to
> work with device handles, but not with the stdin console) or
> a non blocking getc. I have done an ugly hack, but I think there
> must be a cleaner way. I remove any message in the queue except
> a key down message (even a key release message). This works as
> long as you don't press any non ascii key. Does anybody know
> a link to information how to do it correctly?
>

Here it is in your favorite syntax:

program testc;
#include( "stdlib.hhf" )
#include( "w.hhf" )

procedure tgetc( handle:dword; duration:dword ); @nodisplay;
var
index :dword;
curMode :dword;
newMode :dword;

static
buffer :dword := 0;
number :dword := 1;

begin tgetc;

w.GetConsoleMode( handle, curMode );
mov( curMode, eax );
and( #$01, al );
mov( eax, newMode );
w.SetConsoleMode( handle, newMode );

w.WaitForSingleObject( handle, duration );
if ( eax != w.WAIT_TIMEOUT ) then
w.ReadFile( handle, buffer, number, index, null );
endif;

w.SetConsoleMode( handle, curMode );
mov( (type byte buffer[ 0 ]), al );

end tgetc;

var
hStdIn :dword;

begin testc;

w.GetStdHandle( w.STD_INPUT_HANDLE );
mov( eax, hStdIn );

stdout.put( "Press a key within 2 seconds: " );
tgetc( hStdIn, 2000 ); // Approx. 2 seconds.
stdout.putc( al );
stdout.newln();

stdout.put( "Press a key within 3 seconds: " );
tgetc( hStdIn, 3000 ); // Approx. 3 seconds.
stdout.putc( al );
stdout.newln();


end testc;

http://pastebin.com/m4f534e1a

Nathan.
From: Herbert Kleebauer on
NathanCBaker(a)gmail.com wrote:

> > Therefore I either need a read with a time-out (seems only to
> > work with device handles, but not with the stdin console) or

> Here it is in your favorite syntax:

I can live with the syntax, but does this work for you? Even if I
insert a FlushConsoleInputBuffer() it doesn't work for me. If I
start it within command.com (using the Norton Commander in a CMD
shell) it returns immediately (only the WaitForSingleObject, I have
removed the ReadFile). In a pure CMD shell it waits, but
only until you click on an other Window, because then, I suppose,
a FocusEvent is sent to the console and therefore WaitForSingleObject
returns. This means, you still have to use PeekConsoleInputA()
to examine the message and therefore WaitForSingleObject() is only
a replacement for sleep() in my code, but not for the rest.