The Second Form

Add a new form to an application is easy - just select File -> New Form in the main menu (or use the icon, in our version the forth in the second line, see picture bellow).

After program execution, only the first form will appear. If we like more, we have to ask the Delphi to show them (calling appropriate function by program; cannot be activated using Object Inspector).

The description of the Form2 is linked to another unit, default name is unit2 (the Form2 can be renamed using the name property in the Object Inspector, the unit2 can be renamed by saving with another name - Save As... function). [in the 308 and Delphi 4, you have to save whole project immediately after creating the new unit, to a directory, where you can write.]

If we like to use the new unit, we have to say to compiler about this. It has to be written in the unit1; switch back to unit1, move to the beginning of the Pascal code, and look for the uses keyword. There is already list of used units; add the new one here (in the following example, on the end of the list):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes,
  Graphics, Controls, Forms, Dialogs, unit2;

type

The compiler stops the translation on the uses directive and before continues, translates each of them from this list (or just reads the result, if they are precompiled, as the units, which come together with Delphi itself). If some of them contain the uses directive again, this step is nested.

The result is, that we cannot add the unit1 to the list of units in the unit2, because translator would start to cycle here (never finish this - in real, it shows an error message). If we need to access anything from the unit1 to the unit2, we have to write the "uses unit1" to another place. The correct position for this is after the implementation keyword; using this place, the compiler will ignore this in the first step of compilation, but the linker (the second step of compilation) will link these two units correctly:

implementation

uses unit1;
{$R *.DFM}

procedure TForm2.Edit1Change(Sender: TObject);

Example: Create another form with an Edit and some Scrollbar, for changing the text on the Button1 (on the first form) and the position of the Button1:

As the first, we should connect both units, as is in the both previous code examples.

On the Form1, we should double-click to the Button (on the picture, the Caption has been changed to "Form2"), and we can add the command, which will show the second form. If we need both forms, the correct procedure is show, but if only the new one should be active, we have to use showmodal:

procedure TForm1.Button1Click(Sender: TObject);
begin
  unit2.Form2.ShowModal;
end;

Now, we can change the Caption of the button from the second form; doubleclick to the Edit will create the OnChange event; the code will be activated, if the text is changed (if you write there, then during typing):

procedure TForm2.Edit1Change(Sender: TObject);
begin
  unit1.Form1.Button1.Caption := Edit1.Text;
end;

Because there is no ambiguity, we don't have to write the name of the unit as part of the name of variable; but we are outside the Form1 form, so we have to add name of the concurrent form.

The second task was to add correct response for Scrollbar; the Scrollbar limits (min, max, position) should be set, before use. The Min can stay zero (default), while the Max should be the maximum position for the Button1 - it depends on the Button1 size:

procedure TForm1.Button1Click(Sender: TObject);
begin
  unit2.Form2.ScrollBar1.Max :=
    Form1.ClientWidth - Button1.Width;
  unit2.Form2.ShowModal;
end;

Then, the OnChange event of the Scrollbar1 in the unit2 can be:

procedure TForm2.ScrollBar1Change(Sender: TObject);
begin
  unit1.Form1.Button1.Left := ScrollBar1.Position;
end;

Solved example is here. For the next example, create a new application.


Another properties of buttons, edits and labels

To try, how the "Enabled", "Visible" and "ShowHint" work, create a new form like the next picture. This contains a button (we will change the properties of this) and three Checkboxes, which Caption has been changed, use Object Inspector. In the same time, change the Checked property to the True, and this value for the Button1 for this three properties as well.

Visible - if this is False, the component disappear. We can use this for hide components temporally (for example, when they are inactive of can be confusing), for alternative appearance (for example, either edit, or label, on the same position), or even for some kind of template, if we like to create more component dynamically, while program is running.

Enabled - if become false, the button cannot be pressed, and edit cannot be changed. If active, then the component changes color of text to gray. If not enabled, the content of the edit can be changed only from program, by rewriting the Text property.

Hint - simple help (a small label on a yellow stick, which appears, when an user moves the cursor on the component for a while. For activate this, this program will change the ShowHint property to True, but if this should work, you have to change the Hint property of the button to some reasonable text (using Object Inspector).

Set the appropriate values in the Object Inspector, then generate the events for all of the Checkboxes (doubleclick on them) and add a copying of their state to the appropriate button properties:

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  Button1.Visible := CheckBox1.Checked;
end;

procedure TForm1.CheckBox2Click(Sender: TObject);
begin
  Button1.Enabled := CheckBox2.Checked;
end;

procedure TForm1.CheckBox3Click(Sender: TObject);
begin
  Button1.ShowHint := CheckBox3.Checked;
end;

Solved example not available.


RadioButton

This is a special type of button, which creates groups; only one of them can be pressed (by user - program can set more of them, or none, as you can try in the Object Inspector). This property is again - Checked.

It is easier to create a group of this by use the RadioGroup component (only one of them can be checked, even by the program, because which is checked, is in the ItemIndex property; the Items are type of Tstrings, as in memo, each line in this will create a new radiobutton, for example by use RadioGroup.Items.Add(....) method; Items are numbered from the zero; if ItemIndex is negative, for example "-1", no one is selected).

The radiobuttons/radiogroup consume much of space; now, the ListBox is much more popular.

Try to study the next component by yourself, spot on the listed properties:

ListBox. Items (Tstrings), ItemIndex; Multiselect, SelCount, Selected[i].

ComboBox.

BitBtn. Kind, ModalResult, Glyph (on the "additional" ribbon). Try to change the Glyph (save it and edit by the Windows PaintBrush).

MaskEdit - EditMask...

StaticText. BorderStyle.


Stay-on-Top

Sometimes, this is important to have a window, which is always visible (on top-level). It can be used not only for important thing to display, but for masking an annoying (i.e. animated) advertisement on your favorite newspaper web page. It can be easy create, by change only one parameter of your form. The included example is from the www.greatisdelphi.com web page.

The Button1 will create window "top-most", the second will return it to standard state. Zip included.

procedure TForm1.Button1Click(Sender: TObject);
  begin
    SetWindowPos(Handle, HWND_TOPMOST, Left, Top, Width, Height, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
  end;

procedure TForm1.Button2Click(Sender: TObject);
  begin
    SetWindowPos(Handle, HWND_BOTTOM, Left, Top, Width, Height, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
  end;