Idle Loop Processing

Idle loop processing allows your program to perform specified tasks when there is not pending user input or system messages. The default message loop provided by the Microsoft Foundation Class Library calls the virtual function OnIdle in class CWinApp whenever there are no pending messages in the message queue for the application.

If you want to do idle processing, you can override OnIdle in your derived application class. This function has a LONG argument and returns a BOOL result. By default, it returns FALSE to indicate that no idle processing time is required. The LONG argument indicates how many times OnIdle has been called since the last message was taken from the event queue.

Idle loop processing proceeds according to the following list of actions:

1.If the message loop in the Microsoft Foundation Class Library checks the message queue and finds no pending messages, it calls OnIdle for the current application object, supplying 0 as the lCount argument.

2.OnIdle performs some processing, and returns TRUE if it wants to be called again to do further processing.

3.The message loop checks the message queue again. If no messages are pending, it calls OnIdle again, incrementing the lCount argument.

4.Eventually, OnIdle finishes processing all its idle tasks and returns FALSE. This tells the message loop to stop calling OnIdle until the next message is retrieved from the message queue, at which point the idle cycle restarts with the argument reset to 0.

An example may make this process clearer. Since the argument to OnIdle is incremented each time it is called, you can essentially prioritize the idle tasks that you want to perform. By checking the value of the argument to OnIdle, you can determine how long (relatively) the message queue has been empty.

For instance, assume that you have two idle tasks you want to do. The first is high priority, and you want to do it whenever there is an idle moment. The second task is less important, and should be done only when there is a long pause in user input. To handle these two cases, you could implement your OnIdle function as shown here. Note that you must call OnIdle for the base class (CWinApp) to ensure that the default idle processing gets done too.

BOOL CTheApp::OnIdle( LONG lCount )

{

CWinApp::OnIdle( lCount );

switch( lCount )

{

case 0:

TRACE( "frequent\n" );

return TRUE;

case 10000:

TRACE( "infrequent\n" );

return FALSE;

default:

return TRUE;

}

}

Since message processing does not occur until OnIdle has returned control to the message loop, you should never retain control for too long. Trying to do too much in OnIdle can hamper your program's responsiveness to user input. If you have lengthy idle processing, break it up into smaller pieces and do one piece each time OnIdle is called.