Heya, sicne i want to handle large amount of data, it seems that normal ListView is not capable for doing the job quickly..
my current ListView does not have the handle of OWNER DATA (i can add it in the resource editor - where i create my listview)
so i wonder if someone here has a small example on how to handle virtual listview ?
thnx
Posted on 2003-08-19 04:36:21 by wizzra
hm.. i got it to work, but 1 more question..
for every sub item / item do i need to create diffrent text buffer ?
if i use same buffer to hold the text, it will override the whole items with the same text it holds...

i did a simple C test:


switch(nmdisp->item.iSubItem)
{
case 0:nmdisp->item.pszText=Buffer;break;
case 1:nmdisp->item.pszText=Buffer;break;
case 2:nmdisp->item.pszText=Buffer;break;
case 3:nmdisp->item.pszText=Buffer;break;
case 4:nmdisp->item.pszText=Buffer;break;
case 5:nmdisp->item.pszText=Buffer;break;

}


at initDialog i specify diff text for each sub item..but they all get the same text in the end..

the test i did is:


for(DWORD in=0; in<1000000;in++)
{
LvItem.iItem=in; // choose item
LvItem.iSubItem=0; // Put in first coluom
LvItem.pszText="Item 0"; // Text to display (can be from a char variable) (Items)
strcpy(Buffer,"Item 0"); // will be used in owner data handler
SendMessage(hList,LVM_INSERTITEM,0,(LPARAM)&LvItem); // Send to the Listview

for(i=1;i<=5;i++) // Add SubItems in a loop
{
LvItem.iSubItem=i;
sprintf(Temp,"SubItem %d",i);
strcpy(Buffer,Temp);
LvItem.pszText=Temp;
SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter etxt to SubItems
}
}



Not only that, i put the code in a thread, and it seems that the listview is stuck for few sec and all the items appears..
at normal listview it is scrolling threw while inserting items...
but i still can't figure how to fix the problem where each item has the same text as the one above him...
Posted on 2003-08-19 05:51:59 by wizzra
Hi wizzra

I think the problem is that the text has to be defined during your LVN_GETDISPINFO handler of the WM_NOTIFY message, instead of during initdialog or elsewhere. This is why a virtual listview can handle thousands of entries and doesn't bog down like a regular listview, the system doesn't have to remember them all but are only updated by *you* for only the *on-screen* items as you scroll the listview up and down.

You can send the LVM_INSERTITEM message in a loop with each item and subitem (text not needed) outside of the WM_NOTIFY handler, but this is only to set up the params for the LVN_GETDISPINFO message. Here's a little code which is a bit scrappy but I hope might explain it better.



; in your initdialog code...

invoke SendMessage, hListView, WM_SETREDRAW, FALSE, 0
; we don't want wm_notify called yet

invoke SendMessage, hListView, LVM_DELETEALLITEMS, 0, 0

mov lvi.iItem,-1 ; set to row -1

LOOP1:

Some test for end of data
jnz eof_found

inc lvi.iItem ; increment to next row

; ----------------------------------
; Insert column items for each row
; ----------------------------------
.while lvi.iSubItem < 5
invoke SendMessage, hListView, LVM_INSERTITEM, 0, ADDR lvi
inc lvi.iSubItem
.endw
mov lvi.iSubItem,0 ; set to column 1

JMP LOOP1 ; repeat for next address
eof_found:

invoke SendMessage, hListView, WM_SETREDRAW, TRUE, 0
; trigger WM_NOTIFY
invoke RedrawWindow, hMainWindow, 0, 0, RDW_UPDATENOW+RDW_INVALIDATE

and the WM_NOTIFY handler


.ELSEIF uMsg==WM_NOTIFY
mov edi, lParam
assume edi:ptr NMHDR

mov eax, hListView

.if [edi].hwndFrom == eax && [edi].code == LVN_GETDISPINFO

assume edi:ptr LV_DISPINFO

.if [edi].item.imask & LVIF_TEXT

;============
; 1st Column
;============

.if [edi].item.iSubItem == 0

; prepare your buffer for the first column item
; row is in [edi].item.iItem

; THIS is where your text is defined and updated
mov [edi].item.pszText, offset globalBuffer

;=============
; 2nd Column
;=============
.elseif [edi].item.iSubItem == 1

;prepare your buffer, call your disasm procs, whatever

mov [edi].item.pszText, offset globalBuffer

;etc...


That's the general idea anyway.. Notice there is no LVM_SETITEM used to insert the subitems. I'm not sure if you NEED to send LVM_INSERTITEM during initdialog for each and every entry in your listview, or only for the items initially expected on-screen. When you later scroll the listview, a new LVN_GETDISPINFO message seems to be generated with the correct iItem/iSubItem parameters which your handler should automatically take care of and update the view. Hope this helps.

Kayaker
Posted on 2003-08-19 11:38:07 by Kayaker
Hi,

LVM_INSERTITEM isnt required at all, just send a LVM_SETITEMCOUNT message and handle the LVN_GETDISPINFO messages

Japheth
Posted on 2003-08-19 12:13:17 by japheth
"...just send a LVM_SETITEMCOUNT message and handle the LVN_GETDISPINFO messages"

Here is a part of my WndProc:


WndProc:
cmp dword ptr [esp+2*4], WM_DESTROY ; uMsg
je MLoopExit ; Exit

cmp dword ptr [esp+2*4], WM_NOTIFY ; uMsg
jne DefWindowProc
mov edx, [esp+4*4] ; lParam
mov ecx, hListView
cmp ecx, [edx].LV_DISPINFO.hdr.hwndFrom
jne DefWindowProc
cmp [edx].NM_LISTVIEW.hdr.code, LVN_GETDISPINFO
jne DefWindowProc
cmp [edx].LV_DISPINFO.item.iSubItem, 0
jne LSubItem_1
test [edx].LV_DISPINFO.item.imask, LVIF_TEXT ; Column 0
mov [edx].LV_DISPINFO.item.iImage, 0
je DefWindowProc
mov ecx, [edx].LV_DISPINFO.item.iItem
mov eax, hMem ; hMem is table with strings addresses
mov eax, [eax+ecx*4]
mov [edx].LV_DISPINFO.item.pszText, eax
jmp DefWindowProc
LSubItem_1: ; Next column
test [edx].LV_DISPINFO.item.imask, LVIF_TEXT
je DefWindowProc
mov ecx, [edx].LV_DISPINFO.item.iItem
......
Posted on 2003-08-19 15:11:04 by lingo12
yeah i got some stuff working, than now the only prob will be where i have enough memory to store over 1,000,000++ items+subItems in memory...
that would be a challenge to optimize any idea?
Posted on 2003-08-19 17:04:18 by wizzra
wow thats a lot of items... max I have had to use sofar is like 1,000- 20,000
Posted on 2003-08-19 17:08:57 by devilsclaw