0
101 Sep 27, 2011 at 19:44

Hi there.

I often create little projects, and I at the moment I have a basic window creation & message loop (handling) set up.
But often, my message loops result in the “infinite window” bug when
moving the window. This is just minor of course, but this always bugs me out.

Does anybody know what actually causes this? Is it because I’m not
double buffering yet?

Here’s a link to a screenshot if you don’t know what I mean with the “Infinite Window” bug.

21 Replies

0
101 Sep 27, 2011 at 21:05

Do you have any wait function in your message loop? Maybe your application eats all CPU and other applications doesn’t have required processor power to redraw windows?

0
101 Sep 27, 2011 at 22:53

Indeed. Can you post the code for your message loop?

0
101 Sep 28, 2011 at 00:54

Well, atm it’s a very basic message loop. I need to add a timer when I get up in the morning :)

MSG msg = {};
while(msg.message != WM_QUIT)
{
// Send the message if one is found
if(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

0
165 Sep 28, 2011 at 01:02

Well, there’s your problem! PeekMessage doesn’t wait if there’s no message available, so your app just sits in that tight loop taking up 100% CPU and not giving the other apps much chance to run. ;)

It doesn’t look like you’re doing any rendering yet. Once you do, you’ll presumably be waiting on vsync at the end of rendering, so this problem will go away. You could also put a Sleep(0) call in the loop, although it’s probably not good to have that in there long-term.

0
101 Sep 28, 2011 at 01:06

Yeah, basically how I usually do it, I set an if else loop, where in the if it checks for a message, if none is found, it checks if the minimum time for a frame (max frame cap) has elapsed yet and renders/thinks if so.

Will this make the “infinite window” go away? Because usually when I get to that point in programming, I already use a fullscreen (which I won’t in this program)

0
165 Sep 28, 2011 at 01:53

Well, what does it do if the minimum time for a frame *hasn’t* elapsed yet? If you do a Sleep(0) or something in that case, you should be fine, as you’ll yield the rest of your time-slice back to the OS. But if you just sit in a loop and don’t do anything that suspends the thread, you’ll keep taking up 100% CPU and making it hard for anything else to run.

IMO, the right way to do this is to configure your rendering API to wait for vsync, and if the API is built properly this should suspend the thread until the vsync clears, which will have the side effect of reducing the CPU utilization to a more reasonable level.

For reference, here’s my message loop:

MSG msg;
while (true)
{
if (g_fRendering)
{
Update();
Render();

while (g_fRendering && PeekMessage(&msg, NULL, 0, 0, true))
DispatchMessage(&msg);
}
else
{
if (!GetMessage(&msg, NULL, 0, 0))
break;
DispatchMessage(&msg);
}
}


The g_fRendering flag gets set to false when you minimize the app, or when it starts shutting down; in that case I use GetMessage, which waits for a message, rather than PeekMessage. Down inside the Render() call I’m eventually calling Present() (since I’m using D3D) and telling it to wait for vsync, which both prevents tearing (usually…) and suspends the thread so that other apps can run.

It’s also important to handle *all* available messages after each rendered frame, not just one, hence the PeekMessage in the inner while loop. Otherwise messages can back up and overflow the queue because you don’t process them fast enough. Mouse moves especially can generate several messages per frame.

0
101 Sep 28, 2011 at 10:58

What I usually do is using SetTimer() to let Windows post a WM_TIMER to my message queue every x milliseconds (the minimum is 10, which gives you 100 messages per second), and then do my rendering in response to a WM_TIMER. Automatic frame limiter ;)

0
101 Sep 28, 2011 at 14:37

@Reedbeta

The g_fRendering flag gets set to false when you minimize the app, or when it starts shutting down; in that case I use GetMessage, which waits for a message, rather than PeekMessage. Down inside the Render() call I’m eventually calling Present() (since I’m using D3D) and telling it to wait for vsync, which both prevents tearing (usually…) and suspends the thread so that other apps can run. It’s also important to handle *all* available messages after each rendered frame, not just one, hence the PeekMessage in the inner while loop. Otherwise messages can back up and overflow the queue because you don’t process them fast enough. Mouse moves especially can generate several messages per frame.

If you do this, how would you then set in a frame limiter? Would you do that inside the scope where Update & Render get called?

0
101 Sep 28, 2011 at 14:49

No, I would do that in the message loop itself. Calculate how much time there’s left before you want to do another frame, and use MsgWaitForMultipleObjects() to wait for a message with a timeout, and use as the timeout the time until the next frame you just calculated.

But as said, I would just stick to SetTimer(), it makes your code clean and simple.

0
165 Sep 28, 2011 at 16:59

@_NOISEcore

If you do this, how would you then set in a frame limiter? Would you do that inside the scope where Update & Render get called?

Frame limiting is taken care of by the vsync. I don’t have a need to limit to some arbitrary rate like 100 fps; I only ever want to run at the refresh rate (or divisors thereof).

0
101 Sep 28, 2011 at 17:09

Some people turn off vsync. You’d better still have some other means to limit the framerate available as well. Besides, there is no vsync in windowed mode.

0
165 Sep 28, 2011 at 18:10

@.oisyn

Besides, there is no vsync in windowed mode.

Uhm…what? ;) I’m using vsync just fine in windowed mode in my own Direct3D app…

0
101 Sep 28, 2011 at 18:36

Well, the problem is that I’m currently working on a little project for school (sort of) that tries to make as much use of GDI as possible.

So I don’t really have access to VSYNC (I think), in which I just switch to limiting the framerate to the refresh rate of the screen (or more if desired)

That’s why I need to implement the timer :)

0
101 Sep 28, 2011 at 19:36

For simple game you don’t need to redraw every frame (for tetris you must redraw on button press & timer tick only). Put you drawing code in WM_PAINT handler (together with ValidateRect if needed) and call InvalidateRect when you need to update window contents.

0
101 Sep 28, 2011 at 21:39

@Reedbeta

Uhm…what? :huh: I’m using vsync just fine in windowed mode in my own Direct3D app…

It appears that you are right. I don’t know where I got this from ;)

0
101 Sep 29, 2011 at 09:50

@’

‘]For simple game you don’t need to redraw every frame (for tetris you must redraw on button press & timer tick only). Put you drawing code in WM_PAINT handler (together with ValidateRect if needed) and call InvalidateRect when you need to update window contents.

I actually haven’t thought of that. I still need alot of “lessons” on effeciency :)
Thank you !

EDIT: I do have an additional problem atm. Well 2, concerning the same things.
First of all, my message loop looks like this:

        MSG msg = {};
while(msg.message != WM_QUIT)
{
if(m_bActive)
{
// If the window is active

while(m_bActive && PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Sleep(0);
}
else
{
if(!GetMessage(&msg,NULL,0,0))
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}


The problem is, m_bActive gets set to false when WM_ACTIVATE with wParam being WA_INACTIVE, and else it gets set back to true.
When I click away, this works, but when I just minimize it keeps using thesame CPU amount as when activated.

This comes to my second problem, at the moment my program doesn’t do that much, but yet it uses 25% of my CPU (dual core so..)
This is probably because of me not returning the remainder of my time slice, but I don’t know how to do this. They say with Sleep(0)
but this doesn’t seem to do anything.

0
101 Sep 29, 2011 at 11:01

Please, don’t resort to Sleep(0), it’s bad practice for the purpose you’re using it for.

hey say with Sleep(0) but this doesn’t seem to do anything.

It does, but if there’s no other process who wants CPU time it still goes to your app.

0
101 Sep 29, 2011 at 14:32

If sleep is a bad practice, what should I use then? MsgWaitForMultipleObjects ?

0
101 Sep 29, 2011 at 14:47

I’m not saying Sleep is bad practice, I was talking about Sleep(0). You don’t want to just give up the remainded of the time slice, you want to wait until it’s time for the next frame. So you should calculate how long you’d like to wait.

And you can implement the wait with Sleep(), but the downside is that you’re unable to process messages when you’re sleeping. So MsgWaitForMultipleObjects() is, in my opinion, the better choice.

0
165 Sep 29, 2011 at 16:21

@_NOISEcore

When I click away, this works, but when I just minimize it keeps using thesame CPU amount as when activated.

You’ll need to trap WM_SIZE as well as WM_ACTIVATE, and check for wParam being SIZE_MINIMIZED.

0
101 Sep 29, 2011 at 17:17

@Reedbeta

You’ll need to trap WM_SIZE as well as WM_ACTIVATE, and check for wParam being SIZE_MINIMIZED.

This does not seem to do the trick. But I’ll look into that later :)

However, I still have the issue that apparently Sleep(0) doesn’t do anything (still uses 25%) and so does MsgWaitForMultipleObjects, however, Sleep(1) does reduce it greatly (0 or 1%) but cuts my framerate in half.