I'm new to native c++. Right now, I made it so when I press the left mouse button, it has a for loop that does InvalidateRect and draws a rectangle, and increments X by the box size each time it iterates. But, C++ is so much faster and efficient at drawing than C# that, it draws all this instantly. What I would like is for it to invalidate the rectangle, show the rectangle, wait 50ms, then continue the loop. I tried Sleep(50) but it still waits until painting is done before showing the result. I also tried PeekMessage but it did not change anything. Any help would be appreciated. Thanks
+5
A:
DoEvents basically translates as:
void DoEvents()
{
MSG msg;
while ( ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if ( ::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
:: DispatchMessage(&msg);
}
else
break;
}
}
Reed Copsey
2009-09-12 13:20:26
+1, almost correct, except that the return value of GetMessage is not checked and WM_QUIT is not correctly handled.
Filip Navara
2009-09-12 13:23:44
If GetMessage return 0, then the WM_QUIT message needs to be reposted (http://blogs.msdn.com/oldnewthing/archive/2005/02/22/378018.aspx). GetMessage can also return -1, which should be handled.
Filip Navara
2009-09-12 13:29:03
+1
A:
I am a bit rusty in Win32 API, but the asynchronous way of doing this would be:
- Invalidate the rect
- Set a timer (see below) to send a message after 50ms
- Return to the event loop to let WM_PAINT events happen
- On receiving the timer message, move the rect, then repeat
This way integrates nicely with being event driven. I realize this is not exactly what you ask for, but I thought I'd mention it as a possible solution anyway :)
EDIT: A quick google turns up the Windows API call SetTimer which you can use to facilitate this. The message will be a WM_TIMER one.
Magnus Hoff
2009-09-12 13:27:38