Commit 566ce8f5 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

user32: Add more listbox message tests, make them pass under Wine.

parent 6b3c0ecf
......@@ -300,6 +300,9 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr )
static LRESULT LISTBOX_SetTopItem( LB_DESCR *descr, INT index, BOOL scroll )
{
INT max = LISTBOX_GetMaxTopIndex( descr );
TRACE("setting top item %d, scroll %d\n", index, scroll);
if (index > max) index = max;
if (index < 0) index = 0;
if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size;
......@@ -473,6 +476,8 @@ static LRESULT LISTBOX_GetItemRect( LB_DESCR *descr, INT index, RECT *rect )
rect->right += descr->horz_pos;
}
TRACE("item %d, rect %s\n", index, wine_dbgstr_rect(rect));
return ((rect->left < descr->width) && (rect->right > 0) &&
(rect->top < descr->height) && (rect->bottom > 0));
}
......@@ -680,7 +685,7 @@ static void LISTBOX_RepaintItem( LB_DESCR *descr, INT index, UINT action )
if (!IsWindowEnabled(descr->self))
SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
LISTBOX_PaintItem( descr, hdc, &rect, index, action, FALSE );
LISTBOX_PaintItem( descr, hdc, &rect, index, action, TRUE );
if (oldFont) SelectObject( hdc, oldFont );
if (oldBrush) SelectObject( hdc, oldBrush );
ReleaseDC( descr->self, hdc );
......@@ -688,6 +693,33 @@ static void LISTBOX_RepaintItem( LB_DESCR *descr, INT index, UINT action )
/***********************************************************************
* LISTBOX_DrawFocusRect
*/
static void LISTBOX_DrawFocusRect( LB_DESCR *descr, BOOL on )
{
HDC hdc;
RECT rect;
HFONT oldFont = 0;
/* Do not repaint the item if the item is not visible */
if (!IsWindowVisible(descr->self)) return;
if (descr->focus_item == -1) return;
if (!descr->caret_on || !descr->in_focus) return;
if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) != 1) return;
if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE ))) return;
if (descr->font) oldFont = SelectObject( hdc, descr->font );
if (!IsWindowEnabled(descr->self))
SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
LISTBOX_PaintItem( descr, hdc, &rect, descr->focus_item, ODA_FOCUS, on ? FALSE : TRUE );
if (oldFont) SelectObject( hdc, oldFont );
ReleaseDC( descr->self, hdc );
}
/***********************************************************************
* LISTBOX_InitStorage
*/
static LRESULT LISTBOX_InitStorage( LB_DESCR *descr, INT nb_items )
......@@ -1317,6 +1349,8 @@ static void LISTBOX_MakeItemVisible( LB_DESCR *descr, INT index, BOOL fully )
{
INT top;
TRACE("current top item %d, index %d, fully %d\n", descr->top_item, index, fully);
if (index <= descr->top_item) top = index;
else if (descr->style & LBS_MULTICOLUMN)
{
......@@ -1354,16 +1388,17 @@ static LRESULT LISTBOX_SetCaretIndex( LB_DESCR *descr, INT index, BOOL fully_vis
{
INT oldfocus = descr->focus_item;
TRACE("old focus %d, index %d\n", oldfocus, index);
if (descr->style & LBS_NOSEL) return LB_ERR;
if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
if (index == oldfocus) return LB_OKAY;
LISTBOX_DrawFocusRect( descr, FALSE );
descr->focus_item = index;
if ((oldfocus != -1) && descr->caret_on && (descr->in_focus))
LISTBOX_RepaintItem( descr, oldfocus, ODA_FOCUS );
LISTBOX_MakeItemVisible( descr, index, fully_visible );
if (descr->caret_on && (descr->in_focus))
LISTBOX_RepaintItem( descr, index, ODA_FOCUS );
LISTBOX_DrawFocusRect( descr, TRUE );
return LB_OKAY;
}
......@@ -1439,8 +1474,8 @@ static LRESULT LISTBOX_SetSelection( LB_DESCR *descr, INT index,
if (index == oldsel) return LB_OKAY;
if (oldsel != -1) descr->items[oldsel].selected = FALSE;
if (index != -1) descr->items[index].selected = TRUE;
descr->selected_item = index;
if (oldsel != -1) LISTBOX_RepaintItem( descr, oldsel, ODA_SELECT );
descr->selected_item = index;
if (index != -1) LISTBOX_RepaintItem( descr, index, ODA_SELECT );
if (send_notify && descr->nb_items) SEND_NOTIFICATION( descr,
(index != -1) ? LBN_SELCHANGE : LBN_SELCANCEL );
......@@ -1459,7 +1494,7 @@ static LRESULT LISTBOX_SetSelection( LB_DESCR *descr, INT index,
*/
static void LISTBOX_MoveCaret( LB_DESCR *descr, INT index, BOOL fully_visible )
{
INT oldfocus = descr->focus_item;
TRACE("old focus %d, index %d\n", descr->focus_item, index);
if ((index < 0) || (index >= descr->nb_items))
return;
......@@ -1472,9 +1507,7 @@ static void LISTBOX_MoveCaret( LB_DESCR *descr, INT index, BOOL fully_visible )
4. Set the focus to 'index' and repaint the item */
/* 1. remove the focus and repaint the item */
descr->focus_item = -1;
if ((oldfocus != -1) && descr->caret_on && (descr->in_focus))
LISTBOX_RepaintItem( descr, oldfocus, ODA_FOCUS );
LISTBOX_DrawFocusRect( descr, FALSE );
/* 2. then turn off the previous selection */
/* 3. repaint the new selected item */
......@@ -1499,8 +1532,7 @@ static void LISTBOX_MoveCaret( LB_DESCR *descr, INT index, BOOL fully_visible )
/* 4. repaint the new item with the focus */
descr->focus_item = index;
LISTBOX_MakeItemVisible( descr, index, fully_visible );
if (descr->caret_on && (descr->in_focus))
LISTBOX_RepaintItem( descr, index, ODA_FOCUS );
LISTBOX_DrawFocusRect( descr, TRUE );
}
......@@ -2005,7 +2037,10 @@ static LRESULT LISTBOX_HandleMouseWheel(LB_DESCR *descr, SHORT delta )
static LRESULT LISTBOX_HandleLButtonDown( LB_DESCR *descr, DWORD keys, INT x, INT y )
{
INT index = LISTBOX_GetItemFromPoint( descr, x, y );
TRACE("[%p]: lbuttondown %d,%d item %d\n", descr->self, x, y, index );
TRACE("[%p]: lbuttondown %d,%d item %d, focus item %d\n",
descr->self, x, y, index, descr->focus_item);
if (!descr->caret_on && (descr->in_focus)) return 0;
if (!descr->in_focus)
......@@ -2016,6 +2051,16 @@ static LRESULT LISTBOX_HandleLButtonDown( LB_DESCR *descr, DWORD keys, INT x, IN
if (index == -1) return 0;
if (!descr->lphc)
{
if (descr->style & LBS_NOTIFY )
SendMessageW( descr->owner, WM_LBTRACKPOINT, index,
MAKELPARAM( x, y ) );
}
descr->captured = TRUE;
SetCapture( descr->self );
if (descr->style & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL))
{
/* we should perhaps make sure that all items are deselected
......@@ -2058,14 +2103,8 @@ static LRESULT LISTBOX_HandleLButtonDown( LB_DESCR *descr, DWORD keys, INT x, IN
TRUE, (descr->style & LBS_NOTIFY) != 0 );
}
descr->captured = TRUE;
SetCapture( descr->self );
if (!descr->lphc)
{
if (descr->style & LBS_NOTIFY )
SendMessageW( descr->owner, WM_LBTRACKPOINT, index,
MAKELPARAM( x, y ) );
if (GetWindowLongW( descr->self, GWL_EXSTYLE ) & WS_EX_DRAGDETECT)
{
POINT pt;
......@@ -2902,7 +2941,7 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
if (IS_MULTISELECT(descr)) return LB_ERR;
LISTBOX_SetCaretIndex( descr, wParam, FALSE );
ret = LISTBOX_SetSelection( descr, wParam, TRUE, FALSE );
if (lphc && ret != LB_ERR) ret = descr->selected_item;
if (ret != LB_ERR) ret = descr->selected_item;
return ret;
case LB_GETSELCOUNT16:
......@@ -3063,7 +3102,7 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
descr->in_focus = TRUE;
descr->caret_on = TRUE;
if (descr->focus_item != -1)
LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
LISTBOX_DrawFocusRect( descr, TRUE );
SEND_NOTIFICATION( descr, LBN_SETFOCUS );
return 0;
case WM_KILLFOCUS:
......
......@@ -9848,16 +9848,63 @@ static const struct message wm_lb_setcursel_0[] =
{
{ LB_SETCURSEL, sent|wparam|lparam, 0, 0 },
{ WM_CTLCOLORLISTBOX, sent|parent },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x00120f2 },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000120f2 },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 },
{ EVENT_OBJECT_SELECTION, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 },
{ 0 }
};
static const struct message wm_lb_setcursel_1[] =
{
{ LB_SETCURSEL, sent|wparam|lparam, 1, 0 },
{ WM_CTLCOLORLISTBOX, sent|parent },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x00020f2 },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000020f2 },
{ WM_CTLCOLORLISTBOX, sent|parent },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x00121f2 },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000121f2 },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 2 },
{ EVENT_OBJECT_SELECTION, winevent_hook|wparam|lparam, OBJID_CLIENT, 2 },
{ 0 }
};
static const struct message wm_lb_setcursel_2[] =
{
{ LB_SETCURSEL, sent|wparam|lparam, 2, 0 },
{ WM_CTLCOLORLISTBOX, sent|parent },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000021f2 },
{ WM_CTLCOLORLISTBOX, sent|parent },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000122f2 },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 3 },
{ EVENT_OBJECT_SELECTION, winevent_hook|wparam|lparam, OBJID_CLIENT, 3 },
{ 0 }
};
static const struct message wm_lb_click_0[] =
{
{ WM_LBUTTONDOWN, sent|wparam|lparam, 0, MAKELPARAM(1,1) },
{ HCBT_SETFOCUS, hook },
{ WM_KILLFOCUS, sent|parent },
{ WM_IME_SETCONTEXT, sent|wparam|optional|parent, 0 },
{ WM_IME_SETCONTEXT, sent|wparam|optional, 1 },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
{ WM_SETFOCUS, sent },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x001142f2 },
{ WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_LISTBOX, LBN_SETFOCUS) },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 3 },
{ WM_LBTRACKPOINT, sent|wparam|lparam|parent, 0, MAKELPARAM(1,1) },
{ EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000142f2 },
{ WM_CTLCOLORLISTBOX, sent|parent },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000022f2 },
{ WM_CTLCOLORLISTBOX, sent|parent },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000120f2 },
{ WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x001140f2 },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 },
{ EVENT_OBJECT_SELECTION, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 },
{ WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
{ EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
{ WM_CAPTURECHANGED, sent|wparam|lparam, 0, 0 },
{ WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_LISTBOX, LBN_SELCHANGE) },
{ 0 }
};
......@@ -9896,13 +9943,14 @@ static void check_lb_state_dbg(HWND listbox, int count, int cur_sel,
{
LRESULT ret;
ret = SendMessage(listbox, LB_GETCOUNT, 0, 0);
/* calling an orig proc helps to avoid unnecessary message logging */
ret = CallWindowProcA(listbox_orig_proc, listbox, LB_GETCOUNT, 0, 0);
ok_(__FILE__, line)(ret == count, "expected count %d, got %ld\n", count, ret);
ret = SendMessage(listbox, LB_GETCURSEL, 0, 0);
ret = CallWindowProcA(listbox_orig_proc, listbox, LB_GETCURSEL, 0, 0);
ok_(__FILE__, line)(ret == cur_sel, "expected cur sel %d, got %ld\n", cur_sel, ret);
ret = SendMessage(listbox, LB_GETCARETINDEX, 0, 0);
ret = CallWindowProcA(listbox_orig_proc, listbox, LB_GETCARETINDEX, 0, 0);
ok_(__FILE__, line)(ret == caret_index, "expected caret index %d, got %ld\n", caret_index, ret);
ret = SendMessage(listbox, LB_GETTOPINDEX, 0, 0);
ret = CallWindowProcA(listbox_orig_proc, listbox, LB_GETTOPINDEX, 0, 0);
ok_(__FILE__, line)(ret == top_index, "expected top index %d, got %ld\n", top_index, ret);
}
......@@ -9915,16 +9963,16 @@ static void test_listbox(void)
100, 100, 200, 200, 0, 0, 0, NULL);
listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
WS_CHILD | LBS_NOTIFY | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | WS_VISIBLE,
10, 10, 80, 20, parent, (HMENU)ID_LISTBOX, 0, NULL);
10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
check_lb_state(listbox, 0, LB_ERR, 0, 0);
ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
ok(ret == 0, "expected 0, got %ld\n", ret);
ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
ok(ret == 1, "expected 1, got %ld\n", ret);
ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 3");
ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
ok(ret == 2, "expected 2, got %ld\n", ret);
check_lb_state(listbox, 3, LB_ERR, 0, 0);
......@@ -9934,16 +9982,33 @@ static void test_listbox(void)
log_all_parent_messages++;
trace("selecting item 0\n");
SendMessage(listbox, LB_SETCURSEL, 0, 0);
ret = SendMessage(listbox, LB_SETCURSEL, 0, 0);
ok(ret == 0, "expected 0, got %ld\n", ret);
ok_sequence(wm_lb_setcursel_0, "LB_SETCURSEL 0", FALSE );
check_lb_state(listbox, 3, 0, 0, 0);
flush_sequence();
trace("selecting item 1\n");
SendMessage(listbox, LB_SETCURSEL, 1, 0);
ret = SendMessage(listbox, LB_SETCURSEL, 1, 0);
ok(ret == 1, "expected 1, got %ld\n", ret);
ok_sequence(wm_lb_setcursel_1, "LB_SETCURSEL 1", FALSE );
check_lb_state(listbox, 3, 1, 1, 0);
trace("selecting item 2\n");
ret = SendMessage(listbox, LB_SETCURSEL, 2, 0);
ok(ret == 2, "expected 2, got %ld\n", ret);
ok_sequence(wm_lb_setcursel_2, "LB_SETCURSEL 2", FALSE );
check_lb_state(listbox, 3, 2, 2, 0);
trace("clicking on item 0\n");
ret = SendMessage(listbox, WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1));
ok(ret == LB_OKAY, "expected LB_OKAY, got %ld\n", ret);
ret = SendMessage(listbox, WM_LBUTTONUP, 0, 0);
ok(ret == LB_OKAY, "expected LB_OKAY, got %ld\n", ret);
ok_sequence(wm_lb_click_0, "WM_LBUTTONDOWN 0", FALSE );
check_lb_state(listbox, 3, 0, 0, 0);
flush_sequence();
log_all_parent_messages--;
DestroyWindow(parent);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment