MsgBox()
This commit is contained in:
parent
0ef46ff6a0
commit
657b44eb25
62 changed files with 591 additions and 104 deletions
|
|
@ -187,7 +187,7 @@
|
|||
#define OP_SHOW_FORM 0x85 // [uint8 modal] pop formRef, show it
|
||||
#define OP_HIDE_FORM 0x86 // pop formRef, hide it
|
||||
#define OP_DO_EVENTS 0x87
|
||||
#define OP_MSGBOX 0x88 // [uint8 flags] pop message string, push result
|
||||
#define OP_MSGBOX 0x88 // pop flags, pop message string, push result
|
||||
#define OP_INPUTBOX 0x89 // pop default, pop title, pop prompt, push result string
|
||||
#define OP_ME_REF 0x8A // push current form reference
|
||||
#define OP_CREATE_CTRL 0x8B // pop name, pop typeName, pop formRef, push controlRef
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ static const BuiltinFuncT builtinFuncs[] = {
|
|||
// Helper prototypes (alphabetized)
|
||||
// ============================================================
|
||||
|
||||
static void addPredefConst(BasParserT *p, const char *name, int32_t val);
|
||||
static void addPredefConsts(BasParserT *p);
|
||||
static void advance(BasParserT *p);
|
||||
static bool check(BasParserT *p, BasTokenTypeE type);
|
||||
static bool checkKeyword(BasParserT *p, const char *kw);
|
||||
|
|
@ -212,6 +214,39 @@ static void exitListPatch(ExitListT *el, BasParserT *p);
|
|||
// Helper implementations
|
||||
// ============================================================
|
||||
|
||||
static void addPredefConst(BasParserT *p, const char *name, int32_t val) {
|
||||
BasSymbolT *sym = basSymTabAdd(&p->sym, name, SYM_CONST, BAS_TYPE_LONG);
|
||||
if (sym) {
|
||||
sym->constInt = val;
|
||||
sym->isDefined = true;
|
||||
sym->scope = SCOPE_GLOBAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void addPredefConsts(BasParserT *p) {
|
||||
// MsgBox button flags (VB3 compatible)
|
||||
addPredefConst(p, "vbOKOnly", 0x0000);
|
||||
addPredefConst(p, "vbOKCancel", 0x0001);
|
||||
addPredefConst(p, "vbYesNo", 0x0002);
|
||||
addPredefConst(p, "vbYesNoCancel", 0x0003);
|
||||
addPredefConst(p, "vbRetryCancel", 0x0004);
|
||||
|
||||
// MsgBox icon flags
|
||||
addPredefConst(p, "vbInformation", 0x0010);
|
||||
addPredefConst(p, "vbExclamation", 0x0020);
|
||||
addPredefConst(p, "vbCritical", 0x0030);
|
||||
addPredefConst(p, "vbQuestion", 0x0040);
|
||||
|
||||
// MsgBox return values
|
||||
addPredefConst(p, "vbOK", 1);
|
||||
addPredefConst(p, "vbCancel", 2);
|
||||
addPredefConst(p, "vbYes", 3);
|
||||
addPredefConst(p, "vbNo", 4);
|
||||
addPredefConst(p, "vbRetry", 5);
|
||||
}
|
||||
|
||||
|
||||
static void advance(BasParserT *p) {
|
||||
if (p->hasError) {
|
||||
return;
|
||||
|
|
@ -1131,6 +1166,22 @@ static void parsePrimary(BasParserT *p) {
|
|||
return;
|
||||
}
|
||||
|
||||
// MsgBox(message [, flags]) -- as function expression returning button ID
|
||||
if (tt == TOK_MSGBOX) {
|
||||
advance(p);
|
||||
expect(p, TOK_LPAREN);
|
||||
parseExpression(p); // message
|
||||
if (match(p, TOK_COMMA)) {
|
||||
parseExpression(p); // flags
|
||||
} else {
|
||||
basEmit8(&p->cg, OP_PUSH_INT16);
|
||||
basEmit16(&p->cg, 0); // default flags = vbOKOnly
|
||||
}
|
||||
expect(p, TOK_RPAREN);
|
||||
basEmit8(&p->cg, OP_MSGBOX);
|
||||
return;
|
||||
}
|
||||
|
||||
// SHELL("command") -- as function expression
|
||||
if (tt == TOK_SHELL) {
|
||||
advance(p);
|
||||
|
|
@ -4410,11 +4461,17 @@ static void parseStatement(BasParserT *p) {
|
|||
break;
|
||||
|
||||
case TOK_MSGBOX:
|
||||
// MsgBox message [, flags] (statement form, discard result)
|
||||
advance(p);
|
||||
parseExpression(p);
|
||||
parseExpression(p); // message
|
||||
if (match(p, TOK_COMMA)) {
|
||||
parseExpression(p); // flags
|
||||
} else {
|
||||
basEmit8(&p->cg, OP_PUSH_INT16);
|
||||
basEmit16(&p->cg, 0); // default flags = MB_OK
|
||||
}
|
||||
basEmit8(&p->cg, OP_MSGBOX);
|
||||
basEmit8(&p->cg, 0);
|
||||
basEmit8(&p->cg, OP_POP);
|
||||
basEmit8(&p->cg, OP_POP); // discard result
|
||||
break;
|
||||
|
||||
case TOK_ME: {
|
||||
|
|
@ -5059,6 +5116,8 @@ void basParserInit(BasParserT *p, const char *source, int32_t sourceLen) {
|
|||
exitListInit(&exitSubList);
|
||||
exitListInit(&exitFuncList);
|
||||
|
||||
addPredefConsts(p);
|
||||
|
||||
// basLexerInit already primes the first token -- no advance needed
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static const char *FORM_DEFAULT_EVENT = "Load";
|
|||
// Prototypes
|
||||
// ============================================================
|
||||
|
||||
static WidgetT *createDesignWidget(const char *vbTypeName, WidgetT *parent);
|
||||
// dsgnCreateDesignWidget is declared in ideDesigner.h (non-static)
|
||||
static const char *getPropValue(const DsgnControlT *ctrl, const char *name);
|
||||
static DsgnHandleE hitTestHandles(const DsgnControlT *ctrl, int32_t x, int32_t y);
|
||||
static int32_t hitTestControl(const DsgnStateT *ds, int32_t x, int32_t y);
|
||||
|
|
@ -48,13 +48,13 @@ static void syncWidgetGeom(DsgnControlT *ctrl);
|
|||
|
||||
|
||||
// ============================================================
|
||||
// createDesignWidget
|
||||
// dsgnCreateDesignWidget
|
||||
// ============================================================
|
||||
//
|
||||
// Create a real DVX widget for design-time display. Mirrors the
|
||||
// logic in formrt.c createWidget().
|
||||
|
||||
static WidgetT *createDesignWidget(const char *vbTypeName, WidgetT *parent) {
|
||||
WidgetT *dsgnCreateDesignWidget(const char *vbTypeName, WidgetT *parent) {
|
||||
const char *wgtName = resolveTypeName(vbTypeName);
|
||||
|
||||
if (!wgtName) {
|
||||
|
|
@ -185,7 +185,7 @@ void dsgnCreateWidgets(DsgnStateT *ds, WidgetT *contentBox) {
|
|||
}
|
||||
}
|
||||
|
||||
WidgetT *w = createDesignWidget(ctrl->typeName, parent);
|
||||
WidgetT *w = dsgnCreateDesignWidget(ctrl->typeName, parent);
|
||||
|
||||
if (!w) {
|
||||
continue;
|
||||
|
|
@ -775,7 +775,7 @@ void dsgnOnMouse(DsgnStateT *ds, int32_t x, int32_t y, bool drag) {
|
|||
|
||||
// Create the live widget
|
||||
if (parentWidget) {
|
||||
ctrl.widget = createDesignWidget(typeName, parentWidget);
|
||||
ctrl.widget = dsgnCreateDesignWidget(typeName, parentWidget);
|
||||
|
||||
if (ctrl.widget) {
|
||||
ctrl.widget->minW = wgtPixels(ctrl.width);
|
||||
|
|
|
|||
|
|
@ -176,6 +176,9 @@ bool dsgnIsContainer(const char *typeName);
|
|||
// Free designer resources.
|
||||
void dsgnFree(DsgnStateT *ds);
|
||||
|
||||
// Create a live design-time widget for a given VB type name.
|
||||
WidgetT *dsgnCreateDesignWidget(const char *vbTypeName, WidgetT *parent);
|
||||
|
||||
// ============================================================
|
||||
// Code rename support (implemented in ideMain.c)
|
||||
// ============================================================
|
||||
|
|
|
|||
|
|
@ -3535,8 +3535,351 @@ static void printCallback(void *ctx, const char *text, bool newline) {
|
|||
// onFormWinKey
|
||||
// ============================================================
|
||||
|
||||
static void dsgnCopySelected(void) {
|
||||
if (!sDesigner.form || sDesigner.selectedIdx < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t count = (int32_t)arrlen(sDesigner.form->controls);
|
||||
|
||||
if (sDesigner.selectedIdx >= count) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Serialize the selected control to FRM text
|
||||
char buf[2048];
|
||||
int32_t pos = 0;
|
||||
DsgnControlT *ctrl = &sDesigner.form->controls[sDesigner.selectedIdx];
|
||||
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "Begin %s %s\n", ctrl->typeName, ctrl->name);
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " Caption = \"%s\"\n", wgtGetText(ctrl->widget) ? wgtGetText(ctrl->widget) : "");
|
||||
|
||||
if (ctrl->width > 0) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " MinWidth = %d\n", (int)ctrl->width);
|
||||
}
|
||||
|
||||
if (ctrl->height > 0) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " MinHeight = %d\n", (int)ctrl->height);
|
||||
}
|
||||
|
||||
if (ctrl->maxWidth > 0) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " MaxWidth = %d\n", (int)ctrl->maxWidth);
|
||||
}
|
||||
|
||||
if (ctrl->maxHeight > 0) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " MaxHeight = %d\n", (int)ctrl->maxHeight);
|
||||
}
|
||||
|
||||
if (ctrl->weight > 0) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " Weight = %d\n", (int)ctrl->weight);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < ctrl->propCount; i++) {
|
||||
if (strcasecmp(ctrl->props[i].name, "Caption") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " %s = \"%s\"\n", ctrl->props[i].name, ctrl->props[i].value);
|
||||
}
|
||||
|
||||
// Save interface properties
|
||||
if (ctrl->widget) {
|
||||
const char *wgtName = wgtFindByBasName(ctrl->typeName);
|
||||
const WgtIfaceT *iface = wgtName ? wgtGetIface(wgtName) : NULL;
|
||||
|
||||
if (iface) {
|
||||
for (int32_t i = 0; i < iface->propCount; i++) {
|
||||
const WgtPropDescT *p = &iface->props[i];
|
||||
|
||||
if (!p->getFn) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool already = false;
|
||||
|
||||
for (int32_t j = 0; j < ctrl->propCount; j++) {
|
||||
if (strcasecmp(ctrl->props[j].name, p->name) == 0) {
|
||||
already = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (already) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->type == WGT_IFACE_ENUM && p->enumNames) {
|
||||
int32_t v = ((int32_t (*)(const WidgetT *))p->getFn)(ctrl->widget);
|
||||
const char *name = (v >= 0 && p->enumNames[v]) ? p->enumNames[v] : NULL;
|
||||
|
||||
if (name) {
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " %s = %s\n", p->name, name);
|
||||
}
|
||||
} else if (p->type == WGT_IFACE_INT) {
|
||||
int32_t v = ((int32_t (*)(const WidgetT *))p->getFn)(ctrl->widget);
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " %s = %d\n", p->name, (int)v);
|
||||
} else if (p->type == WGT_IFACE_BOOL) {
|
||||
bool v = ((bool (*)(const WidgetT *))p->getFn)(ctrl->widget);
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " %s = %s\n", p->name, v ? "True" : "False");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "End\n");
|
||||
dvxClipboardCopy(buf, pos);
|
||||
}
|
||||
|
||||
|
||||
static void dsgnPasteControl(void) {
|
||||
if (!sDesigner.form || !sDesigner.form->contentBox) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t clipLen = 0;
|
||||
const char *clip = dvxClipboardGet(&clipLen);
|
||||
|
||||
if (!clip || clipLen <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify it looks like a control definition
|
||||
if (strncasecmp(clip, "Begin ", 6) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse type and name from "Begin TypeName CtrlName"
|
||||
const char *rest = clip + 6;
|
||||
char typeName[DSGN_MAX_NAME];
|
||||
char ctrlName[DSGN_MAX_NAME];
|
||||
|
||||
int32_t ti = 0;
|
||||
|
||||
while (*rest && *rest != ' ' && *rest != '\t' && ti < DSGN_MAX_NAME - 1) {
|
||||
typeName[ti++] = *rest++;
|
||||
}
|
||||
|
||||
typeName[ti] = '\0';
|
||||
|
||||
while (*rest == ' ' || *rest == '\t') {
|
||||
rest++;
|
||||
}
|
||||
|
||||
int32_t ci = 0;
|
||||
|
||||
while (*rest && *rest != ' ' && *rest != '\t' && *rest != '\r' && *rest != '\n' && ci < DSGN_MAX_NAME - 1) {
|
||||
ctrlName[ci++] = *rest++;
|
||||
}
|
||||
|
||||
ctrlName[ci] = '\0';
|
||||
|
||||
// Auto-generate a unique name to avoid duplicates
|
||||
char newName[DSGN_MAX_NAME];
|
||||
dsgnAutoName(&sDesigner, typeName, newName, DSGN_MAX_NAME);
|
||||
|
||||
// Create the control
|
||||
DsgnControlT ctrl;
|
||||
memset(&ctrl, 0, sizeof(ctrl));
|
||||
snprintf(ctrl.name, DSGN_MAX_NAME, "%s", newName);
|
||||
snprintf(ctrl.typeName, DSGN_MAX_NAME, "%s", typeName);
|
||||
|
||||
// Parse properties from the clipboard text
|
||||
const char *line = rest;
|
||||
|
||||
while (*line) {
|
||||
while (*line == '\r' || *line == '\n') {
|
||||
line++;
|
||||
}
|
||||
|
||||
if (!*line) {
|
||||
break;
|
||||
}
|
||||
|
||||
const char *lineStart = line;
|
||||
|
||||
while (*line == ' ' || *line == '\t') {
|
||||
line++;
|
||||
}
|
||||
|
||||
// "End" terminates
|
||||
if (strncasecmp(line, "End", 3) == 0 && (line[3] == '\0' || line[3] == '\r' || line[3] == '\n')) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse "Key = Value"
|
||||
char *eq = strchr(line, '=');
|
||||
|
||||
if (eq) {
|
||||
char key[DSGN_MAX_NAME];
|
||||
int32_t klen = 0;
|
||||
const char *kp = line;
|
||||
|
||||
while (kp < eq && *kp != ' ' && *kp != '\t' && klen < DSGN_MAX_NAME - 1) {
|
||||
key[klen++] = *kp++;
|
||||
}
|
||||
|
||||
key[klen] = '\0';
|
||||
|
||||
char *vp = (char *)eq + 1;
|
||||
|
||||
while (*vp == ' ' || *vp == '\t') {
|
||||
vp++;
|
||||
}
|
||||
|
||||
char val[DSGN_MAX_TEXT];
|
||||
int32_t vi = 0;
|
||||
|
||||
if (*vp == '"') {
|
||||
vp++;
|
||||
|
||||
while (*vp && *vp != '"' && vi < DSGN_MAX_TEXT - 1) {
|
||||
val[vi++] = *vp++;
|
||||
}
|
||||
} else {
|
||||
while (*vp && *vp != '\r' && *vp != '\n' && vi < DSGN_MAX_TEXT - 1) {
|
||||
val[vi++] = *vp++;
|
||||
}
|
||||
|
||||
while (vi > 0 && (val[vi - 1] == ' ' || val[vi - 1] == '\t')) {
|
||||
vi--;
|
||||
}
|
||||
}
|
||||
|
||||
val[vi] = '\0';
|
||||
|
||||
if (strcasecmp(key, "MinWidth") == 0 || strcasecmp(key, "Width") == 0) {
|
||||
ctrl.width = atoi(val);
|
||||
} else if (strcasecmp(key, "MinHeight") == 0 || strcasecmp(key, "Height") == 0) {
|
||||
ctrl.height = atoi(val);
|
||||
} else if (strcasecmp(key, "MaxWidth") == 0) {
|
||||
ctrl.maxWidth = atoi(val);
|
||||
} else if (strcasecmp(key, "MaxHeight") == 0) {
|
||||
ctrl.maxHeight = atoi(val);
|
||||
} else if (strcasecmp(key, "Weight") == 0) {
|
||||
ctrl.weight = atoi(val);
|
||||
} else if (ctrl.propCount < DSGN_MAX_PROPS) {
|
||||
snprintf(ctrl.props[ctrl.propCount].name, DSGN_MAX_NAME, "%s", key);
|
||||
snprintf(ctrl.props[ctrl.propCount].value, DSGN_MAX_TEXT, "%s", val);
|
||||
ctrl.propCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Advance to next line
|
||||
while (*line && *line != '\n') {
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the live widget
|
||||
WidgetT *parentWidget = sDesigner.form->contentBox;
|
||||
ctrl.widget = dsgnCreateDesignWidget(typeName, parentWidget);
|
||||
|
||||
if (ctrl.widget) {
|
||||
if (ctrl.width > 0) { ctrl.widget->minW = wgtPixels(ctrl.width); }
|
||||
if (ctrl.height > 0) { ctrl.widget->minH = wgtPixels(ctrl.height); }
|
||||
if (ctrl.maxWidth > 0) { ctrl.widget->maxW = wgtPixels(ctrl.maxWidth); }
|
||||
if (ctrl.maxHeight > 0) { ctrl.widget->maxH = wgtPixels(ctrl.maxHeight); }
|
||||
ctrl.widget->weight = ctrl.weight;
|
||||
wgtSetName(ctrl.widget, ctrl.name);
|
||||
|
||||
const char *caption = NULL;
|
||||
|
||||
for (int32_t pi = 0; pi < ctrl.propCount; pi++) {
|
||||
if (strcasecmp(ctrl.props[pi].name, "Caption") == 0) {
|
||||
caption = ctrl.props[pi].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (caption) {
|
||||
wgtSetText(ctrl.widget, caption);
|
||||
}
|
||||
|
||||
// Apply interface properties (Alignment, etc.)
|
||||
const char *wgtName = wgtFindByBasName(typeName);
|
||||
const WgtIfaceT *iface = wgtName ? wgtGetIface(wgtName) : NULL;
|
||||
|
||||
if (iface) {
|
||||
for (int32_t pi = 0; pi < iface->propCount; pi++) {
|
||||
const WgtPropDescT *p = &iface->props[pi];
|
||||
|
||||
if (!p->setFn) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *val = NULL;
|
||||
|
||||
for (int32_t j = 0; j < ctrl.propCount; j++) {
|
||||
if (strcasecmp(ctrl.props[j].name, p->name) == 0) {
|
||||
val = ctrl.props[j].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->type == WGT_IFACE_ENUM && p->enumNames) {
|
||||
for (int32_t en = 0; p->enumNames[en]; en++) {
|
||||
if (strcasecmp(p->enumNames[en], val) == 0) {
|
||||
((void (*)(WidgetT *, int32_t))p->setFn)(ctrl.widget, en);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (p->type == WGT_IFACE_INT) {
|
||||
((void (*)(WidgetT *, int32_t))p->setFn)(ctrl.widget, atoi(val));
|
||||
} else if (p->type == WGT_IFACE_BOOL) {
|
||||
((void (*)(WidgetT *, bool))p->setFn)(ctrl.widget, strcasecmp(val, "True") == 0);
|
||||
} else if (p->type == WGT_IFACE_STRING) {
|
||||
((void (*)(WidgetT *, const char *))p->setFn)(ctrl.widget, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arrput(sDesigner.form->controls, ctrl);
|
||||
sDesigner.selectedIdx = (int32_t)arrlen(sDesigner.form->controls) - 1;
|
||||
sDesigner.form->dirty = true;
|
||||
|
||||
prpRebuildTree(&sDesigner);
|
||||
prpRefresh(&sDesigner);
|
||||
|
||||
if (sFormWin) {
|
||||
dvxInvalidateWindow(sAc, sFormWin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void onFormWinKey(WindowT *win, int32_t key, int32_t mod) {
|
||||
(void)mod;
|
||||
// Ctrl+C: copy selected control
|
||||
if (key == 3 && (mod & ACCEL_CTRL)) {
|
||||
dsgnCopySelected();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+X: cut selected control
|
||||
if (key == 24 && (mod & ACCEL_CTRL)) {
|
||||
dsgnCopySelected();
|
||||
|
||||
if (sDesigner.selectedIdx >= 0) {
|
||||
dsgnOnKey(&sDesigner, KEY_DELETE);
|
||||
prpRebuildTree(&sDesigner);
|
||||
prpRefresh(&sDesigner);
|
||||
|
||||
if (sFormWin) {
|
||||
dvxInvalidateWindow(sAc, sFormWin);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+V: paste control
|
||||
if (key == 22 && (mod & ACCEL_CTRL)) {
|
||||
dsgnPasteControl();
|
||||
return;
|
||||
}
|
||||
|
||||
if (key == KEY_DELETE && sDesigner.selectedIdx >= 0) {
|
||||
int32_t prevCount = sDesigner.form ? (int32_t)arrlen(sDesigner.form->controls) : 0;
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
// ============================================================
|
||||
|
||||
#define TBX_COLS 4
|
||||
#define TBX_WIN_W 90
|
||||
#define TBX_WIN_H 200
|
||||
#define TBX_WIN_W 120
|
||||
#define TBX_WIN_H 250
|
||||
|
||||
// ============================================================
|
||||
// Per-tool entry
|
||||
|
|
@ -89,6 +89,7 @@ WindowT *tbxCreate(AppContextT *ctx, DsgnStateT *ds) {
|
|||
win->onClose = onTbxClose;
|
||||
|
||||
WidgetT *root = wgtInitWindow(ctx, win);
|
||||
root->spacing = wgtPixels(1);
|
||||
|
||||
// Enumerate all registered widget interfaces with a basName
|
||||
int32_t ifaceCount = wgtIfaceCount();
|
||||
|
|
@ -118,15 +119,15 @@ WindowT *tbxCreate(AppContextT *ctx, DsgnStateT *ds) {
|
|||
int32_t pathIdx = wgtIfaceGetPathIndex(wgtName);
|
||||
|
||||
if (wgtPath) {
|
||||
// Build suffixed resource names: "icon16", "icon16-2", etc.
|
||||
// Build suffixed resource names: "icon24", "icon24-2", etc.
|
||||
char iconResName[32];
|
||||
char nameResName[32];
|
||||
|
||||
if (pathIdx <= 1) {
|
||||
snprintf(iconResName, sizeof(iconResName), "icon16");
|
||||
snprintf(iconResName, sizeof(iconResName), "icon24");
|
||||
snprintf(nameResName, sizeof(nameResName), "name");
|
||||
} else {
|
||||
snprintf(iconResName, sizeof(iconResName), "icon16-%d", (int)pathIdx);
|
||||
snprintf(iconResName, sizeof(iconResName), "icon24-%d", (int)pathIdx);
|
||||
snprintf(nameResName, sizeof(nameResName), "name-%d", (int)pathIdx);
|
||||
}
|
||||
|
||||
|
|
@ -144,6 +145,7 @@ WindowT *tbxCreate(AppContextT *ctx, DsgnStateT *ds) {
|
|||
// Start a new row every TBX_COLS buttons
|
||||
if (col == 0 || !row) {
|
||||
row = wgtHBox(root);
|
||||
row->spacing = wgtPixels(1);
|
||||
}
|
||||
|
||||
// Create button in the current row
|
||||
|
|
|
|||
|
|
@ -2746,13 +2746,15 @@ BasVmResultE basVmStep(BasVmT *vm) {
|
|||
}
|
||||
|
||||
case OP_MSGBOX: {
|
||||
uint8_t flags = readUint8(vm);
|
||||
// Stack: [message, flags] — flags on top
|
||||
BasValueT flagsVal;
|
||||
BasValueT msgVal;
|
||||
|
||||
if (!pop(vm, &msgVal)) {
|
||||
if (!pop(vm, &flagsVal) || !pop(vm, &msgVal)) {
|
||||
return BAS_VM_STACK_UNDERFLOW;
|
||||
}
|
||||
|
||||
int32_t flags = (int32_t)basValToNumber(flagsVal);
|
||||
int32_t result = 1; // default OK
|
||||
|
||||
if (vm->ui.msgBox) {
|
||||
|
|
@ -2761,6 +2763,7 @@ BasVmResultE basVmStep(BasVmT *vm) {
|
|||
basValRelease(&sv);
|
||||
}
|
||||
|
||||
basValRelease(&flagsVal);
|
||||
basValRelease(&msgVal);
|
||||
push(vm, basValInteger((int16_t)result));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2434,6 +2434,73 @@ int main(void) {
|
|||
"Counter\n"
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Coverage: MsgBox statement form (no return value)
|
||||
// ============================================================
|
||||
|
||||
runProgram("MsgBox statement",
|
||||
"MsgBox \"Hello\"\n"
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Coverage: MsgBox statement with flags
|
||||
// ============================================================
|
||||
|
||||
runProgram("MsgBox statement with flags",
|
||||
"MsgBox \"Save?\", vbYesNo + vbQuestion\n"
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Coverage: MsgBox function form (returns value)
|
||||
// ============================================================
|
||||
|
||||
runProgram("MsgBox function",
|
||||
"DIM result AS INTEGER\n"
|
||||
"result = MsgBox(\"Continue?\", vbYesNo)\n"
|
||||
"PRINT result\n"
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Coverage: MsgBox function with default flags
|
||||
// ============================================================
|
||||
|
||||
runProgram("MsgBox function default flags",
|
||||
"DIM r AS INTEGER\n"
|
||||
"r = MsgBox(\"OK\")\n"
|
||||
"PRINT r\n"
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Coverage: VB3 predefined constants
|
||||
// ============================================================
|
||||
|
||||
runProgram("VB3 predefined constants",
|
||||
"PRINT vbOKOnly\n"
|
||||
"PRINT vbOKCancel\n"
|
||||
"PRINT vbYesNo\n"
|
||||
"PRINT vbYesNoCancel\n"
|
||||
"PRINT vbRetryCancel\n"
|
||||
"PRINT vbInformation\n"
|
||||
"PRINT vbExclamation\n"
|
||||
"PRINT vbCritical\n"
|
||||
"PRINT vbQuestion\n"
|
||||
"PRINT vbOK\n"
|
||||
"PRINT vbCancel\n"
|
||||
"PRINT vbYes\n"
|
||||
"PRINT vbNo\n"
|
||||
"PRINT vbRetry\n"
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Coverage: MsgBox result used in If
|
||||
// ============================================================
|
||||
|
||||
runProgram("MsgBox in If condition",
|
||||
"If MsgBox(\"Exit?\", vbYesNo) = vbYes Then\n"
|
||||
" PRINT \"yes\"\n"
|
||||
"End If\n"
|
||||
);
|
||||
|
||||
printf("All tests complete.\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1473,11 +1473,18 @@ static void int9Handler(void) {
|
|||
|
||||
|
||||
void platformKeyUpInit(void) {
|
||||
// INT 9 hook disabled pending investigation of keyboard corruption.
|
||||
// Key-up events are not available until this is fixed.
|
||||
(void)sOldInt9;
|
||||
(void)sNewInt9;
|
||||
(void)int9Handler;
|
||||
if (sKeyUpInstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
_go32_dpmi_get_protected_mode_interrupt_vector(9, &sOldInt9);
|
||||
|
||||
sNewInt9.pm_offset = (unsigned long)int9Handler;
|
||||
sNewInt9.pm_selector = _go32_my_cs();
|
||||
|
||||
_go32_dpmi_chain_protected_mode_interrupt_vector(9, &sNewInt9);
|
||||
|
||||
sKeyUpInstalled = true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ BINDIR = ../bin
|
|||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(BINDIR)/dvxres $(BINDIR)/mkicon $(BINDIR)/mktbicon
|
||||
all: $(BINDIR)/dvxres $(BINDIR)/mkicon $(BINDIR)/mktbicon $(BINDIR)/mkwgticon
|
||||
|
||||
$(BINDIR)/dvxres: dvxres.c ../core/dvxResource.c ../core/dvxResource.h | $(BINDIR)
|
||||
$(CC) $(CFLAGS) -o $@ dvxres.c ../core/dvxResource.c
|
||||
|
|
@ -21,6 +21,9 @@ $(BINDIR)/mkicon: mkicon.c | $(BINDIR)
|
|||
$(BINDIR)/mktbicon: mktbicon.c | $(BINDIR)
|
||||
$(CC) $(CFLAGS) -o $@ mktbicon.c
|
||||
|
||||
$(BINDIR)/mkwgticon: mkwgticon.c | $(BINDIR)
|
||||
$(CC) $(CFLAGS) -o $@ mkwgticon.c
|
||||
|
||||
$(BINDIR):
|
||||
mkdir -p $(BINDIR)
|
||||
|
||||
|
|
|
|||
BIN
widgets/ansiTerm/terminal.bmp
(Stored with Git LFS)
BIN
widgets/ansiTerm/terminal.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon terminal.bmp
|
||||
icon24 icon terminal.bmp
|
||||
name text "Terminal"
|
||||
author text "DVX Project"
|
||||
description text "ANSI terminal emulator widget"
|
||||
|
|
|
|||
BIN
widgets/box/box.bmp
(Stored with Git LFS)
BIN
widgets/box/box.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,13 +1,13 @@
|
|||
# box.res -- Resources for VBox, HBox, and Frame widgets
|
||||
#
|
||||
# VBox (first registered, uses unsuffixed names)
|
||||
icon16 icon box.bmp
|
||||
icon24 icon box.bmp
|
||||
name text "VBox"
|
||||
# HBox (second registered)
|
||||
icon16-2 icon box.bmp
|
||||
icon24-2 icon box.bmp
|
||||
name-2 text "HBox"
|
||||
# Frame (third registered)
|
||||
icon16-3 icon box.bmp
|
||||
icon24-3 icon box.bmp
|
||||
name-3 text "Frame"
|
||||
author text "DVX Project"
|
||||
description text "VBox, HBox, and Frame container widgets"
|
||||
|
|
|
|||
BIN
widgets/button/button.bmp
(Stored with Git LFS)
BIN
widgets/button/button.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon button.bmp
|
||||
icon24 icon button.bmp
|
||||
name text "Button"
|
||||
author text "DVX Project"
|
||||
description text "Command button widget"
|
||||
|
|
|
|||
BIN
widgets/canvas/canvas.bmp
(Stored with Git LFS)
BIN
widgets/canvas/canvas.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon canvas.bmp
|
||||
icon24 icon canvas.bmp
|
||||
name text "Canvas"
|
||||
author text "DVX Project"
|
||||
description text "Pixel drawing surface"
|
||||
|
|
|
|||
BIN
widgets/checkbox/checkbox.bmp
(Stored with Git LFS)
BIN
widgets/checkbox/checkbox.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon checkbox.bmp
|
||||
icon24 icon checkbox.bmp
|
||||
name text "CheckBox"
|
||||
author text "DVX Project"
|
||||
description text "Check box toggle widget"
|
||||
|
|
|
|||
BIN
widgets/comboBox/combobox.bmp
(Stored with Git LFS)
BIN
widgets/comboBox/combobox.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon combobox.bmp
|
||||
icon24 icon combobox.bmp
|
||||
name text "ComboBox"
|
||||
author text "DVX Project"
|
||||
description text "Editable dropdown combo box"
|
||||
|
|
|
|||
BIN
widgets/dropdown/dropdown.bmp
(Stored with Git LFS)
BIN
widgets/dropdown/dropdown.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon dropdown.bmp
|
||||
icon24 icon dropdown.bmp
|
||||
name text "DropDown"
|
||||
author text "DVX Project"
|
||||
description text "Non-editable dropdown selector"
|
||||
|
|
|
|||
BIN
widgets/image/image.bmp
(Stored with Git LFS)
BIN
widgets/image/image.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon image.bmp
|
||||
icon24 icon image.bmp
|
||||
name text "Image"
|
||||
author text "DVX Project"
|
||||
description text "Static image display"
|
||||
|
|
|
|||
BIN
widgets/imageButton/imgbtn.bmp
(Stored with Git LFS)
BIN
widgets/imageButton/imgbtn.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon imgbtn.bmp
|
||||
icon24 icon imgbtn.bmp
|
||||
name text "ImageButton"
|
||||
author text "DVX Project"
|
||||
description text "Button with bitmap icon"
|
||||
|
|
|
|||
BIN
widgets/label/label.bmp
(Stored with Git LFS)
BIN
widgets/label/label.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon label.bmp
|
||||
icon24 icon label.bmp
|
||||
name text "Label"
|
||||
author text "DVX Project"
|
||||
description text "Static text label"
|
||||
|
|
|
|||
BIN
widgets/listBox/listbox.bmp
(Stored with Git LFS)
BIN
widgets/listBox/listbox.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon listbox.bmp
|
||||
icon24 icon listbox.bmp
|
||||
name text "ListBox"
|
||||
author text "DVX Project"
|
||||
description text "Scrollable item list with single or multi-select"
|
||||
|
|
|
|||
BIN
widgets/listView/listview.bmp
(Stored with Git LFS)
BIN
widgets/listView/listview.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon listview.bmp
|
||||
icon24 icon listview.bmp
|
||||
name text "ListView"
|
||||
author text "DVX Project"
|
||||
description text "Multi-column list with sortable headers"
|
||||
|
|
|
|||
BIN
widgets/progressBar/progress.bmp
(Stored with Git LFS)
BIN
widgets/progressBar/progress.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon progress.bmp
|
||||
icon24 icon progress.bmp
|
||||
name text "ProgressBar"
|
||||
author text "DVX Project"
|
||||
description text "Progress indicator bar"
|
||||
|
|
|
|||
BIN
widgets/radio/radio.bmp
(Stored with Git LFS)
BIN
widgets/radio/radio.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon radio.bmp
|
||||
icon24 icon radio.bmp
|
||||
name text "RadioButton"
|
||||
author text "DVX Project"
|
||||
description text "Radio button option selector"
|
||||
|
|
|
|||
BIN
widgets/scrollPane/scrlpane.bmp
(Stored with Git LFS)
BIN
widgets/scrollPane/scrlpane.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon scrlpane.bmp
|
||||
icon24 icon scrlpane.bmp
|
||||
name text "ScrollPane"
|
||||
author text "DVX Project"
|
||||
description text "Scrollable content container"
|
||||
|
|
|
|||
BIN
widgets/separator/separatr.bmp
(Stored with Git LFS)
BIN
widgets/separator/separatr.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon separatr.bmp
|
||||
icon24 icon separatr.bmp
|
||||
name text "Separator"
|
||||
author text "DVX Project"
|
||||
description text "Horizontal or vertical divider line"
|
||||
|
|
|
|||
BIN
widgets/slider/slider.bmp
(Stored with Git LFS)
BIN
widgets/slider/slider.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon slider.bmp
|
||||
icon24 icon slider.bmp
|
||||
name text "Slider"
|
||||
author text "DVX Project"
|
||||
description text "Value slider (scrollbar)"
|
||||
|
|
|
|||
BIN
widgets/spacer/spacer.bmp
(Stored with Git LFS)
BIN
widgets/spacer/spacer.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon spacer.bmp
|
||||
icon24 icon spacer.bmp
|
||||
name text "Spacer"
|
||||
author text "DVX Project"
|
||||
description text "Invisible spacing widget"
|
||||
|
|
|
|||
BIN
widgets/spinner/spinner.bmp
(Stored with Git LFS)
BIN
widgets/spinner/spinner.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon spinner.bmp
|
||||
icon24 icon spinner.bmp
|
||||
name text "Spinner"
|
||||
author text "DVX Project"
|
||||
description text "Numeric up/down spinner"
|
||||
|
|
|
|||
BIN
widgets/splitter/splitter.bmp
(Stored with Git LFS)
BIN
widgets/splitter/splitter.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon splitter.bmp
|
||||
icon24 icon splitter.bmp
|
||||
name text "Splitter"
|
||||
author text "DVX Project"
|
||||
description text "Draggable pane divider"
|
||||
|
|
|
|||
BIN
widgets/statusBar/statbar.bmp
(Stored with Git LFS)
BIN
widgets/statusBar/statbar.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon statbar.bmp
|
||||
icon24 icon statbar.bmp
|
||||
name text "StatusBar"
|
||||
author text "DVX Project"
|
||||
description text "Window status bar container"
|
||||
|
|
|
|||
BIN
widgets/tabControl/tabctrl.bmp
(Stored with Git LFS)
BIN
widgets/tabControl/tabctrl.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon tabctrl.bmp
|
||||
icon24 icon tabctrl.bmp
|
||||
name text "TabControl"
|
||||
author text "DVX Project"
|
||||
description text "Tabbed page container"
|
||||
|
|
|
|||
BIN
widgets/textInput/textinpt.bmp
(Stored with Git LFS)
BIN
widgets/textInput/textinpt.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,10 +1,10 @@
|
|||
# textinpt.res -- Resources for TextBox and TextArea widgets
|
||||
#
|
||||
# TextBox (first registered, uses unsuffixed names)
|
||||
icon16 icon textinpt.bmp
|
||||
icon24 icon textinpt.bmp
|
||||
name text "TextBox"
|
||||
# TextArea (second registered)
|
||||
icon16-2 icon textinpt.bmp
|
||||
icon24-2 icon textinpt.bmp
|
||||
name-2 text "TextArea"
|
||||
author text "DVX Project"
|
||||
description text "Single-line and multi-line text editor"
|
||||
|
|
|
|||
BIN
widgets/timer/timer.bmp
(Stored with Git LFS)
BIN
widgets/timer/timer.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon timer.bmp
|
||||
icon24 icon timer.bmp
|
||||
name text "Timer"
|
||||
author text "DVX Project"
|
||||
description text "Periodic event timer"
|
||||
|
|
|
|||
BIN
widgets/toolbar/toolbar.bmp
(Stored with Git LFS)
BIN
widgets/toolbar/toolbar.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon toolbar.bmp
|
||||
icon24 icon toolbar.bmp
|
||||
name text "Toolbar"
|
||||
author text "DVX Project"
|
||||
description text "Button toolbar container"
|
||||
|
|
|
|||
BIN
widgets/treeView/treeview.bmp
(Stored with Git LFS)
BIN
widgets/treeView/treeview.bmp
(Stored with Git LFS)
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
icon16 icon treeview.bmp
|
||||
icon24 icon treeview.bmp
|
||||
name text "TreeView"
|
||||
author text "DVX Project"
|
||||
description text "Hierarchical tree with expand/collapse"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue