From: Herbert Kleebauer on 13 Oct 2008 16:37 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 13 Oct 2008 20:15 "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 13 Oct 2008 22:58 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 14 Oct 2008 00:51 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 14 Oct 2008 04:51
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. |