I have never used a grid control in any of my programs.
(A listview for display of info yes, but not for user inputs)
I have taken a look at mylittlegrid, but can seem to find any related help in the documentation.
Is there some free control out there that one can use where i can change the headers and allow controlled user input in columns and rows?
Peter,
This is not a direct answer to your inquiry, but I thought it worth mentioning. You can use the list view as you do now. When a user performs an action that your program takes as a signal to start edit mode (ie, single click or double-click on an item) you create an edit box over the top of the item and process the input yourself. Not trivial, but doable. There are examples on PB's forums. None use SDK style programming so you would have to convert from DDT. Search for "editable listview".
David
Ok, i can give that a shot, thanks. Sounds workable!
Unless of course i buy the little grid :)
How does users find the registered version?
Something Gary Beene posted on the Pb forums:
'Compilable Example:
#Compiler PBWin 10
#Compile Exe
#Dim All
%Unicode=1
#Include "win32api.inc" 'Jose Roca includes
Enum Equates Singular
IDC_ListView = 500
IDM_Demo
End Enum
Global hDlg, hListView As Dword, SortDirection As Long
Global MaxRow, MaxCol, CurrentRow, CurrentCol, OrigLVProc As Long
Function PBMain() As Long
Dialog New Pixels, 0, "ListView Grid Demo",300,300,400,220, %WS_OverlappedWindow To hDlg
CreateListView
Dialog Show Modal hDlg Call DlgProc
End Function
CallBack Function DlgProc() As Long
Local i,j As Long, pLVDI As LV_DISPINFO Ptr, lplvcd As NMLVCUSTOMDRAW Ptr
Select Case Cb.Msg
Case %WM_InitDialog
'initialize data/location
CreateLVData
CurrentRow = 1 : CurrentCol = 1
UpdateStatusBar
BuildAcceleratorTable
OrigLVProc = SetWindowLong(hListView, %GWL_WndProc, CodePtr(NewLVProc)) 'subclass LV
Case %WM_Destroy
SetWindowLong hListView, %GWL_WNDPROC, OrigLVProc
Case %WM_Command
Select Case Cb.Ctl
Case %IDM_Demo 'Ctrl-D to run the Demo
For i = 1 To 3
CurrentCol = i
For j = 1 To 10
CurrentRow = j : Sleep 250
UpdateStatusBar : Control ReDraw hDlg, %IDC_ListView
Next j
Next i
End Select
Case %WM_Notify
Select Case Cb.NmId
Case %IDC_ListView
Select Case Cb.NmCode
Case %NM_CustomDraw
lpLvCd = CbLParam
Select Case @lplvcd.nmcd.dwDrawStage
Case %CDDS_PREPAINT, %CDDS_ITEMPREPAINT
Function = %CDRF_NOTIFYSUBITEMDRAW
Case %CDDS_ITEMPREPAINT Or %CDDS_SUBITEM
If @lplvcd.nmcd.dwItemSpec = CurrentRow-1 Then
If @lpLvCd.iSubItem <> CurrentCol-1 Then
@lpLvCd.clrTextBk = %White
Else
@lpLvCd.clrTextBk = %Green
End If
End If
Function = %CDRF_NEWFONT
End Select
End Select
End Select
End Select
End Function
Sub CreateListView
Control Add ListView, hDlg, %IDC_ListView,"", 10,10,380,200
Control Handle hDlg, %IDC_ListView To hListView
ListView Set StyleXX hDlg, %IDC_ListView, %LVS_Ex_CheckBoxes Or %LVS_Ex_GridLines Or %LVS_Ex_FullRowSelect
End Sub
Sub CreateLVData
Local i,j As Long
MaxRow = 50 : MaxCol = 10
For i = 1 To MaxCol
ListView Insert Column hDlg, %IDC_ListView, i, "Col" + Trim$(Str$(i)), 100, 0
Next i
For i = 1 To MaxRow
ListView Insert Item hDlg, %IDC_ListView, i,0, "Row " + Trim$(Str$(i))
For j = 1 To MaxCol
ListView Set Text hDlg, %IDC_ListView, i, j, "Row" + Trim$(Str$(i)) + " Col" + Trim$(Str$(j))
Next j
Next i
End Sub
Sub BuildAcceleratorTable
Local c As Long, ac() As ACCELAPI, hAccelerator As Dword ' for keyboard accelator table values
Dim ac(0)
ac(c).fvirt = %FVIRTKEY Or %FCONTROL : ac(c).key = %VK_D : ac(c).cmd = %IDM_Demo : Incr c
Accel Attach hDlg, AC() To hAccelerator
End Sub
Sub UpdateStatusBar
Dialog Set Text hDlg, "ListView Grid Demo: " + Str$(CurrentRow) + Str$(CurrentCol)
End Sub
Function NewLVProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Local hdnptr As HD_NOTIFY Ptr, hdiptr As HD_ITEM Ptr, w,iResult As Long
Local LpLvNm As NM_LISTVIEW Ptr, LVHT As LVHitTestInfo
Select Case Msg
Case %WM_KeyDown
Select Case wParam
Case %VK_Up
CurrentRow = Max(1,CurrentRow-1)
UpdateStatusBar
Control ReDraw hDlg, %IDC_ListView
Case %VK_Down
CurrentRow = Min(MaxRow,CurrentRow+1)
UpdateStatusBar
Control ReDraw hDlg, %IDC_ListView
Case %VK_Left
CurrentCol = Max(1,CurrentCol-1)
UpdateStatusBar
Control ReDraw hDlg, %IDC_ListView
Case %VK_Right
CurrentCol = Min(MaxCol,CurrentCol+1)
UpdateStatusBar
Control ReDraw hDlg, %IDC_ListView
Case %VK_Pgup
Dialog Set Text hDlg, "PageUp" 'not sure what row/col this corresponds to
Case %VK_PgDn
Dialog Set Text hDlg, "PageDown" 'not sure what row/col this corresponds to
Case %VK_Home
CurrentCol = 1
If GetKeyState(%VK_Control) Then CurrentRow = 1
Control ReDraw hDlg, %IDC_ListView
UpdateStatusBar
Case %VK_End
CurrentCol = MaxCol
If GetKeyState(%VK_Control) Then CurrentRow = MaxRow
Control ReDraw hDlg, %IDC_ListView
UpdateStatusBar
End Select
End Select
Function = CallWindowProc(OrigLVProc, hWnd, Msg, wParam, lParam)
End Function
Will play around with this, it seems most of the tricks is in here.
Nope, just colored backgrounds. Will dig more....
Found a working example on the PB site. Simple, but effective.
#INCLUDE ONCE "WIN32API.INC"
#INCLUDE ONCE "COMMCTRL.INC"
#INCLUDE ONCE "PBForms.INC"
%IDD_DIALOG1 = 101
%IDC_LISTVIEW1 = 1001
%IDC_TEXTBOX1 = 1002
FUNCTION PBMAIN()
PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR _
%ICC_INTERNET_CLASSES)
ShowDIALOG1 %HWND_DESKTOP
END FUNCTION
CALLBACK FUNCTION ShowDIALOG1Proc()
LOCAL my_LpLvNm AS NM_LISTVIEW PTR
STATIC LVRow AS LONG, LVCol AS LONG
STATIC hListView AS LONG, i AS LONG, x AS LONG, y AS LONG, txtv AS STRING, datav AS LONG
STATIC SIrect AS RECT
SELECT CASE AS LONG CB.MSG
CASE %WM_INITDIALOG
' Initialization handler
CONTROL HANDLE CBHNDL, %IDC_LISTVIEW1 TO hListView
CASE %WM_NCACTIVATE
STATIC hWndSaveFocus AS DWORD
IF ISFALSE CB.WPARAM THEN
' Save control focus
hWndSaveFocus = GetFocus()
ELSEIF hWndSaveFocus THEN
' Restore control focus
SetFocus(hWndSaveFocus)
hWndSaveFocus = 0
END IF
CASE %WM_NOTIFY
IF LOWRD(CBWPARAM)= %IDC_LISTVIEW1 THEN
my_LpLvNm = CBLPARAM
SELECT CASE @my_LpLvNm.hdr.code
CASE %NM_CLICK
'cursor position
LVRow = @my_LpLvNm.iItem
LVCol = @my_LpLvNm.iSubItem
LISTVIEW UNSELECT CBHNDL, %IDC_LISTVIEW1, LVRow + 1
i = ListView_GetSubItemRect(hListView, LVRow, LVCol, %LVIR_BOUNDS, VARPTR(SIrect))
CONTROL GET LOC CBHNDL, %IDC_LISTVIEW1 TO x, y
IF LVCol = 0 THEN
LISTVIEW GET COLUMN CBHNDL, %IDC_LISTVIEW1, 1 TO datav
CONTROL SET LOC CBHNDL, %IDC_TEXTBOX1, x + SIrect.nLeft + 6 , y + SIrect.nTop + 1
CONTROL SET SIZE CBHNDL, %IDC_TEXTBOX1, datav - 7 , SIrect.nBottom - SIrect.nTop
ELSE
CONTROL SET LOC CBHNDL, %IDC_TEXTBOX1, x + SIrect.nLeft + 7 , y + SIrect.nTop + 1
CONTROL SET SIZE CBHNDL, %IDC_TEXTBOX1, SIrect.nRight - SIrect.nLeft - 8 , SIrect.nBottom - SIrect.nTop
END IF
CONTROL NORMALIZE CBHNDL, %IDC_TEXTBOX1
CONTROL SET FOCUS CBHNDL, %IDC_TEXTBOX1
LISTVIEW GET TEXT CBHNDL, %IDC_LISTVIEW1, LVRow + 1, LVCol + 1 TO txtv
CONTROL SET TEXT CBHNDL, %IDC_TEXTBOX1, txtv
FUNCTION = 1
EXIT FUNCTION
END SELECT
END IF
CASE %WM_COMMAND
' Process control notifications
SELECT CASE AS LONG CB.CTL
CASE %IDC_TEXTBOX1
IF CB.CTLMSG = %EN_CHANGE THEN
CONTROL GET TEXT CBHNDL, %IDC_TEXTBOX1 TO txtv
IF ISTRUE INSTR(txtv, $CRLF) THEN
CONTROL HIDE CBHNDL, %IDC_TEXTBOX1
txtv = REMOVE$(txtv, $CRLF)
LISTVIEW SET TEXT CBHNDL, %IDC_LISTVIEW1, LVRow + 1, LVCol + 1, txtv
END IF
END IF
END SELECT
END SELECT
END FUNCTION
FUNCTION SampleListView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lColCnt _
AS LONG, BYVAL lRowCnt AS LONG) AS LONG
LOCAL lCol AS LONG
LOCAL lRow AS LONG
LOCAL lStyle AS LONG
LISTVIEW GET STYLEXX hDlg, lID TO lStyle
LISTVIEW SET STYLEXX hDlg, lID, lStyle OR %LVS_EX_FULLROWSELECT OR _
%LVS_EX_GRIDLINES
' Load column headers.
FOR lCol = 1 TO lColCnt
LISTVIEW INSERT COLUMN hDlg, lID, lCol, USING$("Column #", lCol), 0, 0
NEXT lCol
' Load sample data.
FOR lRow = 1 TO lRowCnt
LISTVIEW INSERT ITEM hDlg, lID, lRow, 0, USING$("Column # Row #", _
lCol, lRow)
FOR lCol = 1 TO lColCnt
LISTVIEW SET TEXT hDlg, lID, lRow, lCol, USING$("Column # Row #", _
lCol, lRow)
NEXT lCol
NEXT lRow
' Auto size columns.
FOR lCol = 1 TO lColCnt
LISTVIEW FIT HEADER hDlg, lID, lCol
NEXT lCol
END FUNCTION
FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
LOCAL lRslt AS LONG
LOCAL hDlg AS DWORD
DIALOG NEW PIXELS, hParent, "Very Simple Editable Listview", , , _
768, 372, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
%WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME _
OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
%WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
%WS_EX_RIGHTSCROLLBAR, TO hDlg
CONTROL ADD LISTVIEW, hDlg, %IDC_LISTVIEW1, "", 20, 20, 730, _
330, %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR %LVS_REPORT OR _
%LVS_SHOWSELALWAYS, %WS_EX_LEFT
CONTROL SET COLOR hDlg, %IDC_LISTVIEW1, %BLACK, RGB(225, 225, 255)
CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "", 590, 0, 160, 20, %WS_CHILD _
OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT OR %ES_AUTOHSCROLL OR %ES_MULTILINE OR %ES_WANTRETURN OR %ES_AUTOVSCROLL, _
%WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
CONTROL HIDE hDlg, %IDC_TEXTBOX1
SampleListView hDlg, %IDC_LISTVIEW1, 7, 30
DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
FUNCTION = lRslt
END FUNCTION
This is the SDK version build with FF-PB, but I did not get it converted to FF-FB jet.
Very nice Klaas!
Did you start with a DDT example and convert it to SDK yourself or build from scratch?
Peter,
Klaas saved you a bunch of work man. This looks to me like it could easily be adapted to your needs.
The issue I have with most of these ListView/Grid attempts is the lack of multiline headers.
Jose did have an example but I believe it failed with more than one listview in a window.
I hope Paul will have multi-line header text in the FreeBasic grid he said he is working on.
This is a Report mode based on Patrice's(?) code for manipulating the header font.
James
Klaas, this is a neat piece of work!!!
I am very impressed!!!
Thanks a million.
Now show me another forum on the internet with help and support like this!!!
Problem solved! Will give due credits!!!!!!
Quote from: Klaas Holland on May 11, 2015, 06:16:28 PM
This is the SDK version build with FF-PB, but I did not get it converted to FF-FB jet.
Hi Klaas,
If you post your FreeBasic version then I will help fix it for you.
Man, this tool works like a charm!
So easy!
I am very impressed.
For now PB is fine, haven't really thought about doing a project in FB.
Nice thing about this is the listview headers in the Project is in Dutch which of course is mostly the same as my language.
Kind of making it feel like a very personalized help!
Full marks!
Klaas,
thanks a lot for your fine example! This is really what I needed. ListViews are new to me and I didn't know where to start!
Something I noticed, when clicking on an item in column 2, a textbox appears on the cell, but I can not type any text in it. When I type a character I hear a 'ping' sound (some kind of windows sound message).
In column 4 I can type text in the ListView textbox and when I hit ENTER key, the text is stored in the LV. So that works as advertised. :)
Thanks again!
Kind regards
AAARRGGGHHH ;D Silly me! I typed text characters in the edit box while only numbers are allowed !!!!! ::) :o ;D
Kind regards
Klaas,
I have a bug report for your sample listview. When running the program, change a column width so that you get a horizontal scrollbar to appear. If you put either column 2 or 4 into edit mode and then scroll the horizontal scrollbar, you will get drawing artifacts as the edit box is not moving also. Similar results when using the combobox. You can quick-fix that by adding %WM_HSCROLL to the case under the FORMT1_LISTVIEW1_CUSTOM function.
Another bug would be that none of the controls are aware that the column they are drawn over might change in size. Or might get "off it's column" when another column is being resized.
Personally, I think I would try updating the controls location and size for all scroll and columnsize events and see if I couldn't keep the edit going instead of just ending it. Although I do think it should be ended if it is pushed out of view by a scrolling or a columnsize event. But I'll put off working on those features for the next time I need an editable ListView. ;)
David,
With help from this forum by Rudolf Furstauer.
I think the EditBox and Combobox should disappear when you try to do something else.
Paul,
Here is the FF-FB version.
I build the forms from scratch, so the Forms-functions must be Ok.
The parts that don't work are commented out.
Thanks it advance.
Btw.: The Example Addressbook does not work either because of:
If (Index <= UBound(gAddressBook(1))) And (Index >= LBound(gAddressBook(1))) Then
Temp = gAddressBook(Index)
End If
Quote from: Klaas Holland on May 13, 2015, 07:19:06 AM
I think the EditBox and Combobox should disappear when you try to do something else.
Fair enough.
You just commented on the my ramblings about what I would do. I just wanted to make sure that you did get that there are two bugs in the version you posted. They are minor drawing artifacts and possible incorrect size/location of the edit or combo box that happen when either a column is resized when in edit mode, or when the user scrolls the listview in the horizontal (also while in edit mode). Canceling the edit should work for either case.
Quote from: Klaas Holland on May 13, 2015, 07:19:06 AM
Paul,
Here is the FF-FB version.
I build the forms from scratch, so the Forms-functions must be Ok.
The parts that don't work are commented out.
Hi Klaas,
I have attached a working FreeBASIC example for you. I added additional code to the FB version that you had in your PB version (but was missing from your download attachment). The FB example should now run similar to your PB example.
You will also need to copy the attached FF_ListView_GetCountPerPage.inc file into your CodeStore/FreeBasic/ListView folder.
Paul,
Thank you for your help, now I can study the differences between PB and FB.
David,
Thank you for your bug-report.
I think this will fix it:
'--------------------------------------------------------------------------------
Function FORMT1_LISTVIEW1_CUSTOM ( _
ControlIndex As Long, _ ' index in Control Array
hWndForm As Dword, _ ' handle of Form
hWndControl As Dword, _ ' handle of Control
wMsg As Long, _ ' type of message
wParam As Dword, _ ' first message parameter
lParam As Long _ ' second message parameter
) As Long
Select Case wMsg
Case %WM_PARENTNOTIFY, %WM_HSCROLL, %WM_VSCROLL, %WM_MOUSEWHEEL
FF_Control_ShowState HWND_FORMT1_TEXT1, %SW_HIDE
FF_Control_ShowState HWND_FORMT1_COMBO2, %SW_HIDE
End Select
End Function
I also updated the FF-PB version of May 11, 2015.
Klaas