There is a search button at the bottom of the page.
This tutorial assumes that you are comfortable with using arrays in general. For example, if writing a program to keep track of a small shop's stock of the 20 items it routinely carries, it is assumed that you would immediately plan to use something like StockLevel:array[1..20] of integer; (Working from 0 is often beneficial, but used 1 in case the zero index confused anyone.)
I hope you will see ways to write a better program as the tutorial progresses. I am trying to keep the project from having too many distracting embellishments.
You may find one particular aspect of using an array of controls odd.... you won't be able to place them on your form as you would a plain edit box. More on this later.
I am endebted to Mr. Alan Lloyd of comp.lang.pascal.delphi.misc newsgroup for getting me past obstacles I encountered when I first tried to use arrays of controls.
The program will create a screen like:
==================== Add these up 4 5 1 5 2 8 1 7 - - - - ? ? ? ? Click here when done ====================
The user replaces each '?' with something, and the program marks the answers. N.B. For this tutorial about arrays, the program we are writing is NOT asking the user to add four thousand, five hundred, fifteen to anything. The user IS being asked to do four separate sums, the answer to the second being 13. (The program could be modified to ask the user to add two four digit numbers.)
Arrays of edit boxes will be used for the digits of the first number in each problem (FirstNum[x]), for the digits of the second number (SecNum[x]), and the digits of the user's guess (Guess[x]). The digits of the right answer will be in an array of strings (Correct[x]). While it seems odd to be using strings to hold the elements of arithmetic problems, it works well.
As a first step, we will create the array FirstNum, and the first element of that array. The index ("number") of that element is going to be 0.
Start a new project called DD15, with my usual suffixes to distinguish forms, units, etc.
Add StdCtrls to the Uses section. The TEdit control is defined in StdCtrls, so the compiler needs StdCtrls to set up our array of TEdit controls.
In the Var section add:
FirstNum:array [0..3] of TEdit;
Use the Object Inspector to create an OnCreate event handler for the application's form (DD15f1, in my naming scheme). Add the following to it:
FirstNum:=TEdit.Create(Self); FirstNum.parent:=Self; FirstNum.top:=5; FirstNum.left:=5; FirstNum.height:=50; FirstNum.width:=50; FirstNum.enabled:=true; FirstNum.show; FirstNum.text:='Hi';
...and run the program. You should get an edit box in the upper left, saying 'Hi'.
Some fine points:
a) My teacher suggested using
I looked up what the Delphi help had to say about TWinControl:
'The TWinControl component is the abstract component type for windowed controls, which are controls with window handles, including the standard Windows controls. It is unlikely that you will ever derive a new component directly from TWinControl, however. Instead, you will usually derive from TCustomControl'
My simpler version seems to work. (Alan was creating an array of panels, maybe that matters.)
b) The program 'works' without the FirstNum.enabled:=true; and FirstNum.show;... but assumptions about initial states are always dangerous in programming. To quote from the Delphi Help: 'Since a constructor always clears the storage it allocates for a new object, all fields automatically have a default value of zero (ordinal types), nil (pointer and class types), or empty (string types).'
c) Of course, the FirstNum.text:='Hi'; isn't necessary, but it does allow you to be sure that any edit box you see is the one you created.
d) By the way... don't try to do FirstNum.setfocus; because it won't work within FormCreate, even for an 'ordinary' edit box. Setfocus must be done in a different procedure after form has been created. I've had this type of problem in other circumstances, and any feedback on ways around it would be welcomed! The problem: Often I create, initialise, etc, objects, etc, in the main form's OnCreate handler, but find that I can't do all of the initialisation I would like because, in essense(?) I'm trying to use things before they are set up and available(?)
Once you have the above working, you have mastered all of the essentials! The rest of the tutorial is just putting together the promised example, with a few hints at shortcuts along the way.
Start a new project. Again, I'm calling mine DD15
Add StdCtrls to the Uses section.
In the Var section add:
FirstNum, SecNum, Guess:array [0..3] of TEdit; Correct:array [0..3] of string;
(If I were writing this for the end result, I'd use a two dimensional array. You might like to try re-writing it that way as an exercise!)
Just after the Var section, make a Const section with:
GridTop=25; GridLeft=15; VSpace=20; HSpace=40; Gap=10;
(These are just for things like positioning the edit boxes, they don't need to be 'understood'.)
Use the Object Inspector to create an OnCreate event handler for DD15f1. Make it:
procedure TDemoF1.FormCreate(Sender: TObject); var b1:byte; begin for b1:=0 to 3 do begin FirstNum[b1]:=TEdit.Create(Self); secnum[b1]:=TEdit.Create(Self); Guess[b1]:=TEdit.Create(Self); FirstNum[b1].parent:=Self; secnum[b1].parent:=Self; Guess[b1].parent:=Self; FirstNum[b1].top:=GridTop; secnum[b1].top:=GridTop+Gap+VSpace; Guess[b1].top:=GridTop+2*(VSpace+Gap); FirstNum[b1].left:=GridLeft+b1*(HSpace+Gap); secnum[b1].left:=GridLeft+b1*(HSpace+Gap); Guess[b1].left:=GridLeft+b1*(HSpace+Gap); FirstNum[b1].width:=HSpace; secnum[b1].width:=HSpace; Guess[b1].width:=HSpace; FirstNum[b1].height:=VSpace; secnum[b1].height:=VSpace; Guess[b1].height:=VSpace; FirstNum[b1].show; secnum[b1].show; Guess[b1].show; FirstNum[b1].enabled:=false; secnum[b1].enabled:=false; Guess[b1].enabled:=true; FirstNum[b1].text:='?'; secnum[b1].text:='?'; Guess[b1].text:='?'; end;(*for*) end;(*OnCreate*)
... and run the program. You should get a matrix of edit boxes, four wide, three high, all with a '?' in them.
Now to set up problems to solve....
Add a menu with a 'New' option, named mmNew
Make the mmNewClick event the following:
procedure TDemoF1.mmNewClick(Sender: TObject); var b1,bNum1,bNum2:byte; begin for b1:=0 to 3 do begin bNum1:=random(10); bNum2:=random(10); FirstNum[b1].text:=IntToStr(bNum1); SecNum[b1].text:=IntToStr(bNum2); Correct[b1]:=IntToStr(bNum1+bNum2); Guess[b1].text:='?'; end; Guess.setfocus; end;
Get that to run without error messages.
(Unless you want the same problems over & over again, add
Add a button to the form, underneath where the matrix of edit boxes appears (though there will be none in sight on the form you edit... they only appear when the program runs, as you have seen by now.) Name it buClickToMark, Caption 'Click here to mark answers'.
Add a label to the form below buClickToMark. Name: laScore, Visible: false. (Don't set Enabled false, by the way... it acts like Visible:=false!)
When testing the program, using the tab key to go from window to window is easy. You never need touch the mouse.
Make the OnClick for buClickToMark:
procedure TDemoF1.buClickToMarkClick(Sender: TObject); var b1,bScore:byte; begin bScore:=0; for b1:=0 to 3 do begin if Guess[b1].text= Correct[b1] then inc(bScore); end; bScore:=bScore; laScore.caption:=IntToStr(bScore); laScore.show; end;
Remember: THis program is asking the user to do four separate addition problems. The user is NOT adding two four digit numbers, though you could modify the program for that use quite easily when everything else is working.
(Irrelevant aside: You might be amused to know that I spent about half an hour trying to find out why I always got a score of 4 if the test before inc(bScore) was
... of course, I looked in all the wrong places first.)
There you have it! There's plenty of room to improve the application, of course, but the use of several arrays of edit boxes is clear, I hope.
There is a Level Four tutorial which follows on from this with ideas for making use of modified standard components. (Filename at one point was Dt4a.htm)
Click here for zip file with source code.
Click here to visit editor's freeware, shareware page.
Page WILL BE tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org
....... P a g e . . . E n d s .....