Visual C++ programming in the Windows GDI map flashing solution

  • 2020-04-02 02:58:03
  • OfStack

This paper illustrates the solution of GDI map flicker in Visual C++ programming. Share with you for your reference. The details are as follows:

The typical Windows complex interface USES multiple Windows and textures to beautify it, so it's inevitable that Windows will flicker as they move or change size.

Let's talk about what causes flicker

Reason 1:

If you are familiar with graphics, calling the GDI function to output to the screen does not immediately appear on the screen
It is only written to the video memory, and the video card every once in a while to the video memory content output to the screen, this is the refresh cycle.

General graphics card refresh cycle is 1/80 seconds or so, the specific number can be set.

So here's the problem, usually you draw the background color first, and then you draw the content, if the two operations are not the same
When the refresh cycle is completed, the visual impression is to see the image with only the background color, and then see the image with the painting content.
So it feels like it's flickering.

Solutions:

Output image as fast as possible, so that the output is completed in a refresh cycle, if the output content is a lot of slow, then use
Memory buffer method, the content to be output in memory ready, and then output to video memory. Remember that an API call is usually ok
Complete in a refresh cycle.

For GDI, just use the method of creating a memory DC

Reason two:

The complex interface consists of several layers of Windows. When Windows changes its size, it first redraws the parent window, then the child window, and then the child window
The window repainting process is generally not completed within a refresh cycle, so it flashes.

We know that there is no need to redraw the part of the parent window that is blocked by the quilt window

Solutions:

Add a style WS_CLIPCHILDREN to the window so that the parts blocked by the quilt window on the parent window are not redrawn.

If there is overlap between sibling Windows, you need to add the WS_CLIPSIBLINGS style

Three reasons:

Sometimes you need to use controls on a window, such as IE, which flashes when your window changes size, even if you have WS_CLIPCHILDREN
It is no use. The reason is that the window's class style is CS_HREDRAW or CS_VREDRAW, which means that the window changes in width or height
Redraw, but this will cause IE to blink

Solutions:

Do not use either style when registering a window class. If the window needs to be redrawn when changing its size, it can be redrawn at WM_SIZE
Calling RedrawWindow.

Reason 4:

There are many Windows on the interface, and when you change the size, many Windows have to be moved and resized, if you use the MoveWindow or SetWindowPos apis
Change the size and position of the window, because they wait for the window to be redrawn before returning, so the process is slow, so the visual effect may flicker.

Solutions:

Use the following apis to handle window movement, BeginDeferWindowPos, DeferWindowPos, and EndDeferWindowPos
Call BeginDeferWindowPos to set the number of Windows to be moved
Using DeferWindowPos to move the window, this API doesn't really cause the window to move
EndDeferWindowPos changes the size and location of all Windows at once.

There is a place to pay special attention to, to carefully calculate clearly how many Windows to move, BeginDeferWindowPos Settings
The number must be the same as the actual number, otherwise in Win9x, if the actual number of Windows moved more than call BeginDeferWindowPos
Is the number that may cause the system to crash. This is not an issue with the Windows NT family.

Hope that this article described for everyone's Visual C++ programming help.


Related articles: