From: Gabriel Ivăncescu gabrielopcode@gmail.com
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 --- dlls/comctl32/listbox.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index e89d25761e..cbe57f2616 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -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;