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
Look at this example closely.
Klaas
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
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......
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.
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
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
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
How about MyLittleGrid? It offers cell editing.
http://www.planetsquires.com/mylittlegrid.html
Rolf