From: Esme Povirk esme@codeweavers.com
--- dlls/comctl32/listbox.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index bb37af8f10e..0ae511f7d70 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -1526,6 +1526,9 @@ static LRESULT LISTBOX_SelectItemRange( LB_DESCR *descr, INT first, LISTBOX_InvalidateItemRect(descr, i); } } + + NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN, descr->self, OBJID_CLIENT, 0 ); + return LB_OKAY; }
@@ -1711,6 +1714,9 @@ static LRESULT LISTBOX_InsertString( LB_DESCR *descr, INT index, LPCWSTR str )
TRACE("[%p]: added item %d %s\n", descr->self, index, HAS_STRINGS(descr) ? debugstr_w(new_str) : "" ); + + NotifyWinEvent( EVENT_OBJECT_CREATE, descr->self, OBJID_CLIENT, index + 1 ); + return index; }
@@ -1757,6 +1763,7 @@ static LRESULT LISTBOX_RemoveItem( LB_DESCR *descr, INT index )
if (descr->nb_items == 1) { + NotifyWinEvent( EVENT_OBJECT_DESTROY, descr->self, OBJID_CLIENT, 1 ); SendMessageW(descr->self, LB_RESETCONTENT, 0, 0); return LB_OKAY; } @@ -1793,6 +1800,7 @@ static LRESULT LISTBOX_RemoveItem( LB_DESCR *descr, INT index ) descr->focus_item = descr->nb_items - 1; if (descr->focus_item < 0) descr->focus_item = 0; } + NotifyWinEvent( EVENT_OBJECT_DESTROY, descr->self, OBJID_CLIENT, index + 1 ); return LB_OKAY; }
From: Esme Povirk esme@codeweavers.com
--- dlls/comctl32/tests/listbox.c | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index 9993031fb5f..b707b540aa5 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -40,6 +40,47 @@ enum seq_index
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
+static void CALLBACK msg_winevent_proc(HWINEVENTHOOK hevent, + DWORD event, + HWND hwnd, + LONG object_id, + LONG child_id, + DWORD thread_id, + DWORD event_time) +{ + struct message msg = {0}; + char class_name[256]; + + /* ignore window and other system events */ + if (object_id != OBJID_CLIENT) return; + + /* ignore events not from a listbox control */ + if (!GetClassNameA(hwnd, class_name, ARRAY_SIZE(class_name)) || + strcmp(class_name, WC_LISTBOXA) != 0) + return; + + msg.message = event; + msg.flags = winevent_hook|wparam|lparam; + msg.wParam = object_id; + msg.lParam = child_id; + add_message(sequences, LB_SEQ_INDEX, &msg); +} + +static void init_winevent_hook(void) { + hwineventhook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandleA(0), msg_winevent_proc, + 0, GetCurrentThreadId(), WINEVENT_INCONTEXT); + if (!hwineventhook) + win_skip( "no win event hook support\n" ); +} + +static void uninit_winevent_hook(void) { + if (!hwineventhook) + return; + + UnhookWinEvent(hwineventhook); + hwineventhook = 0; +} + /* encoded MEASUREITEMSTRUCT into a WPARAM */ typedef struct { @@ -227,9 +268,13 @@ static void run_test(DWORD style, const struct listbox_test test) static const struct message delete_seq[] = { { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 }, { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 }, { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 }, { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 }, { LB_RESETCONTENT, sent|wparam|lparam|defwinproc, 0, 0 }, { 0 } }; @@ -2900,6 +2945,8 @@ START_TEST(listbox)
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
+ init_winevent_hook(); + test_listbox(); test_item_height(); test_ownerdraw(); @@ -2922,5 +2969,7 @@ START_TEST(listbox) test_LB_FINDSTRING(); test_keypresses();
+ uninit_winevent_hook(); + unload_v6_module(ctx_cookie, hCtx); }
From: Esme Povirk esme@codeweavers.com
--- dlls/comctl32/tests/listbox.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index b707b540aa5..4012811473c 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -186,6 +186,19 @@ static LRESULT WINAPI listbox_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, L
static HWND create_listbox(DWORD add_style, HWND parent) { + static const struct message addstring_seq[] = + { + { LB_ADDSTRING, sent }, + { WM_GETMINMAXINFO, sent|defwinproc|optional }, + { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 }, + { LB_ADDSTRING, sent }, + { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CLIENT, 2 }, + { LB_ADDSTRING, sent }, + { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CLIENT, 3 }, + { LB_ADDSTRING, sent }, + { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CLIENT, 4 }, + { 0 } + }; INT_PTR ctl_id = 0; WNDPROC oldproc; HWND handle; @@ -197,13 +210,15 @@ static HWND create_listbox(DWORD add_style, HWND parent) parent, (HMENU)ctl_id, NULL, 0); ok(handle != NULL, "Failed to create listbox window.\n");
+ oldproc = (WNDPROC)SetWindowLongPtrA(handle, GWLP_WNDPROC, (LONG_PTR)listbox_wnd_proc); + SetWindowLongPtrA(handle, GWLP_USERDATA, (LONG_PTR)oldproc); + + flush_sequence(sequences, LB_SEQ_INDEX); SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[0]); SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[1]); SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[2]); SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[3]); - - oldproc = (WNDPROC)SetWindowLongPtrA(handle, GWLP_WNDPROC, (LONG_PTR)listbox_wnd_proc); - SetWindowLongPtrA(handle, GWLP_USERDATA, (LONG_PTR)oldproc); + ok_sequence(sequences, LB_SEQ_INDEX, addstring_seq, "addstring_seq", FALSE);
return handle; } @@ -646,6 +661,12 @@ static void test_ownerdraw(void)
static void test_LB_SELITEMRANGE(void) { + static const struct message selitemrange_seq[] = + { + { LB_SELITEMRANGE, sent }, + { EVENT_OBJECT_SELECTIONWITHIN, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { 0 } + }; static const struct listbox_stat test_nosel = { 0, LB_ERR, 0, 0 }; static const struct listbox_stat test_1 = { 0, LB_ERR, 0, 2 }; static const struct listbox_stat test_2 = { 0, LB_ERR, 0, 3 }; @@ -687,8 +708,11 @@ static void test_LB_SELITEMRANGE(void) listbox_query(hLB, &answer); listbox_test_query(test_nosel, answer);
+ flush_sequence(sequences, LB_SEQ_INDEX); ret = SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(2, 10)); ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret); + ok_sequence(sequences, LB_SEQ_INDEX, selitemrange_seq, "selitemrange_seq", FALSE); + listbox_query(hLB, &answer); listbox_test_query(test_1, answer);