[PATCH 1/2] user32: Send WM_NCPAINT and WM_ERASEBKGND when window is shown and add tests
Fabian Maurer
dark.shadow4 at web.de
Wed Feb 1 13:52:45 CST 2017
Fixes Bug 2624 and 6682 and a few others
v2: Make patch independent from the WM_NCPAINT issue
Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
dlls/user32/tests/msg.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++
dlls/user32/winpos.c | 7 ++++
2 files changed, 111 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 45b5222deb..eeb8e95d58 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -927,6 +927,79 @@ static const struct message WmShowVisiblePopupSeq_3[] = {
{ WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE, 0, SWP_SHOWWINDOW },
{ 0 }
};
+/* CreateWindow (for a popup window with WS_VISIBLE style set)
+ */
+static const struct message WmShowPopupFirstDrawSeq_1[] = {
+ { HCBT_CREATEWND, hook },
+ { WM_NCCREATE, sent },
+ { WM_NCCALCSIZE, sent|wparam, 0 },
+ { WM_CREATE, sent },
+ { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_SIZE, sent|wparam, SIZE_RESTORED },
+ { WM_MOVE, sent },
+ { WM_SHOWWINDOW, sent|wparam, 1 },
+ { WM_WINDOWPOSCHANGING, sent },
+ { HCBT_ACTIVATE, hook },
+ { WM_WINDOWPOSCHANGING, sent|optional },
+ { WM_QUERYNEWPALETTE, sent|optional },
+ { WM_ACTIVATEAPP, sent },
+ { WM_NCACTIVATE, sent },
+ { WM_ACTIVATE, sent },
+ { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
+ { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+ { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { HCBT_SETFOCUS, hook },
+ { WM_SETFOCUS, sent|defwinproc },
+ { WM_NCPAINT, sent|wparam, 1 },
+ { WM_ERASEBKGND, sent },
+ { WM_WINDOWPOSCHANGED, sent },
+ { WM_PAINT, sent },
+ /* ocasionally received on test machines */
+ { WM_NCPAINT, sent|beginpaint|optional },
+ { WM_ERASEBKGND, sent|beginpaint|optional },
+ { 0 }
+};
+/* CreateWindow (for a popup window that is shown with ShowWindow(SW_SHOWMAXIMIZED))
+ */
+static const struct message WmShowPopupFirstDrawSeq_2[] = {
+ { HCBT_CREATEWND, hook },
+ { WM_NCCREATE, sent },
+ { WM_NCCALCSIZE, sent|wparam, 0 },
+ { WM_CREATE, sent },
+ { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_SIZE, sent|wparam, SIZE_RESTORED },
+ { WM_MOVE, sent },
+ { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE },
+ { WM_GETMINMAXINFO, sent },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_STATECHANGED|SWP_SHOWWINDOW|SWP_FRAMECHANGED },
+ { WM_NCCALCSIZE, sent|wparam, TRUE },
+ { HCBT_ACTIVATE, hook },
+ { WM_WINDOWPOSCHANGING, sent|optional },
+ { WM_NCPAINT, sent|optional|wparam, 1 },
+ { WM_ERASEBKGND, sent|optional },
+ { WM_WINDOWPOSCHANGED, sent|optional },
+ { WM_QUERYNEWPALETTE, sent|optional },
+ { WM_ACTIVATEAPP, sent },
+ { WM_NCACTIVATE, sent },
+ { WM_ACTIVATE, sent },
+ { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
+ { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+ { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { HCBT_SETFOCUS, hook },
+ { WM_SETFOCUS, sent|defwinproc },
+ { WM_NCPAINT, sent|wparam, 1 },
+ { WM_ERASEBKGND, sent },
+ { WM_WINDOWPOSCHANGED, sent },
+ { WM_MOVE, sent|defwinproc },
+ { WM_SIZE, sent|defwinproc, 0 },
+ { WM_PAINT, sent},
+ /* ocasionally received on test machines */
+ { WM_NCPAINT, sent|beginpaint|optional },
+ { WM_ERASEBKGND, sent|beginpaint|optional },
+ { 0 }
+};
/* CreateWindow (for child window, not initially visible) */
static const struct message WmCreateChildSeq[] = {
{ HCBT_CREATEWND, hook },
@@ -4826,6 +4899,37 @@ static void test_messages(void)
DestroyWindow(hwnd);
ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped", FALSE);
+ /* Test if window is correctly drawn when first shown - visible, redraw */
+ flush_sequence();
+ hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP | WS_VISIBLE,
+ 10, 10, 100, 100, NULL, 0, 0, NULL );
+ ok (hwnd != 0, "Failed to create popup window\n");
+ RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW);
+ ok_sequence(WmShowPopupFirstDrawSeq_1, "RedrawWindow:show_popup_first_draw_visible", FALSE);
+ DestroyWindow(hwnd);
+
+ /* Test if window is correctly drawn when first shown - invisible, show, message */
+ flush_sequence();
+ hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP,
+ 10, 10, 100, 100, NULL, 0, 0, NULL );
+ ok (hwnd != 0, "Failed to create popup window\n");
+ ShowWindow(hwnd, SW_SHOW);
+ SendMessageW(hwnd, WM_PAINT, 0, 0);
+ ok_sequence(WmShowPopupFirstDrawSeq_1, "RedrawWindow:show_popup_first_draw_show", FALSE);
+ DestroyWindow(hwnd);
+
+ /* Test if window is correctly drawn when first shown - invisible, show maximized, redraw */
+ flush_sequence();
+ hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP,
+ 10, 10, 100, 100, NULL, 0, 0, NULL );
+ ok (hwnd != 0, "Failed to create popup window\n");
+ ShowWindow(hwnd, SW_SHOWMAXIMIZED);
+ RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW);
+ ok_sequence(WmShowPopupFirstDrawSeq_2, "RedrawWindow:show_popup_first_draw_show_maximized", FALSE);
+ DestroyWindow(hwnd);
+
+ /* Test child windows */
+
hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 200, 200, 0, 0, 0, NULL);
ok (hparent != 0, "Failed to create parent window\n");
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 2fa194fa1c..da3bc73ecb 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -2254,6 +2254,13 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos )
SetForegroundWindow( winpos->hwnd );
}
+ /* Give newly shown windows a chance to redraw, skip unchanged windows to not send too many messages */
+ if((orig_flags & SWP_SHOWWINDOW)
+ && ((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE))
+ {
+ RedrawWindow( winpos->hwnd, NULL, 0, RDW_ERASENOW | RDW_ALLCHILDREN );
+ }
+
/* And last, send the WM_WINDOWPOSCHANGED message */
TRACE("\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
--
2.11.0
More information about the wine-patches
mailing list