Thread View: borland.public.cppbuilder.nativeapi
4 messages
4 total messages
Started by Helmut Giese
Wed, 07 Feb 2007 15:55
How to keep a console app busy and responsive?
Author: Helmut Giese
Date: Wed, 07 Feb 2007 15:55
Date: Wed, 07 Feb 2007 15:55
55 lines
2647 bytes
2647 bytes
Hello out there,
a console mode app of mine needs to periodically perform some action
while still being able to react to input from the user.
I thought that the combination of getting the handle to the input
console and then doing a WaitForSingleObject with a suitable timeout
would accomplish what I need - but it doesn't work.
The program below (when started from a console)
1) repeatedly prints out the message "No key ...." UNTIL any key is
pressed, at which point
2) it ALWAYS goes into the 'ReadConsole' after the WaitForSingleObject
call, whether a key is pressed or not. Of course it blocks there if no
key is pressed - the message "No key ..." is never again seen.
When started via Start | Run, step (1) from above is skipped.
Any help to get me on the right track will be greatly appreciated,
Best regards
Helmut Giese
-----
#include <windows.h>
#include <stdio.h>
#pragma argsused
int main(int argc, char* argv[])
{
HANDLE inHdl, outHdl;
char inBuff[80];
int done = 0;
DWORD cnt, dwRes;
// get console handle
inHdl = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleMode(inHdl, 0);
// SetConsoleMode(inHdl, ENABLE_PROCESSED_INPUT);
printf("Trying to be busy & responsive in console mode\n");
while ( !done ) {
dwRes = WaitForSingleObject(inHdl, 1000);
if ( dwRes == WAIT_OBJECT_0 ) {
// input available
ReadConsole(inHdl, inBuff, 1, &cnt, 0);
switch ( inBuff[0] ) {
case '1': printf("Received key '1'\n"); break;
case '2': printf("Received key '2'\n"); break;
case 'q': done = 1; break;
}
} else {
printf("No key - going to do other work\n");
}
}
return 0;
}
-----
Re: How to keep a console app busy and responsive?
Author: Bob Gonder
Date: Wed, 07 Feb 2007 19:20
Date: Wed, 07 Feb 2007 19:20
68 lines
3230 bytes
3230 bytes
Helmut Giese wrote:
>a console mode app of mine needs to periodically perform some action
>while still being able to react to input from the user.
>I thought that the combination of getting the handle to the input
>console and then doing a WaitForSingleObject with a suitable timeout
>would accomplish what I need - but it doesn't work.
Have you tried ResetEvent( inHdl ) ?
Maybe FlushConsoleInputBuffer( inHdl ) ?
The docs for ReadConsole don't mention waiting, but the docs for
ReadConsoleInput do. You might try that function.
My own code uses polling with a Sleep( 10 ) because I also check for
UDP messages. Several copies of the program can run with no
notiiceable delays.
I also allow mouse clicks which brings in mouse movements as well
(which I ignore).
GetNumberOfConsoleInputEvents( stdin, &written );
if( 0 == written )
{ ++WaitCounter;
if( WaitCounter > 100 )
{ WaitCounter = 0;
BackgroundProcess();
}else{
Sleep( 10 );
};
}else{
ReadConsoleInput( stdin, &input_record, 1, &written );
// if you want background to only fire after
// 1 second of inactivity
WaitCounter = 0;
};
See Reading Input Buffer Events
http://msdn2.microsoft.com/en-us/library/ms685035.aspx
- - - -
In any case, the usual method these days is to use threads.
Main() could create a CancelEvent, then start the background thread.
When main() wants to exit, it signals CancelEvent to terminate the
background thread.
Main() could also set a global boolean whenever it processes a
keystroke.
The background thread could WaitForSingleObject on the CancelEvent,
and process during WAIT_TIMEOUT, exiting on WAIT_OBJECT_0.
while( 1 )
{ if( WAIT_OBJECT_0 == WaitForSingleObject( CancelEvent, 1000) )
break;
if( GlobalKeyPressed )
{ // key was pressed while we slept
GlobalKeyPressed = false;
}else{
BackgroundProcess();
};
};
This has the advantage of being responsive even when the background
thread is busy.
Whichever thread method you use, you would also want to add
SetConsoleCtrlHandler( &CtrlHandler, TRUE);
to catch the Big Red X and other app closers so you can signal the
thread to exit nicely.
Re: How to keep a console app busy and responsive?
Author: Helmut Giese
Date: Thu, 08 Feb 2007 10:23
Date: Thu, 08 Feb 2007 10:23
10 lines
1298 bytes
1298 bytes
Hi Bob, many thanks for the info - lots of ways to chose from. - Calling FlushConsoleInputBuffer did not change anything - going the multi-threaded way looks a bit like too much effort for this particular app, - so I think I use your polling example Oh, and thanks for the link to Input Buffer Events. Best regards Helmut Giese
Re: How to keep a console app busy and responsive?
Author: Michael Harris
Date: Wed, 14 Mar 2007 04:31
Date: Wed, 14 Mar 2007 04:31
41 lines
2376 bytes
2376 bytes
in addition..
while (!dgDone)
{
// standard console processing
//
INPUT_RECORD lpPeekBuffer = { '\0' };
DWORD dwNumEventsPeek = 0;
::PeekConsoleInput(inHdl, // handle to a console
input buffer
&lpPeekBuffer, // pointer to the
buffer for peek data
sizeof(INPUT_RECORD), // number of records to
read
&dwNumEventsPeek); // pointer to number of
records read
if(dwNumEventsPeek)
{
read the console .. it has events.
}
do something else
repeat..
}
--
Michael
"Helmut Giese" <hgiese@ratiosoft.com> wrote in message
news:7vtls2tbtoeo4qv75aqhaj8l2e8rvlfrp1@4ax.com...
> Hi Bob,
> many thanks for the info - lots of ways to chose from.
> - Calling FlushConsoleInputBuffer did not change anything
> - going the multi-threaded way looks a bit like too much effort for
> this particular app,
> - so I think I use your polling example
>
> Oh, and thanks for the link to Input Buffer Events.
> Best regards
> Helmut Giese
>
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads