We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now


clipping problem with rapid MoveWindow calls

Ashurbanipal asked
Medium Priority
Last Modified: 2013-11-19
In a window derived from CView I am doing some animation.  When I do fast repeated calls to MoveWindow for an image which is supposed to fly around the screen, the image disappears partway through the movement.  It acts like it is getting clipped.  Even when I only have one image in the view, it still won't go around in a circle for example without getting clipped.  The clipping does not happen on the first move, but once it starts the image does not appear again until it stops moving.  At this point the view gets invalidated so that brings it back.

While I am not writing a game, the animation probably uses some of the same techniques.  Do I need to handle the movement differently?
Watch Question

That happens because by default the windows erase their background. That means that every time you move your window it erases its entire background and then it paints itself. The same happens to the parent of the moving window, but only in the updated region. That's why the best result you will get is a flickering flying window.
You can work around the problem handling the WM_ERASEBKGND in the moving window. If you supply a handler that does nothing then you will not get the nasty flicker. You will need to do the same with the parent window, since it also erases its background at the place where the moving window was. Don't forget, however, that your OnPaint() handlers should cover the entire window surface. Otherwise you will get some ugly mess on the screen.

some pointers...

If the clipping behaviour is only in horizontal areas, then this could be due to the redraw of the window and the refreshing of the screen clashing.  Games programmers synchronize their redraws to the 'vertical retrace' event of the video card to avoid this.

Also, redraws of windows... ie, delivery of WM_PAINT, is not synchronized to the MoveWindow() event.  The WM_PAINT is posted to the window and is queued with other messages waiting for the window.

If you want high-quality animation, and the data you are animating is static, ie, does not vary, you are better off making an AVI like the ones the '95 user interface shows while doing file copies.

If WM_ERASEBKGND is the issue here, I recall you can set a window's - it may be a window class' - background brush to NULL.




I checked out erasing the background, but it did not work very well.  Then I tried the following block of code immediately after the MoveWindow.  

MSG msg;
while (::PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {

This removed the clipping problem, but the image flickers contiually through the move.  From what I've read the best way to deal with this is by using a technique called "virtual windows", where everything gets output to a virtual HDC and when it comes time to paint the proper region is copied from the virtual HDC to the screen.  When I try to implement it though in the main window of the MDI nothing happens, so I must be doing something wrong.

I create the virtual HDC in the OnCreate for the main window

int max_x=GetSystemMetrics(SM_CXSCREEN);
int max_y=GetSystemMetrics(SM_CYSCREEN);

HDC hdc=::GetDC(GetSafeHwnd());
HBITMAP hbit=CreateCompatibleBitmap(hdc,max_x,max_y);
HBRUSH hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH);

Then in OnPaint for the main window it looks like this:

PAINTSTRUCT paintstruct;
HDC hdc=:BeginPaint(GetSafeHwnd(),&paintstruct);

I expected the above to have some effect, at least making a mess of the screen, but nothing.  Is this code really overriding the paint command?  It seems as if a ON_WM_PAINT message gets sent, but the painting is really done elsewhere.  How do I do this?

Ash, on your flickering problem, you will always have some flicker because your screen update is not syncd to the video card frame.

On your latest issue, the MFC code that calls OnPaint() has already done the Begin/EndPaint() call and given you a nice prepared hDC as a parameter.  Kill your Begin/EndPaint() code, and use the supplied hDC and maybe something will happen for you.

Ash, sorry, I was thinking of CView::OnDraw().  Ignore my second point above.


It sounds as though I need to do two things, sync to the video card and get the virtual hdc working.  One book I have give an example for the virtual hdc and that is the code I've tried to implement.  Either I've set it up wrong or there is more going on with MFC (their example isn't MFC based).  What's the trick?

It sounds as though I need a good book on game programming or web site with good examples.  I'm stuck though in having to use a CView in an MDI application, no flexibility there.
Unlock this solution and get a sample of our free trial.
(No credit card required)

>And this windows animation stuff really does not have to
> do anything with the so called "synchronization of the
> video card frame". That only can be used when you draw
> directly to the video card.

There are a bunch of APIs like DirectDraw which are very aware of Frame Sync/ frame buffering issues.  You're right that it is hard to synchronize Windows GDI activity around the Frame Sync, but that doesn't mean that using the Frame Sync is a bad idea, it means that animating via the GDI will give you artefacts like 'tearing'.

Much better to let someone else's specific implementation take the strain and use an AVI if you can.

warmcat: agree...
I only said that _windows_ animation has nothing to do with frame sync and so on... Of course DirectDraw and DirectX technology at all are for that, but it _cannot_ be implemented in any real windows applications, i.e. they are always full screen, full PC control, etc... gamelike stuff :-)
I just thought that Ashurbanipal is trying to use animation in standard windows application and not in a DirectDraw one... AVI idea is good and cheap in time and resource - I agree with that also, but what if the animation depends on user input? You cannot achieve that with static AVIs...


>Of course DirectDraw and DirectX technology at all are
>for that, but it _cannot_ be implemented in any real
>windows applications, i.e. they are always full screen,
>full PC control

This is not true.  Even Quake II, which uses one or another of these APIs runs happily in a window on my PC while other apps share time.  Not that it's the best way to experience it, as a 640x480 window on a 1600x1200 desktop, but it works fine that way, as I recall without tearing.

On the AVI thing, yes, it's only suitable for static animations, as I said earlier, but it's not clear what Ash is trying to achieve.


Ash is dealing with a software package which simulates industrial plants like paper mills.  Originally it was never meant to have a graphic display, but the effort to make it a general use product requires it.  Currently the graphics work fine for pumps and plots of land that don't move around the screen.  Then I tried to simulate planetary motion, that's when the problem came up.  Speed is a serious consideration for simulation, dealing with the screen is quite a load on the package.  Once I get it working I can start to look into optimizing it.  I haven't dealt with AVI's before, but it sounds like that will come.  All part of the continuing education.

I'm neck deep in alligators and should be able to check out your example this evening, Mile.  It looks pretty good.

What's up Ash? Any progress with that problem?


Your example works as you described.  When I went to implement it in my software two issues came up.

1. I was using MoveTo and LineTo, both class members of dc.  Do win32 versions exist for these?  I couldn't find any on the developer's network cd, but they must exist.

2. I take it that child windows of the CView need to have their OnPaint overriden so that they write to the m_virtualdc in their parent.

Are you in school?  I may have need of a good software person in the future.

Well Ash,

1.In Win32 there are ::LineTo and CDC::LineTo functions - they are exactly the same as in Win16. ::MoveTo is changed to ::MoveToEx in Win32, but CDC still has a member CDC::MoveTo.

2. Yes - you have to override OnPaint functions of all the children of your m_virtualdc holder. Firs make them transparent - i.e. override OnEraseBkgnd() like shown so it does nothig. Second override OnPaint() and send all the drawing to the m_virtualdc of the parent - you can access m_virtualdc using a global pointer to it or, better, cast the CWnd* returned from GetParent() function to say CTestView. You have to calculate the accurate coordinates when drawing from child windows, since their 0, 0 position is offset according to the m_virtualdc 0, 0 position.

I am not in school - I am currently a software developer... What will you need that software person for? Consulting I guess :-) Be welcome to ask questions

Ash, if my answer works for you you are supposed to rate me and grant me the points...
thank you...


Yes, I know.

My needs will involve modifications to an existing software package.  Two issues come to mind, one involves 3D display of data, the other deals with a dll which interfaces between the package and various external packages.  The first one I would like to have, but don't have a good feel for what it would cost versus what would be a satisfactory final result.  The second depends on whether customers are willing to come up with the money for it, I'll know that later this year.  When the time comes I may need to farm these tasks out, that's why I'm interested in people who might be able to handle them.

John Arkison
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.