Hi All,
Is there a way to hide a listview column from the user, I have tried setting the width to 0 but the user can still expand the column.
Many Thanks
Hi John,
I am pretty sure that there is no easy way to hide the column (other than setting the width to zero). The probelm, as you have noticed, is that the user can resize the column.
I expect that you are trying to hide data that you will need to refer to when a user clicks on a line in the ListView. If so, then a better approach would be to manually allocate the data to the line via FF_ListView_SetItemlParam
If the data that you want to save is a Long/DWord then you can simply save the value in the lParam. If you need to save more data, then you will need to create a TYPE structure, manually allocate memory, create a pointer to that structure and then store the pointer in the lParam. When a user clicks on the line then you would retrieve the lParam and dereference the pointer to the TYPE. When the ListView is destroyed you will need to free the memory that you created. This probably sounds more complicated than it really is.
Is this what you want to do? If so, then I'll put together some code for you.
That is exactly it, code most welcome.
No problem.... this is a generic example. The code can be placed in various areas of your project depending on your need. Once you get used to manually creating and destroying memory, you'll find that it is easy to create arrays in TYPE's that don't waste memory, etc.... Lots of uses for it. It also helps you to understand pointers.
Put the following at the start of your Form or in a separate Module.
Type COMPANY_TYPE
CompanyID As Asciiz * 100
'... you could put as many elements here as you like
End Type
Function MemAlloc( ByVal nSize As Dword ) As Long
If nSize = 0 Then Exit Function
Function = HeapAlloc( GetProcessHeap(), %HEAP_ZERO_MEMORY, nSize )
End Function
Function MemFree( ByVal pMem As Long ) As Long
If pMem = 0 Then Exit Function
HeapFree GetProcessHeap(), 0, ByVal pMem
Function = 1
End Function
The following should be placed in the section of your code where you are creating your ListView. In my case, I simply put it in the WM_CREATE message for the Form.
'Create a pointer that will reference our data.
Local pCompany As COMPANY_TYPE Ptr
'Create the ListView
FF_ListView_DeleteAllItems HWND_FORM1_LISTVIEW1
FF_ListView_InsertColumn HWND_FORM1_LISTVIEW1, 0, "Order Number", 0, 100
FF_ListView_InsertColumn HWND_FORM1_LISTVIEW1, 1, "Company Name", 0, 200
FF_ListView_InsertColumn HWND_FORM1_LISTVIEW1, 2, "Address", 0, 100
For row& = 0 To 10
'Create your data
pCompany = MemAlloc( SizeOf(COMPANY_TYPE) ) 'assigns the new memory address to the pointer
@pCompany.CompanyID = "ABC123" & Format$(row&) 'dummy data to represent company id
For col& = 0 To 2
FF_ListView_InsertItem HWND_FORM1_LISTVIEW1, row&, col&, Str$(row&) & Str$(col&), pCompany, 0
Next
Next
Whenever you need to get the data that you stored you would simply retrieve the lParam into a COMPANY_TYPE pointer and reference the data. I did it in response to someone clicking a CommandButton.
Local CurRow As Long
Local pCompany As COMPANY_TYPE Ptr
CurRow = FF_ListView_GetSelectedItem(HWND_FORM1_LISTVIEW1)
pCompany = FF_ListView_GetItemlParam(HWND_FORM1_LISTVIEW1, CurRow, 0)
If pCompany Then
MsgBox "Company ID for row" & Str$(CurRow) & " is " & @pCompany.CompanyID
End If
Lastly, you should destroy the manually created data in order to avoid memory leaks.
In WM_DESTROY, put the following:
Local NumItems As Long
Local x As Long
Local MemAddress As Dword
'Deallocate our manually created memory
NumItems& = FF_ListView_GetItemCount( HWND_FORM1_LISTVIEW1)
For x& = 0 To NumItems& - 1
MemAddress = FF_ListView_GetItemlParam( HWND_FORM1_LISTVIEW1, x&, 0)
MemFree MemAddress
Next
Lastly, if you only want to dynamically store a string instead of a whole TYPE variable, then you can allocate the memory using MemAllocByVal rather than MemAlloc.
For example:
FUNCTION MemAllocByVal( BYVAL sData AS STRING ) AS DWORD
DIM pData AS DWORD
sData = sData & $Nul
pData = MemAlloc( LEN( sData ) )
IF pData > 0 THEN POKE$ pData, sData
FUNCTION = pData
END FUNCTION
The to get the string you would do this:
Local pzString As ASCIIZ ptr
pzString = FF_ListView_GetLparam(.....)
If pzString then
MsgBox @pzString
End If
You will still need to destroy the memory:
MemFree pzString
Hope this helps. :)
Thanks Paul, the code is a great help.
Just as a follow up to this, I have tried to work out how to capture when the user resizes the column. With out any luck. I am only trying to work this out as another exercise in using the windows api. If anyone can help me out, I would be grateful.