The listview bug is caused by passing the incorrect index to the LISTVIEW_SortItems callers custom compare function. If we pass the copied array indices, which are different because of the sorting, the caller is going to use those indices for their unsorted array which don't match.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56140
-- v2: comctl32: Fix sorting for listview. comctl32/tests: Add test for listview sorting order.
From: Jacob Czekalla jczekalla@codeweavers.com
--- dlls/comctl32/tests/listview.c | 81 ++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+)
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 1081a045cde..7c718e5116d 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -23,6 +23,7 @@ #include <stdio.h> #include <windows.h> #include <commctrl.h> +#include <time.h> #include <objbase.h>
#include "wine/test.h" @@ -3028,6 +3029,84 @@ static void test_subitem_rect(void) DestroyWindow(hwnd); }
+static INT WINAPI test_CallBackCompareEx(LPARAM first, LPARAM second, LPARAM lParam) +{ + HWND hwnd_List_view = (HWND)lParam; + CHAR buffer1[256], buffer2[256]; + int itm1, itm2; + + ListView_GetItemTextA(hwnd_List_view, first, 0, buffer1, sizeof(buffer1)); + ListView_GetItemTextA(hwnd_List_view, second, 0, buffer2, sizeof(buffer2)); + + itm1 = atoi(buffer1); + itm2 = atoi(buffer2); + + return (itm1 - itm2); +} + +static void test_sort_order(void) +{ + LVITEMA lvi = {0}; + LV_COLUMNA lvc = {0}; + RECT rcClient; + CHAR buffer[256]; + CHAR col_names[][2] = { "1", "2" }; + HWND hwndListView = create_listview_control(LVS_REPORT); + int prev_value; + + GetClientRect(hwndparent, &rcClient); + + lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + lvc.pszText = col_names[0]; + lvc.cx = rcClient.right / 2; + lvc.iSubItem = 0; + ListView_InsertColumnA(hwndListView, 0, &lvc); + + lvc.pszText = col_names[1]; + lvc.iSubItem = 1; + lvc.cx = rcClient.right / 2; + ListView_InsertColumnA(hwndListView, 1, &lvc); + + srand((unsigned)time(NULL)); + + for (int i = 0; i < 100; i++) + { + lvi.mask = LVIF_TEXT; + lvi.iItem = i; + lvi.iSubItem = 0; + lvi.pszText = buffer; + sprintf(buffer, "%d", rand() % 100); + ListView_InsertItemA(hwndListView, &lvi); + + lvi.iSubItem = 1; + sprintf(buffer, "%d", rand() % 100); + ListView_SetItemTextA(hwndListView, i, 1, buffer); + } + + SendMessageA(hwndListView, LVM_SORTITEMSEX, (WPARAM) hwndListView, (LPARAM) test_CallBackCompareEx); + + memset(&lvi, 0, sizeof(lvi)); + for (int i = 1; i < 100; i++) + { + ListView_GetItemTextA(hwndListView, i-1, 0, buffer, sizeof(buffer)); + prev_value = atoi(buffer); + + ListView_GetItemTextA(hwndListView, i, 0, buffer, sizeof(buffer)); + + /* */ + if (atoi(buffer) < prev_value) + { + prev_value = 1; + break; + } + prev_value = 0; + } + + todo_wine ok(!prev_value, "ListView not sorted correctly.\n"); + + DestroyWindow(hwndListView); +} + /* comparison callback for test_sorting */ static INT WINAPI test_CallBackCompare(LPARAM first, LPARAM second, LPARAM lParam) { @@ -3211,6 +3290,8 @@ static void test_sorting(void) ok(lstrcmpA(buff, names[3]) == 0, "Expected '%s', got '%s'\n", names[3], buff);
DestroyWindow(hwnd); + + test_sort_order(); }
static void test_ownerdata(void)
From: Jacob Czekalla jczekalla@codeweavers.com
--- dlls/comctl32/listview.c | 2 +- dlls/comctl32/tests/listview.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index c82473b6205..0302e3e19a0 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -9396,7 +9396,7 @@ static BOOL LISTVIEW_SortItems(LISTVIEW_INFO *infoPtr, PFNLVCOMPARE pfnCompare, if (infoPtr->nFocusedItem >= 0) focusedItem = DPA_GetPtr(infoPtr->hdpaItems, infoPtr->nFocusedItem);
- context.items = hdpaItems; + context.items = infoPtr->hdpaItems; context.compare_func = pfnCompare; context.lParam = lParamSort; if (IsEx) diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 7c718e5116d..7cf87d54c69 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -3102,7 +3102,7 @@ static void test_sort_order(void) prev_value = 0; }
- todo_wine ok(!prev_value, "ListView not sorted correctly.\n"); + ok(!prev_value, "ListView not sorted correctly.\n");
DestroyWindow(hwndListView); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=147414
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:733: Test failed: peek: raw_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x46, lparam 0x10001 input.c:733: Test failed: peek: raw_legacy: 0: test->expect 2 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x66, lparam 0x10001 input.c:734: Test failed: peek: raw_legacy: 0: got F: 0 input.c:733: Test failed: peek: raw_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x46, lparam 0xffffffffc0020001 input.c:733: Test failed: peek: raw_vk_packet_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0xe7, lparam 0x10001 input.c:734: Test failed: peek: raw_vk_packet_legacy: 0: got 0xe7: 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0xe7, lparam 0xffffffffc0020001 input.c:733: Test failed: peek: raw_unicode_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x3c0, lparam 0x1 input.c:734: Test failed: peek: raw_unicode_legacy: 0: got 0xe7: 0 input.c:733: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x11, lparam 0xc00001 input.c:734: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: got VK_CONTROL: 0 input.c:734: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: got VK_LCONTROL: 0 input.c:733: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 1: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x11, lparam 0xffffffffc0c00001 input.c:733: Test failed: peek: raw_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_vk_packet_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_vk_packet_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x46, lparam 0x10001 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 2 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x66, lparam 0x10001 input.c:734: Test failed: receive: raw_legacy: 0: got F: 0 input.c:733: Test failed: receive: raw_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x46, lparam 0xffffffffc0020001 input.c:733: Test failed: receive: raw_vk_packet_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0xe7, lparam 0x10001 input.c:734: Test failed: receive: raw_vk_packet_legacy: 0: got 0xe7: 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0xe7, lparam 0xffffffffc0020001 input.c:733: Test failed: receive: raw_unicode_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x3c0, lparam 0x1 input.c:734: Test failed: receive: raw_unicode_legacy: 0: got 0xe7: 0 input.c:733: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x11, lparam 0xc00001 input.c:734: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: got VK_CONTROL: 0 input.c:734: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: got VK_LCONTROL: 0 input.c:733: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 1: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x11, lparam 0xffffffffc0c00001 input.c:733: Test failed: receive: raw_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_vk_packet_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_vk_packet_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0