From 35c23b08d74493c359d20d580b7401878530e4d0 Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Mon, 11 May 2026 14:29:26 +0200 Subject: [PATCH 1/2] Document Printer and Printers. --- docs/Reference/VB/Printer/index.md | 518 ++++++++++++++++++++++++++++ docs/Reference/VB/Printers/index.md | 69 ++++ docs/Reference/VB/todo.md | 1 - 3 files changed, 587 insertions(+), 1 deletion(-) create mode 100644 docs/Reference/VB/Printer/index.md create mode 100644 docs/Reference/VB/Printers/index.md diff --git a/docs/Reference/VB/Printer/index.md b/docs/Reference/VB/Printer/index.md new file mode 100644 index 0000000..04d5744 --- /dev/null +++ b/docs/Reference/VB/Printer/index.md @@ -0,0 +1,518 @@ +--- +title: Printer +parent: VB Package +permalink: /tB/Packages/VB/Printer/ +has_toc: false +--- + +# Printer class +{: .no_toc } + +A **Printer** object encapsulates one Windows printer device, exposing a drawing surface that records the application's graphics calls and forwards them to the spooler as a print job. The implicit **Printer** is mutable and tracks the system default printer; the entries of the [**Printers**](../Printers/) collection are read-only descriptors of the installed devices, useful for enumeration or for switching the active printer with `Set Printer = Printers("HP LaserJet")`. + +A print job begins implicitly the first time the application calls a drawing or text method on the **Printer** ([**Print**](#print), [**Line**](#line), [**Circle**](#circle), [**PSet**](#pset), [**PaintPicture**](#paintpicture), …), and is finalised by [**EndDoc**](#enddoc). [**NewPage**](#newpage) advances to a fresh page within the same job; [**KillDoc**](#killdoc) aborts the job without finishing the current page. + +```tb +Printer.FontSize = 12 +Printer.Print "Hello, world!" +Printer.NewPage +Printer.Print "Second page." +Printer.EndDoc +``` + +User code never instantiates a **Printer** directly — the class is marked `[COMCreatable(False)]` and its public API has no useful constructor. The two access paths are the implicit **Printer** global and the [**Printers**](../Printers/) collection. + +* TOC +{:toc} + +## The default Printer and the Printers collection + +twinBASIC exposes a single implicit **Printer** object, accessible by name from anywhere in user code, plus a [**Printers**](../Printers/) collection enumerating every printer installed on the system: + +```tb +Dim p As Printer +For Each p In Printers + Debug.Print p.DeviceName, p.DriverName, p.Port +Next +``` + +By default the implicit **Printer** has [**TrackDefault**](#trackdefault) **True**: every property read consults the current system-default printer, so the application picks up changes the user makes in **Settings → Printers** without restarting. Writing to a settings property, calling **Set Printer = Printers(i)**, or starting a print job locks **TrackDefault** to **False** and pins the object to a specific device. + +The entries returned by [**Printers**](../Printers/) are immutable — assigning to one of their properties raises run-time error 383 (*Property is read-only*), and the document-control methods raise error 438 (*Object doesn't support this property or method*). To print to one of them, copy it onto the implicit **Printer** with **Set**: + +```tb +Set Printer = Printers("HP LaserJet") +Printer.Orientation = vbPRORLandscape +Printer.Print "Hello on landscape paper." +Printer.EndDoc +``` + +`Set Printer = …` does not replace the implicit instance — it forwards the new device's identity onto the existing object, ending any active print job and discarding the cached device context in the process. + +## Print-job lifecycle + +The methods that manage the job — [**EndDoc**](#enddoc), [**KillDoc**](#killdoc), [**NewPage**](#newpage) — and the implicit "start-on-first-output" rule together form a small state machine: + +| State | How it advances | +|--------------------|----------------------------------------------------------------------------------------------------------| +| No job in progress | The next drawing or text method starts a new job and a fresh page. | +| Page in progress | [**NewPage**](#newpage) emits the page and starts another; [**EndDoc**](#enddoc) emits it and finishes. | +| Anywhere | [**KillDoc**](#killdoc) aborts the job without emitting whatever is on the current page. | + +[**Page**](#page) reports the current page number (starting at 1). Property setters that affect page geometry — [**PaperSize**](#papersize), [**Orientation**](#orientation), [**Copies**](#copies), [**Width**](#width), [**Height**](#height), [**Duplex**](#duplex), [**PaperBin**](#paperbin), [**ColorMode**](#colormode), [**PrintQuality**](#printquality), [**Zoom**](#zoom) — must be assigned on a blank page; doing so mid-page raises error 396 (*'PropertyName' cannot be set within a page*). + +## Coordinate system + +A **Printer** has its own coordinate system, configured through [**ScaleMode**](#scalemode), the [**Scale\***](#scaleleft) properties, and [**Scale**](#scale). The default mode is **vbTwips**, with the surface spanning the physical paper area. Drawing primitives consume coordinates in the current units; [**ScaleX**](#scalex) and [**ScaleY**](#scaley) convert distances between any two scale modes without changing the active one. + +```tb +Printer.ScaleMode = vbInches +Printer.Line (0.5, 0.5)-(8, 10.5), vbBlack, B ' 1/2-inch margin rectangle +``` + +## Printing to a file + +Assigning a path to [**OutputFile**](#outputfile) **before** the job starts redirects the raw spool output to that file instead of the printer device. The file holds the printer-driver-specific bytes that would otherwise be sent over the port — typically a `.prn` file that can later be copied to a port with the **COPY /B** command. + +```tb +Printer.OutputFile = "C:\Spool\report.prn" +Printer.Print "Captured to file" +Printer.EndDoc +``` + +## Properties + +### ColorMode +{: .no_toc } + +Whether the printer should print in colour or monochrome. + +Syntax: *object*.**ColorMode** [ = *value* ] + +*value* +: A member of [**PrinterObjectConstants_ColorMode**](../../VBRUN/Constants/PrinterObjectConstants_ColorMode): **vbPRCMMonochrome** (1) or **vbPRCMColor** (2). Other values raise error 380. + +### Copies +{: .no_toc } + +The number of copies to print. **Integer**. The maximum value supported by the driver is checked through the device-capabilities API: values greater than the maximum raise error 380, and a driver that does not advertise a maximum raises error 483 (*Printer driver does not support specified property*). + +### CurrentX +{: .no_toc } + +The horizontal pen position used by [**Print**](#print), [**Line**](#line), [**Circle**](#circle), and [**PSet**](#pset) when they omit a starting coordinate. **Double**, in the current [**ScaleMode**](#scalemode) units. Updated automatically by each drawing call. + +### CurrentY +{: .no_toc } + +The vertical pen position. **Double**. See [**CurrentX**](#currentx). + +### DeviceName +{: .no_toc } + +The friendly name of the bound printer, as it appears in the Windows printer dialog. **String**, read-only. While [**TrackDefault**](#trackdefault) is **True**, this returns the *current* default printer rather than a cached value. + +### DrawMode +{: .no_toc } + +The raster operation applied when drawing-method output is combined with the page. A member of [**DrawModeConstants**](../../VBRUN/Constants/DrawModeConstants), default **vbCopyPen** (opaque overwrite). Re-applied automatically after a printer change. + +### DrawStyle +{: .no_toc } + +The pen pattern used by line-drawing methods. A member of [**DrawStyleConstants**](../../VBRUN/Constants/DrawStyleConstants): **vbSolid** (0, default), **vbDash**, **vbDot**, **vbDashDot**, **vbDashDotDot**, **vbInvisible**, or **vbInsideSolid**. Solid is forced when [**DrawWidth**](#drawwidth) is greater than 1. + +### DrawWidth +{: .no_toc } + +The pen thickness, in pixels, used by [**Line**](#line), [**Circle**](#circle), and [**PSet**](#pset). **Long**, default 1. + +### DriverName +{: .no_toc } + +The name of the device driver that handles the bound printer. **String**, read-only. While [**TrackDefault**](#trackdefault) is **True**, this returns the *current* default printer's driver. + +### Duplex +{: .no_toc } + +Whether the printer should print on one or both sides of the paper. + +Syntax: *object*.**Duplex** [ = *value* ] + +*value* +: A member of [**PrinterObjectConstants_Duplex**](../../VBRUN/Constants/PrinterObjectConstants_Duplex): **vbPRDPSimplex** (1), **vbPRDPHorizontal** (2), or **vbPRDPVertical** (3). Values that exceed the driver's reported duplex capability raise error 380. Simplex is always accepted, even when the driver does not advertise duplex support. + +### FillColor +{: .no_toc } + +The colour used to fill closed shapes drawn by [**Line**](#line) (with the `F` flag) and [**Circle**](#circle), as an **OLE_COLOR**. Default **0** (black). Honoured only when [**FillStyle**](#fillstyle) is not **vbFSTransparent**. + +### FillStyle +{: .no_toc } + +The pattern used to fill closed shapes. A member of [**FillStyleConstants**](../../VBRUN/Constants/FillStyleConstants): **vbFSTransparent** (1, default), **vbFSSolid** (0), or one of the hatched styles. **Transparent** suppresses fill entirely, so only the outline is drawn. + +### Font +{: .no_toc } + +The **StdFont** used to render [**Print**](#print) output and measured by [**TextWidth**](#textwidth) / [**TextHeight**](#textheight). The convenience properties [**FontName**](#fontname), [**FontSize**](#fontsize), [**FontBold**](#fontbold), [**FontItalic**](#fontitalic), [**FontStrikethru**](#fontstrikethru), [**FontUnderline**](#fontunderline), and [**FontTransparent**](#fonttransparent) read or write members of this object. Assigning a string to **Font** is a shortcut for assigning to **Font.Name**; assigning an **StdFont** with **Set** replaces the underlying font object. + +On a printer obtained from [**Printers**](../Printers/), **Font** can still be read (a fresh, mutable **StdFont** is returned), but reassigning it raises error 383. + +### FontBold +{: .no_toc } + +Shortcut for [**Font**](#font)`.Bold`. **Boolean**. + +### FontCount +{: .no_toc } + +The number of typefaces installed on the printer. **Long**, read-only. Used together with [**Fonts**](#fonts) to enumerate them. + +### FontItalic +{: .no_toc } + +Shortcut for [**Font**](#font)`.Italic`. **Boolean**. + +### FontName +{: .no_toc } + +Shortcut for [**Font**](#font)`.Name`. **String**. + +### Fonts +{: .no_toc } + +Indexed access to the names of the typefaces installed on the printer. + +Syntax: *object*.**Fonts**( *Index* ) **As String** + +*Index* +: *required* A zero-based **Long** in the range `0 .. FontCount - 1`. Out-of-range indices return an empty string rather than raising an error. + +### FontSize +{: .no_toc } + +Shortcut for [**Font**](#font)`.Size`, the point size. **Single**. + +### FontStrikethru +{: .no_toc } + +Shortcut for [**Font**](#font)`.Strikethrough`. **Boolean**. + +### FontTransparent +{: .no_toc } + +When **True** (default), text drawn by [**Print**](#print) leaves the background pixels untouched between glyphs; when **False**, the glyphs' background is filled with the printer's drawn background colour. **Boolean**. + +### FontUnderline +{: .no_toc } + +Shortcut for [**Font**](#font)`.Underline`. **Boolean**. + +### ForeColor +{: .no_toc } + +The colour used by the drawing-method pen (lines, circles, points) and by [**Print**](#print) text. **OLE_COLOR**. + +### hDC +{: .no_toc } + +The Win32 device-context handle for the printer's drawing surface, as a **LongPtr**. Read-only. + +Reading **hDC** the first time creates the device context — calling the driver's **CreateDC** and preparing the surface for drawing — but does **not** start the spool job. The spooler is engaged only when the first drawing call runs, so reading **hDC** for, say, a **GetDeviceCaps** query is non-committal: nothing is printed if the application never calls a drawing method afterwards. + +### Height +{: .no_toc } + +The physical page height, in twips. **Long**. Assigning a value overrides the driver's reported paper height and forces [**PaperSize**](#papersize) to a custom size; the new value can be read back through `Height` itself. + +### Orientation +{: .no_toc } + +The page orientation. + +Syntax: *object*.**Orientation** [ = *value* ] + +*value* +: A member of [**PrinterObjectConstants_Orientation**](../../VBRUN/Constants/PrinterObjectConstants_Orientation): **vbPRORPortrait** (1) or **vbPRORLandscape** (2). Assigning landscape on a driver that does not advertise the **DC_ORIENTATION** capability raises error 380; portrait is always accepted. + +### OutputFile +{: .no_toc } + +The path of a file to capture the raw spooled bytes into, instead of sending them to the printer device. **String**. New in twinBASIC. Must be set before the first drawing call; assigning while a job is active has no effect on the running job. Read-only on a printer obtained from [**Printers**](../Printers/). + +### Page +{: .no_toc } + +The page currently being composed, starting at 1 when the job begins. **Long**, read-only. Reset to 1 by [**EndDoc**](#enddoc) and [**KillDoc**](#killdoc); incremented by [**NewPage**](#newpage). + +### PaperBin +{: .no_toc } + +The paper source the printer should pull from. + +Syntax: *object*.**PaperBin** [ = *value* ] + +*value* +: A member of [**PrinterObjectConstants_PaperBin**](../../VBRUN/Constants/PrinterObjectConstants_PaperBin) — for example **vbPRBNUpper**, **vbPRBNManual**, **vbPRBNCassette**. The value must be one of the bins the driver enumerates through **DC_BINS**; an unsupported value raises error 380. + +### PaperSize +{: .no_toc } + +The paper size to print on. + +Syntax: *object*.**PaperSize** [ = *value* ] + +*value* +: A member of [**PrinterObjectConstants_PaperSize**](../../VBRUN/Constants/PrinterObjectConstants_PaperSize) — for example **vbPRPSLetter**, **vbPRPSA4**, **vbPRPSEnv10**. Assigning to [**Width**](#width) or [**Height**](#height) forces this property to **vbPRPSUser** (256). + +### Port +{: .no_toc } + +The name of the port that connects to the printer (e.g. `LPT1:`, `USB001`, `IP_192.168.1.50`). **String**, read-only. While [**TrackDefault**](#trackdefault) is **True**, this returns the *current* default printer's port. + +### PrintQuality +{: .no_toc } + +The print resolution. + +Syntax: *object*.**PrintQuality** [ = *value* ] + +*value* +: An **Integer** — either a positive DPI value supported by the driver, or a member of [**PrinterObjectConstants_PrintQuality**](../../VBRUN/Constants/PrinterObjectConstants_PrintQuality): **vbPRPQDraft** (-1), **vbPRPQLow** (-2), **vbPRPQMedium** (-3), or **vbPRPQHigh** (-4). Zero, or values below -4, raise error 380. + +### RightToLeft +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### ScaleHeight +{: .no_toc } + +The vertical extent of the printer's drawing surface in [**ScaleMode**](#scalemode) units. **Double**. Assigning a value switches [**ScaleMode**](#scalemode) to **vbUser** and rescales the vertical axis so the page maps to the new height. + +### ScaleLeft +{: .no_toc } + +The X coordinate that maps to the left edge of the printable area. **Double**, default 0. Assigning a value switches [**ScaleMode**](#scalemode) to **vbUser**. + +### ScaleMode +{: .no_toc } + +The unit used by [**CurrentX**](#currentx), [**CurrentY**](#currenty), and every drawing method. A member of [**ScaleModeConstants**](../../VBRUN/Constants/ScaleModeConstants): **vbUser** (0), **vbTwips** (1, default), **vbPoints**, **vbPixels**, **vbCharacters**, **vbInches**, **vbMillimeters**, or **vbCentimeters**. Switching away from **vbUser** resets [**ScaleLeft**](#scaleleft) and [**ScaleTop**](#scaletop) to 0. + +### ScaleTop +{: .no_toc } + +The Y coordinate that maps to the top edge of the printable area. **Double**, default 0. Assigning a value switches [**ScaleMode**](#scalemode) to **vbUser**. + +### ScaleWidth +{: .no_toc } + +The horizontal extent of the printer's drawing surface in [**ScaleMode**](#scalemode) units. **Double**. Assigning a value switches [**ScaleMode**](#scalemode) to **vbUser**. + +### TrackDefault +{: .no_toc } + +When **True**, every property read consults the current system-default printer; when **False**, the **Printer** is locked to the specific device identified by [**DeviceName**](#devicename), [**DriverName**](#drivername), and [**Port**](#port). **Boolean**. + +Setting **TrackDefault** to **False** captures the current default device into the cached identifiers so subsequent reads stop drifting. Setting it back to **True** finishes any active print job (as if [**EndDoc**](#enddoc) had been called) and clears the cached device context. Always **False** on a printer obtained from [**Printers**](../Printers/), and read-only there. + +### TwipsPerPixelX +{: .no_toc } + +The number of twips that correspond to one device pixel, horizontally — useful for hand-rolled DPI-aware sizing. **Double**, read-only. + +### TwipsPerPixelY +{: .no_toc } + +The vertical counterpart of [**TwipsPerPixelX**](#twipsperpixelx). **Double**, read-only. + +### Width +{: .no_toc } + +The physical page width, in twips. **Long**. Assigning a value overrides the driver's reported paper width and forces [**PaperSize**](#papersize) to a custom size; the new value can be read back through `Width` itself. + +### Zoom +{: .no_toc } + +The print-scaling percentage applied by the driver. **Integer**, default 100. Values greater than 100 enlarge the output; values less than 100 shrink it. Zero and negative values raise error 380. + +## Methods + +### Circle +{: .no_toc } + +Draws a circle, ellipse, or elliptical arc on the current page. + +Syntax: *object*.**Circle** [ **Step** ] ( *X*, *Y* ), *Radius* [, *Color* [, *Start* [, *End* [, *Aspect* ] ] ] ] + +*X*, *Y* +: *required* Coordinates of the centre in [**ScaleMode**](#scalemode) units. **Single**. **Step** makes them relative to [**CurrentX**](#currentx) / [**CurrentY**](#currenty). + +*Radius* +: *required* The radius along the X axis. **Single**. + +*Color* +: *optional* An **OLE_COLOR** for the outline. Defaults to [**ForeColor**](#forecolor). + +*Start*, *End* +: *optional* Start and end angles in radians (0 to 2π). Negative values connect the arc end-point to the centre with a chord. Omitted draws a full circle. + +*Aspect* +: *optional* The Y/X aspect ratio. **1.0** for a circle (default); other values give an ellipse. + +If no job is in progress, **Circle** implicitly starts one. + +### EndDoc +{: .no_toc } + +Finalises the current print job, sending whatever is on the current page to the spooler and releasing the underlying GDI document. Has no effect when no job is in progress. + +Syntax: *object*.**EndDoc** + +### KillDoc +{: .no_toc } + +Aborts the current print job, discarding any in-progress page output. Releases the device context immediately, without further interaction with the spooler beyond an **AbortDoc** call. + +Syntax: *object*.**KillDoc** + +### Line +{: .no_toc } + +Draws a straight line, a rectangle outline, or a filled rectangle. + +Syntax: *object*.**Line** [ [ **Step** ] ( *X1*, *Y1* ) ] **-** [ **Step** ] ( *X2*, *Y2* ) [, *Color* [, **B** [**F**] ] ] + +*X1*, *Y1* +: *optional* Start coordinates. **Single**. If omitted, the line starts at [**CurrentX**](#currentx) / [**CurrentY**](#currenty). **Step** makes them relative to the pen. + +*X2*, *Y2* +: *required* End coordinates. **Single**. **Step** makes them relative to the start point. + +*Color* +: *optional* An **OLE_COLOR** for the line. Defaults to [**ForeColor**](#forecolor). + +*B* +: *optional* Draws a rectangle whose opposite corners are *(X1, Y1)* and *(X2, Y2)* instead of a line. + +*F* +: *optional* Only valid with **B**. Fills the rectangle with [**FillColor**](#fillcolor) at the current [**FillStyle**](#fillstyle). + +If no job is in progress, **Line** implicitly starts one. + +### NewPage +{: .no_toc } + +Emits the current page to the spooler and begins a new blank page. [**Page**](#page) is incremented; [**CurrentX**](#currentx) and [**CurrentY**](#currenty) are reset to 0. If no job is in progress, **NewPage** implicitly starts one before emitting the first page break. + +Syntax: *object*.**NewPage** + +### PaintPicture +{: .no_toc } + +Draws a picture onto the current page, optionally scaling, clipping, or applying a raster operation. + +Syntax: *object*.**PaintPicture** *Picture*, *X1*, *Y1* [, *Width1* [, *Height1* [, *X2* [, *Y2* [, *Width2* [, *Height2* [, *Opcode* ] ] ] ] ] ] ] + +*Picture* +: *required* An **IPictureDisp** to paint. + +*X1*, *Y1* +: *required* Destination top-left in [**ScaleMode**](#scalemode) units. + +*Width1*, *Height1* +: *optional* Destination size. Defaults to the picture's natural size. + +*X2*, *Y2*, *Width2*, *Height2* +: *optional* Source rectangle within *Picture*. Defaults to the whole picture. + +*Opcode* +: *optional* A raster-operation code passed through to **BitBlt** — for example **&HCC0020** (`vbSrcCopy`, default) or **&H660046** (`vbSrcInvert`). + +If no job is in progress, **PaintPicture** implicitly starts one. + +### Print +{: .no_toc } + +Writes text to the current page using [**Font**](#font), starting at [**CurrentX**](#currentx) / [**CurrentY**](#currenty) and advancing them as it goes. Dispatched through the **Print** statement so multiple expressions can be separated by `;` (no spacing) or `,` (tab to next print zone). **Spc(n)** inserts *n* spaces and **Tab(n)** moves to print column *n*. + +Syntax: *object*.**Print** \[ *expressionlist* \] \[ **;** \| **,** \] + +A trailing `;` or `,` suppresses the newline so the next [**Print**](#print) call continues on the same line. If no job is in progress, **Print** implicitly starts one. + +### PSet +{: .no_toc } + +Sets a single pixel on the current page. + +Syntax: *object*.**PSet** [ **Step** ] ( *X*, *Y* ) [, *Color* ] + +*X*, *Y* +: *required* Coordinates in [**ScaleMode**](#scalemode) units. **Single**. **Step** makes them relative to [**CurrentX**](#currentx) / [**CurrentY**](#currenty). + +*Color* +: *optional* An **OLE_COLOR**. Defaults to [**ForeColor**](#forecolor). + +If no job is in progress, **PSet** implicitly starts one. + +### Scale +{: .no_toc } + +Defines a user coordinate system for the page. Calling **Scale** with no arguments resets [**ScaleMode**](#scalemode) to **vbTwips** and clears [**ScaleLeft**](#scaleleft) / [**ScaleTop**](#scaletop). + +Syntax: *object*.**Scale** [ ( *X1*, *Y1* ) **-** ( *X2*, *Y2* ) ] + +*X1*, *Y1* +: *required* (with the second pair) The coordinate that maps to the top-left corner — sets [**ScaleLeft**](#scaleleft) and [**ScaleTop**](#scaletop). + +*X2*, *Y2* +: *required* The coordinate that maps to the bottom-right corner — sets [**ScaleWidth**](#scalewidth) = `X2 - X1` and [**ScaleHeight**](#scaleheight) = `Y2 - Y1`. [**ScaleMode**](#scalemode) becomes **vbUser**. + +Calling **Scale** with coordinates implicitly starts a print job (matching VB6 behaviour); calling it without arguments does not. + +### ScaleX +{: .no_toc } + +Converts a horizontal distance from one scale mode to another, without changing the printer's [**ScaleMode**](#scalemode). + +Syntax: *object*.**ScaleX**( *Width*, *FromScale* [, *ToScale* ] ) **As Double** + +*Width* +: *required* The value to convert. **Double**. + +*FromScale* +: *required* A [**ScaleModeConstants**](../../VBRUN/Constants/ScaleModeConstants) member identifying the unit of *Width*. Unlike on a [**PictureBox**](../PictureBox/) or [**Form**](../Form/), this argument has no default on a **Printer** — omitting it raises error 448 (*Named argument not found*). + +*ToScale* +: *optional* A [**ScaleModeConstants**](../../VBRUN/Constants/ScaleModeConstants) member identifying the unit of the result; defaults to the printer's current [**ScaleMode**](#scalemode). + +### ScaleY +{: .no_toc } + +The vertical counterpart of [**ScaleX**](#scalex), for heights. + +Syntax: *object*.**ScaleY**( *Height*, *FromScale* [, *ToScale* ] ) **As Double** + +### TextHeight +{: .no_toc } + +Measures the height of the given string when rendered in the current [**Font**](#font), in [**ScaleMode**](#scalemode) units — including the line-spacing leading, so the result is suitable for advancing [**CurrentY**](#currenty) between rows of text. Embedded line breaks are honoured. + +Syntax: *object*.**TextHeight**( *Str* **As String** ) **As Double** + +### TextWidth +{: .no_toc } + +Measures the width of the given string when rendered in the current [**Font**](#font), in [**ScaleMode**](#scalemode) units. Returns the longest line width when *Str* contains embedded line breaks. + +Syntax: *object*.**TextWidth**( *Str* **As String** ) **As Double** + +## See Also + +- [Printers](../Printers/) — read-only collection of every installed printer. +- [Form.PrintForm](../Form/#printform) — sends a screenshot of a form to the implicit **Printer**. +- [Report.PrintReport](../Report/#printreport) — sends every page of a banded report to the implicit **Printer**. +- [PrinterObjectConstants](../../VBRUN/Constants/PrinterObjectConstants) — combined enumeration of printer option values. diff --git a/docs/Reference/VB/Printers/index.md b/docs/Reference/VB/Printers/index.md new file mode 100644 index 0000000..52155a7 --- /dev/null +++ b/docs/Reference/VB/Printers/index.md @@ -0,0 +1,69 @@ +--- +title: Printers +parent: VB Package +permalink: /tB/Packages/VB/Printers/ +has_toc: false +--- + +# Printers class +{: .no_toc } + +A **Printers** object is a read-only collection of every printer installed on the system. It is exposed through the implicit **Printers** global — there is no user-callable constructor — and yields a [**Printer**](../Printer/) for each device, keyed by its **DeviceName**. Use it to enumerate the installed devices, or to switch the active printer with `Set Printer = Printers(name)`. + +```tb +Dim p As Printer +For Each p In Printers + Debug.Print p.DeviceName, p.DriverName, p.Port +Next + +Set Printer = Printers("HP LaserJet") ' make this the active printer +``` + +* TOC +{:toc} + +## What the collection contains + +Each entry is a [**Printer**](../Printer/) bound to the corresponding device. These instances are **immutable** descriptors — they are intended for identification and for handing to `Set Printer = …`, not for driving a print job directly. Assigning any of the settings properties on one raises run-time error 383 (*Property is read-only*); calling [**EndDoc**](../Printer/#enddoc), [**KillDoc**](../Printer/#killdoc), [**NewPage**](../Printer/#newpage), [**Print**](../Printer/#print), or the other document-control methods raises run-time error 438 (*Object doesn't support this property or method*). [**TrackDefault**](../Printer/#trackdefault) is always **False** on these instances. + +A driver that advertises a single device over multiple ports produces one [**Printer**](../Printer/) entry per port; only the first such entry is keyed by **DeviceName**, the rest are accessible only by numeric index. + +## Live enumeration + +The collection is **not cached**. Every call to [**Count**](#count), [**Item**](#item), or `For Each` re-reads the system's installed-printers list from the Windows registry's profile section and reconstructs a fresh batch of [**Printer**](../Printer/) instances. A printer added or removed in **Settings → Printers** is therefore picked up the next time the collection is touched, with no need to refresh anything from code. The trade-off is that consecutive accesses are not cheap — when enumerating, cache the result if many lookups are needed: + +```tb +Dim snapshot As Variant : snapshot = Array() ' or use a Collection +For Each p In Printers + snapshot = Array(snapshot, p.DeviceName) ' (illustrative) +Next +``` + +## Indexing + +Numeric indexing is **0-based**, in contrast with most VB6 collections, which are 1-based. The first installed printer is `Printers(0)`; the last is `Printers(Printers.Count - 1)`. An index outside that range raises run-time error 9 (*Subscript out of range*). + +String indexing looks up by **DeviceName** — new in twinBASIC; VB6's **Printers** supports only numeric access. A name that is not present raises the underlying collection's run-time error 5 (*Invalid procedure call or argument*). + +## Properties + +### Count +{: .no_toc } + +The number of installed printer entries. **Long**, read-only. Re-counted on every access — see [Live enumeration](#live-enumeration). + +Syntax: *object*.**Count** + +### Item +{: .no_toc } + +Returns the [**Printer**](../Printer/) at the given index. **Default property** — `Printers(0)` is shorthand for `Printers.Item(0)`. + +Syntax: *object*.**Item**( *Index* ) **As Printer** + +*Index* +: *required* A **Variant**. As a **Long**, the zero-based position in the collection (`0` to `Count - 1`); out-of-range values raise run-time error 9. As a **String**, the **DeviceName** of the printer; an unknown name raises run-time error 5. + +## See Also + +- [Printer](../Printer/) — the printer object itself, and the implicit **Printer** global. diff --git a/docs/Reference/VB/todo.md b/docs/Reference/VB/todo.md index 0abbb29..4949fca 100644 --- a/docs/Reference/VB/todo.md +++ b/docs/Reference/VB/todo.md @@ -3,7 +3,6 @@ title: General TODO List for /tB/Packages/VB/ nav_exclude: true redirect_from: - /tB/Packages/VB/DriveListBox - - /tB/Packages/VB/Printer --- > [!WARNING] From fbdf18d5e36543c4f5aca186f95d2f9934f2e95b Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Mon, 11 May 2026 14:41:20 +0200 Subject: [PATCH 2/2] Document the App, Clipboard, Screen, and Global objects. --- .../AppGlobalClassProject/App/index.md | 12 - docs/Reference/AppGlobalClassProject/index.md | 10 - docs/Reference/AppGlobalClassProject/todo.md | 12 - docs/Reference/VB/App/index.md | 265 ++++++++++++++++++ docs/Reference/VB/Clipboard/index.md | 145 ++++++++++ docs/Reference/VB/DirListBox/index.md | 4 +- docs/Reference/VB/FileListBox/index.md | 6 +- docs/Reference/VB/Global/index.md | 218 ++++++++++++++ docs/Reference/VB/Screen/index.md | 136 +++++++++ 9 files changed, 769 insertions(+), 39 deletions(-) delete mode 100644 docs/Reference/AppGlobalClassProject/App/index.md delete mode 100644 docs/Reference/AppGlobalClassProject/index.md delete mode 100644 docs/Reference/AppGlobalClassProject/todo.md create mode 100644 docs/Reference/VB/App/index.md create mode 100644 docs/Reference/VB/Clipboard/index.md create mode 100644 docs/Reference/VB/Global/index.md create mode 100644 docs/Reference/VB/Screen/index.md diff --git a/docs/Reference/AppGlobalClassProject/App/index.md b/docs/Reference/AppGlobalClassProject/App/index.md deleted file mode 100644 index 2b0b5b2..0000000 --- a/docs/Reference/AppGlobalClassProject/App/index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -nav_exclude: true -#parent: AppGlobalClassProject Package -permalink: /tB/Packages/AppGlobalClassProject/App ---- - -> [!WARNING] -> -> Pardon, we have not documented this class yet. - -# Path - diff --git a/docs/Reference/AppGlobalClassProject/index.md b/docs/Reference/AppGlobalClassProject/index.md deleted file mode 100644 index 3a85200..0000000 --- a/docs/Reference/AppGlobalClassProject/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: AppGlobalClassProject Package -parent: Reference Section -permalink: /tB/Packages/AppGlobalClassProject -nav_order: 20 ---- - -# AppGlobalClassProject Package - -This package exposes the global `App` object. diff --git a/docs/Reference/AppGlobalClassProject/todo.md b/docs/Reference/AppGlobalClassProject/todo.md deleted file mode 100644 index 98d1372..0000000 --- a/docs/Reference/AppGlobalClassProject/todo.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: General TODO List for /tB/Packages/AppGlobalClassProject/ -nav_exclude: true -redirect_from: ---- - -> [!WARNING] -> -> Pardon, we have not documented this class yet. - - - diff --git a/docs/Reference/VB/App/index.md b/docs/Reference/VB/App/index.md new file mode 100644 index 0000000..2031233 --- /dev/null +++ b/docs/Reference/VB/App/index.md @@ -0,0 +1,265 @@ +--- +title: App +parent: VB Package +permalink: /tB/Packages/VB/App/ +has_toc: false +--- + +# App class +{: .no_toc } + +The **App** class wraps the running application's identity and version metadata, plus a small amount of process-level state (the module handle, the main thread ID, whether the process is running inside the twinBASIC IDE or with elevated privileges, …). It is a singleton — there is exactly one **App** instance per process, owned by the runtime and exposed through the global **App** property of the [**Global**](../Global/) object. Code reaches it without qualification: + +```tb +Debug.Print "Running from " & App.Path +Debug.Print "Version " & App.Major & "." & App.Minor & "." & App.Revision & "." & App.Build + +If App.PrevInstance Then + MsgBox "Another instance is already running.", vbExclamation + End +End If + +App.HelpFile = App.Path & "\help.chm" +``` + +Most properties are read-only and are populated from the project settings (compiled into the executable's Win32 `VERSIONINFO` resource) at build time. The handful of read/write properties — [**Title**](#title) and [**HelpFile**](#helpfile) — let code change a small amount of run-time state that other parts of the runtime (notably the form caption defaults and the **F1** help dispatcher) consult. + +* TOC +{:toc} + +## Singleton and access + +**App** is not creatable: there is no `New App` and no public coclass to instantiate. The runtime exposes the singleton through the [**App**](../Global/#app) property on the [**Global**](../Global/) app-object, which is itself accessible without qualification. References returned by **App** are cached and stable for the lifetime of the process. + +## File and module location + +[**Path**](#path) and [**ModulePath**](#modulepath) describe where the executable lives: + +- [**Path**](#path) returns the folder containing the EXE, with no trailing backslash (e.g. `"C:\Program Files\MyApp"`). +- [**ModulePath**](#modulepath) returns the full path to the EXE itself (e.g. `"C:\Program Files\MyApp\MyApp.exe"`). +- [**EXEName**](#exename) returns the EXE's base name without the extension (e.g. `"MyApp"`). + +When the project is running inside the twinBASIC IDE — `App.IsInIDE` is **True** — [**Path**](#path) is the folder of the *project file* rather than of a compiled EXE, so it remains useful as a "where the application is" anchor for opening relative resources at design time. + +[**LastBuildPath**](#lastbuildpath) is a twinBASIC-specific extension that records the path the most recent IDE build wrote its EXE to — handy for build scripts that need to chain steps after an IDE build. + +## Version metadata + +The version-info properties read straight from the EXE's `VERSIONINFO` resource: + +- [**Major**](#major), [**Minor**](#minor), [**Revision**](#revision), and [**Build**](#build) — the four parts of the four-part version number set in the project's *Make* tab. +- [**Comments**](#comments), [**CompanyName**](#companyname), [**FileDescription**](#filedescription), [**LegalCopyright**](#legalcopyright), [**LegalTrademarks**](#legaltrademarks), and [**ProductName**](#productname) — the standard text fields of the same resource. +- [**Title**](#title) — the friendly application title shown in tasklist and message-box defaults; readable and writable. + +[**hInstance**](#hinstance) and [**ThreadID**](#threadid) expose the underlying Win32 module handle and the ID of the application's main thread — useful for interop with Windows API functions that need either. + +## Properties + +### Build +{: .no_toc } + +The **Build** component of the application's four-part version number, as set on the project's *Make* tab. **Integer**, read-only. + +### Comments +{: .no_toc } + +The free-form **Comments** field of the application's `VERSIONINFO` resource. **String**, read-only. + +### CompanyName +{: .no_toc } + +The **CompanyName** field of the application's `VERSIONINFO` resource. **String**, read-only. + +### EXEName +{: .no_toc } + +The base name of the executable — the file name minus its `.exe` extension and any directory component. **String**, read-only. When running inside the IDE, this is the project's compile-time output name rather than the IDE host's name. + +### FileDescription +{: .no_toc } + +The **FileDescription** field of the application's `VERSIONINFO` resource. **String**, read-only. + +### HelpFile +{: .no_toc } + +The full path to the application's help file (`.hlp` or `.chm`). **String**, readable and writable. The runtime consults this property when a control's [**HelpContextID**](../CheckBox/#helpcontextid) is non-zero and the user presses **F1**, and when application code calls `MsgBox` with a help-file argument. + +### hInstance +{: .no_toc } + +The Win32 module handle (`HINSTANCE`) for the executable. **LongPtr**, read-only. Useful when calling Windows API functions that load resources or create windows on the application's behalf. + +### IsElevated +{: .no_toc } + +**True** if the process is running with administrative privileges (a "Run as administrator" elevation token), **False** otherwise. **Boolean**, read-only. + +### IsInIDE +{: .no_toc } + +**True** if the running process is the twinBASIC IDE host rather than a stand-alone compiled executable. **Boolean**, read-only. Useful for code paths that should only run at design time, or for diagnostic logging that should be suppressed in shipping builds. + +### LastBuildPath +{: .no_toc } + +The full path that the IDE wrote the most recent build to. **String**, read-only. Empty when the IDE has not yet produced a build during the current session. twinBASIC-specific — VB6 had no equivalent. + +### LegalCopyright +{: .no_toc } + +The **LegalCopyright** field of the application's `VERSIONINFO` resource. **String**, read-only. + +### LegalTrademarks +{: .no_toc } + +The **LegalTrademarks** field of the application's `VERSIONINFO` resource. **String**, read-only. + +### LogMode +{: .no_toc } + +The current logging mode, as a member of [**LogModeConstants**](../../VBRUN/Constants/LogModeConstants). Read-only. + +> [!NOTE] +> twinBASIC currently reports only **vbLogOff** and **vbLogAuto**, distinguishing IDE-detection cases. The other VB6 logging modes (file, NT event log) are not yet honoured. + +### LogPath +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### Major +{: .no_toc } + +The **Major** component of the application's four-part version number. **Integer**, read-only. + +### Minor +{: .no_toc } + +The **Minor** component of the application's four-part version number. **Integer**, read-only. + +### ModulePath +{: .no_toc } + +The full path to the executable file. **String**, read-only. This is what `GetModuleFileName(App.hInstance, …)` would return. + +### NonModalAllowed +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### OleRequestPendingMsgText +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### OleRequestPendingMsgTitle +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### OleRequestPendingTimeout +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### OleServerBusyMsgText +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### OleServerBusyMsgTitle +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### OleServerBusyRaiseError +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### OleServerBusyTimeout +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### Path +{: .no_toc } + +The folder containing the executable, with no trailing backslash. **String**, read-only. When running inside the IDE, this is the folder containing the project file rather than the IDE host's folder, so code that opens files relative to the application location works identically at design time and at run time. + +### PrevInstance +{: .no_toc } + +**True** if another instance of the application is already running, **False** otherwise. **Boolean**, read-only. Typically tested at startup so the second instance can bring the first to the foreground or exit cleanly. + +### ProductName +{: .no_toc } + +The **ProductName** field of the application's `VERSIONINFO` resource. **String**, read-only. + +### RetainedProject +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### Revision +{: .no_toc } + +The **Revision** component of the application's four-part version number. **Integer**, read-only. + +### StartMode +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### TaskVisible +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### ThreadID +{: .no_toc } + +The Win32 thread ID of the application's main (UI) thread. **Long**, read-only. + +### Title +{: .no_toc } + +The application title shown to the OS (in the tasklist) and used as the default title for `MsgBox`, `InputBox`, and other system dialogs. **String**, readable and writable. Defaults to the executable's [**FileDescription**](#filedescription) (or [**EXEName**](#exename) if no description is set). + +### UnattendedApp +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +## Methods + +### LogEvent +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +Syntax: *object*.**LogEvent** *LogBuffer*, *EventType* + +### StartLogging +{: .no_toc } + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +Syntax: *object*.**StartLogging** *LogTarget*, *LogModes* diff --git a/docs/Reference/VB/Clipboard/index.md b/docs/Reference/VB/Clipboard/index.md new file mode 100644 index 0000000..bb0f00a --- /dev/null +++ b/docs/Reference/VB/Clipboard/index.md @@ -0,0 +1,145 @@ +--- +title: Clipboard +parent: VB Package +permalink: /tB/Packages/VB/Clipboard/ +has_toc: false +--- + +# Clipboard class +{: .no_toc } + +The **Clipboard** class wraps the system clipboard — the Win32 inter-application copy-and-paste surface — and exposes it as a singleton object. Code reads and writes text, queries which formats are currently available, and (eventually — see [the picture caveat](#picture-data)) reads and writes pictures. + +**Clipboard** is not creatable: there is exactly one instance per process, owned by the runtime and exposed through the [**Clipboard**](../Global/#clipboard) property on the [**Global**](../Global/) app-object. Code reaches it without qualification: + +```tb +' Copy +Clipboard.Clear +Clipboard.SetText "Hello, world!" + +' Paste +If Clipboard.GetFormat(vbCFText) Then + txtEditor.Text = Clipboard.GetText() +End If +``` + +* TOC +{:toc} + +## Formats + +Clipboard contents are tagged with a *format* — text, bitmap, files, rich text, and so on. The [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) enum lists the predefined formats: + +| Constant | Value | Meaning | +|-----------------------|-------|------------------------------------------------| +| **vbCFText** | 1 | ANSI plain text. | +| **vbCFBitmap** | 2 | DDB (device-dependent bitmap). | +| **vbCFMetafile** | 3 | Windows metafile (`WMF`). | +| **vbCFDIB** | 8 | DIB (device-independent bitmap). | +| **vbCFPalette** | 9 | Colour palette. | +| **vbCFUnicodeText** | 13 | UTF-16 plain text. | +| **vbCFEMetafile** | 14 | Enhanced metafile (`EMF`). | +| **vbCFFiles** | 15 | A list of file paths (`CF_HDROP`). | +| **vbCFLink** | `&HFFFFBF00` | DDE link (legacy OLE-1 link source). | +| **vbCFRTF** | `&HFFFFBF01` | Rich Text Format. | + +The [**GetText**](#gettext) / [**SetText**](#settext) methods take an optional *Format* argument constrained to the text-shaped subset (**vbCFText**, **vbCFUnicodeText**, **vbCFRTF**, **vbCFLink**). The [**GetData**](#getdata) / [**SetData**](#setdata) methods carry pictures, restricted to the bitmap and metafile formats. + +## Picture data + +The picture methods — [**GetData**](#getdata) and [**SetData**](#setdata) — are declared but not yet wired up. + +> [!NOTE] +> [**GetData**](#getdata) and [**SetData**](#setdata) are reserved for compatibility with VB6; they are not currently implemented in twinBASIC. For picture-clipboard interop, use the Win32 clipboard API (`OpenClipboard`, `GetClipboardData`, `SetClipboardData`, `CloseClipboard`) directly until the implementation lands. + +[**Clear**](#clear), [**GetText**](#gettext), [**SetText**](#settext), and [**GetFormat**](#getformat) are all fully functional. + +## Methods + +### Clear +{: .no_toc } + +Empties the clipboard, removing every format currently on it. + +Syntax: *object*.**Clear** + +### GetData +{: .no_toc } + +Reads picture data from the clipboard. Returns the result as a **stdole.StdPicture**. + +Syntax: *object*.**GetData**( [ *Format* ] ) + +*Format* +: *optional* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) selecting which picture format to retrieve (**vbCFBitmap**, **vbCFDIB**, **vbCFMetafile**, **vbCFEMetafile**, or **vbCFPalette**). When omitted, the implementation picks the most descriptive format the clipboard currently holds. + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### GetFormat +{: .no_toc } + +Tests whether the clipboard currently contains data in the given format. Returns **True** if it does, **False** otherwise. + +Syntax: *object*.**GetFormat**( *Format* ) + +*Format* +: *required* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) — the format to probe for. + +```tb +If Clipboard.GetFormat(vbCFFiles) Then + ' The clipboard holds a file list (e.g. from Explorer copy) +End If +``` + +### GetText +{: .no_toc } + +Reads text data from the clipboard. Returns a **String**; returns an empty string if the clipboard does not currently hold data in the requested format. + +Syntax: *object*.**GetText**( [ *Format* ] ) + +*Format* +: *optional* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) selecting which text format to retrieve: **vbCFText** (default), **vbCFUnicodeText**, **vbCFRTF**, or **vbCFLink**. + +```tb +Dim s As String +s = Clipboard.GetText() ' plain text +Dim rtf As String +rtf = Clipboard.GetText(vbCFRTF) ' RTF, if available +``` + +### SetData +{: .no_toc } + +Places picture data onto the clipboard. + +Syntax: *object*.**SetData** *Picture* [, *Format* ] + +*Picture* +: *required* A **stdole.StdPicture** carrying the picture to copy. + +*Format* +: *optional* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) — which picture format to publish. When omitted, the format is inferred from the picture's underlying type. + +> [!NOTE] +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. + +### SetText +{: .no_toc } + +Places text data onto the clipboard. Note that **SetText** does *not* implicitly clear the clipboard first — call [**Clear**](#clear) explicitly when you want only this one value on the clipboard, so that no stale data of other formats survives. + +Syntax: *object*.**SetText** *Str* [, *Format* ] + +*Str* +: *required* The **String** to publish. + +*Format* +: *optional* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) — **vbCFText** (default), **vbCFUnicodeText**, **vbCFRTF**, or **vbCFLink**. + +```tb +Clipboard.Clear +Clipboard.SetText "Plain text" +Clipboard.SetText "{\rtf1 \b Bold \b0 plain.}", vbCFRTF ' add an RTF alternative +``` diff --git a/docs/Reference/VB/DirListBox/index.md b/docs/Reference/VB/DirListBox/index.md index 920da82..9dd64cb 100644 --- a/docs/Reference/VB/DirListBox/index.md +++ b/docs/Reference/VB/DirListBox/index.md @@ -33,7 +33,7 @@ End Sub The control is built around three closely-related properties: -- [**Path**](#path) — the absolute path of the *current* directory. Set it from code (or by double-clicking an entry) to navigate the list. Defaults to [**App.Path**](../../AppGlobalClassProject/App#path) when the control is first created. +- [**Path**](#path) — the absolute path of the *current* directory. Set it from code (or by double-clicking an entry) to navigate the list. Defaults to [**App.Path**](../App/#path) when the control is first created. - [**ListIndex**](#listindex) — which entry the user has *selected*. `-1` selects the current folder itself (the deepest of the ancestor entries); `0` and up select successive subdirectories. Selecting an entry is independent of navigating to it — the selection just moves the highlight. - [**PathSelected**](#pathselected) — the absolute path that would become **Path** if the selected entry were activated. For an ancestor entry it walks back up the tree; for a subdirectory it concatenates **Path** and the entry's name. @@ -376,7 +376,7 @@ Syntax: *object*\_**GotFocus**( ) ### Initialize {: .no_toc } -Raised once, immediately after the underlying window is created and the initial path ([**App.Path**](../../AppGlobalClassProject/App#path)) has been loaded. New in twinBASIC — VB6 had no equivalent on this control. +Raised once, immediately after the underlying window is created and the initial path ([**App.Path**](../App/#path)) has been loaded. New in twinBASIC — VB6 had no equivalent on this control. Syntax: *object*\_**Initialize**( ) diff --git a/docs/Reference/VB/FileListBox/index.md b/docs/Reference/VB/FileListBox/index.md index 40840d4..b89e03a 100644 --- a/docs/Reference/VB/FileListBox/index.md +++ b/docs/Reference/VB/FileListBox/index.md @@ -36,7 +36,7 @@ End Sub ## Path and Pattern -[**Path**](#path) is the directory whose files are listed. It defaults to [**App.Path**](../../AppGlobalClassProject/App#path) when the control is first created. Setting it from code reloads the list, raises [**PathChange**](#pathchange), and trims any trailing backslash (except for a drive root). Setting a bare drive specifier without a backslash — `"C:"` — is silently rejected; use `"C:\"`. Assigning a path that does not exist raises run-time error 76 (*Path not found*). [**PathWithBackslash**](#pathwithbackslash) returns the same value with a trailing backslash always present, which is convenient when concatenating with [**FileName**](#filename). +[**Path**](#path) is the directory whose files are listed. It defaults to [**App.Path**](../App/#path) when the control is first created. Setting it from code reloads the list, raises [**PathChange**](#pathchange), and trims any trailing backslash (except for a drive root). Setting a bare drive specifier without a backslash — `"C:"` — is silently rejected; use `"C:\"`. Assigning a path that does not exist raises run-time error 76 (*Path not found*). [**PathWithBackslash**](#pathwithbackslash) returns the same value with a trailing backslash always present, which is convenient when concatenating with [**FileName**](#filename). [**Pattern**](#pattern) is one or more wildcard masks separated by semicolons (`"*.txt;*.doc"`). Each mask is matched case-insensitively using the **Like** operator; a file is shown if it matches *any* mask. The default is `"*.*"`. Setting **Pattern** reloads the list and raises [**PatternChange**](#patternchange) when the new value differs from the previous one. @@ -240,7 +240,7 @@ A reference to the **Form** (or **UserControl**) that contains this control. Rea ### Path {: .no_toc } -The directory whose files are listed. **String**. Defaults to [**App.Path**](../../AppGlobalClassProject/App#path) when the control is first created. +The directory whose files are listed. **String**. Defaults to [**App.Path**](../App/#path) when the control is first created. Syntax: *object*.**Path** [ = *string* ] @@ -468,7 +468,7 @@ Syntax: *object*\_**GotFocus**( ) ### Initialize {: .no_toc } -Raised once, immediately after the underlying window is created and the initial list of files has been loaded from [**App.Path**](../../AppGlobalClassProject/App#path). New in twinBASIC — VB6 had no equivalent on this control. +Raised once, immediately after the underlying window is created and the initial list of files has been loaded from [**App.Path**](../App/#path). New in twinBASIC — VB6 had no equivalent on this control. Syntax: *object*\_**Initialize**( ) diff --git a/docs/Reference/VB/Global/index.md b/docs/Reference/VB/Global/index.md new file mode 100644 index 0000000..f9ac195 --- /dev/null +++ b/docs/Reference/VB/Global/index.md @@ -0,0 +1,218 @@ +--- +title: Global +parent: VB Package +permalink: /tB/Packages/VB/Global/ +has_toc: false +--- + +# Global class +{: .no_toc } + +**Global** is the application's *app object* — a singleton that the runtime instantiates on startup and whose members are accessible from any code in the project *without qualification*. Writing `App.Path` is in fact a call to `Global.App.Path`; the leading `Global.` is implicit. The class exists so that the language's built-in globals — the singletons [**App**](../App/), [**Clipboard**](../Clipboard/), and [**Screen**](../Screen/), the [**Forms**](#forms) collection, the **Printer** and **Printers** objects, the resource loaders, and the `Load` / `Unload` form-lifetime helpers — can be reached uniformly through the same name resolution path. + +There is exactly one **Global** per process and it is not creatable from user code: no `New Global`, no public coclass to instantiate. The runtime publishes it via the IDE's special `[AppObject]` mechanism, and the compiler maps unqualified references to its members. + +```tb +' All four of these resolve to a method/property on Global: +Dim p As StdPicture +Set p = LoadPicture(App.Path & "\splash.png") + +Form2.Show +Load Form3 ' creates the form without showing it +Unload Form1 +``` + +* TOC +{:toc} + +## Built-in singletons + +[**App**](#app), [**Clipboard**](#clipboard), and [**Screen**](#screen) return the corresponding runtime singletons. Each is documented on its own page: + +- [**App**](../App/) — application metadata, version info, and process state. +- [**Clipboard**](../Clipboard/) — system clipboard access. +- [**Screen**](../Screen/) — primary-display metrics, active form/control, application-wide mouse pointer. + +These properties are cached references — repeated reads return the same object instance for the lifetime of the process. + +## Forms collection + +[**Forms**](#forms) returns the application's collection of currently-loaded [**Form**](../Form/) instances — every form that has been **Load**-ed or **Show**-n but not yet **Unload**-ed. The collection is live: it grows when a form is loaded and shrinks when one is unloaded. The collection supports three operations: + +- **Forms.Count** — a **Long** giving the number of currently-loaded forms. +- **Forms.Item(** *Index* **)** — the [**Form**](../Form/) at zero-based *Index*. **Item** is the default member, so `Forms(0)` and `Forms.Item(0)` are equivalent. Reading a negative or out-of-range index raises run-time error 9 (*Subscript out of range*). +- **Forms.Add(** *Name* **)** — creates a new instance of the form class named *Name*, adds it to the collection, and returns the new [**Form**](../Form/). The form is loaded but not shown. + +The collection also supports `For Each` enumeration: + +```tb +Dim f As Form +For Each f In Forms + Debug.Print f.Name, f.Caption +Next +``` + +A common idiom is closing every open form at shutdown — note that unloading shrinks the collection, so iterate backwards or by index from the top down: + +```tb +Dim i As Long +For i = Forms.Count - 1 To 0 Step -1 + Unload Forms(i) +Next +``` + +## Resource loaders + +twinBASIC compiles project-level resources (bitmaps, strings, raw byte blobs) into the final EXE's resource section. The four `LoadRes*` methods retrieve them at run time: + +- [**LoadResPicture**](#loadrespicture) — loads a bitmap, icon, or cursor resource into a **StdPicture**. +- [**LoadResString**](#loadresstring) — loads a string resource. +- [**LoadResData**](#loadresdata) — loads a raw byte-array resource. +- [**LoadResIdList**](#loadresidlist) — enumerates the IDs of resources of a given type. + +[**LoadPicture**](#loadpicture) loads a picture from a *file* rather than from an embedded resource — typically used at run time for user-chosen content or for resources kept outside the EXE. + +## Form lifetime helpers + +[**Load**](#load) creates a form (or, for control arrays, a control instance) without showing it; [**Unload**](#unload) tears it back down. Both are written without parentheses by convention — `Load Form1`, `Unload Form1` — and behave as statements, but they are in fact calls to **Global.Load** and **Global.Unload**. The corresponding form-lifecycle events ([**Initialize**](../Form/#initialize), [**Load**](../Form/#load), [**Unload**](../Form/#unload), [**Terminate**](../Form/#terminate)) fire at the expected points. + +## Printer and Printers + +The compile-time `FEATURE_PRINTER` flag exposes the **Printer** and **Printers** members. [**Printer**](../Printer/) is the currently-selected printer, and [**Printers**](../Printers/) is the collection of all installed printers; assigning a different printer object to **Printer** switches the application's current printer. + +## Properties + +### App +{: .no_toc } + +The application's singleton [**App**](../App/) instance — its identity, version, and process-state metadata. Read-only. + +### Clipboard +{: .no_toc } + +The application's singleton [**Clipboard**](../Clipboard/) instance — the system clipboard wrapper. Read-only. + +### Forms +{: .no_toc } + +The application's live collection of currently-loaded [**Form**](../Form/) instances. Read-only. See [Forms collection](#forms-collection). + +### Printer +{: .no_toc } + +The currently-selected [**Printer**](../Printer/). Readable and assignable with `Set` — assigning a different printer object switches the application's current printer. + +### Printers +{: .no_toc } + +The [**Printers**](../Printers/) collection of all installed printers on the system. Read-only. + +### Screen +{: .no_toc } + +The application's singleton [**Screen**](../Screen/) instance — primary-display metrics, active form/control, application-wide mouse pointer. Read-only. + +## Methods + +### Load +{: .no_toc } + +Creates an instance of the named form (or a new element of a control array) without showing it. The form's [**Initialize**](../Form/#initialize) and [**Load**](../Form/#load) events fire. + +Syntax: **Load** *object* + +*object* +: *required* The default instance of a form class (`Form1`), an explicit form reference, or a control-array element (`Command1(3)`). + +```tb +Load Form2 ' instantiates and runs Form_Load, but Form2 stays hidden +Set frm = Forms("Form2") ' the new instance now exists in Forms +``` + +### LoadPicture +{: .no_toc } + +Loads a picture from a file. Returns a **stdole.IPictureDisp**. + +Syntax: **LoadPicture**( [ *FileName* [, *Size* [, *ColorDepth* [, *X* [, *Y* ] ] ] ] ] ) + +*FileName* +: *optional* A **String** giving the path to a `.bmp`, `.dib`, `.gif`, `.jpg`, `.png`, `.wmf`, `.emf`, `.ico`, or `.cur` file. When omitted, returns an empty picture — useful for clearing an [**Image**](../Image/) or [**PictureBox**](../PictureBox/)'s **Picture** property. + +*Size* +: *optional* A member of [**LoadPictureSizeConstants**](../../VBRUN/Constants/LoadPictureSizeConstants) — meaningful only for icons and cursors, where it picks among the sizes stored in the file. + +*ColorDepth* +: *optional* A member of [**LoadPictureColorConstants**](../../VBRUN/Constants/LoadPictureColorConstants) — meaningful only for icons and cursors, where it picks among the colour depths stored in the file. + +*X*, *Y* +: *optional* Width and height overrides used when *Size* is **vbLPCustom**, in pixels. + +```tb +Set imgLogo.Picture = LoadPicture(App.Path & "\logo.png") +Set imgLogo.Picture = LoadPicture() ' clears the picture +``` + +### LoadResData +{: .no_toc } + +Loads a raw resource — usually a binary blob — from the application's resource section, as a **Byte()** array wrapped in a **Variant**. + +Syntax: **LoadResData**( *id*, *Type* ) + +*id* +: *required* The resource ID, either as a **Long** (numeric ID) or **String** (name). + +*Type* +: *required* The resource type, identifying the resource section to look in. Either a **Long** standard-resource type or a **String** custom-resource type. + +### LoadResIdList +{: .no_toc } + +Returns the list of resource IDs in the resource section of the given type, as a **Variant** array. + +Syntax: **LoadResIdList**( *Type* ) + +*Type* +: *required* The resource type — see [**LoadResData**](#loadresdata). + +### LoadResPicture +{: .no_toc } + +Loads a picture, icon, or cursor resource from the application's resource section into a **stdole.IPictureDisp**. + +Syntax: **LoadResPicture**( *id*, *restype* [, *width* [, *height* ] ] ) + +*id* +: *required* The resource ID — **Long** (numeric) or **String** (name). + +*restype* +: *required* A member of [**LoadResConstants**](../../VBRUN/Constants/LoadResConstants) — **vbResBitmap**, **vbResIcon**, or **vbResCursor**. + +*width*, *height* +: *optional* Pixel dimensions for icon/cursor resources; **0** (default) selects the resource's natural size. + +### LoadResString +{: .no_toc } + +Loads a string resource from the application's resource section. Returns a **String**. + +Syntax: **LoadResString**( *id* ) + +*id* +: *required* The resource ID, as a **Long**. + +### Unload +{: .no_toc } + +Tears down the form (or removes the control-array element). The form's [**QueryUnload**](../Form/#queryunload), [**Unload**](../Form/#unload), and [**Terminate**](../Form/#terminate) events fire in order. Either of the first two can set its *Cancel* argument non-zero to veto the unload, in which case the form remains loaded and visible. + +Syntax: **Unload** *object* + +*object* +: *required* The default instance of a form class, an explicit form reference, or a control-array element. + +```tb +Unload Me ' close the current form +Unload Forms(0) ' close whichever form is at the head of the list +``` diff --git a/docs/Reference/VB/Screen/index.md b/docs/Reference/VB/Screen/index.md new file mode 100644 index 0000000..5cfe09d --- /dev/null +++ b/docs/Reference/VB/Screen/index.md @@ -0,0 +1,136 @@ +--- +title: Screen +parent: VB Package +permalink: /tB/Packages/VB/Screen/ +has_toc: false +--- + +# Screen class +{: .no_toc } + +The **Screen** class wraps the user's primary display — its dimensions and twip-to-pixel ratio, the list of installed fonts, the currently active [**Form**](../Form/) and the currently focused control on that form, and the application-wide mouse-pointer override. It is a singleton: there is exactly one **Screen** instance per process, owned by the runtime and exposed through the [**Screen**](../Global/#screen) property of the [**Global**](../Global/) app-object. Code reaches it without qualification: + +```tb +' Centre a form on the primary display +Me.Left = (Screen.Width - Me.Width) \ 2 +Me.Top = (Screen.Height - Me.Height) \ 2 + +' Show an hourglass cursor across the whole application during a long task +Screen.MousePointer = vbHourglass +LongRunningWork +Screen.MousePointer = vbDefault +``` + +* TOC +{:toc} + +## Dimensions and DPI + +[**Width**](#width) and [**Height**](#height) report the primary monitor's dimensions in twips — the same unit forms and controls use by default. The conversion factors are exposed too: + +- [**TwipsPerPixelX**](#twipsperpixelx) — twips per horizontal pixel on the primary display. +- [**TwipsPerPixelY**](#twipsperpixely) — twips per vertical pixel. + +On a 96-DPI display these are both `15` (1440 twips per logical inch ÷ 96 pixels per inch); on a 144-DPI display they are `10`. Use them when interop with the Win32 API forces a conversion between pixels and the form-side coordinate system. + +> [!NOTE] +> twinBASIC's **Screen** describes the *primary* monitor only. For per-monitor information in a multi-monitor configuration, fall through to the Win32 `EnumDisplayMonitors` / `GetMonitorInfo` API. + +## Active form and active control + +[**ActiveForm**](#activeform) returns the [**Form**](../Form/) instance that is currently the foreground form in the application; [**ActiveControl**](#activecontrol) returns the control within that form that currently holds the focus. Both return **Nothing** if no form in the application is active. + +The most common idiom is reaching into the active form from a global handler — for example, a toolbar button on an [**MDIForm**](../MDIForm/) that operates on whatever MDI child is in front: + +```tb +Private Sub tbrEdit_ButtonClick(ByVal Button As MSComctlLib.Button) + Dim f As Form + Set f = Screen.ActiveForm + If f Is Nothing Then Exit Sub + Select Case Button.Key + Case "Cut": f.ActiveControl.SelText = "" + Case "Copy": Clipboard.SetText f.ActiveControl.SelText + ... + End Select +End Sub +``` + +## Fonts + +[**FontCount**](#fontcount) is the number of fonts the OS reports for the current display context; [**Fonts**](#fonts)(*Index*) returns the name of the font at *Index* — `0` to `FontCount - 1`. Together they let an application build a font-picker without going through the Win32 `EnumFontFamilies` API. + +```tb +Dim i As Integer +For i = 0 To Screen.FontCount - 1 + cboFonts.AddItem Screen.Fonts(i) +Next +``` + +## Mouse pointer override + +[**MousePointer**](#mousepointer) is an application-wide cursor override. Setting it to anything other than **vbDefault** forces the chosen cursor over every window of the application, regardless of each individual control's own [**MousePointer**](../CheckBox/#mousepointer) setting — the typical use is showing the hourglass while a synchronous operation runs. Set it back to **vbDefault** when the operation completes. + +[**MouseIcon**](#mouseicon) supplies a custom **StdPicture** to use when [**MousePointer**](#mousepointer) is **vbCustom**. + +## Properties + +### ActiveControl +{: .no_toc } + +The control on the [**ActiveForm**](#activeform) that currently has the input focus, as a [**Control**](../CheckBox/) reference, or **Nothing** if no form is active. Read-only. + +### ActiveForm +{: .no_toc } + +The [**Form**](../Form/) that is currently the foreground form in the application, or **Nothing** if no form is active. Read-only. + +### FontCount +{: .no_toc } + +The number of fonts the OS reports as available on the current display context. **Integer**, read-only. + +### Fonts +{: .no_toc } + +The name of the font at the given zero-based index, in the order the OS reported it. **String**, read-only. + +Syntax: *object*.**Fonts**( *Index* ) + +*Index* +: *required* An **Integer** in the range `0` to [**FontCount**](#fontcount) `- 1`. Out-of-range indices return an empty string. + +### Height +{: .no_toc } + +The height of the primary display, in twips. **Single**, read-only. + +### MouseIcon +{: .no_toc } + +The custom cursor picture used when [**MousePointer**](#mousepointer) is **vbCustom**, as a **StdPicture**. Readable, writable (`Let`), and assignable by reference (`Set`). + +### MousePointer +{: .no_toc } + +The application-wide mouse-pointer override, as a member of [**MousePointerConstants**](../../VBRUN/Constants/MousePointerConstants). **Integer**, readable and writable. + +Setting **MousePointer** to anything other than **vbDefault** (0) forces the chosen cursor over every window of the application, ignoring per-control overrides. The typical use is showing **vbHourglass** during a synchronous long-running operation; set it back to **vbDefault** when the operation finishes. + +### TwipsPerPixelX +{: .no_toc } + +The number of twips per horizontal pixel on the primary display, as a **Single**. Effectively `1440 / dpi_x`. Returned by a parameterless function call. + +Syntax: *object*.**TwipsPerPixelX**( ) + +### TwipsPerPixelY +{: .no_toc } + +The number of twips per vertical pixel on the primary display, as a **Single**. Effectively `1440 / dpi_y`. Returned by a parameterless function call. + +Syntax: *object*.**TwipsPerPixelY**( ) + +### Width +{: .no_toc } + +The width of the primary display, in twips. **Single**, read-only.