A window update problem in Dutch tax program.

Rein Klazes rklazes at xs4all.nl
Mon Sep 13 10:44:06 CDT 2004


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.
-- 
Rein Klazes
rklazes at xs4all.nl



More information about the wine-devel mailing list