调整大小时Win32 GUI闪烁

时间:2010-01-10 09:30:03

标签: user-interface winapi resize flicker

我有一个带有选项卡控件的Win32 GUI程序,每个选项卡都有一个列表视图控件。每当调整窗口大小时,都会出现大量闪烁。我尝试过以下的事情:

  • 在主wndproc中处理WM_ERASEBKGND并返回TRUE。没效果。
  • 过滤掉事件循环中的所有WM_ERASEBKGND消息。没效果。
  • 在主窗口上设置WM_CLIPCHILDREN样式。现在,当调整窗口大小时,列表视图控件将被简单地删除为白色背景并且不会重绘。
  • 使用DefWindowPos而不是MoveWindow。没效果。
  • 在MoveWindow中为bRepaint传递FALSE。与设置WS_CLIPCHILDREN(见上文)相同。

这是RegisterClassEx代码:

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);

WM_SIZE处理程序:

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);

样式如下:

  • 主窗口:WS_OVERLAPPEDWINDOW
  • 标签控件:WS_CHILD(和WS_VISIBLE
  • 列表视图控件:WS_CHILD | WS_BORDER | LVS_REPORT(和WS_VISIBLE

4 个答案:

答案 0 :(得分:4)

事实证明Z-ordering存在问题 - 在列表视图上调用BringWindowToTop解决了这个问题。

答案 1 :(得分:2)

Windows支持重新调整大小的批处理操作,旨在避免在大量子窗口独立调整大小时导致的闪烁。有关详细信息,请参阅BeginDeferWindowPos

如果不起作用,请尝试WM_SETREDRAW消息。看起来可以停止绘制父窗口 - 这将禁止所有子控件,然后,当布局完成时,再次启用绘图,并调用RedrawWindow一次重绘整个窗口。我确实认为这是Deferred窗口定位在内部使用的内容。

答案 2 :(得分:1)

我可能会说明显而已,但我认为 double buffering 是Win32闪烁的解决方案。我是一名Java开发人员,我一直在写win32,所以如果我在说废话,请告诉我

以下是如何:http://www.gamedev.net/community/forums/topic.asp?topic_id=411559

以下是一些样本代码:http://www.codeproject.com/KB/cpp/DoubleBuffering.aspx

这是.NET等效问题(?):How to prevent a Windows Forms TextBox from flickering on resize?

答案 3 :(得分:0)

  

当ListView停靠时,如   Windows资源管理器(你有一个好的   项目数量),调整主要大小   表单将导致所有项目   闪烁。   http://www.codeproject.com/KB/list/listviewxp.aspx