COMCTL32 - TreeView control not correctly updated with COMCTL32.OCX (was: Re: comctl32.dll: Running siap and modules under wine, first steps)

Alex Villací­s Lasso a_villacis at palosanto.com
Mon Oct 3 13:42:56 CDT 2005


This SIAP application is revealing more problems with Wine. This time it 
is the
reason for the original complaint: Mr. Maximiliano Curia reported that 
in the
version of Wine he could test, the treeview control in the middle of the 
screen
was not updated correctly. The treeview control should have looked like 
this:

+---------------------------------+
|Persona Física                   |
| |                               |
| +- Datos identificatorios       |
| |     |                         |
| |     +- Nombre y otros datos   |
| |     +- Domicilio              |
| |     +- Actividades            |
| +- Datos comerciales            |
| |     |                         |
| |     +- Datos de interés fiscal|
| |     +- Claves bancarias       |
| +- Responsable por deuda ajena  |
+---------------------------------+

Don't mind the actual meaning of the text in the nodes. The problem is 
that for
Mr. Curia, the treeview control actually shows up like this:

+---------------------------------+
|Persona Física                   |
|                                 |
|                                 |
|                                 |
|                                 |
|                                 |
|                                 |
|                                 |
|                                 |
|                                 |
|                                 |
|                                 |
+---------------------------------+

That is, the treeview control only shows the first line of the tree. 
After some
digging in the treeview control, I saw that the code in the control 
tries to
save some drawing by querying the update region of the control window. 
When the
WM_PAINT message indicates a non-null HDC in wParam, the code fetches 
the update
region for the control window. If I understand the intent of the code 
correctly,
the WM_PAINT message can be sent to the control with an wParam of the 
HDC of an
offscreen bitmap, in order to draw the tree into it. When the update 
region of
the control is NULL, the code fetches the BITMAP structure of the target HDC
in order to clip the drawing to the dimensions of the target bitmap.

The problem is that, in the case of the treeview managed by 
COMCTL32.OCX, for
some as yet undiscovered reason, the control *always* has a null update 
region,
except for the very first rendering (which is overwritten by a second 
rendering
with the problematic null region). No matter how the window is 
uncovered, the
update region remains null. Therefore, the control believes that the 
target is
an offscreen bitmap, even for the rendering to the screen. It then 
fetches the
default bitmap selected, which is an 1x1 dummy bitmap, gets a 1x1 target 
region,
and believes that only 1 pixel should be updated. Only the very first 
item gets
redrawn because of this.

The following patch works around this issue. However, this is not a 
proper fix,
because the control window should have been properly invalidated in the 
first
place, and the control should therefore have a proper update region. I 
am not
really sure whether the root cause is in the treeview code or in the region
updating code. I am inclined to the former, because the same treeview 
control
seems to work correctly in regedit.exe:

--- wine-20050930-cvs/dlls/comctl32/treeview.c  2005-09-12 
17:34:07.000000000 -0500
+++ wine-20050930-cvs-patch/dlls/comctl32/treeview.c    2005-10-02 
22:08:08.000000000 -0500
@@ -2790,6 +2790,8 @@
     RECT rect = *rc;
     TREEVIEW_ITEM *wineItem;

+    TRACE("refreshing on (%ld,%ld)-(%ld,%ld)\n", rect.left, rect.top, 
rect.right, rect.bottom);
+
     if (infoPtr->clientHeight == 0 || infoPtr->clientWidth == 0)
     {
        TRACE("empty window\n");
@@ -2859,6 +2861,12 @@
             rc.left = 0; rc.top = 0;
             rc.right = bitmap.bmWidth;
             rc.bottom = bitmap.bmHeight;
+            if (bitmap.bmWidth == 1 &&
+                bitmap.bmHeight == 1 &&
+                bitmap.bmWidthBytes == 2) {
+                ERR("failed to recover a valid update region, using 
GetClientRect()\n");
+                GetClientRect(infoPtr->hwnd, &rc);
+            }
             TREEVIEW_EraseBackground(infoPtr, (HDC)wParam);
         }
     }

The sample (VisualBasic) code and executable have been uploaded as 
testcases for
the following bug report: http://bugs.winehq.org/show_bug.cgi?id=3476

BTW: what happened to the patch that fixes the DBGRID32.OCX control? 
(Subject: OLEAUT32: add additional condition for creation of interface)

On an (hopefully) unrelated note, the user32 tests are failing, at least 
on my
machine:

../../../tools/runtest -q -P wine -M user32.dll -T ../../.. -p 
user32_test.exe.so sysparams.c && touch sysparams.ok
sysparams.c:1182: Test failed: lfHeight: got -16 instead of 0
sysparams.c:1183: Test failed: lfWidth: got 0 instead of 400
sysparams.c:1185: Test failed: lfWeight: got 400 instead of 7471169
sysparams.c:1186: Test failed: lfItalic: got 0 instead of 105
sysparams.c:1187: Test failed: lfStrikeOut: got 0 instead of 97
sysparams.c:1190: Test failed: lfOutPrecision: got 0 instead of 108
sysparams.c:1193: Test failed: lfQuality: got 0 instead of 32
make: *** [sysparams.ok] Error 7
../../../tools/runtest -q -P wine -M user32.dll -T ../../.. -p 
user32_test.exe.so win.c && touch win.ok
fixme:win:WIN_CreateWindowEx Parent is HWND_MESSAGE
win.c:2213: Test failed: message 0200 available
win.c:2221: Test failed: message 000f available
win.c:2229: Test failed: message 000f available
win.c:2240: Test failed: message 000f available
win.c:2248: Test failed: message 000f available
win.c:2256: Test failed: message 000f available
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x94000000:0x00000000, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x94000000:0x00000000, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x15c00000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x15c00000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c00000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c00000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c00000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c00000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c80000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c80000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c40000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c40000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c20000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c20000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c10000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c10000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14d00000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14d00000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14e00000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14e00000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x94000000:0x00000200, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x94000000:0x00000200, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c40000:0x00000300, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c40000:0x00000300, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x94000000:0x00000080, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x94000000:0x00000080, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c40000:0x00000180, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c40000:0x00000180, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x94000000:0x00000000, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x94000000:0x00000000, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c40000:0x00000100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c40000:0x00000100, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x94000000:0x00040000, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x94000000:0x00040000, menu=1
win.c:693: Test failed: window rect does not match: 
style:exstyle=0x14c40000:0x00040100, menu=1
win.c:718: Test failed: synthetic rect does not match: 
style:exstyle=0x14c40000:0x00040100, menu=1
make: *** [win.ok] Error 42
make: Debido a los errores, el objetivo `test' no se reconstruyó.




More information about the wine-devel mailing list