🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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?
#2626
Author: Helmut Giese
Date: Wed, 07 Feb 2007 15:55
55 lines
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?
#2631
Author: Bob Gonder
Date: Wed, 07 Feb 2007 19:20
68 lines
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?
#2496
Author: Helmut Giese
Date: Thu, 08 Feb 2007 10:23
10 lines
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?
#2333
Author: Michael Harris
Date: Wed, 14 Mar 2007 04:31
41 lines
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