Files
TerminalBasic/docs/forms-referenz.md
Chili Palmer 5a1a284505 Phase 6-07a: Fensterlokale Control-Menüs und Windows-Testkorrekturen
Control-Menüs öffnen für alle Fensterarten am [≡]-Symbol des aktiven
Fensters: eigener Auswahlzustand statt Kopplung an die Menüleiste,
bevorzugt unter der Titelzeile, bei Platzmangel nach oben aufgeklappt,
am rechten Rand nur so weit nach links wie nötig. Regressionstest über
TestBackend für Code-, Projekt-, Output-, Immediate-, Debug- und
Hilfefenster, maximiert, minimiert, Rand und Maus.

Nebenbefunde der Windows-Testausführung: Temporärdatei vor sync_all
schreibend öffnen (Zugriff verweigert), relative Projektverweise immer
mit / schreiben, zeilenendenneutrale Vergleiche in Referenzmatrix-,
Kompatibilitäts- und MAK-Beispieltests, DriveListBox-Zeichenbild
plattformneutral. Korpus-Sollausgaben per .gitattributes auf LF.

Specs ide-oberflaeche und ide-projekte synchronisiert, Change archiviert.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 11:02:40 +02:00

339 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 0254; `Height`/`Width`
für Controls 1254, 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 | 065 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 | 012 (Default, Block, Cross, I-Beam, …) | 0 |
| ForeColor/BackColor | 015 | 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 | `[ / ▼]` (unter Windows `[ \ ▼]`, Wurzeltrenner der Plattform) | 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(017)`
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 400403 (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)