Hi,
I am looking in a display problem in the electronic declaration programs of the Dutch tax office.
Here is a schematic of the windows involved:
+--10022-------------------------------+ | | | +--100c6-------------------------+ | | | | | ..20110... | | | . . | | | . . | | | +-20114--+ | | | | | | | | | | | | | +--------+ | | | | | | | | +--------------------------------+ +--------------------------------------+
[10022] is a top level window. One of its child [20114] has itself a child window [20110] that initially lies outside the parent client area. A series of calls to ScrollWindowEx() brings it inside, simulating a drop down listbox.
Now [20114] should normally not be visible because it lies behind another child of the main window:
[10022] | +--[20114] | | | +--[20110] | | +-[100c6] | + ...
No window styles that could affect this behavior (WS_CLIPCHILDREN, WS_CLIPSIBLINGS, WS_EX_TRANSPARENT) are used.
Here the partial output of info wnd command:
00010022 WindowIB2003 14cb0000 00000000 Aangifte 2003 00020114 WindowIB2003 50000000 00000000 -- Empty -- 00020110 @LISTBOX 50800141 00000000 -- Empty -- 000100c6 WindowIB2003 50000000 00000000 TheContent
The program first validates the update region of the main window with the rect of [20114].
|0009:Call user32.ValidateRect(00010022,4070f988) ret=00426f64 ... |trace:win:RedrawWindow Update region of hwnd 0x10022 is nil |0009:Ret user32.ValidateRect() retval=00000001 ret=00426f64
As the extra trace message reports, this window has a null update region at this point.
Then the first scroll is requested:
|0009:Call user32.ScrollWindowEx(00020114,00000000,0000000a,4070f6e4,4070f6b4,00000000,00000000,00000001) ret=00426fd1 |trace:scroll:ScrollWindowEx 0x20114, 0,10 hrgnUpdate=(nil) rcUpdate = (nil) (0,-47)-(71,0) 0001 |trace:scroll:ScrollWindowEx clipRect = (0,0)-(71,10) ... |0009:Ret user32.ScrollWindowEx() retval=00000001 ret=00426fd1
directly after this the same scroll rectangle (4070f6e4) is invalidated:
|0009:Call user32.InvalidateRect(00020114,4070f6e4,00000001) ret=00426fe6 |trace:win:RedrawWindow 0x20114 (0x137e) rect 0,0-71,10 (nil) flags=0005 |trace:win:dump_rdw_flags flags: RDW_INVALIDATE RDW_ERASE ... |0009:Ret user32.InvalidateRect() retval=00000001 ret=00426fe6
and directly UpdateWindow is called:
|0009:Call user32.UpdateWindow(00020114) ret=00426fef
|0009:Call x11drv.MsgWaitForMultipleObjectsEx(00000001,4070f460,00000000,000000ff,00000000) ret=40764927 |trace:event:EVENT_ProcessEvent called.
UpdateWindow calls RedrawWindows that first looks for outstanding events, that is where the trouble starts:
|trace:event:EVENT_ProcessEvent Got event Expose for hwnd/window 0x20114/3a001aa, GetFocus()=0x20112 |trace:x11drv:X11DRV_Expose win 0x20114 (3a001aa) 0,0 71x47 ... |0009:Call user32.RedrawWindow(00010022,4070f010,00000000,00000085) ret=40d519a2 |trace:win:RedrawWindow 0x10022 ((nil)) rect 291,142-362,189 (nil) flags=0085 |trace:win:dump_rdw_flags flags: RDW_INVALIDATE RDW_ERASE RDW_ALLCHILDREN
and the main window and child [100c6] find them selves invalidated:
|trace:win:RDW_Paint hwnd 0x10022 [0x1382] -> hrgn [0x139e], flags [0085] ... |trace:win:RDW_Paint hwnd 0x100c6 [0x138a] -> hrgn [0x139e], flags [0085]
after the final scroll, a WM_PAINT message is dispatched to [100c6] and the scrolled window [20114] is invisible.
I am not sure what the real problem is: either the expose event should not be there or the handling of the event is wrong. For the latter case: the handling in expose_window() sure does not expect to make visible a normally obscured window.
Any suggestions? The program is available on-line, but I would need to give some instruction for non-Dutch users.
Rein.