Edit a cell in a ListView?

Started by John Montenigro, June 26, 2015, 04:03:01 PM

Previous topic - Next topic

John Montenigro

I have a dialog that contains a ListView, in which the first 5 columns display product data, and the last 3 are:
   UnitPrice
   Quantity
   ExtendedPrice

The UnitPrice column gets populated according to option buttons CustomerType. After the user enters the Quantity, the program will calculate the ExtendedPrice.

All cells are not-editable, but I need to allow the user to edit the Quantity column.

I've tried a bunch of things, but I cannot find any way to allow this.

Any help would be greatly appreciated!

Thanks,
-John

Klaas Holland

Look at this example closely.

Klaas

John Montenigro

#2
Thanks Klass!

When I run the .EXE (from cmd.exe, or from within FF), I have a very hard time getting the edit-textbox to become available. It does NOT show up with a click or a double-click; I cannot just click in the cell that I want to edit.

The only way I have found that lets me edit the cell, is to position the mouse pointer one or two pixels to the right of the grid line and then single-click. Click anywhere else and the textbox does not open up.

And then, if I move the mouse at all, it obliterates any characters I was able to type. I have to be VERY careful to type (and CAREFULLY press ENTER); with the slightest mouse movement, I lose the text I typed.

So, I have started to study the code, and it's more complex than anything I've ever coded. (For example, I have never even looked at the FF_PumpHook functions!)

So, I will be studying it for a few days, to be sure! Eventually, I'm sure I will come to understand how it works. I just need some time to absorb it all. And, I'm sure that I will have some questions!

Thank you for sharing this!
-John

Petrus Vorster

There were a few recent posts on this topic.
Regrettably the Listview is what is says VIEW only.
Klaas had made a solution which I think is one of the best around.

But yes, we desperately need a control like a listview where you can easily enter and change info like a Gridcontrol.
But with the recent move to Freebasic I dont see anyone willing to create new controls for Powerbasic.
It would be a nice project though......
-Regards
Peter

Wilko Verweij

I managed to use a textbox in combination with the listview to allow editing. Thanks to several posts here. I will try to strip the code to the smallest example that works and post it here. Give me some time.

Wilko Verweij

OK, here we go. Not perfect (see below) but it works. The steps that you need are basically:

  • create a new project
  • the name of the form can be left Form1
  • create a listview with default properties and name it LB
  • create a textbox, default properties except that it is NOT visible; name it TB
  • in the form-create event, fill the listview with some dummy data
  • in the form-notify event, detect the click
  • create a SUB called HandleClick to start editing
  • in the KILLFOCUS event, finish editing

Code looks like this:
'--------------------------------------------------------------------------------
Function FORM1_WM_CREATE ( _
                         hWndForm As Dword, _      ' handle of Form
                         ByVal UserData As Long _  ' optional user defined Long value
                         ) As Long

  Local Col As Long
  Local Row As Long

  'put some info in the listview
  For Col = 1 To 4
    FF_ListView_InsertColumn(HWND_FORM1_LV, Col - 1, "Column" & Format$(Col), %LVCFMT_CENTER, 100)
  Next Col
  For Col = 1 To 4
    For Row = 1 To 20
      FF_ListView_InsertItem( HWND_FORM1_LV, Row - 1 , Col - 1, "T-C" & Format$(Col) & "-R"& Format$(Row))
    Next Row
  Next Col

End Function
'--------------------------------------------------------------------------------
Function FORM1_WM_NOTIFY ( _
                         hWndForm     As Dword,     _  ' handle of Form
                         idCtrl       As Dword,     _  ' control ID
                         ByVal pNMHDR As NMHDR Ptr  _  ' pointer to NMHDR structure
                         ) As Long

  Local Col As Long
  Local DwPos As Dword
  Local I As Long
  Local LpLvNm As NM_LISTVIEW Ptr
  Local P_Info As LV_HitTestInfo
  Local Rc As Rect
  Local Row As Long
 
  Select Case @pNMHDR.idFrom
    Case IDC_FORM1_LV
      LpLvNm = pNMHDR
      Select Case @LpLvNm.hdr.Code
        Case %NM_CLICK 'left click
          DwPos = GetMessagePos()
          'first get screen position in screen coordinates
          P_Info.pt.x = LOWORD(DwPos)
          P_Info.pt.y = HIWORD(DwPos)
         
          'convert to list-view coordinates
          ScreenToClient(HWND_FORM1_LV, P_Info.pt)
         
          'where hit?
          ListView_SubItemHitTest(HWND_FORM1_LV, P_Info)

          If P_Info.iItem = -1 Then 'first column
            Col = 1 '1-based
            For I = 0 To FF_ListView_GetItemCount(HWND_FORM1_LV)
              ListView_GetItemRect(HWND_FORM1_LV, I, Rc, %LVIR_BOUNDS)
              If Rc.nTop > P_Info.pt.y Then
                Row = I
                Exit For
              End If
            Next I
            If Row = 0 Then Row = FF_ListView_GetItemCount(HWND_FORM1_LV)
          Else 'second or further column
            Col = P_Info.iSubItem + 1 
            Row = P_Info.iItem + 1
          End If
          Call HandleClick(Col, Row)
      End Select
  End Select

End Function
'--------------------------------------------------------------------------------
Sub HandleClick(ByVal Col As Long, ByVal Row As Long)

  Local Left4TxtB As Long
  Local Rc As Rect
  Local Top4TxtB As Long
  'ztrace "clicked in col" & Str$(Col) & " in row " & Str$(Row)

  'first set text box to match text in listview
  FF_Control_SetText(HWND_FORM1_TB, FF_ListView_GetItemText(HWND_FORM1_LV, Row - 1, Col - 1))
 
   'determine left and top of cell over which text box should be placed
  ListView_GetSubItemRect(HWND_FORM1_LV, Row - 1, Col - 1, %LVIR_BOUNDS, Rc)
  FF_Control_GetLoc(HWND_FORM1_LV, Left4TxtB, Top4TxtB)
  Left4TxtB = Left4TxtB + rc.nLeft + 3
  Top4TxtB = Top4TxtB + rc.nTop + 2
  'put text box there
  FF_Control_SetLoc(HWND_FORM1_TB, Left4TxtB, Top4TxtB)
 
  'then size
  FF_Control_SetSize(HWND_FORM1_TB, Rc.nRight - Rc.nLeft - 1, Rc.nBottom - Rc.nTop - 1)
  FF_Control_ShowState(HWND_FORM1_TB, %SW_SHOW)
  FF_Control_Enable(HWND_FORM1_TB)
  'without next line, two clicks are needed
  FF_Control_Redraw(HWND_FORM1_LV)
  BringWindowToTop(HWND_FORM1_TB)
  FF_Control_SetFocus(HWND_FORM1_TB)

  'now editing starts...
 
  'store Col and Row in Prop
  SetProp(HWND_FORM1, "Col", Col)
  SetProp(HWND_FORM1, "Row", Row)

End Sub
'--------------------------------------------------------------------------------
Function FORM1_TB_EN_KILLFOCUS ( _
                               ControlIndex   As Long,  _  ' index in Control Array
                               hWndForm       As Dword, _  ' handle of Form
                               hWndControl    As Dword, _  ' handle of Control
                               idTextControl  As Long   _  ' identifier of text control
                               ) As Long
 
  Local Col As Long
  Local NewTextInTextBox$
  Local Row As Long
 
  NewTextInTextBox$ = FF_Control_GetText(HWND_FORM1_TB)
 
  'read Col and Row from Prop
  Col = GetProp(HWND_FORM1, "Col")
  Row = GetProp(HWND_FORM1, "Row")
 
  'copy text from text box to listview
  FF_ListView_SetItemText(HWND_FORM1_LV, Row - 1, Col - 1, NewTextInTextBox$)

  'hide the text box
  FF_Control_ShowState(HWND_FORM1_TB, %SW_HIDE)

End Function


There are two drawbacks:

  • if you click in the first column, the texxtbox is set not the cell but to the entire row
  • if the last column is partly visible, the textbox will extend beyond the scrollbar

Anyway, I hope this gets you started.
BTW it's not my invention but compiled from what others posted here. Can be modified to host combo boxes as well.
Wilko

John Montenigro

Wow, that step-by-step explanation is SO helpful!

I was getting kinda lost in the other code, not being sure about the impact of the "lost focus" parts...

This makes it very clear, and I appreciate your help very much!!!!

-John

John Montenigro

Hi Petrus,
The other day, I read on the PB forum that Dominic Mitchell is releasing a grid soon. I don't know how well it will integrate with FF, but I'm looking forward to exploring it.
I'll post here if/when I get some experience with it.
-John

Rolf Brandt

Rolf Brandt
http://www.rbsoft.eu
http://www.taxifreeware.com
I cook with wine, sometimes I even add it to the food.
(W. C. Fields)