Originally Posted by
Elysia
Not really. MFC, too, is event driven. You specify which what what messages you want to handle them and MFC forwards them to you. Yes, they go through the framework and MFC processes them too,
Sorry if I was not clear, MFC is a subset of WIN32 and is totally event driven.
Originally Posted by
Elysia
which might not always be ideal for gaming, but in general, it's the same.
Ummmmm.....no.
There are two main types of message pumps, standard (GetMessage) and game (PeekMessage). [this is a simplification]
The standard pump gets messages and sends them off.
If no messages are available it WAITS until there is a message for the app.
This uses very little CPU unless the app is never idle (always getting input/processing).
The game message pump checks for a message and sends it off.
If no messages are available it returns (without waiting) and immediately calls code to update the screen. Thus the screen can be redrawn as many times as possible while proccessing all user input.
This uses 100% CPU.
MFC creates its own message loop using a series of PeekMessage calls and a GetMessage call.
MFC's message loop can not be modified, but limited processing can be done in the OnIdle() handler.
EDIT: As all OnIdle() processing is done prior to checking for user input and so is out of sequence for a game (which wants to get user input, move objects based on time/input then update screen)
As MFC uses multiple calls to retreive a single message from the OS queue, it is very slow.
Code:
//MFC message pump
ASSERT_VALID(this);
_AFX_THREAD_STATE* pState = AfxGetThreadState();
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
// acquire and dispatch messages until a WM_QUIT message is received.
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume "no idle" state
}
// phase2: pump messages while available
do
{
// pump message, but quit on WM_QUIT
//this calls GetMessage
if (!PumpMessage())
return ExitInstance();
// reset "no idle" state after pumping "normal" message
//if (IsIdleMessage(&m_msgCur))
if (IsIdleMessage(&(pState->m_msgCur)))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));
}
}