# Forms-Referenz Terminal Basic

Rekonstruierte Referenz der Forms-Engine des Vorbilds (VBDOS 1.0) —
Grundlage für `tb-ui::forms` und den Formular-Designer. Primärquellen:
Original-Hilfedatei (dekodiert), `CONSTANT.BI`, Stringtabellen der
Original-Programme, Beispielprojekte. Aussagen ohne TODO sind daraus belegt.
Die zeilenweise Matrix mit Typ, Bereich, Vorgabe, Laufzeit-Schreibbarkeit
und Klassenquelle liegt im Change-Dokument
`openspec/changes/phase-4-objektmodell/klassen-und-eigenschaften.md`.
Als Beispiel-Gegenprobe dient `cout/vbdos` Commit
`1cdd2b32b829fe1721d0b6aecc433abc47a96fb6`; dessen binäre Formulare
`microsoft/check.frm`, `notepad.frm`, `qlbview.frm`, `seek.frm`,
`spindemo.frm`, `graphics/graphics.frm` und `misc/mentors/mentors.frm`
enthalten die dort ausgewiesenen Eigenschaften und Ereignisprozeduren.

## Koordinatenmodell

Einheit ist durchgängig die **Textzelle** (Spalte/Zeile), keine Twips.
`Left`/`Top` relativ zum Container, gültiger Bereich 0–254; `Height`/`Width`
für Controls 1–254, für Formulare bis Bildschirmgröße. `ScaleHeight`/
`ScaleWidth` (nur Form/PictureBox, read-only) = Innenmaß ohne Rahmen/Menü.
Maus-Koordinaten in Ereignissen sind SINGLE, aber in Zellen.

## Steuerelemente (exakte Klassennamen)

`CheckBox, ComboBox, CommandButton, DirListBox, DriveListBox, FileListBox,
Frame, HScrollBar, Label, ListBox, Menu, OptionButton, PictureBox, Spin, TextBox,
Timer, VScrollBar` — alle außer `Menu` über die Toolbox platzierbar
(Menüs entstehen im Menu Design Window). Default-Namen: `Check1`, `Combo1`,
`Command1`, `Dir1`, `Drive1`, `File1`, `Frame1`, `HScroll1`, `Label1`,
`List1`, `Option1`, `Picture1`, `Text1`, `Timer1`, `VScroll1`.

## Eigenschaften/Methoden/Ereignisse je Steuerelement

**Form** — Ereignisse: Click, DblClick, DragDrop, DragOver, GotFocus,
KeyDown, KeyPress, KeyUp, Load, LostFocus, MouseDown, MouseMove, MouseUp,
Paint, Resize, Unload. Methoden: CLS, DRAG, HIDE, LOAD, MOVE, PRINT,
PRINTFORM, REFRESH, SHOW, TEXTHEIGHT, TEXTWIDTH, UNLOAD. Eigenschaften:
AutoRedraw, BackColor, BorderStyle, Caption, ControlBox, CurrentX, CurrentY,
DragMode, Enabled, ForeColor, FormName, FormType, Height, Left, MaxButton,
MinButton, MousePointer, Parent, ScaleHeight, ScaleWidth, Tag, Top,
Visible, Width, WindowState.

**CommandButton** — Ereignisse: Click, DragDrop, DragOver, GotFocus,
KeyDown, KeyPress, KeyUp, LostFocus. Methoden: DRAG, MOVE, REFRESH,
SETFOCUS. Eigenschaften: BackColor, Cancel, Caption, CtlName, Default,
DragMode, Enabled, Height, Index, Left, MousePointer, Parent, TabIndex,
TabStop, Tag, Top, Value, Visible, Width. Darstellung nach Höhe:
1 = `<Text>`, 2 = einzeiliger Rahmen, ≥3 = Kasten; Mindestgröße 1×3.

**TextBox** — Ereignisse: Change, DragDrop, DragOver, GotFocus, KeyDown,
KeyPress, KeyUp, LostFocus. Methoden: DRAG, MOVE, REFRESH, SETFOCUS.
Eigenschaften: BackColor, BorderStyle, CtlName, DragMode, Enabled,
ForeColor, Height, Index, Left, MousePointer, MultiLine, Parent,
ScrollBars, SelLength, SelStart, SelText, TabIndex, TabStop, Tag, Text,
Top, Visible, Width.

**ListBox** — Ereignisse: Click, DblClick, DragDrop, DragOver, GotFocus,
Key*, LostFocus, Mouse*. Methoden: ADDITEM, DRAG, MOVE, REFRESH,
REMOVEITEM, SETFOCUS. Eigenschaften: BackColor, CtlName, DragMode, Enabled,
ForeColor, Height, Index, Left, List, ListCount, ListIndex, MousePointer,
Parent, Sorted, TabIndex, TabStop, Tag, Text, Top, Visible, Width.

**ComboBox** — wie ListBox plus Change, DropDown (Ereignisse), SelLength/
SelStart/SelText/Style/Text (Eigenschaften).

`ListIndex = -1` hebt die Auswahl auch bei leerer Liste auf. ADDITEM vor dem
ausgewählten Eintrag verschiebt seinen Index nach rechts, REMOVEITEM davor
nach links; Entfernen des ausgewählten Eintrags setzt ihn auf −1. Das gilt
auch für sortierte Listen. `ListCount` und `List(i)` spiegeln die geänderte
Liste unmittelbar wider. Ohne Auswahl liefern ListBox und ComboBox.Style 2
leeren Text. Die editierbaren ComboBox-Stile 0 und 1 erhalten ihren separaten
Eingabetext; ihre Anzeige entspricht auch ohne Auswahl diesem Text.
Nachträgliches `Sorted = -1` sortiert den vorhandenen Inhalt ohne Beachtung
der Groß-/Kleinschreibung. Gleich sortierte Einträge behalten ihre relative
Reihenfolge; die Auswahl bleibt beim selben Eintrag, auch bei Duplikaten.
Die Simple-ComboBox zeigt unter dem Eingabefeld ihre Listeneinträge samt
Auswahlmarkierung; Inhalt wird auf den verfügbaren Listenbereich begrenzt.

**CheckBox / OptionButton** — Ereignisse: Click (Option auch DblClick),
Drag*, GotFocus, Key*, LostFocus. Methoden: DRAG, MOVE, REFRESH, SETFOCUS.
Eigenschaften: BackColor, Caption, CtlName, DragMode, Enabled, ForeColor,
Height, Index, Left, MousePointer, Parent, TabIndex, TabStop, Tag, Top,
Value, Visible, Width.

**Frame** — nur DragDrop/DragOver; DRAG, MOVE, REFRESH (kein SetFocus);
Container für Gruppierung (OptionButton-Gruppen). `Index` und `TabIndex`
werden in den Originaldateien auch für Frames gespeichert.

**Label** — Ereignisse: Change, Click, DblClick, Drag*, Mouse*. Methoden:
DRAG, MOVE, REFRESH. Eigenschaften: zusätzlich Index, TabIndex, Alignment,
AutoSize, BorderStyle.

**HScrollBar/VScrollBar** — Ereignisse: Change, Drag*, GotFocus, Key*,
LostFocus (**kein** separates Scroll-Ereignis). Eigenschaften: zusätzlich
Attached (VBDOS-Spezifikum: am Formularrand angedockt; Laufzeit read-only),
LargeChange, Min, Max, SmallChange, Value.

**Spin** — Ereignisse: Custom(EventType), Drag*, GotFocus, Key*, LostFocus.
`Style` wählt vertikal/horizontal, `Interval` steuert die Wiederholung; `Value`
läuft zyklisch zwischen `Min` und `Max`. `BorderStyle`, `Width` und `Height`
sind zur Laufzeit schreibgeschützt.

**PictureBox** — Text-Zeichenfläche (PRINT/CLS aufs Control) und Container
für OptionButton-Gruppen. Ereignisse: Click, DblClick, Drag*, GotFocus,
Key*, LostFocus, Mouse*, Paint. Methoden: CLS, DRAG, MOVE, PRINT, REFRESH,
SETFOCUS, TEXTHEIGHT, TEXTWIDTH. Eigenschaften: zusätzlich Index, TabIndex,
TabStop, AutoRedraw, CurrentX, CurrentY, ScaleHeight, ScaleWidth.

**Timer** — Ereignis Timer, keine Methoden; Eigenschaften: CtlName, Enabled,
Index, Interval (0 = aus … 65 535 ms), Parent, Tag.

Die erste Frist beginnt mit der Aktivierung auf einem sichtbaren Formular
oder dem Zuweisen eines positiven Intervalls an der aktuellen Hostzeit.
Erneutes Zuweisen von Enabled = −1 an einen bereits aktiven Timer verändert
die Frist nicht. Intervalländerungen beginnen eine neue Phase und verwerfen
alte wartende Timerereignisse; Enabled = 0 und Interval = 0 verwerfen sie
ebenfalls. Verstecken/Entladen beendet die aktive Phase. Ein durchgehend
aktiver 100-ms-Timer erzeugt bei einem Fortschritt um 250 ms zwei Ereignisse.
Zeiten vor Aktivierung oder während einer inaktiven Phase werden nicht nachgeholt.

Einbetter, die das Forms-Modell direkt verändern, rufen nach der Änderung
`sync_timers(|| host.jetzt_ms())` auf. Die Closure wird ausschließlich bei
neu beginnenden aktiven Timern ausgewertet. Die VM erledigt dies nach
Property-Zuweisungen, SHOW und dem Laden von Arrayelementen sowie beim
Übernehmen eines vorbereiteten Modells; es gibt keinen globalen Zeitcache.

**Menu** — Ereignis Click; Eigenschaften Caption, Checked, CtlName, Enabled,
Index, Parent, Separator, Shortcut, Tag, Visible.

**DirListBox/DriveListBox/FileListBox** — Datei-Browser-Controls
(Path/Drive/FileName/Pattern/Archive/Hidden/Normal/ReadOnly/System;
Ereignisse u. a. Change, PathChange, PatternChange). Terminal Basic bildet
sie plattformneutral nach (Laufwerksliste → Wurzeln/Mounts).

## Ereignisquellen im Terminal

Eine Hosttaste liefert KeyDown und KeyUp; eine Zeichentaste zusätzlich
KeyPress. Ohne behandelndes Control gilt derselbe Ablauf für das aktive
Formular. Show/Hide und Formularwechsel liefern GotFocus/LostFocus,
geänderte Formularmaße Resize; Show und Refresh liefern Paint, bei
PictureBox liefert Refresh Paint. Label.Caption löst bei Änderung Change aus.
Nicht registrierte Ereignisse verfallen; Change, Timer und Paint verändern
den Eingabefokus nicht. Menüs und Labels werden dadurch nicht zum aktiven
Eingabe-Control.

Alt+Pfeil-ab öffnet bzw. schließt die Liste einer ComboBox und löst beim
Öffnen DropDown aus. Enter oder Esc schließt sie. Der sichtbare Listenbereich
bleibt durch die Control-Höhe begrenzt. DirListBox.Path meldet PathChange und
Change, FileListBox.Path meldet PathChange und FileListBox.Pattern meldet
PatternChange; DriveListBox.Drive meldet Change.

## Standardwerte und Wertebereiche

| Eigenschaft | Bereich | Default |
|---|---|---|
| CheckBox.Value | 0 Unchecked · 1 Checked · 2 Grayed | 0 |
| OptionButton.Value | 0/−1 | 0 |
| CommandButton.Value | True löst Click aus | False |
| ComboBox.Style | 0 Dropdown · 1 Simple · 2 Dropdown List | 0 |
| BorderStyle (Form) | 0 None · 1 Fixed Single · 2 Sizable Single · 3 Fixed Double · 4 Sizable Double · 5 Fixed Solid · 6 Sizable Solid | 2 |
| BorderStyle (Control) | 0 None · 1 Single · 2 Double (nur Label/PictureBox) | Label 0; TextBox/PictureBox 1 |
| WindowState | 0 Normal · 1 Minimized · 2 Maximized | 0 |
| FormType | 0 Normal · 1 MDI-Container | 0 |
| Timer.Interval | 0–65 535 ms | 0 |
| ScrollBar Min/Max | −32 768…32 767 | 0 / 32 767 |
| Small-/LargeChange | 1…32 767 | 1 |
| TextBox.ScrollBars | 0 None · 1 H · 2 V · 3 Both | 0 |
| MultiLine/Sorted/Attached | Boolean, Laufzeit read-only | False |
| Alignment (Label) | 0 Left · 1 Right · 2 Center | 0 |
| DragMode | 0 Manual · 1 Automatic | 0 |
| MousePointer | 0–12 (Default, Block, Cross, I-Beam, …) | 0 |
| ForeColor/BackColor | 0–15 | 0 / 7 |
| Text (TextBox/ComboBox) | — | Entwurfszeit = CtlName |
| ListIndex | −1 = keine Auswahl | −1 |

## Zeichenbilder und Zustände

Die Originalquellen belegen Aufbau und Rahmenformen, enthalten aber keine
vollständige Screenshot-Reihe für jede Klasse und jeden Zustand. Die folgende
einheitliche Umsetzung ist deshalb **unsere Festlegung**: normal = die Werte
aus `ForeColor`/`BackColor`, fokussiert = Farbe 15 auf 1, deaktiviert = Farbe
8 auf 0. `&` kennzeichnet
nur den Access-Key und wird nicht ausgegeben. Die Beispiele zeigen jeweils
normal · fokussiert · deaktiviert; Inhalt wird auf die verfügbare Breite
gekürzt und der Rest mit Leerzeichen gefüllt.

Listenrahmen bleiben auch bei Width = 1 oder Height = 1 innerhalb des
Steuerelements; nicht passende Rahmenstücke und Zeilen entfallen.
Die Kürzung von Listen- und Combo-Inhalten zählt Bildschirmzellen: breite
Unicode-Zeichen werden nur vollständig ausgegeben, Steuerzeichen als
Leerzeichen dargestellt. Am Bildschirmrand wird die Forms-Ausgabe ohne
Umbruch oder Scrollen abgeschnitten.

| Klasse | normal | fokussiert | deaktiviert |
|---|---|---|---|
| CommandButton, Höhe 1 | `<OK>` | `<OK>` | `<OK>` |
| CommandButton, Höhe 2 | `┌OK──┐` / `└────┘` | ebenso | ebenso |
| CommandButton, Höhe ≥ 3 | `┌────┐` / `│ OK │` / `└────┘` | ebenso | ebenso |
| Label | `Text` | `Text` | `Text` |
| Frame | `┌ Titel ─┐` / `│        │` / `└────────┘` | ebenso | ebenso |
| CheckBox | `[ ] Text` | `[ ] Text` | `[ ] Text` |
| CheckBox, gewählt/grau | `[x] Text` / `[-] Text` | ebenso | ebenso |
| OptionButton | `( ) Text` | `( ) Text` | `( ) Text` |
| OptionButton, gewählt | `(•) Text` | `(•) Text` | `(•) Text` |
| TextBox | `┌──────┐` / `│Text  │` / `└──────┘` | ebenso, Cursor an `SelStart` | ebenso, ohne Cursor |
| ListBox | `┌──────┐` / `│eins  │` / `│zwei  │` / `└──────┘` | ebenso, aktuelle Zeile in Fokusfarben | ebenso |
| ComboBox, Dropdown | `[Text ▼]` | ebenso in Fokusfarben | ebenso |
| ComboBox, Simple | `[Text ▼]` / `┌──────┐` / `│eins  │` / `└──────┘` | ebenso in Fokusfarben | ebenso |
| HScrollBar | `◄──□──►` | ebenso in Fokusfarben | ebenso |
| VScrollBar | `▲` / `│` / `□` / `│` / `▼` | ebenso in Fokusfarben | ebenso |
| Spin | `▲` / `▼` oder `◄ ►` | ebenso in Fokusfarben | ebenso |
| PictureBox | `┌──────┐` / `│Text  │` / `└──────┘` | ebenso in Fokusfarben | ebenso |
| DirListBox | `┌──────┐` / `│[dir] │` / `└──────┘` | ebenso, aktuelle Zeile in Fokusfarben | ebenso |
| DriveListBox | `[ / ▼]` | ebenso in Fokusfarben | ebenso |
| FileListBox | `┌──────┐` / `│a.bas │` / `└──────┘` | ebenso, aktuelle Zeile in Fokusfarben | ebenso |
| Menu | ` Datei  Bearbeiten ` | gewählter Titel/Eintrag in Fokusfarben | Text in Farbe 8 |
| Timer | keine sichtbaren Zellen | keine sichtbaren Zellen | keine sichtbaren Zellen |

`BorderStyle = 0` unterdrückt den Rahmen von Label, TextBox und PictureBox;
`BorderStyle = 2` nutzt `╔═╗║╚╝`. Scrollbars erscheinen nur in den von
`ScrollBars` genannten Richtungen. Ein unsichtbares Steuerelement zeichnet
keine Zelle.

## Festgelegte Reihenfolgen

Die folgenden Regeln sind **unsere Festlegung**, nicht nachgewiesenes
Referenzverhalten:

- **Z-Reihenfolge:** Ein Container liegt stets hinter seinen Kindern, auch
  bei indizierten Eltern. Im Übrigen gilt Erzeugungsreihenfolge; später erzeugte Elemente liegen
  oben. Bei Steuerelement-Arrays entscheidet bei sonst gleicher Position der
  aufsteigende Index, sodass der höchste Index oben liegt. Gezeichnet wird von
  unten nach oben, die Trefferprüfung läuft umgekehrt.
- **Timer-Reihenfolge:** Sind mehrere Timer am selben Zustellpunkt fällig,
  werden ihre Ereignisse in aufsteigender, ASCII-unabhängig
  großgeschriebener `CtlName`-Reihenfolge zugestellt. Mehrere verstrichene
  Intervalle desselben Timers bleiben in zeitlicher Reihenfolge davor. Bei
  gleichem Arraynamen folgt der aufsteigende numerische Index.

Die Korpusfälle `listenauswahl.frm` und `timer-aktivierung.frm` prüfen diese
Verträge mit festgelegten Sollausgaben: Listenauswahl/Combo-Eingabetext und
späte Timeraktivierung bei 1000 ms mit erster Zustellung bei 1100 ms.
Dies sind Vertragsregressionen, keine neu aufgenommenen VBDOS-Referenzläufe.

**Keine Default-Eigenschaften:** `Text1 = "x"` gibt es nicht — Zugriff
immer explizit (`Text1.Text`). „Default" ist nur die CommandButton-
Eigenschaft (Enter-Taste); „Cancel" analog für Esc.

## Ereignis-Signaturen

```basic
SUB Form_KeyDown (KeyCode AS INTEGER, Shift AS INTEGER)
SUB ctl_KeyPress ([Index AS INTEGER,] KeyAscii AS INTEGER)
SUB Form_MouseDown (Button AS INTEGER, Shift AS INTEGER, X AS SINGLE, Y AS SINGLE)
SUB Form_DragDrop (Source AS CONTROL, X AS SINGLE, Y AS SINGLE)
SUB Form_DragOver (Source AS CONTROL, X AS SINGLE, Y AS SINGLE, State AS INTEGER)
SUB Form_Unload (Cancel AS INTEGER)   ' Cancel <> 0 verhindert Entladen
```

Shift-Bitfeld 1 Shift · 2 Ctrl · 4 Alt; Button 1 links · 2 rechts;
DragOver-State 0 Enter · 1 Leave · 2 Over. Bei Steuerelement-Arrays steht
`Index AS INTEGER` immer vorn. KeyAscii ist bei uns ein Unicode-Codepoint
(UTF-8-Abweichung); klassische KeyCode-Konstanten bleiben gültig
(Vorbild-Eigenheit: Entf = 127).
Ereignisse ohne eine der oben genannten Argumentfamilien haben keine
Parameter. Bei Arrays wird ausschließlich `Index AS INTEGER` vorangestellt;
die restliche Signatur bleibt unverändert.

## SCREEN-Objekt

Eigenschaften: ActiveControl, ActiveForm, AutoRedraw, ControlPanel,
Height, Width (Zeichen, read-only — bei uns die **aktuelle Terminalgröße**,
Abweichung: das Vorbild lieferte fest 25/43/50 × 80), MousePointer.
Methoden: HIDE, SHOW (alle sichtbaren Formulare ein-/ausblenden). `SCREEN.ControlPanel(0–17)`
konfiguriert Systemfarben/-effekte (AccessKey-/Desktop-/Menü-/Titel-
Farben, Schatten, 3D-Effekte, Desktop-Füllzeichen) — Konstanten in der
Konstanten-Include-Datei.

## Show/Hide/Load/Unload und Modalität

`form.SHOW [style%]`: **0 = modeless (Standard), 1 = modal**; lädt bei
Bedarf. Bei modal läuft der Code nach `SHOW` erst nach Schließen weiter.
Modal-Stacking-Regeln → Fehler 400–403 (u. a. „MDI form cannot be shown
modally"). `HIDE` setzt nur `Visible = False`; `LOAD`/`UNLOAD` mit
Load-/Unload-Ereignis (Cancel-Parameter). `LOAD/UNLOAD ctl(index%)` für
Steuerelement-Arrays (Entwurfszeit-Elemente sind nicht entladbar,
Fehler 362); deren Eigenschaften sind über `ctl(index%).Eigenschaft`
adressierbar und werden beim `LOAD` vom Entwurfszeit-Element 0 geklont.

## Menüsystem

Definition pro Formular im **Menu Design Window**, bis zu 6 Ebenen.
Felder: Caption (`&` Access-Key, `-` Separator), CtlName, Tag, Index,
Checked/Enabled/Visible/Separator, Shortcut-Dropdown. Regeln: Separatoren
nicht checked/disabled/mit Shortcut; Menütitel ohne Shortcut.
Menü-Steuerelement-Arrays sind möglich.

## Steuerelement-Arrays, Drag & Drop, Custom Controls

- **Control-Arrays:** gleiche CtlName + Index; Laufzeit-Erzeugung per
  `LOAD ctl(index%)`.
- **Drag & Drop:** DragMode 0/1, Methode `DRAG action%` (0 Cancel ·
  1 Begin · 2 Drop), Ereignisse DragDrop/DragOver mit `Source AS CONTROL`.
- **Custom Controls:** das Vorbild lud sie aus Quick-Libraries; für
  Terminal Basic ist ein natives Erweiterungsmodell **Stufe 2** (PLAN.md).

## Offene Detailfragen

- `.FRM`-Textformat: exakte Serialisierung (siehe dateiformate.md)
