2010-01-10 77 views
5

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

  • 在main 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
  • Tab控件:WS_CHILD(和WS_VISIBLE
  • 列表视图控件:WS_CHILD | WS_BORDER | LVS_REPORT(和WS_VISIBLE
+4

啊是的,win32窗口闪烁。这带来回忆... – 2010-01-10 10:42:19

+0

我不知道如果双缓冲将有助于某种方式... – 2010-01-11 03:24:35

回答

4

事实证明,Z顺序存在问题 - 在列表视图中调用BringWindowToTop解决了问题。

+0

我有同样的问题。调用窗口显示为标签的内容的'BringWindowToTop'解决它。我已经完成它InitDialog后显示初始选项卡每次在显示新选项卡后选择的选项卡都改变了 – 2010-12-17 12:49:30

+2

我也有类似的闪烁问题(在调整大小时)选项卡控制本身,这是通过在父对话框中添加'WS_CLIPCHILDREN'风格解决的 – 2010-12-17 12:51:09

+0

@Adam:非常感谢,给父母修好了。 – 2011-02-27 16:04:19

2

Windows支持,是为了避免闪烁,当大量的子窗口被自主承担调整重新大小批量操作。有关更多信息,请参见BeginDeferWindowPos

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

+0

我已经尝试过,因为我在问题中说... – wj32 2010-01-10 10:17:57

+0

对不起,错过了。下一站,WM_SETREDRAW – 2010-01-10 13:01:37

0

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

+0

我没有使用.NET,所以它没有“停靠”。 – wj32 2010-01-10 10:28:33

+0

即使文章谈到.net这个问题是一个win32通用麻烦,我们所有使用win32api gui-controls的人都会在做任何不是玩具代码的事情时或多或少地碰到listview闪烁问题。 – Jonke 2010-01-10 11:00:25

+0

你能否建议这篇文章如何应用于我的情况?我已经尝试过滤掉所有的擦除背景消息,所以这不可能是问题:( – wj32 2010-01-10 11:08:53

1

我可说明明显,但我认为double buffering是解决Win32的闪烁。我是一个Java开发者,它已经有一段时间正弦我写的Win32所以请让我知道如果我胡说

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

下面是一些SAMPE代码:http://www.codeproject.com/KB/cpp/DoubleBuffering.aspx

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

+0

我已经在列表视图上设置了LVS_EX_DOUBLEBUFFER扩展样式。还是你在谈论另一种双缓冲?仅供参考,我试过使用WS_EX_COMPOSITED,但与WS_CLIPCHILDREN列表视图不重画了:( – wj32 2010-01-10 10:29:50