Win32 flicker free drawing without double buffering.

Started by
1 comment, last by Skizz 17 years, 4 months ago
Is it possible to perform flicker free drawing without double buffering. I'm implementing my own text control. I'm processing the WM_ERASEBKGND and doing no drawing in it. I use ExtTextOut to print text and fill in a rect at the same time. All drawing done never overlaps any other drawing. The entire client area is painted too. Most flicker has been eliminated. Yet I still see the slightest flicker. It's like all the ExtTextOut calls are not being performed within the same vertical retrace of the monitor. My custom text control could easily be full screen. I'm basically creating the text control in VisualStudio where all source code is displayed. How would VisualStudio solve this problem. Assuming it's using double buffering for a moment. It could create one bitmap whose pixel format matches the screen's pixel format. The bitmap resolution would be the max width and height of all document windows. Whenever a document window needs to be redrawn, it does nothing in WM_ERASEBKGND, draws to the area of the bitmap matching it's client size, and calls BitBlt() to copy over the pixel data to the window. This raises a question. Since the document window could be very large, potentially fullscreen (1280+ x 1024+), will the BitBlt() execute all within a vertical retrace. Will I see no flicker? Or should I be invalidating only the portions of the document window that absolutely needs to be redrawn as the user types? In typing text, everything below the text would need to be repainted. Scrolling of course would cause all of the client are to be repainted. The EDIT window has existed since the beginning of windows. I find it hard to believe it achieves it's flicker free drawing via double buffering. Memory used to be rather low back in the Windows 3.1 days. Is there just a secret I don't know about in achieving flicker free drawing without double buffering. How does VisualStudio, Word, Internet Explorer do it?????????? Any tips would be apprecieated.
Advertisement
I think you need the parent of the text control to have the WS_CLIPCHILDREN style, otherwise it will paint its background over your area as well.
GDI and GDI+ are not tied to the vertical refresh of the display. GDI/GDI+ can draw to non-display devices such as a printer so there's no generic concept of vertical refresh. Drawing in the WM_PAINT and forcing no update in WM_ERASEBKGND is the only way to do it without double buffering. This means doing the drawing as quick as possible1 - so no memory allocations or resource acquisitions during the paint. Double buffering will make things ultra flicker free. A BitBlt that takes more than one frame (or crosses a vertiical refresh) won't flicker. You'll only notice 'shearing', the top half of one image and the bottom half of the other image. This is more noticable where there's horizontal movement between Blts, where vertical lines become broken. For a text control it won't be a problem.

Following on from (1), you must also limit your drawing to the region being updated and only update those areas that actually need to be redrawn (dirty rectangles).

Skizz

This topic is closed to new replies.

Advertisement