What is to best approach to repeatedly invalidate a window using InvalidateRect?

686 views Asked by At

I need to repeatedly redraw a window showing some form of continous analysis. Now:

1) If I do that in WM_PAINT after the painting, I basically kill everyone else's painting, so it's not usable.

2) If I do that in a timer, it is kind of lagging.

So what is the best way to do that so the window is frequently repainted, but when the OS is busy processing some data or by painting other applications, it lowers the rate. I always thought the OS should take care of distributing the CPU power between the processes leaving the graphics secondary to ensure actual processing has enough time, but it doesn't look so on Windows nor on Mac.

1

There are 1 answers

2
gavinb On

Typically you would create a timer and invalidate the window at each timer tick. If there is a lag, it could be that the update frequency is too high, or the processing performed in the paint method is too expensive.

Keep in mind that games with complex 3D scenes routinely achieve 60fps (and higher). So high framerate updates are certainly possible.

Note that under Windows, the WM_TIMER event is notoriously inconsistent. You may need to explore other high-resolution timers if you need more than ~1 second resolution.

On the Mac, you can create an NSTimer and call setNeedsDisplay:YES on your NSView. Something like this:

// in your init... method
NSTimer* repaintTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
    target:self
    selector:@selector(timerTickHandler:)
    userInfo:nil
   repeats:YES];

// ...

-(void)timerTickHandler(NSTimer*)timer {
    [self.view setNeedsDisplay:YES];
}

The NSTimer in Cocoa is quite reliable, so the above should work just fine, even for quite fast updates.

If you need to update at frame-rate (ie. 25fps) have a look at the CVDisplayLink support. This is really only needed for video applications and the like.