Win32 control flickering

Started by
5 comments, last by GameDev.net 19 years, 6 months ago
Using WTL I have been rewriting my conversation windows in a hierarchical fashion: TabbedConversationWindow, which has-a: - ConversationCtrl, which has-a: -- Splitter, which has: --- MessageHistoryCtrl ---- RichEdit box --- MessageEntryCtrl ---- RichEdit box ---- Send button Now from an engineering perspective there is no doubt in my mind that this is pretty close to optimal in terms of maintainability. However, I'm running into some difficulties. I'm using a VS.NET-like tab control inside of my TabbedConversationWindow, and when I resize the frame window, the inner controls (RichEdit boxes) flicker like crazy. I don't think it is a problem with the tab control itself because the sample included with it doesn't flicker at all. I have "Show window contents while dragging" on, but I never see flicker in apps like Firebird. Inside of each user control I handle WM_SIZE by just calling MoveWindow() on the child windows contained with the new size. The layout logic is very simple, mostly consisting of a few subtractions. I ran DevPartner on it and it came back with 99.9% of the time being spent inside system DLLs, mostly inside of DefWindowProcW.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Advertisement
Have you tried SetWindowPos instead of MoveWindow?
SetWindowPos (window_handle, 0, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);

Skizz
Tried that, same flicker. Narrowed it down to be WM_ERASEBKGD. If I return nonzero to indicate that I would handle erasing the background, it is fine. The background of the control shows briefly before the textbox is drawn over it. But, the background has to be drawn or else you end up with significant visual artifacts.

After some fiddling and a few hours of Googling I found the solution and rationale. My child controls didn't all have the WS_CLIPCHILDREN style set. It affects how large the update region is when portions of a window are invalidated. Without it, the entire background is drawn first, then the control. This was the flicker I was seeing. With it, the update regions are constrained to be only in areas that don't have a control in them.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
antareus, a have just the same problem as you did. But the problem is I don't understand your solution. When / if I create a window with the additional style tag WS_CLIPCHILDREN, like this:

CreateWindowEx( WS_EX_CLIENTEDGE,
WC_LISTVIEW, "",
WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_CLIPCHILDREN,
8, 8,
544, 240,
hWndParent,
NULL,
hInstance,
NULL);

It would still flicker. AND I created the parent window WITH the WS_CLIPCHILDREN tag.

Btw, I use MoveWindow API when resizing.
You need to set WS_CLIPCHILDREN on the window that contains the ListBox. Setting on the listbox just says "when this window (that is, the listbox), exclude child controls from the invalidated region." Setting it on the window means "exclude the listbox from the invalidated region when redrawing."
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Most of the common controls erase the background they will be drawing in anyways so WS_CLIPCHILDREN will not help much (a little bit but not much). Tab controls, edit controls, and list boxes I am sure do this, probably more.
Ok, now I have made the buttons stop flicker by adding an WM_CLIPCHILDREN flag to the parent window, but the ListView control still does...
Has anyone made the ListView (WC_LISTVIEW) control stop flicker while resizing?!?

This topic is closed to new replies.

Advertisement