Problem with a message loop

Started by
6 comments, last by EnergyX 20 years, 5 months ago
Hi, I just cant seem to find the roots of this problem... I coded this App Framework which uses a real-time message loop which looks something like this : while(1) { if(peekmessage(....)) { ... if(message==WM_QUIT) break; ... translatemessage(...); dispatchmessage(...); ... } else { FrameMove(); } } However, the function FrameMove never gets called. After investigating , I found that peekmessage always returns a message (int value=15 , so that would be 0x000F , which is for WM_PAINT). If I set the if condition to ignore this message, it works OK (the screen flickers a lot, but that might be due to the crap directx code Ive written for testing). Other progs use similar message loops, but they dont seem to encounter such problems... Can any1 point out what Im doing incorrect here?
Advertisement
here''s one way to do it
while (1) {  MSG msg;  if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {    // Check for a quit message    if (msg.message == WM_QUIT) break;      TranslateMessage(&msg);      DispatchMessage(&msg);    } else {      // your update here    }}
quote:Original post by Anonymous Poster
here''s one way to do it
while (1) {  MSG msg;  if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {    // Check for a quit message    if (msg.message == WM_QUIT) break;      TranslateMessage(&msg);      DispatchMessage(&msg);    } else {      // your update here    }}


Thats exactly what Im doing... only problem is , PeekMessage is (for some reason) always returning true , and the update code is never reached.
I believe the correct syntax is


void GameLoop()
{
bool bMessage;

PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);

while(msg.message != WM_QUIT)
{
bMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

if(bMessage)
{
//Process message
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//No message to process, so render the current scene
UpdateGameFrameAndDraw();
}
}
}


You need to process ALL pending messages before your update loop, otherwise you will have an input queue that gets flooded.



quote:Original post by Sphet
I believe the correct syntax is


void GameLoop()
{
bool bMessage;

PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);

while(msg.message != WM_QUIT)
{
bMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

if(bMessage)
{
//Process message
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//No message to process, so render the current scene
UpdateGameFrameAndDraw();
}
}
}


You need to process ALL pending messages before your update loop, otherwise you will have an input queue that gets flooded.






Ive tried that too (The DirectX 9 Sample Codes use a similar method) , but the same problem results there...
if PeekMessage is always returning WM_PAINT that means that you''ve munged up the WM_PAINT processing, either by returning 0 without having actually done anything to resolve the reason for the WM_PAINT message in the first place, or by doing something incorrectly, like invalidating another rect while processing the WM_PAINT message. in both cases the system will turn around and issue another WM_PAINT message since there will still be an invalidated region that needs to be validated. once all of the invalidated regions have been validated, then the WM_PAINT messages will stop being sent, at least until the next invalidated region comes along.

so, are you letting WM_PAINT messages pass through to DefWindowProc, which would auto-validate any invalidated regions, or are you at least issuing BeginPaint and EndPaint calls (essentially duplicating the work that DefWindowProc would do for you), which would also validate any invalidated regions? or are you doing something else within your WM_PAINT processing? or are you always returning from your message handler function without calling DefWindowProc? or?
You should take note of the fact that in the example posted by the AP the game update code was inside the if statement that called PeekMessage.

peace and (trance) out

Mage
---------------------------------------------------There are 10 kinds of people in the world:Those that understand binary, and those that dont...Mage
quote:Original post by Anonymous Poster
if PeekMessage is always returning WM_PAINT that means that you''ve munged up the WM_PAINT processing, either by returning 0 without having actually done anything to resolve the reason for the WM_PAINT message in the first place, or by doing something incorrectly, like invalidating another rect while processing the WM_PAINT message. in both cases the system will turn around and issue another WM_PAINT message since there will still be an invalidated region that needs to be validated. once all of the invalidated regions have been validated, then the WM_PAINT messages will stop being sent, at least until the next invalidated region comes along.

so, are you letting WM_PAINT messages pass through to DefWindowProc, which would auto-validate any invalidated regions, or are you at least issuing BeginPaint and EndPaint calls (essentially duplicating the work that DefWindowProc would do for you), which would also validate any invalidated regions? or are you doing something else within your WM_PAINT processing? or are you always returning from your message handler function without calling DefWindowProc? or?


Hey Thanks! I Forgot to call DefWindowProc and was simply returning a 0 (excellent diagnosis m8).
Works fine now.

This topic is closed to new replies.

Advertisement