2010-01-10 136 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