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

This commit is contained in:
Dmitry Timoshkov 2007-10-16 22:23:34 +09:00 committed by Alexandre Julliard
parent 6b3c0ecf2e
commit 566ce8f5ed
2 changed files with 138 additions and 34 deletions

View File

@ -300,6 +300,9 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr )
static LRESULT LISTBOX_SetTopItem( LB_DESCR *descr, INT index, BOOL scroll ) static LRESULT LISTBOX_SetTopItem( LB_DESCR *descr, INT index, BOOL scroll )
{ {
INT max = LISTBOX_GetMaxTopIndex( descr ); INT max = LISTBOX_GetMaxTopIndex( descr );
TRACE("setting top item %d, scroll %d\n", index, scroll);
if (index > max) index = max; if (index > max) index = max;
if (index < 0) index = 0; if (index < 0) index = 0;
if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size; 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; rect->right += descr->horz_pos;
} }
TRACE("item %d, rect %s\n", index, wine_dbgstr_rect(rect));
return ((rect->left < descr->width) && (rect->right > 0) && return ((rect->left < descr->width) && (rect->right > 0) &&
(rect->top < descr->height) && (rect->bottom > 0)); (rect->top < descr->height) && (rect->bottom > 0));
} }
@ -680,13 +685,40 @@ static void LISTBOX_RepaintItem( LB_DESCR *descr, INT index, UINT action )
if (!IsWindowEnabled(descr->self)) if (!IsWindowEnabled(descr->self))
SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) ); SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL ); 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 (oldFont) SelectObject( hdc, oldFont );
if (oldBrush) SelectObject( hdc, oldBrush ); if (oldBrush) SelectObject( hdc, oldBrush );
ReleaseDC( descr->self, hdc ); ReleaseDC( descr->self, hdc );
} }
/***********************************************************************
* 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 * LISTBOX_InitStorage
*/ */
@ -1317,6 +1349,8 @@ static void LISTBOX_MakeItemVisible( LB_DESCR *descr, INT index, BOOL fully )
{ {
INT top; INT top;
TRACE("current top item %d, index %d, fully %d\n", descr->top_item, index, fully);
if (index <= descr->top_item) top = index; if (index <= descr->top_item) top = index;
else if (descr->style & LBS_MULTICOLUMN) 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; INT oldfocus = descr->focus_item;
TRACE("old focus %d, index %d\n", oldfocus, index);
if (descr->style & LBS_NOSEL) return LB_ERR; if (descr->style & LBS_NOSEL) return LB_ERR;
if ((index < 0) || (index >= descr->nb_items)) return LB_ERR; if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
if (index == oldfocus) return LB_OKAY; if (index == oldfocus) return LB_OKAY;
LISTBOX_DrawFocusRect( descr, FALSE );
descr->focus_item = index; 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 ); LISTBOX_MakeItemVisible( descr, index, fully_visible );
if (descr->caret_on && (descr->in_focus)) LISTBOX_DrawFocusRect( descr, TRUE );
LISTBOX_RepaintItem( descr, index, ODA_FOCUS );
return LB_OKAY; return LB_OKAY;
} }
@ -1439,8 +1474,8 @@ static LRESULT LISTBOX_SetSelection( LB_DESCR *descr, INT index,
if (index == oldsel) return LB_OKAY; if (index == oldsel) return LB_OKAY;
if (oldsel != -1) descr->items[oldsel].selected = FALSE; if (oldsel != -1) descr->items[oldsel].selected = FALSE;
if (index != -1) descr->items[index].selected = TRUE; if (index != -1) descr->items[index].selected = TRUE;
descr->selected_item = index;
if (oldsel != -1) LISTBOX_RepaintItem( descr, oldsel, ODA_SELECT ); if (oldsel != -1) LISTBOX_RepaintItem( descr, oldsel, ODA_SELECT );
descr->selected_item = index;
if (index != -1) LISTBOX_RepaintItem( descr, index, ODA_SELECT ); if (index != -1) LISTBOX_RepaintItem( descr, index, ODA_SELECT );
if (send_notify && descr->nb_items) SEND_NOTIFICATION( descr, if (send_notify && descr->nb_items) SEND_NOTIFICATION( descr,
(index != -1) ? LBN_SELCHANGE : LBN_SELCANCEL ); (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 ) 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)) if ((index < 0) || (index >= descr->nb_items))
return; 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 */ 4. Set the focus to 'index' and repaint the item */
/* 1. remove the focus and repaint the item */ /* 1. remove the focus and repaint the item */
descr->focus_item = -1; LISTBOX_DrawFocusRect( descr, FALSE );
if ((oldfocus != -1) && descr->caret_on && (descr->in_focus))
LISTBOX_RepaintItem( descr, oldfocus, ODA_FOCUS );
/* 2. then turn off the previous selection */ /* 2. then turn off the previous selection */
/* 3. repaint the new selected item */ /* 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 */ /* 4. repaint the new item with the focus */
descr->focus_item = index; descr->focus_item = index;
LISTBOX_MakeItemVisible( descr, index, fully_visible ); LISTBOX_MakeItemVisible( descr, index, fully_visible );
if (descr->caret_on && (descr->in_focus)) LISTBOX_DrawFocusRect( descr, TRUE );
LISTBOX_RepaintItem( descr, index, ODA_FOCUS );
} }
@ -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 ) static LRESULT LISTBOX_HandleLButtonDown( LB_DESCR *descr, DWORD keys, INT x, INT y )
{ {
INT index = LISTBOX_GetItemFromPoint( descr, x, 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->caret_on && (descr->in_focus)) return 0;
if (!descr->in_focus) 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 (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)) if (descr->style & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL))
{ {
/* we should perhaps make sure that all items are deselected /* 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 ); TRUE, (descr->style & LBS_NOTIFY) != 0 );
} }
descr->captured = TRUE;
SetCapture( descr->self );
if (!descr->lphc) 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) if (GetWindowLongW( descr->self, GWL_EXSTYLE ) & WS_EX_DRAGDETECT)
{ {
POINT pt; POINT pt;
@ -2902,7 +2941,7 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
if (IS_MULTISELECT(descr)) return LB_ERR; if (IS_MULTISELECT(descr)) return LB_ERR;
LISTBOX_SetCaretIndex( descr, wParam, FALSE ); LISTBOX_SetCaretIndex( descr, wParam, FALSE );
ret = LISTBOX_SetSelection( descr, wParam, TRUE, 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; return ret;
case LB_GETSELCOUNT16: case LB_GETSELCOUNT16:
@ -3063,7 +3102,7 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
descr->in_focus = TRUE; descr->in_focus = TRUE;
descr->caret_on = TRUE; descr->caret_on = TRUE;
if (descr->focus_item != -1) if (descr->focus_item != -1)
LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS ); LISTBOX_DrawFocusRect( descr, TRUE );
SEND_NOTIFICATION( descr, LBN_SETFOCUS ); SEND_NOTIFICATION( descr, LBN_SETFOCUS );
return 0; return 0;
case WM_KILLFOCUS: case WM_KILLFOCUS:

View File

@ -9848,16 +9848,63 @@ static const struct message wm_lb_setcursel_0[] =
{ {
{ LB_SETCURSEL, sent|wparam|lparam, 0, 0 }, { LB_SETCURSEL, sent|wparam|lparam, 0, 0 },
{ WM_CTLCOLORLISTBOX, sent|parent }, { 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 } { 0 }
}; };
static const struct message wm_lb_setcursel_1[] = static const struct message wm_lb_setcursel_1[] =
{ {
{ LB_SETCURSEL, sent|wparam|lparam, 1, 0 }, { LB_SETCURSEL, sent|wparam|lparam, 1, 0 },
{ WM_CTLCOLORLISTBOX, sent|parent }, { 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_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 } { 0 }
}; };
@ -9896,13 +9943,14 @@ static void check_lb_state_dbg(HWND listbox, int count, int cur_sel,
{ {
LRESULT ret; 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); 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); 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); 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); 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); 100, 100, 200, 200, 0, 0, 0, NULL);
listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL, listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
WS_CHILD | LBS_NOTIFY | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | WS_VISIBLE, 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); listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
check_lb_state(listbox, 0, LB_ERR, 0, 0); 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); 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); 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); ok(ret == 2, "expected 2, got %ld\n", ret);
check_lb_state(listbox, 3, LB_ERR, 0, 0); check_lb_state(listbox, 3, LB_ERR, 0, 0);
@ -9934,16 +9982,33 @@ static void test_listbox(void)
log_all_parent_messages++; log_all_parent_messages++;
trace("selecting item 0\n"); 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 ); ok_sequence(wm_lb_setcursel_0, "LB_SETCURSEL 0", FALSE );
check_lb_state(listbox, 3, 0, 0, 0); check_lb_state(listbox, 3, 0, 0, 0);
flush_sequence(); flush_sequence();
trace("selecting item 1\n"); 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 ); ok_sequence(wm_lb_setcursel_1, "LB_SETCURSEL 1", FALSE );
check_lb_state(listbox, 3, 1, 1, 0); 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--; log_all_parent_messages--;
DestroyWindow(parent); DestroyWindow(parent);