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.
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???
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.
Roger,
Can you post a snippet of code that you are using? I have used the FF_ListView_InsertItem with no trouble.
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.
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
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?