From: Angelo Haller angelo@szanni.org
Signed-off-by: Angelo Haller angelo@szanni.org --- dlls/comctl32/tests/listview.c | 180 +++++++++++++++++++++++++-------- 1 file changed, 140 insertions(+), 40 deletions(-)
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index fec1a83de4d..fd60e18a97f 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -256,11 +256,77 @@ static const struct message ownerdata_deselect_all_parent_seq[] = { { 0 } };
-static const struct message ownerdata_multiselect_odstatechanged_seq[] = { - { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, +static const struct message ownerdata_multiselect_select_0_to_1_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, -1, 0, LVN_ITEMCHANGED }, { WM_NOTIFY, sent|id, 0, 0, LVN_ODSTATECHANGED }, - { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, - { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 0, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 1, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_select_0_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, -1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 0, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_select_0_modkey_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, -1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 0, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 0, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_move_0_to_1_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, 0, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 1, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_select_0_to_2_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, -1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ODSTATECHANGED }, + { WM_NOTIFY, sent|id|wparam, 1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 2, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_select_3_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, -1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 2, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 3, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_select_3_modkey_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, -1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 3, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 2, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 3, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_select_3_to_2_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, -1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ODSTATECHANGED }, + { WM_NOTIFY, sent|id|wparam, 3, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 2, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_move_3_to_2_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, 3, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 2, 0, LVN_ITEMCHANGED }, + { 0 } +}; + +static const struct message ownerdata_multiselect_select_3_to_1_odstatechanged_seq[] = { + { WM_NOTIFY, sent|id|wparam, -1, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id, 0, 0, LVN_ODSTATECHANGED }, + { WM_NOTIFY, sent|id|wparam, 2, 0, LVN_ITEMCHANGED }, + { WM_NOTIFY, sent|id|wparam, 1, 0, LVN_ITEMCHANGED }, { 0 } };
@@ -3544,11 +3610,55 @@ static void test_ownerdata(void) DestroyWindow(hwnd); }
+struct kbd_select_sequence { + BOOL hold_shift; + BOOL hold_control; + UINT press_key; + UINT selected_count; + const char *context; + const struct message *expected; + BOOL todo; +}; + static void test_ownerdata_multiselect(void) { HWND hwnd; DWORD res; LVITEMA item; + unsigned int i; + char buf[256]; + struct kbd_select_sequence sequence[] = { + /* First down then up */ + { TRUE, FALSE, VK_DOWN, 2, "select multiple via SHIFT+DOWN", + ownerdata_multiselect_select_0_to_1_odstatechanged_seq, FALSE }, + { TRUE, FALSE, VK_UP, 1, "select one item via SHIFT+UP", + ownerdata_multiselect_select_0_modkey_odstatechanged_seq, TRUE }, + { TRUE, TRUE, VK_DOWN, 2, "select multiple via SHIFT+CONTROL+DOWN", + ownerdata_multiselect_select_0_to_1_odstatechanged_seq, FALSE }, + { TRUE, TRUE, VK_UP, 1, "select one item via SHIFT+CONTROL+UP", + ownerdata_multiselect_select_0_modkey_odstatechanged_seq, TRUE }, + { FALSE, TRUE, VK_DOWN, 1, "keep selection but move cursor via CONTROL+DOWN", + ownerdata_multiselect_move_0_to_1_odstatechanged_seq, FALSE }, + { TRUE, TRUE, VK_DOWN, 3, "select multiple after skip via SHIFT+CONTROL+DOWN", + ownerdata_multiselect_select_0_to_2_odstatechanged_seq, FALSE }, + { FALSE, FALSE, VK_DOWN, 1, "deselect all, select item 3 via DOWN", + ownerdata_multiselect_select_3_odstatechanged_seq, FALSE }, + /* First up then down */ + { TRUE, FALSE, VK_UP, 2, "select multiple via SHIFT+UP", + ownerdata_multiselect_select_3_to_2_odstatechanged_seq, FALSE }, + { TRUE, FALSE, VK_DOWN, 1, "select one item via SHIFT+DOWN", + ownerdata_multiselect_select_3_modkey_odstatechanged_seq, TRUE }, + { TRUE, TRUE, VK_UP, 2, "select multiple via SHIFT+CONTROL+UP", + ownerdata_multiselect_select_3_to_2_odstatechanged_seq, FALSE }, + { TRUE, TRUE, VK_DOWN, 1, "select one item via SHIFT+CONTROL+DOWN", + ownerdata_multiselect_select_3_modkey_odstatechanged_seq, TRUE }, + { FALSE, TRUE, VK_UP, 1, "keep selection but move cursor via CONTROL+UP", + ownerdata_multiselect_move_3_to_2_odstatechanged_seq, FALSE }, + { TRUE, TRUE, VK_UP, 3, "select multiple after skip via SHIFT+CONTROL+UP", + ownerdata_multiselect_select_3_to_1_odstatechanged_seq, FALSE }, + { FALSE, FALSE, VK_UP, 1, "deselect all, select item 0 via UP", + ownerdata_multiselect_select_0_odstatechanged_seq, FALSE }, + };
hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); @@ -3557,6 +3667,7 @@ static void test_ownerdata_multiselect(void) res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0); expect(0, res);
+ /* Select and focus the first row */ memset(&item, 0, sizeof(item)); item.state = LVIS_SELECTED | LVIS_FOCUSED; item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; @@ -3564,46 +3675,35 @@ static void test_ownerdata_multiselect(void) expect(TRUE, res); res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0); expect(1, res); - res = SendMessageA(hwnd, LVM_SETSELECTIONMARK, 0, 0); expect(0, res);
- hold_key(VK_SHIFT); - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - res = SendMessageA(hwnd, WM_KEYDOWN, VK_DOWN, 0); - expect(0, res); - - ok_sequence(sequences, PARENT_ODSTATECHANGED_SEQ_INDEX, - ownerdata_multiselect_odstatechanged_seq, - "ownerdata select multiple notification", FALSE); - - res = SendMessageA(hwnd, WM_KEYUP, VK_DOWN, 0); - expect(0, res); - - res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0); - expect(2, res); - - hold_key(VK_CONTROL); - - flush_sequences(sequences, NUM_MSG_SEQUENCES); - - res = SendMessageA(hwnd, WM_KEYDOWN, VK_DOWN, 0); - expect(0, res); - - ok_sequence(sequences, PARENT_ODSTATECHANGED_SEQ_INDEX, - ownerdata_multiselect_odstatechanged_seq, - "ownerdata select multiple notification", FALSE); - - res = SendMessageA(hwnd, WM_KEYUP, VK_DOWN, 0); - expect(0, res); - - release_key(VK_CONTROL); - release_key(VK_SHIFT); + /* Select/deselect rows using UP/DOWN and SHIFT/CONTROL keys */ + for (i = 0; i < ARRAY_SIZE(sequence); i++) + { + flush_sequences(sequences, NUM_MSG_SEQUENCES);
- res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0); - expect(3, res); + if (sequence[i].hold_shift) + hold_key(VK_SHIFT); + if (sequence[i].hold_control) + hold_key(VK_CONTROL); + + res = SendMessageA(hwnd, WM_KEYDOWN, sequence[i].press_key, 0); + expect(0, res); + sprintf(buf, "ownerdata multiselect: %s", sequence[i].context); + ok_sequence(sequences, PARENT_ODSTATECHANGED_SEQ_INDEX, sequence[i].expected, + buf, sequence[i].todo); + res = SendMessageA(hwnd, WM_KEYUP, sequence[i].press_key, 0); + expect(0, res); + + res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0); + expect(sequence[i].selected_count, res); + + if (sequence[i].hold_shift) + release_key(VK_SHIFT); + if (sequence[i].hold_control) + release_key(VK_CONTROL); + }
DestroyWindow(hwnd); }