Hi,
I have been looking at http://bugs.winehq.org/show_bug.cgi?id=14312 which shows up as the MDI client window not being repainted properly when a new child is created given an already maximised child window being present.
There is a related issue here that sometimes the child window frames are not being redrawn properly.
I am trying to understand where this problem is occurring, and am failing to see the big picture.
As I understand it, WM_MDIRESTORE is sent for the maximised child window, which calls ShowWindow(SW_RESTORE) on the child. This is then (from what I can tell) is handled by the windowing code (with the client behaving like a desktop window), which is taking care of the positioning and layout of the child windows.
For some reason, the parent window (the client) is not being updated properly (i.e. a WM_ERASEBKGND+WM_PAINT is not being sent). Likewise, the child windows don't appear to be handling and/or receiving a WM_NCPAINT message to redraw their frame.
In addition to this, looking at the message trail tests in user32/tests/msg.c, only some of these are testing a WM_ERASEBKGND+WM_PAINT message is being sent. How accurate are these with respect to WM_PAINT messages (that is, are WM_PAINT messages ignored in message trails unless explicitly tested for?).
And in terms of a fix, what is the best approach for fixing the issue? That is, Alexandre does not like an explicit call to InvalidateRect in the WM_MDICREATE handler, so I assume that the repaint logic should be done in a more specific place or figure out why it is not being called for the MDI client.
- Reece
Reece Dunn msclrhd@googlemail.com wrote:
And in terms of a fix, what is the best approach for fixing the issue? That is, Alexandre does not like an explicit call to InvalidateRect in the WM_MDICREATE handler, so I assume that the repaint logic should be done in a more specific place or figure out why it is not being called for the MDI client.
Probably WM_SETREDRAW has something to do with redrawing bug. Before fixing the problem we need to understand what exactly is the sequence of events that leads to it, how Windows and Wine behaviours differ.
On 6 February 2010 04:15, Dmitry Timoshkov dmitry@codeweavers.com wrote:
Reece Dunn msclrhd@googlemail.com wrote:
And in terms of a fix, what is the best approach for fixing the issue? That is, Alexandre does not like an explicit call to InvalidateRect in the WM_MDICREATE handler, so I assume that the repaint logic should be done in a more specific place or figure out why it is not being called for the MDI client.
Probably WM_SETREDRAW has something to do with redrawing bug.
WM_SETREDRAW is used in two places in mdi.c, both of which don't do an InvalidateRect/UpdateWindow call after the WM_SETREDRAW guard.
However, these don't have an effect. It might be a redraw bug deeper into the windowing logic that mdi.c is making use of.
Before fixing the problem we need to understand what exactly is the sequence of events that leads to it, how Windows and Wine behaviours differ.
I understand this.
- Reece
On 6 February 2010 10:29, Reece Dunn msclrhd@googlemail.com wrote:
On 6 February 2010 04:15, Dmitry Timoshkov dmitry@codeweavers.com wrote:
Reece Dunn msclrhd@googlemail.com wrote: Before fixing the problem we need to understand what exactly is the sequence of events that leads to it, how Windows and Wine behaviours differ.
I understand this.
Looking a bit deeper into the MDI tests, the MDI client window used in the tests has a size (0,0 - 0,0), whereas an MDI client in a real-world application has it covering the frame's client area.
That is...
----- 8< ----- diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 76fef3b..7c707e7 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -3359,6 +3359,7 @@ static void test_mdi_messages(void) CLIENTCREATESTRUCT client_cs; HWND mdi_frame, mdi_child, mdi_child2, active_child; BOOL zoomed; + RECT rc; HMENU hMenu = CreateMenu();
assert(mdi_RegisterWindowClasses()); @@ -3389,6 +3390,11 @@ static void test_mdi_messages(void) assert(mdi_client); ok_sequence(WmCreateMDIclientSeq, "Create visible MDI client window", FALSE);
+ GetClientRect(mdi_frame, &rc); + MoveWindow(mdi_client, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); + /*MessageBoxA(NULL, "test", "test", MB_OK);*/ + flush_sequence(); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); ok(GetFocus() == mdi_frame, "input focus should be on MDI frame not on %p\n", GetFocus()); ----- >8 ------
which then fails some of the tests in Wine...
$ make msg.ok msg.c:3510: Test failed: ShowWindow(SW_MAXIMIZE):invisible MDI child: 19: in msg 0x0047 expecting wParam 0x9863 got 0x9062 msg.c:3532: Test failed: ShowWindow(SW_RESTORE):invisible MDI child: 5: in msg 0x0047 expecting wParam 0x9863 got 0x9062 msg.c:3556: Test failed: ShowWindow(SW_MAXIMIZE):MDI child: 5: in msg 0x0047 expecting wParam 0x9823 got 0x9022 msg.c:3562: Test failed: ShowWindow(SW_RESTORE):maximized MDI child: 4: in msg 0x0047 expecting wParam 0x9823 got 0x9022 msg.c:3719: Test failed: Create maximized invisible MDI child window: 17: in msg 0x0047 expecting wParam 0x8839 got 0x8038
... I am going to run this on the winetestbot to see how Windows behaves.
- Reece