comctl32/listbox: Implement LBS_NODATA for single-selection listboxes.
The LBS_NODATA style's purpose is to drastically improve performance and memory usage on very large lists, since they should function as virtual lists. Thus, don't store any data for single-selection listboxes (descr->items always NULL). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=32374 Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e98d4b4502
commit
1b7886edaf
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - LBS_NODATA
|
||||
* - LBS_NODATA for multi-selection listboxes
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -135,17 +135,20 @@ static BOOL resize_storage(LB_DESCR *descr, UINT items_size)
|
|||
items_size + LB_ARRAY_GRANULARITY * 2 < descr->items_size)
|
||||
{
|
||||
items_size = (items_size + LB_ARRAY_GRANULARITY - 1) & ~(LB_ARRAY_GRANULARITY - 1);
|
||||
items = heap_realloc(descr->items, items_size * sizeof(LB_ITEMDATA));
|
||||
if (!items)
|
||||
if ((descr->style & (LBS_NODATA | LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != LBS_NODATA)
|
||||
{
|
||||
SEND_NOTIFICATION(descr, LBN_ERRSPACE);
|
||||
return FALSE;
|
||||
items = heap_realloc(descr->items, items_size * sizeof(LB_ITEMDATA));
|
||||
if (!items)
|
||||
{
|
||||
SEND_NOTIFICATION(descr, LBN_ERRSPACE);
|
||||
return FALSE;
|
||||
}
|
||||
descr->items = items;
|
||||
}
|
||||
descr->items_size = items_size;
|
||||
descr->items = items;
|
||||
}
|
||||
|
||||
if ((descr->style & LBS_NODATA) && items_size > descr->nb_items)
|
||||
if ((descr->style & LBS_NODATA) && descr->items && items_size > descr->nb_items)
|
||||
{
|
||||
memset(&descr->items[descr->nb_items], 0,
|
||||
(items_size - descr->nb_items) * sizeof(LB_ITEMDATA));
|
||||
|
@ -190,6 +193,8 @@ static void insert_item_data(LB_DESCR *descr, UINT index, WCHAR *str, ULONG_PTR
|
|||
{
|
||||
LB_ITEMDATA *item;
|
||||
|
||||
if (!descr->items) return;
|
||||
|
||||
item = descr->items + index;
|
||||
if (index < descr->nb_items)
|
||||
memmove(item + 1, item, (descr->nb_items - index) * sizeof(LB_ITEMDATA));
|
||||
|
@ -204,6 +209,8 @@ static void remove_item_data(LB_DESCR *descr, UINT index)
|
|||
{
|
||||
LB_ITEMDATA *item;
|
||||
|
||||
if (!descr->items) return;
|
||||
|
||||
item = descr->items + index;
|
||||
if (index < descr->nb_items)
|
||||
memmove(item, item + 1, (descr->nb_items - index) * sizeof(LB_ITEMDATA));
|
||||
|
@ -1762,7 +1769,8 @@ static void LISTBOX_ResetContent( LB_DESCR *descr )
|
|||
{
|
||||
INT i;
|
||||
|
||||
for(i = descr->nb_items - 1; i>=0; i--) LISTBOX_DeleteItem( descr, i);
|
||||
if (!(descr->style & LBS_NODATA))
|
||||
for (i = descr->nb_items - 1; i >= 0; i--) LISTBOX_DeleteItem(descr, i);
|
||||
HeapFree( GetProcessHeap(), 0, descr->items );
|
||||
descr->nb_items = 0;
|
||||
descr->top_item = 0;
|
||||
|
|
Loading…
Reference in New Issue