diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 1c002d9de35..d3e4ee86509 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -387,6 +387,89 @@ static HWND subclass_header(HWND hwndListview) return hwnd; } +/* Performs a single LVM_HITTEST test */ +static void test_lvm_hittest(HWND hwnd, INT x, INT y, INT item, UINT flags, + BOOL todo_item, BOOL todo_flags, int line) +{ + LVHITTESTINFO lpht; + DWORD ret; + + lpht.pt.x = x; + lpht.pt.y = y; + lpht.iSubItem = 10; + + trace("hittesting pt=(%d,%d)\n", lpht.pt.x, lpht.pt.y); + ret = SendMessage(hwnd, LVM_HITTEST, 0, (LPARAM)&lpht); + + if (todo_item) + { + todo_wine + { + ok_(__FILE__, line)(ret == item, "Expected %d item, got %d\n", item, ret); + ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); + ok_(__FILE__, line)(lpht.iSubItem == 10, "Expected subitem not overwrited\n"); + } + } + else + { + ok_(__FILE__, line)(ret == item, "Expected %d item, got %d\n", item, ret); + ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); + ok_(__FILE__, line)(lpht.iSubItem == 10, "Expected subitem not overwrited\n"); + } + + if (todo_flags) + { + todo_wine + ok_(__FILE__, line)(lpht.flags == flags, "Expected flags %x, got %x\n", flags, lpht.flags); + } + else + ok_(__FILE__, line)(lpht.flags == flags, "Expected flags %x, got %x\n", flags, lpht.flags); +} + +/* Performs a single LVM_SUBITEMHITTEST test */ +static void test_lvm_subitemhittest(HWND hwnd, INT x, INT y, INT item, INT subitem, UINT flags, + BOOL todo_item, BOOL todo_subitem, BOOL todo_flags, int line) +{ + LVHITTESTINFO lpht; + DWORD ret; + + lpht.pt.x = x; + lpht.pt.y = y; + + trace("subhittesting pt=(%d,%d)\n", lpht.pt.x, lpht.pt.y); + ret = SendMessage(hwnd, LVM_SUBITEMHITTEST, 0, (LPARAM)&lpht); + + if (todo_item) + { + todo_wine + { + ok_(__FILE__, line)(ret == item, "Expected %d item, got %d\n", item, ret); + ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); + } + } + else + { + ok_(__FILE__, line)(ret == item, "Expected %d item, got %d\n", item, ret); + ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); + } + + if (todo_subitem) + { + todo_wine + ok_(__FILE__, line)(lpht.iSubItem == subitem, "Expected subitem %d, got %d\n", subitem, lpht.iSubItem); + } + else + ok_(__FILE__, line)(lpht.iSubItem == subitem, "Expected subitem %d, got %d\n", subitem, lpht.iSubItem); + + if (todo_flags) + { + todo_wine + ok_(__FILE__, line)(lpht.flags == flags, "Expected flags %x, got %x\n", flags, lpht.flags); + } + else + ok_(__FILE__, line)(lpht.flags == flags, "Expected flags %x, got %x\n", flags, lpht.flags); +} + static void test_images(void) { HWND hwnd; @@ -2241,6 +2324,108 @@ static void test_setredraw(void) DestroyWindow(hwnd); } +static void test_hittest(void) +{ + HWND hwnd; + DWORD r; + RECT bounds; + LVITEMA item; + static CHAR text[] = "1234567890ABCDEFGHIJKLMNOPQRST"; + POINT pos; + INT x, y; + HIMAGELIST himl, himl2; + HBITMAP hbmp; + + hwnd = create_listview_control(0); + ok(hwnd != NULL, "failed to create a listview window\n"); + + /* LVS_REPORT with a single subitem (2 columns) */ + insert_column(hwnd, 0); + insert_column(hwnd, 1); + insert_item(hwnd, 0); + + item.iSubItem = 0; + /* the only purpose of that line is to be as long as a half item rect */ + item.pszText = text; + r = SendMessage(hwnd, LVM_SETITEMTEXT, 0, (LPARAM)&item); + expect(TRUE, r); + + r = SendMessage(hwnd, LVM_SETCOLUMNWIDTH, 0, MAKELPARAM(100, 0)); + expect(TRUE, r); + r = SendMessage(hwnd, LVM_SETCOLUMNWIDTH, 1, MAKELPARAM(100, 0)); + expect(TRUE, r); + + memset(&bounds, 0, sizeof(bounds)); + bounds.left = LVIR_BOUNDS; + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&bounds); + ok(bounds.bottom - bounds.top > 0, "Expected non zero item height\n"); + ok(bounds.right - bounds.left > 0, "Expected non zero item width\n"); + r = SendMessage(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pos); + expect(TRUE, r); + + /* LVS_EX_FULLROWSELECT not set, no icons attached */ + x = pos.x + 50; /* column half width */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMLABEL, FALSE, FALSE, __LINE__); + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE, __LINE__); + x = pos.x + 150; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, FALSE, FALSE, __LINE__); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, TRUE, TRUE, TRUE, __LINE__); + /* parent client area is 100x100 by default */ + MoveWindow(hwnd, 0, 0, 300, 100, FALSE); + x = pos.x + 150; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_NOWHERE, FALSE, FALSE, __LINE__); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE, __LINE__); + /* the same with LVS_EX_FULLROWSELECT */ + SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); + x = pos.x + 150; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEM, FALSE, FALSE, __LINE__); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, FALSE, FALSE, FALSE, __LINE__); + MoveWindow(hwnd, 0, 0, 100, 100, FALSE); + x = pos.x + 150; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, -1, LVHT_TORIGHT, FALSE, FALSE, __LINE__); + test_lvm_subitemhittest(hwnd, x, y, 0, 1, LVHT_ONITEMLABEL, TRUE, TRUE, TRUE, __LINE__); + /* try with icons */ + himl = ImageList_Create(16, 16, 0, 4, 4); + ok(himl != NULL, "failed to create imagelist\n"); + hbmp = CreateBitmap(16, 16, 1, 1, NULL); + ok(hbmp != NULL, "failed to create bitmap\n"); + r = ImageList_Add(himl, hbmp, 0); + ok(r == 0, "should be zero\n"); + + r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl); + ok(r == 0, "should return zero\n"); + + item.mask = LVIF_IMAGE; + item.iImage = 0; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM)&item); + expect(TRUE, r); + /* on state icon */ + x = pos.x + 8; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMSTATEICON, FALSE, TRUE, __LINE__); + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMSTATEICON, FALSE, FALSE, TRUE, __LINE__); + + himl2 = (HIMAGELIST)SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)NULL); + ok(himl2 == himl, "should return handle\n"); + + r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl); + ok(r == 0, "should return zero\n"); + /* on item icon */ + x = pos.x + 8; /* outside column */ + y = pos.y + (bounds.bottom - bounds.top) / 2; + test_lvm_hittest(hwnd, x, y, 0, LVHT_ONITEMICON, FALSE, FALSE, __LINE__); + test_lvm_subitemhittest(hwnd, x, y, 0, 0, LVHT_ONITEMICON, FALSE, FALSE, FALSE, __LINE__); + + DestroyWindow(hwnd); +} + START_TEST(listview) { HMODULE hComctl32; @@ -2284,6 +2469,7 @@ START_TEST(listview) test_norecompute(); test_nosortheader(); test_setredraw(); + test_hittest(); DestroyWindow(hwndparent); }