Does SetWindowPos paint immediately - c++

On every mouse move event, I am moving my window. From the documentation it appears that if the move is successful SetWindowPos return a non-zero value.
I wanted to confirm my inference that every time SetWindowPos returns a non-zero value, the move has already happened. Which means, the window has actually been re-painted at the new position and only then does the function return. It is NOT the case that move will happen a little while later (when some kind of message is processed) after the function has returned.

I wanted to confirm my inference that every time SetWindowPos returns a non-zero value, the move has already happened. Which means, the window has actually been re-painted
This is false assumption. Successful move and non-zero return has nothing to do with painting.
The API changes position and non-zero returned value confirm that new values were accepted. The API does not promise, does not do the complete repaint cycle as a part of its execution. More to that, change in position, Z-order etc. is likely to affect visibility of other windows too, which in turn need repaint, which in turn has to happen on respective threads. The repaints are scheduled, they are not synchronized with SetWindowPos return. Documentation on MSDN does not have any promises regarding repaints/updates. Then zero return from the API is an indication that your arguments are not accepted at all (esp. invalid window handle).
Bonus reading:
When you call the Set­Window­Pos function, the window manager updates the window size, position, whatever, and then it goes around repainting the windows that were affected by the operation. By default, the Set­Window­Pos function does a quick-repaint of the windows before returning. After the function returns, the normal WM_PAINT message does the real work of painting the window. The quick-repaint is done so that there is immediate feedback that the window did change its size, position, whatever.

SetWindowPos returns immediately after it has done its job.
But the main painting is deferred until WM_NCPAINT and WM_PAINT are received by the window. From my experience, I can say that changes to the frame are often drawn directly by SetWindowPos.
If you want the window completely redrawn call UpdateWindow or RedrawWindow (with appropriate flags) after the call to SetWindowPos

Related

How do I get the mouse's position off the dialog continuously? (MFC)

My question is:
How do i continuously get the mouse's position even when it isn't on any dialogs, in mfc?
It depends on your specific requirements. If you need to direct mouse input temporarily to a control you can call SetCapture. This will request the system to send all mouse messages to a specific window until you not longer need it by calling ReleaseCapture, or you lose it, when another window gains input focus. The latter is signaled through a WM_CAPTURECHANGED message.
If, on the other hand, you need continuous information about mouse positions you can install a timer (SetTimer) and call GetCursorPos.
You can always install a mouse hook. It's a bit overkill, but, it will give you what you want.

How to update the screen once it has lost focus

I'm working on a program that requires WM_ERASEBKGND to be disabled (to avoid flickering).
The problem comes in when my main window loses focus, and another window (another program) gains the focus.
The window that has the focus (not my program) invalidates MY program's window every time it passes over it! The result is, my window's screen turns white everywhere that another window has passed by it, leaving it almost totally blank afterward. Obviously, I cannot have a program where the screen turns white every time it loses focus.
Is there any way to continue my window's drawing operations, (continue calling wm_paint, for example) even after my window has lost focus (WM_KILLFOCUS)?
First of all, from the comments above, never send the WM_PAINT manually with SendMessage or PostMessage. Use InvalidateRect to instruct the window to be repainted.
About the WM_ERASEBKGND, the return value is used to indicate the WM_PAINT handler that the background has been erased, in case the paint procedure can be optimized. To actually prevent the background from being erased, simply do not call DefWndProc() for that message. Or even easier, set the hbrBackground to NULL in the window class.
As others mentioned the focus has nothing to do with repainting, and your window should paint normally even while in the background.

What are the differences between RedrawWindow and UpdateWindow in Win32?

What are the differences between RedrawWindow and UpdateWindow in Win32?
Since they seem to have the same purpose to refresh a window, what are the differences?
RedrawWindow is typically used to force a redraw of the entire window (or some specified region within) right now.
UpdateWindow will force a redraw of only the update region of the window, i.e. that part of the window that has been invalidated (e.g. by calling InvalidateRect) since the last paint cycle.

c++ gdi drawing ellipse problem

ok i can draw ellipse the problem is this, im trying to draw one ellipse but change its x value to different one. like this i draw one ellipse and the x value is 1 after ten seconds i want it the x value to be 10 but it seems that im creating new ellipse with x value 10. here is my code
while(sd==1)//sd equal 1
{
sf++;//sf equals 1
onPaint(hdc);
InvalidateRect(hWnd,0,true);
}
//on paint function
VOID onPaint(HDC hdc)
{
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawEllipse(&pen,sf , 0, 50, 50);
}
well i thought that invalidate rect will clear everything have been painted and repaint it but it didn't work
If you want to make an animation you are better setting a timer.
Using InvalidateRect as a way to generate WM_PAINTs seems overkill, it will do much more thant that. Instead you can draw directly in OnTimer call, since it is outside a WM_PAINT you will need to get a device context with GetDC.
For example if you can have the function DrawFrame(HDC hDC). OnTimer will update the current position and call DrawFrame, OnPaint will call DrawFrame but will not update the position (that way if you want to stop the animation you will have the last frame draw).
The DrawFrame will clear the background (probably with a FillRect), and draw the circle in the new position. If you have a large area this will flicker, to avoid it as Tom suggested you may use a memory DC and a HBITMAP for the double buffer.
You shouldn't try to draw multiple frames of an animation in one shot.
Save your variable sf somewhere, and in OnPaint(), increment sf, draw a single ellipse, and call Invalidate()
The Invalidate will trigger OnPaint() to be called again.
This should work, but will be very flickery :) You can fix the flicker by double-buffering.
InvalidateRect marks the window as "invalid", but that doesn't cause an erase and repaint to happen right away. The erasing and painting happen only when your message pump is running (e.g., the loop with GetMessage and DispatchMessage). When the message queue runs dry, GetMessage will synthesize WM_ERASEBKGND and WM_PAINT messages for the invalid windows. When those messages are dispatched to the window procedure, the window gets a chance to draw.
Your onPaint function only draws, it doesn't erase. And since your loop never exits, the message pump never gets to run.
For simple animations, the solution is to SetTimer. In your handler for the WM_TIMER messages, update your variables for single frame, call InvalidateRect, and return (which lets the message pump keep running). The erasing and painting message will happen, then the timer will fire again, and you'll get the next frame.

Difference between InvalidateRect and RedrawWindow

When I want to redraw a window, is there any preferred function to call between InvalidateRect and RedrawWindow?
For instance, are these two calls equal: (win would be a HWND)
RedrawWindow(win, NULL, NULL, RDW_INVALIDATE);
InvalidateRect(win, NULL, NULL);
The main question(s): When should I use one or the other? Are there any differences that happen in the background? (different WM_messages / focus / order / priorities..)
The reason that I want to redraw the window is because I send a new image to it that I want it to display, meaning the content of the window is no longer valid.
InvalidateRect does not immediately redraw the window. It simply "schedules" a future redraw for a specific rectangular area of the window. Using InvalidateRect you may schedule as many areas as you want, making them accumulate in some internal buffer. The actual redrawing for all accumulated scheduled areas will take place later, when the window has nothing else to do. (Of course, if the window is idle at the moment when you issue the InvalidateRect call, the redrawing will take place immediately).
You can also force an immediate redraw for all currently accumulated invalidated areas by calling UpdateWindow. But, again, if you are not in a hurry, explicitly calling UpdateWindow is not necessary, since once the window is idle it will perform a redraw for all currently invalidated areas automatically.
RedrawWindow, on the other hand, is a function with a much wider and flexible set of capabilities. It can be used to perform invalidation scheduling (i.e. the same thing InvalidateRect does) or it can be used to forcefully perform immediate redrawing of the specified area, without doing any "scheduling". In the latter case calling RedrawWindow is virtually equivalent to calling InvalidateRect and then immediately calling UpdateWindow.
RedrawWindow(win, NULL, NULL, RDW_INVALIDATE); and InvalidateRect(win, NULL, NULL); are equivalent. Both functions invalidate the window. The WM_PAINT occurs at the normal time (no other messages in the application queue) in both cases.
If you want the paint to be done immediately then calling either RedrawWindow(win, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW) or InvalidateRect followed by an UpdateWindow will do that.
RedrawWindow simply gives more options with the RDW_* bits. If all you want is to invalidate the window without the immediate paint then calling InvalidateRect seems cleaner.
I don't like just giving links, but the MSDN gives you all the information you need and it would be a waste of time to re-type it all here.
RedrawWindow
InvalidateRect
In short, yes there are differences. The question is, why do you want to redraw the window? Is it because the contents are no longer valid? If so, use InvalidateRect, otherwise use RedrawWindow.
RedrawWindow repaints the window immediately. InvalidateRect only marks the window to be repainted on the next WM_PAINT message. But WM_PAINT messages have lower priority than other messages, so the repainting won't be immediately if your app is busy handling other messages.