WinComm/forms/protocol.md
Scott Duensing dd115d3727 Add BitBtn, SpeedButton, TabSet, Notebook, TabbedNotebook, MaskEdit, Outline, Bevel, Header, and ScrollBox control types
Completes the Delphi 1.0 Standard, Additional, and Win31 component
palettes. DFM parser maps Tabs/Lines/Pages/Sections.Strings to Items
and TabIndex/PageIndex to ItemIndex. Kind extended with bk* idents
for BitBtn.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:13:59 -06:00

10 KiB

Remote Forms Protocol

Overview

Text-based protocol for remote GUI. A C server on Linux sends form/control commands over a transport layer; a Delphi 1.0 client on Windows 3.1 creates native controls and sends user events back.

Message Format

  • One command per message.
  • Transport delivers whole messages (today: newline-delimited over serial).
  • Strings are double-quoted with escapes: \" \\ \n \r \t.
  • Bare tokens (IDs, numbers, type names) are whitespace-delimited.
  • IDs are positive integers assigned by the server.

Server → Client Commands

FORM.CREATE

FORM.CREATE <formId> <width> <height> "<title>"

Create a new form with the given dimensions and title. The form is not shown until FORM.SHOW is sent.

FORM.SHOW

FORM.SHOW <formId>

FORM.HIDE

FORM.HIDE <formId>

FORM.DESTROY

FORM.DESTROY <formId>

Free the form and all its controls.

CTRL.CREATE

CTRL.CREATE <formId> <ctrlId> <type> <left> <top> <width> <height> [Key="val" ...]

Create a control on the specified form. Inline key/value properties are applied immediately after creation. See Control Types and Properties below.

CTRL.SET

CTRL.SET <formId> <ctrlId> Key="val" [Key="val" ...]

Update one or more properties on an existing control.

EVENT.BIND

EVENT.BIND <formId> <ctrlId> <eventName>

Wire an opt-in event handler. Auto-wired events do not need explicit binding.

EVENT.UNBIND

EVENT.UNBIND <formId> <ctrlId> <eventName>

Remove an event handler.

Client → Server Events

EVENT <formId> <ctrlId> <eventName> [<data>]

Event data varies by event type:

Event Data
Click (none), or <itemIndex> (RadioGroup)
DblClick (none)
Change "new text", <position> (ScrollBar), or <index> (TabSet, TabbedNotebook)
Select <index> "selected text"
KeyDown <vkCode>
KeyUp <vkCode>
MouseDown <x> <y> <button>
MouseUp <x> <y> <button>
MouseMove <x> <y> <button>
Enter (none)
Exit (none)
Close (none)
Notify (none)

Control Types

Type Delphi Class Auto-wired Events
Label TLabel (none)
Edit TEdit Change
Button TButton Click
CheckBox TCheckBox Click
ListBox TListBox Select
ComboBox TComboBox Select, Change
Memo TMemo Change
Image TImage (none)
GroupBox TGroupBox (none)
RadioButton TRadioButton Click
Panel TPanel (none)
ScrollBar TScrollBar Change
MediaPlayer TMediaPlayer (none)
MainMenu TMainMenu (none)
PopupMenu TPopupMenu (none)
MenuItem TMenuItem Click
RadioGroup TRadioGroup Click
BitBtn TBitBtn Click
SpeedButton TSpeedButton Click
TabSet TTabSet Change
Notebook TNotebook (none)
TabbedNotebook TTabbedNotebook Change
MaskEdit TMaskEdit Change
Outline TOutline (none)
Bevel TBevel (none)
Header THeader (none)
ScrollBox TScrollBox (none)

MainMenu and PopupMenu use 0 0 0 0 geometry (non-visual). MenuItem uses 0 0 0 0 geometry and requires a Parent property to specify its parent menu or menu item. One MainMenu per form (auto-attached). PopupMenu is associated with any control via the PopupMenu property.

GroupBox and Panel are cosmetic containers (flat parent model — no child containment in the protocol). RadioButtons are all in one group per form.

Opt-in events (require EVENT.BIND): Click (Image, GroupBox, Panel), Notify (MediaPlayer), DblClick, KeyDown, KeyUp, Enter, Exit, MouseDown, MouseUp, MouseMove. Menu and RadioGroup components do not support opt-in events.

Properties

Property Applies To Value Format
Caption Label, Button, CheckBox, GroupBox, RadioButton, Panel, MenuItem, RadioGroup, BitBtn, SpeedButton Quoted string
Text Edit, ComboBox, Memo, MaskEdit Quoted string (\n for line breaks)
Items ListBox, ComboBox, RadioGroup, TabSet, Notebook, TabbedNotebook, Outline, Header Quoted string (\n-delimited)
Checked CheckBox, RadioButton, MenuItem 0 or 1
Enabled All 0 or 1
Visible All 0 or 1
MaxLength Edit, MaskEdit Integer
ReadOnly Edit, Memo 0 or 1
ScrollBars Memo 0-3 (ssNone..ssBoth)
ItemIndex ListBox, ComboBox, RadioGroup, TabSet, Notebook, TabbedNotebook Integer (-1 = none)
TabOrder All windowed controls Integer
Stretch Image 0 or 1
Center Image 0 or 1
Transparent Image 0 or 1
Picture Image Quoted string (filename, BMP only)
BevelOuter Panel 0-2 (bvNone, bvLowered, bvRaised)
BevelInner Panel 0-2 (bvNone, bvLowered, bvRaised)
BorderStyle Panel 0-1 (bsNone, bsSingle)
Kind ScrollBar, BitBtn Integer (see below)
Min ScrollBar Integer
Max ScrollBar Integer
Position ScrollBar Integer
LargeChange ScrollBar Integer
SmallChange ScrollBar Integer
FileName MediaPlayer Quoted string (media file path)
DeviceType MediaPlayer Quoted string (e.g., dtWaveAudio)
AutoOpen MediaPlayer 0 or 1
Command MediaPlayer Quoted string (pseudo-property, see below)
Parent MenuItem Integer (ctrlId of parent menu/item)
Columns RadioGroup Integer (number of columns)
ShortCut MenuItem Integer (Delphi ShortCut value)
PopupMenu Any TControl Integer (ctrlId of PopupMenu)
Layout BitBtn, SpeedButton 0-3 (blGlyphLeft..blGlyphBottom)
NumGlyphs BitBtn, SpeedButton Integer (1-4)
GroupIndex SpeedButton Integer (0 = no group)
Down SpeedButton 0 or 1
AllowAllUp SpeedButton 0 or 1
EditMask MaskEdit Quoted string
OutlineStyle Outline 0-6 (osText..osTreePictureText)
Shape Bevel 0-5 (bsBox..bsRightLine)
Style Bevel 0-1 (bsLowered, bsRaised)

File path properties (Picture, FileName) are resolved relative to the client's BasePath setting. Subdirectories are allowed (e.g., Picture="images\logo.bmp" with BasePath=C:\MYAPP resolves to C:\MYAPP\images\logo.bmp).

Command is a pseudo-property that triggers a method call on the MediaPlayer rather than setting a value. Valid commands: Open, Play, Stop, Close, Pause, Resume, Rewind, Next, Previous.

String Encoding

  • Strings in the protocol are always double-quoted.
  • Escape sequences: \" (literal quote), \\ (literal backslash), \n (newline), \r (carriage return), \t (tab).
  • Multi-line values (Memo text, ListBox items) use \n within a single quoted string.

Transport Layer

The protocol is transport-agnostic. Messages are delivered via:

int  ReadMessage(char *buf, int maxLen);   // returns bytes read, 0 = none
void WriteMessage(const char *buf);        // sends complete message

Current transport: newline-delimited serial (messages terminated by CR+LF). The transport handles framing; protocol layer never sees delimiters.