[PATCH] user32/tests: Added tests for infinite WM_PAINT loop (resent, again)
Austin Lund
austin.lund at gmail.com
Mon Aug 10 20:46:04 CDT 2009
-------------- next part --------------
From 43828773e27dca04f5f8542d7274c6bb1a1577f9 Mon Sep 17 00:00:00 2001
From: Austin Lund <austin.lund at gmail.com>
Date: Fri, 10 Jul 2009 09:10:07 +1000
Subject: [PATCH] user32/tests: Added tests for infinite WM_PAINT loop
In most situations processing a WM_PAINT message should leave the
entire window validated when it returns. Bug 10522 displays a
situation where this is not true in Wine (when using Microsoft
software). Programs which trigger this problem have a call to
RedrawWindow() with the RDW_INVALIDATE and RDW_FRAME flags set
when processing an WM_NCPAINT message. In Wine this causes an
infinite loop of WM_PAINT messages but not in Windows. This patch
adds a test for this behaviour.
---
dlls/user32/tests/win.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index d45eba3..6ec120a 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -4859,6 +4859,78 @@ static void test_Expose(void)
DestroyWindow(mw);
}
+static LRESULT CALLBACK TestNCRedraw_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static UINT ncredrawflags;
+ PAINTSTRUCT ps;
+ RECT rect;
+ BOOL updateRectValue;
+
+ switch(msg)
+ {
+ case WM_CREATE:
+ ncredrawflags = *(UINT *) (((CREATESTRUCT *)lParam)->lpCreateParams);
+ return 0;
+ case WM_NCPAINT:
+ updateRectValue = GetUpdateRect(hwnd, &rect, FALSE);
+ RedrawWindow(hwnd, NULL, NULL, ncredrawflags);
+ break;
+ case WM_PAINT:
+ BeginPaint(hwnd, &ps);
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+static void run_NCRedrawLoop(UINT flags)
+{
+ HWND hwnd;
+ MSG msg;
+
+ UINT loopcount = 0;
+
+ hwnd = CreateWindowA("TestNCRedrawClass", "MainWindow",
+ WS_OVERLAPPEDWINDOW, 0, 0, 200, 100,
+ NULL, NULL, 0, &flags);
+ ShowWindow(hwnd, SW_SHOW);
+ UpdateWindow(hwnd);
+ while(PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE) != 0)
+ {
+ if (msg.message == WM_PAINT) loopcount++;
+ if (loopcount >= 100) break;
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT);
+ }
+ if (flags == (RDW_INVALIDATE | RDW_FRAME))
+ todo_wine ok(loopcount < 100, "Detected infinite WM_PAINT loop (%x).\n", flags);
+ else
+ ok(loopcount < 100, "Detected infinite WM_PAINT loop (%x).\n", flags);
+ DestroyWindow(hwnd);
+}
+
+static void test_NCRedraw(void)
+{
+ WNDCLASSA wndclass;
+
+ wndclass.lpszClassName = "TestNCRedrawClass";
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = TestNCRedraw_WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = 0;
+ wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
+ wndclass.lpszMenuName = NULL;
+
+ RegisterClassA(&wndclass);
+
+ run_NCRedrawLoop(RDW_INVALIDATE | RDW_FRAME);
+ run_NCRedrawLoop(RDW_INVALIDATE);
+}
+
static void test_GetWindowModuleFileName(void)
{
HWND hwnd;
@@ -5647,6 +5719,7 @@ START_TEST(win)
test_SetMenu(hwndMain);
test_SetFocus(hwndMain);
test_SetActiveWindow(hwndMain);
+ test_NCRedraw();
test_children_zorder(hwndMain);
test_popup_zorder(hwndMain2, hwndMain);
--
1.6.0.4
More information about the wine-patches
mailing list