Add StringGrid control type
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dd115d3727
commit
da21cc71f6
4 changed files with 392 additions and 8 deletions
|
|
@ -336,6 +336,7 @@ messages are available, dispatching each command as it arrives.
|
|||
| `Bevel` | TBevel | Cosmetic beveled line/box |
|
||||
| `Header` | THeader | Column header bar |
|
||||
| `ScrollBox` | TScrollBox | Scrollable container |
|
||||
| `StringGrid` | TStringGrid | Editable string grid |
|
||||
|
||||
### Creating Controls
|
||||
|
||||
|
|
@ -728,6 +729,91 @@ Input mask string (mask;save literals;blank char).
|
|||
- **Format:** `0` (bsLowered) or `1` (bsRaised)
|
||||
- **Example:** `Style=1`
|
||||
|
||||
### ColCount
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Integer (default 5)
|
||||
- **Example:** `ColCount=10`
|
||||
|
||||
Number of columns in the grid.
|
||||
|
||||
### RowCount
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Integer (default 5)
|
||||
- **Example:** `RowCount=20`
|
||||
|
||||
Number of rows in the grid.
|
||||
|
||||
### FixedCols
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Integer (default 1)
|
||||
- **Example:** `FixedCols=1`
|
||||
|
||||
Number of non-scrollable columns on the left.
|
||||
|
||||
### FixedRows
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Integer (default 1)
|
||||
- **Example:** `FixedRows=1`
|
||||
|
||||
Number of non-scrollable rows at the top.
|
||||
|
||||
### DefaultColWidth
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Integer (pixels)
|
||||
- **Example:** `DefaultColWidth=80`
|
||||
|
||||
### DefaultRowHeight
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Integer (pixels)
|
||||
- **Example:** `DefaultRowHeight=20`
|
||||
|
||||
### Options (StringGrid)
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Integer (bitmask)
|
||||
- **Example:** `Options=1549`
|
||||
|
||||
Bitmask of TGridOption values:
|
||||
|
||||
| Bit | Value | Option | Description |
|
||||
|-----|--------|---------------------|---------------------------|
|
||||
| 0 | 0x0001 | goFixedVertLine | Vertical lines on fixed |
|
||||
| 1 | 0x0002 | goFixedHorzLine | Horizontal lines on fixed |
|
||||
| 2 | 0x0004 | goVertLine | Vertical lines on cells |
|
||||
| 3 | 0x0008 | goHorzLine | Horizontal lines on cells |
|
||||
| 4 | 0x0010 | goRangeSelect | Allow range selection |
|
||||
| 5 | 0x0020 | goDrawFocusSelected | Draw focused cell selected|
|
||||
| 6 | 0x0040 | goRowSizing | Allow row resizing |
|
||||
| 7 | 0x0080 | goColSizing | Allow column resizing |
|
||||
| 8 | 0x0100 | goRowMoving | Allow row moving |
|
||||
| 9 | 0x0200 | goColMoving | Allow column moving |
|
||||
| 10 | 0x0400 | goEditing | Allow in-place editing |
|
||||
| 11 | 0x0800 | goTabs | Tab between cells |
|
||||
| 12 | 0x1000 | goThumbTracking | Track scrollbar thumb |
|
||||
|
||||
### Cells
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Quoted string (tab-delimited columns, `\n`-delimited rows)
|
||||
- **Example:** `Cells="Name\tAge\nAlice\t30\nBob\t25"`
|
||||
|
||||
Bulk-loads all cell data. Columns are separated by tab characters,
|
||||
rows by newlines. Row 0 is the first row (typically fixed header).
|
||||
|
||||
### Cell
|
||||
|
||||
- **Applies to:** StringGrid
|
||||
- **Format:** Quoted string (`col,row,value`)
|
||||
- **Example:** `Cell="1,2,Hello"`
|
||||
|
||||
Sets a single cell value. Column and row are zero-based indices.
|
||||
|
||||
### BasePath
|
||||
|
||||
`BasePath` is a property on `TFormClient` (not a protocol property).
|
||||
|
|
@ -766,6 +852,7 @@ No `EVENT.BIND` command is needed.
|
|||
| TabSet | Change | `<tabIndex>` |
|
||||
| TabbedNotebook | Change | `<pageIndex>` |
|
||||
| MaskEdit | Change | `"new text"` |
|
||||
| StringGrid | SelectCell | `<col> <row>` |
|
||||
|
||||
### Opt-in Events
|
||||
|
||||
|
|
@ -784,6 +871,7 @@ client will send them. Use `EVENT.UNBIND` to disconnect.
|
|||
| MouseDown | `<x> <y> <button>` | 0=left, 1=right, 2=middle |
|
||||
| MouseUp | `<x> <y> <button>` | 0=left, 1=right, 2=middle |
|
||||
| MouseMove | `<x> <y> 0` | Coordinates relative to control |
|
||||
| SetEditText | `<col> <row> "text"` | StringGrid in-place edit |
|
||||
|
||||
### Form Close Event
|
||||
|
||||
|
|
|
|||
100
forms/dfm2form.c
100
forms/dfm2form.c
|
|
@ -46,7 +46,8 @@ typedef enum {
|
|||
ctOutline,
|
||||
ctBevel,
|
||||
ctHeader,
|
||||
ctScrollBox
|
||||
ctScrollBox,
|
||||
ctStringGrid
|
||||
} CtrlTypeE;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -140,6 +141,21 @@ typedef struct {
|
|||
bool hasShape;
|
||||
bool hasStyle;
|
||||
bool hasEditMask;
|
||||
int32_t colCount;
|
||||
int32_t rowCount;
|
||||
int32_t fixedCols;
|
||||
int32_t fixedRows;
|
||||
int32_t defaultColWidth;
|
||||
int32_t defaultRowHeight;
|
||||
int32_t options;
|
||||
bool hasColCount;
|
||||
bool hasRowCount;
|
||||
bool hasFixedCols;
|
||||
bool hasFixedRows;
|
||||
bool hasDefaultColWidth;
|
||||
bool hasDefaultRowHeight;
|
||||
bool hasOptions;
|
||||
bool hasOnSetEditText;
|
||||
} DfmCtrlT;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -439,6 +455,9 @@ static CtrlTypeE mapClassName(const char *className) {
|
|||
if (stricmp_local(className, "TScrollBox") == 0) {
|
||||
return ctScrollBox;
|
||||
}
|
||||
if (stricmp_local(className, "TStringGrid") == 0) {
|
||||
return ctStringGrid;
|
||||
}
|
||||
return ctUnknown;
|
||||
}
|
||||
|
||||
|
|
@ -1013,6 +1032,59 @@ static void parseProperties(const uint8_t *data, int32_t size, int32_t *pos, Dfm
|
|||
ctrl->style = readIntValue(data, size, pos, tag);
|
||||
}
|
||||
ctrl->hasStyle = true;
|
||||
} else if (!isForm && stricmp_local(propName, "ColCount") == 0) {
|
||||
ctrl->colCount = readIntValue(data, size, pos, tag);
|
||||
ctrl->hasColCount = true;
|
||||
} else if (!isForm && stricmp_local(propName, "RowCount") == 0) {
|
||||
ctrl->rowCount = readIntValue(data, size, pos, tag);
|
||||
ctrl->hasRowCount = true;
|
||||
} else if (!isForm && stricmp_local(propName, "FixedCols") == 0) {
|
||||
ctrl->fixedCols = readIntValue(data, size, pos, tag);
|
||||
ctrl->hasFixedCols = true;
|
||||
} else if (!isForm && stricmp_local(propName, "FixedRows") == 0) {
|
||||
ctrl->fixedRows = readIntValue(data, size, pos, tag);
|
||||
ctrl->hasFixedRows = true;
|
||||
} else if (!isForm && stricmp_local(propName, "DefaultColWidth") == 0) {
|
||||
ctrl->defaultColWidth = readIntValue(data, size, pos, tag);
|
||||
ctrl->hasDefaultColWidth = true;
|
||||
} else if (!isForm && stricmp_local(propName, "DefaultRowHeight") == 0) {
|
||||
ctrl->defaultRowHeight = readIntValue(data, size, pos, tag);
|
||||
ctrl->hasDefaultRowHeight = true;
|
||||
} else if (!isForm && stricmp_local(propName, "Options") == 0) {
|
||||
if (tag == vaSet) {
|
||||
ctrl->options = 0;
|
||||
while (*pos < size) {
|
||||
readStr(data, size, pos, strBuf, sizeof(strBuf));
|
||||
if (strBuf[0] == '\0') {
|
||||
break;
|
||||
}
|
||||
if (stricmp_local(strBuf, "goFixedVertLine") == 0) { ctrl->options |= 0x0001; }
|
||||
else if (stricmp_local(strBuf, "goFixedHorzLine") == 0) { ctrl->options |= 0x0002; }
|
||||
else if (stricmp_local(strBuf, "goVertLine") == 0) { ctrl->options |= 0x0004; }
|
||||
else if (stricmp_local(strBuf, "goHorzLine") == 0) { ctrl->options |= 0x0008; }
|
||||
else if (stricmp_local(strBuf, "goRangeSelect") == 0) { ctrl->options |= 0x0010; }
|
||||
else if (stricmp_local(strBuf, "goDrawFocusSelected") == 0) { ctrl->options |= 0x0020; }
|
||||
else if (stricmp_local(strBuf, "goRowSizing") == 0) { ctrl->options |= 0x0040; }
|
||||
else if (stricmp_local(strBuf, "goColSizing") == 0) { ctrl->options |= 0x0080; }
|
||||
else if (stricmp_local(strBuf, "goRowMoving") == 0) { ctrl->options |= 0x0100; }
|
||||
else if (stricmp_local(strBuf, "goColMoving") == 0) { ctrl->options |= 0x0200; }
|
||||
else if (stricmp_local(strBuf, "goEditing") == 0) { ctrl->options |= 0x0400; }
|
||||
else if (stricmp_local(strBuf, "goTabs") == 0) { ctrl->options |= 0x0800; }
|
||||
else if (stricmp_local(strBuf, "goThumbTracking") == 0) { ctrl->options |= 0x1000; }
|
||||
}
|
||||
} else {
|
||||
ctrl->options = readIntValue(data, size, pos, tag);
|
||||
}
|
||||
ctrl->hasOptions = true;
|
||||
} else if (stricmp_local(propName, "OnSetEditText") == 0) {
|
||||
if (tag == vaIdent) {
|
||||
readStr(data, size, pos, strBuf, sizeof(strBuf));
|
||||
} else {
|
||||
skipValue(data, size, pos, tag);
|
||||
}
|
||||
if (!isForm) {
|
||||
ctrl->hasOnSetEditText = true;
|
||||
}
|
||||
} else {
|
||||
skipValue(data, size, pos, tag);
|
||||
}
|
||||
|
|
@ -1160,7 +1232,7 @@ static void emitCtrl(FILE *out, int32_t formId, int32_t ctrlId, DfmCtrlT *ctrl)
|
|||
"MainMenu", "PopupMenu", "MenuItem", "RadioGroup",
|
||||
"BitBtn", "SpeedButton", "TabSet", "Notebook",
|
||||
"TabbedNotebook", "MaskEdit", "Outline", "Bevel",
|
||||
"Header", "ScrollBox"
|
||||
"Header", "ScrollBox", "StringGrid"
|
||||
};
|
||||
char escaped[8192];
|
||||
|
||||
|
|
@ -1291,6 +1363,27 @@ static void emitCtrl(FILE *out, int32_t formId, int32_t ctrlId, DfmCtrlT *ctrl)
|
|||
if (ctrl->hasStyle && ctrl->style != 0) {
|
||||
fprintf(out, " Style=%d", ctrl->style);
|
||||
}
|
||||
if (ctrl->hasColCount) {
|
||||
fprintf(out, " ColCount=%d", ctrl->colCount);
|
||||
}
|
||||
if (ctrl->hasRowCount) {
|
||||
fprintf(out, " RowCount=%d", ctrl->rowCount);
|
||||
}
|
||||
if (ctrl->hasFixedCols) {
|
||||
fprintf(out, " FixedCols=%d", ctrl->fixedCols);
|
||||
}
|
||||
if (ctrl->hasFixedRows) {
|
||||
fprintf(out, " FixedRows=%d", ctrl->fixedRows);
|
||||
}
|
||||
if (ctrl->hasDefaultColWidth) {
|
||||
fprintf(out, " DefaultColWidth=%d", ctrl->defaultColWidth);
|
||||
}
|
||||
if (ctrl->hasDefaultRowHeight) {
|
||||
fprintf(out, " DefaultRowHeight=%d", ctrl->defaultRowHeight);
|
||||
}
|
||||
if (ctrl->hasOptions) {
|
||||
fprintf(out, " Options=%d", ctrl->options);
|
||||
}
|
||||
|
||||
fprintf(out, "\n");
|
||||
|
||||
|
|
@ -1329,6 +1422,9 @@ static void emitCtrl(FILE *out, int32_t formId, int32_t ctrlId, DfmCtrlT *ctrl)
|
|||
if (ctrl->hasOnMouseUp) {
|
||||
fprintf(out, "EVENT.BIND %d %d MouseUp\n", formId, ctrlId);
|
||||
}
|
||||
if (ctrl->hasOnSetEditText) {
|
||||
fprintf(out, "EVENT.BIND %d %d SetEditText\n", formId, ctrlId);
|
||||
}
|
||||
|
||||
// Suppress unused variable warning for autoSelect
|
||||
(void)autoSelect;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ interface
|
|||
|
||||
uses
|
||||
SysUtils, Classes, Controls, Forms, StdCtrls, ExtCtrls, Menus, Buttons, Tabs,
|
||||
TabNotBk, Mask, Outline, MPlayer, WinTypes, WinProcs;
|
||||
TabNotBk, Mask, Outline, Grids, MPlayer, WinTypes, WinProcs;
|
||||
|
||||
const
|
||||
MaxMsgLen = 4096;
|
||||
|
|
@ -34,12 +34,12 @@ type
|
|||
ctMainMenu, ctPopupMenu, ctMenuItem, ctRadioGroup,
|
||||
ctBitBtn, ctSpeedButton, ctTabSet, ctNotebook,
|
||||
ctTabbedNotebook, ctMaskEdit, ctOutline, ctBevel,
|
||||
ctHeader, ctScrollBox);
|
||||
ctHeader, ctScrollBox, ctStringGrid);
|
||||
|
||||
{ Bound event flags }
|
||||
TBoundEvent = (beDblClick, beKeyDown, beKeyUp,
|
||||
beEnter, beExit, beMouseDown, beMouseUp, beMouseMove,
|
||||
beClick, beNotify);
|
||||
beClick, beNotify, beSetEditText);
|
||||
TBoundEvents = set of TBoundEvent;
|
||||
|
||||
{ Per-control record }
|
||||
|
|
@ -120,6 +120,8 @@ type
|
|||
procedure HandleRadioGroupClick(Sender: TObject);
|
||||
procedure HandleTabSetChange(Sender: TObject);
|
||||
procedure HandleTabbedNotebookChange(Sender: TObject);
|
||||
procedure HandleStringGridSelectCell(Sender: TObject; ACol, ARow: Longint; var CanSelect: Boolean);
|
||||
procedure HandleStringGridSetEditText(Sender: TObject; ACol, ARow: Longint; const Value: string);
|
||||
|
||||
{ Outgoing event helpers }
|
||||
procedure SendEvent(FormId, CtrlId: Integer; const EventName: string; const Data: string);
|
||||
|
|
@ -777,6 +779,36 @@ begin
|
|||
end;
|
||||
|
||||
|
||||
procedure TFormClient.HandleStringGridSelectCell(Sender: TObject; ACol, ARow: Longint; var CanSelect: Boolean);
|
||||
var
|
||||
Tag: Longint;
|
||||
FormId: Integer;
|
||||
CtrlId: Integer;
|
||||
begin
|
||||
Tag := (Sender as TComponent).Tag;
|
||||
FormId := Tag shr 16;
|
||||
CtrlId := Tag and $FFFF;
|
||||
SendEvent(FormId, CtrlId, 'SelectCell', IntToStr(ACol) + ' ' + IntToStr(ARow));
|
||||
CanSelect := True;
|
||||
end;
|
||||
|
||||
|
||||
procedure TFormClient.HandleStringGridSetEditText(Sender: TObject; ACol, ARow: Longint; const Value: string);
|
||||
var
|
||||
Tag: Longint;
|
||||
FormId: Integer;
|
||||
CtrlId: Integer;
|
||||
Escaped: array[0..4095] of Char;
|
||||
begin
|
||||
Tag := (Sender as TComponent).Tag;
|
||||
FormId := Tag shr 16;
|
||||
CtrlId := Tag and $FFFF;
|
||||
StrPCopy(FTmpBuf, Value);
|
||||
EscapeString(FTmpBuf, Escaped, SizeOf(Escaped));
|
||||
SendEvent(FormId, CtrlId, 'SetEditText', IntToStr(ACol) + ' ' + IntToStr(ARow) + ' "' + StrPas(Escaped) + '"');
|
||||
end;
|
||||
|
||||
|
||||
procedure TFormClient.HandleFormClose(Sender: TObject;
|
||||
var Action: TCloseAction);
|
||||
var
|
||||
|
|
@ -828,6 +860,8 @@ begin
|
|||
(CR^.Control as TTabbedNotebook).OnChange := HandleTabbedNotebookChange;
|
||||
ctMaskEdit:
|
||||
(CR^.Control as TMaskEdit).OnChange := HandleMaskEditChange;
|
||||
ctStringGrid:
|
||||
(CR^.Control as TStringGrid).OnSelectCell := HandleStringGridSelectCell;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -897,6 +931,12 @@ begin
|
|||
if CR^.Control is TMediaPlayer then
|
||||
(CR^.Control as TMediaPlayer).OnNotify := HandleMediaPlayerNotify;
|
||||
CR^.Bound := CR^.Bound + [beNotify];
|
||||
end
|
||||
else if EventName = 'SetEditText' then
|
||||
begin
|
||||
if CR^.Control is TStringGrid then
|
||||
(CR^.Control as TStringGrid).OnSetEditText := HandleStringGridSetEditText;
|
||||
CR^.Bound := CR^.Bound + [beSetEditText];
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -966,6 +1006,12 @@ begin
|
|||
if CR^.Control is TMediaPlayer then
|
||||
(CR^.Control as TMediaPlayer).OnNotify := nil;
|
||||
CR^.Bound := CR^.Bound - [beNotify];
|
||||
end
|
||||
else if EventName = 'SetEditText' then
|
||||
begin
|
||||
if CR^.Control is TStringGrid then
|
||||
(CR^.Control as TStringGrid).OnSetEditText := nil;
|
||||
CR^.Bound := CR^.Bound - [beSetEditText];
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -981,6 +1027,10 @@ var
|
|||
P: PChar;
|
||||
Start: PChar;
|
||||
PCR: PFormCtrlRec;
|
||||
Col: Integer;
|
||||
Row: Integer;
|
||||
W: Word;
|
||||
Opts: TGridOptions;
|
||||
begin
|
||||
S := StrPas(Key);
|
||||
|
||||
|
|
@ -1538,6 +1588,119 @@ begin
|
|||
N := StrToIntDef(StrPas(Value), 0);
|
||||
if CR^.CtrlType = ctBevel then
|
||||
(CR^.Control as TBevel).Style := TBevelStyle(N);
|
||||
end
|
||||
else if S = 'ColCount' then
|
||||
begin
|
||||
N := StrToIntDef(StrPas(Value), 5);
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
(CR^.Control as TStringGrid).ColCount := N;
|
||||
end
|
||||
else if S = 'RowCount' then
|
||||
begin
|
||||
N := StrToIntDef(StrPas(Value), 5);
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
(CR^.Control as TStringGrid).RowCount := N;
|
||||
end
|
||||
else if S = 'FixedCols' then
|
||||
begin
|
||||
N := StrToIntDef(StrPas(Value), 1);
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
(CR^.Control as TStringGrid).FixedCols := N;
|
||||
end
|
||||
else if S = 'FixedRows' then
|
||||
begin
|
||||
N := StrToIntDef(StrPas(Value), 1);
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
(CR^.Control as TStringGrid).FixedRows := N;
|
||||
end
|
||||
else if S = 'DefaultColWidth' then
|
||||
begin
|
||||
N := StrToIntDef(StrPas(Value), 64);
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
(CR^.Control as TStringGrid).DefaultColWidth := N;
|
||||
end
|
||||
else if S = 'DefaultRowHeight' then
|
||||
begin
|
||||
N := StrToIntDef(StrPas(Value), 24);
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
(CR^.Control as TStringGrid).DefaultRowHeight := N;
|
||||
end
|
||||
else if S = 'Options' then
|
||||
begin
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
begin
|
||||
N := StrToIntDef(StrPas(Value), 0);
|
||||
W := Word(N);
|
||||
Move(W, Opts, SizeOf(Opts));
|
||||
(CR^.Control as TStringGrid).Options := Opts;
|
||||
end;
|
||||
end
|
||||
else if S = 'Cells' then
|
||||
begin
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
begin
|
||||
UnescapeString(Value, Unesc, SizeOf(Unesc));
|
||||
Row := 0;
|
||||
P := Unesc;
|
||||
while P^ <> #0 do
|
||||
begin
|
||||
{ Parse one row: tab-delimited columns }
|
||||
Col := 0;
|
||||
Start := P;
|
||||
while (P^ <> #0) and (P^ <> #10) do
|
||||
begin
|
||||
if P^ = #9 then
|
||||
begin
|
||||
P^ := #0;
|
||||
if (Col < (CR^.Control as TStringGrid).ColCount) and (Row < (CR^.Control as TStringGrid).RowCount) then
|
||||
(CR^.Control as TStringGrid).Cells[Col, Row] := StrPas(Start);
|
||||
Inc(Col);
|
||||
Inc(P);
|
||||
Start := P;
|
||||
end
|
||||
else
|
||||
Inc(P);
|
||||
end;
|
||||
{ Last column in row }
|
||||
if (Col < (CR^.Control as TStringGrid).ColCount) and (Row < (CR^.Control as TStringGrid).RowCount) then
|
||||
(CR^.Control as TStringGrid).Cells[Col, Row] := StrPas(Start);
|
||||
if P^ = #10 then
|
||||
Inc(P);
|
||||
Inc(Row);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else if S = 'Cell' then
|
||||
begin
|
||||
if CR^.CtrlType = ctStringGrid then
|
||||
begin
|
||||
{ Format: "col,row,value" }
|
||||
UnescapeString(Value, Unesc, SizeOf(Unesc));
|
||||
P := Unesc;
|
||||
{ Parse col }
|
||||
Start := P;
|
||||
while (P^ <> #0) and (P^ <> ',') do
|
||||
Inc(P);
|
||||
if P^ = ',' then
|
||||
begin
|
||||
P^ := #0;
|
||||
Col := StrToIntDef(StrPas(Start), 0);
|
||||
Inc(P);
|
||||
{ Parse row }
|
||||
Start := P;
|
||||
while (P^ <> #0) and (P^ <> ',') do
|
||||
Inc(P);
|
||||
if P^ = ',' then
|
||||
begin
|
||||
P^ := #0;
|
||||
Row := StrToIntDef(StrPas(Start), 0);
|
||||
Inc(P);
|
||||
{ Rest is value }
|
||||
if (Col < (CR^.Control as TStringGrid).ColCount) and (Row < (CR^.Control as TStringGrid).RowCount) then
|
||||
(CR^.Control as TStringGrid).Cells[Col, Row] := StrPas(P);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
@ -1656,6 +1819,8 @@ begin
|
|||
Result := ctHeader
|
||||
else if S = 'ScrollBox' then
|
||||
Result := ctScrollBox
|
||||
else if S = 'StringGrid' then
|
||||
Result := ctStringGrid
|
||||
else
|
||||
Result := ctUnknown;
|
||||
end;
|
||||
|
|
@ -1833,6 +1998,8 @@ begin
|
|||
Comp := THeader.Create(FR^.Form);
|
||||
ctScrollBox:
|
||||
Comp := TScrollBox.Create(FR^.Form);
|
||||
ctStringGrid:
|
||||
Comp := TStringGrid.Create(FR^.Form);
|
||||
end;
|
||||
|
||||
if Comp = nil then
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ Event data varies by event type:
|
|||
| Exit | (none) |
|
||||
| Close | (none) |
|
||||
| Notify | (none) |
|
||||
| SelectCell| `<col> <row>` |
|
||||
| SetEditText| `<col> <row> "text"` |
|
||||
|
||||
## Control Types
|
||||
|
||||
|
|
@ -115,6 +117,7 @@ Event data varies by event type:
|
|||
| Bevel | TBevel | (none) |
|
||||
| Header | THeader | (none) |
|
||||
| ScrollBox | TScrollBox | (none) |
|
||||
| StringGrid | TStringGrid | SelectCell |
|
||||
|
||||
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
|
||||
|
|
@ -125,9 +128,9 @@ 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.
|
||||
Notify (MediaPlayer), SetEditText (StringGrid), DblClick, KeyDown,
|
||||
KeyUp, Enter, Exit, MouseDown, MouseUp, MouseMove. Menu and
|
||||
RadioGroup components do not support opt-in events.
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
@ -174,6 +177,15 @@ not support opt-in events.
|
|||
| OutlineStyle| Outline | 0-6 (osText..osTreePictureText) |
|
||||
| Shape | Bevel | 0-5 (bsBox..bsRightLine) |
|
||||
| Style | Bevel | 0-1 (bsLowered, bsRaised) |
|
||||
| ColCount | StringGrid | Integer (default 5) |
|
||||
| RowCount | StringGrid | Integer (default 5) |
|
||||
| FixedCols | StringGrid | Integer (default 1) |
|
||||
| FixedRows | StringGrid | Integer (default 1) |
|
||||
| DefaultColWidth | StringGrid | Integer (pixels) |
|
||||
| DefaultRowHeight| StringGrid | Integer (pixels) |
|
||||
| Options | StringGrid | Integer (bitmask, see below) |
|
||||
| Cells | StringGrid | Quoted string (tab-delimited cols, `\n`-delimited rows) |
|
||||
| Cell | StringGrid | Quoted string (`col,row,value`) |
|
||||
|
||||
File path properties (Picture, FileName) are resolved relative to the
|
||||
client's `BasePath` setting. Subdirectories are allowed (e.g.,
|
||||
|
|
@ -185,6 +197,27 @@ MediaPlayer rather than setting a value. Valid commands: `Open`,
|
|||
`Play`, `Stop`, `Close`, `Pause`, `Resume`, `Rewind`, `Next`,
|
||||
`Previous`.
|
||||
|
||||
StringGrid Options is an integer bitmask of TGridOption values:
|
||||
|
||||
| Bit | Value | Option |
|
||||
|--------|--------|---------------------|
|
||||
| 0 | 0x0001 | goFixedVertLine |
|
||||
| 1 | 0x0002 | goFixedHorzLine |
|
||||
| 2 | 0x0004 | goVertLine |
|
||||
| 3 | 0x0008 | goHorzLine |
|
||||
| 4 | 0x0010 | goRangeSelect |
|
||||
| 5 | 0x0020 | goDrawFocusSelected |
|
||||
| 6 | 0x0040 | goRowSizing |
|
||||
| 7 | 0x0080 | goColSizing |
|
||||
| 8 | 0x0100 | goRowMoving |
|
||||
| 9 | 0x0200 | goColMoving |
|
||||
| 10 | 0x0400 | goEditing |
|
||||
| 11 | 0x0800 | goTabs |
|
||||
| 12 | 0x1000 | goThumbTracking |
|
||||
|
||||
Cells is a bulk-load property: columns are tab-delimited, rows are
|
||||
`\n`-delimited. Cell is an individual update: `"col,row,value"`.
|
||||
|
||||
## String Encoding
|
||||
|
||||
- Strings in the protocol are always double-quoted.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue