Module 9: Arrays and Buttons
Copyright: C Wragg 2000

What is an array?

In our secrets program, we need to be able to hold several pieces of information. The freeware version allows you to store 50 different items of information, and for each of these there is a description as well as the secret data itself. We could choose 100 different variable names, and even make it easier to recognise them by using something like data1, data2, ... data50, but not only would this be tedious, but it would also be difficult to write a simple routine to step from one to another.

The answer is to use arrays. An array has the same name for all the items of data, but distinguishes between them by number. So we might set up a one-dimensional array to record the description as follows:

DIM description$(50)

This uses the same keyword DIM that we used before, and the purpose is the same if you stop to consider what is happening. The program is asking the OS to set aside space for 50 strings, and we can then pick out the 5th description as description$(5), etc. Actually this in not strictly correct because the OS will actually reserve space for 51 strings, the first one being description$(0), and we shall use this fact in our program in a few moments.

An array does not have to be one-dimensional. It is frequently useful to have 2 or 3-dimensional arrays, and a two dimensional array could be defined by the statement

DIM array2$(4,20)

This establishes a 5 x 21 array called array2$. Such an array might be established to store 5 different pieces of information about 21 different people. It could be that the five items are the name, sex, age, height and weight of each person, so that the age of the 5th person would be stored in array2$(2,4), and of the 12th person in array2$(2,11). Note here that array$(0,0) is the name of the first person.

Array illustration
The first two records of array2$()

The use of arrays is particularly useful when going through all the data. For example, to print all the data you might use a loop as follows:

FOR X%=0 TO 20
    FOR Y%=0 TO 4
        PRINT array2$(Y%,X%)+", ";
    NEXT
    PRINT
NEXT

Note the extra PRINT before repeating the X% loop. The semi-colon after the first PRINT statement makes the arrays print on one line. The second PRINT ensures a new line is begun for the next person. Note also how important it is to get the X% and Y% the right way round to ensure that one person's details are all printed together!

Adding the arrays to the program

There are a number of ways in which the arrays could be set up, but we are going to use two separate arrays for the description and the secret data. We shall use two-dimensional arrays in each case so that we can use the '0,0' element for work space when converting encrypted data. Find the line

app$="Secrets"

and insert immediately before this the following two lines:

DIM desc$(1,50), secret$(1,50)
desc$()="":secret$()=""

The second of the two lines uses a particularly useful feature of BASIC V which enables you to set all the elements in an array to a default value. In this case we have set all the elements in both desc$() and secret$() to be empty.

Note also that you can only DIM an array once, so it would be good practice to avoid using the DIM statement twice in the same program for the same array, even if you think the program will only meet one of them.

Responding to the buttons

You may have noticed in the last Module that having brought up the Secrets window on the screen, you could click on either of the writable icons and the caret would appear, just as you would expect from other programs. This is all controlled by the wimp as a result of our original descriptions of the icons. Furthermore, you could delete what was there using the delete key or Control-U, and you could type in your own statements. What you could not do, however, was save what you had typed, nor could you move on to another item. To do this, we must write code to describe what we want to happen when the buttons are pressed.

In general, there are two common actions we use to tell the program to do something: we click the mouse, or we press a key. This is picked up by the Wimp polling routine, which will then point to the appropriate procedure to be followed. In the remainder of this module we are going to implement the 'add', 'back' and 'next' buttons so that we can begin to make things happen.

Our code for the polling routine is already in place, and a click with the mouse calls the procedure PROCclick(win%). This already contains the code to handle clicks over the iconbar and the iconbar menu. It begins with a line 'CASE win% OF', the purpose of which is to determine which window the pointer is over when the mouse is clicked. So far, we only have the value 'WHEN -2' which means it is over the icon on the iconbar.

To indicate that the pointer is over the main window, go to the end of the 'WHEN -2' section (between the two consecutive occurrences of ENDCASE) and add a new section as follows

WHEN main%
    CASE block%!8 OF
        WHEN 1,4:
            CASE block%!16 OF
                WHEN 8:PROCback
                WHEN 9:PROCnext
                WHEN 13:PROCadd
            ENDCASE
    ENDCASE

Remember that the value in block%!8 tells us which button was clicked, 4 for Select and 1 for Adjust. We have therefore ensured that a click with the Menu button will have no effect in this procedure.

block%!16 contains the number of the icon that has been clicked over. The icons are numbered from 0 in the order in which they are defined for the particular window in PROCinit. If you count through the definitions you will see that number 8, the 9th icon, is the line

a%=FNcreate_icon(main%,388,-384,148,56,&1700313D,"",keylast%,R5%,2)

and keylast% contains the string "back". In other words, when the mouse is clicked on this icon, with the word 'back' on it, the procedure PROCback is called. Similarly, the button 'next' leads to PROCnext, and the button 'add' is the 14th button defined and leads to PROCadd.

We must now add these three procedures, and they should follow at the end of the listing after PROCmenuselect(). Enter as follows.

DEFPROCback
IFn%<=1 ENDPROC
n%-=1
PROCreset
ENDPROC

DEFPROCnext
IFn%>=50 ENDPROC
n%+=1
PROCreset
ENDPROC

DEFPROCadd
desc$(1,n%)=FNstring(text1%)
secret$(1,n%)=FNstring(text2%)
PROCreset
ENDPROC

PROCback and PROCnext are very similar, as you would expect. Note that the IF statement is very important because if you try to move back from the first entry, or beyond the last entry, not only will it not make sense, but you are also likely to step outside the range of the array causing an error.

PROCreset is used by all three of these procedures, and is the routine that rewrites the details in the icons and so updates the window on the screen. This procedure should now be added at the end:

DEFPROCreset
$text1%=desc$(1,n%)
$text2%=secret$(1,n%)
!block%=main%
block%!4=4:block%!8=0:block%!12=0
SYS"Wimp_SetIconState",,block%
!block%=main%
block%!4=6:block%!8=0:block%!12=0
SYS"Wimp_SetIconState",,block%
ENDPROC

Remember that we defined text1% and text2% to be the addresses of the data to be displayed in the writable icons in the window. n% is used to hold the number of the current record, and in PROCback for example it was reduced by 1, so PROCreset installs the new strings into these two icons. We then reset !block to point to main%, block%!4 to the number of the icon we are updating (and the next two words both to zero) and call SYS"Wimp_SetIconState" to update icon 4. We then repeat this for the second icon which is icon 6.

Use of buttons
Using buttons to move through the file

DEFPROCadd is slightly different because writing a string in a writable icon does not automatically put it in to the corresponding array; we have to arrange for this to happen. We could write code so that it automatically happens when you move backwards or forwards through the data, but secret data could be too precious to risk mistakes. Therefore, we have chosen to only record the data by a specific click on the add button.

In the PROCadd procedure we use a Library function FNstring. This is invaluable, because it takes the string stored at the given address (e.g. text1%), converts it to a normal BASIC string, and puts it into the corresponding element of the array.

More to do

We have now activated three of the buttons, and you will not be able to enter data, move on and add more, go back to previous entries, etc. Unfortunately you cannot save any of this yet, nor can you encrypt it, but you might like to try to write the procedures, PROCbegin and PROClast, for the two buttons marked '|<' and '>|' which should display the first and last records respectively.

Return to the Module Index