diff --git a/apps/dvxbasic/compiler/parser.c b/apps/dvxbasic/compiler/parser.c index e2205fb..0505308 100644 --- a/apps/dvxbasic/compiler/parser.c +++ b/apps/dvxbasic/compiler/parser.c @@ -247,6 +247,9 @@ static void addPredefConsts(BasParserT *p) { addPredefConst(p, "vbYes", 3); addPredefConst(p, "vbNo", 4); addPredefConst(p, "vbRetry", 5); + + // Show mode flags + addPredefConst(p, "vbModal", 1); } @@ -1911,9 +1914,14 @@ static void parseAssignOrCall(BasParserT *p) { basEmitU16(&p->cg, nameIdx); basEmit8(&p->cg, OP_LOAD_FORM); uint8_t modal = 0; - if (check(p, TOK_INT_LIT) || check(p, TOK_IDENT)) { - // Parse modal flag - if (check(p, TOK_INT_LIT) && p->lex.token.intVal != 0) { + if (check(p, TOK_INT_LIT)) { + if (p->lex.token.intVal != 0) { + modal = 1; + } + advance(p); + } else if (check(p, TOK_IDENT)) { + BasSymbolT *modSym = basSymTabFind(&p->sym, p->lex.token.text); + if (modSym && modSym->kind == SYM_CONST && modSym->constInt != 0) { modal = 1; } advance(p); @@ -5034,6 +5042,12 @@ static void parseStatement(BasParserT *p) { modal = 1; } advance(p); + } else if (check(p, TOK_IDENT)) { + BasSymbolT *modSym = basSymTabFind(&p->sym, p->lex.token.text); + if (modSym && modSym->kind == SYM_CONST && modSym->constInt != 0) { + modal = 1; + } + advance(p); } basEmit8(&p->cg, OP_SHOW_FORM); basEmit8(&p->cg, modal); diff --git a/core/dvxFont.h b/core/dvxFont.h index 78e178e..fd42988 100644 --- a/core/dvxFont.h +++ b/core/dvxFont.h @@ -5,12 +5,8 @@ // byte copy of the font stored in the VGA BIOS ROM. // // Embedding as a static const array (rather than reading from the VGA ROM -// at INT 10h) serves two purposes: -// 1. The data is available on non-DOS platforms (Linux/SDL) where no -// VGA BIOS exists. -// 2. On DOS, reading the VGA ROM font requires a real-mode interrupt -// call during init, and the data would need to be copied somewhere -// anyway. Compiling it in is simpler and more portable. +// at INT 10h) avoids a real-mode interrupt call during init and the need +// to copy the data from the ROM. Compiling it in is simpler. // // The glyph format is 1 bit per pixel, 8 pixels wide, with MSB = leftmost // pixel. Each glyph occupies 16 consecutive bytes. The drawing code in diff --git a/core/dvxTypes.h b/core/dvxTypes.h index f2dcf72..140f927 100644 --- a/core/dvxTypes.h +++ b/core/dvxTypes.h @@ -52,8 +52,7 @@ typedef struct { // // The single display context passed by pointer through every layer. // Using one struct instead of globals makes the entire stack reentrant -// in principle and simplifies testing under Linux (where lfb points to -// an SDL surface instead of real VESA memory). +// in principle and keeps the API clean. // // The double-buffer strategy (backBuf in system RAM, lfb is the real // framebuffer) exists because writes to video memory over the PCI bus @@ -162,8 +161,8 @@ typedef struct { // (x = col * 8), glyph lookup is a single array index, and the 1bpp // format means each scanline of a glyph is exactly one byte. // -// Two font sizes are provided (8x14 and 8x16), matching the standard -// VGA ROM fonts and CP437 encoding. Proportional fonts would require +// One font size is provided (8x16), matching the standard +// VGA ROM font and CP437 encoding. Proportional fonts would require // glyph-width tables, kerning, and per-character positioning -- none of // which is worth the complexity for a DOS-era window manager targeting // 640x480 screens. The 8-pixel width also aligns nicely with byte @@ -173,7 +172,7 @@ typedef struct { typedef struct { int32_t charWidth; // fixed width per glyph (e.g. 8) - int32_t charHeight; // e.g. 14 or 16 + int32_t charHeight; // 16 (only 8x16 font provided) int32_t firstChar; // ASCII code of first glyph (typically 0) int32_t numChars; // number of glyphs (typically 256) const uint8_t *glyphData; // packed 1bpp, charHeight bytes per glyph diff --git a/core/platform/dvxPlatform.h b/core/platform/dvxPlatform.h index 650ff0d..65d8958 100644 --- a/core/platform/dvxPlatform.h +++ b/core/platform/dvxPlatform.h @@ -4,11 +4,9 @@ // interface. To port DVX to a new platform, implement a new // dvxPlatformXxx.c against this header. // -// Currently two implementations exist: +// Currently one implementation exists: // dvxPlatformDos.c -- DJGPP/DPMI: real VESA VBE, INT 33h mouse, // INT 16h keyboard, rep movsd/stosl asm spans -// dvxPlatformLinux.c -- SDL2: software rendering to an SDL window, -// used for development and testing on Linux // // The abstraction covers five areas: video mode setup, framebuffer // flushing, optimized memory spans, mouse input, and keyboard input. @@ -53,13 +51,12 @@ void dvxLog(const char *fmt, ...); // ============================================================ // One-time platform initialisation. On DOS this installs signal handlers -// for clean shutdown on Ctrl+C/Ctrl+Break. On Linux this initializes SDL. +// for clean shutdown on Ctrl+C/Ctrl+Break. void platformInit(void); // Cooperative yield -- give up the CPU timeslice when the event loop has // nothing to do. On DOS this calls __dpmi_yield() to be friendly to -// multitaskers (Windows 3.x, OS/2). On Linux this calls -// SDL_Delay(1) to avoid busy-spinning at 100% CPU. +// multitaskers (Windows 3.x, OS/2). void platformYield(void); // ============================================================ @@ -68,8 +65,7 @@ void platformYield(void); // Probe for a suitable video mode, enable it, map the framebuffer, and // allocate the system RAM backbuffer. On DOS this involves VBE BIOS calls -// and DPMI physical memory mapping. On Linux this creates an SDL window -// and software surface. Fills in all DisplayT fields on success. +// and DPMI physical memory mapping. Fills in all DisplayT fields on success. int32_t platformVideoInit(DisplayT *d, int32_t requestedW, int32_t requestedH, int32_t preferredBpp); // Restore the previous video mode and free all video resources. On DOS @@ -78,13 +74,11 @@ void platformVideoShutdown(DisplayT *d); // Enumerate LFB-capable graphics modes. The callback is invoked for each // available mode. Used by videoInit() to find the best match for the -// requested resolution and depth. On Linux, this reports a fixed set of -// common resolutions since SDL doesn't enumerate modes the same way. +// requested resolution and depth. void platformVideoEnumModes(void (*cb)(int32_t w, int32_t h, int32_t bpp, void *userData), void *userData); // Program the VGA/VESA DAC palette registers (8-bit mode only). pal -// points to RGB triplets (3 bytes per entry). On Linux this is a no-op -// since the SDL surface is always truecolor. +// points to RGB triplets (3 bytes per entry). void platformVideoSetPalette(const uint8_t *pal, int32_t firstEntry, int32_t count); // ============================================================ @@ -94,7 +88,6 @@ void platformVideoSetPalette(const uint8_t *pal, int32_t firstEntry, int32_t cou // Copy a rectangle from the system RAM backbuffer (d->backBuf) to the // display surface (d->lfb). On DOS this copies to real video memory via // the LFB mapping -- the critical path where PCI bus write speed matters. -// On Linux this copies to the SDL surface, then SDL_UpdateRect is called. // Each scanline is copied as a contiguous block; rep movsd on DOS gives // near-optimal bus utilization for aligned 32-bit writes. void platformFlushRect(const DisplayT *d, const RectT *r); @@ -106,8 +99,7 @@ void platformFlushRect(const DisplayT *d, const RectT *r); // These are the innermost loops of the renderer -- called once per // scanline of every rectangle fill, blit, and text draw. On DOS they // use inline assembly: rep stosl for fills (one instruction fills an -// entire scanline) and rep movsd for copies. On Linux they use memset/ -// memcpy which the compiler can auto-vectorize. +// entire scanline) and rep movsd for copies. // // Three variants per operation (8/16/32 bpp) because the fill semantics // differ by depth: 8-bit fills a byte per pixel, 16-bit fills a word @@ -128,7 +120,7 @@ void platformSpanCopy32(uint8_t *dst, const uint8_t *src, int32_t count); // Initialize the mouse driver and constrain movement to the screen bounds. // On DOS this calls INT 33h functions to detect the mouse, set the X/Y -// range, and center the cursor. On Linux this initializes SDL mouse state. +// range, and center the cursor. void platformMouseInit(int32_t screenW, int32_t screenH); // Poll the current mouse state. Buttons is a bitmask: bit 0 = left, @@ -156,8 +148,8 @@ int32_t platformMouseWheelPoll(void); void platformMouseSetAccel(int32_t threshold); // Move the mouse cursor to an absolute screen position. Uses INT 33h -// function 04h on DOS, SDL_WarpMouseInWindow on Linux. Used to clamp -// the cursor to window edges during resize operations. +// function 04h on DOS. Used to clamp the cursor to window edges during +// resize operations. void platformMouseWarp(int32_t x, int32_t y); // ============================================================ @@ -166,8 +158,7 @@ void platformMouseWarp(int32_t x, int32_t y); // Return the current modifier key state in BIOS shift-state format: // bits 0-1 = either shift, bit 2 = ctrl, bit 3 = alt. On DOS this -// reads the BIOS data area at 0040:0017. On Linux this queries SDL -// modifier state and translates to the same bit format. +// reads the BIOS data area at 0040:0017. int32_t platformKeyboardGetModifiers(void); // Non-blocking read of the next key from the keyboard buffer. Returns @@ -179,13 +170,11 @@ bool platformKeyboardRead(PlatformKeyEventT *evt); // Non-blocking read of the next key-up event. Returns true if a // key release was detected. On DOS this requires an INT 9 hook to -// detect break codes (scan code with bit 7 set). On Linux this -// uses SDL_KEYUP events. +// detect break codes (scan code with bit 7 set). bool platformKeyUpRead(PlatformKeyEventT *evt); // Install/remove the INT 9 hook for key-up detection. On DOS this -// chains the hardware keyboard interrupt. On Linux this is a no-op -// (SDL provides key-up events natively). Call Init before using +// chains the hardware keyboard interrupt. Call Init before using // platformKeyUpRead, and Shutdown before exit. void platformKeyUpInit(void); void platformKeyUpShutdown(void); @@ -209,7 +198,6 @@ char platformAltScanToChar(int32_t scancode); // The display pointer provides the current video mode info. Returns a // pointer to a static buffer valid for the lifetime of the process. // On DOS this uses CPUID, RDTSC, DPMI, INT 21h, INT 33h, and VBE. -// On other platforms it returns whatever the OS can report. const char *platformGetSystemInfo(const DisplayT *display); // ============================================================ @@ -219,7 +207,6 @@ const char *platformGetSystemInfo(const DisplayT *display); // Validate a filename against platform-specific rules. On DOS this // enforces 8.3 naming (no long filenames), checks for reserved device // names (CON, PRN, etc.), and rejects characters illegal in FAT filenames. -// On Linux the rules are much more permissive (just no slashes or NUL). // Returns NULL if the filename is valid, or a human-readable error string // describing why it's invalid. Used by the file dialog's save-as validation. const char *platformValidateFilename(const char *name); @@ -272,11 +259,11 @@ void platformVideoFreeBuffers(DisplayT *d); // Return a pointer to the last directory separator in path, or NULL if // none is found. On DOS this checks both '/' and '\\' since DJGPP -// accepts either. On other platforms only '/' is recognised. +// accepts either. char *platformPathDirEnd(const char *path); // Return the platform's native line ending string. -// "\r\n" on DOS/Windows, "\n" on Unix/Linux. +// "\r\n" on DOS. const char *platformLineEnding(void); // Strip platform-specific line ending characters from a buffer in place. @@ -290,7 +277,7 @@ int32_t platformStripLineEndings(char *buf, int32_t len); // Register platform and C runtime symbols with the dynamic module // loader so that DXE modules can resolve them at load time. On DOS // this calls dlregsym() with the full DJGPP libc/libm/libgcc/platform -// export table. On platforms without DXE (Linux/SDL), this is a no-op. +// export table. void platformRegisterDxeExports(void); // ============================================================ diff --git a/docs/dvx_api_reference.html b/docs/dvx_api_reference.html new file mode 100644 index 0000000..93c1f6a --- /dev/null +++ b/docs/dvx_api_reference.html @@ -0,0 +1,2933 @@ + + +
+ +DOS Visual eXecutive -- Complete public API documentation generated from source headers
++ Central type definitions shared across all five layers of the DVX GUI stack. + Every header includes this file. Contains no function definitions -- only structs, + enums, typedefs, and compile-time constants. +
+ +Callbacks:
+| Macro | Description |
|---|---|
| BEVEL_RAISED(cs, bw) | Raised bevel style from a ColorSchemeT pointer and border width |
| BEVEL_SUNKEN(cs, face, bw) | Sunken bevel style with explicit face color |
| BEVEL_TROUGH(cs) | 1px sunken trough (for scrollbar tracks) |
| BEVEL_SB_BUTTON(cs) | 1px raised scrollbar button |
| Define | Value | Description |
|---|---|---|
| CHROME_BORDER_WIDTH | 4 | Outer frame border width |
| CHROME_TITLE_HEIGHT | 20 | Title bar height |
| CHROME_TITLE_PAD | 4 | Title text padding |
| CHROME_INNER_BORDER | 2 | Inner chrome border |
| CHROME_MENU_HEIGHT | 20 | Menu bar height |
| CHROME_TOTAL_TOP | 26 | Total inset from top of frame to content |
| CHROME_TOTAL_SIDE | 6 | Total inset from side of frame to content |
| CHROME_TOTAL_BOTTOM | 6 | Total inset from bottom of frame to content |
| CHROME_CLOSE_BTN_SIZE | 16 | Close button gadget size |
| Define | Value | Description |
|---|---|---|
| HIT_CONTENT | 0 | Content area |
| HIT_TITLE | 1 | Title bar |
| HIT_CLOSE | 2 | Close gadget |
| HIT_RESIZE | 3 | Resize border |
| HIT_MENU | 4 | Menu bar |
| HIT_VSCROLL | 5 | Vertical scrollbar |
| HIT_HSCROLL | 6 | Horizontal scrollbar |
| HIT_MINIMIZE | 7 | Minimize gadget |
| HIT_MAXIMIZE | 8 | Maximize gadget |
| HIT_NONE | -1 | No window hit (desktop) |
| Define | Value | Description |
|---|---|---|
| MOUSE_LEFT | 1 | Left mouse button |
| MOUSE_RIGHT | 2 | Right mouse button |
| MOUSE_MIDDLE | 4 | Middle mouse button |
| Define | Value | Description |
|---|---|---|
| ACCEL_SHIFT | 0x03 | Shift key (matches BIOS shift state bits) |
| ACCEL_CTRL | 0x04 | Ctrl key |
| ACCEL_ALT | 0x08 | Alt key |
| Define | Description |
|---|---|
| KEY_F1 .. KEY_F12 | Function keys (scancode | 0x100) |
| KEY_INSERT | Insert key |
| KEY_DELETE | Delete key |
| KEY_HOME | Home key |
| KEY_END | End key |
| KEY_PGUP | Page Up key |
| KEY_PGDN | Page Down key |
| Define | Value | Description |
|---|---|---|
| RESIZE_NONE | 0 | No resize edge |
| RESIZE_LEFT | 1 | Left edge |
| RESIZE_RIGHT | 2 | Right edge |
| RESIZE_TOP | 4 | Top edge |
| RESIZE_BOTTOM | 8 | Bottom edge (combinable via OR for corners) |
| Macro | Description |
|---|---|
| DVX_MIN(a, b) | Return the smaller of two values |
| DVX_MAX(a, b) | Return the larger of two values |
+ Embedded 16x16 mouse cursor bitmaps compiled as static const data. No external cursor + files. Uses the standard AND/XOR mask encoding from the IBM VGA hardware cursor spec. +
+ +| Define | Value | Description |
|---|---|---|
| CURSOR_ARROW | 0 | Standard arrow (hot spot at tip) |
| CURSOR_RESIZE_H | 1 | Horizontal resize (left/right arrows) |
| CURSOR_RESIZE_V | 2 | Vertical resize (up/down arrows) |
| CURSOR_RESIZE_DIAG_NWSE | 3 | NW-SE diagonal resize |
| CURSOR_RESIZE_DIAG_NESW | 4 | NE-SW diagonal resize |
| CURSOR_BUSY | 5 | Hourglass (wait) |
| CURSOR_CROSSHAIR | 6 | Crosshair for placement |
| CURSOR_COUNT | 7 | Total number of cursor shapes |
+ The lowest layer. Responsible for VESA VBE mode negotiation, LFB mapping via DPMI, + system RAM backbuffer allocation, pixel format discovery, and color packing. + LFB-only design: bank switching is deliberately unsupported. +
+ +Probe VBE for a mode matching the requested resolution and depth, enable it, map + the LFB into DPMI linear address space, and allocate a system RAM backbuffer. + preferredBpp is a hint; the closest available depth is used if an exact match is not found.
+Returns: 0 on success, negative on failure
+Restore VGA text mode (mode 3), unmap the LFB, and free the backbuffer. + Safe to call even if videoInit() failed.
+Pack an RGB triplet into the display's native pixel format. For direct-color modes + (15/16/32 bpp), returns a packed pixel value using shift/mask fields. For 8-bit mode, + returns the nearest palette index via Euclidean distance in RGB space.
+Returns: Native pixel value suitable for direct framebuffer write
+Set the clip rectangle on the display. All subsequent draw operations clip to this rectangle. + The caller must save and restore the clip rect around scoped operations.
+Reset the clip rectangle to the full display dimensions.
++ All 2D drawing operations: rectangle fills, bitmap blits, text rendering, bevels, lines, + and cursor rendering. Every function draws into the display's backbuffer and clips to + the current clip rectangle. This layer is stateless beyond the clip rect on DisplayT. +
+ +Populate a BlitOpsT with the correct span functions for the display's pixel depth. + Must be called once after videoInit().
+Fill a rectangle with a solid color. Clips to the display clip rect. Workhorse for + backgrounds, window fills, and clear operations.
+Copy a rectangle from an arbitrary source buffer into the backbuffer. Used to blit + per-window content buffers during compositing.
+Copy a rectangle with grayscale conversion. Each pixel's RGB is converted to luminance + (0.299R + 0.587G + 0.114B) for a disabled/grayed appearance.
+Draw a beveled frame. Top/left edges in highlight color, bottom/right in shadow. + Interior filled with face color if non-zero.
+Draw a single character glyph. When opaque is true, the background fills the entire cell; + when false, only foreground pixels are drawn (transparent background).
+Returns: Advance width (always charWidth)
+Draw a null-terminated string. Calls drawChar per character.
+Optimized batch text rendering for a known character count. Computes clip bounds once, + fills background in a single rectFill, then overlays glyph foreground pixels. Significantly + faster than per-character drawChar for long runs (terminal rows, list items).
+Return the pixel width of a null-terminated string (strlen(text) * charWidth).
+Returns: Width in pixels
+Scan text for an & prefix and return the following character as a lowercase accelerator + key. "&File" returns 'f', "E&xit" returns 'x'.
+Returns: Lowercase accelerator character, or 0 if none
+Draw text with & accelerator markers. The character after & is drawn underlined to + indicate the keyboard shortcut. && produces a literal &. Used for menu items and button labels.
+Measure text width excluding & markers (so "&File" measures as 4 chars).
+Returns: Width in pixels
+Draw a 1-bit AND/XOR masked bitmap. Used for software-rendered mouse cursors.
+Render an entire row of terminal character cells (ch/attr byte pairs) in a single pass. + Colors looked up from a 16-color palette. Attribute bit 7 controls blink.
+Draw a 1px dotted rectangle (alternating pixels). Used for keyboard focus indicators, + matching the Windows 3.x focus rectangle convention.
+Draw a horizontal line (1px tall).
+Draw a vertical line (1px wide).
++ Tracks changed screen regions and ensures only dirty regions are redrawn and flushed + to video memory. The compositing pipeline: mark dirty, merge overlapping rects, redraw + desktop + windows (back-to-front, painter's algorithm), flush to LFB. +
+ +Zero the dirty rect count. Called at the start of each frame.
+Enqueue a dirty rectangle. Grows dynamically; triggers merge at a soft capacity limit.
+Consolidate the dirty list by merging overlapping and adjacent rects. Uses iterative + pairwise merge: if combining two rects does not increase total area beyond a threshold, + they are merged. Reduces compositor passes and LFB flush operations.
+Reset the dirty list to empty (sets count to 0).
+Copy a rectangle from the system RAM backbuffer to the LFB (video memory). This is + the only place the real framebuffer is written. Uses platform-specific fast copy + (rep movsd on DOS) for each scanline.
+Compute the intersection of two rectangles.
+Returns: true if the rectangles overlap, false if disjoint
+Test whether a rectangle has zero or negative area.
+Returns: true if w <= 0 or h <= 0
++ Manages the window lifecycle, Z-order stack, chrome drawing, hit testing, and + interactive operations (drag, resize, scroll). The WM owns window geometry and chrome; + content is owned by the application via callbacks or the widget system. +
+ +Zero the window stack. Must be called before any other WM function.
+Allocate a new window, initialize its geometry and content buffer, and push it to + the top of the Z-order stack. Returns with all callbacks NULL; the caller should set + onPaint/onKey/etc. before the next event loop iteration.
+Returns: Pointer to new WindowT, or NULL on failure
+Free the window's content buffer and all attached resources (menu bar, scrollbars, + widget tree), remove it from the stack, and dirty the vacated region.
+Move window at stack index idx to the top of the Z-order. Dirties both old and new + top positions so overlapping windows get repainted.
+Transfer keyboard focus to the window at stack index idx. Unfocuses the previously + focused window and dirties both title bars.
+Recompute contentX/Y/W/H from the window's outer frame dimensions, accounting for + chrome borders, title bar, menu bar, and scrollbars. Must be called after any change + to frame size or chrome configuration.
+Reallocate the per-window content backbuffer to match current contentW/H. Old buffer + contents are lost; caller should trigger a full repaint via onPaint afterward.
+Returns: 0 on success, -1 on allocation failure
+Get the minimum window size. Accounts for chrome, gadgets, and menu bar.
+Allocate and attach a menu bar to a window. Adjusts content area to make room + (CHROME_MENU_HEIGHT pixels). One menu bar per window.
+Returns: Pointer to the new MenuBarT
+Free the menu bar and reclaim the content area.
+Append a dropdown menu to the menu bar. The label supports & accelerator markers + (e.g. "&File").
+Returns: Pointer to the new MenuT to populate with items
+Append a clickable item to a menu. The id is passed to the window's onMenu callback + when selected.
+Add a checkbox-style menu item. Check state toggles on click; rendered with a checkmark glyph.
+Add a radio-style menu item. Radio groups are defined implicitly by consecutive radio + items; selecting one unchecks the others in the group.
+Insert a horizontal separator line. Separators are not interactive.
+Query the checked state of a menu item by command ID. Searches all menus in the bar.
+Returns: true if checked
+Set the checked state of a menu item by command ID. For radio items, setting + checked=true also unchecks other radio items in the same group.
+Enable or disable a menu item by command ID.
+Create a cascading submenu attached to a parent menu. The child MenuT is heap-allocated + and freed when the parent window is destroyed.
+Returns: Pointer to the child MenuT, or NULL on allocation failure
+Allocate a heap-resident MenuT for use as a context menu (right-click). Unlike menu + bar menus, context menus are standalone allocations. Free with wmFreeMenu().
+Returns: Pointer to the new MenuT
+Free a standalone menu allocated with wmCreateMenu(). Also frees any heap-allocated + submenu children recursively.
+Attach a vertical scrollbar to the right edge of the window's content area. Shrinks + contentW by SCROLLBAR_WIDTH pixels.
+Returns: Pointer to the new ScrollbarT
+Attach a horizontal scrollbar to the bottom edge. Shrinks contentH by SCROLLBAR_WIDTH pixels.
+Returns: Pointer to the new ScrollbarT
+Draw the window frame: outer bevel, title bar with text, close/minimize/maximize + gadgets, and menu bar if present. Drawing is clipped to the intersection with clipTo.
+Blit the window's content backbuffer into the display backbuffer, clipped to the + dirty rect. Pure copy operation (no drawing).
+Draw scrollbars (track, arrows, proportional thumb) for a window. Drawn after content + so scrollbars overlay the content area edge.
+Draw icons for all minimized windows along the bottom of the screen. Each icon shows + a scaled preview of the window's content with a beveled border.
+Determine which window and chrome region is under the given screen coordinates. + Iterates front-to-back (highest Z first) so the topmost window wins.
+Returns: Stack index of hit window, or -1 for desktop
+Determine which edge(s) of a window's border zone are targeted for resize.
+Returns: Bitmask of RESIZE_LEFT / RESIZE_RIGHT / RESIZE_TOP / RESIZE_BOTTOM
+Hit-test minimized icons at the bottom of the screen.
+Returns: Stack index of the minimized window, or -1
+Begin a window drag operation. Records the mouse offset from the window origin.
+Update window position during an active drag. Dirties both old and new positions.
+End the current drag operation. Clears dragWindow state.
+Begin a window resize operation. Records which edge(s) are being dragged.
+Update window dimensions during an active resize. Enforces MIN_WINDOW_W/H and + maxW/maxH constraints. Reallocates content buffer and calls onResize if size changed. + mouseX/mouseY are in/out: clamped on return for cursor warping.
+End the current resize operation. Clears resizeWindow state.
+Handle an initial click on a scrollbar. Determines what was hit (arrows, trough, or + thumb) and either adjusts the value immediately or begins a thumb drag.
+Update the scroll value during an active thumb drag. Maps mouse position along the + track to a proportional scroll value.
+End an active scrollbar thumb drag.
+Maximize a window. Saves current geometry, then expands to screen or maxW/maxH bounds.
+Minimize a window. Hides the window and shows an icon at the bottom of the screen.
+Restore a maximized window to its pre-maximize geometry.
+Restore a minimized window (show it again and remove the icon).
+Compute the screen position of a minimized icon by ordinal index. Icons wrap into + rows from bottom to top when the screen fills up.
+Compute the screen rect covering all minimized icon rows. Used to dirty the icon area + when windows are minimized or restored.
+Set the window title and dirty the title bar for repaint.
+Load an icon image for a window from a file. Converts to display pixel format.
+Returns: 0 on success, -1 on failure
++ The topmost layer and the public-facing API. Aggregates all lower layers into a single + AppContextT. Applications interact exclusively through dvx*() functions and window + callbacks. The event loop follows a cooperative model: poll, dispatch, composite, yield. +
+ +Initialize the entire GUI stack: video mode, input devices, font, color scheme, cursor + shapes, and internal state. Single entry point for starting a DVX application.
+Returns: 0 on success, negative on failure
+Tear down the GUI stack in reverse order: destroy all windows, restore text mode, + release input devices. Safe to call after a failed dvxInit().
+Switch to a new video mode live. Reallocates the backbuffer, all window content buffers, + repacks colors, rescales wallpaper, and repositions off-screen windows.
+Returns: 0 on success, -1 on failure (old mode restored)
+Enter the main event loop. Polls input, dispatches events, composites dirty regions, + and yields on each iteration. Returns when ctx->running becomes false.
+Process exactly one frame of the event loop. For applications that integrate the GUI + into their own main loop (e.g. polling serial ports between frames).
+Returns: false when the GUI wants to exit
+Request exit from the main event loop (sets ctx->running = false).
+Create a window at an explicit screen position. The window is raised to the top, + focused, and its entire region is dirtied.
+Returns: Pointer to new WindowT
+Convenience wrapper that centers the window on screen.
+Returns: Pointer to new WindowT
+Destroy a window, free all its resources, and dirty its former region.
+Raise a window to the top of the Z-order and give it focus.
+Resize a window to exactly fit its widget tree's computed minimum size (plus chrome). + Used for dialog boxes and fixed-layout windows.
+Resize window width only to fit widget tree's minimum width (plus chrome).
+Resize window height only to fit widget tree's minimum height (plus chrome).
+Programmatically resize a window to the specified outer dimensions.
+Minimize a window (show as icon at bottom of screen).
+Maximize a window (expand to fill screen or maxW/maxH).
+Hide a window without destroying it. Marks the exposed region dirty.
+Show a previously hidden window. Marks its region dirty for repaint.
+Mark a sub-region of a window's content area as needing repaint. Coordinates are + relative to the content area, not the screen. Triggers onPaint during the next + composite pass.
+Mark the entire window content area as dirty.
+Set a window's title text and dirty the title bar.
+Load an icon for a window from an image file.
+Returns: 0 on success, -1 on failure
+Set or clear busy state. While busy, the hourglass cursor is shown and input is blocked.
+Get a pointer to the default font.
+Returns: Pointer to the active BitmapFontT
+Get a pointer to the current color scheme.
+Returns: Pointer to the active ColorSchemeT
+Get a pointer to the display context.
+Returns: Pointer to the DisplayT
+Get a pointer to the blit operations vtable.
+Returns: Pointer to the active BlitOpsT
+Return the list of available video modes enumerated at init time.
+Returns: Pointer to the VideoModeInfoT array
+Set a single color by ID. Repacks to native pixel format and invalidates the entire screen.
+Get a color's RGB values by ID.
+Apply all colors from ctx->colorRgb[] at once (repack + full repaint).
+Reset all colors to the built-in defaults and repaint.
+Load a theme file (INI format with [colors] section) and apply it.
+Returns: true on success
+Save the current color scheme to a theme file.
+Returns: true on success
+Return the INI key name for a color ID (e.g. "desktop", "windowFace").
+Returns: Static string
+Return a human-readable display label (e.g. "Desktop", "Cursor Color").
+Returns: Static string
+Load and apply a wallpaper image using the current wallpaperMode (stretch/tile/center). + Pass NULL to clear the wallpaper.
+Returns: true on success
+Change the wallpaper display mode and re-render. No effect if no wallpaper is loaded.
+Configure mouse behavior.
+Allocate a new accelerator table. Attach to a window via win->accelTable.
+Returns: Pointer to new AccelTableT
+Free an accelerator table and its entries.
+Register a keyboard shortcut. On match, fires the window's onMenu callback with cmdId.
+Cascade all visible, non-minimized windows. Each is offset diagonally by the title bar height.
+Arrange visible windows in an NxM grid filling the screen.
+Tile windows horizontally (side by side, equal width, full height).
+Tile windows vertically (stacked, full width, equal height).
+Load an image file (BMP, PNG, JPEG, GIF) and convert to the display's native pixel + format. Caller must free with dvxFreeImage().
+Returns: Pixel buffer, or NULL on failure
+Load an image from a memory buffer. Same output format as dvxLoadImage(). Caller must + free with dvxFreeImage().
+Returns: Pixel buffer, or NULL on failure
+Free a pixel buffer returned by dvxLoadImage() or dvxLoadImageFromMemory().
+Query image dimensions without decoding the full file.
+Returns: true on success
+Save native-format pixel data to a PNG file.
+Returns: 0 on success, -1 on failure
+Save the entire screen (backbuffer contents) to a PNG file. Converts from native + pixel format to RGB.
+Returns: 0 on success, -1 on failure
+Save a window's content to a PNG file.
+Returns: 0 on success, -1 on failure
+Copy text to the process-wide clipboard buffer. Simple static buffer (not inter-process).
+Retrieve the current clipboard contents. Returns a pointer to the internal buffer + (valid until the next dvxClipboardCopy), or NULL if empty.
+Returns: Clipboard text, or NULL
+Load an icon/image resource from a DXE file and decode to native pixel format. + Caller must free with dvxFreeImage().
+Returns: Pixel buffer, or NULL if not found
+Load a text resource from a DXE file into a caller-provided buffer. Null-terminated + and truncated to fit bufSize.
+Returns: true on success
+Load a raw binary resource from a DXE file. Returns a malloc'd buffer that the + caller must free.
+Returns: Data buffer, or NULL if not found
+Compute a djb2-xor hash for cheap dirty detection. Compare at save time with + the current hash to detect changes without a shadow copy. Not cryptographic.
+Returns: 32-bit hash value
++ Retained-mode widget toolkit layered on the DVX window manager. Widgets form a tree + (parent-child) rooted at a per-window VBox container. Layout is automatic: measure + minimum sizes bottom-up, then allocate space top-down with flexbox-like weighted + distribution. Widget types are registered dynamically at runtime via DXE plugins. +
+ +Universal Callbacks:
+| Macro | Description |
|---|---|
| wgtPixels(v) | Size in pixels |
| wgtChars(v) | Size in character widths (multiplied by charWidth at layout time) |
| wgtPercent(v) | Size as percentage of parent dimension |
| Flag | Description |
|---|---|
| WCLASS_FOCUSABLE | Can receive keyboard focus (Tab navigation) |
| WCLASS_HORIZ_CONTAINER | Lays out children horizontally (vs. vertical) |
| WCLASS_PAINTS_CHILDREN | Widget handles child rendering itself |
| WCLASS_NO_HIT_RECURSE | Hit testing stops here, no child recursion |
| WCLASS_FOCUS_FORWARD | Accel hit forwards focus to next focusable sibling |
| WCLASS_HAS_POPUP | Has dropdown popup overlay |
| WCLASS_SCROLLABLE | Accepts mouse wheel events |
| WCLASS_SCROLL_CONTAINER | Scroll container (ScrollPane) |
| WCLASS_NEEDS_POLL | Needs periodic polling |
| WCLASS_SWALLOWS_TAB | Tab key goes to widget, not focus navigation |
| WCLASS_RELAYOUT_ON_SCROLL | Full relayout on scrollbar drag |
| WCLASS_PRESS_RELEASE | Click = press + release (Button, ImageButton) |
| WCLASS_ACCEL_WHEN_HIDDEN | Accelerator matching works even when invisible |
Initialize the widget system for a window. Creates a root VBox container that fills + the content area, and installs callback handlers (onPaint, onMouse, onKey, onResize) + for widget-based event dispatch. The window's userData is set to the AppContextT pointer.
+Returns: Root VBox widget (add children to this)
+Walk from any widget up the tree to the root, then retrieve the AppContextT stored + in the window's userData. Lets any widget access the full application context.
+Returns: Pointer to the AppContextT
+Mark a widget as needing both re-layout (measure + position) and repaint. Propagates + upward to ancestors. Use after structural changes (adding/removing children, text changes + that affect size).
+Mark a widget as needing repaint only, without re-layout. Use for visual-only changes + (checkbox toggle, selection highlight, cursor blink).
+Set widget text content (dispatches to the widget class's SET_TEXT handler).
+Get the widget's current text content.
+Returns: Text string (empty string if no handler)
+Enable or disable a widget. Disabled widgets are grayed out and do not receive input.
+Set read-only mode. Allows scrolling and selection but blocks editing.
+Set keyboard focus to a widget.
+Get the currently focused widget.
+Returns: Focused widget, or NULL
+Show or hide a widget.
+Set a widget's name for lookup via wgtFind().
+Find a widget by name. Searches the subtree rooted at root.
+Returns: Matching widget, or NULL
+Destroy a widget and all its children. Removes from parent's child list.
+Set tooltip text for a widget. Pass NULL to remove. Caller owns the string and it + must outlive the widget.
+Default window resize handler installed by wgtInitWindow(). Re-evaluates scrollbars + and relayouts the widget tree. Call from custom onResize handlers to chain to the + widget system.
+Decode a tagged size value (WGT_SIZE_PIXELS/CHARS/PERCENT) into a concrete pixel count. + Returns 0 for a raw 0 input (meaning "auto").
+Returns: Size in pixels
+Execute the full two-pass layout algorithm. Pass 1 (bottom-up): compute minimum sizes. + Pass 2 (top-down): allocate space with weighted distribution. Normally called automatically; + exposed for cases where layout must be forced before the next paint.
+Paint the entire widget tree by depth-first traversal. Each widget's clip rect is set + to its bounds. Overlays (popups, tooltips) are painted in a second pass on top.
+Draw colored borders around layout containers for debugging.
+Register a new widget class at runtime. Appends to widgetClassTable. The WidgetClassT + must remain valid for the lifetime of the process (typically static const in a DXE).
+Returns: Assigned type ID
+Register a widget API struct under a name. Each widget DXE registers its API during + initialization. Callers retrieve it via wgtGetApi() and cast to the widget-specific type.
+Retrieve a registered widget API struct by name.
+Returns: Pointer to the API struct, or NULL if not found
+Register an interface descriptor for a widget type. Used by the BASIC form runtime and + IDE for generic property/method dispatch.
+Retrieve an interface descriptor by widget type name.
+Returns: Interface descriptor, or NULL
+Find a widget type name by its VB-style name (e.g. "CommandButton" -> "button"). + Case-insensitive search.
+Returns: Internal type name, or NULL
+Return the number of registered widget interfaces.
+Returns: Count of registered interfaces
+Get a registered widget interface by index.
+Returns: Interface descriptor
+Get the .wgt DXE file path for a registered widget.
+Returns: File path string
+Set the .wgt DXE file path for a registered widget (called by the loader).
+Get the 1-based index of this widget within its .wgt file. Used to construct suffixed + resource names (e.g. "name-2", "icon16-2").
+Returns: 1-based index within the DXE file
+The following inline functions provide type-safe dispatch through the WidgetClassT +handler table. Each checks for a non-NULL handler before calling.
+ +| Function | Method ID | Description |
|---|---|---|
| wclsHas(w, methodId) | -- | Check if a handler exists for the given method ID |
| wclsPaint(w, d, ops, font, colors) | WGT_METHOD_PAINT | Paint the widget |
| wclsPaintOverlay(w, d, ops, font, colors) | WGT_METHOD_PAINT_OVERLAY | Paint overlay (popups, dropdowns) |
| wclsCalcMinSize(w, font) | WGT_METHOD_CALC_MIN_SIZE | Compute minimum size |
| wclsLayout(w, font) | WGT_METHOD_LAYOUT | Layout children |
| wclsGetLayoutMetrics(w, font, ...) | WGT_METHOD_GET_LAYOUT_METRICS | Get pad, gap, extraTop, borderW |
| wclsOnMouse(w, root, vx, vy) | WGT_METHOD_ON_MOUSE | Handle mouse event |
| wclsOnKey(w, key, mod) | WGT_METHOD_ON_KEY | Handle key event |
| wclsOnAccelActivate(w, root) | WGT_METHOD_ON_ACCEL_ACTIVATE | Handle accelerator activation |
| wclsDestroy(w) | WGT_METHOD_DESTROY | Destroy widget-private data |
| wclsOnChildChanged(parent, child) | WGT_METHOD_ON_CHILD_CHANGED | Notify parent of child change |
| wclsGetText(w) | WGT_METHOD_GET_TEXT | Get widget text |
| wclsSetText(w, text) | WGT_METHOD_SET_TEXT | Set widget text |
| wclsClearSelection(w) | WGT_METHOD_CLEAR_SELECTION | Clear text selection |
| wclsClosePopup(w) | WGT_METHOD_CLOSE_POPUP | Close dropdown popup |
| wclsGetPopupRect(w, font, ...) | WGT_METHOD_GET_POPUP_RECT | Get popup screen rect |
| wclsOnDragUpdate(w, root, x, y) | WGT_METHOD_ON_DRAG_UPDATE | Update during drag |
| wclsOnDragEnd(w, root, x, y) | WGT_METHOD_ON_DRAG_END | End drag operation |
| wclsGetCursorShape(w, vx, vy) | WGT_METHOD_GET_CURSOR_SHAPE | Get cursor shape for position |
| wclsPoll(w, win) | WGT_METHOD_POLL | Periodic polling (comms, etc.) |
| wclsQuickRepaint(w, outY, outH) | WGT_METHOD_QUICK_REPAINT | Fast partial repaint |
| wclsScrollChildIntoView(parent, child) | WGT_METHOD_SCROLL_CHILD_INTO_VIEW | Scroll to make child visible |
DOS Visual eXecutive -- A Windowing GUI for DJGPP/DPMI
+ ++DVX (DOS Visual eXecutive) is a complete windowing GUI compositor targeting +DJGPP/DPMI on DOS. It provides overlapping windows with +Motif-style chrome, a retained-mode widget toolkit, cooperative multitasking +of DXE-loaded applications, and a dirty-rectangle compositor optimized for +486/Pentium hardware. +
+ +Key design constraints:
+tsYield(); there is no preemptive scheduler.The runtime environment consists of a bootstrap loader
+(dvx.exe) that loads core DXE libraries, widget plugins, and
+the shell, which in turn loads and manages DXE application modules.
DVX is organized into five layers, each implemented as a single
+.h/.c pair. Every header includes
+dvxTypes.h (the shared type definitions) to avoid circular
+dependencies. The layers are strictly stacked: each layer depends only on the
+layers below it.
+ Applications (DXE .app modules)
+ ==================================================
+ | |
+ | +------------------------------------------+ |
+ | | Layer 5: dvxApp (Application API) | | dvxApp.h / dvxApp.c
+ | | Event loop, window creation, public API | |
+ | +------------------------------------------+ |
+ | | Layer 4: dvxWm (Window Manager) | | dvxWm.h / dvxWm.c
+ | | Window stack, chrome, drag, resize | |
+ | +------------------------------------------+ |
+ | | Layer 3: dvxComp (Compositor) | | dvxComp.h / dvxComp.c
+ | | Dirty rect tracking, merge, LFB flush | |
+ | +------------------------------------------+ |
+ | | Layer 2: dvxDraw (Drawing Primitives) | | dvxDraw.h / dvxDraw.c
+ | | Rects, bevels, text, blits, cursors | |
+ | +------------------------------------------+ |
+ | | Layer 1: dvxVideo (Video Backend) | | dvxVideo.h / dvxVideo.c
+ | | VESA VBE, LFB mapping, pixel format | |
+ | +------------------------------------------+ |
+ | |
+ | +------------------------------------------+ |
+ | | Platform Layer (dvxPlatform.h) | | dvxPlatformDos.c
+ | | OS-specific: video, input, asm spans | |
+ | +------------------------------------------+ |
+ | |
+ | +------------------------------------------+ |
+ | | Shared Types (dvxTypes.h) | |
+ | | DisplayT, WindowT, RectT, ColorSchemeT | |
+ | +------------------------------------------+ |
+ ==================================================
+
+| Layer | Header | Responsibility |
|---|---|---|
| 1 - Video | +dvxVideo.h |
+ VESA VBE mode negotiation, LFB mapping via DPMI, backbuffer
+ allocation, packColor() (RGB to native pixel format),
+ display-wide clip rectangle. |
+
| 2 - Draw | +dvxDraw.h |
+ All 2D drawing operations: rectFill, rectCopy,
+ drawBevel, drawText/drawTextN,
+ drawMaskedBitmap (cursor), drawTermRow
+ (batch terminal row rendering). Stateless beyond the clip rect on
+ DisplayT. Dispatches hot inner loops through BlitOpsT
+ function pointers. |
+
| 3 - Compositor | +dvxComp.h |
+ Dirty rectangle tracking (dirtyListAdd), pairwise merge
+ of overlapping rects (dirtyListMerge), and the
+ flushRect function that copies dirty regions from the
+ system RAM backbuffer to the LFB. |
+
| 4 - Window Manager | +dvxWm.h |
+ Window lifecycle, Z-order stack, chrome drawing (title bars, bevels, + close/minimize/maximize gadgets), hit testing, drag/resize, menu bars, + scrollbars, system menu, keyboard move/resize mode, minimized icon + bar. | +
| 5 - Application | +dvxApp.h |
+ Public API aggregating all layers into AppContextT.
+ Provides dvxInit/dvxShutdown,
+ dvxRun/dvxUpdate, window creation
+ helpers, image loading, clipboard, accelerator tables, theme
+ management, wallpaper, video mode switching, screenshot capture. |
+
The double-buffer strategy is the single most important performance
+decision in DVX. All drawing goes to a system RAM backbuffer
+(DisplayT.backBuf); only dirty rectangles are flushed to the
+linear framebuffer (DisplayT.lfb) in video
+memory.
This matters because writes to video memory over the PCI bus are +10-50x slower than writes to main RAM on 486/Pentium hardware for +random-access patterns.
+ + 1. Input poll (mouse, keyboard)
+ |
+ 2. Event dispatch (focus window callbacks)
+ |
+ 3. Layers call dirtyListAdd() for changed regions
+ |
+ 4. dirtyListMerge() consolidates overlapping rects
+ |
+ 5. For each merged dirty rect:
+ a. Clip and redraw desktop background (or wallpaper)
+ b. For each window (back-to-front, painter's algorithm):
+ - wmDrawChrome() -- frame, title bar, gadgets, menu bar
+ - wmDrawContent() -- blit per-window content buffer
+ - wmDrawScrollbars()
+ c. Draw minimized window icons
+ d. Draw popup menus / tooltips (overlay pass)
+ e. Draw software mouse cursor
+ |
+ 6. flushRect() -- copy each dirty rect from backBuf to LFB
+ |
+ 7. Yield (platformYield)
+
+
+DisplayTBlitOpsTrep stosl
+ / rep movsd asm inner loops.DirtyListTRectT. Linear scanning for
+ merge candidates is cache-friendly at typical sizes (under 128 rects).
+ If the list fills up, the compositor merges aggressively or falls back to
+ full-screen repaint.Each WindowT is the central object of the window manager. Key
+fields:
| Field Group | Purpose |
|---|---|
Geometry (x, y, w, h) |
+ Outer frame rectangle (including chrome). |
Content area (contentX/Y/W/H) |
+ Computed from frame minus chrome. Where application content lives. |
Content buffer (contentBuf, contentPitch) |
+ Per-window backbuffer in native pixel format. Persists across frames. |
Chrome state (menuBar, vScroll, hScroll) |
+ Optional menu bar and scrollbars. Affect content area computation. |
Widget tree (widgetRoot) |
+ Root of the retained-mode widget tree (NULL if using raw callbacks). |
| Callbacks | +onPaint, onKey, onKeyUp,
+ onMouse,
+ onResize, onClose, onMenu,
+ onScroll, onFocus, onBlur,
+ onCursorQuery. |
WindowStackT is an array of WindowT* ordered
+front-to-back: index count-1 is the topmost window. This allows:
Only one drag/resize/scroll operation can be active system-wide at a time +(single mouse), so that state lives on the stack, not on individual windows.
+ + +-------------------------------------------+
+ | 4px outer border (raised bevel) |
+ | +-------------------------------------+ |
+ | | [X] Title Bar Text [_] [^] [X] | | 20px title height
+ | +-------------------------------------+ |
+ | | 2px inner border | |
+ | +-------------------------------------+ |
+ | | Menu Bar (optional, 20px) | |
+ | +-------------------------------------+ |
+ | | | |
+ | | Content Area | |
+ | | | |
+ | | | S | | S = vertical scrollbar
+ | | | B | | (16px wide)
+ | +-------------------------------------+ |
+ | | Horizontal Scrollbar (optional) | | 16px tall
+ | +-------------------------------------+ |
+ | 4px outer border |
+ +-------------------------------------------+
+
+
+Chrome constants are compile-time defines:
+ CHROME_BORDER_WIDTH = 4px
+ CHROME_TITLE_HEIGHT = 20px
+ CHROME_INNER_BORDER = 2px
+ CHROME_MENU_HEIGHT = 20px
+ SCROLLBAR_WIDTH = 16px
+ CHROME_CLOSE_BTN_SIZE = 16px
+
+
+
+wmHitTest() iterates the stack front-to-back and returns a
+hit-part identifier: HIT_CONTENT, HIT_TITLE,
+HIT_CLOSE, HIT_RESIZE, HIT_MENU,
+HIT_VSCROLL, HIT_HSCROLL,
+HIT_MINIMIZE, HIT_MAXIMIZE.
+Resize edge detection returns a bitmask of RESIZE_LEFT,
+RESIZE_RIGHT, RESIZE_TOP,
+RESIZE_BOTTOM (corners combine two edges).
+
+Menus use fixed-size arrays with inline char buffers (no heap
+strings). Up to 8 menus per bar, items dynamically allocated. Supports
+cascading submenus via MenuItemT.subMenu pointer. Item types:
+normal, checkbox, radio. Separators are non-interactive items. The popup
+state (PopupStateT) tracks a stack of parent frames for
+cascading submenu nesting.
+
+Minimized windows display as 64x64 icons at the bottom of the screen with +beveled borders, similar to a classic desktop icon bar. Icons show a +scaled-down preview of the window's content buffer, refreshed one per frame +in a round-robin fashion to amortize the scaling cost. +
+ + +The widget system (dvxWidget.h) is a retained-mode toolkit
+layered on top of the window manager. Widgets form a tree rooted at a
+per-window VBox container.
Every widget shares the same WidgetT struct. The
+type field is a runtime-assigned integer ID.
+The wclass pointer references the widget's
+WidgetClassT vtable. Widget-specific private data is stored in
+w->data (opaque void*).
Tree linkage: parent, firstChild,
+lastChild, nextSibling. No
+prevSibling -- this halves pointer overhead and removal is
+still O(n) for typical tree depths of 5-10.
Two-pass flexbox-like algorithm:
+weight
+ values (0 = fixed, 100 = normal stretch).Size hints use a tagged encoding: the top 2 bits of an int32_t
+select the unit (pixels, character widths, or percentage of parent), the low
+30 bits hold the value. Macros: wgtPixels(v),
+wgtChars(v), wgtPercent(v).
Each widget type provides a WidgetClassT with a
+handlers[] array indexed by stable method IDs. Method IDs are
+never reordered or reused -- new methods append at the end. This provides
+ABI-stable dispatch so that widget DXEs compiled against an older DVX
+version continue to work.
Methods include: PAINT, PAINT_OVERLAY,
+CALC_MIN_SIZE, LAYOUT, ON_MOUSE,
+ON_KEY, ON_ACCEL_ACTIVATE, DESTROY,
+GET_TEXT, SET_TEXT, POLL, and more
+(21 defined, room for 32).
Class flags encode static properties:
+| Flag | Meaning |
|---|---|
WCLASS_FOCUSABLE | Can receive keyboard focus (Tab navigation) |
WCLASS_HORIZ_CONTAINER | Lays out children horizontally (HBox) |
WCLASS_PAINTS_CHILDREN | Widget handles child rendering itself |
WCLASS_SCROLLABLE | Accepts mouse wheel events |
WCLASS_SCROLL_CONTAINER | ScrollPane -- scrolling viewport |
WCLASS_NEEDS_POLL | Needs periodic polling (e.g. AnsiTerm comms) |
WCLASS_SWALLOWS_TAB | Tab key goes to widget, not focus navigation |
WCLASS_PRESS_RELEASE | Click = press + release (buttons) |
Each widget is a separate .wgt DXE module. 29 widget types
+are included:
| Widget | Description |
|---|---|
| Box (VBox/HBox) | Vertical and horizontal layout containers |
| Button | Clickable push button with label |
| Canvas | Raw drawing surface for custom painting |
| Checkbox | Boolean toggle with checkmark |
| ComboBox | Text input with dropdown list |
| DataCtrl | Data-bound control for database operations |
| DbGrid | Database grid (tabular data display) |
| Dropdown | Dropdown selection list |
| Image | Static image display |
| ImageButton | Button with bitmap icon |
| Label | Static text label |
| ListBox | Scrollable selection list |
| ListView | Multi-column list with headers and sorting |
| ProgressBar | Determinate progress indicator |
| Radio | Radio button (mutual exclusion group) |
| ScrollPane | Scrollable viewport container |
| Separator | Visual divider line |
| Slider | Value selection via draggable thumb |
| Spacer | Empty space for layout |
| Spinner | Numeric input with up/down arrows |
| Splitter | Resizable split pane |
| StatusBar | Window status bar with sections |
| TabControl | Tabbed page container |
| Terminal (AnsiTerm) | ANSI terminal emulator widget |
| TextInput | Single-line text entry field |
| Timer | Periodic timer events |
| Toolbar | Toolbar with icon buttons |
| TreeView | Hierarchical tree display |
| WrapBox | Flow layout (wrapping horizontal container) |
Each widget DXE registers a small API struct under a name during
+wgtRegister(). Callers retrieve it via
+wgtGetApi("button") and cast to the widget-specific API type.
+Per-widget headers provide typed accessors so callers avoid manual casts.
+Adding a new widget requires zero changes to the core.
Each widget can register an interface descriptor that describes its
+BASIC-facing properties, methods, and events. These descriptors are used
+by the form runtime and IDE for generic dispatch and property panel
+enumeration. Properties have typed getters/setters
+(WGT_IFACE_STRING, WGT_IFACE_INT,
+WGT_IFACE_BOOL, WGT_IFACE_ENUM).
DVX uses DJGPP's DXE3 (Dynamic eXtension) format for
+all loadable modules. DXE3 supports RTLD_GLOBAL symbol
+sharing -- symbols exported by one module are visible to all subsequently
+loaded modules. This is critical: widget DXEs call core API functions
+(e.g. rectFill, wgtInvalidate) that are exported
+by the core library DXE.
| Extension | Directory | Purpose | Examples |
|---|---|---|---|
.lib |
+ LIBS/ |
+ Core libraries loaded first. Provide infrastructure APIs. | +libtasks.lib (task switcher),
+ libdvx.lib (GUI core),
+ dvxshell.lib (shell) |
+
.wgt |
+ WIDGETS/ |
+ Widget type plugins. Each exports a wgtRegister()
+ function called at load time. |
+ button.wgt, listview.wgt,
+ terminal.wgt |
+
.app |
+ APPS/*/ |
+ Application modules. Each exports appDescriptor
+ and appMain(). Loaded on demand by the shell. |
+ progman.app, notepad.app,
+ cpanel.app |
+
dvx.exe (loader)
+ |
+ +-- Enter VGA mode 13h, display splash screen with progress bar
+ |
+ +-- Scan LIBS/ for *.lib, WIDGETS/ for *.wgt
+ |
+ +-- Read .dep files for each module (dependency base names)
+ |
+ +-- Topological sort: load modules in dependency order
+ | - dlopen() with RTLD_GLOBAL
+ | - Each .wgt that exports wgtRegister() has it called
+ |
+ +-- Find and call shellMain() (exported by dvxshell.lib)
+ |
+ +-- dvxInit() -- video mode, input, font, colors, cursors
+ |
+ +-- Load desktop app (progman.app)
+ |
+ +-- Main loop:
+ dvxUpdate() -> tsYield() -> shellReapApps()
+
+
+Two kinds of DXE apps:
+ +hasMainLoop = false)appMain() creates windows, registers callbacks, and returns.
+ The app lives through GUI callbacks driven by the shell's main loop.
+ Lifecycle ends when the last window is closed. No extra task stack
+ needed -- simpler and cheaper.hasMainLoop = true)appMain() runs in
+ that task with its own loop, calling tsYield() to share CPU.
+ Needed for apps with continuous work (terminal emulators, games).
+ Lifecycle ends when appMain() returns.
+The platform layer installs signal handlers for SIGSEGV,
+SIGFPE, SIGILL. On crash, the handler logs
+platform-specific diagnostics (register dump on DJGPP), then
+longjmps back to the shell's main loop. The crashed app is
+killed; other apps and the shell survive. This provides Windows 3.1-style
+fault tolerance.
+
+All allocations route through dvxMalloc/dvxFree
+wrappers that prepend a 16-byte header recording the owning app ID and
+allocation size. The Task Manager displays per-app memory usage, and leaks
+are detected at app termination.
+
DVX uses a cooperative polling model. The main loop
+(dvxRun / dvxUpdate) runs this cycle each frame:
platformMousePoll() returns
+ position and button bitmask. Compare with previous frame for
+ press/release edge detection.platformKeyboardRead()
+ returns ASCII + scancode. Non-blocking; returns false if buffer is
+ empty.onKey, onMouse, etc.)
+ on the focused window. If the window has a widget tree, the widget
+ system's installed handlers dispatch to individual widgets.platformYield() or idle
+ callback. Mouse/Keyboard Input
+ |
+ Global handlers (Ctrl+Esc, modal filter)
+ |
+ Accelerator table check (focused window)
+ |
+ Window callback (onMouse / onKey)
+ |
+ [If widget tree installed:]
+ |
+ widgetOnMouse / widgetOnKey
+ |
+ Widget hit test (widgetHitTest)
+ |
+ wclsOnMouse / wclsOnKey (vtable dispatch)
+ |
+ Universal callbacks (onClick, onChange, etc.)
+
+
+
+Per-window accelerator tables map key + modifier combinations to command IDs.
+The runtime normalizes key/modifier at registration time (uppercase key,
+strip shift from modifiers) so matching at dispatch time is two integer
+comparisons per entry. Matched accelerators fire the window's
+onMenu callback with the command ID, unifying the menu and
+hotkey code paths.
+
+Software-rendered cursor using the classic AND/XOR mask approach. Seven +cursor shapes are compiled in: arrow, horizontal resize, vertical resize, +NW-SE diagonal resize, NE-SW diagonal resize, busy (hourglass), and +crosshair. The cursor is painted into the backbuffer on top of the +composited frame and the affected region is flushed to the LFB each frame. +
+ ++Timestamp-based: two clicks on the same target (title bar, minimized icon, +close gadget) within the configurable double-click interval trigger the +double-click action. Separate tracking for each target type. +
+ + +DVX uses fixed-width 8-pixel-wide bitmap fonts only. +One size is provided: 8x16, matching the standard VGA ROM font +and CP437 encoding (256 glyphs).
+ + typedef struct {
+ int32_t charWidth; // fixed width per glyph (always 8)
+ int32_t charHeight; // 16
+ int32_t firstChar; // typically 0
+ int32_t numChars; // typically 256
+ const uint8_t *glyphData; // packed 1bpp, charHeight bytes per glyph
+ } BitmapFontT;
+
+
+Design rationale:
+x = col * 8).drawChar()drawTextN()rectFill,
+ then overlays glyph foreground pixels. Significantly faster than
+ per-character rendering for long runs.drawTermRow()drawTextAccel()& accelerator markers. The character
+ after & is underlined to indicate the keyboard
+ shortcut.
+AppContextT stores a fixed-point 16.16 reciprocal of
+font.charHeight (charHeightRecip) so that dividing
+by charHeight (for pixel-to-row conversion in terminal/text widgets) becomes
+a multiply+shift instead of an integer divide, which costs 40+ cycles on a
+486.
+
+PixelFormatT describes the active VESA mode's pixel encoding.
+Populated once from the VBE mode info block. Stores shift, mask, and bit
+count for each channel so packColor() can convert RGB to native
+format with shift-and-mask arithmetic -- no per-pixel computation.
+
Supported depths:
+| Depth | Bytes/Pixel | Notes |
|---|---|---|
| 8 bpp | 1 | Palette mode. Nearest-index via 6x6x6 color cube + grey ramp. |
| 15 bpp | 2 | 5-5-5 RGB (1 bit unused). |
| 16 bpp | 2 | 5-6-5 RGB. |
| 32 bpp | 4 | 8-8-8 RGB (8 bits unused). |
+All 20 UI colors are pre-packed into display pixel format at init
+time. Every color is a uint32_t that can be written
+directly to the framebuffer with zero per-pixel conversion. The scheme must
+be regenerated on video mode change, but mode changes require re-init
+anyway.
+
Color roles mirror classic Motif/Windows 3.x conventions:
+desktop -- desktop backgroundwindowFace, windowHighlight,
+ windowShadow -- window chrome bevel tripletactiveTitleBg/Fg, inactiveTitleBg/Fg --
+ focused vs. unfocused title barcontentBg/Fg -- window content areamenuBg/Fg, menuHighlightBg/Fg -- menusbuttonFace -- button backgroundscrollbarBg/Fg/Trough -- scrollbar componentscursorFg/Bg -- mouse cursor colorsSource RGB values are kept in AppContextT.colorRgb[] for
+theme save/load. Themes are stored as INI files with a
+[colors] section. The API provides
+dvxLoadTheme(), dvxSaveTheme(),
+dvxSetColor(), and dvxResetColorScheme().
+Bevels are the defining visual element of the Motif aesthetic. Convenience +macros create bevel style descriptors by swapping highlight and shadow +colors: +
+ BEVEL_RAISED(colorScheme, borderWidth) -- raised 3D look
+ BEVEL_SUNKEN(colorScheme, face, borderWidth) -- sunken/inset look
+ BEVEL_TROUGH(colorScheme) -- 1px scrollbar trough
+ BEVEL_SB_BUTTON(colorScheme) -- scrollbar button
+
+
+
+All OS-specific and CPU-specific code is isolated behind
+dvxPlatform.h. To port DVX, implement a new
+dvxPlatformXxx.c against this header.
| File | Target | Details |
|---|---|---|
dvxPlatformDos.c |
+ DJGPP / DPMI | +Real VESA VBE, INT 33h mouse, INT 16h keyboard,
+ rep movsd/rep stosl asm spans,
+ DPMI physical memory mapping for LFB, INT 9 hook for key-up,
+ CuteMouse Wheel API. |
+
platformVideoInit() -- mode probe and framebuffer setup.platformVideoShutdown() -- restore previous mode.platformVideoEnumModes() -- enumerate available modes.platformFlushRect() -- copy dirty rect from backBuf to LFB.
+ On DOS, each scanline uses rep movsd for near-optimal
+ aligned 32-bit writes over the PCI bus.platformSpanFill8/16/32() and
+ platformSpanCopy8/16/32(). Called once per scanline of
+ every rectangle fill, blit, and text draw. On DOS these use inline
+ assembly for critical inner loops
+ memset/memcpy.platformMousePoll() returns position and
+ button bitmask. Wheel support via CuteMouse API.platformKeyboardRead() -- non-blocking key read.platformKeyUpRead() -- key release detection (requires
+ INT 9 hook on DOS).platformAltScanToChar() -- scancode-to-ASCII lookup for
+ Alt+key combinations.platformInstallCrashHandler() -- signal handlers +
+ longjmp for fault tolerance.platformRegisterDxeExports() -- register C runtime and
+ platform symbols for DXE resolution.platformRegisterSymOverrides() -- register function
+ pointer overrides for module loader.DVX is cross-compiled from Linux using a DJGPP cross-compiler
+(i586-pc-msdosdjgpp-gcc). The top-level Makefile
+orchestrates building all subsystems in dependency order.
make -- build everything
+ ./mkcd.sh -- build + create ISO for 86Box
+
+
+ all: core tasks loader texthelp listhelp tools widgets shell taskmgr serial sql apps
+
+
+| Target | Output | Description |
|---|---|---|
core | bin/libs/libdvx.lib |
+ GUI core library (draw, comp, wm, app, widget infrastructure) |
tasks | bin/libs/libtasks.lib |
+ Cooperative task switcher |
loader | bin/dvx.exe |
+ Bootstrap loader (the DOS executable) |
widgets | bin/widgets/*.wgt |
+ 29 widget type plugins |
shell | bin/libs/dvxshell.lib |
+ DVX Shell (app management, desktop) |
taskmgr | bin/libs/taskmgr.lib |
+ Task Manager (loaded as a separate DXE) |
texthelp | shared library | +Shared text editing helpers (clipboard, word boundaries) |
listhelp | shared library | +Shared dropdown/list helpers |
apps | bin/apps/*/*.app |
+ Application modules (progman, notepad, clock, etc.) |
tools | bin/dvxres |
+ Resource compiler (runs on Linux, builds resource sections into DXEs) |
serial | serial DXE libs | +UART driver, HDLC packets, security, seclink |
sql | SQL DXE lib | +SQLite integration |
Each DXE module is compiled to an object file with GCC, then linked
+with dxe3gen:
# Compile
+ i586-pc-msdosdjgpp-gcc -O2 -march=i486 -mtune=i586 -c -o widget.o widget.c
+
+ # Link as DXE with exported symbols
+ dxe3gen -o widget.wgt -E _wgtRegister -U widget.o
+
+ # Optionally append resources
+ dvxres build widget.wgt widget.res
+
+
+The -E flag specifies exported symbols (prefixed with
+underscore per DJGPP convention). -U marks unresolved symbols
+as OK (they'll be resolved at load time from previously loaded DXEs).
make all.dvx.exe,
+ libtasks.lib, libdvx.lib,
+ dvxshell.lib).bin/ using
+ mkisofs:
+ -iso-level 1: strict 8.3 filenames for DOS-J: Joliet extensions for long names-V DVX: volume label~/.var/app/net._86box._86Box/data/86Box/dvx.iso for
+ 86Box to mount as CD-ROM. -O2 Optimization level 2
+ -march=i486 486 instruction set baseline
+ -mtune=i586 Optimize scheduling for Pentium
+ -Wall -Wextra Full warnings
+
+
+ dvxgui/
+ +-- core/ Core library sources (dvxVideo, dvxDraw, dvxComp, dvxWm, dvxApp, widget infra)
+ | +-- platform/ Platform abstraction (dvxPlatform.h, dvxPlatformDos.c)
+ | +-- thirdparty/ stb_image, stb_ds, stb_image_write
+ +-- loader/ Bootstrap loader (dvx.exe)
+ +-- tasks/ Cooperative task switcher (libtasks.lib)
+ +-- shell/ DVX Shell (dvxshell.lib)
+ +-- widgets/ Widget DXE modules (*.wgt), each in its own subdirectory
+ | +-- box/ VBox/HBox layout containers
+ | +-- button/ Push button
+ | +-- textInput/ Text entry field
+ | +-- listView/ Multi-column list
+ | +-- ... (29 widget types total)
+ +-- texthelp/ Shared text editing helpers
+ +-- listhelp/ Shared dropdown/list helpers
+ +-- apps/ Application DXE modules (*.app)
+ | +-- progman/ Program Manager (desktop)
+ | +-- notepad/ Text editor
+ | +-- cpanel/ Control Panel
+ | +-- imgview/ Image viewer
+ | +-- clock/ Clock
+ | +-- dvxdemo/ Demo / showcase app
+ | +-- dvxbasic/ DVX BASIC compiler and VM
+ +-- tools/ Build tools (dvxres resource compiler)
+ +-- rs232/ ISR-driven UART driver
+ +-- packet/ HDLC framing, CRC-16, sliding window
+ +-- security/ DH key exchange, XTEA cipher, DRBG RNG
+ +-- seclink/ Encrypted channel wrapper
+ +-- serial/ Combined serial stack DXE
+ +-- proxy/ Linux proxy (86Box <-> secLink <-> telnet)
+ +-- sql/ SQLite integration
+ +-- bin/ Build output (dvx.exe, libs/, widgets/, apps/, config/)
+ +-- obj/ Intermediate object files
+ +-- docs/ Documentation
+
+
+Generated 2026-04-06. Source: DVX GUI codebase headers and design documents.
+ + + diff --git a/docs/dvx_widget_reference.html b/docs/dvx_widget_reference.html new file mode 100644 index 0000000..7f4a2c8 --- /dev/null +++ b/docs/dvx_widget_reference.html @@ -0,0 +1,1553 @@ + + + + +
+Complete reference for the DVX GUI widget toolkit. All widgets are implemented
+as dynamically loaded DXE modules. They are created via convenience macros
+that wrap the per-widget API function tables. The base WidgetT
+structure is defined in core/dvxWidget.h; individual widget
+headers live in widgets/.
+
+DVX Widget Reference -- Generated from source headers in
+core/dvxWidget.h and widgets/*.h.
+
+This document describes every VB-style control available in DVX BASIC.
+Each control maps to an underlying DVX widget loaded dynamically via
+.wgt DXE files. Properties and methods are dispatched through
+interface descriptors registered by each widget.
+
+Every control in DVX BASIC inherits a set of common properties, events, +and methods. These are handled by the form runtime before dispatching +to widget-specific interface descriptors. +
+ +| Property | Type | R/W | Description |
|---|---|---|---|
Name | String | R | The control's name (e.g. "Command1"). Read-only at runtime. |
Left | Integer | R/W | X position in pixels relative to the parent container. |
Top | Integer | R/W | Y position in pixels relative to the parent container. |
Width | Integer | R/W | Current width in pixels. Setting this changes the minimum width constraint. |
Height | Integer | R/W | Current height in pixels. Setting this changes the minimum height constraint. |
MinWidth | Integer | R/W | Minimum width for layout. Alias for Width in the setter. |
MinHeight | Integer | R/W | Minimum height for layout. Alias for Height in the setter. |
MaxWidth | Integer | R/W | Maximum width cap (0 = no limit, stretch to fill). |
MaxHeight | Integer | R/W | Maximum height cap (0 = no limit, stretch to fill). |
Weight | Integer | R/W | Layout weight. 0 = fixed size, >0 = share extra space proportionally. |
Visible | Boolean | R/W | Whether the control is visible. |
Enabled | Boolean | R/W | Whether the control accepts user input. |
BackColor | Long | R/W | Background color as a 32-bit ARGB value. |
ForeColor | Long | R/W | Foreground (text) color as a 32-bit ARGB value. |
TabIndex | Integer | R | Accepted for VB compatibility but ignored. DVX has no tab order. |
+These events are wired on every control loaded from a .frm
+file. Controls created dynamically at runtime via code only receive
+Click, DblClick, Change, GotFocus, and LostFocus; the keyboard, mouse,
+and scroll events below require the control to be defined in the
+.frm file.
+
| Event | Parameters | Description |
|---|---|---|
Click | (none) | Fires when the control is clicked. |
DblClick | (none) | Fires when the control is double-clicked. |
Change | (none) | Fires when the control's value or text changes. |
GotFocus | (none) | Fires when the control receives keyboard focus. |
LostFocus | (none) | Fires when the control loses keyboard focus. |
KeyPress | KeyAscii As Integer | Fires when a printable key is pressed. KeyAscii is the ASCII code. |
KeyDown | KeyCode As Integer, Shift As Integer | Fires when any key is pressed down. KeyCode is the scan code; Shift indicates modifier keys. |
KeyUp | KeyCode As Integer, Shift As Integer | Fires when a key is released. |
MouseDown | Button As Integer, X As Integer, Y As Integer | Fires when a mouse button is pressed over the control. |
MouseUp | Button As Integer, X As Integer, Y As Integer | Fires when a mouse button is released over the control. |
MouseMove | Button As Integer, X As Integer, Y As Integer | Fires when the mouse moves over the control. |
Scroll | Delta As Integer | Fires when the control is scrolled (mouse wheel or scrollbar). |
| Method | Parameters | Description |
|---|---|---|
SetFocus | (none) | Gives keyboard focus to this control. |
Refresh | (none) | Forces the control to repaint. |
+The Form is the top-level container representing a DVX window. It is declared
+in the .frm file with Begin Form FormName.
+All controls are children of the form's content box, which uses either VBox
+(default) or HBox layout.
+
| Property | Type | Default | Description |
|---|---|---|---|
Name | String | "Form1" | The form's name, used for event dispatch and Load statement. |
Caption | String | (same as Name) | Window title bar text. |
Width | Integer | 400 | Window width in pixels. Setting this disables AutoSize. |
Height | Integer | 300 | Window height in pixels. Setting this disables AutoSize. |
Left | Integer | 0 | Initial X position. Used when Centered is False. |
Top | Integer | 0 | Initial Y position. Used when Centered is False. |
Layout | String | "VBox" | Content box layout: "VBox" (vertical) or "HBox" (horizontal). |
AutoSize | Boolean | True | When True, the window shrink-wraps to fit its content. |
Resizable | Boolean | True | Whether the user can resize the window at runtime. |
Centered | Boolean | True | When True, the window is centered on screen. When False, Left/Top are used. |
| Event | Parameters | Description |
|---|---|---|
Load | (none) | Fires after the form and all controls are created. This is the default event. |
Unload | (none) | Fires when the form is being closed or unloaded. |
QueryUnload | Cancel As Integer | Fires before Unload. Set Cancel = 1 to abort the close. |
Resize | (none) | Fires when the window is resized by the user. |
Activate | (none) | Fires when the window gains focus. |
Deactivate | (none) | Fires when the window loses focus. |
| Statement | Description |
|---|---|
Load FormName | Load the form (creates the window and controls, fires Load event). |
Unload FormName | Unload the form (fires Unload, destroys window). |
FormName.Show | Make the form visible. |
FormName.Show 1 | Show as modal dialog (blocks until closed). |
FormName.Hide | Hide the form without unloading it. |
+Sub Form_Load ()
+ Form1.Caption = "Hello World"
+ Print "Form loaded!"
+End Sub
+
+Sub Form_QueryUnload (Cancel As Integer)
+ If MsgBox("Really quit?", 4) <> 6 Then
+ Cancel = 1
+ End If
+End Sub
+
+Sub Form_Resize ()
+ Print "Window resized"
+End Sub
+
+
+
+
+
+A push button that triggers an action when clicked. Created with
+wgtButton(parent, text).
+
| Property | Type | Description |
|---|---|---|
Caption | String | The text displayed on the button. Use & for accelerator keys (e.g. "&OK"). |
No additional type-specific properties beyond common properties and Caption.
+ +Click+Begin Form Form1 + Caption = "Button Demo" + Begin CommandButton Command1 + Caption = "&Click Me!" + End +End + +Sub Command1_Click () + MsgBox "Button was clicked!" +End Sub ++ + + +
+A static text label. Supports left, center, and right alignment. +
+ +| Property | Type | Description |
|---|---|---|
Caption | String | The text displayed by the label. |
Alignment | Enum | Text alignment: Left (default), Center, or Right. |
Click+Begin Label Label1 + Caption = "Hello, World!" + Alignment = "Center" +End ++ + + +
+A single-line text input field. Supports data binding via DataSource +and DataField properties. +
+ +| Property | Type | Description |
|---|---|---|
Text | String | The text content of the input field. |
DataSource | String | Name of a Data control for data binding. |
DataField | String | Column name for data binding. |
Change+Begin TextBox Text1 + Text = "Enter text here" +End + +Sub Text1_Change () + Label1.Caption = "You typed: " & Text1.Text +End Sub ++ + + +
+A multi-line text editing area. This is a DVX extension with no direct VB3 +equivalent (VB uses a TextBox with MultiLine=True). Supports syntax +colorization, line numbers, auto-indent, and find/replace via the C API. +
+ +| Property | Type | Description |
|---|---|---|
Text | String | The full text content. |
Change+A toggle control with a label. Checked state is exposed as a Boolean. +
+ +| Property | Type | Description |
|---|---|---|
Caption | String | The text displayed next to the checkbox. |
Value | Boolean | True if checked, False if unchecked. |
Click+Begin CheckBox Check1 + Caption = "Enable feature" +End + +Sub Check1_Click () + If Check1.Value Then + Label1.Caption = "Feature ON" + Else + Label1.Caption = "Feature OFF" + End If +End Sub ++ + + +
+A radio button for mutually exclusive choices. DVX uses a radio group
+container; individual OptionButtons are children of the group. The
+Value property returns the button's index within its group.
+
| Property | Type | Description |
|---|---|---|
Caption | String | The text displayed next to the radio button. |
Value | Integer | The index of this radio button within its group (read-only). |
| Method | Parameters | Description |
|---|---|---|
SetSelected | Index As Integer | Select the radio button at the given index within the group. |
Click
+A container with a titled border. Child controls are placed inside the frame
+using VBox layout. In the .frm file, nest Begin/End
+blocks inside the Frame block.
+
| Property | Type | Description |
|---|---|---|
Caption | String | The title displayed in the frame border. |
Click+Begin Frame Frame1 + Caption = "Options" + Begin CheckBox Check1 + Caption = "Option A" + End + Begin CheckBox Check2 + Caption = "Option B" + End +End ++ + + +
+A container that arranges its children vertically, top to bottom. No title
+or border. Use Weight on children to distribute extra space.
+
ClickNo type-specific properties.
+ + + +
+A container that arranges its children horizontally, left to right. Use
+Weight on children to distribute extra space.
+
ClickNo type-specific properties.
+ + + ++A scrollable list of selectable items. Items are managed via methods +(AddItem, RemoveItem, Clear). Supports single and multi-select modes. +
+ +| Property | Type | Description |
|---|---|---|
ListIndex | Integer | Index of the currently selected item (-1 = no selection). |
ListCount | Integer | Number of items in the list (read-only). |
| Method | Parameters | Description |
|---|---|---|
AddItem | Text As String | Add an item to the end of the list. |
RemoveItem | Index As Integer | Remove the item at the given index. |
Clear | (none) | Remove all items from the list. |
List | Index As Integer | Return the text of the item at the given index. |
SelectAll | (none) | Select all items (multi-select mode). |
ClearSelection | (none) | Deselect all items. |
SetMultiSelect | Multi As Boolean | Enable or disable multi-select mode. |
SetReorderable | Reorderable As Boolean | Enable or disable drag-to-reorder. |
IsItemSelected | Index As Integer | Returns True if the item at Index is selected. |
SetItemSelected | Index As Integer, Selected As Boolean | Select or deselect a specific item. |
Click+Sub Form_Load () + List1.AddItem "Apple" + List1.AddItem "Banana" + List1.AddItem "Cherry" +End Sub + +Sub List1_Click () + Dim idx As Integer + idx = List1.ListIndex + If idx >= 0 Then + Label1.Caption = "Selected: " & List1.List(idx) + End If +End Sub ++ + + +
+A combination of a text input and a drop-down list. The user can type +text or select from the list. Supports the same AddItem/RemoveItem/Clear/List +methods as ListBox. +
+ +| Property | Type | Description |
|---|---|---|
Text | String | The text in the editable field. |
ListIndex | Integer | Index of the currently selected list item (-1 = none). |
ListCount | Integer | Number of items in the drop-down list (read-only). |
Same as ListBox: AddItem, RemoveItem, Clear, List.
Click+A read-only drop-down list. Unlike ComboBox, the user cannot type free text; +they can only select from the provided items. Supports AddItem/RemoveItem/Clear/List. +
+ +| Property | Type | Description |
|---|---|---|
ListIndex | Integer | Index of the currently selected item. |
ListCount | Integer | Number of items (read-only). |
Same as ListBox: AddItem, RemoveItem, Clear, List.
Click+A horizontal slider/scrollbar control. The value ranges between a minimum +and maximum set at creation time (default 0 to 100). +
+ +| Property | Type | Description |
|---|---|---|
Value | Integer | The current slider position (clamped to min/max range). |
Change+Begin HScrollBar HScroll1 + MinWidth = 200 +End + +Sub HScroll1_Change () + Label1.Caption = "Value: " & Str$(HScroll1.Value) +End Sub ++ + + +
+A numeric input with up/down buttons. Supports integer mode (default) and +real-number mode with configurable decimal places. +
+ +| Property | Type | Description |
|---|---|---|
Value | Integer | Current integer value (in integer mode). |
RealMode | Boolean | True to use floating-point mode; False for integer mode. |
Decimals | Integer | Number of decimal places shown in real mode. |
| Method | Parameters | Description |
|---|---|---|
SetRange | Min As Integer, Max As Integer | Set the allowed value range. |
SetStep | Step As Integer | Set the increment per button click. |
Change+A non-visual control that fires its event at a regular interval. The Timer +widget is invisible at runtime -- it has no on-screen representation. +
+ +| Property | Type | Description |
|---|---|---|
Enabled | Boolean | True to start the timer, False to stop it. |
Interval | Integer | Timer interval in milliseconds (write-only from BASIC). |
| Method | Parameters | Description |
|---|---|---|
Start | (none) | Start the timer. |
Stop | (none) | Stop the timer. |
| Event | Parameters | Description |
|---|---|---|
Timer | (none) | Fires each time the interval elapses. This is the default event. |
Timer event instead of Change.
+The onChange callback on the underlying widget is remapped automatically.
++Begin Timer Timer1 + Interval = 1000 + Enabled = True +End + +Dim counter As Integer + +Sub Timer1_Timer () + counter = counter + 1 + Label1.Caption = "Ticks: " & Str$(counter) +End Sub ++ + + +
+A drawing surface (canvas). Supports drawing lines, rectangles, circles, +text, and individual pixels. Can save and load BMP images. The default +canvas size is 64x64 pixels. +
+ +| Method | Parameters | Description |
|---|---|---|
Clear | Color As Integer | Fill the entire canvas with the specified color. |
+Additional drawing methods (DrawLine, DrawRect,
+FillRect, FillCircle, SetPixel,
+GetPixel, DrawText, Save,
+Load) are available through the C API but not currently
+exposed through BASIC interface descriptors.
+
Click
+A static image display control. Loads BMP images from file. Cannot be
+placed via the designer toolbox (requires pixel data at creation time);
+typically created in code or loaded via the Picture property.
+
| Property | Type | Description |
|---|---|---|
Picture | String | Path to a BMP file to load (write-only). |
ImageWidth | Integer | Width of the loaded image in pixels (read-only). |
ImageHeight | Integer | Height of the loaded image in pixels (read-only). |
Click
+A button that displays an image instead of text. Like Image, it requires
+pixel data at creation time and is typically loaded via the
+Picture property.
+
| Property | Type | Description |
|---|---|---|
Picture | String | Path to a BMP file to load (write-only). |
ImageWidth | Integer | Width of the loaded image in pixels (read-only). |
ImageHeight | Integer | Height of the loaded image in pixels (read-only). |
Click+A horizontal progress indicator bar. +
+ +| Property | Type | Description |
|---|---|---|
Value | Integer | Current progress value (0-100). |
No type-specific events or methods. No default event.
+ + + ++A multi-column list with column headers. Supports sorting, multi-select, +and drag-to-reorder. Columns are configured via the C API (SetColumns, +SetData). +
+ +| Property | Type | Description |
|---|---|---|
ListIndex | Integer | Index of the currently selected row (-1 = none). |
| Method | Parameters | Description |
|---|---|---|
SelectAll | (none) | Select all rows. |
ClearSelection | (none) | Deselect all rows. |
SetMultiSelect | Multi As Boolean | Enable or disable multi-select. |
SetReorderable | Reorderable As Boolean | Enable or disable row reordering. |
IsItemSelected | Index As Integer | Returns True if the row at Index is selected. |
SetItemSelected | Index As Integer, Selected As Boolean | Select or deselect a specific row. |
Click
+A hierarchical tree of expandable/collapsible nodes. Nodes are created
+via the C API (wgtTreeItem). Supports multi-select and
+drag-to-reorder.
+
| Method | Parameters | Description |
|---|---|---|
SetMultiSelect | Multi As Boolean | Enable or disable multi-select mode. |
SetReorderable | Reorderable As Boolean | Enable or disable node reordering. |
Click+A tabbed container. Each tab page is a separate container that holds +child controls. Switching tabs shows one page and hides others. +
+ +| Property | Type | Description |
|---|---|---|
TabIndex | Integer | Index of the active tab (0-based). Note: this property name collides with the common VB-compatibility TabIndex property, which shadows it at runtime. Use the SetActive method instead to switch tabs. |
| Method | Parameters | Description |
|---|---|---|
SetActive | Index As Integer | Switch to the tab at the given index. This is the recommended way to change tabs at runtime (the TabIndex property is shadowed by the common property handler). |
Click+A resizable split pane. Holds exactly two child widgets separated by a +draggable divider. Default orientation is vertical (top/bottom split). +
+ +| Property | Type | Description |
|---|---|---|
Position | Integer | Position of the divider in pixels from the top (or left). |
No default event.
+ + + ++A scrollable container. Place child controls inside and the ScrollPane +automatically provides scrollbars when the content exceeds the visible area. +
+ +| Property | Type | Description |
|---|---|---|
NoBorder | Boolean | When True, suppresses the border around the scroll pane. |
No default event.
+ + + +
+A container that arranges children in a flowing layout, wrapping to the
+next row when the available width is exceeded. Similar to CSS flexbox with
+flex-wrap: wrap.
+
| Property | Type | Description |
|---|---|---|
Alignment | Enum | Horizontal alignment of items: Left, Center, or Right. |
Click+A visual separator line. The underlying widget supports both horizontal +and vertical orientations. The default (via BASIC) is horizontal. +
+ +No type-specific properties, events, or methods.
+ + + +
+An invisible layout spacer. Takes up space in the layout without rendering
+anything. Useful for pushing controls apart. Give it a Weight
+to absorb extra space.
+
No type-specific properties, events, or methods.
+ + + ++A horizontal container styled as a toolbar, with compact padding and +spacing. Place buttons, labels, or other controls inside. +
+ +No type-specific properties, events, or methods.
+ + + +
+A horizontal container styled as a status bar, typically placed at the
+bottom of a form. At the C API level it accepts child widgets, but it
+is not registered as a container in the form runtime, so child controls
+cannot be nested inside it in .frm files. Set its
+Caption property to display status text.
+
No type-specific properties, events, or methods.
+ + + ++A VT100/ANSI terminal emulator widget. Supports ANSI escape sequences, +scrollback buffer, and serial communication. Default size is 80 columns +by 25 rows. +
+ +| Property | Type | Description |
|---|---|---|
Cols | Integer | Number of character columns (read-only). |
Rows | Integer | Number of character rows (read-only). |
Scrollback | Integer | Number of scrollback lines (write-only). |
| Method | Parameters | Description |
|---|---|---|
Clear | (none) | Clear the terminal screen. |
Write | Text As String | Write text (with ANSI escape processing) to the terminal. |
No default event.
+ + + +
+A data access control that connects to a SQLite database and provides
+record navigation. Other controls can bind to a Data control via their
+DataSource and DataField properties.
+See the Data Binding section for details.
+
| Property | Type | R/W | Description |
|---|---|---|---|
DatabaseName | String | R/W | Path to the SQLite database file. |
RecordSource | String | R/W | Table name or SQL SELECT query for the recordset. |
KeyColumn | String | R/W | Primary key column name (used for UPDATE/DELETE operations). |
Caption | String | R/W | Text displayed on the navigator bar. |
BOF | Boolean | R | True if the current position is before the first record (read-only). |
EOF | Boolean | R | True if the current position is past the last record (read-only). |
MasterSource | String | R/W | Name of a master Data control (for master-detail binding). |
MasterField | String | R/W | Column in the master recordset to filter by. |
DetailField | String | R/W | Column in this recordset that matches the master field. |
| Method | Parameters | Description |
|---|---|---|
MoveFirst | (none) | Navigate to the first record. |
MoveLast | (none) | Navigate to the last record. |
MoveNext | (none) | Navigate to the next record. |
MovePrevious | (none) | Navigate to the previous record. |
AddNew | (none) | Add a new blank record. |
Delete | (none) | Delete the current record. |
Refresh | (none) | Re-query the database and reload records. |
Update | (none) | Write pending changes to the database. |
| Event | Parameters | Description |
|---|---|---|
Reposition | (none) | Fires after the current record changes (navigation). This is the default event. |
Validate | Cancel As Integer | Fires before writing a record. Set Cancel = 1 to abort. |
+A data-bound grid that displays records from a Data control in a tabular
+format. Columns are auto-generated from the query results. Bind it using
+the DataSource property.
+
| Property | Type | Description |
|---|---|---|
DataSource | String | Name of the Data control that supplies records. |
GridLines | Boolean | Show or hide grid lines between cells. |
| Method | Parameters | Description |
|---|---|---|
Refresh | (none) | Reload and redraw the grid from the Data control. |
| Event | Parameters | Description |
|---|---|---|
Click | (none) | Fires when a cell is clicked. |
DblClick | (none) | Fires when a cell is double-clicked. This is the default event. |
+DVX BASIC provides VB3-style data binding through three properties that can +be set on most controls: +
+ +| Property | Set On | Description |
|---|---|---|
DataSource | Any control | Name of the Data control to bind to (e.g. "Data1"). |
DataField | Any control | Column name from the Data control's recordset to display. |
DatabaseName
+ and RecordSource properties.DataSource to the Data control's name and
+ DataField to a column name.Reposition event fires, and the runtime
+ pushes the current record's field values into all bound controls).LostFocus), its current
+ text is written back to the Data control's record cache, and
+ Update is called automatically to persist changes.+For hierarchical data (e.g. orders and order items), use two Data controls: +
+ +MasterSource
+ set to the master's name, MasterField set to the key column
+ in the master, and DetailField set to the foreign key column
+ in the detail table.+When the master record changes, the detail Data control automatically +re-queries using the master's current value for filtering. All controls +bound to the detail are refreshed. +
+ +
+Set the DBGrid's DataSource to a Data control name. The grid
+auto-populates columns from the query results and refreshes whenever the
+Data control refreshes.
+
+VERSION DVX 1.00 +Begin Form frmData + Caption = "Data Binding Example" + AutoSize = False + Width = 400 + Height = 280 + Begin Data Data1 + DatabaseName = "myapp.db" + RecordSource = "customers" + End + Begin Label lblName + Caption = "Name:" + End + Begin TextBox txtName + DataSource = "Data1" + DataField = "name" + End + Begin Label lblEmail + Caption = "Email:" + End + Begin TextBox txtEmail + DataSource = "Data1" + DataField = "email" + End +End + +Sub Data1_Reposition () + Print "Current record changed" +End Sub + +Sub Data1_Validate (Cancel As Integer) + If txtName.Text = "" Then + MsgBox "Name cannot be empty!" + Cancel = 1 + End If +End Sub ++ + + +
+Menus are defined in the .frm file using Begin Menu
+blocks. Each menu item has a name, caption, and nesting level. Menu items
+fire Click events dispatched as
+MenuName_Click.
+
+Begin Form Form1 + Caption = "Menu Demo" + + Begin Menu mnuFile + Caption = "&File" + Begin Menu mnuOpen + Caption = "&Open" + End + Begin Menu mnuSave + Caption = "&Save" + End + Begin Menu mnuSep1 + Caption = "-" + End + Begin Menu mnuExit + Caption = "E&xit" + End + End + + Begin Menu mnuEdit + Caption = "&Edit" + Begin Menu mnuCopy + Caption = "&Copy" + End + Begin Menu mnuPaste + Caption = "&Paste" + End + End +End ++ +
| Property | Type | Description |
|---|---|---|
Caption | String | The text displayed. Use & for accelerator key. Set to "-" for a separator. |
Checked | Boolean | Whether the menu item shows a checkmark. |
Enabled | Boolean | Whether the menu item is enabled (default True). |
+Menu items are nested by placing Begin Menu blocks inside
+other Begin Menu blocks:
+
+A level-0 menu that contains children becomes a top-level menu header. +A non-level-0 menu that contains children becomes a submenu. +
+ +
+Each clickable menu item (not headers, not separators) receives a unique
+numeric ID at load time. When clicked, the form's onMenu
+handler maps the ID to the menu item's name and fires
+MenuName_Click.
+
+Sub mnuOpen_Click () + MsgBox "Open was clicked" +End Sub + +Sub mnuExit_Click () + Unload Form1 +End Sub ++ + + +
+DVX BASIC supports VB-style control arrays. Multiple controls can share
+the same name, differentiated by an Index property. When an
+event fires on a control array element, the element's index is passed as
+the first parameter.
+
+Begin CommandButton Command1 + Caption = "Button A" + Index = 0 +End +Begin CommandButton Command1 + Caption = "Button B" + Index = 1 +End +Begin CommandButton Command1 + Caption = "Button C" + Index = 2 +End ++ +
+When a control has an Index property (>= 0), the event handler
+receives Index As Integer as the first parameter, before any
+event-specific parameters.
+
+Sub Command1_Click (Index As Integer) + Select Case Index + Case 0 + MsgBox "Button A clicked" + Case 1 + MsgBox "Button B clicked" + Case 2 + MsgBox "Button C clicked" + End Select +End Sub ++ +
+Use the indexed form ControlName(Index) to access
+a specific element:
+
+Command1(0).Caption = "New Text" +Command1(1).Enabled = False ++ +
KeyPress would be
+Sub Ctrl1_KeyPress (Index As Integer, KeyAscii As Integer)).
+
+The .frm file is a text file that describes a form's layout,
+controls, menus, and code. It follows a format compatible with VB3 .frm
+files, with DVX-specific extensions.
+
+VERSION DVX 1.00 +Begin Form FormName + form-level properties... + + Begin Menu mnuFile + Caption = "&File" + Begin Menu mnuOpen + Caption = "&Open" + End + End + + Begin TypeName ControlName + property = value + ... + End + + Begin Frame Frame1 + Caption = "Group" + Begin TypeName ChildName + ... + End + End +End + +BASIC code follows... + +Sub FormName_Load () + ... +End Sub ++ +
VERSION line is optional. VERSION DVX 1.00 marks a native DVX form.
+ VB forms with version <= 2.0 are accepted for import.Begin Form Name and ends with End.Begin TypeName Name / End.Key = Value. String values are optionally quoted.End is BASIC source code.' (single quote).| Property | Applies To | Description |
|---|---|---|
Caption | Form, controls | Display text or window title. |
Text | TextBox, ComboBox | Initial text content. |
MinWidth / Width | Controls | Minimum width. Both names are accepted. |
MinHeight / Height | Controls | Minimum height. Both names are accepted. |
MaxWidth | Controls | Maximum width (0 = no cap). |
MaxHeight | Controls | Maximum height (0 = no cap). |
Weight | Controls | Layout weight for flexible sizing. |
Left | Form, controls | X position (used by Form when Centered=False; informational for controls). |
Top | Form, controls | Y position. |
Index | Controls | Control array index (-1 or absent = not in array). |
Visible | Controls | Initial visibility. |
Enabled | Controls | Initial enabled state. |
Layout | Form | "VBox" or "HBox". |
AutoSize | Form | Auto-fit window to content. |
Resizable | Form | Allow runtime resizing. |
Centered | Form | Center window on screen. |
DatabaseName | Data | SQLite database file path. |
RecordSource | Data | Table name or SQL query. |
DataSource | Bound controls | Name of the Data control. |
DataField | Bound controls | Column name in the recordset. |
+DVX BASIC Control Reference -- Generated from source code analysis of +formrt.c, ideProperties.c, ideDesigner.c, and widget DXE interface descriptors. +
+ + + diff --git a/docs/dvxbasic_ide_guide.html b/docs/dvxbasic_ide_guide.html new file mode 100644 index 0000000..4a82f00 --- /dev/null +++ b/docs/dvxbasic_ide_guide.html @@ -0,0 +1,895 @@ + + + + ++DVX BASIC is a Visual BASIC development environment for the DVX GUI System. +It provides a VB3-style integrated development environment with a code editor, +form designer, project system, and a full interactive debugger -- all running +natively on DOS under the DVX windowing system. +
++This guide covers every feature of the IDE: menus, toolbar, editor, form +designer, project management, debugger, and auxiliary windows. +
+ ++The DVX BASIC IDE is modeled after Visual Basic 3.0. It consists of several +floating windows arranged on the DVX desktop: +
++The IDE compiles BASIC source into bytecode and runs it in an integrated virtual +machine (VM). Programs execute in cooperative slices (10,000 VM steps per slice), +yielding to the DVX event loop between slices so the GUI remains responsive. +
+ + +| Menu Item | Shortcut | Description |
|---|---|---|
| New Project... | Create a new DVX BASIC project. | |
| Open Project... | Open an existing .dbp project file. | |
| Save Project | Save the current project file to disk. | |
| Close Project | Close the current project (prompts to save unsaved changes). | |
| Project Properties... | Edit project metadata (name, author, version, startup form, icon, etc.). | |
| Add File... | Ctrl+O | Add a .bas or .frm file to the project. If no project is open, creates an implicit project from the file. |
| Save File | Ctrl+S | Save the active file to disk. |
| Save All | Save all modified files in the project. | |
| Remove File | Remove the selected file from the project (prompts to save if modified). | |
| Exit | Close the IDE (prompts to save unsaved changes). | |
| Menu Item | Shortcut | Description |
|---|---|---|
| Cut | Ctrl+X | Cut selected text to the clipboard. |
| Copy | Ctrl+C | Copy selected text to the clipboard. |
| Paste | Ctrl+V | Paste text from the clipboard. |
| Select All | Ctrl+A | Select all text in the active editor. |
| Delete | Del | Delete the selected text or control (in the form designer). |
| Find... | Ctrl+F | Open the Find/Replace dialog. |
| Find Next | F3 | Find the next occurrence of the search text. |
| Replace... | Ctrl+H | Open the Find/Replace dialog with replace enabled. |
| Menu Item | Shortcut | Description |
|---|---|---|
| Run | F5 | Compile and run the program. If paused at a breakpoint, resumes execution with debugging disabled (runs free). |
| Debug | Shift+F5 | Compile and run with the debugger active. Breakpoints are active but execution does not pause at the first statement. If paused, resumes to the next breakpoint. |
| Run Without Recompile | Ctrl+F5 | Re-run the last compiled module without recompiling. |
| Stop | Esc | Stop the running program immediately. |
| Step Into | F8 | Execute one statement, stepping into SUB/FUNCTION calls. If idle, starts a debug session and breaks at the first statement. |
| Step Over | Shift+F8 | Execute one statement, stepping over SUB/FUNCTION calls. |
| Step Out | Ctrl+Shift+F8 | Run until the current SUB/FUNCTION returns. |
| Run to Cursor | Ctrl+F8 | Run until execution reaches the line where the cursor is positioned. |
| Toggle Breakpoint | F9 | Toggle a breakpoint on the current editor line. |
| Clear Output | Clear the Output window. | |
| Save on Run | Checkbox: when enabled, all modified files are saved automatically before compiling. Persisted in preferences. | |
| Menu Item | Shortcut | Description |
|---|---|---|
| Code | F7 | Switch to Code view for the active file (or the file selected in the Project Explorer). |
| Designer | Shift+F7 | Switch to Design view for the active form file. |
| Toolbar | Checkbox: show or hide the toolbar. Persisted in preferences. | |
| Status Bar | Checkbox: show or hide the status bar. Persisted in preferences. | |
| Menu Editor... | Ctrl+E | Open the Menu Editor dialog for the active form. Allows designing menu bars with captions, names, levels, checked state, and enabled state. |
| Menu Item | Description |
|---|---|
| Code Editor | Show or raise the Code Editor window. |
| Output | Show or raise the Output window. |
| Immediate | Show or raise the Immediate window. |
| Locals | Show or raise the Locals debug window. |
| Call Stack | Show or raise the Call Stack debug window. |
| Watch | Show or raise the Watch debug window. |
| Breakpoints | Show or raise the Breakpoints window. |
| Project Explorer | Show or raise the Project Explorer window. |
| Toolbox | Show or raise the Toolbox window. |
| Properties | Show or raise the Properties panel. |
| Menu Item | Description |
|---|---|
| Preferences... | Open the Preferences dialog (editor settings and project defaults). |
| Debug Layout | Checkbox: toggle a debug overlay that shows widget layout boundaries. Useful for diagnosing widget layout issues. |
| Menu Item | Description |
|---|---|
| About DVX BASIC... | Show the About dialog with version and copyright information. |
+The toolbar is organized into four groups separated by vertical dividers. +Each button has a tooltip showing its name and keyboard shortcut. +
+ +| Button | Shortcut | Action |
|---|---|---|
| Open | Ctrl+O | Add a file to the project (same as File > Add File). |
| Save | Ctrl+S | Save the active file. |
| Button | Shortcut | Action |
|---|---|---|
| Run | F5 | Compile and run the program. |
| Stop | Esc | Stop the running program. |
| Button | Shortcut | Action |
|---|---|---|
| Debug | Shift+F5 | Start or resume a debug session. |
| Step Into | F8 | Step into the next statement. |
| Step Over | Shift+F8 | Step over the next statement. |
| Step Out | Ctrl+Shift+F8 | Step out of the current procedure. |
| Run to Cursor | Ctrl+F8 | Run to the cursor position. |
| Button | Shortcut | Action |
|---|---|---|
| Code | F7 | Switch to Code view. |
| Design | Shift+F7 | Switch to Design view. |
+The Code Editor is the primary editing window for BASIC source code. It +occupies the center of the screen, below the toolbar and above the Output +and Immediate windows. +
+ ++At the top of the Code Editor are two dropdown lists: +
+(General) plus all objects
+ (form name, control names, menu item names). Selecting an object filters
+ the Function dropdown.[Click]).
+ Selecting an unimplemented event creates a new event handler stub.
+The editor shows one procedure at a time. Each procedure has its own buffer,
+and switching between them is instantaneous. The (General) section
+contains module-level declarations and code.
+
+The editor applies real-time syntax coloring as you type. The following +categories are highlighted in distinct colors: +
+| Category | Examples |
|---|---|
| Keywords | IF, THEN, FOR, NEXT, SUB, FUNCTION, DIM, PRINT, SELECT, CASE, DO, LOOP, WHILE, WEND, END, EXIT, CALL, GOSUB, GOTO, RETURN, DECLARE, CONST, TYPE, AND, OR, NOT, XOR, MOD, etc. |
| Type names | INTEGER, LONG, SINGLE, DOUBLE, STRING, BOOLEAN, BYTE, TRUE, FALSE |
| String literals | "Hello, World!" |
| Comments | ' This is a comment, REM This is a comment |
| Numbers | 42, 3.14 |
| Operators | =, <, >, +, -, *, /, \, & |
+The Form Designer provides a visual design surface for editing .frm files. +Switch to it with Shift+F7 or the Design toolbar button. It opens +in a separate window showing a WYSIWYG preview of the form. +
+ +DSGN_GRID_SIZE) when placed or resized.Command1, Command2). Clicking the same
+ tool again deselects it (toggles back to pointer mode).+Forms have the following design-time properties: Name, Caption, Width, Height, +Left, Top, Layout (VBox or HBox), Centered, AutoSize, and Resizable. +
+ + +
+A DVX BASIC project is stored as a .dbp file (DVX BASIC Project).
+The project file records:
+
+When the project is compiled, all files are concatenated into a single source
+stream. A source map tracks which lines belong to which file, enabling accurate
+error reporting and debugger navigation across multiple files. For .frm files,
+an injected BEGINFORM directive is prepended to the code section.
+
| Operation | Description |
|---|---|
| New Project | Creates a blank project with a name and directory. A default .frm file is added automatically. |
| Open Project | Opens a .dbp file and loads all referenced files into memory. |
| Save Project | Writes the .dbp file to disk. |
| Close Project | Closes the project, prompting to save unsaved changes. |
| Add File | Adds a .bas or .frm file to the project. Opening a file without a project auto-creates an implicit project. |
| Remove File | Removes a file from the project (prompts to save if modified). |
| Project Properties | Opens a dialog for editing project metadata (name, author, company, version, copyright, description, icon, startup form). |
+The Project Explorer is a tree view window listing all project files. Double-click +a file to open it: .bas files open in Code view, .frm files open in Design view. +The selected file in the Project Explorer determines the target for View > Code +and View > Designer commands. +
+ + ++The Properties panel (Window > Properties) has two sections: +
++Each control type exposes different properties (e.g., Caption, Text, Width, Height, +MaxWidth, MaxHeight, Weight, Alignment, Enabled, Visible, and type-specific +properties like DataSource and DataField for data-bound controls). +
+ + +
+The Toolbox (Window > Toolbox) is a floating palette of
+buttons, one for each available control type. Controls are loaded dynamically
+from the widget plugin registry -- any widget DXE that provides a
+basName appears in the toolbox.
+
+Click a tool to select it (the active tool name is stored in the designer +state), then click on the form to place a new instance. Click the same tool +again to deselect it and return to pointer mode. +
+ +| VB Name | Description |
|---|---|
| CommandButton | Push button that triggers a Click event. |
| Label | Static text label. |
| TextBox | Single-line text input field. |
| TextArea | Multi-line text editor. |
| CheckBox | On/off checkbox. |
| OptionButton | Radio button (mutually exclusive within a group). |
| ListBox | Scrollable list of items. |
| ComboBox | Drop-down combo box. |
| DropDown | Simple drop-down list. |
| PictureBox | Canvas for drawing and images. |
| Image | Static image display. |
| ImageButton | Clickable image button. |
| Frame | Grouping container with a labeled border. |
| VBox | Vertical layout container. |
| HBox | Horizontal layout container. |
| WrapBox | Flow layout container that wraps items to the next row. |
| Splitter | Resizable split between two child panes. |
| ScrollPane | Scrollable container for large content. |
| TabStrip | Tabbed container with multiple pages. |
| ListView | Multi-column list with headers. |
| TreeView | Hierarchical tree control. |
| ProgressBar | Progress indicator bar. |
| HScrollBar | Horizontal slider/scrollbar. |
| SpinButton | Numeric up/down spinner. |
| Line | Horizontal or vertical separator line. |
| Spacer | Invisible spacing element for layout. |
| Timer | Non-visual timer that fires periodic events. |
| Toolbar | Toolbar container for buttons. |
| StatusBar | Status bar at the bottom of a form. |
| Terminal | ANSI terminal emulator control. |
| Data | Data control for binding to a database. |
| DBGrid | Data-bound grid for displaying database query results. |
+The DVX BASIC IDE includes a full interactive debugger. The debugger operates +as a state machine with three states: +
+| State | Description |
|---|---|
DBG_IDLE | No program loaded or running. |
DBG_RUNNING | Program is executing (VM running in slices). |
DBG_PAUSED | Execution is paused at a breakpoint or step point. The IDE GUI is fully interactive. |
+Not every line can have a breakpoint. The IDE validates the line content and +silently refuses to set breakpoints on: +
+' or REM)SUB and FUNCTION declaration linesEND SUB and END FUNCTION lines
+Each breakpoint records the project file index, the code line number within the
+file, the procedure index, and the procedure name (as Object.Event).
+When the project is compiled, breakpoints are converted to concatenated source
+line numbers that match the VM's OP_LINE opcodes.
+
+When lines are added or removed in the editor, breakpoints below the edit +point are automatically shifted to stay on the correct line. +
+ +| Action | Shortcut | Behavior |
|---|---|---|
| Step Into | F8 | Execute one statement. If the statement is a SUB/FUNCTION call, step into it. |
| Step Over | Shift+F8 | Execute one statement. If the statement is a SUB/FUNCTION call, execute the entire call and break at the next line in the current scope. |
| Step Out | Ctrl+Shift+F8 | Run until the current SUB/FUNCTION returns to its caller. |
| Run to Cursor | Ctrl+F8 | Run until execution reaches the line under the cursor. |
+When a program is running in debug mode, the IDE enters a cooperative loop: +
+BAS_VM_BREAKPOINT), the state
+ transitions to DBG_PAUSED. The IDE navigates the code editor
+ to the breakpoint line, highlights it in yellow, auto-opens the Locals
+ and Call Stack windows, and updates all debug windows.dvxUpdate() continuously,
+ keeping the GUI responsive. The user can inspect variables, modify them
+ in the Immediate window, step, continue, or stop.DBG_RUNNING and the loop continues.
+Press Esc or click the Stop toolbar button at any time to halt execution.
+The VM is destroyed, debug state resets to DBG_IDLE, and the IDE
+restores the designer windows that were hidden at run start.
+
+When the debugger pauses, the Locals and Call Stack windows are auto-opened +(if not already visible). The Watch and Breakpoints windows can be opened +manually from the Window menu. +
+ ++Shows variables for the current execution scope. Displayed as a three-column +ListView: +
+| Column | Content |
|---|---|
| Name | Variable name (internal mangled names like static variable placeholders are filtered out). |
| Type | Data type: Integer, Long, Single, Double, String, Boolean, Array, UDT. Array types show the element type (e.g., Integer()). |
| Value | Current value. Strings are shown in quotes. Booleans as True/False. Arrays show bounds and element count (e.g., Integer(0 To 9) [10]). Uninitialized arrays show (uninitialized). |
+The Locals window displays: +
++Up to 64 variables are displayed. The window is resizable. +
+ ++Shows the current call chain as a two-column ListView: +
+| Column | Content |
|---|---|
| Procedure | Procedure name (or (module) for module-level code). |
| Line | Line number where execution is paused (shown for the topmost frame). |
+The current location is shown first, followed by each caller in the call stack +(walking from the deepest frame back to the module entry point). Up to 32 +frames are displayed. +
+ ++Allows monitoring arbitrary expressions while debugging. The window has +a text input at the top and a two-column ListView below: +
+| Column | Content |
|---|---|
| Expression | The watch expression text. |
| Value | Evaluated result (or <error> if evaluation fails). Blank when not paused. |
+Type an expression in the text input and press Enter. +Up to 16 watch expressions can be active at once. +
+ ++Watch expressions support: +
+x, countarr(5), matrix(2, 3)player.nameitems(i).pricex + y * 2, Len(name$)+Lists all set breakpoints as a three-column ListView: +
+| Column | Content |
|---|---|
| File | Project file path. |
| Procedure | Procedure name (Object.Event format, or (General)). |
| Line | Code line number within the file. |
+The Immediate window is an interactive REPL at the bottom-right of the screen. +Type a line of BASIC and press Enter to evaluate it. Results appear +inline below your input. +
+ +
+If the input is not a recognized statement keyword, it is automatically wrapped
+in a PRINT statement. For example, typing 2 + 2
+evaluates as PRINT 2 + 2 and displays 4.
+
+You can also type full statements: +
+PRINT x * 2 -- evaluate and print an expression.DIM tmp As Integer -- declare a temporary variable.LET x = 42 -- explicit assignment (see below).
+Parse or runtime errors are displayed inline with an Error: prefix.
+
+When the debugger is paused at a breakpoint, the Immediate window has access
+to the running VM's state. Global variable values are copied into the evaluation
+VM, so expressions like count or name$ & " test"
+display live values.
+
+When paused, you can modify variables in the running program directly from the +Immediate window using assignment syntax: +
+variableName = newValue
+
+The optional LET keyword is also accepted:
+
LET variableName = newValue
++Assignment works for: +
+x = 42, name$ = "test"arr(5) = 100, matrix(2, 3) = 7.5player.score = 1000items(0).price = 9.99+The new value is written directly into the VM's live variable slot (local, +global, or form scope). A confirmation message is displayed, and the Locals +and Watch windows update automatically to reflect the change. +
++If the assignment target cannot be resolved (unknown variable, out-of-bounds +index, wrong type), an error message is displayed. +
+ + ++The Output window is a read-only TextArea at the bottom-left of the screen. +It displays: +
+PRINT statement output from
+ the running program is appended here.Error on line N: prefix.+The output buffer holds up to 32,768 characters. Use Run > Clear Output +to clear it. +
+
+INPUT statements prompt the user via a modal InputBox dialog; the
+prompt text is also echoed to the Output window.
+
+Open with Ctrl+F (Find) or Ctrl+H (Replace). The +Find/Replace dialog is modeless -- it stays open while you continue editing. +
+ +| Control | Description |
|---|---|
| Find input | The text to search for. |
| Replace checkbox + input | Enable replacement mode and enter replacement text. |
| Scope | Radio group: Function, Object, File, or Project. Default is Project. |
| Direction | Radio group: Forward or Backward. |
| Match Case | Checkbox: case-sensitive search. |
| Button | Action |
|---|---|
| Find Next | Find the next occurrence. Wraps across procedures, files, and the entire project depending on the scope setting. |
| Replace | Replace the current match and find the next one. |
| Replace All | Replace all occurrences within the selected scope. |
| Close | Close the dialog. |
+F3 repeats the last search (Find Next) without opening the dialog. +
+ + +
+Open via Tools > Preferences. Settings are saved to
+dvxbasic.ini in the app's config directory.
+
| Setting | Description | Default |
|---|---|---|
| Skip comments/strings when renaming | When renaming a control or form, skip occurrences inside comments and string literals. | On |
| Require variable declaration (OPTION EXPLICIT) | When enabled, variables must be declared with DIM before use. | Off |
| Tab width | Number of spaces per tab stop (1-8). | 3 |
| Insert spaces instead of tabs | When enabled, pressing Tab inserts spaces. When disabled, inserts a real tab character. | On |
+These fields set the default values for new project metadata: +
+| Field | Description | Default |
|---|---|---|
| Author | Default author name. | (empty) |
| Company | Default company name. | (empty) |
| Version | Default version string. | 1.0 |
| Copyright | Default copyright notice. | (empty) |
| Description | Default project description (multi-line). | (empty) |
| Shortcut | Action |
|---|---|
| Ctrl+O | Add File |
| Ctrl+S | Save File |
| Ctrl+A | Select All |
| Ctrl+X | Cut |
| Ctrl+C | Copy |
| Ctrl+V | Paste |
| Ctrl+F | Find |
| Ctrl+H | Replace |
| Ctrl+E | Menu Editor |
| F3 | Find Next |
| F5 | Run |
| Shift+F5 | Debug |
| Ctrl+F5 | Run Without Recompile |
| Esc | Stop |
| F7 | Code View |
| Shift+F7 | Design View |
| F8 | Step Into |
| Shift+F8 | Step Over |
| Ctrl+Shift+F8 | Step Out |
| Ctrl+F8 | Run to Cursor |
| F9 | Toggle Breakpoint |
| Del | Delete |
DVX BASIC 1.0 -- Copyright 2026 Scott Duensing
+ + + diff --git a/docs/dvxbasic_language_reference.html b/docs/dvxbasic_language_reference.html new file mode 100644 index 0000000..2b3f7cd --- /dev/null +++ b/docs/dvxbasic_language_reference.html @@ -0,0 +1,1973 @@ + + + + +Complete reference for the DVX BASIC language as implemented in the +DVX BASIC compiler and runtime. DVX BASIC is a QuickBASIC/Visual Basic +compatible dialect targeting the DVX GUI environment.
+ +DVX BASIC supports the following data types. Each type has a corresponding +type suffix character that can be appended to variable names.
+ +| Type | +Size | +Suffix | +Range / Description | +
|---|---|---|---|
Integer |
+ 2 bytes | +% |
+ -32768 to 32767 | +
Long |
+ 4 bytes | +& |
+ -2147483648 to 2147483647 | +
Single |
+ 4 bytes | +! |
+ 32-bit float, approximately 7 digits precision | +
Double |
+ 8 bytes | +# |
+ 64-bit float, approximately 15 digits precision | +
String |
+ variable | +$ |
+ Variable-length, reference-counted, dynamic string | +
Boolean |
+ 2 bytes | ++ | True (-1) or False (0) | +
| Internal Type | +Description | +
|---|---|
| Array | +Reference-counted multi-dimensional array (up to 8 dimensions) | +
| UDT | +User-defined type instance (created with TYPE...END TYPE) |
+
| Object | +Opaque host object (form reference, control reference) | +
| Ref | +ByRef pointer to a variable slot (used for ByRef parameters) | +
Type suffixes can be appended to variable names to declare their type +implicitly:
+ ++count% = 42 ' Integer +total& = 100000 ' Long +rate! = 3.14 ' Single +pi# = 3.14159265 ' Double +name$ = "Hello" ' String ++ +
| Form | Example | Description |
|---|---|---|
| Decimal integer | 42 | Values -32768..32767 are Integer; larger values are Long |
| Hex integer | &HFF | Hexadecimal literal |
| Long suffix | 42&, &HFF& | Force Long type |
| Floating-point | 3.14, 1.5E10 | Double by default |
| Single suffix | 3.14! | Force Single type |
| Double suffix | 3.14# | Force Double type |
When mixing types in expressions, values are automatically promoted to a
+common type: Integer -> Long -> Single -> Double. Strings are
+not automatically converted to numbers (use VAL and
+STR$).
Operators listed from highest precedence (evaluated first) to lowest +precedence (evaluated last).
+ +| Precedence | +Operator | +Description | +
|---|---|---|
| 1 (highest) | +^ |
+ Exponentiation | +
| 2 | +- (unary) |
+ Negation | +
| 3 | +* / \
+ MOD |
+ Multiplication, float division, integer division, modulus | +
| 4 | ++ - |
+ Addition, subtraction | +
| 5 | +& |
+ String concatenation | +
| 6 | += <> <
+ > <=
+ >= |
+ Comparison (returns Boolean) | +
| 7 | +NOT |
+ Logical/bitwise NOT | +
| 8 | +AND |
+ Logical/bitwise AND | +
| 9 | +XOR |
+ Logical/bitwise XOR | +
| 10 | +OR |
+ Logical/bitwise OR | +
| 11 | +EQV |
+ Logical/bitwise equivalence | +
| 12 (lowest) | +IMP |
+ Logical/bitwise implication | +
Use & to concatenate strings. The + operator
+also concatenates when both operands are strings.
+result$ = "Hello" & " " & "World" +result$ = firstName$ & " " & lastName$ ++ + + +
Multiple statements can appear on one line separated by :.
+Lines can be continued with _ at the end. Comments start with
+' or REM.
Declares variables and arrays with an explicit type.
+ ++DIM variable AS type +DIM variable(upperBound) AS type +DIM variable(lower TO upper) AS type +DIM variable(dim1, dim2, ...) AS type +DIM variable AS UdtName +DIM variable AS STRING * n +DIM SHARED variable AS type ++ +
Examples:
+ ++Dim name As String +Dim count As Integer +Dim values(100) As Double +Dim matrix(1 To 10, 1 To 10) As Single +Dim Shared globalFlag As Boolean +Dim record As PersonType +Dim fixedStr As String * 20 ++ +
DIM SHARED makes a variable accessible from all procedures
+without passing it as a parameter.
+Reallocates a dynamic array, optionally preserving existing data.
+ ++REDIM array(newBounds) AS type +REDIM PRESERVE array(newBounds) AS type ++ +
+ReDim items(newSize) As String +ReDim Preserve scores(1 To newCount) As Integer ++ + + +
Declares a named constant. The value must be a literal (integer, float, +string, or boolean).
+ ++CONST name = value ++ +
+Const MAX_SIZE = 100 +Const PI = 3.14159265 +Const APP_NAME = "DVX App" +Const DEBUG_MODE = True ++ + + +
Defines a user-defined type (record/structure).
+ ++TYPE TypeName + fieldName AS type + ... +END TYPE ++ +
+Type PersonType + firstName As String + lastName As String + age As Integer +End Type + +Dim p As PersonType +p.firstName = "Scott" +p.age = 30 ++ +
UDT fields can themselves be UDTs (nested types).
+ + + +Conditional execution. Supports single-line and multi-line forms.
+ ++IF condition THEN statement +IF condition THEN statement ELSE statement ++ +
+IF condition THEN + statements +ELSEIF condition THEN + statements +ELSE + statements +END IF ++ +
+If x > 10 Then + Print "Large" +ElseIf x > 5 Then + Print "Medium" +Else + Print "Small" +End If + +If ready Then Print "Go!" ++ + + +
Multi-way branch based on an expression value.
+ ++SELECT CASE expression + CASE value + statements + CASE value1, value2 + statements + CASE low TO high + statements + CASE IS operator value + statements + CASE ELSE + statements +END SELECT ++ +
+Select Case grade + Case 90 To 100 + Print "A" + Case 80 To 89 + Print "B" + Case Is >= 70 + Print "C" + Case 60, 65 + Print "D (borderline)" + Case Else + Print "F" +End Select ++ +
CASE items can be combined with commas. The IS keyword allows
+comparison operators: <, >,
+<=, >=, =,
+<>.
Counted loop with an optional step value.
+ ++FOR variable = start TO limit [STEP step] + statements +NEXT [variable] ++ +
+For i = 1 To 10 + Print i +Next i + +For x = 10 To 0 Step -2 + Print x +Next ++ +
The variable name after NEXT is optional. Use
+EXIT FOR to break out early.
General-purpose loop with pre-test, post-test, or infinite forms.
+ ++DO [WHILE condition | UNTIL condition] + statements +LOOP [WHILE condition | UNTIL condition] ++ +
+' Pre-test +Do While count < 10 + count = count + 1 +Loop + +' Post-test +Do + line$ = ReadLine() +Loop Until line$ = "quit" + +' Infinite loop (exit with EXIT DO) +Do + DoEvents + If done Then Exit Do +Loop ++ + + +
Simple pre-test loop (legacy form; prefer DO...LOOP).
+WHILE condition + statements +WEND ++ +
+While Not EOF(1) + Line Input #1, line$ + Print line$ +Wend ++ + + +
Defines a subroutine (no return value).
+ ++SUB name ([BYVAL] param AS type, ...) + statements +END SUB ++ +
+Sub Greet(ByVal name As String) + Print "Hello, " & name +End Sub ++ +
Parameters are passed ByRef by default. Use
+ByVal for value semantics. Use EXIT SUB to
+return early.
Defines a function with a return value.
+ ++FUNCTION name ([BYVAL] param AS type, ...) AS returnType + statements + name = returnValue +END FUNCTION ++ +
+Function Square(ByVal n As Double) As Double + Square = n * n +End Function ++ +
Assign to the function name to set the return value. Use
+EXIT FUNCTION to return early.
Defines a single-expression function.
+ ++DEF FNname(params) = expression ++ +
+Def FnSquare(x) = x * x +Print FnSquare(5) ' prints 25 ++ + + +
Exits the current block early.
+ ++EXIT FOR +EXIT DO +EXIT SUB +EXIT FUNCTION ++ + + +
Explicitly calls a subroutine or function. The return value (if any) is +discarded.
+ ++CALL name +CALL name(args) ++ +
Normally you can omit CALL and just use the name directly.
+GOTO label +GOSUB label +RETURN ++ +
GOSUB pushes the return address, executes code at the label,
+and RETURN jumps back. At module level, RETURN
+returns from a GOSUB. Inside a SUB/FUNCTION, RETURN returns
+from the procedure.
+GoSub Initialize +Print "Done" +End + +Initialize: + count = 0 + name$ = "" +Return ++ + + +
Computed branch based on an integer expression.
+ ++ON expression GOTO label1, label2, ... +ON expression GOSUB label1, label2, ... ++ +
If the expression evaluates to 1, control goes to the first label; 2, the +second; and so on. If out of range, execution falls through.
+ + + +Outputs text to the console or to a file channel.
+ +
+PRINT [expression] [{; | ,} expression] ...
+PRINT #channel, expression
+PRINT USING format$; expression [; expression] ...
+
+
+; between items -- no separator (items are concatenated), between items -- advance to the next 14-column tab zone; or , suppresses the newline? is an alias for PRINTSpecial functions inside PRINT:
+ +SPC(n) -- print n spacesTAB(n) -- advance to column n+Print "Name:"; Tab(20); name$ +Print Using "###.##"; total +Print #1, "Written to file" ++ + + +
Reads a line of text from the user or from a file channel.
+ ++INPUT variable +INPUT "prompt"; variable +INPUT #channel, variable ++ +
+Input "Enter your name: "; name$ +Input #1, line$ ++ + + +
Inline data pool for constants.
+ ++DATA value1, value2, "string", ... +READ variable1, variable2, ... +RESTORE ++ +
DATA statements define a pool of values. READ
+reads the next value from the pool into a variable. RESTORE
+resets the read pointer to the beginning.
+Data 10, 20, 30, "Hello" +Read a, b, c, msg$ +Print a; b; c; msg$ +Restore ++ + + +
Assigns a value to a variable, array element, or UDT field.
+ ++variable = expression +array(index) = expression +udt.field = expression +LET variable = expression ++ +
The LET keyword is optional and supported for
+compatibility.
Exchanges the values of two variables.
+ ++SWAP variable1, variable2 ++ +
+Swap a, b ++ + + +
Frees the memory of an array and resets it.
+ ++ERASE arrayName ++ + + +
Sets compiler options. Must appear before any executable code.
+ ++OPTION BASE 0 ' Arrays start at index 0 (default) +OPTION BASE 1 ' Arrays start at index 1 +OPTION COMPARE BINARY ' Case-sensitive string comparisons (default) +OPTION COMPARE TEXT ' Case-insensitive string comparisons +OPTION EXPLICIT ' All variables must be declared with DIM ++ + + +
Set the default type for variables based on their first letter.
+ ++DEFINT letterRange +DEFLNG letterRange +DEFSNG letterRange +DEFDBL letterRange +DEFSTR letterRange ++ +
+DefInt I-N ' Variables starting with I through N default to Integer +DefStr S ' Variables starting with S default to String ++ + + +
Declares a local variable that retains its value between calls.
+ ++STATIC variable AS type ++ +
+Sub Counter() + Static count As Integer + count = count + 1 + Print count +End Sub ++ + + +
+ON ERROR GOTO label ' Enable error handler +ON ERROR GOTO 0 ' Disable error handler +RESUME ' Retry the statement that caused the error +RESUME NEXT ' Continue at the next statement after the error +ERROR n ' Raise a runtime error with error number n ++ +
The ERR keyword returns the current error number in
+expressions.
+On Error GoTo ErrorHandler +Open "missing.txt" For Input As #1 +Exit Sub + +ErrorHandler: + Print "Error number:"; Err + Resume Next ++ + + +
Executes an operating system command.
+ ++SHELL "command" ++ +
When used as a function, returns the exit code of the command.
+ +
+Shell "DIR /B"
+exitCode = Shell("COPY A.TXT B.TXT")
+
+
+
+
+Pauses execution for a specified number of seconds.
+ ++SLEEP seconds ++ + + +
Seeds the random number generator.
+ ++RANDOMIZE seed +RANDOMIZE TIMER ' Seed from system clock ++ + + +
Terminates program execution immediately.
+ ++END ++ + + +
Forward-declares a SUB or FUNCTION. Required when a procedure is called +before it is defined.
+ ++DECLARE SUB name ([BYVAL] param AS type, ...) +DECLARE FUNCTION name ([BYVAL] param AS type, ...) AS returnType ++ + + +
Declares external native functions from a dynamically loaded library. +This allows BASIC programs to call functions exported by DXE libraries.
+ ++DECLARE LIBRARY "libraryName" + DECLARE SUB name ([BYVAL] param AS type, ...) + DECLARE FUNCTION name ([BYVAL] param AS type, ...) AS returnType +END DECLARE ++ +
+Declare Library "rs232" + Declare Function ComOpen(ByVal port As Integer) As Integer + Declare Sub ComClose(ByVal port As Integer) + Declare Sub ComSend(ByVal port As Integer, ByVal data$ As String) +End Declare ++ + + +
Opens a file for reading, writing, or appending.
+ ++OPEN filename$ FOR INPUT AS #channel +OPEN filename$ FOR OUTPUT AS #channel +OPEN filename$ FOR APPEND AS #channel +OPEN filename$ FOR RANDOM AS #channel [LEN = recordSize] +OPEN filename$ FOR BINARY AS #channel ++ +
| Mode | Description |
|---|---|
INPUT | Open for sequential reading. File must exist. |
OUTPUT | Open for sequential writing. Creates or truncates. |
APPEND | Open for sequential writing at end of file. |
RANDOM | Open for random-access record I/O. |
BINARY | Open for raw binary I/O. |
+CLOSE #channel ++ + +
Writes text to a file.
+ ++PRINT #channel, expression ++ + +
Reads comma-delimited data from a file.
+ ++INPUT #channel, variable ++ + +
Reads an entire line from a file into a string variable.
+ ++LINE INPUT #channel, variable$ ++ + +
Writes comma-delimited data to a file. Strings are enclosed in quotes, +numbers are undecorated. Each statement writes a newline at the end.
+ ++WRITE #channel, expr1, expr2, ... ++ +
+Write #1, "Scott", 42, 3.14 +' Output: "Scott",42,3.14 ++ + +
Read and write records in RANDOM or BINARY mode files.
+ ++GET #channel, [recordNum], variable +PUT #channel, [recordNum], variable ++ + +
Sets the file position. As a function, returns the current position.
+ ++SEEK #channel, position ' Statement: set position +pos = SEEK(channel) ' Function: get current position ++ + + +
| Function | +Args | +Returns | +Description | +
|---|---|---|---|
ASC(s$) |
+ 1 | +Integer | +Returns the ASCII code of the first character of s$. | +
CHR$(n) |
+ 1 | +String | +Returns the character with ASCII code n. | +
FORMAT$(value, fmt$) |
+ 2 | +String | +Formats a numeric value using the format string fmt$. | +
HEX$(n) |
+ 1 | +String | +Returns the hexadecimal representation of n. | +
INSTR(s$, find$) |
+ 2-3 | +Integer | +Returns the position of find$ in s$ (1-based). Optionally
+ takes a starting position as the first argument:
+ INSTR(start, s$, find$). Returns 0 if
+ not found. |
+
LCASE$(s$) |
+ 1 | +String | +Converts s$ to lowercase. | +
LEFT$(s$, n) |
+ 2 | +String | +Returns the leftmost n characters of s$. | +
LEN(s$) |
+ 1 | +Integer | +Returns the length of s$. | +
LTRIM$(s$) |
+ 1 | +String | +Removes leading spaces from s$. | +
MID$(s$, start [, length]) |
+ 2-3 | +String | +Returns a substring starting at position start (1-based). If + length is omitted, returns from start to end. | +
RIGHT$(s$, n) |
+ 2 | +String | +Returns the rightmost n characters of s$. | +
RTRIM$(s$) |
+ 1 | +String | +Removes trailing spaces from s$. | +
SPACE$(n) |
+ 1 | +String | +Returns a string of n spaces. | +
STR$(n) |
+ 1 | +String | +Converts number n to its string representation. | +
STRING$(n, char) |
+ 2 | +String | +Returns a string of n copies of char (ASCII code or + single-character string). | +
TRIM$(s$) |
+ 1 | +String | +Removes leading and trailing spaces from s$. | +
UCASE$(s$) |
+ 1 | +String | +Converts s$ to uppercase. | +
VAL(s$) |
+ 1 | +Double | +Converts the string s$ to a numeric value. | +
MID$ can also be used on the left side of an assignment to
+replace a portion of a string:
+Mid$(s$, 3, 2) = "XY" ' Replace 2 characters starting at position 3 ++ + + +
| Function | +Args | +Returns | +Description | +
|---|---|---|---|
ABS(n) |
+ 1 | +Double | +Absolute value of n. | +
ATN(n) |
+ 1 | +Double | +Arctangent of n (in radians). | +
COS(n) |
+ 1 | +Double | +Cosine of n (radians). | +
EXP(n) |
+ 1 | +Double | +Returns e raised to the power n. | +
FIX(n) |
+ 1 | +Integer | +Truncates n toward zero (removes the fractional part). | +
INT(n) |
+ 1 | +Integer | +Returns the largest integer less than or equal to n (floor). | +
LOG(n) |
+ 1 | +Double | +Natural logarithm (base e) of n. | +
RND[(n)] |
+ 0-1 | +Double | +Returns a random number between 0 (inclusive) and 1 (exclusive). + With a negative argument, seeds and returns. With 0, returns the + previous value. | +
SGN(n) |
+ 1 | +Integer | +Returns the sign of n: -1, 0, or 1. | +
SIN(n) |
+ 1 | +Double | +Sine of n (radians). | +
SQR(n) |
+ 1 | +Double | +Square root of n. | +
TAN(n) |
+ 1 | +Double | +Tangent of n (radians). | +
TIMER |
+ 0 | +Double | +Returns the number of seconds since midnight. | +
| Function | +Args | +Returns | +Description | +
|---|---|---|---|
CDBL(n) |
+ 1 | +Double | +Converts n to Double. | +
CINT(n) |
+ 1 | +Integer | +Converts n to Integer (with banker's rounding). | +
CLNG(n) |
+ 1 | +Long | +Converts n to Long. | +
CSNG(n) |
+ 1 | +Single | +Converts n to Single. | +
CSTR(n) |
+ 1 | +String | +Converts n to its String representation. | +
| Function | +Args | +Returns | +Description | +
|---|---|---|---|
EOF(channel) |
+ 1 | +Boolean | +Returns True if the file pointer is at end of file. | +
FREEFILE |
+ 0 | +Integer | +Returns the next available file channel number. | +
INPUT$(n, #channel) |
+ 2 | +String | +Reads n characters from the file and returns them as a string. | +
LOC(channel) |
+ 1 | +Long | +Returns the current read/write position in the file. | +
LOF(channel) |
+ 1 | +Long | +Returns the length of the file in bytes. | +
SEEK(channel) |
+ 1 | +Long | +Returns the current file position (function form of SEEK). | +
LBOUND(array [, dim]) |
+ 1-2 | +Integer | +Returns the lower bound of an array dimension. | +
UBOUND(array [, dim]) |
+ 1-2 | +Integer | +Returns the upper bound of an array dimension. | +
| Function | +Args | +Returns | +Description | +
|---|---|---|---|
DATE$ |
+ 0 | +String | +Returns the current date as "MM-DD-YYYY". | +
TIME$ |
+ 0 | +String | +Returns the current time as "HH:MM:SS". | +
ENVIRON$(name$) |
+ 1 | +String | +Returns the value of the environment variable name$. | +
ERR |
+ 0 | +Integer | +Returns the current runtime error number (0 if no error). | +
DVX BASIC supports Visual Basic-style forms and controls for building
+graphical user interfaces. Forms are defined in .frm files and
+loaded at runtime.
+LOAD FormName +UNLOAD FormName ++ +
LOAD creates the form and its controls in memory.
+UNLOAD destroys the form and frees its resources.
+FormName.Show [modal] +FormName.Hide +Me.Show [modal] +Me.Hide ++ +
Pass vbModal (1) to Show for a modal dialog.
+Form2.Show vbModal +Me.Hide ++ +
Read and write control properties using dot notation:
+ ++ControlName.Property = value +value = ControlName.Property ++ +
+Text1.Text = "Hello" +label1.Caption = "Name: " & name$ +x = Text1.Left ++ +
+ControlName.Method [args] ++ +
+List1.AddItem "New entry" +List1.Clear ++ +
Me refers to the current form. Use it to access the form's
+own properties, controls, and methods from within event handlers.
+Me.Caption = "Updated Title" +Me.Text1.Text = "" +Me.Hide ++ +
Multiple controls can share a name with unique indices. Access individual +controls with parenthesized indices:
+ ++Option1(0).Value = True +Label1(idx).Caption = "Item " & Str$(idx) +Me.Label1(i).Visible = True ++ +
Yields control to the DVX event loop, allowing the GUI to process pending +events. Call this in long-running loops to keep the UI responsive.
+ ++DOEVENTS ++ +
+For i = 1 To 10000 + ' process data + If i Mod 100 = 0 Then DoEvents +Next ++ +
Displays a message box dialog. Can be used as a statement (discards +result) or as a function (returns the button clicked).
+ ++MSGBOX message$ [, flags] +result = MSGBOX(message$ [, flags]) ++ +
+MsgBox "Operation complete"
+answer = MsgBox("Continue?", vbYesNo + vbQuestion)
+If answer = vbYes Then
+ ' proceed
+End If
+
+
+Displays an input dialog and returns the user's text entry.
+ ++result$ = INPUTBOX$(prompt$ [, title$ [, default$]]) ++ +
+name$ = InputBox$("Enter your name:", "Name Entry", "")
+
+
+Event handlers are named ControlName_EventName
+and defined as SUBs:
+Sub Command1_Click() + MsgBox "Button clicked!" +End Sub + +Sub Form_Load() + Me.Caption = "My App" +End Sub + +Sub Text1_Change() + Label1.Caption = "You typed: " & Text1.Text +End Sub ++ +
Common events:
+ +| Event | Description |
|---|---|
Click | Control was clicked |
DblClick | Control was double-clicked |
Change | Control value/text changed |
KeyPress | Key was pressed (receives key code) |
KeyDown | Key went down (receives key code and shift state) |
KeyUp | Key was released |
MouseDown | Mouse button pressed |
MouseUp | Mouse button released |
MouseMove | Mouse moved over control |
GotFocus | Control received input focus |
LostFocus | Control lost input focus |
Form_Load | Form is being loaded |
Form_Unload | Form is being unloaded |
Form_Resize | Form was resized |
Timer | Timer interval elapsed |
DVX BASIC includes built-in SQLite database support through a set of SQL
+functions. All functions use database handles and result set handles
+(integers) returned by SQLOpen and SQLQuery.
Opens a SQLite database file and returns a database handle.
+ ++db = SQLOPEN(path$) ++ +
+db = SQLOpen(App.Data & "\mydata.db") ++ +
Closes an open database.
+ ++SQLCLOSE db ++ + +
Executes a SQL statement that does not return data (INSERT, UPDATE, +DELETE, CREATE TABLE, etc.). Can be used as a statement or as a function +returning a Boolean success flag.
+ ++SQLEXEC db, sql$ +ok = SQLEXEC(db, sql$) ++ +
+SQLExec db, "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"
+SQLExec db, "INSERT INTO users (name) VALUES ('Scott')"
+ok = SQLExec(db, "DELETE FROM users WHERE id = 5")
+
+
+Returns the number of rows affected by the last INSERT, UPDATE, or DELETE.
+ ++count = SQLAFFECTED(db) ++ + +
Executes a SELECT query and returns a result set handle.
+ ++rs = SQLQUERY(db, sql$) ++ +
+rs = SQLQuery(db, "SELECT id, name FROM users ORDER BY name") ++ +
Advances to the next row in the result set. Can be used as a statement or +as a function returning True if a row is available.
+ ++SQLNEXT rs +hasRow = SQLNEXT(rs) ++ +
Returns True if there are no more rows in the result set.
+ ++done = SQLEOF(rs) ++ + +
Returns a field value as a string. The field can be specified by column +index (0-based) or by column name.
+ ++value$ = SQLFIELD$(rs, columnIndex) +value$ = SQLFIELD$(rs, "columnName") ++ +
+name$ = SQLField$(rs, "name") +first$ = SQLField$(rs, 0) ++ +
Returns a field value as an integer.
+ ++value = SQLFIELDINT(rs, columnIndex) ++ +
Returns a field value as a double.
+ ++value# = SQLFIELDDBL(rs, columnIndex) ++ +
Returns the number of columns in the result set.
+ ++count = SQLFIELDCOUNT(rs) ++ + +
Frees a result set. Always call this when done iterating a query.
+ ++SQLFREERESULT rs ++ + +
Returns the last error message for the database.
+ ++msg$ = SQLERROR$(db) ++ + +
+Dim db As Long
+Dim rs As Long
+
+db = SQLOpen(App.Data & "\contacts.db")
+SQLExec db, "CREATE TABLE IF NOT EXISTS contacts (name TEXT, phone TEXT)"
+SQLExec db, "INSERT INTO contacts VALUES ('Alice', '555-1234')"
+
+rs = SQLQuery(db, "SELECT name, phone FROM contacts")
+Do While Not SQLEof(rs)
+ SQLNext rs
+ Print SQLField$(rs, "name"); Tab(20); SQLField$(rs, "phone")
+Loop
+SQLFreeResult rs
+SQLClose db
+
+
+
+
+The App object provides read-only properties for the
+application's directory paths.
| Property | +Returns | +Description | +
|---|---|---|
App.Path |
+ String | +The directory containing the application's executable. | +
App.Config |
+ String | +The directory for application configuration files. | +
App.Data |
+ String | +The directory for application data files (databases, etc.). | +
+configFile$ = App.Config & "\settings.ini" +dbPath$ = App.Data & "\myapp.db" +Print "Running from: " & App.Path ++ + + +
DVX BASIC provides built-in functions for reading and writing standard INI +configuration files.
+ +Reads a value from an INI file. Returns the default value if the key is +not found.
+ ++value$ = INIREAD(file$, section$, key$, default$) ++ +
+name$ = IniRead(App.Config & "\app.ini", "User", "Name", "Unknown") +fontSize = Val(IniRead(App.Config & "\app.ini", "Display", "FontSize", "12")) ++ +
Writes a value to an INI file. Creates the file, section, or key if they +do not exist.
+ ++INIWRITE file$, section$, key$, value$ ++ +
+IniWrite App.Config & "\app.ini", "User", "Name", "Scott" +IniWrite App.Config & "\app.ini", "Display", "FontSize", Str$(fontSize) ++ + + +
The following constants are predefined by the compiler and available in all +programs.
+ +| Constant | Value | Description |
|---|---|---|
vbOKOnly | 0 | OK button only (default) |
vbOKCancel | 1 | OK and Cancel buttons |
vbYesNo | 2 | Yes and No buttons |
vbYesNoCancel | 3 | Yes, No, and Cancel buttons |
vbRetryCancel | 4 | Retry and Cancel buttons |
Add an icon flag to the button style to display an icon in the message +box.
+ +| Constant | Value | Description |
|---|---|---|
vbInformation | &H10 | Information icon |
vbExclamation | &H20 | Warning icon |
vbCritical | &H30 | Error/critical icon |
vbQuestion | &H40 | Question mark icon |
| Constant | Value | Description |
|---|---|---|
vbOK | 1 | User clicked OK |
vbCancel | 2 | User clicked Cancel |
vbYes | 3 | User clicked Yes |
vbNo | 4 | User clicked No |
vbRetry | 5 | User clicked Retry |
| Constant | Value | Description |
|---|---|---|
vbModal | 1 | Show form as modal dialog |
| Constant | Value | Description |
|---|---|---|
True | -1 | Boolean true |
False | 0 | Boolean false |
DVX BASIC Language Reference -- Generated from compiler source code. +Covers the lexer, parser, and VM opcode set as implemented.
+ + +