Otrebor wrote:@Danilo
Your code works great!
But when i try to use with virtual ListIcon, i can not get it to work.
With a virtual ListIcon, you need to handle the #LVN_ODFINDITEM notification within your callback.
The message #LVM_GETTOPINDEX does not work anymore with virtual ListIcon (always returns 0),
so we also need to change the scrolling stuff.
A bit complicated, but I hope it works for you:
Code: Select all
;... Use 1000000 items
#ItemCount = 60000
#LVSICF_NOINVALIDATEALL = 1
#LVN_ODCACHEHINT = #LVN_FIRST - 13
;... Array to hold data
Global Dim myItems.s(#ItemCount,1)
Procedure WinCallback(hwnd, msg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*pnmh.NMHDR = lParam
Select *pnmh\code
Case #LVN_ODCACHEHINT, #LVN_ODSTATECHANGED
result = 0
Case #LVN_GETDISPINFO
*pnmlvdi.NMLVDISPINFO = lParam
If *pnmlvdi\item\mask & #LVIF_TEXT
;... Item text is being requested
*pnmlvdi\item\pszText = @myItems(*pnmlvdi\item\iItem,0);*pnmlvdi\item\iSubItem)
EndIf
Case #LVN_ODFINDITEM
result = -1
Protected *nmlvfinditem.NMLVFINDITEM = lParam
If *nmlvfinditem And *nmlvfinditem\lvfi\psz
Protected text.s = PeekS(*nmlvfinditem\lvfi\psz)
For i=0 To #ItemCount
If myItems(i,0) = text
result = i
Break
EndIf
Next i
EndIf
EndSelect
EndSelect
ProcedureReturn result
EndProcedure
Procedure FindLI(gadget, text.s)
Protected pos, rect.RECT
Protected item.LVFINDINFO
item\flags = #LVFI_STRING ;| #LVFI_PARTIAL
item\psz = @text
pos = SendMessage_(GadgetID(gadget), #LVM_FINDITEM, -1, @item)
If pos <> -1
;SendMessage_(GadgetID(gadget), #LVM_ENSUREVISIBLE,pos,0)
header = SendMessage_(GadgetID(gadget),#LVM_GETHEADER,0,0) ; get header control
GetClientRect_(header,headerRect.RECT) ; get size of header control
SendMessage_(GadgetID(gadget), #LVM_GETITEMRECT, 0 , @rect) ; get rect for item 0
SendMessage_(GadgetID(gadget), #LVM_SCROLL, 0, rect\top-headerRect\bottom) ; scroll to item 0 (minus header height)
SendMessage_(GadgetID(gadget), #LVM_GETITEMRECT, pos, @rect) ; get rect for our item
SendMessage_(GadgetID(gadget), #LVM_SCROLL, 0, rect\top-headerRect\bottom) ; scroll to our item (minus header height)
EndIf
EndProcedure
OpenWindow(0, 0, 0, 300, 300,"Listview example",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
SetWindowCallback(@WinCallback())
StringGadget(2,230,10,60,20,"",#PB_String_Numeric)
ButtonGadget(3,230,40,60,20,"SEARCH")
; left column
ListIconGadget(1,10,10,200,280,"ID",100,#LVS_OWNERDATA)
;... Set desired number of ListIconGdaget items
SendMessage_(GadgetID(1), #LVM_SETITEMCOUNT, #ItemCount, #LVSICF_NOINVALIDATEALL)
AddGadgetColumn(1,2,"Name",10)
For i=0 To #ItemCount
myItems(i,0) = RSet(Str((i)),5,"0")
;myItems(i,1) = ""
Next i
; Here we change the ListIcon display to large icons and show an image
;SetWindowCallback(0)
Repeat
Event = WaitWindowEvent()
gadgetID = EventGadget()
If Event = #PB_Event_Gadget
If gadgetID = 3
find.s = RSet(GetGadgetText(2),5,"0")
FindLI(1, find)
;Debug "I need to show at the top of ListViewGadgeget, the number found"
ElseIf gadgetID = 2 And EventType() = #PB_EventType_Change
find.s = RSet(GetGadgetText(2),5,"0")
FindLI(1, find)
EndIf
EndIf
Until Event = #PB_Event_CloseWindow