From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/tests/listbox.c | 91 +++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 21 deletions(-)
diff --git a/dlls/comctl32/tests/listbox.c b/dlls/comctl32/tests/listbox.c index 43da3caa42..362447e083 100644 --- a/dlls/comctl32/tests/listbox.c +++ b/dlls/comctl32/tests/listbox.c @@ -34,6 +34,7 @@
enum seq_index { + LB_SEQ_INDEX, PARENT_SEQ_INDEX, NUM_MSG_SEQUENCES }; @@ -90,9 +91,47 @@ static const char BAD_EXTENSION[] = "*.badtxt";
#define ID_LISTBOX 1
+static LRESULT WINAPI listbox_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + static LONG defwndproc_counter = 0; + struct message msg = { 0 }; + LRESULT ret; + + switch (message) + { + case WM_SIZE: + case WM_GETTEXT: + case WM_PAINT: + case WM_ERASEBKGND: + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + case WM_NCCALCSIZE: + case WM_NCPAINT: + case WM_NCHITTEST: + case WM_DEVICECHANGE: + break; + + default: + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + add_message(sequences, LB_SEQ_INDEX, &msg); + } + + defwndproc_counter++; + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + static HWND create_listbox(DWORD add_style, HWND parent) { INT_PTR ctl_id = 0; + WNDPROC oldproc; HWND handle;
if (parent) @@ -107,6 +146,9 @@ static HWND create_listbox(DWORD add_style, HWND parent) 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); + return handle; }
@@ -167,9 +209,18 @@ static void keypress(HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
static void run_test(DWORD style, const struct listbox_test test) { + static const struct message delete_seq[] = + { + { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { LB_RESETCONTENT, sent|wparam|lparam|defwinproc, 0, 0 }, + { 0 } + }; struct listbox_stat answer; + int i, res, count; RECT second_item; - int i, res; HWND hLB;
hLB = create_listbox (style, 0); @@ -224,8 +275,17 @@ static void run_test(DWORD style, const struct listbox_test test) ok(res == LB_ERR, "Expected LB_ERR items, got %d\n", res); res = SendMessageA(hLB, LB_DELETESTRING, 4, 0); ok(res == LB_ERR, "Expected LB_ERR items, got %d\n", res); - res = SendMessageA(hLB, LB_GETCOUNT, 0, 0); - ok(res == 4, "Expected 4 items, got %d\n", res); + count = SendMessageA(hLB, LB_GETCOUNT, 0, 0); + ok(count == 4, "Unexpected item count %d.\n", count); + + /* Emptying listbox sends a LB_RESETCONTENT to itself. */ + flush_sequence(sequences, LB_SEQ_INDEX); + for (i = count; i--;) + { + res = SendMessageA(hLB, LB_DELETESTRING, 0, 0); + ok(res == i, "Unexpected return value %d.\n", res); + } + ok_sequence(sequences, LB_SEQ_INDEX, delete_seq, "Emptying listbox", FALSE);
DestroyWindow(hLB); } @@ -1815,34 +1875,23 @@ static void test_set_count( void ) DestroyWindow( parent ); }
-static int lb_getlistboxinfo; - -static LRESULT WINAPI listbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); - - if (message == LB_GETLISTBOXINFO) - lb_getlistboxinfo++; - - return CallWindowProcA(oldproc, hwnd, message, wParam, lParam); -} - static void test_GetListBoxInfo(void) { + static const struct message getlistboxinfo_seq[] = + { + { LB_GETLISTBOXINFO, sent }, + { 0 } + }; HWND listbox, parent; - WNDPROC oldproc; DWORD ret;
parent = create_parent(); listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
- oldproc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (LONG_PTR)listbox_subclass_proc); - SetWindowLongPtrA(listbox, GWLP_USERDATA, (LONG_PTR)oldproc); - - lb_getlistboxinfo = 0; + flush_sequences(sequences, NUM_MSG_SEQUENCES); ret = GetListBoxInfo(listbox); ok(ret > 0, "got %d\n", ret); - ok(lb_getlistboxinfo == 1, "got %d\n", lb_getlistboxinfo); + ok_sequence(sequences, LB_SEQ_INDEX, getlistboxinfo_seq, "GetListBoxInfo()", FALSE);
DestroyWindow(listbox); DestroyWindow(parent);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/listbox.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index dbc7b4a844..a2085edd7a 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -125,6 +125,11 @@ static TIMER_DIRECTION LISTBOX_Timer = LB_TIMER_NONE;
static LRESULT LISTBOX_GetItemRect( const LB_DESCR *descr, INT index, RECT *rect );
+static BOOL is_item_selected( const LB_DESCR *descr, UINT index ) +{ + return descr->items[index].selected; +} + /*********************************************************************** * LISTBOX_GetCurrentPageSize * @@ -2763,7 +2768,7 @@ static LRESULT CALLBACK LISTBOX_WindowProc( HWND hwnd, UINT msg, WPARAM wParam, case LB_GETSEL: if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items)) return LB_ERR; - return descr->items[wParam].selected; + return is_item_selected(descr, wParam);
case LB_SETSEL: ret = LISTBOX_SetSelection( descr, lParam, wParam, FALSE );
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/listbox.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index a2085edd7a..51f6115059 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -491,7 +491,13 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, INT index, UINT action, BOOL ignoreFocus ) { LB_ITEMDATA *item = NULL; - if (index < descr->nb_items) item = &descr->items[index]; + BOOL selected = FALSE; + + if (index < descr->nb_items) + { + item = &descr->items[index]; + selected = is_item_selected(descr, index); + }
if (IS_OWNERDRAW(descr)) { @@ -522,7 +528,8 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, dis.hDC = hdc; dis.itemID = index; dis.itemState = 0; - if (item->selected) dis.itemState |= ODS_SELECTED; + if (selected) + dis.itemState |= ODS_SELECTED; if (!ignoreFocus && (descr->focus_item == index) && (descr->caret_on) && (descr->in_focus)) dis.itemState |= ODS_FOCUS; @@ -545,7 +552,7 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, DrawFocusRect( hdc, rect ); return; } - if (item && item->selected) + if (selected) { oldBk = SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) ); oldText = SetTextColor( hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); @@ -570,7 +577,7 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, item->str, strlenW(item->str), descr->nb_tabs, descr->tabs, 0); } - if (item && item->selected) + if (selected) { SetBkColor( hdc, oldBk ); SetTextColor( hdc, oldText );
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/listbox.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index 51f6115059..71a9c18478 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -490,8 +490,8 @@ static INT LISTBOX_GetItemFromPoint( const LB_DESCR *descr, INT x, INT y ) static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, INT index, UINT action, BOOL ignoreFocus ) { + BOOL selected = FALSE, focused; LB_ITEMDATA *item = NULL; - BOOL selected = FALSE;
if (index < descr->nb_items) { @@ -499,6 +499,8 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, selected = is_item_selected(descr, index); }
+ focused = !ignoreFocus && descr->focus_item == index && descr->caret_on && descr->in_focus; + if (IS_OWNERDRAW(descr)) { DRAWITEMSTRUCT dis; @@ -530,9 +532,8 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, dis.itemState = 0; if (selected) dis.itemState |= ODS_SELECTED; - if (!ignoreFocus && (descr->focus_item == index) && - (descr->caret_on) && - (descr->in_focus)) dis.itemState |= ODS_FOCUS; + if (focused) + dis.itemState |= ODS_FOCUS; if (!IsWindowEnabled(descr->self)) dis.itemState |= ODS_DISABLED; dis.itemData = item->data; dis.rcItem = *rect; @@ -582,9 +583,8 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, SetBkColor( hdc, oldBk ); SetTextColor( hdc, oldText ); } - if (!ignoreFocus && (descr->focus_item == index) && - (descr->caret_on) && - (descr->in_focus)) DrawFocusRect( hdc, rect ); + if (focused) + DrawFocusRect( hdc, rect ); } }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/listbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index 71a9c18478..7525e7f7fe 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -535,10 +535,10 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, if (focused) dis.itemState |= ODS_FOCUS; if (!IsWindowEnabled(descr->self)) dis.itemState |= ODS_DISABLED; - dis.itemData = item->data; + dis.itemData = item ? item->data : 0; dis.rcItem = *rect; TRACE("[%p]: drawitem %d (%s) action=%02x state=%02x rect=%s\n", - descr->self, index, debugstr_w(item->str), action, + descr->self, index, item ? debugstr_w(item->str) : "", action, dis.itemState, wine_dbgstr_rect(rect) ); SendMessageW(descr->owner, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis); SelectClipRgn( hdc, hrgn );