Draw background of the empty selected item in empty lists.

Don't draw a focus rect if we dont have the focus.
Don't select items on key up/down in multi-select lists.
Handle LBS_NOSEL correctly, fix remaining todo_wine tests.
This commit is contained in:
Jon Griffiths 2004-10-05 22:31:00 +00:00 committed by Alexandre Julliard
parent f3a56591ec
commit 7a9e800566
2 changed files with 63 additions and 40 deletions

View File

@ -106,7 +106,8 @@ typedef struct
#define IS_MULTISELECT(descr) \
((descr)->style & LBS_MULTIPLESEL || ((descr)->style & LBS_EXTENDEDSEL))
((descr)->style & (LBS_MULTIPLESEL|LBS_EXTENDEDSEL) && \
!((descr)->style & LBS_NOSEL))
#define SEND_NOTIFICATION(hwnd,descr,code) \
(SendMessageW( (descr)->owner, WM_COMMAND, \
@ -968,7 +969,9 @@ static LRESULT LISTBOX_GetSelCount( LB_DESCR *descr )
INT i, count;
LB_ITEMDATA *item = descr->items;
if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
if (!(descr->style & LBS_MULTIPLESEL) ||
(descr->style & LBS_NOSEL))
return LB_ERR;
for (i = count = 0; i < descr->nb_items; i++, item++)
if (item->selected) count++;
return count;
@ -1038,6 +1041,8 @@ static LRESULT LISTBOX_Paint( HWND hwnd, LB_DESCR *descr, HDC hdc )
{
/* Special case for empty listbox: paint focus rect */
rect.bottom = rect.top + descr->item_height;
ExtTextOutW( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED,
&rect, NULL, 0, NULL );
LISTBOX_PaintItem( hwnd, descr, hdc, &rect, descr->focus_item,
ODA_FOCUS, FALSE );
rect.top = rect.bottom;
@ -1091,7 +1096,8 @@ static LRESULT LISTBOX_Paint( HWND hwnd, LB_DESCR *descr, HDC hdc )
}
/* Paint the focus item now */
if (focusRect.top != focusRect.bottom && descr->caret_on)
if (focusRect.top != focusRect.bottom &&
descr->caret_on && descr->in_focus)
LISTBOX_PaintItem( hwnd, descr, hdc, &focusRect, descr->focus_item, ODA_FOCUS, FALSE );
if (!IS_OWNERDRAW(descr))
@ -1404,7 +1410,11 @@ static LRESULT LISTBOX_SetSelection( HWND hwnd, LB_DESCR *descr, INT index,
{
TRACE( "index=%d notify=%s\n", index, send_notify ? "YES" : "NO" );
if (descr->style & LBS_NOSEL) return LB_ERR;
if (descr->style & LBS_NOSEL)
{
descr->selected_item = index;
return LB_ERR;
}
if ((index < -1) || (index >= descr->nb_items)) return LB_ERR;
if (descr->style & LBS_MULTIPLESEL)
{
@ -1507,7 +1517,7 @@ static LRESULT LISTBOX_InsertItem( HWND hwnd, LB_DESCR *descr, INT index,
item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
max_items * sizeof(LB_ITEMDATA) );
else
item = HeapAlloc( GetProcessHeap(), 0,
item = HeapAlloc( GetProcessHeap(), 0,
max_items * sizeof(LB_ITEMDATA) );
if (!item)
{
@ -1566,8 +1576,8 @@ static LRESULT LISTBOX_InsertItem( HWND hwnd, LB_DESCR *descr, INT index,
{
if (index <= descr->selected_item)
{
descr->selected_item++;
descr->focus_item = oldfocus; /* focus not changed */
descr->selected_item++;
descr->focus_item = oldfocus; /* focus not changed */
}
}
return LB_OKAY;
@ -1996,7 +2006,7 @@ static LRESULT LISTBOX_HandleLButtonDown( HWND hwnd, LB_DESCR *descr,
if (index == -1) return 0;
if (descr->style & LBS_EXTENDEDSEL)
if (descr->style & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL))
{
/* we should perhaps make sure that all items are deselected
FIXME: needed for !LBS_EXTENDEDSEL, too ?
@ -2012,15 +2022,25 @@ static LRESULT LISTBOX_HandleLButtonDown( HWND hwnd, LB_DESCR *descr,
!descr->items[index].selected,
(descr->style & LBS_NOTIFY) != 0);
}
else LISTBOX_MoveCaret( hwnd, descr, index, FALSE );
}
else
{
LISTBOX_MoveCaret( hwnd, descr, index, FALSE );
LISTBOX_SetSelection( hwnd, descr, index,
else
{
LISTBOX_MoveCaret( hwnd, descr, index, FALSE );
if (descr->style & LBS_MULTIPLESEL)
{
LISTBOX_SetSelection( hwnd, descr, index,
(!(descr->style & LBS_MULTIPLESEL) ||
!descr->items[index].selected),
(descr->style & LBS_NOTIFY) != 0 );
}
}
}
else
{
descr->anchor_item = index;
LISTBOX_MoveCaret( hwnd, descr, index, FALSE );
LISTBOX_SetSelection( hwnd, descr, index,
TRUE, (descr->style & LBS_NOTIFY) != 0 );
}
descr->captured = TRUE;
@ -2278,7 +2298,7 @@ static LRESULT LISTBOX_HandleKeyDown( HWND hwnd, LB_DESCR *descr, WPARAM wParam
INT caret = -1;
BOOL bForceSelection = TRUE; /* select item pointed to by focus_item */
if ((IS_MULTISELECT(descr)) || (descr->selected_item == descr->focus_item))
bForceSelection = FALSE; /* only for single select list */
bForceSelection = FALSE; /* only for single select list */
if (descr->style & LBS_WANTKEYBOARDINPUT)
{
@ -2358,18 +2378,23 @@ static LRESULT LISTBOX_HandleKeyDown( HWND hwnd, LB_DESCR *descr, WPARAM wParam
caret = descr->focus_item;
if (caret >= 0)
{
if ((descr->style & LBS_EXTENDEDSEL) &&
!(GetKeyState( VK_SHIFT ) & 0x8000))
if (((descr->style & LBS_EXTENDEDSEL) &&
!(GetKeyState( VK_SHIFT ) & 0x8000)) ||
!IS_MULTISELECT(descr))
descr->anchor_item = caret;
LISTBOX_MoveCaret( hwnd, descr, caret, TRUE );
LISTBOX_SetSelection( hwnd, descr, caret, TRUE, FALSE);
if (descr->style & LBS_MULTIPLESEL)
descr->selected_item = caret;
else
LISTBOX_SetSelection( hwnd, descr, caret, TRUE, FALSE);
if (descr->style & LBS_NOTIFY)
{
if( descr->lphc )
if( descr->lphc )
{
/* make sure that combo parent doesn't hide us */
descr->lphc->wState |= CBF_NOROLLUP;
}
/* make sure that combo parent doesn't hide us */
descr->lphc->wState |= CBF_NOROLLUP;
}
if (descr->nb_items) SEND_NOTIFICATION( hwnd, descr, LBN_SELCHANGE );
}
}
@ -2655,15 +2680,13 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
case LB_GETCURSEL16:
case LB_GETCURSEL:
if (descr->nb_items==0)
return LB_ERR;
if (descr->nb_items == 0)
return LB_ERR;
if (!IS_MULTISELECT(descr))
return descr->selected_item;
/* else */
if (descr->selected_item!=-1)
return descr->selected_item;
/* else */
return descr->focus_item;
return descr->selected_item;
if (descr->selected_item != -1)
return descr->selected_item;
return descr->focus_item;
/* otherwise, if the user tries to move the selection with the */
/* arrow keys, we will give the application something to choke on */
case LB_GETTOPINDEX16:
@ -2884,7 +2907,7 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
/* according to Win16 docs, DDL_DRIVES should make DDL_EXCLUSIVE
* be set automatically (this is different in Win32) */
if (wParam & DDL_DRIVES) wParam |= DDL_EXCLUSIVE;
lParam = (LPARAM)MapSL(lParam);
lParam = (LPARAM)MapSL(lParam);
/* fall through */
case LB_DIR:
{

View File

@ -143,24 +143,24 @@ START_TEST(listbox)
/* {add_style} */
{{0},
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
{ 1, 1, 1, LB_ERR}, {0,1,0,0},
{ 2, 2, 2, LB_ERR}, {0,1,0,0}};
{ 1, 1, 1, LB_ERR}, {0,0,0,0},
{ 2, 2, 2, LB_ERR}, {0,0,0,0}};
/* {selected, anchor, caret, selcount}{TODO fields} */
const struct listbox_test SS_NS =
{{LBS_NOSEL},
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
{ 1, 1, 1, LB_ERR}, {1,1,0,0},
{ 2, 2, 2, LB_ERR}, {1,1,1,0}};
{ 1, 1, 1, LB_ERR}, {0,0,0,0},
{ 2, 2, 2, LB_ERR}, {0,0,0,0}};
const struct listbox_test MS =
{{LBS_MULTIPLESEL},
{ 0, LB_ERR, 0, 0}, {0,0,0,0},
{ 1, 1, 1, 1}, {0,1,0,0},
{ 2, 1, 2, 1}, {0,1,0,1}};
{ 1, 1, 1, 1}, {0,0,0,0},
{ 2, 1, 2, 1}, {0,0,0,0}};
const struct listbox_test MS_NS =
{{LBS_MULTIPLESEL | LBS_NOSEL},
{LB_ERR, LB_ERR, 0, LB_ERR}, {1,0,0,1},
{ 1, 1, 1, LB_ERR}, {0,1,0,1},
{ 2, 2, 2, LB_ERR}, {0,1,0,1}};
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
{ 1, 1, 1, LB_ERR}, {0,0,0,0},
{ 2, 2, 2, LB_ERR}, {0,0,0,0}};
trace (" Testing single selection...\n");
check (SS);