FF_ListView_InsertItem doesn't add sub items

Started by Roger Garstang, July 01, 2004, 06:06:36 AM

Previous topic - Next topic

Roger Garstang

Alright, I came up to another problem now.  I can't get FF_ListView_InsertItem to insert anything in a column to the right of the main column.  It is in Report View, I have 3 Columns- File Name, Size, Modified.  Column names appear, all the filenames appear, no other columns appear.  I even pasted the sample code with the For/Next loops and it only has 0 0 through 10 0 in the first column.  What am I missing?

I also noticed that when the option is selected to allow sub items to have images, the mask for sub items in the function still only allows text.

Roger Garstang

I know something is wrong now.  I went back and found some old listview code I made for a mock Regedit that worked fine and still runs fine in PB.  Copied it over and it does the same thing...only values are in the first column???

Roger Garstang

Well, I still don't know why it isn't working right, but if I run it then call the function again it works???  Both times it already has the column names created, and both times it deletes all the items and adds them back.  First time it runs it is only putting the main item on the left, but after I call it again it is putting all of them.  I never had to do that before.

One other weird thing I noticed is that none of the generated files FF makes seem to have any data that FindFirstFile can return.  FindFirstFile returns the name, but no size info.

TechSupport

Roger,

Can you post a snippet of code that you are using? I have used the FF_ListView_InsertItem with no trouble.

Roger Garstang

Called in form's WM_CREATE, when F5 is pressed in the list, and when selecting a new folder.  F5= RefreshFileList(""), New Folder= RefreshFileList(FF_BrowseForFolder(HWND_HTML, "Select a Folder to Share From", CurDir$), WM_CREATE= RefreshFileList(CurDir$).  BaseDir is a Global string.  Press F5 or select another folder and the size appears fine.


Function RefreshFileList(ByVal SearchString As String) As Long
   Local msg As tagMsg
   Local searchHandle As Dword
   Local row As Dword
   Local foundFile As WIN32_FIND_DATA
   Local fileSize As QuadTime ' Tacky, but reusing a FILETIME Union I made
   Local searchDir As Asciiz * %MAX_PATH
   Static instance As Dword
   
   If instance= 0 Then
       SendMessage(HWND_HTML_FILELIST, %LVM_DELETEALLITEMS, 0, 0)
       If Len(SearchString)= 0 Then SearchString= BaseDir Else BaseDir= SearchString
   End If
   Incr instance

   searchDir= SearchString + "\"
   searchHandle= FindFirstFile(searchDir + "*.*", foundFile)
   If searchHandle <> %INVALID_HANDLE_VALUE Then
   Do
       If (foundFile.dwFileAttributes And %FILE_ATTRIBUTE_DIRECTORY)= 0 Or foundFile.cFileName= "." Then
           If (Len(searchDir) - Len(BaseDir) + Len(foundFile.cFileName)) < (%MAX_PATH - 1) Then
               row= SendMessage(HWND_HTML_FILELIST, %LVM_GETITEMCOUNT, 0, 0)
               FF_ListView_InsertItem (HWND_HTML_FILELIST, row, 0, Right$(searchDir, Len(searchDir) - Len(BaseDir)) + foundFile.cFileName, 0, 0)
               fileSize.Parts.dwHighDateTime= foundFile.nFileSizeHigh
               fileSize.Parts.dwLowDateTime= foundFile.nFileSizeLow
               FF_ListView_InsertItem (HWND_HTML_FILELIST, row, 1, Format$(fileSize.Whole), 0, 0)
           End If
       ElseIf foundFile.cFileName <> ".." Then
           RefreshFileList(searchDir + foundFile.cFileName)
       End If
   Loop While FindNextFile(searchHandle, foundFile)
   Else
       MsgBox "Could not search " + searchDir, %MB_ICONWARNING Or %MB_TASKMODAL, "Search Error"
   End If
   FindClose(searchHandle)
       
   Decr instance
   Do While PeekMessage(Msg, %Null, 0, 0, %PM_REMOVE)
       TranslateMessage Msg
       DispatchMessage Msg
   Loop
End Function


It is still a work in progress, but you get the idea.  Having the list set to Sort Ascending doesn't seem to hurt the row, because it still adds the sub items to the correct columns/rows.  If it is Sort Ascending can I just insert everything at row 0?  I believe that is what I did in my mock regedit app.  I may end up using threads or something so I don't run out of stack space.

Roger Garstang

In my Regedit mockup I had a sub like below so I could add to row 0 in a list that was sorted and get the subitems to add right, maybe you could modify the FF_function to allow for something like this.


SUB AddItemToList(BYVAL hCtl AS DWORD, BYVAL lstItem AS STRING, BYVAL lstType AS STRING, BYVAL lstData AS STRING)
  LOCAL tLVI    AS LV_ITEM
  LOCAL szBuf   AS ASCIIZ * 64

  IF INSTR(lstType, "SZ") THEN tLVI.iImage= 3 ELSE tLVI.iImage= 4

  'Load data.
     tLVI.pszText    = VARPTR(szBuf)
     tLVI.iItem      = 0
     szBuf           = lstItem
     tLVI.iSubItem   = 0
     tLVI.mask       = %LVIF_TEXT OR %LVIF_IMAGE

     tLVI.iItem      = ListView_InsertItem(hCtl, tLVI)
     tLVI.iSubItem   = 1
     szBuf           = lstType
     tLVI.mask       = %LVIF_TEXT
     ListView_SetItem hCtl, tLVI

     tLVI.iSubItem   = 2
     szBuf           = lstData
     tLVI.mask       = %LVIF_TEXT
     ListView_SetItem hCtl, tLVI
END SUB  

Roger Garstang

I found my problem.   :oops:  When I moved my column header lines to WM_CREATE I forgot to put them before the call to Refresh the file list.

Going off of my Regedit function I said above though:


FUNCTION FF_ListView_InsertItem (BYVAL hWndControl AS DWORD, _
                                BYVAL iRow    AS LONG, _        
                                BYVAL iColumn AS LONG, _
                                BYVAL TheText AS STRING, _
                                OPTIONAL BYVAL lParam AS LONG, _
                                OPTIONAL BYVAL iImage AS LONG) AS LONG

LOCAL tlv_item AS LV_ITEM

' Do a check to ensure that this is actually a window handle
IF IsWindow(hWndControl) THEN  
    tlv_item.iItem     = iRow
    tlv_item.iSubItem  = iColumn
    tlv_item.pszText   = STRPTR(TheText)
    tlv_item.iImage    = iImage
    tlv_item.lParam    = lParam
       
    IF iColumn = 0 THEN
       tlv_item.mask      = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_IMAGE
       IF SendMessage( hWndControl, %LVM_INSERTITEM, 0, BYVAL VARPTR(tlv_item)) <> -1 THEN
          FUNCTION = %TRUE
       END IF  
    ELSE
       tlv_item.mask      = %LVIF_TEXT
       FUNCTION = SendMessage( hWndControl, %LVM_SETITEM, 0, BYVAL VARPTR(tlv_item))
    END IF
END IF
END FUNCTION    


Should be:

FUNCTION FF_ListView_InsertItem (BYVAL hWndControl AS DWORD, _
                                BYVAL iRow    AS LONG, _        
                                BYVAL iColumn AS LONG, _
                                BYVAL TheText AS STRING, _
                                OPTIONAL BYVAL lParam AS LONG, _
                                OPTIONAL BYVAL iImage AS LONG) AS LONG

 LOCAL tlv_item AS LV_ITEM

 ' Do a check to ensure that this is actually a window handle
 IF IsWindow(hWndControl) THEN  
   tlv_item.iItem     = iRow
   tlv_item.iSubItem  = iColumn
   tlv_item.pszText   = STRPTR(TheText)
   tlv_item.iImage    = iImage
   tlv_item.lParam    = lParam
       
   IF iColumn = 0 THEN
     tlv_item.mask      = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_IMAGE
     FUNCTION = SendMessage( hWndControl, %LVM_INSERTITEM, 0, BYVAL VARPTR(tlv_item))
   ELSE
     tlv_item.mask      = %LVIF_TEXT
     FUNCTION = SendMessage( hWndControl, %LVM_SETITEM, 0, BYVAL VARPTR(tlv_item))
   END IF
 END IF
END FUNCTION    


That way it returns the row or -1 just like the Column insert, and I can then use the returned value to set the subitems like I do in my function since when they are sorted it may not insert where one would expect...I'm guessing I was just lucking out before since it was reading the folder in order.

There may still need to be something added to set the image on subitems when the option to enable it is set.

And, why does the Double click Activate option underline them like a link?  How do I make it look like plain old Explorer style, where they are just highlighted without underline or hand pointer and double clicking sends a message?