Phase 4: Steuerelemente implementieren

This commit is contained in:
2026-09-05 12:49:46 +02:00
parent 1cb6ae8fd9
commit 19804e0e2d
36 changed files with 6472 additions and 689 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-09-04

View File

@@ -0,0 +1,119 @@
# Design — Steuerelemente, Menüs, Dialoge
## Context
Siehe proposal.md — Why. Dieser Change setzt auf drei fertigen Stücken
auf: dem Zellenpuffer aus Phase 3, der Ereignisschleife samt Mausquelle
(`phase-4-ereignisschleife`) und dem Objektmodell
(`phase-4-objektmodell`). Er ist der breiteste Change der Phase — 16
Klassen, Menüs, Dialoge —, aber der mit den wenigsten offenen
Architekturfragen.
Die Forms-Referenz lässt drei Detailfragen offen, die hier beantwortet
werden müssen: die Optik je Zustand, die Z-Reihenfolge bei Überlappung
und die Reihenfolge gleichzeitig fälliger Timer.
## Goals / Non-Goals
**Goals:**
- Eine Darstellung, die im Zellenpuffer entsteht und deshalb mit dem
bestehenden Snapshot-Vergleich prüfbar ist.
- Eingabebehandlung, die je Klasse an einer Stelle steht, statt über
Sonderfälle in der Schleife verteilt zu sein.
**Non-Goals:**
- Pixelgenaue Nachbildung der Originaloptik; maßgeblich sind Aufbau und
Zeichen, nicht der Farbton eines Schattens.
- Ein Layoutalgorithmus. Steuerelemente stehen, wo ihre Koordinaten sie
hinstellen.
## Decisions
### D1 — Zeichnen ist eine Funktion des Zustands, kein Nebeneffekt
Jede Klasse zeichnet sich vollständig aus ihren Eigenschaften in den
Zellenpuffer. Es gibt keinen inkrementellen Zeichenpfad und kein
Merken zuvor gezeichneter Bereiche.
| Alternative | Warum nicht |
|---|---|
| Nur veränderte Bereiche neu zeichnen | Bei 80×25 Zellen ist das Neuzeichnen ohnehin billig; der Zustandsabgleich wäre die zweite Quelle der Wahrheit neben den Eigenschaften |
Neu gezeichnet wird an den Zustellpunkten der Ereignisschleife, wenn
eine Eigenschaft sich geändert hat — dieselbe Bedingung, die der
Bildschirmpuffer heute schon für `present` nutzt.
### D2 — Eingabe geht durch eine Kette, nicht durch eine Fallunterscheidung
Ein Tastenereignis läuft: Menü (wenn offen) → modaler Dialog (wenn
offen) → Access-Key des Formulars → fokussiertes Steuerelement →
`Default`/`Cancel`-Schaltfläche → Formular. Jede Station nimmt das
Ereignis an oder gibt es weiter. Für die Maus entsprechend: Menü →
Dialog → Trefferprüfung über die Z-Reihenfolge → Formular.
Die Kette ist die einzige Stelle, an der Vorrang entschieden wird; die
Klassen selbst wissen nichts über einander.
### D3 — Antworten auf die offenen Detailfragen der Forms-Referenz
- **Optik je Zustand**: aus den Original-Screenshots abgeleitet und je
Klasse in der Forms-Referenz als Zeichenbild festgehalten, bevor
gezeichnet wird — sonst legt der erste Implementierungsversuch sie
stillschweigend fest.
- **Z-Reihenfolge**: Reihenfolge der Erzeugung, später Erzeugtes liegt
oben; Steuerelement-Arrays nach Index. Das ist die Regel, die aus einer
`.FRM` reproduzierbar folgt.
- **Gleichzeitig fällige Timer**: in aufsteigender Reihenfolge ihres
Namens im Formular, damit die Ausgabe eines Korpusprogramms nicht von
einer Hashreihenfolge abhängt.
Alle drei werden in `docs/forms-referenz.md` als unsere Festlegung
gekennzeichnet, nicht als Referenzverhalten ausgegeben.
### D4 — Dialoge sind Formulare, keine Sonderfälle
`MSGBOX` und `INPUTBOX$` bauen ein Formular mit Label und Schaltflächen
und zeigen es modal über den Weg aus `phase-4-objektmodell` (Frame-Marke,
D4 dort). Damit gelten Fokus, Access-Keys und Esc ohne Sonderbehandlung,
und die Dialoge sind mit demselben Snapshot-Vergleich prüfbar wie jedes
andere Formular.
### D5 — Menü hält die Ereigniszustellung an
Die Forms-Referenz nennt es für das Vorbild: Zeitereignisse und Trapping
ruhen, solange ein Menü den Fokus hat. Umgesetzt wird das über den
`STOP`-Zustand der Ereignissteuerung — kein neuer Mechanismus, sondern
der vorhandene, vom Menü gesetzt und beim Schließen zurückgenommen.
### D6 — Dateisystem-Steuerelemente werden plattformneutral abgebildet
DriveListBox zeigt keine Laufwerksbuchstaben, sondern die Wurzeln bzw.
Einhängepunkte der Plattform; DirListBox und FileListBox arbeiten auf
Pfaden. `Pattern` bleibt das Muster des Vorbilds. Die Abweichung wird in
der Sprachreferenz festgehalten.
### D7 — Korpusbefunde werden im gemeinsamen Ausführungspfad geschlossen
Die VBDOS-Projekte laufen durch denselben CLI-, Frontend-, VM- und
Zellenpufferpfad wie eigene Programme. Projekt- und Include-Auflösung,
VSpin/HSpin, Common-Dialog-Routinen und die tatsächlich verwendete Grafik
werden deshalb dort implementiert und getestet, nicht im Korpus umgangen.
## Risks / Trade-offs
- **Breite statt Tiefe** → 16 Klassen sind viel Fläche für Flüchtigkeit;
jede Klasse bekommt ihren eigenen Korpusnachweis, nicht nur einen
gemeinsamen Sammeltest.
- **Vollständiges Neuzeichnen bei großen Terminals** → bei 200×60 sind es
12 000 Zellen je Anzeige; falls das messbar stört, greift die
Bedingung „nur bei Änderung" bereits heute, und ein Ausbau bleibt
möglich, ohne die Klassen anzufassen.
- **Fremdprogramme scheitern aus unerwartetem Grund** → jeder Befund wird
festgehalten statt umgangen; er ist das eigentliche Ergebnis des
Kompatibilitätstests.
## Open Questions
Keine.

View File

@@ -0,0 +1,83 @@
# Phase 4 (Abschluss) — Steuerelemente, Menüs, Dialoge
## Why
Das Objektmodell (`phase-4-objektmodell`) macht Formulare und
Steuerelemente ansprechbar, zeigt aber nichts an und nimmt nichts
entgegen. Dieser Change füllt die Klassen mit Verhalten: Darstellung im
Zellenpuffer, Fokus- und Tabreihenfolge, Access-Keys, Maussteuerung,
Menüsystem und die drei vordefinierten Dialoge. Damit schließt Phase 4.
Die drei Dialoge (`MSGBOX` als Anweisung **und** als Funktion,
`INPUTBOX$`) sind die letzten drei offenen Inventareinträge der Phase.
Sie stehen in keiner Steuerelementliste und fielen deshalb bisher
zwischen die Aufgaben.
## What Changes
- **Steuerelementklassen mit Verhalten**: CommandButton, TextBox,
ListBox, ComboBox, CheckBox, OptionButton, Frame, Label, HScrollBar,
VScrollBar, PictureBox, Timer sowie die Dateisystem-Steuerelemente
DirListBox, DriveListBox, FileListBox und VSpin/HSpin — je mit Darstellung,
Zuständen (normal, fokussiert, deaktiviert) und ihren Methoden.
- **Darstellung im Zellenpuffer**: Steuerelemente zeichnen in den
vorhandenen Textbildschirm; es entsteht keine zweite Zeichenschicht.
Die höhenabhängige Darstellung des CommandButton (1 Zeile `<Text>`,
2 Zeilen Rahmen, ab 3 Zeilen Kasten) und die Rahmenarten der übrigen
Klassen folgen der Forms-Referenz.
- **Fokus, Tabreihenfolge, Access-Keys**: `TabIndex`/`TabStop`,
Weiterschalten mit Tab und Umschalt-Tab, `&` im Text als Access-Key,
`Default`- und `Cancel`-Schaltfläche für Enter und Esc, `SETFOCUS`,
`GotFocus`/`LostFocus`.
- **Maussteuerung**: Die Mausereignisse aus `phase-4-ereignisschleife`
werden auf Steuerelemente abgebildet — Trefferprüfung über die
Z-Reihenfolge, Klick, Doppelklick, `MouseDown`/`MouseMove`/`MouseUp`
sowie Ziehen und Ablegen (`DragMode`, `DRAG`, `DragDrop`, `DragOver`).
- **Menüsystem**: Menüleiste je Formular, bis zu sechs Ebenen,
Access-Keys, Shortcuts, `Checked`/`Enabled`/`Visible`/`Separator`,
Menü-Steuerelement-Arrays. Während ein Menü den Fokus hält, ruhen
Zeitereignisse und Traps.
- **Vordefinierte Dialoge** (3 Inventareinträge): `MSGBOX` als Anweisung
und als Funktion mit den Schaltflächengruppen und Rückgabewerten der
Sprachreferenz, `INPUTBOX$` mit fester Größe 46×16 Zeichen und
Positionierung in Zeichen.
- **Timer als Steuerelement**: `Interval` 065 535 ms auf der Zeitquelle
der Ereignisschleife, Ereignis `Timer`.
- **VBDOS-Kompatibilität**: `.MAK`- und `$INCLUDE`-Auflösung, `RUN`,
VSpin/HSpin, die verwendete Zellgrafik (`SCREEN`, `LINE`, `PAINT`, `VIEW`)
und die von den Beispielen benutzten Common-Dialog-Routinen.
**Non-Goals:** Der Formular-Designer (Phase 5). Für den geforderten
VBDOS-Kompatibilitätsnachweis notwendige Projektauflösung, native
Erweiterungssteuerelemente und Grafikausgabe gehören zu diesem Change.
## Capabilities
### New Capabilities
- `forms-steuerelemente`: Verhalten und Darstellung der
Steuerelementklassen, Fokus- und Tabreihenfolge, Access-Keys,
Maussteuerung mit Ziehen und Ablegen, Menüsystem und die
vordefinierten Dialoge.
### Modified Capabilities
- `kompat-testkorpus`: Der Korpus SHALL Formularprogramme mit
Bildschirm-Sollausgabe und deterministischer Ereignisfolge führen.
## Impact
- `crates/tb-ui`: Darstellung und Eingabebehandlung je Klasse, Menüs,
Dialoge, Trefferprüfung, Fokusverwaltung.
- `crates/tb-runtime`: Fehler 260480 des Forms-Bereichs als Auslöser,
`MSGBOX`/`INPUTBOX$` und die benötigte Zellgrafik.
- `crates/tb-frontend`: Signaturen von `MSGBOX` (Anweisung und Funktion)
und `INPUTBOX$`, Projektquellen, `RUN` und die verwendete Grafiksyntax.
- `tests/compat`: Formularprogramme mit Sollausgabe; die Programme aus
`github.com/cout/vbdos` als Kompatibilitätsnachweis.
- `docs/`: `forms-referenz.md` — die offenen Detailfragen (Optik je
Zustand, Z-Reihenfolge, Reihenfolge gleichzeitig fälliger Timer)
werden beantwortet; `inventar.md` setzt die Einträge dieses Changes
auf `implementiert`.
- PLAN.md: Punkte „Steuerelemente", „Menüsystem", „Fokus-/Tab-Reihenfolge",
„Vordefinierte Dialoge" und die beiden Meilensteine der Phase 4.

View File

@@ -0,0 +1,138 @@
## Purpose
Die Steuerelemente machen ein Formular bedienbar: sie stellen sich im
Textbildschirm dar, nehmen Tastatur und Maus entgegen, führen Fokus und
Tabreihenfolge, tragen die Menüleiste und stellen die vordefinierten
Dialoge bereit.
## ADDED Requirements
### Requirement: Darstellung im Zellenpuffer
Steuerelemente SHALL sich im vorhandenen Textbildschirm darstellen; es
MUST NOT eine zweite Zeichenschicht neben ihm entstehen. Jede Klasse
SHALL die in der Forms-Referenz festgelegte Optik für die Zustände
normal, fokussiert und deaktiviert zeigen. Der CommandButton SHALL seine
Darstellung nach der Höhe wählen: eine Zeile als `<Text>`, zwei Zeilen
mit einzeiligem Rahmen, ab drei Zeilen als Kasten. Überlappen
Steuerelemente, SHALL die festgelegte Z-Reihenfolge entscheiden, welches
sichtbar ist.
#### Scenario: Schaltfläche nach Höhe
- **WHEN** ein CommandButton mit `Height = 1` und `Caption = "OK"` gezeichnet wird
- **THEN** erscheint im Zellenpuffer `<OK>`
#### Scenario: Deaktivierter Zustand
- **WHEN** ein Steuerelement `Enabled = 0` trägt
- **THEN** unterscheidet sich seine Darstellung sichtbar vom aktiven Zustand und es nimmt keinen Fokus an
### Requirement: Fokus, Tabreihenfolge und Access-Keys
Der Fokus SHALL mit Tab in aufsteigender `TabIndex`-Folge und mit
Umschalt-Tab rückwärts wechseln; Elemente mit `TabStop = 0` oder
`Enabled = 0` MUST übersprungen werden. Ein `&` im Text SHALL den
folgenden Buchstaben zum Access-Key machen, der mit Alt das Element
auslöst oder ihm den Fokus gibt. Enter SHALL die `Default`-Schaltfläche
auslösen, Esc die `Cancel`-Schaltfläche. Fokuswechsel MUST `LostFocus`
am alten und `GotFocus` am neuen Element auslösen, in dieser Reihenfolge.
#### Scenario: Tab überspringt
- **WHEN** das mittlere von drei Elementen `TabStop = 0` trägt und Tab gedrückt wird
- **THEN** erhält das dritte Element den Fokus
#### Scenario: Access-Key
- **WHEN** eine Schaltfläche `Caption = "&OK"` trägt und Alt+O gedrückt wird
- **THEN** wird ihr `Click`-Ereignis ausgelöst
#### Scenario: Reihenfolge der Fokusereignisse
- **WHEN** der Fokus von `Text1` auf `Text2` wechselt
- **THEN** läuft erst `Text1_LostFocus`, danach `Text2_GotFocus`
### Requirement: Maussteuerung mit Trefferprüfung
Ein Mausereignis SHALL dem obersten Steuerelement an seiner Position
zugestellt werden; liegt dort keines, dem Formular. Klick, Doppelklick
sowie `MouseDown`, `MouseMove` und `MouseUp` SHALL mit Taste,
Umschaltzustand und Position in Zellen zugestellt werden. Bei
`DragMode = 1` SHALL das Ziehen automatisch beginnen; `DRAG action%`
SHALL es manuell beginnen, ablegen oder abbrechen, mit `DragOver` und
`DragDrop` am Ziel.
#### Scenario: Treffer nach Z-Reihenfolge
- **WHEN** zwei Steuerelemente überlappen und in den gemeinsamen Bereich geklickt wird
- **THEN** erhält das obere das Ereignis
#### Scenario: Klick ohne Steuerelement
- **WHEN** auf eine freie Stelle des Formulars geklickt wird
- **THEN** erhält das Formular das Ereignis
#### Scenario: Ziehen und Ablegen
- **WHEN** ein Element mit `DragMode = 1` auf ein anderes gezogen und dort losgelassen wird
- **THEN** läuft am Ziel `DragOver` mit dem Zustand Over und danach `DragDrop` mit der Quelle als Argument
### Requirement: Steuerelemente mit Listeninhalt
ListBox und ComboBox SHALL `ADDITEM` und `REMOVEITEM` unterstützen und
`List`, `ListCount`, `ListIndex` und `Text` konsistent führen; bei
`Sorted = -1` SHALL die Einfügereihenfolge der Sortierung folgen.
`ListIndex = -1` SHALL „keine Auswahl" bedeuten. Die ComboBox SHALL die
drei Stilarten (Dropdown, Simple, Dropdown List) darstellen.
#### Scenario: Element hinzufügen
- **WHEN** `List1.ADDITEM "b"` und `List1.ADDITEM "a"` bei `Sorted = -1` ausgeführt werden
- **THEN** liefert `List1.List(0)` den Wert `a` und `List1.ListCount` den Wert 2
#### Scenario: Keine Auswahl
- **WHEN** eine ListBox ohne Auswahl gelesen wird
- **THEN** liefert `ListIndex` den Wert 1
### Requirement: Timer-Steuerelement
Ein Timer SHALL bei `Enabled = -1` und `Interval > 0` sein
`Timer`-Ereignis im eingestellten Abstand auslösen, gestützt auf die
Zeitquelle der Ereignissteuerung. `Interval = 0` SHALL ihn abschalten.
Sind mehrere Timer gleichzeitig fällig, SHALL die Reihenfolge festgelegt
und dokumentiert sein.
#### Scenario: Timer feuert im Abstand
- **WHEN** ein Timer mit `Interval = 100` läuft und die Zeit um 250 ms vorrückt
- **THEN** ist sein Ereignis zweimal gelaufen
#### Scenario: Interval 0 schaltet ab
- **WHEN** `Timer1.Interval = 0` gesetzt wird
- **THEN** läuft kein weiteres Ereignis
### Requirement: Menüsystem
Ein Formular SHALL eine Menüleiste mit bis zu sechs Ebenen tragen.
Menüeinträge SHALL Access-Keys (`&`), Shortcuts, `Checked`, `Enabled`,
`Visible` und Separatoren (`-`) unterstützen; ein Separator MUST NOT
`Checked`, deaktiviert oder mit Shortcut versehen sein, ein Menütitel
MUST NOT einen Shortcut tragen. Solange ein Menü geöffnet ist, MUST die
Zustellung von Zeitereignissen und klassischen Traps ruhen und danach
fortgesetzt werden.
#### Scenario: Menüauswahl löst Click aus
- **WHEN** ein Menüeintrag über seinen Access-Key gewählt wird
- **THEN** läuft seine `Click`-Prozedur
#### Scenario: Traps ruhen im geöffneten Menü
- **WHEN** ein Menü geöffnet ist und ein Zeit-Trap fällig wird
- **THEN** läuft sein Handler erst, nachdem das Menü geschlossen wurde
### Requirement: Vordefinierte Dialoge
`MSGBOX text$ [, typ% [, titel$]]` SHALL als Anweisung und als Funktion
verfügbar sein; die Funktion SHALL die gedrückte Schaltfläche als
INTEGER liefern (1 OK, 2 Cancel/Esc, 3 Abort, 4 Retry, 5 Ignore, 6 Yes,
7 No). `typ%` SHALL die Schaltflächengruppe (05) und die
Vorgabeschaltfläche (0/256/512) tragen. `INPUTBOX$(text$ [, titel$
[, vorgabe$ [, x%, y%]]])` SHALL eine Zeichenkette liefern und bei
Abbruch den leeren String. Beide Dialoge SHALL modal sein; `INPUTBOX$`
SHALL 46×16 Zeichen messen und ohne Positionsangabe zentriert
erscheinen.
#### Scenario: MSGBOX als Funktion
- **WHEN** `a% = MSGBOX("Weiter?", 4, "Frage")` ausgeführt und `Yes` gewählt wird
- **THEN** liefert der Aufruf 6
#### Scenario: INPUTBOX$ abgebrochen
- **WHEN** ein `INPUTBOX$`-Dialog mit Esc geschlossen wird
- **THEN** liefert er den leeren String
#### Scenario: Dialog ist modal
- **WHEN** ein Dialog offen ist
- **THEN** wird die Anweisung nach dem Aufruf erst nach dem Schließen ausgeführt

View File

@@ -0,0 +1,28 @@
## ADDED Requirements
### Requirement: Korpusabdeckung der Formularprogramme
Der Testkorpus SHALL Formularprogramme mit byte-genauer
Bildschirm-Sollausgabe führen. Ihre Ereignisfolge (Tasten, Maus, Zeit)
SHALL im Programmkopf deklariert und vom Harness eingespeist werden,
sodass ein Lauf ohne Terminal und ohne Wartezeit auskommt und zweimal
dasselbe Ergebnis liefert. Abgedeckt SHALL sein: Fokus- und
Tabreihenfolge, Access-Key, Klick über die Maus, Menüauswahl, ein
Listen-Steuerelement, ein Timer und ein modaler Dialog.
#### Scenario: Formularprogramm im Korpus
- **WHEN** ein Formular-Korpusprogramm mit deklarierter Ereignisfolge ausgeführt wird
- **THEN** entspricht der Bildschirminhalt byte-genau der Sollausgabe
#### Scenario: Wiederholbarkeit
- **WHEN** dasselbe Programm zweimal ausgeführt wird
- **THEN** ist die Ausgabe beide Male identisch
### Requirement: Kompatibilitätsnachweis an Fremdprogrammen
Die Formularprogramme aus dem öffentlichen Bestand des Vorbilds SHALL
sich ohne Diagnosen oder Non-Features übersetzen lassen und bedienbar
sein. Jeder entdeckte fehlende Sprach-, Projekt-, Formular- oder
Laufzeitpfad MUST implementiert und als Befund festgehalten werden.
#### Scenario: Fremdprogramm übersetzt
- **WHEN** ein Formularprogramm des öffentlichen Bestands übersetzt wird
- **THEN** entstehen keine Diagnosen und das Programm ist bedienbar

View File

@@ -0,0 +1,49 @@
## 1. Festlegungen vorab
- [x] 1.1 Optik je Klasse und Zustand (normal, fokussiert, deaktiviert) als Zeichenbild in `docs/forms-referenz.md` festhalten, aus den Original-Screenshots abgeleitet (D3); verifiziert durch je ein Zeichenbild pro Klasse und Zustand
- [x] 1.2 Z-Reihenfolge und Timer-Reihenfolge festlegen und als unsere Festlegung kennzeichnen (D3); verifiziert durch die beiden Abschnitte in der Forms-Referenz
## 2. Darstellung und Eingabekette
- [x] 2.1 Zeichnen je Klasse aus dem Eigenschaftszustand in den Zellenpuffer (D1); verifiziert durch Snapshot-Tests je Klasse, darunter die drei Höhenformen des CommandButton
- [x] 2.2 Eingabekette für Tastatur und Maus (D2); verifiziert durch Unit-Tests, die je Station den Vorrang prüfen
- [x] 2.3 Trefferprüfung über die Z-Reihenfolge; verifiziert durch einen Test mit überlappenden Steuerelementen und einem Klick ins Formular
## 3. Fokus und Tastatur
- [x] 3.1 Tabreihenfolge über `TabIndex`/`TabStop` vorwärts und rückwärts, deaktivierte Elemente überspringen; verifiziert durch Unit-Tests je Fall
- [x] 3.2 Access-Keys aus `&`, `Default` für Enter, `Cancel` für Esc; verifiziert durch Unit-Tests je Auslöser
- [x] 3.3 `SETFOCUS`, `GotFocus`/`LostFocus` in der festgelegten Reihenfolge; verifiziert durch einen Test, der die Reihenfolge der beiden Ereignisse prüft
## 4. Steuerelementklassen
- [x] 4.1 CommandButton, Label, Frame, CheckBox, OptionButton (inkl. Gruppierung im Container); verifiziert durch Snapshot- und Verhaltenstests je Klasse
- [x] 4.2 TextBox mit `Text`, `SelStart`/`SelLength`/`SelText`, `MultiLine`, `ScrollBars`, Ereignis `Change`; verifiziert durch Tests für Eingabe, Auswahl und Umbruch
- [x] 4.3 ListBox und ComboBox mit `ADDITEM`/`REMOVEITEM`, `List`/`ListCount`/`ListIndex`, `Sorted`, den drei ComboBox-Stilarten; verifiziert durch Tests für Einfügen, Sortierung und „keine Auswahl"
- [x] 4.4 HScrollBar/VScrollBar mit `Min`/`Max`/`Value`/`SmallChange`/`LargeChange`/`Attached` und Ereignis `Change`; verifiziert durch Tests für Tastatur- und Mausbedienung
- [x] 4.5 PictureBox als Textzeichenfläche (`PRINT`, `CLS`, `CurrentX`/`CurrentY`, `TEXTWIDTH`/`TEXTHEIGHT`) und als Container; verifiziert durch Snapshot-Tests
- [x] 4.6 Timer auf der Zeitquelle der Ereignisschleife, Reihenfolge nach 1.2; verifiziert durch Tests mit virtueller Zeit für Abstand, `Interval = 0` und zwei gleichzeitig fällige Timer
- [x] 4.7 DirListBox, DriveListBox, FileListBox plattformneutral (D6) mit `Path`/`Drive`/`FileName`/`Pattern` und ihren Ereignissen; verifiziert durch Tests auf einem angelegten Verzeichnisbaum
- [x] 4.8 Ziehen und Ablegen: `DragMode`, `DRAG action%`, `DragOver` mit Zustand, `DragDrop` mit Quelle; verifiziert durch Tests für automatisches und manuelles Ziehen sowie Abbruch
## 5. Menüs und Dialoge
- [x] 5.1 Menüleiste mit bis zu sechs Ebenen, Access-Keys, Shortcuts, `Checked`/`Enabled`/`Visible`/`Separator`, Menü-Arrays; verifiziert durch Snapshot- und Verhaltenstests, darunter die Regelverstöße (Separator mit Shortcut)
- [x] 5.2 Ereigniszustellung ruht im geöffneten Menü über den vorhandenen `STOP`-Zustand (D5); verifiziert durch einen Test mit fälligem Zeit-Trap bei offenem Menü
- [x] 5.3 `MSGBOX` als Anweisung und Funktion mit Schaltflächengruppen, Vorgabeschaltfläche und Rückgabewerten; verifiziert durch Tests je Gruppe und Rückgabewert
- [x] 5.4 `INPUTBOX$` mit fester Größe 46×16, Positionierung in Zeichen, leerem String bei Abbruch; verifiziert durch Snapshot-Test und Abbruchtest
- [x] 5.5 Frontend-Signaturen für `MSGBOX` (Anweisung und Funktion) und `INPUTBOX$`, `Unsupported`-Absenkung entfernen; verifiziert durch `cargo test -p tb-frontend`
## 6. Korpus und Kompatibilität
- [x] 6.1 Ereignisfolge-Direktive im Programmkopf und ihre Einspeisung durch den Harness; verifiziert durch einen Harness-Test mit deklarierten Tasten-, Maus- und Zeitereignissen
- [x] 6.2 Formular-Korpusprogramme für Fokus/Tab, Access-Key, Mausklick, Menüauswahl, Liste, Timer und modalen Dialog; verifiziert durch `cargo test -p tb-cli` gegen die Sollausgaben
- [x] 6.3 Meilenstein: die Formularprogramme aus `github.com/cout/vbdos` übersetzen und bedienen, jeden Befund festhalten; verifiziert durch den Lauf über den Bestand mit Befundliste
- [x] 6.4 Meilenstein: die Beispiel-Formularprogramme des Korpus laufen; verifiziert durch den grünen Korpuslauf
## 7. Inventar, Dokumentation, Abschluss
- [x] 7.1 `docs/inventar.md`: Einträge dieses Changes auf `implementiert`; verifiziert durch `inventar_stimmt_mit_code_ueberein` mit Abdeckung 0 offen für Phase 4
- [x] 7.2 Abweichungen (Dateisystem-Steuerelemente, festgelegte Optik, Z- und Timer-Reihenfolge) in `docs/sprachreferenz.md` eintragen; verifiziert durch den Abschnitt „Abweichungen"
- [x] 7.3 PLAN.md: die verbleibenden Phase-4-Punkte abhaken und die Befunde der Phase festhalten; verifiziert durch die abgeschlossene Phase-4-Liste
- [x] 7.4 `cargo test` grün und `openspec validate phase-4-steuerelemente --strict` ohne Befund; verifiziert durch beide Kommandos

View File

@@ -0,0 +1,44 @@
# Befunde am öffentlichen VBDOS-Bestand
Geprüft wurde `cout/vbdos` im Commit
`1cdd2b32b829fe1721d0b6aecc433abc47a96fb6`. Maßgeblich waren die
vorhandenen `.MAK`-Projekte; wo keines existiert, wurde die `.FRM` direkt
verwendet. Jeder Eintrag bestand `tbc check` ohne Diagnose. Die Programme
wurden anschließend in einem 100×30-Pseudoterminal gestartet und blieben nach
dem Ende des Modulrumpfs bedienbar, bis ein Steuerelement das Formular schloss
oder der Lauf bewusst abgebrochen wurde.
| Programm | Check | Bediennachweis |
|---|---:|---|
| `graphics/graphics.mak` | 0 Diagnosen | Alt+X löst `cmdExit_Click` aus und entlädt das Formular |
| `microsoft/check.mak` | 0 Diagnosen | Alt+F öffnet das Menü; X erreicht den Exit-/Speicherdialogpfad |
| `microsoft/qlbview.mak` | 0 Diagnosen | Esc löst die Cancel-Schaltfläche aus und entlädt das Formular |
| `microsoft/seek.mak` | 0 Diagnosen | Alt+X löst `cmdExit_Click` aus und entlädt das Formular |
| `microsoft/spindemo.mak` | 0 Diagnosen | Tab und Pfeiltaste werden dem Text-/Spin-Steuerpfad zugestellt |
| `microsoft/notepad.frm` | 0 Diagnosen | Alt+F öffnet das Menü; X löst `mnuFileExit_Click` aus |
| `misc/mentors/mentors.frm` | 0 Diagnosen | Alt+F öffnet das Menü; X erreicht den Exit-/Speicherdialogpfad |
## Geschlossene Befunde
- `.MAK`-Einträge, `$INCLUDE` und `RUN` werden relativ und
DOS-großschreibungsunabhängig aufgelöst; mehrere Module und Formulare
werden als gemeinsames Programm übersetzt.
- Binärformular-P-Code behält Block- und Anweisungsgrenzen, numerische
Suffixe, Record-/UDT-Ausdrücke und Control-Arrays korrekt bei.
- Globale Arrays werden vor `Form_Load` initialisiert; `LEN(record)` liefert
die feste Satzbreite. `INPUT$` liest auch Binärdateien.
- `SCREEN.CONTROLPANEL(index)`, `CLIPBOARD` und `PRINTER` haben
Laufzeitverhalten; die von Notepad verwendeten Common-Dialog-Deklarationen
arbeiten über die vorhandenen Textdialoge.
- Die nativen Controls `VSpin` und `HSpin` werden als bedienbares `Spin`
importiert, einschließlich Wertgrenzen, Wiederholung und `Custom`-Ereignis.
- `SCREEN` 013 sowie die im Grafikbeispiel verwendeten Anweisungen `LINE`,
`PAINT` und `VIEW` zeichnen auf den Zellenpuffer.
- Modellose Formulare halten nach dem Modulrumpf die VM-Ereignisschleife
offen; Formularereignisse laufen auf derselben VM weiter, bis alle Formulare
geschlossen sind. Derselbe Pfad funktioniert im Terminal und mit
vorab eingelesener Pipe-Eingabe.
Damit sind alle während dieses Kompatibilitätslaufs gefundenen
Implementierungslücken geschlossen; es verbleibt kein dokumentierter oder
umgangener Befund.