How to avoid flicker while handling WM_ERASEBKGND in Windows dialog

半腔热情 提交于 2019-12-19 15:41:32

问题


I have a dialog that resizes. It also has a custom background which I paint in response to a WM_ERASEBKGND call (currently a simple call to FillSolidRect).

When the dialog is resized, there is tremendous flickering going on. To try and reduce the flickering I enumerate all child windows and add them to the clipping region. That seems to help a little -- now the flickering is mostly evident in all of the child controls as they repaint.

How can I make the dialog flicker-free while resizing? I suspect double-buffering must play a part, but I'm not sure how to do that with a dialog with child controls (without making all child controls owner-draw or something like that).

I should note that I'm using C++ (not .NET), and MFC, although pure Win32-based solutions are welcomed :)

NOTE: One thing I tried but which didn't work (not sure why) was:

CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.FillSolidRect(rect, backgroundColor);

pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);

回答1:


Assuming that "FillSolidRect" is the erase of your background then return TRUE from the WM_ERASEBKGND.

To do the double buffering that you are almost doing in your code fragment, you will need to use CreateCompatibleBitmap and select that into your memDC.




回答2:


Try adding the following line to your OnInitDialog function:

    ModifyStyle(0, WS_CLIPCHILDREN, 0);



回答3:


Do nothing in the WM_ERASEBKGND handling and do the erase as part of your main WM_PAINT. You can either paint smarter so that you only redraw the invalid areas, or more easily, double-buffer the drawing.

By not doing anything in the erase background, you have all your drawing code in one location which should make it easier for others to follow and maintain.




回答4:


If you are targeting WinXP or higher, you can also use the WS_EX_COMPOSITED style to enable double-buffering by default for top-level windows with this style. Bear in mind this has its own set of limitations -- specifically, no more drawing out of OnPaint cycles using GetDC, etc.




回答5:


you can set parameter of your call to InvalidateRect method as false. This will prevent you to send WM_ERASEBKGND when the window will redraw. Here is a nice link to prevent flickering in window.




回答6:


Double buffering is indeed the only way to make this work.

Child controls will take care of themselves so long as you make sure CLIPCHILDREN.



来源:https://stackoverflow.com/questions/164751/how-to-avoid-flicker-while-handling-wm-erasebkgnd-in-windows-dialog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!