Simulating CWinApp::OnIdle in C

No.of Views550
Bookmarked0 times
Downloads 
Votes0
By  Geming Leader   On  02 Sep 2010 12:09:19
Tag : Visual C++ , Windows Forms
MFC allows you to override CWinApp::OnIdle function to perform idle-time processing.This function is called whenever there are no messages are waiting for processing in the message queue.
emailbookmarkadd commentsprint

Images in this article missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at info@codegain.com

 

This article is also available in my blog, Just Like a Magic.

Introduction

MFC allows you to override CWinApp::OnIdle function to perform idle-time processing.This function is called whenever there're no messages are waiting for processing in the message queue.in this function, you can perform some secondary processing like updating the status bar, toolbar, etc.The definition of this function is as follows:

virtual BOOL OnIdle(LONG lCount);

If you are interested you can override this function and do some processing. The following example paints random rectangle while the application is idle (that is no processing is carried on.) Thus, this code doesn't make the application irresponsive.

BOOL OnIdle(LONG lCount)
	{
		CWinApp::OnIdle(lCount);

		CClientDC dc(m_pMainWnd);
		RECT rct;

		m_pMainWnd->GetClientRect(&rct);
		SetRect(&rct,
			rand() % rct.right,
			rand() % rct.bottom,
			rand() % rct.right,
			rand() % rct.bottom);

		dc.Rectangle(&rct);
		return TRUE;
	}

This function receives only a single argument, lCount; it contains a value incremented each time OnIdle is called, and it is reset to 0 each time a new session is established. A new session is established each time your application finishes processing pending messages and no messages are left.

MFC continues to call CWinApp::OnIdle (incrementing lCount each time) as long as there're no messages are waiting for processing. If the application received a new message, MFC ends the current session and stops calling OnIdle until it establishes a new session again. If you want, you can return TRUE to indicate that further processing is required and MFC should call OnIdle again (as long as we are in the current session,) or FALSE to indicate that processing have been finished and MFC should not call OnIdle again until a new session is established.

Notice that, you should call the base implementation of CWinApp::OnIdle because that the default implementation of OnIdle updates command UI objects like menu items and toolbars besides doing some internal structure cleanup.

Unfortunately, C doesn't include OnIdle function. However, we could work out ours.

The following C example shows our new handmade message queue that simulates CWinApp::OnIdle:

while (TRUE) {
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {

			// if a quit message
			if (WM_QUIT == msg.message)
				break; // exit the loop

			// process other messages
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else {	// no messages are waiting
			// do some idle processing
		}
	}

The key function is PeekMessage. This function checks the message queue and if a message was found it removes the message from the queue (if PM_REMOVE specified,) initializes the MSG object with message data, and returns TRUE to the caller. If no message was found, PeekMessage returns FALSE thus executing the code (secondary processing) in the else statement.

You can also create your fully-featured handmade OnIdle. Consider the following code:

BOOL OnIdle(LONG lCount);

int WINAPI WinMain(. . .)
{
	MSG msg;
	LONG lCount;

	. . .

	while (TRUE) {
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
			// found a message, resetting
			lCount = 0;

			if (WM_QUIT == msg.message)
				break;

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else {
			if (lCount >= 0) {
				if (!OnIdle(lCount)) {
					// set a flag indicates
					// no further OnIdle
					// calls till a new
					// session
					lCount = -1;
				}

				// increment the counter
				lCount++;
			}
		}
	}

	return msg.wParam;
}

BOOL OnIdle(LONG lCount)
{
	/*

	do some processing

	*/

	return FALSE;
}

Have a nice day!

 
Sign Up to vote for this article
 
About Author
 
Geming Leader
Occupation-Software Engineer
Company-Just Like a Magic
Member Type-Expert
Location-Egypt
Joined date-30 Jul 2009
Home Page-http://WithDotNet.net
Blog Page-http://JustLikeAMagic.com
Independent software developer, trainer, and technical writer from Egypt born in 1991
 
 
Other popularSectionarticles
    Creating the pure MFC hand held code on how to create a simple window
    Published Date : 22/Feb/2011
    This article discusses how you can display the page in print preview as grayscale if the printer is black-and-white. It discusses first how you can convert colors to grayscale. After that is discusses how to detect whether you are in print preview or not and whether the current printer is color or black-and-white printer. Let's go!
    Published Date : 02/Sep/2010
Comments
There is no comments for this articles.
Leave a Reply
Title:
Display Name:
Email:
(not display in page for the security purphase)
Website:
Message:
Please refresh your screen using Ctrl+F5
If you can't read this number refresh your screen
Please input the anti-spam code that you can read in the image.
^ Scroll to Top