143 lines
6.6 KiB
Markdown
143 lines
6.6 KiB
Markdown
# forms-objektmodell Specification
|
||
|
||
## Purpose
|
||
|
||
Das Forms-Objektmodell macht Formulare und Steuerelemente zu benannten
|
||
Objekten des laufenden Programms: Eigenschaften lesen und schreiben,
|
||
Formulare laden, zeigen, verbergen und entladen — modal wie nicht-modal —,
|
||
Steuerelement-Arrays führen und Ereignisse an die Prozeduren
|
||
`Name_Ereignis` zustellen. Es ist die Grundlage der Steuerelemente und der
|
||
vordefinierten Dialoge.
|
||
|
||
## Requirements
|
||
|
||
### Requirement: Formulare und Steuerelemente als benannte Objekte
|
||
Ein Formular SHALL unter seinem Namen ansprechbar sein, ein
|
||
Steuerelement unter seinem Namen innerhalb seines Formulars. Eigenschaften
|
||
SHALL über `objekt.eigenschaft` gelesen und geschrieben werden, mit dem
|
||
in der Forms-Referenz festgelegten Typ und Wertebereich. Es SHALL keine
|
||
Standardeigenschaft geben: `Text1 = "x"` MUST abgewiesen werden. Das
|
||
Schreiben eines Wertes außerhalb des Wertebereichs MUST Laufzeitfehler 5
|
||
auslösen; eine zur Laufzeit schreibgeschützte Eigenschaft MUST bei
|
||
Zuweisung einen Fehler auslösen.
|
||
|
||
#### Scenario: Eigenschaft lesen und schreiben
|
||
- **WHEN** `Text1.Text = "hallo"` ausgeführt und danach `Text1.Text` gelesen wird
|
||
- **THEN** liefert der Zugriff `hallo`
|
||
|
||
#### Scenario: Keine Standardeigenschaft
|
||
- **WHEN** ein Programm `Text1 = "x"` enthält
|
||
- **THEN** wird es abgewiesen und die Meldung nennt `Text1`
|
||
|
||
#### Scenario: Wert außerhalb des Bereichs
|
||
- **WHEN** `Check1.Value = 3` ausgeführt wird
|
||
- **THEN** tritt Laufzeitfehler 5 auf
|
||
|
||
#### Scenario: Getrennte Werte gleichnamiger Controls
|
||
- **WHEN** Form1!Text1.Text auf a und Form2!Text1.Text auf b gesetzt werden
|
||
- **THEN** liefern die beiden Zugriffe unabhängig a und b
|
||
|
||
### Requirement: Container-Zugriff über den Bang-Operator
|
||
`form!steuerelement.eigenschaft` SHALL ein Steuerelement eines benannten
|
||
Formulars ansprechen. Die Schreibweise MUST NOT mit dem Typsuffix `!`
|
||
für SINGLE verwechselt werden; eine Variable `Form1!` und ein Zugriff
|
||
`Form1!Text1` MUST unterscheidbar bleiben.
|
||
|
||
#### Scenario: Zugriff über den Container
|
||
- **WHEN** `Form1!Text1.Text = "a"` ausgeführt wird
|
||
- **THEN** trägt die Eigenschaft `Text` des Steuerelements `Text1` in `Form1` den Wert `a`
|
||
|
||
#### Scenario: Typsuffix bleibt Typsuffix
|
||
- **WHEN** ein Programm die Variable `Wert!` verwendet
|
||
- **THEN** bleibt sie eine SINGLE-Variable und wird nicht als Containerzugriff gelesen
|
||
|
||
### Requirement: Lade- und Entladezyklus
|
||
`LOAD form` SHALL das Formular anlegen und `Form_Load` ausführen, bevor
|
||
es sichtbar wird. `UNLOAD form` SHALL `Form_Unload (Cancel)` ausführen;
|
||
ein von der Prozedur gesetzter Wert `Cancel <> 0` MUST das Entladen
|
||
verhindern. `HIDE` SHALL nur die Sichtbarkeit zurücknehmen und das
|
||
Formular geladen lassen. Der Zugriff auf ein nicht geladenes Formular
|
||
SHALL es implizit laden.
|
||
|
||
#### Scenario: Load läuft vor der Anzeige
|
||
- **WHEN** ein Formular gezeigt wird, dessen `Form_Load` eine Eigenschaft setzt
|
||
- **THEN** ist der gesetzte Wert bereits in der ersten Anzeige sichtbar
|
||
|
||
#### Scenario: Entladen abbrechen
|
||
- **WHEN** `Form_Unload` den Parameter `Cancel` auf 1 setzt und `UNLOAD Form1` ausgeführt wird
|
||
- **THEN** bleibt das Formular geladen und sichtbar
|
||
|
||
#### Scenario: HIDE entlädt nicht
|
||
- **WHEN** `Form1.HIDE` ausgeführt und danach eine Eigenschaft von `Form1` gelesen wird
|
||
- **THEN** ist der zuvor gesetzte Wert erhalten und `Form_Load` läuft nicht erneut
|
||
|
||
### Requirement: Modales und nicht-modales Anzeigen
|
||
`form.SHOW [style%]` SHALL das Formular anzeigen; `style%` 0 (Vorgabe)
|
||
zeigt es nicht-modal, 1 modal. Bei modaler Anzeige MUST die Anweisung
|
||
nach `SHOW` erst ausgeführt werden, wenn das Formular entladen oder
|
||
verborgen wurde; die Ereignisschleife MUST währenddessen weiterlaufen.
|
||
Verstöße gegen die Stapelregeln des Vorbilds MUST die Fehler 400–403
|
||
auslösen.
|
||
|
||
#### Scenario: Modal hält den Ablauf an
|
||
- **WHEN** ein Programm `Form1.SHOW 1 : PRINT "danach"` ausführt und ein Ereignis `Form1` entlädt
|
||
- **THEN** erscheint `danach` erst nach dem Entladen
|
||
|
||
#### Scenario: Ereignisse laufen während der Modalität
|
||
- **WHEN** ein modales Formular angezeigt wird und ein Ereignis eintrifft
|
||
- **THEN** läuft die zugehörige Ereignisprozedur
|
||
|
||
### Requirement: Steuerelement-Arrays
|
||
Steuerelemente mit gleichem Namen und `Index` SHALL als Array
|
||
ansprechbar sein. `LOAD ctl(index%)` SHALL ein weiteres Element zur
|
||
Laufzeit anlegen, `UNLOAD ctl(index%)` es entfernen. Der Versuch, ein zur
|
||
Entwurfszeit angelegtes Element zu entladen, MUST Fehler 362 auslösen.
|
||
Bei einem Array MUST `Index AS INTEGER` als erster Parameter der
|
||
Ereignisprozedur übergeben werden.
|
||
|
||
#### Scenario: Element zur Laufzeit anlegen
|
||
- **WHEN** `LOAD Command1(3)` ausgeführt wird
|
||
- **THEN** existiert `Command1(3)` mit den Eigenschaften des Elements 0 als Vorlage
|
||
|
||
#### Scenario: Entwurfszeit-Element ist nicht entladbar
|
||
- **WHEN** `UNLOAD Command1(0)` für ein zur Entwurfszeit angelegtes Element ausgeführt wird
|
||
- **THEN** tritt Fehler 362 auf
|
||
|
||
#### Scenario: Index als erster Parameter
|
||
- **WHEN** ein Klick auf `Command1(3)` zugestellt wird
|
||
- **THEN** wird `Command1_Click` mit `Index = 3` aufgerufen
|
||
|
||
### Requirement: Ereignisdispatch an Name_Ereignis
|
||
Ein Ereignis SHALL die Prozedur `Name_Ereignis` des betroffenen Objekts
|
||
aufrufen und ihr die Argumente der in der Forms-Referenz festgelegten
|
||
Signatur übergeben. Fehlt die Prozedur, MUST das Ereignis wirkungslos
|
||
verfallen, ohne Fehler. Die Zustellung SHALL an den Zustellpunkten der
|
||
Ereignissteuerung erfolgen; es MUST NOT neue Zustellpunkte geben.
|
||
|
||
#### Scenario: Ereignisprozedur wird gerufen
|
||
- **WHEN** ein Klick auf `Command1` zugestellt wird und `SUB Command1_Click` existiert
|
||
- **THEN** läuft die Prozedur genau einmal
|
||
|
||
#### Scenario: Fehlende Ereignisprozedur
|
||
- **WHEN** ein Klick auf ein Steuerelement ohne passende Prozedur zugestellt wird
|
||
- **THEN** läuft das Programm unverändert weiter und es entsteht kein Fehler
|
||
|
||
#### Scenario: Signatur mit Mausargumenten
|
||
- **WHEN** `Form_MouseDown` definiert ist und ein Mausereignis in Zeile 5, Spalte 7 zugestellt wird
|
||
- **THEN** erhält die Prozedur Taste, Umschaltzustand und die Position in Zellen
|
||
|
||
### Requirement: SCREEN-Objekt
|
||
`SCREEN` SHALL als Objekt ansprechbar sein mit `ActiveControl`,
|
||
`ActiveForm`, `Height`, `Width`, `MousePointer` und `ControlPanel` sowie
|
||
den Methoden `SHOW` und `HIDE`. `Height` und `Width` SHALL die
|
||
**aktuelle** Terminalgröße in Zeichen liefern und schreibgeschützt sein;
|
||
die feste Größe des Vorbilds MUST als Abweichung dokumentiert sein.
|
||
|
||
#### Scenario: Größe folgt dem Terminal
|
||
- **WHEN** die Darstellungsfläche 120×40 misst und `SCREEN.Width` gelesen wird
|
||
- **THEN** liefert es 120
|
||
|
||
#### Scenario: Aktives Formular
|
||
- **WHEN** zwei Formulare geladen sind und eines den Fokus hat
|
||
- **THEN** liefert `SCREEN.ActiveForm` dieses Formular
|