Standard Grid Tutorial 2: User-Modifiable Grid
For BBj-specific tutorials, see Grid Tutorial 1- Standard Grid Using SENDMSG() functions and Grid Tutorial 2 - Standard Grid Using BBjGrid Methods.
This tutorial describes how to create a grid that can be edited by users.
-
Open the SYSGUI device and dimension several variables:
sysgui=unt
open (sysgui)"X0"
dim event$:tmpl(sysgui); event=len(event$)
dim generic$:noticetpl(0,0)
dim edit_param$:"initstr:c(1*=0),key:u(2),col:u(2),row:u(4)"
dim grid_data$[2,2]The event$ variable reads the event loop. The generic$ variable contains the template returned by the NOTICETPL() function. (This function is new in Visual PRO/5 Rev. 2 and returns the Notify event template, which is more extensive than the standard event template.) The edit_param$ variable causes the grid to enter edit mode. The grid_data$[] array is used to store the information displayed in the grid. In this example, the data displayed in the grid can be changed, and it is necessary to store the current value of every cell at all times so cells can be redrawn as needed.
-
Draw the window and a grid of three rows and three columns, then assign a string template to the grid$ variable, which contains the grid information block:
print (sysgui)'window'(50,50,200,150,"Grid Editing",$00000002$,$$) grid=100 print (sysgui)'grid'(grid,20,20,160,120,$9040$,3,3,3) dim grid$:tmpl(sysgui,ind=1) -
Set the row height and change the highlight method from changing the highlight color (the default) to outlining the cell:
result$=sendmsg(sysgui,grid,68,150/4,$$); rem ' row height result$=sendmsg(sysgui,grid,57,0,$$); rem ' turn off color change highlighting -
Create nested loops to populate the grid_data$[] array with numbers from 0 to 8. Note the grid_data$[] array is loaded at the same time as the grid:
counter=0 for col=0 to 2 result$=sendmsg(sysgui,grid,36,col,chr(51)); rem ' column width for row=0 to 2 grid_data$[col,row]=str(counter) counter=counter+1 next row next col -
Set up the event loop. The basic structure is the same as in the previous example, but this example will be checking for different events. The code to read the event loop and get a template for the Notify event information is identical:
while 1 read record(sysgui,len=event)event$ if event.code$="N" : then
: generic$=notice(sysgui,event.x);
: dim notice$:noticetpl(generic.objtype,event.flags);
: let notice$=generic$ -
Check for Notify event 22, which indicates that one or more cells in the grid must be redrawn. This event will be sent to the program as soon as the grid displays, so the initial values will be displayed immediately.
if event.code$="N" and event.flags=22 : then : for col=notice.leftcol% to notice.rightcol%; : grid.col=col%; : for row=notice.toprow% to notice.botrow%; : grid.row=row%; : grid.buf$=grid_data$[col,row]; : grid.textcolor$=$000000$,grid.backcolor$=ffffff$,grid.alignment%=2; : result$=sendmsg(sysgui,grid,54,0,grid$); : next row; : next colThere are two user events that are a concern in a program that supports editing in a grid: the user indicating that editing should begin, and the indication that editing should end. In this program, a left-button mouse click on any cell will indicate editing should begin, and clicking on any other cell will indicate editing is complete, and the new value should be stored in the data array. To check for a mouse click, we test for Notify event 14, which is generated when the user clicks on a cell with the left mouse button. We will also check for notice.lparam=0 so that we react to the mouse button being released instead of the button being pushed. When the user indicates editing should begin, SENDMSG() Function 79 is issued to set a mask, and the grid control is put into edit mode with SENDMSG() Function 31. If no mask is specified for a cell, no data can be entered. SENDMSG() Function 31 requires a specially formatted string, which is called edit_param$ in this sample. This string is defined in step one. Here, the string is used to indicate the coordinates of the cell to be edited.
-
Check for Notify event 14 and notice.lparam=0:
if event.code$="N" and notice.code=14 and notice.lparam=0
: then
: result$=sendmsg(sysgui,grid,79,notice.col%,"000");
: edit_param.row%=notice.row%,edit_param.col%=notice.col%;
: result$=sendmsg(sysgui,grid,31,0,edit_param$) -
Check for Notify event 7, which indicates that editing has been completed:
if event.code$="N" and notice.code=7
: then
: grid_data$[notice.col%,notice.row%]=sendmsg(sysgui,grid,34,0,$$)When Notify event 7 is generated, SENDMSG() Function 34 is used to read the value in the just-edited cell and store it in the data array.
-
End the program with the code to enable the user to terminate the event loop by clicking the close button, followed by the end of the event loop itself and the end of the program:
if event.code$="X"
: then
: break
wend
endThe window created by the code so far looks like this:
The complete program is listed below:
|