Les 4: EuroCC with RadioButtons

 In this version of EuroCC, we'll replace the Buttons with RadioButtons.
We'll also introduce subroutines, which constitute the power of every real programming language.

Preparation

  1. If you haven't done so yet, download euroen02.zip to \DelphiLa.
    Don't unzip it now. Remember that every project will reside in it's own directory. We also agreed to keep all original ZIP-files in \DelphiLa.

  2. Create a new directory: \DelphiLa\EuroEN02.

  3. Copy euroen02.zip to \DelphiLa\EuroEN02 and "unzip" the file in this directory. Check if you've got the files euroen02.dpr, euroform.dfm and euroform.pas.

What will the result be?

As in the previous lessons, let's have a look at what version 2 of EuroCC will become.

  1. Start Delphi and open the project euroen02.dpr.

  2. Compile the application. Delphi will start the application in the "environment" of the debugger.

    EuroEn02 starts after compilation

  3. Just play around with the program. Compare it with the previous version, EuroEn01: notice that the label for the starting currency has gone (CurrLabel). The label with the caption "equals" has been replaced by a button. The buttons for the conversions (EuroButton and BEFButton) have been replaced by a group of "RadioButtons", a RadioGroup.

    There is also another change that you can't see when running the program, but only at "design" time. The number of labels for the results and the names of the currencies has been cut in half. Now, each label shows the amount as well as the currency: we combined the two strings to one new string.

    Notice that now the amounts in the labels are nicely aligned, which was not the case in our previous version. We achieve this by replacing the font of the labels with a "fixed width" font, and by making the labels right aligning.

  4. Stop the application.
    In the File menu, click Close All.

  5. Delete all files from \DelphiLa\EuroEN02 (your original zip-file is still in \DelphiLa, I hope...)

  6. Start a New Application in Delphi.

  7. Immediately save the files (see lesson 2). In dialog Save Unit1 as, select directory \DelphiLa\EuroEN02 and enter euroform as the file name. In the next dialog, Save Project1 As, you enter euroen02 as name for the project file.

A Quick Analysis

a quick analysis1 Euro equals 40.3399 BEF (Belgian franc). BTW: the conversion rate for Luxemburg Franc is the same.

1 Euro equals 2.20371 NLG ("Netherlands" Guilder). Netherlands = Dutch.

Clicking the "equals" button should convert the number from the edit-box to a value in Euro (the method of calculation depends from the radiobutton which is selected).

Next, the value is converted from Euro to the other currencies and the results are shown in the labels. The label that corresponds with the starting currency must become invisible.

The program also has to perform a conversion when a radiobutton is clicked. The conversion equally has to be done if a value is entered and the ENTER key is pressed.

The program has to start with a conversion of 100 Euro to the other currencies.

Components for this application, for 3 currencies: 1 edit-box for the input of the amount, 1 button, 3 labels for the results (resulting amounts plus names of currencies).

Adding Components and setting Properties

  1. Put the components on the form (all components can be found on the standard page of the component palette). Your form looks more or less like this:

    Form1 with added components

  2. In the Object Inspector you change the component's properties as follows:

    Edit1

    • Name : InputEdit
    • Text: 100
    Button1
    • Name : ConvertButton
    • Caption : equals
    RadioGroup1
    • Name : ValutaRadioG
    • Caption : completely delete the actual caption
    • ItemIndex : 0
    Label1
    • Name : EuroLabel
    Label2
    • Name : BEFLabel
    Label3
    • Name : NLGLabel

  3. Select the RadioGroup. In the Object Inspector, click property Items. Next, click on the button with the three dots that has appeared:

    the property Items

  4. The String list editor opens. Enter three lines as indicated below. Next, click OK.

    String list editor

  5. After dragging and resizing the components, you should have a form looking like this:

    the components are in place

  6. On the from, select the three labels. You can do that by pressing SHIFT and clicking each label (or by pressing SHIFT and using the mouse to draw a selection rectangle around the three components).

    Now you can set the properties for all the labels at once:

    • Alignment : taRightJustify
    • AutoSize : False
    • Width : 130
    • Font: click on the property, next click on the button with the 3 dots. In the Font dialog box, select the font Courier New (because that one has a fixed width for all characters), Size 9, color Navy.

The 3 labels are selected

A simplified version of the code

  1. Select ConvertButton. In the Object Inspector, click the tab Events. Next, double-click in the white field next to OnClick. Delphi gives the event handler a name: ConvertButtonClick.

    In the Editor, Delphi has created a template for this event handler. Add some code to the event handler as follows:

    procedure TForm1.ConvertButtonClick(Sender: TObject);
    begin
      CurrConvert;
    end;

  2. Select the RadioGroup. Create an event handler for it's OnClick event in the Object Inspector and complete it in the code editor:
    procedure TForm1.ConvertRadioGClick(Sender: TObject);
    begin
      CurrConvert;
    end;

    CurrConvert is the name of the procedure that will perform the calculations and that will show the results. Without this routine "CurrConvert", we would have to repeat the entire code in both the event handlers. Later on, we would have to repeat that block of code in a third and in a fourth event handler: one for pressing the ENTER key after the amount is entered, and one for the first "automatic" conversion that has to be done right after the start of the program.

  3. Firstly, we have to declare that a procedure named CurrConvert will be used in the program. That declaration must appear in the first part of the code, in the interface section. In the editor, put the cursor at the end of the line that says:
    { Private declarations }
    Press ENTER in order to start a new line. Enter the text that I colored in red:
    private
      { Private declarations }
      procedure CurrConvert;

  4. The code for the procedure has to be placed in the implementation section. Put the cursor after the semi-colon that ends the last event handler, after the end;
    Make a blank line and then type as follows:
    procedureTForm1.CurrConvert;
    var
      Amount, Euro: real;
      S1: string;
    begin
      Amount := StrToFloat(InputEdit.Text);
      Euro := Amount;
      S1 := FormatFloat('0.00', Euro);
      EuroLabel.Caption := S1 + ' Euro';
    end;

    Of course, this is only a small part of the code that we need. We are not looking at the radiobuttons and we aren't making any conversions. But testing your program in small bits (bites?) will make it a lot easier to spot any errors.

  5. Compile the program. Click the ConvertButton. Enter a value in the Edit-box and click one of the radiobuttons.
    Stop the program.

Making decisions: IF... THEN... ELSE...

What is the first decision to be made by the program?

Such a decision is made with an if:
if a_condition then an_instruction;

The word then also may be followed by a block of instructions, inserted between the reserved words begin and end. But that's not neccesary in our simple program.

Taking into account that the first radiobutton is button number 0, we could replace the line

Euro := Amount;

with this construction:

if ValutaRadioG.ItemIndex = 0 then 
  Euro := Amount;
if ValutaRadioG.ItemIndex = 1 then
  Euro := Amount / 40.3399;
if ValutaRadioG.ItemIndex = 2 then
  Euro := Amount / 2.20371;

Using if... then... else... will improve our code and make it faster (of course, the increase in speed cannot be measured in this simple example, but speed will become a lot more important in bigger applications). Thus, our code should be something like this:

if ValutaRadioG.ItemIndex = 0 then 
  Euro := Amount
else
  calculate_value_in_euro;

Note that no semicolon is allowed after an instruction that precedes an else. The compiler will treat the entire if...then...else as one big instruction.

Also calculate_value_in_euro has to be split in two parts. We need a second if...then...else, which will be "nested" into the first one:

if ValutaRadioG.ItemIndex = 0 then
  Euro := Amount
else
  if ValutaRadioG.ItemIndex = 1 then
    Euro := Amount / 40.3399
  else
    Euro := Amount / 2.20371;

The second decision to be made by the program, comes after the calculations are done and the results have been shown:

We could do this with an if...then...else construct. But the code "and the other two labels must be visible" is really awful, because it is repeated 3 times. First solution: make all labels visible and then hide one of them through an if...then...else.

But it can be done a lot simpler, without using any "if"! In order to make a component visible or invisible, you have to assign a logical (boolean) value to it's "visible" property, TRUE or FALSE. Or an expression that results in a logical value. Have a look at this chunk of pseudo code:

EuroLabel.Visible := button_0_is_not_selected;
BEFLabel.Visible  := button_1_is_not_selected;
NLGLabel.Visible  := button_2_is_not_selected;

Let's code!

  1. Rewrite procedure CurrConvert als follows (I already added some comments, it is up to you to add more or less remarks):

    { Convert value in InputEdit to Euro, depending
      on the radiobutton selected in ValutaRadioG.
      Next, convert from Euro to other currencies. }
    procedure TForm1.CurrConvert;
    var
      Amount, Euro, BEF, NLG: real;
      S1, S2, S3: string;
    begin
      // Convert text of EDIT to numerical value
      Amount := StrToFloat(InputEdit.Text);
      // Calculate value in Euro
      if ValutaRadioG.ItemIndex = 0 then
        Euro := Amount
      else
        if ValutaRadioG.ItemIndex = 1 then
          Euro := Amount / 40.3399
        else
          Euro := Amount / 2.20371;
      // Convert to other currencies
      BEF := Euro * 40.3399;
      NLG := Euro * 2.20371;
      { Convert the floating point values to strings.
        '0.00' is the "Format String", meaning:
        'result must have 2 digits after dec. separator' }
      S1 := FormatFloat('0.00', Euro);
      S2 := FormatFloat('0.00', BEF);
      S3 := FormatFloat('0.00', NLG);
      { Put strings in the CAPTIONs of the LABELs,
        followed by the name of the currency. Add
        spaces in order to have equal lengths.    }
      EuroLabel.Caption := S1 + ' Euro   ';
      BEFLabel.Caption  := S2 + ' BEF/LUF';
      NLGLabel.Caption  := S3 + ' NLG    ';
      { Do not show the label which corresponds
        with the starting currency              }
      EuroLabel.Visible := (ValutaRadioG.ItemIndex <> 0);
      BEFLabel.Visible  := (ValutaRadioG.ItemIndex <> 1);
      NLGLabel.Visible  := (ValutaRadioG.ItemIndex <> 2);
    end;

    By now it becomes clear why I suggested the font Courier New for the labels: all characters have the same width in this font, also the spaces. As we made the labels right aligning, all the values will align nicely on the form.

    Compile your program and test it thoroughly.

  2. Let's add an event handler in which the first (automatic) conversion is done. The ideal moment to do this is when Form1 is "created". Just like any other components, also forms are objects that are created automatically at the moment the program starts.

    Select the form, either in the listbox of the Object Inspector, or by clicking on an empty spot of Form1. In the Object Inspector, double-click in the field next to OnCreate. In the code-editor, complete the event handler:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      CurrConvert;
    end;

    Easy, isn't it? Go ahead and test if it works.

  3. Finally, we'll add the finishing touch to this version of EuroCC. Also pressing the ENTER key should command a conversion. At least, when the the cursor is in the Edit-component. In Windows speak: when the Edit has the focus.

    Select InputEdit. In the Object Inspector, double-click in the field next to OnKeyPress. Complete the event handler:

    procedure TForm1.InputEditKeyPress(Sender: TObject; var Key: Char);
    begin
      if Key = #13 then ValutaConvert;
    end;

    Delphi hands the variabele Key to us in the header of the procedure. That variable contains the "character" that corresponds with the key that has been pressed. Delphi wrote: var Key: Char which means that Key is a variable of type "char".

    The operator # is used to convert a number to the corresponding character. Thus, #13 means: the character of which the code is 13, the "character" that Windows receives when you press ENTER.

    OK, test it!

See you again for lesson 5!

[ TOP ]

What is a string?
A string is a series of characters. You can show a string by putting it in the Caption of a component (a Form, a Label, a Button) or in the Text of a component (e.g., an Edit).
In the source code, you represent the contents of a string between single quotes.
Strings can be handled in lots of ways, for example: connect two strings in order to make a new string:
S2 := 'ABC' + 'DEF';

[ TOP ]

© Copyright 1999 
Studiebureau Festraets