PlanetSquires Forums

Support Forums => Other Software and Code => Topic started by: John Messingham on November 13, 2004, 05:17:19 PM

Title: Listview columns
Post by: John Messingham on November 13, 2004, 05:17:19 PM
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
Title: Listview columns
Post by: TechSupport on November 14, 2004, 11:12:59 AM
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.
Title: Listview columns
Post by: John Messingham on November 14, 2004, 11:20:26 AM
That is exactly it, code most welcome.
Title: Listview columns
Post by: TechSupport on November 14, 2004, 12:22:52 PM
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.  :)
Title: Listview columns
Post by: John Messingham on November 14, 2004, 01:25:04 PM
Thanks Paul, the code is a great help.
Title: Listview columns
Post by: John Messingham on November 19, 2004, 08:03:22 PM
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.