Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/comctl32/listbox.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index d0e8e60..3d8804a 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -2516,6 +2516,8 @@ static BOOL LISTBOX_Create( HWND hwnd, LPHEADCOMBO lphc ) if (descr->style & LBS_EXTENDEDSEL) descr->style |= LBS_MULTIPLESEL; if (descr->style & LBS_MULTICOLUMN) descr->style &= ~LBS_OWNERDRAWVARIABLE; if (descr->style & LBS_OWNERDRAWVARIABLE) descr->style |= LBS_NOINTEGRALHEIGHT; + if ((descr->style & (LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_SORT)) != LBS_OWNERDRAWFIXED) + descr->style &= ~LBS_NODATA; descr->item_height = LISTBOX_SetFont( descr, 0 );
if (descr->style & LBS_OWNERDRAWFIXED)
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/comctl32/listbox.c | 6 +----- dlls/comctl32/tests/listbox.c | 3 --- 2 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index 3d8804a..4a2df52 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -1752,11 +1752,7 @@ static LRESULT LISTBOX_SetCount( LB_DESCR *descr, INT count ) { LRESULT ret;
- if (HAS_STRINGS(descr)) - { - SetLastError(ERROR_SETCOUNT_ON_BAD_LB); - return LB_ERR; - } + if (!(descr->style & LBS_NODATA)) return LB_ERR;
/* FIXME: this is far from optimal... */ if (count > descr->nb_items) diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index c560ce1..6ac3c73 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -1806,9 +1806,7 @@ static void test_set_count( void )
SetLastError( 0xdeadbeef ); ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 ); - todo_wine_if(i == 0) ok( ret == LB_ERR, "expected %d, got %d\n", LB_ERR, ret ); - todo_wine_if(i == 1) ok( GetLastError() == 0xdeadbeef, "Unexpected error %d.\n", GetLastError() );
DestroyWindow( listbox ); @@ -2341,7 +2339,6 @@ todo_wine style = GetWindowLongA(listbox, GWL_STYLE); ok((style & invalid_styles[i]) == invalid_styles[i], "%u: unexpected window styles %#x.\n", i, style); ret = SendMessageA(listbox, LB_SETCOUNT, 100, 0); - todo_wine_if(i == 1 || i == 4) ok(ret == LB_ERR, "%u: unexpected return value %d.\n", i, ret); DestroyWindow(listbox); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
The test has been updated to deal with the bug. This is clearly broken Windows behavior, because the same 32-bit app returns a different size depending on whether it's ran under WOW64 or natively 32-bit, and only with LB_GETTEXTLEN, which makes no sense at all. So IMO we can choose which one to return here, and size of a pointer simply makes more sense.
dlls/comctl32/listbox.c | 6 +++--- dlls/comctl32/tests/listbox.c | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index 4a2df52..76b09aa 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -762,8 +762,8 @@ static LRESULT LISTBOX_GetText( LB_DESCR *descr, INT index, LPWSTR buffer, BOOL } else { if (buffer) - *((DWORD *)buffer) = *(DWORD *)&descr->items[index].data; - len = sizeof(DWORD); + *((ULONG_PTR *)buffer) = descr->items[index].data; + len = sizeof(ULONG_PTR); } return len; } @@ -2653,7 +2653,7 @@ static LRESULT CALLBACK LISTBOX_WindowProc( HWND hwnd, UINT msg, WPARAM wParam, SetLastError(ERROR_INVALID_INDEX); return LB_ERR; } - if (!HAS_STRINGS(descr)) return sizeof(DWORD); + if (!HAS_STRINGS(descr)) return sizeof(ULONG_PTR); return strlenW( descr->items[wParam].str );
case LB_GETCURSEL: diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index 6ac3c73..c63cccd 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -2296,12 +2296,10 @@ static void test_LBS_NODATA(void) ret = SendMessageA(listbox, LB_SETITEMDATA, valid_idx[i], 42); ok(ret == TRUE, "Unexpected return value %d.\n", ret); ret = SendMessageA(listbox, LB_GETTEXTLEN, valid_idx[i], 0); - todo_wine_if(text_len == 8) - ok(ret == text_len, "Unexpected return value %d.\n", ret); + ok(ret == sizeof(data) || broken(ret == text_len), "Unexpected return value %d.\n", ret);
memset(&data, 0xee, sizeof(data)); ret = SendMessageA(listbox, LB_GETTEXT, valid_idx[i], (LPARAM)&data); - todo_wine_if(sizeof(void *) == 8) ok(ret == sizeof(data), "Unexpected return value %d.\n", ret); todo_wine ok(!memcmp(&data, &zero_data, sizeof(data)), "Unexpected item data.\n");
On 11/13/18 1:35 PM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
The test has been updated to deal with the bug. This is clearly broken Windows behavior, because the same 32-bit app returns a different size depending on whether it's ran under WOW64 or natively 32-bit, and only with LB_GETTEXTLEN, which makes no sense at all. So IMO we can choose which one to return here, and size of a pointer simply makes more sense.
I don't think broken() is justified in this case. It's consistent across Windows versions and it's clear how it's triggered.
To some level it doesn't have to make sense and we might consider making it "right", but for now I agree, let's keep a todo while returning consistent data length until we find something that depends on it.
On Tue, Nov 13, 2018 at 1:35 PM Nikolay Sivov nsivov@codeweavers.com wrote:
On 11/13/18 1:35 PM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
The test has been updated to deal with the bug. This is clearly broken Windows behavior, because the same 32-bit app returns a different size depending on whether it's ran under WOW64 or natively 32-bit, and only with LB_GETTEXTLEN, which makes no sense at all. So IMO we can choose which one to return here, and size of a pointer simply makes more sense.
I don't think broken() is justified in this case. It's consistent across Windows versions and it's clear how it's triggered.
To some level it doesn't have to make sense and we might consider making it "right", but for now I agree, let's keep a todo while returning consistent data length until we find something that depends on it.
There are many WOW64-only bugs (I mean, known by Microsoft), I think this classifies as one of them. Think about it for a minute: first, the behavior between the *same* 32-bit app is different on WOW64 and native 32-bit version of Windows. And we're talking about something like the length of a buffer here, not some cosmetic change.
Secondly, even with WOW64 it returns only the size of a pointer (4 bytes) in LB_GETTEXT, but LB_GETTEXTLEN says the length of the same "text" is 8? That makes no sense to me. It's inconsistent.
If you feel very strongly about it, I will change it to a todo, but I honestly think this is clearly broken.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/comctl32/listbox.c | 3 ++- dlls/comctl32/tests/listbox.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index 76b09aa..aa42c3a 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -762,7 +762,8 @@ static LRESULT LISTBOX_GetText( LB_DESCR *descr, INT index, LPWSTR buffer, BOOL } else { if (buffer) - *((ULONG_PTR *)buffer) = descr->items[index].data; + *((ULONG_PTR *)buffer) = (descr->style & LBS_NODATA) + ? 0 : descr->items[index].data; len = sizeof(ULONG_PTR); } return len; diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index c63cccd..265cffd 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -2301,7 +2301,6 @@ static void test_LBS_NODATA(void) memset(&data, 0xee, sizeof(data)); ret = SendMessageA(listbox, LB_GETTEXT, valid_idx[i], (LPARAM)&data); ok(ret == sizeof(data), "Unexpected return value %d.\n", ret); - todo_wine ok(!memcmp(&data, &zero_data, sizeof(data)), "Unexpected item data.\n");
ret = SendMessageA(listbox, LB_GETITEMDATA, valid_idx[i], 0);
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/comctl32/listbox.c | 2 +- dlls/comctl32/tests/listbox.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index aa42c3a..03afc5e 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -2630,7 +2630,7 @@ static LRESULT CALLBACK LISTBOX_WindowProc( HWND hwnd, UINT msg, WPARAM wParam, SetLastError(ERROR_INVALID_INDEX); return LB_ERR; } - return descr->items[wParam].data; + return (descr->style & LBS_NODATA) ? 0 : descr->items[wParam].data;
case LB_SETITEMDATA: if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items)) diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index 265cffd..2b7612e 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -2304,7 +2304,6 @@ static void test_LBS_NODATA(void) ok(!memcmp(&data, &zero_data, sizeof(data)), "Unexpected item data.\n");
ret = SendMessageA(listbox, LB_GETITEMDATA, valid_idx[i], 0); - todo_wine ok(ret == 0, "Unexpected return value %d.\n", ret); }
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/comctl32/listbox.c | 2 +- dlls/comctl32/tests/listbox.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index 03afc5e..479f6a6 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -2638,7 +2638,7 @@ static LRESULT CALLBACK LISTBOX_WindowProc( HWND hwnd, UINT msg, WPARAM wParam, SetLastError(ERROR_INVALID_INDEX); return LB_ERR; } - descr->items[wParam].data = lParam; + if (!(descr->style & LBS_NODATA)) descr->items[wParam].data = lParam; /* undocumented: returns TRUE, not LB_OKAY (0) */ return TRUE;
diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index 2b7612e..49ea0e5 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -2309,13 +2309,10 @@ static void test_LBS_NODATA(void)
/* More messages that don't work with LBS_NODATA. */ ret = SendMessageA(listbox, LB_FINDSTRING, 1, 42); -todo_wine ok(ret == LB_ERR, "Unexpected return value %d.\n", ret); ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 42); -todo_wine ok(ret == LB_ERR, "Unexpected return value %d.\n", ret); ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 42); -todo_wine ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
DestroyWindow(listbox);
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/comctl32/listbox.c | 2 ++ dlls/comctl32/tests/listbox.c | 6 ++++++ 2 files changed, 8 insertions(+)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index 479f6a6..dbc7b4a 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -880,6 +880,8 @@ static INT LISTBOX_FindString( LB_DESCR *descr, INT start, LPCWSTR str, BOOL exa INT i; LB_ITEMDATA *item;
+ if (descr->style & LBS_NODATA) return LB_ERR; + if (start >= descr->nb_items) start = -1; item = descr->items + start + 1; if (HAS_STRINGS(descr)) diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index 49ea0e5..b3966d0 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -2308,10 +2308,16 @@ static void test_LBS_NODATA(void) }
/* More messages that don't work with LBS_NODATA. */ + ret = SendMessageA(listbox, LB_FINDSTRING, 1, 0); + ok(ret == LB_ERR, "Unexpected return value %d.\n", ret); ret = SendMessageA(listbox, LB_FINDSTRING, 1, 42); ok(ret == LB_ERR, "Unexpected return value %d.\n", ret); + ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 0); + ok(ret == LB_ERR, "Unexpected return value %d.\n", ret); ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 42); ok(ret == LB_ERR, "Unexpected return value %d.\n", ret); + ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 0); + ok(ret == LB_ERR, "Unexpected return value %d.\n", ret); ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 42); ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);