Tests how the rects for the listviews header should be refreshed during painting.
-- v2: comctl32/listview: Remove header rect caching when drawing LVS_REPORT listviews. comctl32/tests: Add test for HDM_SETORDERARRAY in listview test_columns. comctl32/tests: Add test for header item rect caching in LVS_REPORT listview during paint.
From: Jacob Czekalla jczekalla@codeweavers.com
Tests how the rects for the listviews header should be refreshed during painting. --- dlls/comctl32/tests/listview.c | 67 ++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index b767106e97a..2fb672cf7e8 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -608,6 +608,24 @@ static const struct message listview_end_label_edit_kill_focus[] = { { 0 } };
+static const struct message listview_invalidate_rect[] = { + { WM_PAINT, sent }, + { WM_PAINT, sent }, + { WM_NCPAINT, sent|defwinproc }, + { WM_ERASEBKGND, sent|defwinproc }, + { WM_NOTIFY, sent|defwinproc }, + { HDM_ORDERTOINDEX, sent|wparam, 0 }, + { HDM_GETITEMW, sent|wparam|optional, 0 }, /* todo: not sent by wine yet */ + { HDM_GETITEMRECT, sent|wparam, 0 }, + { HDM_ORDERTOINDEX, sent|wparam, 1 }, + { HDM_GETITEMW, sent|wparam|optional, 1 }, /* todo: not sent by wine yet */ + { HDM_GETITEMRECT, sent|wparam, 1 }, + { HDM_ORDERTOINDEX, sent|wparam, 2 }, + { HDM_GETITEMW, sent|wparam|optional, 2 }, /* todo: not sent by wine yet */ + { HDM_GETITEMRECT, sent|wparam, 2 }, + { 0 } +}; + static void hold_key(int vk) { BYTE kstate[256]; @@ -7489,6 +7507,53 @@ static void test_LVM_GETHOTCURSOR(void) DestroyWindow(hwnd); }
+static void test_column_rect_caching(void) +{ + HWND listview; + LVCOLUMNA column = { 0 }; + LVITEMA item = { 0 }; + char a_text[] = "A", b_text[] = "B", c_text[] = "C"; + + listview = create_listview_control(LVS_REPORT); + subclass_header(listview); + + column.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + column.cx = 50; + column.pszText = a_text; + column.iSubItem = 0; + SendMessageA(listview, LVM_INSERTCOLUMNA, 0, (LPARAM)&column); + column.cx = 50; + column.pszText = b_text; + column.iSubItem = 1; + SendMessageA(listview, LVM_INSERTCOLUMNA, 1, (LPARAM)&column); + column.cx = 50; + column.pszText = c_text; + column.iSubItem = 2; + SendMessageA(listview, LVM_INSERTCOLUMNA, 2, (LPARAM)&column); + + item.mask = LVIF_TEXT; + item.iItem = 0; + item.pszText = a_text; + SendMessageA(listview, LVM_INSERTITEMA, 0, (LPARAM)&item); + item.iSubItem = 1; + item.iItem = 0; + item.pszText = b_text; + SendMessageA(listview, LVM_SETITEMTEXTA, 0, (LPARAM)&item); + item.iSubItem = 2; + item.iItem = 0; + item.pszText = c_text; + SendMessageA(listview, LVM_SETITEMTEXTA, 0, (LPARAM)&item); + + flush_events(); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + InvalidateRect(listview, NULL, FALSE); + flush_events(); + ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_invalidate_rect, "column order caching in refresh", TRUE); + + DestroyWindow(listview); +} + START_TEST(listview) { ULONG_PTR ctx_cookie; @@ -7559,6 +7624,7 @@ START_TEST(listview) test_custom_sort(); test_LVM_GETNEXTITEM(); test_LVM_GETHOTCURSOR(); + test_column_rect_caching();
if (!load_v6_module(&ctx_cookie, &hCtx)) { @@ -7611,6 +7677,7 @@ START_TEST(listview) test_LVM_SETBKIMAGE(TRUE); test_LVM_GETHOTCURSOR(); test_LVM_GETORIGIN(TRUE); + test_column_rect_caching();
uninit_winevent_hook();
From: Jacob Czekalla jczekalla@codeweavers.com
Setting the order with HDM_SETORDERARRAY should also set the order of the listview. --- dlls/comctl32/tests/listview.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 2fb672cf7e8..8d21b8662a1 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -1672,7 +1672,7 @@ static void test_columns(void) HWND hwnd, header; LVCOLUMNA column; LVITEMA item; - INT order[2]; + INT order[2], ret_order[2]; CHAR buff[5]; DWORD rc;
@@ -1717,6 +1717,8 @@ static void test_columns(void) hwnd = create_listview_control(LVS_REPORT); subclass_header(hwnd);
+ header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0); + memset(&column, 0, sizeof(column)); column.mask = LVCF_WIDTH; column.cx = 100; @@ -1752,6 +1754,15 @@ static void test_columns(void)
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_setorderarray_seq, "set order array", FALSE);
+ /* HDM_SETORDERARRAY */ + order[0] = 1; + order[1] = 0; + SendMessageA(header, HDM_SETORDERARRAY, 2, (LPARAM)order); + SendMessageA(hwnd, LVM_GETCOLUMNORDERARRAY, 2, (LPARAM)&ret_order); + + ok(order[0] == ret_order[0], "expected %d, got %d.\n", order[0], ret_order[0]); + ok(order[1] == ret_order[1], "expected %d, got %d.\n", order[1], ret_order[1]); + /* after column added subitem is considered as present */ insert_item(hwnd, 0);
From: Jacob Czekalla jczekalla@codeweavers.com
During painting for an LVS_REPORT listview the cached header rects should be refreshed. Listview columns can be reorderd through the header which was not accounted for.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57594 --- dlls/comctl32/listview.c | 6 ++++-- dlls/comctl32/tests/listview.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 31f8a933e56..86c60a2b2ae 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -5015,10 +5015,12 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc, /* narrow down the columns we need to paint */ for(col = 0; col < DPA_GetPtrCount(infoPtr->hdpaColumns); col++) { + COLUMN_INFO* col_info; INT index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, col, 0);
- LISTVIEW_GetHeaderRect(infoPtr, index, &rcItem); - if ((rcItem.right + Origin.x >= rcClip.left) && (rcItem.left + Origin.x < rcClip.right)) + col_info = DPA_GetPtr(infoPtr->hdpaColumns, index); + SendMessageW(infoPtr->hwndHeader, HDM_GETITEMRECT, index, (LPARAM)&col_info->rcHeader); + if ((col_info->rcHeader.right + Origin.x >= rcClip.left) && (col_info->rcHeader.left + Origin.x < rcClip.right)) ranges_additem(colRanges, index); } iterator_rangesitems(&j, colRanges); diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 8d21b8662a1..5c3eab7dbdb 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -7560,7 +7560,7 @@ static void test_column_rect_caching(void)
InvalidateRect(listview, NULL, FALSE); flush_events(); - ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_invalidate_rect, "column order caching in refresh", TRUE); + ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_invalidate_rect, "column order caching in refresh", FALSE);
DestroyWindow(listview); }