Docs added.

This commit is contained in:
Scott Duensing 2026-04-06 22:25:06 -05:00
parent 7ec2aead8f
commit 0f5da09d1f
10 changed files with 10125 additions and 43 deletions

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);
// ============================================================

2933
docs/dvx_api_reference.html Normal file

File diff suppressed because it is too large Load diff

1045
docs/dvx_architecture.html Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,895 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DVX BASIC IDE Guide</title>
<style>
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
max-width: 900px;
margin: 0 auto;
padding: 20px 30px;
line-height: 1.6;
color: #222;
background: #fafafa;
}
h1 {
border-bottom: 3px solid #336;
padding-bottom: 8px;
color: #224;
}
h2 {
border-bottom: 1px solid #99a;
padding-bottom: 4px;
margin-top: 2em;
color: #336;
}
h3 {
color: #446;
margin-top: 1.5em;
}
code, kbd {
font-family: Consolas, "Courier New", monospace;
background: #e8e8ef;
padding: 1px 5px;
border-radius: 3px;
font-size: 0.95em;
}
kbd {
border: 1px solid #bbb;
box-shadow: 0 1px 0 #999;
background: #f4f4f4;
}
table {
border-collapse: collapse;
width: 100%;
margin: 12px 0;
}
th, td {
border: 1px solid #bbc;
padding: 6px 10px;
text-align: left;
}
th {
background: #dde;
color: #224;
}
tr:nth-child(even) {
background: #f0f0f6;
}
.toc {
background: #eef;
border: 1px solid #ccd;
padding: 12px 20px;
margin: 1em 0 2em 0;
border-radius: 4px;
}
.toc ul {
list-style: none;
padding-left: 0;
}
.toc li {
margin: 4px 0;
}
.toc a {
text-decoration: none;
color: #336;
}
.toc a:hover {
text-decoration: underline;
}
.note {
background: #ffd;
border-left: 4px solid #cc6;
padding: 8px 12px;
margin: 12px 0;
}
.sep {
border: none;
border-top: 1px solid #ccc;
margin: 2em 0;
}
</style>
</head>
<body>
<h1>DVX BASIC IDE Guide</h1>
<p>
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.
</p>
<p>
This guide covers every feature of the IDE: menus, toolbar, editor, form
designer, project management, debugger, and auxiliary windows.
</p>
<div class="toc">
<strong>Table of Contents</strong>
<ul>
<li>1. <a href="#overview">Overview</a></li>
<li>2. <a href="#menus">Menu Reference</a></li>
<li>3. <a href="#toolbar">Toolbar</a></li>
<li>4. <a href="#editor">Code Editor</a></li>
<li>5. <a href="#designer">Form Designer</a></li>
<li>6. <a href="#project">Project System</a></li>
<li>7. <a href="#properties">Properties Panel</a></li>
<li>8. <a href="#toolbox">Toolbox</a></li>
<li>9. <a href="#debugger">Debugger</a></li>
<li>10. <a href="#debugwindows">Debug Windows</a></li>
<li>11. <a href="#immediate">Immediate Window</a></li>
<li>12. <a href="#output">Output Window</a></li>
<li>13. <a href="#findreplace">Find / Replace</a></li>
<li>14. <a href="#preferences">Preferences</a></li>
</ul>
</div>
<!-- ============================================================ -->
<h2 id="overview">1. Overview</h2>
<p>
The DVX BASIC IDE is modeled after Visual Basic 3.0. It consists of several
floating windows arranged on the DVX desktop:
</p>
<ul>
<li><strong>Main Toolbar Window</strong> -- anchored at the top of the screen.
Contains the menu bar, toolbar buttons, and status bar.</li>
<li><strong>Code Editor</strong> -- the primary editing surface for BASIC source code,
with Object/Event dropdowns, syntax highlighting, and line numbers.</li>
<li><strong>Form Designer</strong> -- a visual design surface for .frm files,
showing a WYSIWYG preview of the form with grab handles for resizing controls.</li>
<li><strong>Project Explorer</strong> -- a tree view listing all files in the project.</li>
<li><strong>Toolbox</strong> -- a palette of available controls for placing on forms.</li>
<li><strong>Properties Panel</strong> -- a tree of controls and a list of editable properties
for the selected control.</li>
<li><strong>Output Window</strong> -- displays PRINT output and runtime errors.</li>
<li><strong>Immediate Window</strong> -- an interactive REPL for evaluating expressions
and modifying variables at runtime.</li>
<li><strong>Debug Windows</strong> -- Locals, Call Stack, Watch, and Breakpoints windows
that appear automatically when debugging.</li>
</ul>
<p>
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.
</p>
<!-- ============================================================ -->
<h2 id="menus">2. Menu Reference</h2>
<h3>File Menu</h3>
<table>
<tr><th>Menu Item</th><th>Shortcut</th><th>Description</th></tr>
<tr><td>New Project...</td><td></td><td>Create a new DVX BASIC project.</td></tr>
<tr><td>Open Project...</td><td></td><td>Open an existing .dbp project file.</td></tr>
<tr><td>Save Project</td><td></td><td>Save the current project file to disk.</td></tr>
<tr><td>Close Project</td><td></td><td>Close the current project (prompts to save unsaved changes).</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Project Properties...</td><td></td><td>Edit project metadata (name, author, version, startup form, icon, etc.).</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Add File...</td><td><kbd>Ctrl+O</kbd></td><td>Add a .bas or .frm file to the project. If no project is open, creates an implicit project from the file.</td></tr>
<tr><td>Save File</td><td><kbd>Ctrl+S</kbd></td><td>Save the active file to disk.</td></tr>
<tr><td>Save All</td><td></td><td>Save all modified files in the project.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Remove File</td><td></td><td>Remove the selected file from the project (prompts to save if modified).</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Exit</td><td></td><td>Close the IDE (prompts to save unsaved changes).</td></tr>
</table>
<h3>Edit Menu</h3>
<table>
<tr><th>Menu Item</th><th>Shortcut</th><th>Description</th></tr>
<tr><td>Cut</td><td><kbd>Ctrl+X</kbd></td><td>Cut selected text to the clipboard.</td></tr>
<tr><td>Copy</td><td><kbd>Ctrl+C</kbd></td><td>Copy selected text to the clipboard.</td></tr>
<tr><td>Paste</td><td><kbd>Ctrl+V</kbd></td><td>Paste text from the clipboard.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Select All</td><td><kbd>Ctrl+A</kbd></td><td>Select all text in the active editor.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Delete</td><td><kbd>Del</kbd></td><td>Delete the selected text or control (in the form designer).</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Find...</td><td><kbd>Ctrl+F</kbd></td><td>Open the Find/Replace dialog.</td></tr>
<tr><td>Find Next</td><td><kbd>F3</kbd></td><td>Find the next occurrence of the search text.</td></tr>
<tr><td>Replace...</td><td><kbd>Ctrl+H</kbd></td><td>Open the Find/Replace dialog with replace enabled.</td></tr>
</table>
<h3>Run Menu</h3>
<table>
<tr><th>Menu Item</th><th>Shortcut</th><th>Description</th></tr>
<tr><td>Run</td><td><kbd>F5</kbd></td><td>Compile and run the program. If paused at a breakpoint, resumes execution with debugging disabled (runs free).</td></tr>
<tr><td>Debug</td><td><kbd>Shift+F5</kbd></td><td>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.</td></tr>
<tr><td>Run Without Recompile</td><td><kbd>Ctrl+F5</kbd></td><td>Re-run the last compiled module without recompiling.</td></tr>
<tr><td>Stop</td><td><kbd>Esc</kbd></td><td>Stop the running program immediately.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Step Into</td><td><kbd>F8</kbd></td><td>Execute one statement, stepping into SUB/FUNCTION calls. If idle, starts a debug session and breaks at the first statement.</td></tr>
<tr><td>Step Over</td><td><kbd>Shift+F8</kbd></td><td>Execute one statement, stepping over SUB/FUNCTION calls.</td></tr>
<tr><td>Step Out</td><td><kbd>Ctrl+Shift+F8</kbd></td><td>Run until the current SUB/FUNCTION returns.</td></tr>
<tr><td>Run to Cursor</td><td><kbd>Ctrl+F8</kbd></td><td>Run until execution reaches the line where the cursor is positioned.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Toggle Breakpoint</td><td><kbd>F9</kbd></td><td>Toggle a breakpoint on the current editor line.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Clear Output</td><td></td><td>Clear the Output window.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Save on Run</td><td></td><td>Checkbox: when enabled, all modified files are saved automatically before compiling. Persisted in preferences.</td></tr>
</table>
<h3>View Menu</h3>
<table>
<tr><th>Menu Item</th><th>Shortcut</th><th>Description</th></tr>
<tr><td>Code</td><td><kbd>F7</kbd></td><td>Switch to Code view for the active file (or the file selected in the Project Explorer).</td></tr>
<tr><td>Designer</td><td><kbd>Shift+F7</kbd></td><td>Switch to Design view for the active form file.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Toolbar</td><td></td><td>Checkbox: show or hide the toolbar. Persisted in preferences.</td></tr>
<tr><td>Status Bar</td><td></td><td>Checkbox: show or hide the status bar. Persisted in preferences.</td></tr>
<tr><td colspan="3"><hr class="sep"></td></tr>
<tr><td>Menu Editor...</td><td><kbd>Ctrl+E</kbd></td><td>Open the Menu Editor dialog for the active form. Allows designing menu bars with captions, names, levels, checked state, and enabled state.</td></tr>
</table>
<h3>Window Menu</h3>
<table>
<tr><th>Menu Item</th><th>Description</th></tr>
<tr><td>Code Editor</td><td>Show or raise the Code Editor window.</td></tr>
<tr><td>Output</td><td>Show or raise the Output window.</td></tr>
<tr><td>Immediate</td><td>Show or raise the Immediate window.</td></tr>
<tr><td>Locals</td><td>Show or raise the Locals debug window.</td></tr>
<tr><td>Call Stack</td><td>Show or raise the Call Stack debug window.</td></tr>
<tr><td>Watch</td><td>Show or raise the Watch debug window.</td></tr>
<tr><td>Breakpoints</td><td>Show or raise the Breakpoints window.</td></tr>
<tr><td colspan="2"><hr class="sep"></td></tr>
<tr><td>Project Explorer</td><td>Show or raise the Project Explorer window.</td></tr>
<tr><td>Toolbox</td><td>Show or raise the Toolbox window.</td></tr>
<tr><td>Properties</td><td>Show or raise the Properties panel.</td></tr>
</table>
<h3>Tools Menu</h3>
<table>
<tr><th>Menu Item</th><th>Description</th></tr>
<tr><td>Preferences...</td><td>Open the Preferences dialog (editor settings and project defaults).</td></tr>
<tr><td colspan="2"><hr class="sep"></td></tr>
<tr><td>Debug Layout</td><td>Checkbox: toggle a debug overlay that shows widget layout boundaries. Useful for diagnosing widget layout issues.</td></tr>
</table>
<h3>Help Menu</h3>
<table>
<tr><th>Menu Item</th><th>Description</th></tr>
<tr><td>About DVX BASIC...</td><td>Show the About dialog with version and copyright information.</td></tr>
</table>
<!-- ============================================================ -->
<h2 id="toolbar">3. Toolbar</h2>
<p>
The toolbar is organized into four groups separated by vertical dividers.
Each button has a tooltip showing its name and keyboard shortcut.
</p>
<h3>File Group</h3>
<table>
<tr><th>Button</th><th>Shortcut</th><th>Action</th></tr>
<tr><td>Open</td><td><kbd>Ctrl+O</kbd></td><td>Add a file to the project (same as File &gt; Add File).</td></tr>
<tr><td>Save</td><td><kbd>Ctrl+S</kbd></td><td>Save the active file.</td></tr>
</table>
<h3>Run Group</h3>
<table>
<tr><th>Button</th><th>Shortcut</th><th>Action</th></tr>
<tr><td>Run</td><td><kbd>F5</kbd></td><td>Compile and run the program.</td></tr>
<tr><td>Stop</td><td><kbd>Esc</kbd></td><td>Stop the running program.</td></tr>
</table>
<h3>Debug Group</h3>
<table>
<tr><th>Button</th><th>Shortcut</th><th>Action</th></tr>
<tr><td>Debug</td><td><kbd>Shift+F5</kbd></td><td>Start or resume a debug session.</td></tr>
<tr><td>Step Into</td><td><kbd>F8</kbd></td><td>Step into the next statement.</td></tr>
<tr><td>Step Over</td><td><kbd>Shift+F8</kbd></td><td>Step over the next statement.</td></tr>
<tr><td>Step Out</td><td><kbd>Ctrl+Shift+F8</kbd></td><td>Step out of the current procedure.</td></tr>
<tr><td>Run to Cursor</td><td><kbd>Ctrl+F8</kbd></td><td>Run to the cursor position.</td></tr>
</table>
<h3>View Group</h3>
<table>
<tr><th>Button</th><th>Shortcut</th><th>Action</th></tr>
<tr><td>Code</td><td><kbd>F7</kbd></td><td>Switch to Code view.</td></tr>
<tr><td>Design</td><td><kbd>Shift+F7</kbd></td><td>Switch to Design view.</td></tr>
</table>
<!-- ============================================================ -->
<h2 id="editor">4. Code Editor</h2>
<p>
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.
</p>
<h3>Object and Function Dropdowns</h3>
<p>
At the top of the Code Editor are two dropdown lists:
</p>
<ul>
<li><strong>Object</strong> -- lists <code>(General)</code> plus all objects
(form name, control names, menu item names). Selecting an object filters
the Function dropdown.</li>
<li><strong>Function</strong> -- lists all event handlers (procedures) for
the selected object. Implemented handlers are listed first (plain text);
unimplemented handlers follow in brackets (e.g., <code>[Click]</code>).
Selecting an unimplemented event creates a new event handler stub.</li>
</ul>
<p>
The editor shows one procedure at a time. Each procedure has its own buffer,
and switching between them is instantaneous. The <code>(General)</code> section
contains module-level declarations and code.
</p>
<h3>Syntax Highlighting</h3>
<p>
The editor applies real-time syntax coloring as you type. The following
categories are highlighted in distinct colors:
</p>
<table>
<tr><th>Category</th><th>Examples</th></tr>
<tr><td>Keywords</td><td><code>IF</code>, <code>THEN</code>, <code>FOR</code>, <code>NEXT</code>, <code>SUB</code>, <code>FUNCTION</code>, <code>DIM</code>, <code>PRINT</code>, <code>SELECT</code>, <code>CASE</code>, <code>DO</code>, <code>LOOP</code>, <code>WHILE</code>, <code>WEND</code>, <code>END</code>, <code>EXIT</code>, <code>CALL</code>, <code>GOSUB</code>, <code>GOTO</code>, <code>RETURN</code>, <code>DECLARE</code>, <code>CONST</code>, <code>TYPE</code>, <code>AND</code>, <code>OR</code>, <code>NOT</code>, <code>XOR</code>, <code>MOD</code>, etc.</td></tr>
<tr><td>Type names</td><td><code>INTEGER</code>, <code>LONG</code>, <code>SINGLE</code>, <code>DOUBLE</code>, <code>STRING</code>, <code>BOOLEAN</code>, <code>BYTE</code>, <code>TRUE</code>, <code>FALSE</code></td></tr>
<tr><td>String literals</td><td><code>"Hello, World!"</code></td></tr>
<tr><td>Comments</td><td><code>' This is a comment</code>, <code>REM This is a comment</code></td></tr>
<tr><td>Numbers</td><td><code>42</code>, <code>3.14</code></td></tr>
<tr><td>Operators</td><td><code>=</code>, <code>&lt;</code>, <code>&gt;</code>, <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, <code>\</code>, <code>&amp;</code></td></tr>
</table>
<h3>Editor Features</h3>
<ul>
<li><strong>Line numbers</strong> -- displayed in the gutter on the left side.</li>
<li><strong>Auto-indent</strong> -- new lines are automatically indented to match
the previous line.</li>
<li><strong>Tab handling</strong> -- the Tab key is captured by the editor.
Tab width and whether to insert spaces or tab characters are configurable
in Preferences (default: 3 spaces).</li>
<li><strong>Gutter click</strong> -- clicking in the line number gutter toggles
a breakpoint on that line.</li>
<li><strong>Line decorations</strong> -- breakpoint lines show a red dot in the
gutter. The current debug line (when paused) is highlighted with a yellow
background.</li>
</ul>
<!-- ============================================================ -->
<h2 id="designer">5. Form Designer</h2>
<p>
The Form Designer provides a visual design surface for editing .frm files.
Switch to it with <kbd>Shift+F7</kbd> or the Design toolbar button. It opens
in a separate window showing a WYSIWYG preview of the form.
</p>
<h3>Design Surface</h3>
<ul>
<li><strong>Grid snapping</strong> -- controls snap to an 8-pixel grid
(<code>DSGN_GRID_SIZE</code>) when placed or resized.</li>
<li><strong>Selection</strong> -- click a control to select it. The selected
control is highlighted with grab handles.</li>
<li><strong>Grab handles</strong> -- 6x6 pixel handles appear on the right edge (E),
bottom edge (S), and bottom-right corner (SE) of the selected control.
Drag a handle to resize the control.</li>
<li><strong>Reordering</strong> -- drag a control vertically to reorder it
within the form's layout (VBox/HBox).</li>
<li><strong>Placing controls</strong> -- select a control type in the Toolbox,
then click on the form to place a new instance. The control is auto-named
(e.g., <code>Command1</code>, <code>Command2</code>). Clicking the same
tool again deselects it (toggles back to pointer mode).</li>
<li><strong>Menu bar preview</strong> -- if the form has menu items (defined via the
Menu Editor), a preview menu bar is rendered on the design window.</li>
<li><strong>Delete key</strong> -- removes the selected control from the form.</li>
</ul>
<h3>Form Properties</h3>
<p>
Forms have the following design-time properties: Name, Caption, Width, Height,
Left, Top, Layout (VBox or HBox), Centered, AutoSize, and Resizable.
</p>
<!-- ============================================================ -->
<h2 id="project">6. Project System</h2>
<h3>Project Files (.dbp)</h3>
<p>
A DVX BASIC project is stored as a <code>.dbp</code> file (DVX BASIC Project).
The project file records:
</p>
<ul>
<li><strong>Name</strong> -- the project display name (up to 32 characters).</li>
<li><strong>Startup Form</strong> -- which form to show automatically when the
program starts.</li>
<li><strong>Metadata</strong> -- Author, Company, Version, Copyright, Description,
and Icon Path (for compiled binaries).</li>
<li><strong>File list</strong> -- relative paths (8.3 DOS names) of all .bas and .frm
files in the project. Each entry tracks whether it is a form file.</li>
</ul>
<h3>Source Map</h3>
<p>
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 <code>BEGINFORM</code> directive is prepended to the code section.
</p>
<h3>Project Operations</h3>
<table>
<tr><th>Operation</th><th>Description</th></tr>
<tr><td>New Project</td><td>Creates a blank project with a name and directory. A default .frm file is added automatically.</td></tr>
<tr><td>Open Project</td><td>Opens a .dbp file and loads all referenced files into memory.</td></tr>
<tr><td>Save Project</td><td>Writes the .dbp file to disk.</td></tr>
<tr><td>Close Project</td><td>Closes the project, prompting to save unsaved changes.</td></tr>
<tr><td>Add File</td><td>Adds a .bas or .frm file to the project. Opening a file without a project auto-creates an implicit project.</td></tr>
<tr><td>Remove File</td><td>Removes a file from the project (prompts to save if modified).</td></tr>
<tr><td>Project Properties</td><td>Opens a dialog for editing project metadata (name, author, company, version, copyright, description, icon, startup form).</td></tr>
</table>
<h3>Project Explorer</h3>
<p>
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 &gt; Code
and View &gt; Designer commands.
</p>
<!-- ============================================================ -->
<h2 id="properties">7. Properties Panel</h2>
<p>
The Properties panel (<strong>Window &gt; Properties</strong>) has two sections:
</p>
<ul>
<li><strong>Control tree</strong> -- a TreeView at the top listing the form and all
its controls in layout order. Click a control name to select it in both the
Properties panel and the Form Designer. Drag items in the tree to reorder
controls in the form's layout.</li>
<li><strong>Property list</strong> -- a two-column ListView below the tree showing
property names and values for the selected control. Double-click a property
value to edit it via an InputBox dialog. Changes take effect immediately in
the designer preview.</li>
</ul>
<p>
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).
</p>
<!-- ============================================================ -->
<h2 id="toolbox">8. Toolbox</h2>
<p>
The Toolbox (<strong>Window &gt; Toolbox</strong>) 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
<code>basName</code> appears in the toolbox.
</p>
<p>
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.
</p>
<h3>Available Controls</h3>
<table>
<tr><th>VB Name</th><th>Description</th></tr>
<tr><td>CommandButton</td><td>Push button that triggers a Click event.</td></tr>
<tr><td>Label</td><td>Static text label.</td></tr>
<tr><td>TextBox</td><td>Single-line text input field.</td></tr>
<tr><td>TextArea</td><td>Multi-line text editor.</td></tr>
<tr><td>CheckBox</td><td>On/off checkbox.</td></tr>
<tr><td>OptionButton</td><td>Radio button (mutually exclusive within a group).</td></tr>
<tr><td>ListBox</td><td>Scrollable list of items.</td></tr>
<tr><td>ComboBox</td><td>Drop-down combo box.</td></tr>
<tr><td>DropDown</td><td>Simple drop-down list.</td></tr>
<tr><td>PictureBox</td><td>Canvas for drawing and images.</td></tr>
<tr><td>Image</td><td>Static image display.</td></tr>
<tr><td>ImageButton</td><td>Clickable image button.</td></tr>
<tr><td>Frame</td><td>Grouping container with a labeled border.</td></tr>
<tr><td>VBox</td><td>Vertical layout container.</td></tr>
<tr><td>HBox</td><td>Horizontal layout container.</td></tr>
<tr><td>WrapBox</td><td>Flow layout container that wraps items to the next row.</td></tr>
<tr><td>Splitter</td><td>Resizable split between two child panes.</td></tr>
<tr><td>ScrollPane</td><td>Scrollable container for large content.</td></tr>
<tr><td>TabStrip</td><td>Tabbed container with multiple pages.</td></tr>
<tr><td>ListView</td><td>Multi-column list with headers.</td></tr>
<tr><td>TreeView</td><td>Hierarchical tree control.</td></tr>
<tr><td>ProgressBar</td><td>Progress indicator bar.</td></tr>
<tr><td>HScrollBar</td><td>Horizontal slider/scrollbar.</td></tr>
<tr><td>SpinButton</td><td>Numeric up/down spinner.</td></tr>
<tr><td>Line</td><td>Horizontal or vertical separator line.</td></tr>
<tr><td>Spacer</td><td>Invisible spacing element for layout.</td></tr>
<tr><td>Timer</td><td>Non-visual timer that fires periodic events.</td></tr>
<tr><td>Toolbar</td><td>Toolbar container for buttons.</td></tr>
<tr><td>StatusBar</td><td>Status bar at the bottom of a form.</td></tr>
<tr><td>Terminal</td><td>ANSI terminal emulator control.</td></tr>
<tr><td>Data</td><td>Data control for binding to a database.</td></tr>
<tr><td>DBGrid</td><td>Data-bound grid for displaying database query results.</td></tr>
</table>
<!-- ============================================================ -->
<h2 id="debugger">9. Debugger</h2>
<p>
The DVX BASIC IDE includes a full interactive debugger. The debugger operates
as a state machine with three states:
</p>
<table>
<tr><th>State</th><th>Description</th></tr>
<tr><td><code>DBG_IDLE</code></td><td>No program loaded or running.</td></tr>
<tr><td><code>DBG_RUNNING</code></td><td>Program is executing (VM running in slices).</td></tr>
<tr><td><code>DBG_PAUSED</code></td><td>Execution is paused at a breakpoint or step point. The IDE GUI is fully interactive.</td></tr>
</table>
<h3>Starting a Debug Session</h3>
<ul>
<li><kbd>Shift+F5</kbd> (<strong>Debug</strong>) -- compiles the project and starts
execution in debug mode. Breakpoints are active but execution does not pause
at the first statement.</li>
<li><kbd>F8</kbd> (<strong>Step Into</strong>) -- if idle, starts a debug session
and breaks at the first statement.</li>
<li><kbd>F5</kbd> (<strong>Run</strong>) -- compiles and runs without the debugger.
No breakpoints are active. If already paused, resumes execution with debugging
disabled.</li>
</ul>
<h3>Breakpoints</h3>
<h4>Setting Breakpoints</h4>
<ul>
<li>Press <kbd>F9</kbd> to toggle a breakpoint on the current editor line.</li>
<li>Click in the line number gutter to toggle a breakpoint on that line.</li>
</ul>
<h4>Breakpoint Validation</h4>
<p>
Not every line can have a breakpoint. The IDE validates the line content and
silently refuses to set breakpoints on:
</p>
<ul>
<li>Blank lines</li>
<li>Comment lines (<code>'</code> or <code>REM</code>)</li>
<li><code>SUB</code> and <code>FUNCTION</code> declaration lines</li>
<li><code>END SUB</code> and <code>END FUNCTION</code> lines</li>
</ul>
<h4>Breakpoint Storage</h4>
<p>
Each breakpoint records the project file index, the code line number within the
file, the procedure index, and the procedure name (as <code>Object.Event</code>).
When the project is compiled, breakpoints are converted to concatenated source
line numbers that match the VM's <code>OP_LINE</code> opcodes.
</p>
<h4>Visual Indicators</h4>
<ul>
<li>Breakpoint lines show a <strong>red dot</strong> in the gutter.</li>
<li>The current debug line (when paused) has a <strong>yellow background</strong>.</li>
</ul>
<h4>Breakpoint Adjustment on Edit</h4>
<p>
When lines are added or removed in the editor, breakpoints below the edit
point are automatically shifted to stay on the correct line.
</p>
<h3>Stepping</h3>
<table>
<tr><th>Action</th><th>Shortcut</th><th>Behavior</th></tr>
<tr><td>Step Into</td><td><kbd>F8</kbd></td><td>Execute one statement. If the statement is a SUB/FUNCTION call, step into it.</td></tr>
<tr><td>Step Over</td><td><kbd>Shift+F8</kbd></td><td>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.</td></tr>
<tr><td>Step Out</td><td><kbd>Ctrl+Shift+F8</kbd></td><td>Run until the current SUB/FUNCTION returns to its caller.</td></tr>
<tr><td>Run to Cursor</td><td><kbd>Ctrl+F8</kbd></td><td>Run until execution reaches the line under the cursor.</td></tr>
</table>
<h3>The Debug Run Loop</h3>
<p>
When a program is running in debug mode, the IDE enters a cooperative loop:
</p>
<ol>
<li>The VM executes up to 10,000 steps per slice.</li>
<li>If the VM hits a breakpoint (<code>BAS_VM_BREAKPOINT</code>), the state
transitions to <code>DBG_PAUSED</code>. 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.</li>
<li>While paused, the IDE pumps <code>dvxUpdate()</code> continuously,
keeping the GUI responsive. The user can inspect variables, modify them
in the Immediate window, step, continue, or stop.</li>
<li>When the user resumes (F5/Shift+F5/F8/etc.), the state transitions back
to <code>DBG_RUNNING</code> and the loop continues.</li>
</ol>
<h3>Stopping</h3>
<p>
Press <kbd>Esc</kbd> or click the Stop toolbar button at any time to halt execution.
The VM is destroyed, debug state resets to <code>DBG_IDLE</code>, and the IDE
restores the designer windows that were hidden at run start.
</p>
<!-- ============================================================ -->
<h2 id="debugwindows">10. Debug Windows</h2>
<p>
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.
</p>
<h3>Locals Window</h3>
<p>
Shows variables for the current execution scope. Displayed as a three-column
ListView:
</p>
<table>
<tr><th>Column</th><th>Content</th></tr>
<tr><td>Name</td><td>Variable name (internal mangled names like static variable placeholders are filtered out).</td></tr>
<tr><td>Type</td><td>Data type: Integer, Long, Single, Double, String, Boolean, Array, UDT. Array types show the element type (e.g., <code>Integer()</code>).</td></tr>
<tr><td>Value</td><td>Current value. Strings are shown in quotes. Booleans as True/False. Arrays show bounds and element count (e.g., <code>Integer(0 To 9) [10]</code>). Uninitialized arrays show <code>(uninitialized)</code>.</td></tr>
</table>
<p>
The Locals window displays:
</p>
<ul>
<li>Local variables for the current procedure (matched by proc index).</li>
<li>Global (module-level) variables.</li>
<li>Form-scoped variables for the current form (if the program is executing
within a form context).</li>
</ul>
<p>
Up to 64 variables are displayed. The window is resizable.
</p>
<h3>Call Stack Window</h3>
<p>
Shows the current call chain as a two-column ListView:
</p>
<table>
<tr><th>Column</th><th>Content</th></tr>
<tr><td>Procedure</td><td>Procedure name (or <code>(module)</code> for module-level code).</td></tr>
<tr><td>Line</td><td>Line number where execution is paused (shown for the topmost frame).</td></tr>
</table>
<p>
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.
</p>
<h3>Watch Window</h3>
<p>
Allows monitoring arbitrary expressions while debugging. The window has
a text input at the top and a two-column ListView below:
</p>
<table>
<tr><th>Column</th><th>Content</th></tr>
<tr><td>Expression</td><td>The watch expression text.</td></tr>
<tr><td>Value</td><td>Evaluated result (or <code>&lt;error&gt;</code> if evaluation fails). Blank when not paused.</td></tr>
</table>
<h4>Adding Watch Expressions</h4>
<p>
Type an expression in the text input and press <kbd>Enter</kbd>.
Up to 16 watch expressions can be active at once.
</p>
<h4>Watch Expression Syntax</h4>
<p>
Watch expressions support:
</p>
<ul>
<li>Simple variable names: <code>x</code>, <code>count</code></li>
<li>Array subscripts: <code>arr(5)</code>, <code>matrix(2, 3)</code></li>
<li>UDT field access: <code>player.name</code></li>
<li>Combined: <code>items(i).price</code></li>
<li>Arbitrary BASIC expressions (compiled and evaluated against the
paused VM's state): <code>x + y * 2</code>, <code>Len(name$)</code></li>
</ul>
<h4>Editing and Deleting</h4>
<ul>
<li><strong>Double-click</strong> or press <kbd>Enter</kbd> on a watch entry to
move it back into the input box for editing.</li>
<li>Press <kbd>Delete</kbd> to remove the selected watch expression.</li>
</ul>
<h3>Breakpoints Window</h3>
<p>
Lists all set breakpoints as a three-column ListView:
</p>
<table>
<tr><th>Column</th><th>Content</th></tr>
<tr><td>File</td><td>Project file path.</td></tr>
<tr><td>Procedure</td><td>Procedure name (<code>Object.Event</code> format, or <code>(General)</code>).</td></tr>
<tr><td>Line</td><td>Code line number within the file.</td></tr>
</table>
<ul>
<li><strong>Double-click</strong> a breakpoint to navigate the code editor to that location.</li>
<li>Press <kbd>Delete</kbd> to remove selected breakpoints (multi-select is supported).</li>
</ul>
<!-- ============================================================ -->
<h2 id="immediate">11. Immediate Window</h2>
<p>
The Immediate window is an interactive REPL at the bottom-right of the screen.
Type a line of BASIC and press <kbd>Enter</kbd> to evaluate it. Results appear
inline below your input.
</p>
<h3>Expression Evaluation</h3>
<p>
If the input is not a recognized statement keyword, it is automatically wrapped
in a <code>PRINT</code> statement. For example, typing <code>2 + 2</code>
evaluates as <code>PRINT 2 + 2</code> and displays <code>4</code>.
</p>
<p>
You can also type full statements:
</p>
<ul>
<li><code>PRINT x * 2</code> -- evaluate and print an expression.</li>
<li><code>DIM tmp As Integer</code> -- declare a temporary variable.</li>
<li><code>LET x = 42</code> -- explicit assignment (see below).</li>
</ul>
<p>
Parse or runtime errors are displayed inline with an <code>Error:</code> prefix.
</p>
<h3>Inspecting Variables While Paused</h3>
<p>
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 <code>count</code> or <code>name$ &amp; " test"</code>
display live values.
</p>
<h3>Assigning Variables While Paused</h3>
<p>
When paused, you can modify variables in the running program directly from the
Immediate window using assignment syntax:
</p>
<pre><code>variableName = newValue</code></pre>
<p>
The optional <code>LET</code> keyword is also accepted:
</p>
<pre><code>LET variableName = newValue</code></pre>
<p>
Assignment works for:
</p>
<ul>
<li><strong>Scalar variables</strong> -- <code>x = 42</code>, <code>name$ = "test"</code></li>
<li><strong>Array elements</strong> -- <code>arr(5) = 100</code>, <code>matrix(2, 3) = 7.5</code></li>
<li><strong>UDT fields</strong> -- <code>player.score = 1000</code></li>
<li><strong>Combined</strong> -- <code>items(0).price = 9.99</code></li>
</ul>
<p>
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.
</p>
<p>
If the assignment target cannot be resolved (unknown variable, out-of-bounds
index, wrong type), an error message is displayed.
</p>
<!-- ============================================================ -->
<h2 id="output">12. Output Window</h2>
<p>
The Output window is a read-only TextArea at the bottom-left of the screen.
It displays:
</p>
<ul>
<li><strong>PRINT output</strong> -- all <code>PRINT</code> statement output from
the running program is appended here.</li>
<li><strong>Runtime errors</strong> -- if the VM encounters a runtime error
(division by zero, out-of-bounds, etc.), the error message and line number
are displayed in the output with an <code>Error on line N:</code> prefix.</li>
<li><strong>Compile errors</strong> -- if compilation fails, the error message
and location are shown.</li>
</ul>
<p>
The output buffer holds up to 32,768 characters. Use <strong>Run &gt; Clear Output</strong>
to clear it.
</p>
<p>
<code>INPUT</code> statements prompt the user via a modal InputBox dialog; the
prompt text is also echoed to the Output window.
</p>
<!-- ============================================================ -->
<h2 id="findreplace">13. Find / Replace</h2>
<p>
Open with <kbd>Ctrl+F</kbd> (Find) or <kbd>Ctrl+H</kbd> (Replace). The
Find/Replace dialog is modeless -- it stays open while you continue editing.
</p>
<h3>Dialog Controls</h3>
<table>
<tr><th>Control</th><th>Description</th></tr>
<tr><td>Find input</td><td>The text to search for.</td></tr>
<tr><td>Replace checkbox + input</td><td>Enable replacement mode and enter replacement text.</td></tr>
<tr><td>Scope</td><td>Radio group: Function, Object, File, or Project. Default is Project.</td></tr>
<tr><td>Direction</td><td>Radio group: Forward or Backward.</td></tr>
<tr><td>Match Case</td><td>Checkbox: case-sensitive search.</td></tr>
</table>
<h3>Buttons</h3>
<table>
<tr><th>Button</th><th>Action</th></tr>
<tr><td>Find Next</td><td>Find the next occurrence. Wraps across procedures, files, and the entire project depending on the scope setting.</td></tr>
<tr><td>Replace</td><td>Replace the current match and find the next one.</td></tr>
<tr><td>Replace All</td><td>Replace all occurrences within the selected scope.</td></tr>
<tr><td>Close</td><td>Close the dialog.</td></tr>
</table>
<h3>Keyboard Shortcut</h3>
<p>
<kbd>F3</kbd> repeats the last search (Find Next) without opening the dialog.
</p>
<!-- ============================================================ -->
<h2 id="preferences">14. Preferences</h2>
<p>
Open via <strong>Tools &gt; Preferences</strong>. Settings are saved to
<code>dvxbasic.ini</code> in the app's config directory.
</p>
<h3>Editor Section</h3>
<table>
<tr><th>Setting</th><th>Description</th><th>Default</th></tr>
<tr><td>Skip comments/strings when renaming</td><td>When renaming a control or form, skip occurrences inside comments and string literals.</td><td>On</td></tr>
<tr><td>Require variable declaration (OPTION EXPLICIT)</td><td>When enabled, variables must be declared with DIM before use.</td><td>Off</td></tr>
<tr><td>Tab width</td><td>Number of spaces per tab stop (1-8).</td><td>3</td></tr>
<tr><td>Insert spaces instead of tabs</td><td>When enabled, pressing Tab inserts spaces. When disabled, inserts a real tab character.</td><td>On</td></tr>
</table>
<h3>New Project Defaults Section</h3>
<p>
These fields set the default values for new project metadata:
</p>
<table>
<tr><th>Field</th><th>Description</th><th>Default</th></tr>
<tr><td>Author</td><td>Default author name.</td><td>(empty)</td></tr>
<tr><td>Company</td><td>Default company name.</td><td>(empty)</td></tr>
<tr><td>Version</td><td>Default version string.</td><td>1.0</td></tr>
<tr><td>Copyright</td><td>Default copyright notice.</td><td>(empty)</td></tr>
<tr><td>Description</td><td>Default project description (multi-line).</td><td>(empty)</td></tr>
</table>
<hr class="sep">
<h2>Keyboard Shortcut Summary</h2>
<table>
<tr><th>Shortcut</th><th>Action</th></tr>
<tr><td><kbd>Ctrl+O</kbd></td><td>Add File</td></tr>
<tr><td><kbd>Ctrl+S</kbd></td><td>Save File</td></tr>
<tr><td><kbd>Ctrl+A</kbd></td><td>Select All</td></tr>
<tr><td><kbd>Ctrl+X</kbd></td><td>Cut</td></tr>
<tr><td><kbd>Ctrl+C</kbd></td><td>Copy</td></tr>
<tr><td><kbd>Ctrl+V</kbd></td><td>Paste</td></tr>
<tr><td><kbd>Ctrl+F</kbd></td><td>Find</td></tr>
<tr><td><kbd>Ctrl+H</kbd></td><td>Replace</td></tr>
<tr><td><kbd>Ctrl+E</kbd></td><td>Menu Editor</td></tr>
<tr><td><kbd>F3</kbd></td><td>Find Next</td></tr>
<tr><td><kbd>F5</kbd></td><td>Run</td></tr>
<tr><td><kbd>Shift+F5</kbd></td><td>Debug</td></tr>
<tr><td><kbd>Ctrl+F5</kbd></td><td>Run Without Recompile</td></tr>
<tr><td><kbd>Esc</kbd></td><td>Stop</td></tr>
<tr><td><kbd>F7</kbd></td><td>Code View</td></tr>
<tr><td><kbd>Shift+F7</kbd></td><td>Design View</td></tr>
<tr><td><kbd>F8</kbd></td><td>Step Into</td></tr>
<tr><td><kbd>Shift+F8</kbd></td><td>Step Over</td></tr>
<tr><td><kbd>Ctrl+Shift+F8</kbd></td><td>Step Out</td></tr>
<tr><td><kbd>Ctrl+F8</kbd></td><td>Run to Cursor</td></tr>
<tr><td><kbd>F9</kbd></td><td>Toggle Breakpoint</td></tr>
<tr><td><kbd>Del</kbd></td><td>Delete</td></tr>
</table>
<hr class="sep">
<p><em>DVX BASIC 1.0 -- Copyright 2026 Scott Duensing</em></p>
</body>
</html>

File diff suppressed because it is too large Load diff