Good question: bytes to allocate for the strings? I've tested it with varying average string lengths:
SetListbox L$(), c
len:85 ; reset content, then reload with assumed average string len
For 85 bytes, it takes 133 ms to load the 10MB listbox; for 75 bytes, it takes a whopping 5000 ms 8)
So with no options, I calculate the average len of the first 127 strings, add a few bytes, multiply with #elements and use the result for lParam:
push ecx ; #elements in string array
xor ecx, ecx
xor edi, edi
.Repeat
push ecx ; index of element
push arg ; array ID
call MbArrayGet
add edi, Len(eax)
inc ecx
.Until ecx>127 || ecx>stack
xchg eax, edi
add eax, 127
cdq
idiv ecx
inc eax
inc eax
mov ecx, stack
inc ecx
mul ecx
invoke SendMessage, GuiLB, LB_INITSTORAGE, ecx, eax
And that works like a charm - slightly above the fastest point.
Don't ask me
why that works, though. My
Recall() converts to UTF-8, so the average string len is an ASCII value,
but:invoke SendMessageW, GuiLB, LB_ADDSTRING, 0, wRec$(eax) ; UNICODE
And that supports your theory that lParam refers to chars. Messy...