ListItems.Tag?

The place for threads about TimoSoft ExplorerListView.
Post Reply
ufo973
Lieutenant
Posts: 12
Joined: 09 Aug 2012, 22:45

ListItems.Tag?

Post by ufo973 »

Hi,
For somereasons i can't use global variables and i have to save some save variables into ListItems.Tag to retrieve later. but in ExplorerListView there is no such thing like ListItems.Tag?
Is there any work around? like hiding the data in another column and hide it so it is not visible to the user or something?
User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: München
Contact:

Re: ListItems.Tag?

Post by TiKu »

You can use the ItemData property of the ListItem class.
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!
ufo973
Lieutenant
Posts: 12
Joined: 09 Aug 2012, 22:45

Re: ListItems.Tag?

Post by ufo973 »

In ItemData i can only add integer and long. but i can't add strings to itemData?
If you can give me an example please. reply fast please...
User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: München
Contact:

Re: ListItems.Tag?

Post by TiKu »

A Long is sufficient to store ANY data. Changing it to Variant would increase the control's memory consumption significantly.

Here are three functions that can be used to store a string in ItemData:

Code: Select all

  Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByVal pDest As Long, ByVal pSrc As Long, ByVal sz As Long)
  Private Declare Function GetProcessHeap Lib "kernel32.dll" () As Long
  Private Declare Function HeapAlloc Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
  Private Declare Function HeapFree Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal lpMem As Long) As Long

    Private Function GetItemTag(ByVal lvItem As ExLVwLibUCtl.IListViewItem) As String
      Dim pMem As Long
      Dim s As String
      Dim sz As Long
     
      If Not (lvItem Is Nothing) Then
        pMem = lvItem.ItemData
        If pMem Then
          CopyMemory VarPtr(sz), pMem, 4
          s = String$(sz / 2, Chr$(0))
          CopyMemory StrPtr(s), pMem + 4, sz
        End If
      End If
      GetItemTag = s
    End Function
     
     
    Private Sub FreeItemTag(ByVal lvItem As ExLVwLibUCtl.IListViewItem)
      If Not (lvItem Is Nothing) Then
        If lvItem.ItemData <> 0 Then
          HeapFree GetProcessHeap(), 0, lvItem.ItemData
          lvItem.ItemData = 0
        End If
      End If
    End Sub
     
    Private Sub SetItemTag(ByVal lvItem As ExLVwLibUCtl.IListViewItem, ByVal Tag As String)
      Const HEAP_ZERO_MEMORY = &H8
      Dim pMem As Long
      Dim sz As Long
     
      If Not (lvItem Is Nothing) Then
        If lvItem.ItemData <> 0 Then FreeItemTag lvItem
     
        sz = LenB(Tag)
        pMem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz + 4)
        If pMem Then
          CopyMemory pMem, VarPtr(sz), 4
          CopyMemory pMem + 4, StrPtr(Tag), sz
          lvItem.ItemData = pMem
        End If
      End If
    End Sub
Additionally you need to handle the FreeItemData event (don't forget to activate it):

Code: Select all

    Private Sub ExplorerListView1_FreeItemData(ByVal listItem As ExLVwLibUCtl.IListViewItem)
      If Not listItem Is Nothing Then
        FreeItemTag listItem
      End If
    End Sub
And into the Form's Unload event you should put:

Code: Select all

  ExplorerListView1.ListItems.RemoveAll
Now, for instance, instead of using lvItem.ItemData = 123, you call SetItemTag(lvItem, "123"). However, you should no longer access ItemData directly. Use the functions instead. Otherwise you'll run into memory leaks and crashes.
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!
ufo973
Lieutenant
Posts: 12
Joined: 09 Aug 2012, 22:45

Re: ListItems.Tag?

Post by ufo973 »

I am sorry i don't want such a long and complicated process just to store some string data into listitem.
Is there any alternative like adding a new column and hiding it from the user and use that column to add data to the listviewitem or something else?
I was usually storing info regarding the item into the item's tag. it was very easy process but unfortunately your listview lack tag :(
User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: München
Contact:

Re: ListItems.Tag?

Post by TiKu »

ufo973 wrote:I am sorry i don't want such a long and complicated process just to store some string data into listitem.
Well, you asked for a solution and this is the solution that I recommend if you cannot avoid strings at all. It's pretty much the same as how C/C++ applications do it.
ufo973 wrote:Is there any alternative like adding a new column and hiding it from the user and use that column to add data to the listviewitem or something else?
Do you want to develop a software or do you want to hack things together? Using a "hidden" column for such purpose isn't anything that someone, who wants to call himself a software developer, would use. Also a column cannot really be hidden. If you set its width to 0, the user will still be able to resize it to any other width (as long as you allow column resizing).
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!
ufo973
Lieutenant
Posts: 12
Joined: 09 Aug 2012, 22:45

Re: ListItems.Tag?

Post by ufo973 »

TiKu wrote: Additionally you need to handle the FreeItemData event (don't forget to activate it):

Code: Select all

    Private Sub ExplorerListView1_FreeItemData(ByVal listItem As ExLVwLibUCtl.IListViewItem)
      If Not listItem Is Nothing Then
        FreeItemTag listItem
      End If
    End Sub
What is this? and how to activate it?
TiKu wrote: And into the Form's Unload event you should put:

Code: Select all

  ExplorerListView1.ListItems.RemoveAll
what happens if i don't put this in form's unload event?
User avatar
TiKu
Administrator
Administrator
Posts: 832
Joined: 28 Sep 2004, 21:10
Location: München
Contact:

Re: ListItems.Tag?

Post by TiKu »

ufo973 wrote:
TiKu wrote: Additionally you need to handle the FreeItemData event (don't forget to activate it):

Code: Select all

    Private Sub ExplorerListView1_FreeItemData(ByVal listItem As ExLVwLibUCtl.IListViewItem)
      If Not listItem Is Nothing Then
        FreeItemTag listItem
      End If
    End Sub
What is this? and how to activate it?
You activate the event by removing it from the DisabledEvents. You already did the same with the Click and DblClick events.
The code that I've posted, reserves memory (using HeapAlloc) and copies the string that you want to associate with the item into this memory (using CopyMemory). Then it stores the address of this memory into the ItemData property. To retrieve the string from ItemData, the code takes the memory address stored in ItemData and copies the string that is stored at this address (again using CopyMemory).
Since the code reserved memory, it also needs to free this memory (using HeapFree) when it is no longer required - e.g. when the item is removed from the control. Otherwise your application will leak memory. This is done in the FreeItemData event. The FreeItemData event is raisded if any data associated with an item should be freed because the item is being removed.
ufo973 wrote:
TiKu wrote: And into the Form's Unload event you should put:

Code: Select all

  ExplorerListView1.ListItems.RemoveAll
what happens if i don't put this in form's unload event?
When the form is closed, the list view control will be destroyed. However, the control cannot raise the FreeItemData event anymore, because VB6 already has reached a state during form destruction at which it no longer handles any events. And as I wrote above you'll need the FreeItemData event if you don't want your application to leak memory. Therefore you need to remove the list view items manually as long as the FreeItemData event still works.
Crunching for Fab36_Folding-Division at Folding@Home. Join Fab36/Fab30! - Folding@Home and BOINC
Boycott DRM! Boycott HDCP!
ufo973
Lieutenant
Posts: 12
Joined: 09 Aug 2012, 22:45

Re: ListItems.Tag?

Post by ufo973 »

Oh i got it now. thank you very much for explaining so well :)
Post Reply