From: Herbert Kleebauer on
hutch-- wrote:

> call crt__kbhit

That's cheating. The code posted was from kbhit() in Microsoft Platform SDK\src\crt\getch.c
with anything deleted which isn't absolutely necessary for a minimal working code (I need it
as small as possible to be included within a batch file). I hoped there is some simpler
method than using PeekConsoleInput to examine any input messages to find a keyboard message).



int __cdecl _kbhit_lk (

#else /* _MT */

int __cdecl _kbhit (

#endif /* _MT */
void
)
{
PINPUT_RECORD pIRBuf;
DWORD NumPending;
DWORD NumPeeked;
int malloc_flag = 0;
int ret = FALSE;

/*
* if a character has been pushed back, return TRUE
*/
if ( chbuf != -1 )
return TRUE;

/*
* _coninpfh, the handle to the console input, is created the first
* time that either _getch() or _cgets() or _kbhit() is called.
*/

if ( _coninpfh == -2 )
__initconin();

/*
* Peek all pending console events
*/
if ( (_coninpfh == -1) ||

!GetNumberOfConsoleInputEvents((HANDLE)_coninpfh, &NumPending) ||

(NumPending == 0))
{
return FALSE;
}

__try {
pIRBuf = (PINPUT_RECORD)_alloca( NumPending * sizeof(INPUT_RECORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
_resetstkoflw();
pIRBuf = NULL;
}

if ( pIRBuf == NULL )
{
pIRBuf = (PINPUT_RECORD)_malloc_crt( NumPending *
sizeof(INPUT_RECORD));
if ( pIRBuf == NULL )
return FALSE;

malloc_flag = 1;
}

if ( PeekConsoleInput( (HANDLE)_coninpfh,
pIRBuf,
NumPending,
&NumPeeked ) &&

(NumPeeked != 0L) &&

(NumPeeked <= NumPending) )
{

/*
* Scan all of the peeked events to determine if any is a key event
* which should be recognized.
*/
for ( ; NumPeeked > 0 ; NumPeeked--, pIRBuf++ ) {

if ( (pIRBuf->EventType == KEY_EVENT) &&

(pIRBuf->Event.KeyEvent.bKeyDown) &&

( pIRBuf->Event.KeyEvent.uChar.AsciiChar ||
_getextendedkeycode( &(pIRBuf->Event.KeyEvent) ) ) )
{
/*
* Key event corresponding to an ASCII character or an
* extended code. In either case, success!
*/
ret = TRUE;
}
}
}

if ( malloc_flag )
_free_crt( pIRBuf );

return ret;
}
From: Herbert Kleebauer on
Michael Tippach wrote:
> Herbert Kleebauer wrote:

> So what exactly was it that's wrong with:
> WaitForSingleObject(Console_Input_Handle,Timeout)
> ?

I want a program similar to the 16 bit choice.com. If you execute
it with:

choice32.exe 66

it should wait for a key press and then return the ascii code of
the key as error level. If there is no key pressed within 66 seconds,
it should return with an error level 0. Now, this would be trivial with
16 bit DOS code, but AMD/Microsoft decided to no longer support 16 bit
code in 64-bit Windows (that should be reason enough to not buy AMD but
only Intel CPU's).

So either I need a read with a time-out (there is a SetCommTimeouts(),
but that doesn't work for the stdin handle) or a way to do a non blocking
test for keyboard input. WaitForSingleObject() waits for an event within
a given time-out. But when it returns before the time-out, you only know
that there was an event but not whether it was a keyboard event. And
if it wasn't a keyboard event and you call getc(), then the program
waits until you press a key without any time-out. Therefore, even with
WaitForSingleObject(), you have to use PeekConsoleInput() to inspect
the event and therefore WaitForSingleObject() isn't much better than
a sleep() (which I used in the posted code).
From: Rod Pemberton on
"Herbert Kleebauer" <klee(a)unibwm.de> wrote in message
news:48FD8CCA.EFE0C95(a)unibwm.de...
> So either I need a read with a time-out (there is a SetCommTimeouts(),
> but that doesn't work for the stdin handle) or a way to do a non blocking
> test for keyboard input. WaitForSingleObject() waits for an event within
> a given time-out. But when it returns before the time-out, you only know
> that there was an event but not whether it was a keyboard event. And
> if it wasn't a keyboard event and you call getc(), then the program
> waits until you press a key without any time-out. Therefore, even with
> WaitForSingleObject(), you have to use PeekConsoleInput() to inspect
> the event and therefore WaitForSingleObject() isn't much better than
> a sleep() (which I used in the posted code).

Having never programmed anything for Windows and never planning on doing so
ever, my utterly expert advice is to try something like this:

VOID CALLBACK TimeOut(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
exit(-1);
}

int main(int argc, char *argv[], char *envp[])
{

/* declare stuff used below */

if(argc!=2)
exit(-1);
time=strtoul(argv[1],NULL,0);
time*=1000;

hTimerQueue=CreateTimerQueue();
if(hTimerQueue==NULL)
{
//error
}
if(!CreateTimerQueueTimer(&hTimer,hTimerQueue,(WAITORTIMERCALLBACK)TimeOut
,NULL,time,0,0)
{
//error
}

while(1)
{
if(FlushConsoleInputBuffer(hStdin))
{
do{
if(!GetNumberOfConsoleInputEvents(hStdin,lpcNumberOfEvents))
{
//get number error
exit(-1);
}
}while(!lpcNumberOfEvents);
if(!ReadConsoleInput(hStdin,lpBuffer,1,NULL)
{
// read error
exit(-1);
}
if(lpBuffer.EventType==KEY_EVENT)
{
if(lpBuffer.Event.KeyEvent.bKeyDown)
{
exit(lpBuffer.Event.KeyEvent.uChar.AsciiChar);
}
// repeat loop
}
}
else
{
//flush error
exit(-1);
}
}
}


Rod Pemberton

From: Rod Pemberton on

"Rod Pemberton" <do_not_have(a)nohavenot.cmm> wrote in message
news:gdkg6d$ja2$1(a)aioe.org...
> "Herbert Kleebauer" <klee(a)unibwm.de> wrote in message
> news:48FD8CCA.EFE0C95(a)unibwm.de...
> > So either I need a read with a time-out (there is a SetCommTimeouts(),
> > but that doesn't work for the stdin handle) or a way to do a non
blocking
> > test for keyboard input. WaitForSingleObject() waits for an event within
> > a given time-out. But when it returns before the time-out, you only know
> > that there was an event but not whether it was a keyboard event. And
> > if it wasn't a keyboard event and you call getc(), then the program
> > waits until you press a key without any time-out. Therefore, even with
> > WaitForSingleObject(), you have to use PeekConsoleInput() to inspect
> > the event and therefore WaitForSingleObject() isn't much better than
> > a sleep() (which I used in the posted code).
>
> Having never programmed anything for Windows and never planning on doing
so
> ever, my utterly expert advice is to try something like this:
>
[snip]

Wow, that killed the conversation... Have you found a solution?


RP
[Wolfgang Kern offline counter: 27 days...]


From: hutch-- on
herbert,

[quote]
I want a program similar to the 16 bit choice.com. If you execute
it with:

choice32.exe 66
[/quote]

So what the big deal, write a 32 bit console CHOICE.EXE and rename it
CHOICE.COM, will work fine.

Just set the return value in ExitProcess() to what you want on the
timeout.