[PATCH] comctl32/treeview: Make textWidth in struct _TREEITEM compatible with native one.
Nikolay Sivov
nsivov at codeweavers.com
Sat Jan 20 10:45:55 CST 2018
On 01/20/2018 08:40 AM, Zhiyi Zhang wrote:
> Hi Nikolay,
>
> This fixes https://bugs.winehq.org/show_bug.cgi?id=35127
>
> As I was working through bug 35127, I noticed that you had once
> changed the layout of struct _TREEITEM in commit
> 6ec621e835e03f715d5fee27c5de5b0d361814de.
>
> Now I am sure that textWidth in struct _TREEITEM is a WORD and is at the
> offset 0x1a. You can check out the bug comments for details. I tried
> to find out what is at 0x18 but no luck, thus I am adding a unknown
> member to make textWidth at the right offset.
>
> What do you think of the patch? Do you know what member is at struct
> _TREEITEM+0x18? I can use your opinion with this patch.
>
>
>
> struct·_ITEM_DATA
> {
> -· HTREEITEM parent; /* for root value of parent field is unidetified */
> +· HTREEITEM parent; /* for root value of parent field is unidentified */
> · HTREEITEM nextsibling;
> · HTREEITEM firstchild;
> +· UINT unknownField0; /* untested */
> +· UINT unknownField1; /* untested */
> +· UINT unknownField2; /* untested */
> +· WORD padding0; /* unknown field to make textWidth offset compatible
> with the native one */
> +· WORD textWidth; /* horizontal text extent for pszText */
> };
They are all unknown, so a single unknown[7] is better, assuming this
will work on 64 bits.
> +· /* padding0 should be unused on Wine */
> +· if(!strcmp(winetest_platform, "wine"))
> +· {
> +· ok_(__FILE__, line)(data->padding0 == 0, "padding0 %04x, got
> %04x\n", 0, data->padding0);
> +· ok_(__FILE__, line)(data->textWidth == textWidth, "textWidth %04x,
> got %04x\n", textWidth, data->textWidth);
> +· }
> +· /* TODO: textWidth computation on Windows is alway that of Wine
> plus 4, remove this test when it got corrected.
> +· Also, in Windows textWidth is calculated even if tree item is
> invisible whereas in Wine is postponed */
> +· else
> +· {
> +· ok_(__FILE__, line)(textWidth == 0 || data->textWidth == 0 ||
> data->textWidth == textWidth + 4,
> +· "textWidth %04x, got %04x\n", textWidth, data->textWidth);
> +· }
This is very dirty. You should get rid of platform check; testing
padding0 does not look useful; and last test line looks suspicious, if
expected width is 0 nothing gets tested.
> +· /* Set font to make textWidth calculation consistent */
> +· hdc=GetDC(hMainWnd);
> +· SystemParametersInfoA(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0);
> +· SelectObject(hdc, CreateFontIndirectA(&lf));
This doesn't make it consistent, because you select one font, and
control could be using another one, also you're using parent window for
some reason. WM_GETFONT returns what you need.
Instead of calculating this width manually, it's better to use
TVM_GETITEMRECT (with wparam == 1), if that gives expected width. If
text portion rectangle width returned by this message matches internal
field value on Windows, then we should use that. This will also hide +4
difference you see, unless it was caused by a wrong font.
> typedef·struct _TREEITEM /* HTREEITEM is a _TREEINFO *. */
> · UINT callbackMask;
> · UINT state;
> · UINT stateMask;
> +· WORD padding0; /* unknown field to make textWidth offset compatible
> with the native one */
> +· WORD textWidth; /* horizontal text extent for pszText */
Instead this should match structure used in tests, i.e. it should start
with same fields and not have incompatible data mixed with what we try
to match.
More information about the wine-devel
mailing list