5

I have a Win32 GUI program with a tab control, each tab having a list view control. There is massive flickering whenever the window is resized. I've tried the following things:

  • Handling WM_ERASEBKGND in the main wndproc and returning TRUE. No effect.
  • Filtering out all WM_ERASEBKGND messages in the event loop. No effect.
  • Setting the WM_CLIPCHILDREN style on the main window. Now when the window is resized the list view control is simply erased to a white background and doesn't redraw.
  • Using DefWindowPos instead of MoveWindow. No effect.
  • Passing FALSE for bRepaint in MoveWindow. Same effect as setting WS_CLIPCHILDREN (see above).

Here's the RegisterClassEx code:

memset(&wcex, 0, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0;
wcex.lpfnWndProc = PhMainWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = PhInstanceHandle;
wcex.hIcon = LoadIcon(PhInstanceHandle, MAKEINTRESOURCE(IDI_PROCESSHACKER));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
//wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MAINWND);
wcex.lpszClassName = PhWindowClassName;
wcex.hIconSm = (HICON)LoadImage(PhInstanceHandle, MAKEINTRESOURCE(IDI_PROCESSHACKER), IMAGE_ICON, 16, 16, 0);

The WM_SIZE handler:

RECT rect;

// Resize the tab control.

GetClientRect(PhMainWndHandle, &rect);
MoveWindow(TabControlHandle, rect.left, rect.top,
    rect.right - rect.left, rect.bottom - rect.top, TRUE);

// Resize the list view.

TabCtrl_AdjustRect(TabControlHandle, FALSE, &rect);

MoveWindow(ListViewHandle, rect.left, rect.top,
    rect.right - rect.left, rect.bottom - rect.top, TRUE);

The styles are as follows:

  • Main window: WS_OVERLAPPEDWINDOW
  • Tab control: WS_CHILD (and WS_VISIBLE)
  • List view control: WS_CHILD | WS_BORDER | LVS_REPORT (and WS_VISIBLE)
wj32
  • 8,053
  • 3
  • 28
  • 37

4 Answers4

5

It turned out there was a problem with the Z-ordering - calling BringWindowToTop on the list view solved the problem.

wj32
  • 8,053
  • 3
  • 28
  • 37
  • I had the same problem. Calling `BringWindowToTop` for window shown as tab's contents solved it. I have done it in InitDialog after showing the initial tab and each time selected tab changed after showing new tab. – Adam Badura Dec 17 '10 at 12:49
  • 5
    I also had similar problems with flickering (on resizing) tabs control itself. This was solved by adding `WS_CLIPCHILDREN` style to parent dialog. – Adam Badura Dec 17 '10 at 12:51
  • Thanks for this, had the same problem and calling BringWindowToTop solved it – Lefteris Jan 28 '12 at 05:59
2

Windows supports a re-size batching operation that is meant to avoid flicker caused when lots of child windows are indepently resized. See BeginDeferWindowPos for more information on that.

If that is not working, then try the WM_SETREDRAW message. It looks possible to stop drawing of the parent window - which will inhibit all the child controls, then, when the layout is finished, enable drawing again, and call RedrawWindow to repaint the entire window in one pass. I did rather think that this is what Defered window positioning would use internally.

Chris Becke
  • 34,244
  • 12
  • 79
  • 148
1

I may be stating the obvious, but I thought double buffering is the solution to Win32 flickers. I'm a Java Developer and it has been a while sine I wrote win32 so please let me know if I'm talking nonsense

Here is the how to: http://www.gamedev.net/community/forums/topic.asp?topic_id=411559

Here is some sampe code: http://www.codeproject.com/KB/cpp/DoubleBuffering.aspx

Here is the .NET equivalent question (?): How to prevent a Windows Forms TextBox from flickering on resize?

Community
  • 1
  • 1
Eran Medan
  • 44,555
  • 61
  • 184
  • 276
  • I set the LVS_EX_DOUBLEBUFFER extended style on the list view already. Or are you talking about another kind of double buffering? FYI I tried using WS_EX_COMPOSITED but as with WS_CLIPCHILDREN the list view doesn't redraw anymore :( – wj32 Jan 10 '10 at 10:29
0

When a ListView is Docked, as in Windows Explorer (and you have a good amount of items), resizing the main form will cause all of the items to flicker. http://www.codeproject.com/KB/list/listviewxp.aspx

Jonke
  • 6,525
  • 2
  • 25
  • 40
  • I'm not using .NET, so it is not "docked". – wj32 Jan 10 '10 at 10:28
  • Even if the article talks about .net the problem is a win32 generic trouble and all of us who have done anything using win32api gui-controls have more or less hit the listview flicker problem when doing anything that isn't toy code. – Jonke Jan 10 '10 at 11:00
  • Could you suggest how the article would apply to my situation? I've already tried filtering out all erase background messages, so that can't be the problem :( – wj32 Jan 10 '10 at 11:08
  • Have you isolated the trouble as a listview trouble? the tabcontrols have there own way of messing things up. Maybe you have just missed some call that forces something to update. – Jonke Jan 10 '10 at 11:32
  • Do you expect me to know what functions to use? ;) I'm a fairly experienced developer, but I have 0 experience with Win32 GUIs. – wj32 Jan 10 '10 at 12:18