diff --git a/WIP.md b/WIP.md index a7fdb090..6fe71ede 100644 --- a/WIP.md +++ b/WIP.md @@ -28,8 +28,8 @@ The rest of this file is the maintenance guide for updating existing pages or ad - `docs/Reference/Core/` — language statements/keywords (`Dim`, `For-Next`, `Sub`, ...). - `docs/Reference///` — runtime library (VBA, VBRUN), grouped by modules. - `docs/Reference///index.md` — module landing page listing its members. -- `docs/Reference/VB/.md` — single-file class page (e.g. [`CheckBox.md`](docs/Reference/VB/CheckBox.md)). -- `docs/Reference/VB//index.md` — folder-style class page when sub-pages may follow (e.g. [`CheckMark/index.md`](docs/Reference/VB/CheckMark/index.md)). +- `docs/Reference/VB/.md` — single-file class page. No current VB class uses this shape; all VB classes are folder-style. +- `docs/Reference/VB//index.md` — folder-style class page (e.g. [`CheckBox/index.md`](docs/Reference/VB/CheckBox/index.md), [`CheckMark/index.md`](docs/Reference/VB/CheckMark/index.md)). - `docs/Reference/WebView2/` — WebView2 package: the **WebView2** control class plus its small wrapper classes (request / response / headers / environment options) and the `wv2…` enumerations. - `docs/Reference/CustomControls/` — CustomControls package: the eight **Waynes…** custom controls, their shared `Styles/` helper classes (`Fill`, `Borders`, `Corners`, `TextRendering`, …), the `Framework/` DESIGNER surface (interfaces, CoClasses, the `Canvas` / `SerializeInfo` UDTs), and the `Enumerations/` (`CornerShape`, `FillPattern`, `DockMode`, …). - `docs/Reference/CEF/` — CEF (Chromium Embedded Framework) package: the **CefBrowser** control, its `EnvironmentOptions` sub-page, and the two user-facing enumerations (`CefLogSeverity`, `cefPrintOrientation`). This is a much smaller surface than WebView2 — the package is currently BETA and many WebView2-equivalent features are not yet exposed. @@ -66,8 +66,7 @@ Match the existing style. Worked examples to imitate: - VBA module function: `docs/Reference/VBA/Interaction/AppActivate.md`, `docs/Reference/VBA/Interaction/Beep.md`. - VBA property with `Core/` redirect: `docs/Reference/VBA/DateTime/Date.md`. - VBRUN module member: `docs/Reference/VBRUN/AmbientProperties/BackColor.md`, `docs/Reference/VBRUN/PropertyBag/index.md`. -- VB control class (single-file): `docs/Reference/VB/CheckBox.md`. -- VB control class (folder-style): `docs/Reference/VB/CheckMark/index.md`. +- VB control class (folder-style; all current VB classes): `docs/Reference/VB/CheckBox/index.md`, `docs/Reference/VB/CheckMark/index.md`. - Assert module page (single-file, all members inline): `docs/Reference/Assert/Exact.md`. - CEF control class (folder-style with a sub-page): `docs/Reference/CEF/CefBrowser/index.md` + `docs/Reference/CEF/CefBrowser/EnvironmentOptions.md`. - Generic class (single-file, `(Of T1, T2)`): `docs/Reference/WinEventLogLib/EventLog.md`. @@ -314,6 +313,29 @@ The audience is international: standard-English readers worldwide, often non-nat The guiding principle: **replace metaphors imported from outside programming; keep vocabulary with a specific technical meaning inside Win32 / COM / event-driven programming.** If a phrase is the kind of thing a reader would have to look up in a tech blog, it doesn't belong in reference prose. +### Sentence and structure + +The vocabulary tables further down cover word choice. The rules in this subsection cover sentence shape and voice — the structural side of writing for an international audience. + +1. **Page opening.** One-sentence verb-phrase summary directly under the H1, in present tense, no preamble. *Good:* "Activates an application window." / "Writes an **Error**-type entry to the log." *Avoid:* "The **Const** statement is used to declare constants in place of literal values." For class pages, a noun-phrase descriptor is acceptable — *"A **CheckBox** is a Win32 native control that displays..."* + +2. **Voice and tense.** Active voice by default. Passive only for subjectless operations where there is no obvious agent — "the entry is written", "the constant is private by default". Present tense for behavior — `returns`, not `will return`. Don't give the class human traits: it doesn't "decide", "want", or "know" — it returns, raises, contains. + +3. **Sentence shape.** One idea per sentence. Prefer two short sentences over one compound sentence with nested clauses. Em-dash (`—`) for parenthetical asides; reserve parentheses for code-ish notation like `(default)`. + +4. **Person and pronouns.** Reference body prose uses third-person impersonal — "the constant", "the source", "the entry". Rewrite "you" to the impersonal form even in VBA-derived pages. "You" is acceptable inside `Example` lead-ins and in tutorial prose. Avoid first-person ("we", "I"). + +5. **Parameter descriptions.** Italic `*required*` / `*optional*` flag, then a short prose description. Lead with the type when it matters — "A **String** naming the source...", "A *T1* value naming the event...". Don't restate the parameter's name inside its own definition. Property setters omit the flag — the `[ = *value* ]` brackets on the syntax line carry that information. + +6. **Callout severity.** Three severity levels, used distinctly: + - `> [!NOTE]` — twinBASIC-vs-VBA deviations, behavior clarifications, useful caveats. Not for marketing/why-bother prose — that should be a plain paragraph. + - `> [!IMPORTANT]` — requirements that affect correctness: admin rights, threading constraints, ordering. + - `> [!WARNING]` — operations that can corrupt state or lose data. + + One callout per concern; don't stack a NOTE and an IMPORTANT for the same point. + +7. **See Also.** Last section on the page, after `Example`. Format: `- [Symbol](Symbol) ` where `` is the kind: statement, function, property, method, class, module, package. Pages with annotations use `- [Symbol](Symbol) -- short description` — the `--` source renders as a typographic dash via kramdown's smart_quotes (en-dash for `--`, em-dash for `---`). Don't write literal `—` in source; keep `--` for consistency across the docs. Order by conceptual proximity, not strict alphabetical. + ### Replace | Term | Use instead | @@ -383,6 +405,19 @@ Don't over-correct these — they are precise technical vocabulary or otherwise Some kept terms are referenced by in-doc anchors. The most prominent is `idiom` / `idiomatic` — `WIP.WinEventLogLib.md` and `WIP.WinServicesLib.md` reference anchors like `#service-host-idiom` and `#composition-delegation-idiom`. Don't rename these casually; if you do, add `redirect_from` aliases to preserve legacy links. +### Source dashes + +Kramdown's `smart_quotes` feature (enabled by default in this site) converts the ASCII source forms to typographic characters at build time: + +| Source | Rendered | Use for | +|--------|----------|---------| +| `--` | en-dash `–` | bullet-list separator (rule 7), ranges | +| `---` | em-dash `—` | parenthetical asides (rule 3), breaks in thought | + +The source uses the ASCII forms; the rendered HTML uses the typographic characters. Literal `–` or `—` in `docs/` markdown source is forbidden — see the Don'ts at the end of this file. `scripts/convert_em_dash_separators.py` is the canonical normaliser if any literals slip back in. + +WIP.md itself (and other files outside `docs/`) is not part of the Jekyll site and is exempt — literal em-dashes here render directly in the GitHub viewer, which is fine. + ## Scripts and tooling Any new helper script (content conversion, link checks beyond `check.bat`, etc.) should be written in **Python**. Do not add new Ruby code to this repo. The only Ruby allowed is the existing Jekyll/`just-the-docs` build chain (`Gemfile`, `Gemfile.lock`, `_plugins/`) — that stays as-is. @@ -415,6 +450,7 @@ Favor concise one-line git commit messages. - Don't commit `.claude/` or `CLAUDE.md` — both gitignored. (`WIP.md` is committed; `CLAUDE.md` is just a local `@WIP.md` import shim.) - Don't touch `_site/` (build output, gitignored). +- Don't write literal en-dash `–` or em-dash `—` in `docs/` markdown source. Use `--` (renders as en-dash) or `---` (renders as em-dash) — kramdown's smart_quotes does the conversion at build time. `scripts/convert_em_dash_separators.py` normalises any strays. - Don't push or force-push without explicit user request. - Don't invent semantics — read the relevant primary source before paraphrasing (VBA-Docs for VBA-derived pages; the package's `.twin` sources for twinBASIC-specific ones). - Don't add boilerplate sections (Remarks, See Also) if the source has nothing meaningful for them. diff --git a/docs/Challenges/create-a-game.md b/docs/Challenges/create-a-game.md index f7002659..5b215992 100644 --- a/docs/Challenges/create-a-game.md +++ b/docs/Challenges/create-a-game.md @@ -63,7 +63,7 @@ Bonus points may be awarded at the discretion of the twinBASIC team. Entries must be received by: -🗓️ 1st March — 12:00 PM (GMT) +🗓️ 1st March --- 12:00 PM (GMT) Submissions will be locked after the deadline. diff --git a/docs/Features/GUI-Components/Windowless.md b/docs/Features/GUI-Components/Windowless.md index 80cf39db..23c144ac 100644 --- a/docs/Features/GUI-Components/Windowless.md +++ b/docs/Features/GUI-Components/Windowless.md @@ -24,7 +24,7 @@ redirect_from: ### ✅ **Benefits of Windowless Controls** -- **Performance Boost**: No hWnd means less GDI overhead—great for forms with many static elements.3 +- **Performance Boost**: No hWnd means less GDI overhead---great for forms with many static elements.3 - **Visual Flexibility**: Enables transparent or shaped UI elements (e.g., rounded buttons, overlays). - **Resource Efficiency**: Helps avoid hitting system handle limits in control-heavy UIs. @@ -33,7 +33,7 @@ redirect_from: ### ⚠️ **Drawbacks** - **Complex Input Handling**: You must manually forward focus, mouse, and keyboard events from the container. -- **Z-Order Limitations**: Cannot appear above windowed controls—problematic for overlays or tooltips.4 +- **Z-Order Limitations**: Cannot appear above windowed controls---problematic for overlays or tooltips.4 - **Quirks**: twinBASIC has some known issues with windowless control events and other features.2 - **Accessibility Overhead**: Requires extra work to expose accessibility interfaces.1 @@ -41,9 +41,9 @@ redirect_from: 1 [IAccessibleWindowlessSite Interface on Microsoft Learn](https://learn.microsoft.com/en-us/windows/win32/api/oleacc/nn-oleacc-iaccessiblewindowlesssite) -2 Originally reported in [twinBASIC GitHub Issue #1310 – Windowless Anchor Resizing Bug](https://github.com/twinbasic/twinbasic/issues/1310). Fixed in BETA 162. +2 Originally reported in [twinBASIC GitHub Issue #1310 -- Windowless Anchor Resizing Bug](https://github.com/twinbasic/twinbasic/issues/1310). Fixed in BETA 162. -3 Overview of [GDI object handles](https://learn.microsoft.com/en-us/windows/win32/sysinfo/gdi-objects) and [hWnd user object handles](https://learn.microsoft.com/en-us/windows/win32/sysinfo/user-objects) in Windows UI architecture: [MSDN – Window Resources](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-resources) +3 Overview of [GDI object handles](https://learn.microsoft.com/en-us/windows/win32/sysinfo/gdi-objects) and [hWnd user object handles](https://learn.microsoft.com/en-us/windows/win32/sysinfo/user-objects) in Windows UI architecture: [MSDN -- Window Resources](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-resources) 4 Background on Z-order rendering and Windows control layering: [Windows Controls - Z-order](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-features#z-order) @@ -74,16 +74,16 @@ redirect_from: ### 🪟 Windowless Control Examples -- **[SweetIceLolly/VB6-MemoryDC](https://github.com/SweetIceLolly/VB6-MemoryDC)** – A VB6 project demonstrating off-screen rendering using memory device contexts. Great for illustrating custom-drawn, windowless UI elements. -- **[fafalone/WinDevLib](https://github.com/fafalone/WinDevLib)** – A twinBASIC library with low-level Win32 API wrappers. Includes examples of custom rendering and control logic that bypass hWnds. -- **[fafalone/EventTrace](https://github.com/fafalone/EventTrace)** – A twinBASIC port of an ETW file activity monitor. Uses lightweight, non-windowed UI elements for performance. +- **[SweetIceLolly/VB6-MemoryDC](https://github.com/SweetIceLolly/VB6-MemoryDC)** -- A VB6 project demonstrating off-screen rendering using memory device contexts. Great for illustrating custom-drawn, windowless UI elements. +- **[fafalone/WinDevLib](https://github.com/fafalone/WinDevLib)** -- A twinBASIC library with low-level Win32 API wrappers. Includes examples of custom rendering and control logic that bypass hWnds. +- **[fafalone/EventTrace](https://github.com/fafalone/EventTrace)** -- A twinBASIC port of an ETW file activity monitor. Uses lightweight, non-windowed UI elements for performance. ### 🧱 Windowed Control Examples -- **[fafalone/UIRibbonDemos](https://github.com/fafalone/UIRibbonDemos)** – twinBASIC demos of the Windows Ribbon UI framework. Showcases interactive, hWnd-backed controls with full accessibility and Z-order behavior. -- **[SweetIceLolly/DragControlsIDE](https://github.com/SweetIceLolly/DragControlsIDE)** – A VB6-based IDE-like interface with draggable, windowed controls. Useful for demonstrating layout and anchoring behavior. +- **[fafalone/UIRibbonDemos](https://github.com/fafalone/UIRibbonDemos)** -- twinBASIC demos of the Windows Ribbon UI framework. Showcases interactive, hWnd-backed controls with full accessibility and Z-order behavior. +- **[SweetIceLolly/DragControlsIDE](https://github.com/SweetIceLolly/DragControlsIDE)** -- A VB6-based IDE-like interface with draggable, windowed controls. Useful for demonstrating layout and anchoring behavior. - **[SweetIceLolly/DragControlsIDE-v2](https://github.com/SweetIceLolly/DragControlsIDE-v2)** - an updated version of the above. -- **[bclothier/TwinBasicSevenZip](https://github.com/bclothier/TwinBasicSevenZip)** – A twinBASIC wrapper for 7-Zip COM integration. Includes a UI with standard windowed controls for file selection and progress. +- **[bclothier/TwinBasicSevenZip](https://github.com/bclothier/TwinBasicSevenZip)** -- A twinBASIC wrapper for 7-Zip COM integration. Includes a UI with standard windowed controls for file selection and progress. --- @@ -146,4 +146,4 @@ Printer.EndDoc ``` --- -For DPI-aware, multi-monitor layout work, windowless controls are useful—especially for static or decorative elements—but they demand more manual handling when interactivity or layering is involved. If you're building a hybrid layout, a mix of both types might give you the best of both worlds. +For DPI-aware, multi-monitor layout work, windowless controls are useful---especially for static or decorative elements---but they demand more manual handling when interactivity or layering is involved. If you're building a hybrid layout, a mix of both types might give you the best of both worlds. diff --git a/docs/Reference/Assert/Exact.md b/docs/Reference/Assert/Exact.md index 68b64d6c..a9421761 100644 --- a/docs/Reference/Assert/Exact.md +++ b/docs/Reference/Assert/Exact.md @@ -8,21 +8,21 @@ has_toc: false # Exact module {: .no_toc } -The **Exact** module of the [**Assert**](.) package supplies assertions with the strictest possible comparison semantics. String comparisons are case-sensitive; numeric values must match in datatype as well as value (so `5` is not equal to `5.0`); `vbNullString` is distinct from `""`; `Empty` is distinct from `0`, `False`, `""`, and `vbNullString`; and object default members are not evaluated. Use **Exact** when an assertion should flag any kind of implicit conversion or coercion in the values being tested. +The **Exact** module of the [**Assert**](.) package supplies assertions with the strictest possible comparison semantics. String comparisons are case-sensitive; numeric values must match in datatype as well as value (so `5` is not equal to `5.0`); `vbNullString` is distinct from `""`; `Empty` is distinct from `0`, `False`, `""`, and `vbNullString`; and object default members are not evaluated. **Exact** flags any kind of implicit conversion or coercion in the values being tested. * TOC {:toc} ## Comparison semantics -The four equality assertions in this module — [**AreEqual**](#areequal), [**AreNotEqual**](#arenotequal), [**SequenceEquals**](#sequenceequals), and [**NotSequenceEquals**](#notsequenceequals) — apply the rules listed below. The remaining assertions are unaffected. +The four equality assertions in this module --- [**AreEqual**](#areequal), [**AreNotEqual**](#arenotequal), [**SequenceEquals**](#sequenceequals), and [**NotSequenceEquals**](#notsequenceequals) --- apply the rules listed below. The remaining assertions are unaffected. - *String* comparisons are case-sensitive (regardless of the project's `Option Compare` setting). - The datatype of the compared values must match exactly. `Long` and `Double`, `Long` and `Currency`, and `Integer` and `Long` are all considered different. - `vbNullString` and a zero-length **String** (`""`) are considered different. - `Empty` is considered different from `0`, `False`, `""`, and `vbNullString`. - Object references are compared by identity (the **Is** operator); default-member values are not retrieved. -- `Null` is never equal to anything, not even to itself — use [**IsNull**](#isnull) / [**IsNotNull**](#isnotnull) to test for it. +- `Null` is never equal to anything, not even to itself --- use [**IsNull**](#isnull) / [**IsNotNull**](#isnotnull) to test for it. ```tb ' All of these fail under Exact: @@ -40,7 +40,7 @@ Records that the test reached this point without failure. Syntax: **Exact.Succeed** -A test procedure that returns without any assertion having failed is reported as passing implicitly, so calling **Succeed** explicitly is rarely necessary. It is occasionally useful in branches that would otherwise look ambiguous about their outcome — for example, the body of a loop that should reach the end. +A test procedure that returns without any assertion having failed is reported as passing implicitly, so calling **Succeed** explicitly is rarely necessary. It is occasionally useful in branches that would otherwise look ambiguous about their outcome --- for example, the body of a loop that should reach the end. ### Fail @@ -51,7 +51,7 @@ Syntax: **Exact.Fail** [ *Message* ] *Message* : *optional* A **String** describing the failure, recorded together with the source location of the call. -Use **Fail** to mark code paths that should be unreachable in a passing test — most often after a call that is expected to raise an error, in a branch that runs when the call returned normally instead. +**Fail** marks code paths that should be unreachable in a passing test --- most often after a call that is expected to raise an error, in a branch that runs when the call returned normally instead. ```tb On Error Resume Next @@ -61,14 +61,14 @@ If Err.Number = 0 Then Exact.Fail "expected an error, got success" ### Inconclusive -Records the test as inconclusive — neither a pass nor a failure. +Records the test as inconclusive --- neither a pass nor a failure. Syntax: **Exact.Inconclusive** [ *Message* ] *Message* : *optional* A **String** describing why the result is inconclusive. -Use **Inconclusive** when a precondition for the test could not be established, so that the assertion logic that follows would be meaningless. A common case is a setup step that failed to find a required external resource — a test database, a configured network endpoint — where the test itself is neither passing nor failing on its own merits. +**Inconclusive** records that a precondition for the test could not be established and the assertion logic that follows would be meaningless. A common case is a setup step that failed to find a required external resource --- a test database, a configured network endpoint --- where the test itself is neither passing nor failing on its own merits. ## Equality @@ -87,7 +87,7 @@ Syntax: **Exact.AreEqual** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the comparison fails. -The comparison follows this module's [comparison semantics](#comparison-semantics) — *Expected* and *Actual* must have the same datatype, strings are compared case-sensitively, and `Empty`, `vbNullString`, and `""` are all distinct from one another. If either operand is **Null**, the assertion fails — `Null` is never equal to anything; use [**IsNull**](#isnull) to test for **Null** explicitly. +The comparison follows this module's [comparison semantics](#comparison-semantics) --- *Expected* and *Actual* must have the same datatype, strings are compared case-sensitively, and `Empty`, `vbNullString`, and `""` are all distinct from one another. If either operand is **Null**, the assertion fails --- `Null` is never equal to anything; use [**IsNull**](#isnull) to test for **Null** explicitly. ### AreNotEqual @@ -104,11 +104,11 @@ Syntax: **Exact.AreNotEqual** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the values are equal. -Comparison uses this module's [comparison semantics](#comparison-semantics). If either operand is **Null**, the assertion passes — `Null` is never equal to anything. +Comparison uses this module's [comparison semantics](#comparison-semantics). If either operand is **Null**, the assertion passes --- `Null` is never equal to anything. ### AreSame -Asserts that *Actual* and *Expected* refer to the *same* object — equivalent to `Expected Is Actual`. +Asserts that *Actual* and *Expected* refer to the *same* object --- equivalent to `Expected Is Actual`. Syntax: **Exact.AreSame** *Expected*, *Actual* [, *Message* ] @@ -121,11 +121,11 @@ Syntax: **Exact.AreSame** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the references differ. -Reference identity is independent of the module's other comparison rules — **AreSame** always uses the **Is** operator, never default-member equality. To compare values rather than references, use [**AreEqual**](#areequal). +Reference identity is independent of the module's other comparison rules --- **AreSame** always uses the **Is** operator, never default-member equality. To compare values rather than references, use [**AreEqual**](#areequal). ### AreNotSame -Asserts that *Actual* and *Expected* refer to *different* objects — equivalent to `Expected IsNot Actual`. +Asserts that *Actual* and *Expected* refer to *different* objects --- equivalent to `Expected IsNot Actual`. Syntax: **Exact.AreNotSame** *Expected*, *Actual* [, *Message* ] @@ -147,7 +147,7 @@ Asserts that *Condition* evaluates to **True**. Syntax: **Exact.IsTrue** *Condition* [, *Message* ] *Condition* -: *required* A **Variant** holding the condition to test. The value is interpreted as a **Boolean** — zero is **False**, any non-zero value is **True**. +: *required* A **Variant** holding the condition to test. The value is interpreted as a **Boolean** --- zero is **False**, any non-zero value is **True**. *Message* : *optional* A **String** included in the failure record if the condition is **False**. @@ -166,7 +166,7 @@ Syntax: **Exact.IsFalse** *Condition* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the condition is **True**. -If *Condition* is **Null**, the assertion fails — `Null` is neither **True** nor **False**. +If *Condition* is **Null**, the assertion fails --- `Null` is neither **True** nor **False**. ## Reference and value state @@ -186,7 +186,7 @@ This is the object-reference test, equivalent to `Value Is Nothing`. To check fo ### IsNotNothing -Asserts that *Value* refers to an object — i.e. is *not* the **Nothing** reference. +Asserts that *Value* refers to an object --- i.e. is *not* the **Nothing** reference. Syntax: **Exact.IsNotNothing** *Value* [, *Message* ] @@ -243,7 +243,7 @@ Both arguments must support iteration via **For Each**. The assertion fails on t ### NotSequenceEquals -Asserts that *Actual* and *Expected* differ — they contain a different number of elements, or at least one pair of corresponding elements differs under this module's [comparison semantics](#comparison-semantics). +Asserts that *Actual* and *Expected* differ --- they contain a different number of elements, or at least one pair of corresponding elements differs under this module's [comparison semantics](#comparison-semantics). Syntax: **Exact.NotSequenceEquals** *Expected*, *Actual* [, *FailMessage* ] diff --git a/docs/Reference/Assert/Permissive.md b/docs/Reference/Assert/Permissive.md index 1f0cbc54..ac9623c6 100644 --- a/docs/Reference/Assert/Permissive.md +++ b/docs/Reference/Assert/Permissive.md @@ -8,18 +8,18 @@ has_toc: false # Permissive module {: .no_toc } -The **Permissive** module of the [**Assert**](.) package supplies assertions that compare values as if the comparison had been written directly in twinBASIC code, with case-insensitive string comparison. Object default members are evaluated. Use **Permissive** for tests where you don't care about case differences in strings — for example, asserting that an error message contains a particular phrase regardless of capitalisation — and you want object comparison to use the same default-member rules as `=`. +The **Permissive** module of the [**Assert**](.) package supplies assertions that compare values as if the comparison had been written directly in twinBASIC code, with case-insensitive string comparison. Object default members are evaluated. **Permissive** ignores case differences in strings --- for example, when asserting that an error message contains a particular phrase regardless of capitalisation --- and uses the same default-member rules as `=` for object comparison. * TOC {:toc} ## Comparison semantics -The four equality assertions in this module — [**AreEqual**](#areequal), [**AreNotEqual**](#arenotequal), [**SequenceEquals**](#sequenceequals), and [**NotSequenceEquals**](#notsequenceequals) — apply the rules listed below. The remaining assertions are unaffected. +The four equality assertions in this module --- [**AreEqual**](#areequal), [**AreNotEqual**](#arenotequal), [**SequenceEquals**](#sequenceequals), and [**NotSequenceEquals**](#notsequenceequals) --- apply the rules listed below. The remaining assertions are unaffected. - *String* comparisons are case-insensitive (regardless of the project's `Option Compare` setting). -- All other comparisons are evaluated as if the operands had been written either side of `=` in twinBASIC code — numeric promotions apply (`5` equals `5.0`), `vbNullString` and `""` are both empty strings, and object comparison retrieves and compares default members where they exist. -- `Null` is never equal to anything, not even to itself — use [**IsNull**](#isnull) / [**IsNotNull**](#isnotnull) to test for it. +- All other comparisons are evaluated as if the operands had been written either side of `=` in twinBASIC code --- numeric promotions apply (`5` equals `5.0`), `vbNullString` and `""` are both empty strings, and object comparison retrieves and compares default members where they exist. +- `Null` is never equal to anything, not even to itself --- use [**IsNull**](#isnull) / [**IsNotNull**](#isnotnull) to test for it. ```tb ' All pass under Permissive: @@ -36,7 +36,7 @@ Records that the test reached this point without failure. Syntax: **Permissive.Succeed** -A test procedure that returns without any assertion having failed is reported as passing implicitly, so calling **Succeed** explicitly is rarely necessary. It is occasionally useful in branches that would otherwise look ambiguous about their outcome — for example, the body of a loop that should reach the end. +A test procedure that returns without any assertion having failed is reported as passing implicitly, so calling **Succeed** explicitly is rarely necessary. It is occasionally useful in branches that would otherwise look ambiguous about their outcome --- for example, the body of a loop that should reach the end. ### Fail @@ -47,7 +47,7 @@ Syntax: **Permissive.Fail** [ *Message* ] *Message* : *optional* A **String** describing the failure, recorded together with the source location of the call. -Use **Fail** to mark code paths that should be unreachable in a passing test — most often after a call that is expected to raise an error, in a branch that runs when the call returned normally instead. +**Fail** marks code paths that should be unreachable in a passing test --- most often after a call that is expected to raise an error, in a branch that runs when the call returned normally instead. ```tb On Error Resume Next @@ -57,14 +57,14 @@ If Err.Number = 0 Then Permissive.Fail "expected an error, got success" ### Inconclusive -Records the test as inconclusive — neither a pass nor a failure. +Records the test as inconclusive --- neither a pass nor a failure. Syntax: **Permissive.Inconclusive** [ *Message* ] *Message* : *optional* A **String** describing why the result is inconclusive. -Use **Inconclusive** when a precondition for the test could not be established, so that the assertion logic that follows would be meaningless. A common case is a setup step that failed to find a required external resource — a test database, a configured network endpoint — where the test itself is neither passing nor failing on its own merits. +**Inconclusive** records that a precondition for the test could not be established and the assertion logic that follows would be meaningless. A common case is a setup step that failed to find a required external resource --- a test database, a configured network endpoint --- where the test itself is neither passing nor failing on its own merits. ## Equality @@ -83,7 +83,7 @@ Syntax: **Permissive.AreEqual** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the comparison fails. -The comparison follows this module's [comparison semantics](#comparison-semantics) — strings are compared case-insensitively, object comparison reads default members where they exist, and everything else uses normal twinBASIC equality (so numeric promotions apply and `vbNullString` matches `""`). If either operand is **Null**, the assertion fails — `Null` is never equal to anything; use [**IsNull**](#isnull) to test for **Null** explicitly. +The comparison follows this module's [comparison semantics](#comparison-semantics) --- strings are compared case-insensitively, object comparison reads default members where they exist, and everything else uses normal twinBASIC equality (so numeric promotions apply and `vbNullString` matches `""`). If either operand is **Null**, the assertion fails --- `Null` is never equal to anything; use [**IsNull**](#isnull) to test for **Null** explicitly. ### AreNotEqual @@ -100,11 +100,11 @@ Syntax: **Permissive.AreNotEqual** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the values are equal. -Comparison uses this module's [comparison semantics](#comparison-semantics). If either operand is **Null**, the assertion passes — `Null` is never equal to anything. +Comparison uses this module's [comparison semantics](#comparison-semantics). If either operand is **Null**, the assertion passes --- `Null` is never equal to anything. ### AreSame -Asserts that *Actual* and *Expected* refer to the *same* object — equivalent to `Expected Is Actual`. +Asserts that *Actual* and *Expected* refer to the *same* object --- equivalent to `Expected Is Actual`. Syntax: **Permissive.AreSame** *Expected*, *Actual* [, *Message* ] @@ -117,11 +117,11 @@ Syntax: **Permissive.AreSame** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the references differ. -Reference identity is independent of the module's other comparison rules — **AreSame** always uses the **Is** operator, never default-member equality. To compare values rather than references, use [**AreEqual**](#areequal). +Reference identity is independent of the module's other comparison rules --- **AreSame** always uses the **Is** operator, never default-member equality. To compare values rather than references, use [**AreEqual**](#areequal). ### AreNotSame -Asserts that *Actual* and *Expected* refer to *different* objects — equivalent to `Expected IsNot Actual`. +Asserts that *Actual* and *Expected* refer to *different* objects --- equivalent to `Expected IsNot Actual`. Syntax: **Permissive.AreNotSame** *Expected*, *Actual* [, *Message* ] @@ -143,7 +143,7 @@ Asserts that *Condition* evaluates to **True**. Syntax: **Permissive.IsTrue** *Condition* [, *Message* ] *Condition* -: *required* A **Variant** holding the condition to test. The value is interpreted as a **Boolean** — zero is **False**, any non-zero value is **True**. +: *required* A **Variant** holding the condition to test. The value is interpreted as a **Boolean** --- zero is **False**, any non-zero value is **True**. *Message* : *optional* A **String** included in the failure record if the condition is **False**. @@ -162,7 +162,7 @@ Syntax: **Permissive.IsFalse** *Condition* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the condition is **True**. -If *Condition* is **Null**, the assertion fails — `Null` is neither **True** nor **False**. +If *Condition* is **Null**, the assertion fails --- `Null` is neither **True** nor **False**. ## Reference and value state @@ -182,7 +182,7 @@ This is the object-reference test, equivalent to `Value Is Nothing`. To check fo ### IsNotNothing -Asserts that *Value* refers to an object — i.e. is *not* the **Nothing** reference. +Asserts that *Value* refers to an object --- i.e. is *not* the **Nothing** reference. Syntax: **Permissive.IsNotNothing** *Value* [, *Message* ] @@ -239,7 +239,7 @@ Both arguments must support iteration via **For Each**. The assertion fails on t ### NotSequenceEquals -Asserts that *Actual* and *Expected* differ — they contain a different number of elements, or at least one pair of corresponding elements differs under this module's [comparison semantics](#comparison-semantics). +Asserts that *Actual* and *Expected* differ --- they contain a different number of elements, or at least one pair of corresponding elements differs under this module's [comparison semantics](#comparison-semantics). Syntax: **Permissive.NotSequenceEquals** *Expected*, *Actual* [, *FailMessage* ] diff --git a/docs/Reference/Assert/Strict.md b/docs/Reference/Assert/Strict.md index b3cf763d..cd244e45 100644 --- a/docs/Reference/Assert/Strict.md +++ b/docs/Reference/Assert/Strict.md @@ -8,19 +8,19 @@ has_toc: false # Strict module {: .no_toc } -The **Strict** module of the [**Assert**](.) package supplies assertions that compare values as if the comparison had been written directly in twinBASIC code, with two exceptions: string comparisons are case-sensitive (regardless of the project's `Option Compare` setting), and object default members are not evaluated. Use **Strict** for tests that should match the language's normal equality semantics for numbers and primitives but want a guaranteed case-sensitive string compare and reference-style equality on objects. +The **Strict** module of the [**Assert**](.) package supplies assertions that compare values as if the comparison had been written directly in twinBASIC code, with two exceptions: string comparisons are case-sensitive (regardless of the project's `Option Compare` setting), and object default members are not evaluated. **Strict** matches the language's normal equality semantics for numbers and primitives, plus guarantees a case-sensitive string compare and reference-style equality on objects. * TOC {:toc} ## Comparison semantics -The four equality assertions in this module — [**AreEqual**](#areequal), [**AreNotEqual**](#arenotequal), [**SequenceEquals**](#sequenceequals), and [**NotSequenceEquals**](#notsequenceequals) — apply the rules listed below. The remaining assertions are unaffected. +The four equality assertions in this module --- [**AreEqual**](#areequal), [**AreNotEqual**](#arenotequal), [**SequenceEquals**](#sequenceequals), and [**NotSequenceEquals**](#notsequenceequals) --- apply the rules listed below. The remaining assertions are unaffected. - *String* comparisons are case-sensitive (regardless of the project's `Option Compare` setting). - Object references are compared by identity (the **Is** operator); default-member values are not retrieved. -- All other comparisons are evaluated as if the operands had been written either side of `=` in twinBASIC code — numeric promotions apply (`5` equals `5.0`), `vbNullString` and `""` are both empty strings, and so on. -- `Null` is never equal to anything, not even to itself — use [**IsNull**](#isnull) / [**IsNotNull**](#isnotnull) to test for it. +- All other comparisons are evaluated as if the operands had been written either side of `=` in twinBASIC code --- numeric promotions apply (`5` equals `5.0`), `vbNullString` and `""` are both empty strings, and so on. +- `Null` is never equal to anything, not even to itself --- use [**IsNull**](#isnull) / [**IsNotNull**](#isnotnull) to test for it. ```tb ' Pass under Strict (would fail under Exact): @@ -39,7 +39,7 @@ Records that the test reached this point without failure. Syntax: **Strict.Succeed** -A test procedure that returns without any assertion having failed is reported as passing implicitly, so calling **Succeed** explicitly is rarely necessary. It is occasionally useful in branches that would otherwise look ambiguous about their outcome — for example, the body of a loop that should reach the end. +A test procedure that returns without any assertion having failed is reported as passing implicitly, so calling **Succeed** explicitly is rarely necessary. It is occasionally useful in branches that would otherwise look ambiguous about their outcome --- for example, the body of a loop that should reach the end. ### Fail @@ -50,7 +50,7 @@ Syntax: **Strict.Fail** [ *Message* ] *Message* : *optional* A **String** describing the failure, recorded together with the source location of the call. -Use **Fail** to mark code paths that should be unreachable in a passing test — most often after a call that is expected to raise an error, in a branch that runs when the call returned normally instead. +**Fail** marks code paths that should be unreachable in a passing test --- most often after a call that is expected to raise an error, in a branch that runs when the call returned normally instead. ```tb On Error Resume Next @@ -60,14 +60,14 @@ If Err.Number = 0 Then Strict.Fail "expected an error, got success" ### Inconclusive -Records the test as inconclusive — neither a pass nor a failure. +Records the test as inconclusive --- neither a pass nor a failure. Syntax: **Strict.Inconclusive** [ *Message* ] *Message* : *optional* A **String** describing why the result is inconclusive. -Use **Inconclusive** when a precondition for the test could not be established, so that the assertion logic that follows would be meaningless. A common case is a setup step that failed to find a required external resource — a test database, a configured network endpoint — where the test itself is neither passing nor failing on its own merits. +**Inconclusive** records that a precondition for the test could not be established and the assertion logic that follows would be meaningless. A common case is a setup step that failed to find a required external resource --- a test database, a configured network endpoint --- where the test itself is neither passing nor failing on its own merits. ## Equality @@ -86,7 +86,7 @@ Syntax: **Strict.AreEqual** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the comparison fails. -The comparison follows this module's [comparison semantics](#comparison-semantics) — strings are compared case-sensitively, object references are compared by identity, and everything else uses normal twinBASIC equality (so numeric promotions apply and `vbNullString` matches `""`). If either operand is **Null**, the assertion fails — `Null` is never equal to anything; use [**IsNull**](#isnull) to test for **Null** explicitly. +The comparison follows this module's [comparison semantics](#comparison-semantics) --- strings are compared case-sensitively, object references are compared by identity, and everything else uses normal twinBASIC equality (so numeric promotions apply and `vbNullString` matches `""`). If either operand is **Null**, the assertion fails --- `Null` is never equal to anything; use [**IsNull**](#isnull) to test for **Null** explicitly. ### AreNotEqual @@ -103,11 +103,11 @@ Syntax: **Strict.AreNotEqual** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the values are equal. -Comparison uses this module's [comparison semantics](#comparison-semantics). If either operand is **Null**, the assertion passes — `Null` is never equal to anything. +Comparison uses this module's [comparison semantics](#comparison-semantics). If either operand is **Null**, the assertion passes --- `Null` is never equal to anything. ### AreSame -Asserts that *Actual* and *Expected* refer to the *same* object — equivalent to `Expected Is Actual`. +Asserts that *Actual* and *Expected* refer to the *same* object --- equivalent to `Expected Is Actual`. Syntax: **Strict.AreSame** *Expected*, *Actual* [, *Message* ] @@ -120,11 +120,11 @@ Syntax: **Strict.AreSame** *Expected*, *Actual* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the references differ. -Reference identity is independent of the module's other comparison rules — **AreSame** always uses the **Is** operator, never default-member equality. To compare values rather than references, use [**AreEqual**](#areequal). +Reference identity is independent of the module's other comparison rules --- **AreSame** always uses the **Is** operator, never default-member equality. To compare values rather than references, use [**AreEqual**](#areequal). ### AreNotSame -Asserts that *Actual* and *Expected* refer to *different* objects — equivalent to `Expected IsNot Actual`. +Asserts that *Actual* and *Expected* refer to *different* objects --- equivalent to `Expected IsNot Actual`. Syntax: **Strict.AreNotSame** *Expected*, *Actual* [, *Message* ] @@ -146,7 +146,7 @@ Asserts that *Condition* evaluates to **True**. Syntax: **Strict.IsTrue** *Condition* [, *Message* ] *Condition* -: *required* A **Variant** holding the condition to test. The value is interpreted as a **Boolean** — zero is **False**, any non-zero value is **True**. +: *required* A **Variant** holding the condition to test. The value is interpreted as a **Boolean** --- zero is **False**, any non-zero value is **True**. *Message* : *optional* A **String** included in the failure record if the condition is **False**. @@ -165,7 +165,7 @@ Syntax: **Strict.IsFalse** *Condition* [, *Message* ] *Message* : *optional* A **String** included in the failure record if the condition is **True**. -If *Condition* is **Null**, the assertion fails — `Null` is neither **True** nor **False**. +If *Condition* is **Null**, the assertion fails --- `Null` is neither **True** nor **False**. ## Reference and value state @@ -185,7 +185,7 @@ This is the object-reference test, equivalent to `Value Is Nothing`. To check fo ### IsNotNothing -Asserts that *Value* refers to an object — i.e. is *not* the **Nothing** reference. +Asserts that *Value* refers to an object --- i.e. is *not* the **Nothing** reference. Syntax: **Strict.IsNotNothing** *Value* [, *Message* ] @@ -242,7 +242,7 @@ Both arguments must support iteration via **For Each**. The assertion fails on t ### NotSequenceEquals -Asserts that *Actual* and *Expected* differ — they contain a different number of elements, or at least one pair of corresponding elements differs under this module's [comparison semantics](#comparison-semantics). +Asserts that *Actual* and *Expected* differ --- they contain a different number of elements, or at least one pair of corresponding elements differs under this module's [comparison semantics](#comparison-semantics). Syntax: **Strict.NotSequenceEquals** *Expected*, *Actual* [, *FailMessage* ] diff --git a/docs/Reference/Assert/index.md b/docs/Reference/Assert/index.md index 4051e4f6..e33e5de9 100644 --- a/docs/Reference/Assert/index.md +++ b/docs/Reference/Assert/index.md @@ -9,9 +9,9 @@ has_toc: false # Assert Package -The **Assert** built-in package supplies the assertion functions used to write unit tests for twinBASIC code. Each assertion checks an expected condition; on failure, it records a test failure with the call site and an optional message. The test runner — the twinBASIC IDE's Test Explorer, or any equivalent harness — collects those results, decides which tests passed, failed, or were skipped, and reports them. +The **Assert** built-in package supplies the assertion functions used to write unit tests for twinBASIC code. Each assertion checks an expected condition; on failure, it records a test failure with the call site and an optional message. The test runner --- the twinBASIC IDE's Test Explorer, or any equivalent harness --- collects those results, decides which tests passed, failed, or were skipped, and reports them. -The package's three modules — [**Exact**](Exact), [**Strict**](Strict), and [**Permissive**](Permissive) — expose the same fifteen assertion functions; only the *comparison semantics* differ. Pick the flavour that matches how strictly you want equality to be evaluated. +The package's three modules --- [**Exact**](Exact), [**Strict**](Strict), and [**Permissive**](Permissive) --- expose the same fifteen assertion functions; only the *comparison semantics* differ. Each flavour matches a different strictness level for equality evaluation. | Module | String comparisons | Numeric and other comparisons | |------------------------------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -19,7 +19,7 @@ The package's three modules — [**Exact**](Exact), [**Strict**](Strict), and [* | [**Strict**](Strict) | case-sensitive | evaluated as if the comparison were written directly in twinBASIC code; object default members are *not* evaluated | | [**Permissive**](Permissive) | case-insensitive | evaluated as if the comparison were written directly in twinBASIC code | -`Null` is never considered equal to anything — not even to itself — under any of the three flavours. To test for **Null** explicitly, use the [**IsNull**](Exact#isnull) / [**IsNotNull**](Exact#isnotnull) assertions rather than `AreEqual(..., Null)`. +`Null` is never considered equal to anything --- not even to itself --- under any of the three flavours. To test for **Null** explicitly, use the [**IsNull**](Exact#isnull) / [**IsNotNull**](Exact#isnotnull) assertions rather than `AreEqual(..., Null)`. ```tb Sub TestStringReverse() @@ -30,7 +30,7 @@ End Sub ## Calling convention -Every member of every module is tagged `[MustBeQualified(True)]` — calls *must* be written with the module name, even from inside a project that has imported the **Assert** package: +Every member of every module is tagged `[MustBeQualified(True)]` --- calls *must* be written with the module name, even from inside a project that has imported the **Assert** package: ```tb Strict.IsTrue x > 0 ' OK @@ -41,7 +41,7 @@ If a project references more than one package that exposes a module called **Str ## Debug-only -Every assertion is tagged `[DebugOnly(True)]` — the calls compile to *nothing* in release builds, in the same way that [**Debug.Print**](../../Core/Print) and the **Debug.Assert** statement do. A test runner therefore needs to build the project with debug enabled. +Every assertion is tagged `[DebugOnly(True)]` --- the calls compile to *nothing* in release builds, in the same way that [**Debug.Print**](../../Core/Print) and the **Debug.Assert** statement do. A test runner therefore needs to build the project with debug enabled. ## Modules @@ -53,10 +53,10 @@ Every assertion is tagged `[DebugOnly(True)]` — the calls compile to *nothing* Each module exposes the same fifteen functions, grouped here by purpose: -- **Diagnostic outcome** — **Succeed**, **Fail**, **Inconclusive** -- **Equality** — **AreEqual** / **AreNotEqual**, **AreSame** / **AreNotSame** -- **Boolean** — **IsTrue**, **IsFalse** -- **Reference and value state** — **IsNothing** / **IsNotNothing**, **IsNull** / **IsNotNull** -- **Sequence** — **SequenceEquals** / **NotSequenceEquals** +- **Diagnostic outcome** --- **Succeed**, **Fail**, **Inconclusive** +- **Equality** --- **AreEqual** / **AreNotEqual**, **AreSame** / **AreNotSame** +- **Boolean** --- **IsTrue**, **IsFalse** +- **Reference and value state** --- **IsNothing** / **IsNotNothing**, **IsNull** / **IsNotNull** +- **Sequence** --- **SequenceEquals** / **NotSequenceEquals** See the per-module pages for the full signatures and the comparison semantics that apply to each member. diff --git a/docs/Reference/CEF/CefBrowser/EnvironmentOptions.md b/docs/Reference/CEF/CefBrowser/EnvironmentOptions.md index 20e178cc..b0ca2069 100644 --- a/docs/Reference/CEF/CefBrowser/EnvironmentOptions.md +++ b/docs/Reference/CEF/CefBrowser/EnvironmentOptions.md @@ -9,9 +9,9 @@ has_toc: false # CefEnvironmentOptions class {: .no_toc } -Carries the host's pre-creation configuration for the CEF environment — runtime folder, user-data folder, and the optional debug-log destination. Surfaces on every [**CefBrowser**](.) control as its **EnvironmentOptions** property; the control instantiates one automatically before raising the [**Create**](.#create) event. +Pre-creation configuration for the CEF environment --- runtime folder, user-data folder, and the optional debug-log destination. Available on every [**CefBrowser**](.) control as its **EnvironmentOptions** property; the control instantiates one automatically before raising the [**Create**](.#create) event. -The fields below take effect only while the CEF runtime is being launched — that is, *before or during* the control's [**Create**](.#create) event. Assigning them after that point has no effect on the live environment. +The fields below take effect only while the CEF runtime is being launched --- that is, *before or during* the control's [**Create**](.#create) event. Assigning them after that point has no effect on the live environment. ```tb Private Sub CefBrowser1_Create() @@ -23,14 +23,14 @@ Private Sub CefBrowser1_Create() End Sub ``` -The type itself is `Private Class` — you reach instances only through the control's **EnvironmentOptions** property and cannot declare a variable typed as **CefEnvironmentOptions** from outside the package. +The type itself is `Private Class` --- instances are reachable only through the control's **EnvironmentOptions** property, and a variable typed as **CefEnvironmentOptions** cannot be declared from outside the package. ## Properties ### BrowserExecutableFolder {: .no_toc } -Path to the folder containing `libcef.dll` and its accompanying runtime files. **String**. Default: empty (the runtime is loaded from `%LocalAppData%\twinBASIC_CEF_Runtime\` — see [Installing runtime files](../#installing-runtime-files)). +Path to the folder containing `libcef.dll` and its accompanying runtime files. **String**. Default: empty (the runtime is loaded from `%LocalAppData%\twinBASIC_CEF_Runtime\` --- see [Installing runtime files](../#installing-runtime-files)). Set this to point at a portable side-by-side deployment, e.g. a CEF folder shipped beside the application executable: @@ -48,7 +48,7 @@ If `libcef.dll` is not found at the configured (or default) location, the [**Err Path to a writable file CEF will append its debug log to. **String**. Default: empty (no log file is written, regardless of [**LogSeverity**](#logseverity)). -Used together with [**LogSeverity**](#logseverity) — messages at or above the chosen severity are written to this file. The log is appended across runs; rotate or delete the file as needed. +Used together with [**LogSeverity**](#logseverity) --- messages at or above the chosen severity are written to this file. The log is appended across runs; rotate or delete the file as needed. ### LogSeverity {: .no_toc } @@ -60,9 +60,9 @@ Set to **CefLogWarning** or **CefLogError** when investigating runtime issues, a ### UserDataFolder {: .no_toc } -Path to the folder CEF uses for the user profile — cache, cookies, history, local storage, and so on. **String**. Default: empty (the runtime picks a folder under `%LocalAppData%\twinBASIC_CEF\\`). +Path to the folder CEF uses for the user profile --- cache, cookies, history, local storage, and so on. **String**. Default: empty (the runtime picks a folder under `%LocalAppData%\twinBASIC_CEF\\`). -Set a writable, application-specific path when the default would end up in a read-only location, or when multiple deployments of the same application must keep their profiles separate. The same folder cannot be opened by two CEF processes simultaneously — if it's already locked, the [**Error**](.#error) event fires with *"CEF cache path already locked by another process"*. +Set a writable, application-specific path when the default would end up in a read-only location, or when multiple deployments of the same application must keep their profiles separate. The same folder cannot be opened by two CEF processes simultaneously --- if it's already locked, the [**Error**](.#error) event fires with *"CEF cache path already locked by another process"*. ### See Also diff --git a/docs/Reference/CEF/CefBrowser/index.md b/docs/Reference/CEF/CefBrowser/index.md index a0800d4a..ec165809 100644 --- a/docs/Reference/CEF/CefBrowser/index.md +++ b/docs/Reference/CEF/CefBrowser/index.md @@ -8,7 +8,7 @@ has_toc: false # CefBrowser class {: .no_toc } -A **CefBrowser** is a twinBASIC control that hosts the Chromium Embedded Framework — drop one onto a [**Form**](../../VB/Form/) and Chromium renders web content inside its rectangle. Application code can navigate to URLs, run JavaScript, exchange messages with the loaded page, register virtual-host folders, and print the document to PDF. +A **CefBrowser** is a twinBASIC control that hosts the Chromium Embedded Framework --- drop one onto a [**Form**](../../VB/Form/) and Chromium renders web content inside its rectangle. Application code can navigate to URLs, run JavaScript, exchange messages with the loaded page, register virtual-host folders, and print the document to PDF. The control spawns a separate browser process the first time it is used in a session and communicates with it across an IPC channel; many properties and methods raise *"CefBrowser control is not ready"* (run-time error 5) when called before the [**Ready**](#ready) event has fired. @@ -27,7 +27,7 @@ Private Sub CefBrowser1_NavigationComplete( _ End Sub ``` -The control inherits the rect-dockable members (size, layout, **Anchors**, **Dock**) from `BaseControlRectDockable`. It does *not* inherit a focusable layer, so the keyboard / mouse / focus events you might find on [**WebView2**](../../WebView2/WebView2/) are not part of its API — keystrokes go straight into the page once Chromium has focus. +The control inherits the rect-dockable members (size, layout, **Anchors**, **Dock**) from `BaseControlRectDockable`. It does *not* inherit a focusable layer, so the keyboard / mouse / focus events available on [**WebView2**](../../WebView2/WebView2/) are not part of its API --- keystrokes go straight into the page once Chromium has focus. * TOC {:toc} @@ -39,34 +39,34 @@ A **CefBrowser** control progresses through three distinct phases, each triggere | Event | When | |--------------------------------|-------------------------------------------------------------------------------------------------------------------| | [**Create**](#create) | After the container window exists, before the CEF runtime is launched. Last chance to set [**EnvironmentOptions**](#environmentoptions). | -| [**Error**](#error) | The runtime could not be launched — typically because `libcef.dll` is missing or the user-data folder is locked. | +| [**Error**](#error) | The runtime could not be launched --- typically because `libcef.dll` is missing or the user-data folder is locked. | | [**Ready**](#ready) | The browser process is live and IPC has connected. The control is now fully functional. | Calling navigation, scripting, or setting accessors before [**Ready**](#ready) raises run-time error 5 with the message *"CefBrowser control is not ready."* Once **Ready** fires, the control auto-navigates to the [**DocumentURL**](#documenturl) field if it has a non-empty value (the design-time default is `https://www.twinbasic.com`). -The first **CefBrowser** to initialise in a process launches the shared browser helper executable; subsequent **CefBrowser** instances share that helper. Closing the last **CefBrowser** does not terminate the helper — it lingers for the life of the host process so that a future control can attach to it without re-launching. +The first **CefBrowser** to initialise in a process launches the shared browser helper executable; subsequent **CefBrowser** instances share that helper. Closing the last **CefBrowser** does not terminate the helper --- it lingers for the life of the host process so that a future control can attach to it without re-launching. ## Deferred startup -By default the control launches the browser helper as soon as the form is loaded (the `WS_VISIBLE` style is set on the host window and the first resize event triggers the helper). Set [**CreateInitialized**](#createinitialized) to **False** before the form loads, then call [**Initialize**](#initialize) at the moment you want the browser to start — useful when several **CefBrowser** controls live on tabs and you want to defer the cost until the tab is shown. +By default the control launches the browser helper as soon as the form is loaded (the `WS_VISIBLE` style is set on the host window and the first resize event triggers the helper). Set [**CreateInitialized**](#createinitialized) to **False** before the form loads, then call [**Initialize**](#initialize) when the browser should start --- useful when several **CefBrowser** controls live on tabs and the cost of launching the helper should be deferred until the tab is shown. ## JavaScript interop The control offers three families of BASIC ↔ JavaScript bridges: -- **Posting messages** — [**PostWebMessage**](#postwebmessage) sends a value to the page where it arrives via `window.chrome.webview.addEventListener('message', …)`. The page replies with `window.chrome.webview.postMessage(…)`, which fires the [**JsMessage**](#jsmessage) event. -- **Executing script** — [**JsRun**](#jsrun) calls a named JavaScript function and waits for the result, [**JsRunAsync**](#jsrunasync) calls one and fires [**JsAsyncResult**](#jsasyncresult) when the result arrives, and [**ExecuteScript**](#executescript) fires-and-forgets a snippet without awaiting a result. +- **Posting messages** --- [**PostWebMessage**](#postwebmessage) sends a value to the page where it arrives via `window.chrome.webview.addEventListener('message', …)`. The page replies with `window.chrome.webview.postMessage(…)`, which fires the [**JsMessage**](#jsmessage) event. +- **Executing script** --- [**JsRun**](#jsrun) calls a named JavaScript function and waits for the result, [**JsRunAsync**](#jsrunasync) calls one and fires [**JsAsyncResult**](#jsasyncresult) when the result arrives, and [**ExecuteScript**](#executescript) fires-and-forgets a snippet without awaiting a result. -Synchronous [**JsRun**](#jsrun) blocks the BASIC thread until the renderer replies — which means that re-entrancy from the page (a JavaScript handler that posts back into BASIC during the call) can cause a UI freeze. Use [**JsRunAsync**](#jsrunasync) whenever the call is non-trivial. +Synchronous [**JsRun**](#jsrun) blocks the BASIC thread until the renderer replies --- which means that re-entrancy from the page (a JavaScript handler that posts back into BASIC during the call) can cause a UI freeze. Use [**JsRunAsync**](#jsrunasync) whenever the call is non-trivial. ## Mapping virtual hostnames -[**SetVirtualHostNameToFolderMapping**](#setvirtualhostnametofoldermapping) installs a virtual hostname that serves files from a local folder — so the page can `fetch('https://my.app/index.html')` instead of `file:///...` (avoiding the `file://` origin's CORS restrictions). [**ClearVirtualHostNameToFolderMapping**](#clearvirtualhostnametofoldermapping) removes a mapping. +[**SetVirtualHostNameToFolderMapping**](#setvirtualhostnametofoldermapping) installs a virtual hostname that serves files from a local folder --- so the page can `fetch('https://my.app/index.html')` instead of `file:///...` (avoiding the `file://` origin's CORS restrictions). [**ClearVirtualHostNameToFolderMapping**](#clearvirtualhostnametofoldermapping) removes a mapping. Properties ---------- -The control inherits the standard rect-dockable members from `BaseControlRectDockable` — size, position, **Anchors**, **Dock**, **Container**, the design-time **Name** / **Index** / **Tag**. +The control inherits the standard rect-dockable members from `BaseControlRectDockable` --- size, position, **Anchors**, **Dock**, **Container**, the design-time **Name** / **Index** / **Tag**. ### Anchors {: .no_toc } @@ -86,7 +86,7 @@ Whether the browsing history has an entry ahead of the current document. **Boole ### CefMajorVersion {: .no_toc } -The CEF runtime major-version number selected at compile time (`49`, `109`, or `145`). **Long**. Read-only. Resolves from the `CEF_VERSION` conditional-compilation argument on the compiler-package reference — see [Supported runtimes](../#supported-runtimes). +The CEF runtime major-version number selected at compile time (`49`, `109`, or `145`). **Long**. Read-only. Resolves from the `CEF_VERSION` conditional-compilation argument on the compiler-package reference --- see [Supported runtimes](../#supported-runtimes). ### Container {: .no_toc } @@ -106,7 +106,7 @@ Whether the browser helper is launched automatically when the form first lays th ### DocumentTitle {: .no_toc } -The current document's `` text. **String**. Read-only. Updated each time the page changes its title — the [**DocumentTitleChanged**](#documenttitlechanged) event fires on every update. +The current document's `<title>` text. **String**. Read-only. Updated each time the page changes its title --- the [**DocumentTitleChanged**](#documenttitlechanged) event fires on every update. ### DocumentURL {: .no_toc } @@ -121,7 +121,7 @@ How the control docks against its container. A member of [**DockModeConstants**] ### EnvironmentOptions {: .no_toc } -The [**CefEnvironmentOptions**](EnvironmentOptions) object that configures the runtime — executable folder, user-data folder, log file, log severity. The control auto-creates one on initialization; assign to its fields before or during the [**Create**](#create) event for them to take effect. +The [**CefEnvironmentOptions**](EnvironmentOptions) object that configures the runtime --- executable folder, user-data folder, log file, log severity. The control auto-creates one on initialization; assign to its fields before or during the [**Create**](#create) event for them to take effect. ### Height {: .no_toc } @@ -131,7 +131,7 @@ The control's height. **Single**. Inherited. ### hWnd {: .no_toc } -The Win32 window handle of the *container* window that hosts the CEF surface — not the HWND of the Chromium browser tab itself, which lives in a separate process. **LongPtr**. Read-only. +The Win32 window handle of the *container* window that hosts the CEF surface --- not the HWND of the Chromium browser tab itself, which lives in a separate process. **LongPtr**. Read-only. ### Index {: .no_toc } @@ -207,7 +207,7 @@ Syntax: *object*.**ClearVirtualHostNameToFolderMapping** *hostName* ### ExecuteScript {: .no_toc } -Evaluates JavaScript in the page without waiting for it to finish and without returning its result. Use [**JsRun**](#jsrun) or [**JsRunAsync**](#jsrunasync) when you need the value. +Evaluates JavaScript in the page without waiting for it to finish and without returning its result. Use [**JsRun**](#jsrun) or [**JsRunAsync**](#jsrunasync) when the return value is needed. Syntax: *object*.**ExecuteScript** *jsCode* @@ -245,7 +245,7 @@ Calls a named JavaScript function with the given arguments and returns the resul Syntax: *object*.**JsRun** ( *FuncName*, [ *args* ] ) **As Variant** *FuncName* -: *required* A **String** naming the JavaScript function — e.g. `"document.querySelector"`. +: *required* A **String** naming the JavaScript function --- e.g. `"document.querySelector"`. *args* : *optional* Any number of **Variant** arguments. Each is JSON-encoded before being passed to the function. @@ -299,7 +299,7 @@ Syntax: *object*.**Move** *Left* [, *Top* [, *Width* [, *Height* ] ] ] ### Navigate {: .no_toc } -Loads a URL into the browser. Fires [**NavigationStarting**](#navigationstarting) and then [**NavigationComplete**](#navigationcomplete). The URI must include the protocol prefix (`http://`, `https://`, `file://`, …) — there is no automatic prefix insertion. +Loads a URL into the browser. Fires [**NavigationStarting**](#navigationstarting) and then [**NavigationComplete**](#navigationcomplete). The URI must include the protocol prefix (`http://`, `https://`, `file://`, …) --- there is no automatic prefix insertion. Syntax: *object*.**Navigate** *uri* @@ -428,21 +428,21 @@ Syntax: *object*\_**Create**( ) ### DocumentTitleChanged {: .no_toc } -Raised when the document changes its title — typically right after a navigation, but also when client-side JavaScript writes to `document.title`. Read [**DocumentTitle**](#documenttitle) for the new value. +Raised when the document changes its title --- typically right after a navigation, but also when client-side JavaScript writes to `document.title`. Read [**DocumentTitle**](#documenttitle) for the new value. Syntax: *object*\_**DocumentTitleChanged**( ) ### DOMContentLoaded {: .no_toc } -Raised when the page reaches the `DOMContentLoaded` lifecycle event — the DOM tree is built and JavaScript can safely traverse it, but external resources may still be loading. +Raised when the page reaches the `DOMContentLoaded` lifecycle event --- the DOM tree is built and JavaScript can safely traverse it, but external resources may still be loading. Syntax: *object*\_**DOMContentLoaded**( ) ### Error {: .no_toc } -Raised when the CEF runtime fails to launch — most commonly because `libcef.dll` was not found at the configured location, or because the user-data folder is locked by another process. +Raised when the CEF runtime fails to launch --- most commonly because `libcef.dll` was not found at the configured location, or because the user-data folder is locked by another process. Syntax: *object*\_**Error**( *code* **As Long**, *msg* **As String** ) @@ -481,7 +481,7 @@ Raised after a navigation initiated by [**Navigate**](#navigate), [**NavigateToS Syntax: *object*\_**NavigationComplete**( *IsSuccess* **As Boolean**, *WebErrorStatus* **As Long** ) > [!NOTE] -> *IsSuccess* and *WebErrorStatus* are part of the event signature but currently return placeholder values (`True` and `0`) — the underlying CEF callbacks that would populate them have not yet been connected. Use the document state ([**DocumentURL**](#documenturl), [**CanGoBack**](#cangoback)) to determine the outcome. +> *IsSuccess* and *WebErrorStatus* are part of the event signature but currently return placeholder values (`True` and `0`) --- the underlying CEF callbacks that would populate them have not yet been connected. Use the document state ([**DocumentURL**](#documenturl), [**CanGoBack**](#cangoback)) to determine the outcome. ### NavigationStarting {: .no_toc } @@ -524,7 +524,7 @@ Syntax: *object*\_**PrintToPdfCompleted**( ) ### PrintToPdfFailed {: .no_toc } -Raised when an earlier [**PrintToPdf**](#printtopdf) call fails — e.g. because the output path was not writable. +Raised when an earlier [**PrintToPdf**](#printtopdf) call fails --- e.g. because the output path was not writable. Syntax: *object*\_**PrintToPdfFailed**( ) @@ -538,7 +538,7 @@ Syntax: *object*\_**Ready**( ) ### SourceChanged {: .no_toc } -Raised when [**DocumentURL**](#documenturl) has been updated — typically after a navigation. Used to keep an address-bar control in sync with the browser. +Raised when [**DocumentURL**](#documenturl) has been updated --- typically after a navigation. Used to keep an address-bar control in sync with the browser. Syntax: *object*\_**SourceChanged**( *IsNewDocument* **As Boolean** ) @@ -554,7 +554,8 @@ End Sub ## See Also - [CefEnvironmentOptions](EnvironmentOptions) -- pre-creation configuration exposed through [**EnvironmentOptions**](#environmentoptions) -- [CefLogSeverity](../Enumerations/CefLogSeverity), [cefPrintOrientation](../Enumerations/cefPrintOrientation) -- the package's two user-facing enumerations +- [CefLogSeverity](../Enumerations/CefLogSeverity) -- the verbosity threshold for the CEF debug log +- [cefPrintOrientation](../Enumerations/cefPrintOrientation) -- page orientation passed to [**PrintToPdf**](#printtopdf) - [WebView2](../../WebView2/WebView2/) -- the WebView2-runtime counterpart with a larger feature set - [WebView2 parity](../#webview2-parity) -- features available on **WebView2** that are not yet exposed on **CefBrowser** - [ControlTypeConstants](../../VBRUN/Constants/ControlTypeConstants) -- where **vbCefBrowser** lives diff --git a/docs/Reference/CEF/Enumerations/CefLogSeverity.md b/docs/Reference/CEF/Enumerations/CefLogSeverity.md index 86dcacf9..9cbe501e 100644 --- a/docs/Reference/CEF/Enumerations/CefLogSeverity.md +++ b/docs/Reference/CEF/Enumerations/CefLogSeverity.md @@ -11,7 +11,7 @@ The minimum severity at which the CEF runtime records messages to its debug log. | Constant | Value | Description | |----------|-------|-------------| -| **CefLogDisable**{: #cefLogDisable } | 0 | Default — logging is disabled. | +| **CefLogDisable**{: #cefLogDisable } | 0 | Default --- logging is disabled. | | **CefLogVerbose**{: #cefLogVerbose } | 1 | All messages, including verbose tracing. | | **CefLogInfo**{: #cefLogInfo } | 2 | Informational messages and above. | | **CefLogWarning**{: #cefLogWarning } | 3 | Warnings and above. | diff --git a/docs/Reference/CEF/Enumerations/cefPrintOrientation.md b/docs/Reference/CEF/Enumerations/cefPrintOrientation.md index 9030eb89..9871212d 100644 --- a/docs/Reference/CEF/Enumerations/cefPrintOrientation.md +++ b/docs/Reference/CEF/Enumerations/cefPrintOrientation.md @@ -11,5 +11,5 @@ Page orientation passed to [**PrintToPdf**](../CefBrowser/#printtopdf) when writ | Constant | Value | Description | |----------|-------|-------------| -| **cefPrintPortrait**{: #cefPrintPortrait } | 0 | Default — pages are laid out with the long side vertical. | +| **cefPrintPortrait**{: #cefPrintPortrait } | 0 | Default --- pages are laid out with the long side vertical. | | **cefPrintLandscape**{: #cefPrintLandscape } | 1 | Pages are laid out with the long side horizontal. | diff --git a/docs/Reference/CEF/index.md b/docs/Reference/CEF/index.md index 1f9d2e0f..481dd333 100644 --- a/docs/Reference/CEF/index.md +++ b/docs/Reference/CEF/index.md @@ -10,9 +10,9 @@ has_toc: false # CEF Package {: .no_toc } -The **cefPackage** wraps the [Chromium Embedded Framework](https://chromiumembedded.github.io/cef/) and exposes it as an ordinary twinBASIC control. Drop a [**CefBrowser**](CefBrowser/) onto a form and a Chromium browser renders web content inside it — navigate to URLs, run JavaScript, print pages to PDF, and exchange messages with the loaded page. +The **cefPackage** wraps the [Chromium Embedded Framework](https://chromiumembedded.github.io/cef/) and exposes it as an ordinary twinBASIC control. Drop a [**CefBrowser**](CefBrowser/) onto a form and a Chromium browser renders web content inside it --- navigate to URLs, run JavaScript, print pages to PDF, and exchange messages with the loaded page. -The package is a built-in package shipped with twinBASIC, but the CEF runtime itself is distributed *separately* — applications must ship the matching runtime ZIP alongside the executable. See [Runtime files](#runtime-files) below. +The package is a built-in package shipped with twinBASIC, but the CEF runtime itself is distributed *separately* --- applications must ship the matching runtime ZIP alongside the executable. See [Runtime files](#runtime-files) below. > [!IMPORTANT] > The CEF package is currently in **BETA**. Several features available on [**WebView2**](../WebView2/) are not yet exposed; see [WebView2 parity](#webview2-parity) below. @@ -25,10 +25,10 @@ The package is a built-in package shipped with twinBASIC, but the CEF runtime it CEF and [**WebView2**](../WebView2/) both wrap a Chromium-based browser inside a twinBASIC control. CEF brings advantages that matter for some applications: - **Cross-platform ready.** CEF runs on Windows, Linux, and macOS. [**WebView2**](../WebView2/) is Windows-only. -- **Full control over the runtime stack.** The application targets a specific Chromium build and distributes it alongside the software. There is no runtime auto-update behind the developer's back, so behavior stays consistent across deployments. -- **Deeper runtime integration.** CEF allows hosting twinBASIC code inside the renderer / JavaScript process — something the locked-down WebView2 object model cannot do. +- **Full control over the runtime stack.** The application targets a specific Chromium build and distributes it alongside the software. There is no automatic runtime update outside the application's control, so behavior stays consistent across deployments. +- **Deeper runtime integration.** CEF allows hosting twinBASIC code inside the renderer / JavaScript process --- something the more restricted WebView2 object model cannot do. -Choose [**WebView2**](../WebView2/) when targeting only modern Windows and willing to rely on the system-installed Edge runtime; choose **CEF** when control over the Chromium version or cross-platform readiness matters. +[**WebView2**](../WebView2/) is the right fit when targeting only modern Windows and the system-installed Edge runtime is acceptable; **CEF** is preferable when control over the Chromium version or cross-platform readiness matters. ## Supported runtimes @@ -41,14 +41,14 @@ Three CEF versions are supported, each with a different Chromium baseline and di | **v145** | Windows 10+ | Recommended modern runtime. | > [!WARNING] -> Older Chromium versions should not generally be used for unrestricted internet browsing — they carry unpatched security vulnerabilities. They remain appropriate for tightly controlled environments where the browser loads only trusted local or internal content. +> Older Chromium versions should not generally be used for unrestricted internet browsing --- they have unpatched security vulnerabilities. They remain appropriate for tightly controlled environments where the browser loads only trusted local or internal content. The user picks a runtime in two places that must agree: -- **At compile time** — by adding the matching `[COMPILER PACKAGE] twinBASIC - Chromium Embedded Framework Package v<N>` reference to the project. This sets the `CEF_VERSION` conditional-compilation constant (49, 109, or 145) that the package's own sources compile against. [**CefBrowser.CefMajorVersion**](CefBrowser/#cefmajorversion) returns this value at run time. -- **At deploy time** — by shipping the matching runtime ZIP, extracted into [the discovery folder](#installing-runtime-files) or pointed at via [**EnvironmentOptions.BrowserExecutableFolder**](CefBrowser/EnvironmentOptions#browserexecutablefolder). +- **At compile time** --- by adding the matching `[COMPILER PACKAGE] twinBASIC - Chromium Embedded Framework Package v<N>` reference to the project. This sets the `CEF_VERSION` conditional-compilation constant (49, 109, or 145) that the package's own sources compile against. [**CefBrowser.CefMajorVersion**](CefBrowser/#cefmajorversion) returns this value at run time. +- **At deploy time** --- by shipping the matching runtime ZIP, extracted into [the discovery folder](#installing-runtime-files) or pointed at via [**EnvironmentOptions.BrowserExecutableFolder**](CefBrowser/EnvironmentOptions#browserexecutablefolder). -The runtime bitness must match the application bitness — a 32-bit application needs the 32-bit runtime ZIP, a 64-bit application needs the 64-bit ZIP. +The runtime bitness must match the application bitness --- a 32-bit application needs the 32-bit runtime ZIP, a 64-bit application needs the 64-bit ZIP. ## Runtime files @@ -85,7 +85,7 @@ At launch, [**CefBrowser**](CefBrowser/) searches for the runtime in this defaul ### Overriding the runtime location {: .no_toc } -To point at a different folder — for example a portable side-by-side deployment — assign [**EnvironmentOptions.BrowserExecutableFolder**](CefBrowser/EnvironmentOptions#browserexecutablefolder) before or during the [**Create**](CefBrowser/#create) event: +A different folder --- for example a portable side-by-side deployment --- is selected by assigning [**EnvironmentOptions.BrowserExecutableFolder**](CefBrowser/EnvironmentOptions#browserexecutablefolder) before or during the [**Create**](CefBrowser/#create) event: ```tb Private Sub CefBrowser1_Create() @@ -103,9 +103,9 @@ These [**WebView2**](../WebView2/) features are not yet exposed on **CefBrowser* - Methods: **OpenTaskManagerWindow**, **AddObject** (host-object publication for JavaScript), **AddWebResourceRequestedFilter** and the surrounding request-interception machinery. - Events: **AcceleratorKeyPressed**, **PermissionRequested**, **WebResourceRequested**, **ProcessFailed**, **ScriptDialogOpening**, **UserContextMenu**, **SuspendCompleted**, **SuspendFailed**, **DownloadStarting**, **NewWindowRequested**. -The [**NavigationComplete**](CefBrowser/#navigationcomplete) event has **IsSuccess** and **WebErrorStatus** parameters in its signature but currently returns placeholder values (`True` and `0`) — the underlying CEF callbacks that would populate them have not yet been connected. +The [**NavigationComplete**](CefBrowser/#navigationcomplete) event has **IsSuccess** and **WebErrorStatus** parameters in its signature but currently returns placeholder values (`True` and `0`) --- the underlying CEF callbacks that would populate them have not yet been connected. -The API will continue to grow; treat this list as a snapshot of the current beta and not a long-term limitation. +The API will continue to grow; this list is a snapshot of the current beta, not a long-term limitation. ## Classes @@ -121,7 +121,7 @@ The API will continue to grow; treat this list as a snapshot of the current beta - [Getting started](../../../Tutorials/CEF/Getting-Started) -- package reference, runtime download, install path - [Customize the UserDataFolder](../../../Tutorials/CEF/Customize-UserDataFolder) -- relocating the runtime's working folder -- [Re-entrancy](../../../Tutorials/CEF/Re-entrancy) -- the deferred-event model and the one place ([**JsRun**](CefBrowser/#jsrun)) you still have to think about it +- [Re-entrancy](../../../Tutorials/CEF/Re-entrancy) -- the deferred-event model and the one place ([**JsRun**](CefBrowser/#jsrun)) that still requires attention - [Building a browser shell](../../../Tutorials/CEF/Building-A-Browser-Shell) -- back / forward / reload / zoom / PDF - [Hosting local web assets](../../../Tutorials/CEF/Hosting-Local-Web-Assets) -- virtual-host folder mappings - [JavaScript interop](../../../Tutorials/CEF/JavaScript-Interop) -- messages and scripted calls between BASIC and the page diff --git a/docs/Reference/Categories.md b/docs/Reference/Categories.md index 0972b2ab..c5ad2fbf 100644 --- a/docs/Reference/Categories.md +++ b/docs/Reference/Categories.md @@ -49,7 +49,7 @@ Statements: * [On ... GoTo](../tB/Core/On-GoTo), [On ... GoSub](../tB/Core/On-GoSub) - transfer execution to a location selected by an expression * [Stop](../tB/Core/Stop) - interrupt execution -Inline conditional functions — expression-level alternatives to the **If...Then...Else** and **Select Case** statements above: +Inline conditional functions --- expression-level alternatives to the **If...Then...Else** and **Select Case** statements above: * [If](../tB/Modules/Interaction/If) - evaluate an expression and return one of two values; only the chosen branch is evaluated (twinBASIC addition) * [IIf](../tB/Modules/Interaction/IIf) - evaluate an expression and return one of two values; both branches are always evaluated diff --git a/docs/Reference/Controls.md b/docs/Reference/Controls.md index dce3edb3..42eb51ba 100644 --- a/docs/Reference/Controls.md +++ b/docs/Reference/Controls.md @@ -7,61 +7,61 @@ permalink: /tB/Controls # Controls -The standard set of UI control classes that ship with twinBASIC lives in the **VB** built-in package — see [VB Package](Packages/VB) for the package landing page. The classes below are grouped by purpose; each entry links to the per-class reference. +The standard set of UI control classes that ship with twinBASIC lives in the **VB** built-in package --- see [VB Package](Packages/VB) for the package landing page. The classes below are grouped by purpose; each entry links to the per-class reference. ## Forms and host classes -These classes are *containers* rather than controls in the strict sense — they host other controls and back the form/control designer in the IDE. +These classes are *containers* rather than controls in the strict sense --- they host other controls and back the form/control designer in the IDE. -- [Form](Packages/VB/Form/) — top-level window hosting controls, menus, and a drawing surface. -- [MDIForm](Packages/VB/MDIForm/) — top-level MDI parent that hosts MDI-child [Form](Packages/VB/Form/) instances inside a recessed client area. -- [UserControl](Packages/VB/UserControl/) — base class for designing a reusable ActiveX control in twinBASIC. -- [PropertyPage](Packages/VB/PropertyPage/) — container backing a single tab of a COM property-page dialog (the **(Custom)** popup on an ActiveX control's property browser). -- [Report](Packages/VB/Report/) — top-level window specialised for banded report layout, print preview, and printing. +- [Form](Packages/VB/Form/) -- top-level window hosting controls, menus, and a drawing surface. +- [MDIForm](Packages/VB/MDIForm/) -- top-level MDI parent that hosts MDI-child [Form](Packages/VB/Form/) instances inside a recessed client area. +- [UserControl](Packages/VB/UserControl/) -- base class for designing a reusable ActiveX control in twinBASIC. +- [PropertyPage](Packages/VB/PropertyPage/) -- container backing a single tab of a COM property-page dialog (the **(Custom)** popup on an ActiveX control's property browser). +- [Report](Packages/VB/Report/) -- top-level window specialised for banded report layout, print preview, and printing. ## Buttons and toggles -- [CommandButton](Packages/VB/CommandButton/) — push-button used to trigger an action. -- [CheckBox](Packages/VB/CheckBox/) — two- or three-state check box with an optional text caption. -- [CheckMark](Packages/VB/CheckMark/) — windowless check glyph that scales to fill its rectangle; no caption, no focus. -- [OptionButton](Packages/VB/OptionButton/) — radio-button; option buttons sharing a container form a mutually-exclusive group. +- [CommandButton](Packages/VB/CommandButton/) -- push-button used to trigger an action. +- [CheckBox](Packages/VB/CheckBox/) -- two- or three-state check box with an optional text caption. +- [CheckMark](Packages/VB/CheckMark/) -- windowless check glyph that scales to fill its rectangle; no caption, no focus. +- [OptionButton](Packages/VB/OptionButton/) -- radio-button; option buttons sharing a container form a mutually-exclusive group. ## Text and value input -- [TextBox](Packages/VB/TextBox/) — single-line or multi-line edit control, with optional password masking and digit-only input. -- [ComboBox](Packages/VB/ComboBox/) — edit field combined with a drop-down list of items. -- [ListBox](Packages/VB/ListBox/) — vertically-scrolling list of items, optionally multi-column and multi-select. -- [HScrollBar](Packages/VB/HScrollBar/) — stand-alone horizontal scroll bar. -- [VScrollBar](Packages/VB/VScrollBar/) — stand-alone vertical scroll bar. +- [TextBox](Packages/VB/TextBox/) -- single-line or multi-line edit control, with optional password masking and digit-only input. +- [ComboBox](Packages/VB/ComboBox/) -- edit field combined with a drop-down list of items. +- [ListBox](Packages/VB/ListBox/) -- vertically-scrolling list of items, optionally multi-column and multi-select. +- [HScrollBar](Packages/VB/HScrollBar/) -- stand-alone horizontal scroll bar. +- [VScrollBar](Packages/VB/VScrollBar/) -- stand-alone vertical scroll bar. ## File-system browsing These three controls are normally connected together to build a complete file picker. -- DriveListBox — drive picker. *Not yet documented.* -- [DirListBox](Packages/VB/DirListBox/) — directory-tree picker for a single path. -- [FileListBox](Packages/VB/FileListBox/) — file list for a single directory, filtered by wildcard and file-attribute toggles. +- DriveListBox --- drive picker. *Not yet documented.* +- [DirListBox](Packages/VB/DirListBox/) -- directory-tree picker for a single path. +- [FileListBox](Packages/VB/FileListBox/) -- file list for a single directory, filtered by wildcard and file-attribute toggles. ## Containers -- [Frame](Packages/VB/Frame/) — captioned container that groups related controls and scopes [OptionButton](Packages/VB/OptionButton/) groups. -- [MultiFrame](Packages/VB/MultiFrame/) — layout container that arranges a set of [Frame](Packages/VB/Frame/) controls in a horizontal or vertical strip. -- [PictureBox](Packages/VB/PictureBox/) — Win32 native control combining picture display, a drawing surface, and a child-control container. +- [Frame](Packages/VB/Frame/) -- captioned container that groups related controls and scopes [OptionButton](Packages/VB/OptionButton/) groups. +- [MultiFrame](Packages/VB/MultiFrame/) -- layout container that arranges a set of [Frame](Packages/VB/Frame/) controls in a horizontal or vertical strip. +- [PictureBox](Packages/VB/PictureBox/) -- Win32 native control combining picture display, a drawing surface, and a child-control container. ## Display-only -- [Label](Packages/VB/Label/) — windowless lightweight read-only text display, used for captions, status text, and keyboard mnemonics. -- [Image](Packages/VB/Image/) — windowless lightweight picture display; the small, efficient alternative to [PictureBox](Packages/VB/PictureBox/). -- [Line](Packages/VB/Line/) — windowless single straight line between two endpoints. -- [Shape](Packages/VB/Shape/) — windowless geometric primitive (rectangle, oval, circle, star, arrow, …) with configurable border, fill, and rotation. -- [QRCode](Packages/VB/QRCode/) — windowless QR-code renderer populated from a text or byte-array payload. +- [Label](Packages/VB/Label/) -- windowless lightweight read-only text display, used for captions, status text, and keyboard mnemonics. +- [Image](Packages/VB/Image/) -- windowless lightweight picture display; the small, efficient alternative to [PictureBox](Packages/VB/PictureBox/). +- [Line](Packages/VB/Line/) -- windowless single straight line between two endpoints. +- [Shape](Packages/VB/Shape/) -- windowless geometric primitive (rectangle, oval, circle, star, arrow, …) with configurable border, fill, and rotation. +- [QRCode](Packages/VB/QRCode/) -- windowless QR-code renderer populated from a text or byte-array payload. ## Menus -- [Menu](Packages/VB/Menu/) — item in a Win32 native menu — top-level entry on a [Form](Packages/VB/Form/)'s or [MDIForm](Packages/VB/MDIForm/)'s menu bar, a drop-down entry, or a separator. +- [Menu](Packages/VB/Menu/) -- item in a Win32 native menu --- top-level entry on a [Form](Packages/VB/Form/)'s or [MDIForm](Packages/VB/MDIForm/)'s menu bar, a drop-down entry, or a separator. ## Data and external content -- [Data](Packages/VB/Data/) — Win32 native control that opens a DAO recordset and exposes record-navigation buttons for bound controls. -- [OLE](Packages/VB/OLE/) — OLE container hosting a linked or embedded OLE Automation object (Word document, Excel sheet, …). -- [Timer](Packages/VB/Timer/) — non-visual control that raises a periodic event at a programmable interval. +- [Data](Packages/VB/Data/) -- Win32 native control that opens a DAO recordset and exposes record-navigation buttons for bound controls. +- [OLE](Packages/VB/OLE/) -- OLE container hosting a linked or embedded OLE Automation object (Word document, Excel sheet, …). +- [Timer](Packages/VB/Timer/) -- non-visual control that raises a periodic event at a programmable interval. diff --git a/docs/Reference/Core/AddressOf.md b/docs/Reference/Core/AddressOf.md index f9bd06e5..38856d13 100644 --- a/docs/Reference/Core/AddressOf.md +++ b/docs/Reference/Core/AddressOf.md @@ -18,23 +18,23 @@ Syntax: : The name of a [**Sub**](Sub), [**Function**](Function), or [**Property**](Property) procedure whose address is taken. *instance* -: *optional* (twinBASIC) An object reference whose member *procedurename* is targeted. The resulting pointer is bound to *instance*, so calling through it invokes the method on that specific object. +: *optional* (twinBASIC) An object reference whose member *procedurename* is targeted. The resulting pointer is bound to *instance*, so calling through it invokes the method on that specific object. -When a procedure name appears in an argument list, normally the procedure is *called* and the procedure's return value is passed. **AddressOf** suppresses the call and substitutes the procedure's address instead. The most common use is to install a callback in a Windows API — the API then invokes the procedure from outside your code, in a process known as a *callback*. +When a procedure name appears in an argument list, normally the procedure is *called* and the procedure's return value is passed. **AddressOf** suppresses the call and substitutes the procedure's address instead. The most common use is to install a callback in a Windows API --- the API then invokes the procedure from outside the project's code, in a process known as a *callback*. -The value **AddressOf** produces is bit-compatible with **LongPtr**, so it can be passed wherever a function pointer is expected — including legacy [**Declare**](Declare) parameters typed **As Long** or **As LongPtr**. When the destination type is a [**Delegate**](Delegate), the compiler additionally checks that the operand's signature matches the delegate's. +The value **AddressOf** produces is bit-compatible with **LongPtr**, so it can be passed wherever a function pointer is expected --- including legacy [**Declare**](Declare) parameters typed **As Long** or **As LongPtr**. When the destination type is a [**Delegate**](Delegate), the compiler additionally checks that the operand's signature matches the delegate's. -In classic VBA, *procedurename* must name a procedure in a standard [**Module**](Module) of the current project; the destination parameter must be typed **As Long**; and the resulting pointer can only be invoked by code outside Basic (e.g. a DLL). twinBASIC lifts each of these restrictions — see [twinBASIC enhancements](#twinbasic-enhancements) below. +In classic VBA, *procedurename* must name a procedure in a standard [**Module**](Module) of the current project; the destination parameter must be typed **As Long**; and the resulting pointer can only be invoked by code outside Basic (e.g. a DLL). twinBASIC lifts each of these restrictions --- see [twinBASIC enhancements](#twinbasic-enhancements) below. -> [!NOTE] -> Errors raised inside a callback cannot propagate back to the foreign caller — the API runs outside your project's error-handling chain. Place `On Error Resume Next` (or an explicit handler) at the top of any procedure used as an **AddressOf** target. +> [!IMPORTANT] +> Errors raised inside a callback cannot propagate back to the foreign caller --- the API runs outside the project's error-handling chain. Place `On Error Resume Next` (or an explicit handler) at the top of any procedure used as an **AddressOf** target. ### twinBASIC enhancements - **Indirect calls back through Basic.** A delegate variable holding an **AddressOf** value can be called directly: `Dim op As Operation = AddressOf Add: r = op(5, 6)`. Classic VBA can pass such pointers between procedures but cannot invoke through them inside Basic. See [**Delegate**](Delegate). -- **Class, form, and user-control members.** **AddressOf** accepts methods declared on a class, form, or user-control. Take a pointer to an instance method by qualifying the name with the object reference: `AddressOf myInstance.MyMethod`. The resulting pointer remembers the instance — calling through it dispatches to that object. +- **Class, form, and user-control members.** **AddressOf** accepts methods declared on a class, form, or user-control. Take a pointer to an instance method by qualifying the name with the object reference: `AddressOf myInstance.MyMethod`. The resulting pointer remembers the instance --- calling through it dispatches to that object. - **CDecl callbacks.** Mark both the target procedure and the matching [**Delegate**](Delegate) (or [**Declare**](Declare) parameter) with **CDecl** to model `cdecl` callbacks. Classic VBA's **AddressOf** is hard-wired to `__stdcall`. See [API Declarations](../../Features/Advanced/API-Declarations#cdecl-callbacks). -- **No `FARPROC` shim needed.** Assigning a function pointer to a local variable is direct — `Dim lpfn As LongPtr = AddressOf MyFunc` — without writing an intermediate forwarding procedure. +- **No `FARPROC` shim needed.** Assigning a function pointer to a local variable is direct --- `Dim lpfn As LongPtr = AddressOf MyFunc` --- without writing an intermediate forwarding procedure. ### Example diff --git a/docs/Reference/Core/Alias.md b/docs/Reference/Core/Alias.md index 21c83ddd..30d01202 100644 --- a/docs/Reference/Core/Alias.md +++ b/docs/Reference/Core/Alias.md @@ -6,7 +6,7 @@ permalink: /tB/Core/Alias # Alias {: .no_toc } -Declares an alternative name for an intrinsic type, user-defined [**Type**](Type), [**Interface**](Interface), or another **Alias**. The alias and the original type are interchangeable — assigning between them is not a type mismatch. Comparable to `typedef` in C/C++. +Declares an alternative name for an intrinsic type, user-defined [**Type**](Type), [**Interface**](Interface), or another **Alias**. The alias and the original type are interchangeable --- assigning between them is not a type mismatch. Comparable to `typedef` in C/C++. > [!NOTE] > The **Alias** statement is a twinBASIC extension. It has no equivalent in classic VBA, where the only use of the **Alias** keyword is to name a DLL entry point in a [**Declare**](Declare) statement. @@ -15,10 +15,10 @@ Syntax: > [ **Public** \| **Private** ] **Alias** *aliasname* **As** *type* **Public** -: *optional* The alias is exported to the type library of an ActiveX DLL or control, so consumers in other projects see *aliasname* itself. +: *optional* The alias is exported to the type library of an ActiveX DLL or control, so consumers in other projects see *aliasname* itself. **Private** -: *optional* The alias is visible only within the project. Usages of a **Private** alias are replaced with the underlying *type* during compilation, so *aliasname* never appears in the project's type library. +: *optional* The alias is visible only within the project. Usages of a **Private** alias are replaced with the underlying *type* during compilation, so *aliasname* never appears in the project's type library. *aliasname* : The name of the alias. Must be a valid twinBASIC identifier. @@ -26,7 +26,7 @@ Syntax: *type* : The original type. May be an intrinsic type, a user-defined [**Type**](Type), an [**Interface**](Interface), or another **Alias**. -**Alias** statements are valid only in `.twin` source files (not legacy `.bas` or `.cls` files), and must appear at file scope — outside of [**Module**](Module) and [**Class**](Class) blocks, alongside [**Interface**](Interface) and [**CoClass**](CoClass) declarations. +**Alias** statements are valid only in `.twin` source files (not legacy `.bas` or `.cls` files), and must appear at file scope --- outside of [**Module**](Module) and [**Class**](Class) blocks, alongside [**Interface**](Interface) and [**CoClass**](CoClass) declarations. ### Example diff --git a/docs/Reference/Core/And.md b/docs/Reference/Core/And.md index ba6b038e..faf84764 100644 --- a/docs/Reference/Core/And.md +++ b/docs/Reference/Core/And.md @@ -43,7 +43,7 @@ The **And** operator performs a bitwise comparison of identically positioned bit | 1 | 1 | 1 | > [!NOTE] -> **And** evaluates *both* operands every time, even when *expression1* alone determines the result. Use [**AndAlso**](AndAlso) when you want short-circuit evaluation — for example, when *expression2* is expensive, has side effects, or would fail without the guard provided by *expression1*. +> **And** evaluates *both* operands every time, even when *expression1* alone determines the result. Use [**AndAlso**](AndAlso) for short-circuit evaluation --- for example, when *expression2* is expensive, has side effects, or would fail without the guard provided by *expression1*. ### Example diff --git a/docs/Reference/Core/AndAlso.md b/docs/Reference/Core/AndAlso.md index 1e25a5a8..a366209d 100644 --- a/docs/Reference/Core/AndAlso.md +++ b/docs/Reference/Core/AndAlso.md @@ -23,7 +23,7 @@ Syntax: If *expression1* is **False**, *result* is **False** and *expression2* is not evaluated. Otherwise *expression2* is evaluated and its **Boolean** value becomes *result*. -This is the standard "short-circuit AND". It is useful when *expression2* depends on *expression1* having succeeded — for example, a null-check guarding a property access. +This is the standard "short-circuit AND". It is useful when *expression2* depends on *expression1* having succeeded --- for example, a null-check guarding a property access. ### Example diff --git a/docs/Reference/Core/Call.md b/docs/Reference/Core/Call.md index 124ee9b6..485f295e 100644 --- a/docs/Reference/Core/Call.md +++ b/docs/Reference/Core/Call.md @@ -7,7 +7,7 @@ vba_attribution: true # Call -{: no_toc } +{: .no_toc } Transfers control to a **Sub** [procedure](../Gloss#procedure), **Function** procedure, or dynamic-link library (DLL) procedure. @@ -25,9 +25,9 @@ Syntax: : The name of the procedure to call *argumentlist* -: *optional* A comma-delimited list of variables, arrays or expressions to pass to the procedure. Components of *argumentlist* may include the keywords **ByVal** or **ByRef** to describe how the arguments are to be passed to the called procedure. +: *optional* A comma-delimited list of variables, arrays or expressions to pass to the procedure. Components of *argumentlist* may include the keywords **ByVal** or **ByRef** to describe how the arguments are to be passed to the called procedure. -You are not required to use the **Call** keyword when calling a procedure. However, if you use the **Call** keyword to call a procedure that requires arguments, *argumentlist* must be enclosed in parentheses. If you omit the **Call** keyword, you also must omit the parentheses around *argumentlist*. If you use either **Call** syntax to call any intrinsic or user-defined function, the function's return value is discarded. +The **Call** keyword is not required when calling a procedure. However, when the **Call** keyword is used to call a procedure that requires arguments, *argumentlist* must be enclosed in parentheses. When the **Call** keyword is omitted, the parentheses around *argumentlist* must also be omitted. When either **Call** syntax is used to call any intrinsic or user-defined function, the function's return value is discarded. To pass a whole array to a procedure, use the array name followed by empty parentheses. diff --git a/docs/Reference/Core/Class.md b/docs/Reference/Core/Class.md index 4e817168..fd2ab941 100644 --- a/docs/Reference/Core/Class.md +++ b/docs/Reference/Core/Class.md @@ -6,9 +6,9 @@ permalink: /tB/Core/Class # Class -{: no_toc } +{: .no_toc } -Used to define a class. Classes are templates from which objects are created -- classes are object types, as opposed to value types. Objects are held by reference and are reference-counted. The memory an object occupies is freed when there are no more references to it -- when no variables in the process refer to them. +Defines a class. Classes are templates from which objects are created --- classes are object types, as opposed to value types. Objects are held by reference and are reference-counted. The memory an object occupies is freed when there are no more references to it --- when no variables in the process refer to them. Syntax: @@ -24,26 +24,26 @@ Syntax: [ArrayBoundsChecks](Attributes#arrayboundschecks), [ClassId](Attributes#classid), [COMCreatable](Attributes#comcreatable), [CustomControl](Attributes#customcontrol), [Description](Attributes#description), [FloatingPointErrorChecks](Attributes#floatingpointerrorchecks), [FormDesignerId](Attributes#formdesignerid), [Hidden](Attributes#hidden), [IntegerOverflowChecks](Attributes#integeroverflowchecks), [PredeclaredID](Attributes#predeclaredid) **Public** -: *optional* (twinBASIC) In an ActiveX project, marks the class as exported into the type library so that consumers in other projects can create and use it. +: *optional* (twinBASIC) In an ActiveX project, marks the class as exported into the type library so that consumers in other projects can create and use it. **Private** -: *optional* (twinBASIC) In an ActiveX project, withholds the class from the type library: it remains usable within the project but is not exported. The conventional pairing with [**CoClass**](CoClass) — a public **CoClass** as the consumer-visible contract paired with a `Private Class` as the hidden implementation — relies on this modifier. +: *optional* (twinBASIC) In an ActiveX project, withholds the class from the type library: it remains usable within the project but is not exported. The conventional pairing with [**CoClass**](CoClass) --- a public **CoClass** as the consumer-visible contract paired with a `Private Class` as the hidden implementation --- relies on this modifier. *name* : The identifier naming the class. **Of** *typevars* -: *optional* (twinBASIC) One or more type variable names, separated by commas, that make the class a *generic class*. Each type variable can be referenced in member declarations as if it were a regular type. See [Generics](../../Features/Language/Generics). +: *optional* (twinBASIC) One or more type variable names, separated by commas, that make the class a *generic class*. Each type variable can be referenced in member declarations as if it were a regular type. See [Generics](../../Features/Language/Generics). **Inherits** *baseclass* -: *optional* (twinBASIC) Names a single base class whose **Public** and [**Protected**](Protected) members are inherited by *name*. The **Inherits** line, when present, must appear immediately after the **Class** header and before any other member. **Inherits** enables [**Overridable**](Sub) / **Overrides** members, explicit `*baseclass*.New(...)` chained constructor calls from inside `Sub New`, and **Protected** member visibility. See [Inheritance](../../Features/Language/Inheritance). +: *optional* (twinBASIC) Names a single base class whose **Public** and [**Protected**](Protected) members are inherited by *name*. The **Inherits** line, when present, must appear immediately after the **Class** header and before any other member. **Inherits** enables [**Overridable**](Sub) / **Overrides** members, explicit `*baseclass*.New(...)` chained constructor calls from inside `Sub New`, and **Protected** member visibility. See [Inheritance](../../Features/Language/Inheritance). *classmember* : *optional* Any of the following: - [constant](../Gloss#constant) defined using [**Const**](Const), - [variable](../Gloss#variable) defined using [**Public**](Public), [**Protected**](Protected), [**Private**](Private), or [**Dim**](Dim), - - [procedure](../Gloss#procedure) defined using [**Sub**](Sub), [**Function**](Function), or [**Property**](Property) — including the special instance constructor `Sub New(`*args*`)`, which the runtime invokes when the class is created with [**New**](New), + - [procedure](../Gloss#procedure) defined using [**Sub**](Sub), [**Function**](Function), or [**Property**](Property) --- including the special instance constructor `Sub New(`*args*`)`, which the runtime invokes when the class is created with [**New**](New), - [user-defined type (UDTs)](../Gloss#user-defined-type) defined using [**Type**](Type), - (twinBASIC) [**Implements**](Implements) clauses, listing interfaces or classes whose members this class provides bodies for. diff --git a/docs/Reference/Core/Close.md b/docs/Reference/Core/Close.md index ca8ac848..5ef8ce9e 100644 --- a/docs/Reference/Core/Close.md +++ b/docs/Reference/Core/Close.md @@ -8,7 +8,7 @@ vba_attribution: true # Close {: .no_toc } -Concludes input/output (I/O) to a file opened using the **Open** statement. +Concludes input/output (I/O) to a file opened using the **Open** statement. Syntax: @@ -16,15 +16,15 @@ Syntax: The *filenumber* is any valid file number, given as an expression evaluating to an integer. The file numbers do not have to be constant. The **#** prefixes are optional. - **Close** - If you omit *filenumber* list, all active files opened by the **Open** statement are closed. + When the *filenumber* list is omitted, all active files opened by the **Open** statement are closed. > [!WARNING] > -> The parameterless form should be used only when shutting down/exiting the program, since it will close *all* open files that were opened elsewhere in the program. +> The parameterless form should be used only when shutting down/exiting the program, since it closes *all* open files that were opened elsewhere in the program. -When you close files that were opened for **Output** or **Append**, the final buffer of output is written to the operating system buffer for that file. All buffer space associated with the closed file is released. +When files opened for **Output** or **Append** are closed, the final buffer of output is written to the operating system buffer for that file. All buffer space associated with the closed file is released. -When the **Close** statement is executed, the association of a file with its file number ends. +When the **Close** statement is executed, the association of a file with its file number ends. ### Example diff --git a/docs/Reference/Core/CoClass.md b/docs/Reference/Core/CoClass.md index 50578afd..34aeb250 100644 --- a/docs/Reference/Core/CoClass.md +++ b/docs/Reference/Core/CoClass.md @@ -19,7 +19,7 @@ Syntax: > **End CoClass** *attributes* -: *optional* Coclass-level attributes. See [Available attributes](#available-attributes) below. +: *optional* Coclass-level attributes. See [Available attributes](#available-attributes) below. *name* : The identifier naming the coclass. @@ -28,21 +28,21 @@ Syntax: : An [**Interface**](Interface) defined in the project (or imported from a referenced type library) that the coclass exposes. A coclass must list at least one interface and may list several. *member-attributes* -: *optional* Per-interface markers, principally: +: *optional* Per-interface markers, principally: - - `[Default]` — marks an interface as the default interface of the coclass. It is conventional and highly recommended to mark exactly one interface as `[Default]`. - - `[Source]` — marks an interface as a source interface (an outgoing/event interface). Combine with `[Default]` (`[Default, Source]`) to mark the default event interface. + - `[Default]` --- marks an interface as the default interface of the coclass. It is conventional and highly recommended to mark exactly one interface as `[Default]`. + - `[Source]` --- marks an interface as a source interface (an outgoing/event interface). Combine with `[Default]` (`[Default, Source]`) to mark the default event interface. **CoClass** blocks are valid only in `.twin` source files (not legacy `.bas` or `.cls` files), and must appear *before* the [**Class**](Class) or [**Module**](Module) statement in the file. ### Available attributes -- `[CoClassId("...")]` — fixes the CLSID for the coclass (a string GUID). Set this on any public/exported coclass so consumers in other projects bind to a stable identity. -- `[Description("text")]` — exposed as the `helpstring` in the type library. -- `[ComCreatable(True/False)]` — indicates whether the coclass can be created with **New**. `True` by default. -- `[AppObject]` — marks the class as part of the global namespace. Use only when you fully understand the implication. -- `[Hidden]` — hides the coclass from IntelliSense and similar lists. -- `[CoClassCustomConstructor("ModuleName.FunctionName")]` — names a factory function (returning `HRESULT` and producing the new instance via an out parameter) used in place of the default `New` behavior. The factory may construct any private class that implements the coclass's interfaces. +- `[CoClassId("...")]` --- fixes the CLSID for the coclass (a string GUID). Set this on any public/exported coclass so consumers in other projects bind to a stable identity. +- `[Description("text")]` --- exposed as the `helpstring` in the type library. +- `[ComCreatable(True/False)]` --- indicates whether the coclass can be created with **New**. `True` by default. +- `[AppObject]` --- marks the class as part of the global namespace. Use only when the implications are fully understood. +- `[Hidden]` --- hides the coclass from IntelliSense and similar lists. +- `[CoClassCustomConstructor("ModuleName.FunctionName")]` --- names a factory function (returning `HRESULT` and producing the new instance via an out parameter) used in place of the default `New` behavior. The factory may construct any private class that implements the coclass's interfaces. ### Example diff --git a/docs/Reference/Core/Comparison-Operators.md b/docs/Reference/Core/Comparison-Operators.md index 96ac9bca..6bedc276 100644 --- a/docs/Reference/Core/Comparison-Operators.md +++ b/docs/Reference/Core/Comparison-Operators.md @@ -47,7 +47,7 @@ The following table lists the comparison operators and the conditions that deter > [!NOTE] > The [**Is**](Is) and [**Like**](Like) operators have their own dedicated comparison semantics and are documented separately. -The `=` symbol is also the assignment operator (`*variable* = *expression*`). The context — whether `=` appears in an expression or at the top of a statement — determines which meaning applies; you do not need to choose between them explicitly. +The `=` symbol is also the assignment operator (`*variable* = *expression*`). The context --- whether `=` appears in an expression or at the top of a statement --- determines which meaning applies; no explicit choice between them is required. When comparing two expressions, determining whether they are being compared as numbers or as strings can be non-obvious. The following table shows how the expressions are compared, or the result when either expression is not a **Variant**: @@ -74,7 +74,7 @@ If *expression1* and *expression2* are both **Variant** expressions, their under When a **Single** is compared to a **Double**, the **Double** is rounded to the precision of the **Single**. If a **Currency** is compared with a **Single** or **Double**, the **Single** or **Double** is converted to a **Currency**. For **Currency**, any fractional value less than `.0001` may be lost, which can cause two values to compare as equal when they are not. -String comparisons are governed by the module's [**Option Compare**](Option) setting — **Binary** (the default; case-sensitive, ordinal) or **Text** (case-insensitive, locale-sensitive). +String comparisons are governed by the module's [**Option Compare**](Option) setting --- **Binary** (the default; case-sensitive, ordinal) or **Text** (case-insensitive, locale-sensitive). ### Example diff --git a/docs/Reference/Core/Concat.md b/docs/Reference/Core/Concat.md index ee67b597..5f8983dd 100644 --- a/docs/Reference/Core/Concat.md +++ b/docs/Reference/Core/Concat.md @@ -27,14 +27,14 @@ If an *expression* is not a string, it is converted to a **String** variant. The If both expressions are **Null**, *result* is **Null**. However, if only one *expression* is **Null**, that expression is treated as a zero-length string (`""`) when concatenated with the other expression. Any expression that is **Empty** is also treated as a zero-length string. -Prefer **&** over [**+**](Plus) for joining strings: **+** is also the addition operator, so its meaning depends on the operand types and can silently switch between arithmetic and concatenation. **&** is unambiguous — it always concatenates. +Prefer **&** over [**+**](Plus) for joining strings: **+** is also the addition operator, so its meaning depends on the operand types and can silently switch between arithmetic and concatenation. **&** is unambiguous --- it always concatenates. > [!NOTE] > When **&** immediately follows a variable name (for example `x&`), it is parsed as the **Long** type-suffix on the identifier rather than the concatenation operator. Always put a space before **&** when concatenating: `Result = x & y`, not `Result = x& y`. ### Compound assignment -`x &= y` is the twinBASIC shorthand for `x = x & y`. *y* is converted to **String** before being appended; if both sides are already **String**, the result stays **String**. **&=** is a statement, not an expression — it does not produce a value. +`x &= y` is the twinBASIC shorthand for `x = x & y`. *y* is converted to **String** before being appended; if both sides are already **String**, the result stays **String**. **&=** is a statement, not an expression --- it does not produce a value. ```tb Dim Path As String = "C:\Users" diff --git a/docs/Reference/Core/Const.md b/docs/Reference/Core/Const.md index 4a40d127..23eb6ef0 100644 --- a/docs/Reference/Core/Const.md +++ b/docs/Reference/Core/Const.md @@ -7,7 +7,7 @@ vba_attribution: true # Const -{: no_toc } +{: .no_toc } Declares constants for use in place of literal values. @@ -24,11 +24,11 @@ Syntax: : *optional* Keyword used at the module level to declare constants that are available to all procedures in all modules. Not allowed in procedures. **Private** -: *optional* Keyword used at the class or module level to declare constants that are available only within the class or module where the declaration is made. Not allowed in procedures. +: *optional* Keyword used at the class or module level to declare constants that are available only within the class or module where the declaration is made. Not allowed in procedures. *constname* -: Name of the constant; follows standard variable naming conventions. +: *required* Name of the constant; follows standard variable naming conventions. *type* @@ -36,20 +36,19 @@ Syntax: *expression* -: Required. Literal, other constant, or any combination that includes all arithmetic or logical operators except **Is**. +: *required* Literal, other constant, or any combination that includes all arithmetic or logical operators except **Is**. -Constants are private by default. Within procedures, constants are always private; their visibility can't be changed. In standard modules, the default visibility of module-level constants can be changed by using the **Public** keyword. In class modules, however, constants can only be private and their visibility can't be changed by using the **Public** keyword. +Constants are private by default. Within procedures, constants are always private; their visibility can't be changed. In standard modules, the **Public** keyword can change the default visibility of module-level constants. In class modules, constants are always private; the **Public** keyword has no effect. To combine several constant declarations on the same line, separate each constant assignment with a comma. When constant declarations are combined in this way, the **Public** or **Private** keyword, if used, applies to all of them. -You can't use variables, user-defined functions, or intrinsic Visual Basic functions (such as **Chr**) in expressions assigned to constants. +Variables, user-defined functions, and intrinsic Visual Basic functions (such as **Chr**) cannot be used in expressions assigned to constants. -> [!NOTE] -> Constants can make your programs self-documenting and easy to modify. Unlike variables, constants can't be inadvertently changed while your program is running. +Constants can make programs self-documenting and easy to modify. Unlike variables, constants can't be inadvertently changed while the program is running. -If you don't explicitly declare the constant type by using **As** *type*, the constant has the data type that is most appropriate for *expression*. +When the constant type is not explicitly declared by using **As** *type*, the constant has the data type that is most appropriate for *expression*. -Constants declared in a **Sub**, **Function**, or **Property** procedure are local to that procedure. A constant declared outside a procedure is defined throughout the module in which it is declared. Use constants anywhere you can use an expression. +Constants declared in a **Sub**, **Function**, or **Property** procedure are local to that procedure. A constant declared outside a procedure is defined throughout the module in which it is declared. Constants can be used anywhere an expression is allowed. ### Example diff --git a/docs/Reference/Core/Continue.md b/docs/Reference/Core/Continue.md index 0504de61..ccc312fb 100644 --- a/docs/Reference/Core/Continue.md +++ b/docs/Reference/Core/Continue.md @@ -6,7 +6,7 @@ permalink: /tB/Core/Continue # Continue -{: no_toc } +{: .no_toc } Immediately begins the next iteration of the enclosing loop. @@ -25,7 +25,7 @@ While : Used within a [While](While-Wend) loop > [!NOTE] -> **Continue** is a twinBASIC extension. Classic VBA has no skip-iteration form for any loop construct — the closest equivalent is a forward [**GoTo**](GoTo) to a label placed just before the loop's terminator. +> **Continue** is a twinBASIC extension. Classic VBA has no skip-iteration form for any loop construct --- the closest equivalent is a forward [**GoTo**](GoTo) to a label placed just before the loop's terminator. ### Example diff --git a/docs/Reference/Core/Declare.md b/docs/Reference/Core/Declare.md index 4d523547..85fb2ab5 100644 --- a/docs/Reference/Core/Declare.md +++ b/docs/Reference/Core/Declare.md @@ -6,8 +6,9 @@ vba_attribution: true --- # Declare +{: .no_toc } -Used at the module level to declare references to external procedures in a dynamic-link library (DLL). +Declares references to external procedures in a dynamic-link library (DLL) at the module level. > [!NOTE] > @@ -30,9 +31,9 @@ Declare Sub... Syntax: - > [ *attributes* ] - > [ **Public** \| **Private** ] **Declare** [ **PtrSafe** ] **Sub** *name* **Lib** "*libname*" [ **(** [ *arglist* ] **)** ] + > [ **Public** \| **Private** ] **Declare** [ **PtrSafe** ] **Sub** *name* **Lib** "*libname*" [ **(** [ *arglist* ] **)** ] - > [ *attributes* ] - > [ **Public** \| **Private** ] **Declare** [ **PtrSafe** ] **Sub** *name* **Lib** "*libname*" **Alias** "*aliasname*" [ **(** [ *arglist* ] **)** ] + > [ **Public** \| **Private** ] **Declare** [ **PtrSafe** ] **Sub** *name* **Lib** "*libname*" **Alias** "*aliasname*" [ **(** [ *arglist* ] **)** ] - > [ *attributes* ] > [ **Public** \| **Private** ] **Declare** [ **PtrSafe** ] **Function** *name* **Lib** "*libname*" [ **(** [ *arglist* ] **)** ] [ **As** *type* ] - > [ *attributes* ] @@ -62,7 +63,7 @@ Syntax: : Name of the DLL or code resource that contains the declared procedure. **Alias** *aliasname* -: *optional* Indicates that the procedure being called has another name in the DLL. This is useful when the external procedure name is the same as a keyword. You can also use Alias when a DLL procedure has the same name as a public variable, constant, or any other procedure in the same scope. Alias is also useful if any characters in the DLL procedure name aren't allowed by the DLL naming convention. +: *optional* Indicates that the procedure being called has another name in the DLL. This is useful when the external procedure name is the same as a keyword. Alias also applies when a DLL procedure has the same name as a public variable, constant, or any other procedure in the same scope. Alias is also useful when any characters in the DLL procedure name aren't allowed by the DLL naming convention. *aliasname* names the procedure in the DLL or code resource. If the first character is not a number sign (**#**), *aliasname* is the name of the procedure's entry point in the DLL. If (**#**) is the first character, all characters that follow must indicate the ordinal number of the procedure's entry point. *arglist* @@ -87,18 +88,18 @@ Syntax: [ **Optional** ] [ **ByVal** \| **ByRef** ] [ **ParamArray** ] *varname* : *optional* Indicates that the argument is passed by reference. **ByRef** is the default unlike in Visual Basic .NET. **ParamArray** -: *optional* Used only as the last argument in arglist to indicate that the final argument is an **Optional** array of **Variant** elements. The **ParamArray** keyword allows you to provide an arbitrary number of arguments. The ParamArray keyword can't be used with **ByVal**, **ByRef**, or **Optional**. +: *optional* Used only as the last argument in arglist to indicate that the final argument is an **Optional** array of **Variant** elements. The **ParamArray** keyword permits passing an arbitrary number of arguments. The ParamArray keyword can't be used with **ByVal**, **ByRef**, or **Optional**. *varname* : Name of the variable representing the argument being passed to the procedure; follows standard variable naming conventions. **( )** -: Required for array variables. Indicates that *varname* is an array. +: Required for array variables. Indicates that *varname* is an array. *type* : *optional* Data type of the argument passed to the procedure; may be **Byte**, **Boolean**, **Integer**, **Long**, **LongLong**, **LongPtr**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (variable length only), **Object**, **Variant**, a user-defined type (UDT), or an object type. (**LongLong** is a valid declared type only on 64-bit platforms.) -If you include an argument list, the number and type of arguments are checked each time the procedure is called. The First sub in the following example takes one **Long** argument, wherease the Second sub takes no arguments: +When an argument list is included, the number and type of arguments are checked each time the procedure is called. The First sub in the following example takes one **Long** argument, whereas the Second sub takes no arguments: ```tb Declare Sub First Lib "MyLib" (X As Long) @@ -107,12 +108,12 @@ Declare Sub Second Lib "MyLib" () > [!NOTE] > -> - You can't have fixed-length strings in the argument list of a **Declare** statement; only variable-length strings can be passed to procedures. Fixed-length strings can appear as procedure arguments, but they are converted to variable-length strings before being passed. +> - Fixed-length strings cannot appear in the argument list of a **Declare** statement; only variable-length strings can be passed to procedures. Fixed-length strings can appear as procedure arguments, but they are converted to variable-length strings before being passed. > - The **vbNullString** constant is used when calling external procedures, where the external procedure requires a string whose value is zero. This is not the same thing as a zero-length string (""). ### Example -This example shows how the **Declare** statement is used at the module level of a standard module to declare a reference to an external procedure in a dynamic-link library (DLL). You can place the **Declare** statements in class modules if the **Declare** statements are **Private**. +This example shows how the **Declare** statement is used at the module level of a standard module to declare a reference to an external procedure in a dynamic-link library (DLL). **Declare** statements can be placed in class modules when they are **Private**. ```tb ' In 32-bit Microsoft Windows systems, specify the library USER32.DLL. diff --git a/docs/Reference/Core/Deftype.md b/docs/Reference/Core/Deftype.md index 2b177c06..08435672 100644 --- a/docs/Reference/Core/Deftype.md +++ b/docs/Reference/Core/Deftype.md @@ -61,16 +61,16 @@ Message = "Out of stack space." A **Def**_type_ statement affects only the module where it is used. The default data type for variables, arguments, and return types of items not declared explicitly and not covered by a **Def**_type_ statement is **Variant**. -When you specify a letter range, it usually defines the data type for variables that begin with letters in the first 128 characters of the character set. However, when you specify the range A-Z, you set the default to the specified data type for *all* names, including those starting with characters from the extended part of the character set (128-255). +A letter range usually defines the data type for variables that begin with letters in the first 128 characters of the character set. However, the range A-Z sets the default to the specified data type for *all* names, including those starting with characters from the extended part of the character set (128-255). -After the range A-Z has been specified, you can't further redefine subranges by using **Def**_type_ statements. Once a range has been specified, including a previously defined letter in another **Def**_type_ statement is an error. You can, however, explicitly specify the data type of any variable — defined or not — by using a [**Dim**](Dim) statement with an **As** *type* clause: +After the range A-Z has been specified, subranges cannot be further redefined by using **Def**_type_ statements. Once a range has been specified, including a previously defined letter in another **Def**_type_ statement is an error. The data type of any variable --- defined or not --- can still be explicitly specified by using a [**Dim**](Dim) statement with an **As** *type* clause: ```tb DefInt A-Z Dim TaxRate As Double ' explicit declaration overrides the default ``` -**Def**_type_ statements don't affect elements of user-defined types — those must be explicitly declared. +**Def**_type_ statements don't affect elements of user-defined types --- those must be explicitly declared. ### See Also diff --git a/docs/Reference/Core/Delegate.md b/docs/Reference/Core/Delegate.md index e99ec280..673dcd87 100644 --- a/docs/Reference/Core/Delegate.md +++ b/docs/Reference/Core/Delegate.md @@ -6,7 +6,7 @@ permalink: /tB/Core/Delegate # Delegate {: .no_toc } -Declares a function-pointer type — a named signature that variables, parameters, and UDT members can hold a *reference* to a callable matching. A delegate value is bit-compatible with **LongPtr**, but adds compile-time signature checking when it is assigned, passed, or called. +Declares a function-pointer type --- a named signature that variables, parameters, and UDT members can hold a *reference* to a callable matching. A delegate value is bit-compatible with **LongPtr**, but adds compile-time signature checking when it is assigned, passed, or called. > [!NOTE] > The **Delegate** statement is a twinBASIC extension. In classic VBA, function pointers are untyped **LongPtr** values produced by **AddressOf** and called indirectly through custom mechanisms (`DispCallFunc`, `CallWindowProc` shims, etc.). @@ -15,26 +15,26 @@ Syntax: > [ **Public** \| **Private** ] **Delegate Function** *name* [ **CDecl** ] **(** [ *arglist* ] **)** **As** *type* **Public** -: *optional* In an ActiveX project, exports the delegate type to the type library so consumers in other projects see *name*. +: *optional* In an ActiveX project, exports the delegate type to the type library so consumers in other projects see *name*. **Private** -: *optional* Withholds the delegate from the type library; usable only within the project. +: *optional* Withholds the delegate from the type library; usable only within the project. *name* : The identifier naming the delegate type. Must be a valid twinBASIC identifier. **CDecl** -: *optional* Marks the delegate as using the C calling convention (`cdecl` — caller cleans the stack), used to model callbacks expected by C-runtime APIs such as `qsort`. The default is `stdcall`. See [API Declarations](../../Features/Advanced/API-Declarations#cdecl-callbacks). +: *optional* Marks the delegate as using the C calling convention (`cdecl` --- caller cleans the stack), used to model callbacks expected by C-runtime APIs such as `qsort`. The default is `stdcall`. See [API Declarations](../../Features/Advanced/API-Declarations#cdecl-callbacks). *arglist* -: *optional* Parameter signature, written exactly as for a [**Sub**](Sub) or [**Function**](Function) — comma-separated `[ ByVal | ByRef ] [ Optional ] *varname* [ As *type* ]` parts. +: *optional* Parameter signature, written exactly as for a [**Sub**](Sub) or [**Function**](Function) --- comma-separated `[ ByVal | ByRef ] [ Optional ] *varname* [ As *type* ]` parts. *type* : Return type of the delegate's signature. After the declaration, *name* may be used wherever a type is allowed: to declare variables and parameters of function-pointer type, as the type of a member of a [**Type**](Type) (UDT), or as a parameter type in a [**Declare**](Declare) statement or an [**Interface**](Interface) member. -A delegate value is normally produced by **AddressOf**, which yields a delegate-typed reference to a regular procedure with a matching signature. For backwards compatibility, a delegate variable can also be assigned a plain **LongPtr** address obtained by other means — the value passes through unchecked. A delegate variable is called like a function: `result = myDelegate(arg1, arg2)`. +A delegate value is normally produced by **AddressOf**, which yields a delegate-typed reference to a regular procedure with a matching signature. For backwards compatibility, a delegate variable can also be assigned a plain **LongPtr** address obtained by other means --- the value passes through unchecked. A delegate variable is called like a function: `result = myDelegate(arg1, arg2)`. ### Example diff --git a/docs/Reference/Core/Dim.md b/docs/Reference/Core/Dim.md index e49cbce3..95162850 100644 --- a/docs/Reference/Core/Dim.md +++ b/docs/Reference/Core/Dim.md @@ -6,7 +6,7 @@ vba_attribution: true --- # Dim -{: no_toc } +{: .no_toc } Declares variables and allocates storage space. @@ -14,27 +14,27 @@ Syntax: **Dim** [ **WithEvents** ] *varname* [ **(** [ *subscripts* ] **)** ] [ **WithEvents** -: *optional* Keyword that specifies that *varname* is an object variable used to respond to events triggered by an ActiveX object. **WithEvents** is valid only in class modules. You can declare as many individual variables as you like by using **WithEvents**, but you can't create arrays with **WithEvents**. You can't use **New** with **WithEvents**. +: *optional* Keyword that specifies that *varname* is an object variable used to respond to events triggered by an ActiveX object. **WithEvents** is valid only in class modules. Any number of individual variables may be declared by using **WithEvents**, but arrays cannot be declared with **WithEvents**. **New** cannot be combined with **WithEvents**. *varname* -: Name of the variable; follows standard variable naming conventions. +: Name of the variable; follows standard variable naming conventions. *subscripts* -: *optional* Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. +: *optional* Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. **New** -: *optional* Keyword that enables implicit creation of an object. If you use **New** when declaring the object variable, a new instance of the object is created on first reference to it, so you don't have to use the **Set** statement to assign the object reference. The **New** keyword can't be used to declare variables of any intrinsic data type or to declare instances of dependent objects, and it can't be used with **WithEvents**. +: *optional* Keyword that enables implicit creation of an object. When **New** is used to declare the object variable, a new instance of the object is created on first reference to it, so the **Set** statement is not required to assign the object reference. The **New** keyword can't be used to declare variables of any intrinsic data type or to declare instances of dependent objects, and it can't be used with **WithEvents**. *type* -: *optional*. Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **LongLong**, **LongPtr**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type (UDT), an object type, or **Any** (twinBASIC; type is inferred from *expression* — see [Type Inference](../../Features/Language/Type-Inference)). Use a separate **As** *type* clause for each variable you declare. +: *optional*. Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **LongLong**, **LongPtr**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type (UDT), an object type, or **Any** (twinBASIC; type is inferred from *expression* --- see [Type Inference](../../Features/Language/Type-Inference)). Use a separate **As** *type* clause for each declared variable. *expression* -: *optional*. (twinBASIC) Initial value assigned to the variable at declaration. Equivalent to a separate assignment statement immediately after the **Dim** — `Dim i As Long = 1` is the same as `Dim i As Long: i = 1`. For object types, `= New *type* ( *args* )` constructs an instance (and may pass custom-constructor arguments). When *type* is **Any**, *expression* is required and determines the inferred type. See [Inline Variable Initialization](../../Features/Language/Inline-Initialization). +: *optional*. (twinBASIC) Initial value assigned to the variable at declaration. Equivalent to a separate assignment statement immediately after the **Dim** --- `Dim i As Long = 1` is the same as `Dim i As Long: i = 1`. For object types, `= New *type* ( *args* )` constructs an instance (and may pass custom-constructor arguments). When *type* is **Any**, *expression* is required and determines the inferred type. See [Inline Variable Initialization](../../Features/Language/Inline-Initialization). Variables declared with **Dim** at the module level are available to all procedures within the module. At the procedure level, variables are available only within the procedure. @@ -52,13 +52,11 @@ Dim X As New Worksheet If the **New** keyword is not used when declaring an object variable, the variable that refers to the object must be assigned an existing object by using the **Set** statement before it can be used. Until it is assigned an object, the declared object variable has the special value **Nothing**, which indicates that it doesn't refer to any particular instance of an object. -You can also use the **Dim** statement with empty parentheses to declare a dynamic array. After declaring a dynamic array, use the [**ReDim**](ReDim) statement within a procedure to define the number of dimensions and elements in the array. If you try to redeclare a dimension for an array variable whose size was explicitly specified in a [**Private**](Private), [**Public**](Public), or **Dim** statement, an error occurs. +The **Dim** statement with empty parentheses also declares a dynamic array. After declaring a dynamic array, use the [**ReDim**](ReDim) statement within a procedure to define the number of dimensions and elements in the array. Redeclaring a dimension for an array variable whose size was explicitly specified in a [**Private**](Private), [**Public**](Public), or **Dim** statement raises an error. -If you don't specify a data type or object type, and there is no [**Deftype**](Deftype) statement in the module, the variable is **Variant** by default. When variables are initialized, a numeric variable is initialized to 0, a variable-length string is initialized to a zero-length string (""), and a fixed-length string is filled with zeros. **Variant** variables are initialized to Empty. Each element of a user-defined type variable is initialized as if it were a separate variable. +When no data type or object type is specified, and there is no [**Deftype**](Deftype) statement in the module, the variable is **Variant** by default. When variables are initialized, a numeric variable is initialized to 0, a variable-length string is initialized to a zero-length string (""), and a fixed-length string is filled with zeros. **Variant** variables are initialized to Empty. Each element of a user-defined type variable is initialized as if it were a separate variable. -> [!NOTE] -> -> When you use the **Dim** statement in a procedure, you generally put the **Dim** statement at the beginning of the procedure. +By convention, a **Dim** statement inside a procedure is placed at the beginning of the procedure. ### Example diff --git a/docs/Reference/Core/Divide.md b/docs/Reference/Core/Divide.md index e74a789f..2db4349a 100644 --- a/docs/Reference/Core/Divide.md +++ b/docs/Reference/Core/Divide.md @@ -36,7 +36,7 @@ Dividing by zero is an error for integral types; for **Single** and **Double** i ### Compound assignment -`x /= y` is the twinBASIC shorthand for `x = x / y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** / **Empty** rules described above. **/=** is a statement, not an expression — it does not produce a value. +`x /= y` is the twinBASIC shorthand for `x = x / y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** / **Empty** rules described above. **/=** is a statement, not an expression --- it does not produce a value. ```tb Dim Value As Double = 100 diff --git a/docs/Reference/Core/Do-Loop.md b/docs/Reference/Core/Do-Loop.md index 278b4c99..0a029c91 100644 --- a/docs/Reference/Core/Do-Loop.md +++ b/docs/Reference/Core/Do-Loop.md @@ -23,7 +23,7 @@ Syntax: > **Loop** [{ **While** \| **Until** } *condition* ] *condition* -: *optional* Numeric expression or string expression that is **True** or **False**. If *condition* is Null, *condition* is treated as **False**. +: *optional* Numeric expression or string expression that is **True** or **False**. If *condition* is Null, *condition* is treated as **False**. *statements* : One or more statements that are repeated while, or until, *condition* is **True**. @@ -63,9 +63,9 @@ Use **Do...Loop** statements to run a block of statements an indefinite number o ### Repeating statements while a condition is True -There are two ways to use the **While** keyword to check a condition in a **Do...Loop** statement. You can check the condition before you enter the loop, or you can check it after the loop has run at least once. +There are two ways to use the **While** keyword to check a condition in a **Do...Loop** statement. The condition can be checked before entering the loop, or after the loop has run at least once. -In the following `ChkFirstWhile` procedure, you check the condition before you enter the loop. If `myNum` is set to 9 instead of 20, the statements inside the loop will never run. In the `ChkLastWhile` procedure, the statements inside the loop run only once before the condition becomes **False**. +In the following `ChkFirstWhile` procedure, the condition is checked before entering the loop. If `myNum` is set to 9 instead of 20, the statements inside the loop will never run. In the `ChkLastWhile` procedure, the statements inside the loop run only once before the condition becomes **False**. ```tb Sub ChkFirstWhile() @@ -91,7 +91,7 @@ End Sub ### Repeating statements until a condition becomes True -There are two ways to use the **Until** keyword to check a condition in a **Do...Loop** statement. You can check the condition before you enter the loop (as shown in the `ChkFirstUntil` procedure), or you can check it after the loop has run at least once (as shown in the `ChkLastUntil` procedure). Looping continues while the condition remains **False**. +There are two ways to use the **Until** keyword to check a condition in a **Do...Loop** statement. The condition can be checked before entering the loop (as shown in the `ChkFirstUntil` procedure), or after the loop has run at least once (as shown in the `ChkLastUntil` procedure). Looping continues while the condition remains **False**. ```tb Sub ChkFirstUntil() @@ -117,7 +117,7 @@ End Sub ### Exiting a Do...Loop statement from inside the loop -You can exit a **Do...Loop** by using the [**Exit Do**](Exit) statement. For example, to exit an endless loop, use the **Exit Do** statement in the **True** statement block of either an [**If...Then...Else**](If-Then-Else) statement or a [**Select Case**](Select-Case) statement. If the condition is **False**, the loop will run as usual. +The [**Exit Do**](Exit) statement exits a **Do...Loop** from inside. For example, to exit an endless loop, use the **Exit Do** statement in the **True** statement block of either an [**If...Then...Else**](If-Then-Else) statement or a [**Select Case**](Select-Case) statement. If the condition is **False**, the loop will run as usual. In the following example `myNum` is assigned a value that creates an endless loop. The **If...Then...Else** statement checks for this condition, and then exits, preventing endless looping. diff --git a/docs/Reference/Core/End.md b/docs/Reference/Core/End.md index 5aeae3f3..9c5ee1ff 100644 --- a/docs/Reference/Core/End.md +++ b/docs/Reference/Core/End.md @@ -34,15 +34,15 @@ Syntax: Required to end a user-defined type (UDT) definition ([**Type**](Type) statement). - **End With** - Required to end a [**With**](With) statement. + Required to end a [**With**](With) statement. -When executed, the **End** statement resets all module-level variables and all static local variables in all modules. To preserve the value of these variables, use the [**Stop**](Stop) statement instead. You can then resume execution while preserving the value of those variables. +When executed, the **End** statement resets all module-level variables and all static local variables in all modules. To preserve the value of these variables, use the [**Stop**](Stop) statement instead --- execution can then resume while preserving the value of those variables. -> [!NOTE] +> [!IMPORTANT] > -> The **End** statement stops code execution abruptly, without invoking the Unload, QueryUnload, or Terminate event, or any other Visual Basic code. Code you have placed in the Unload, QueryUnload, and Terminate events of forms and class modules is not executed. Objects created from class modules are destroyed, files opened by using the **Open** statement are closed, and memory used by your program is freed. Object references held by other programs are invalidated. +> The **End** statement stops code execution abruptly, without invoking the Unload, QueryUnload, or Terminate event, or any other Visual Basic code. Code placed in the Unload, QueryUnload, and Terminate events of forms and class modules is not executed. Objects created from class modules are destroyed, files opened by using the **Open** statement are closed, and memory used by the program is freed. Object references held by other programs are invalidated. -The **End** statement provides a way to force your program to halt. For normal termination of a Visual Basic program, you should unload all forms. Your program closes as soon as there are no other programs holding references to objects created from your public class modules and no code executing. +The **End** statement provides a way to force the program to halt. For normal termination of a Visual Basic program, all forms should be unloaded. The program closes as soon as there are no other programs holding references to objects created from public class modules and no code executing. ### Example diff --git a/docs/Reference/Core/Enum.md b/docs/Reference/Core/Enum.md index 202269e8..b9e371d2 100644 --- a/docs/Reference/Core/Enum.md +++ b/docs/Reference/Core/Enum.md @@ -29,10 +29,10 @@ Syntax: : *optional* Specifies that the **Enum** type is visible only within the module in which it appears. *name* -: The name of the **Enum** type. The *name* must be a valid Visual Basic identifier and is specified as the type when declaring variables or parameters of the **Enum** type. +: The name of the **Enum** type. The *name* must be a valid Visual Basic identifier and is specified as the type when declaring variables or parameters of the **Enum** type. *membername* -: A valid Visual Basic identifier specifying the name by which a constituent element of the **Enum** type will be known. +: A valid Visual Basic identifier specifying the name by which a constituent element of the **Enum** type will be known. *constantexpression* : *optional* Value of the element (evaluates to a **Long**). If no *constantexpression* is specified, the value assigned is either zero (if it is the first *membername* ), or 1 greater than the value of the immediately preceding *membername*. @@ -47,15 +47,15 @@ Enum SecurityLevel End Enum ``` -An **Enum** statement can appear only at the module level. After the **Enum** type is defined, it can be used to declare variables, parameters, or procedures returning its type. You can't qualify an **Enum** type name with a module name. +An **Enum** statement can appear only at the module level. After the **Enum** type is defined, it can be used to declare variables, parameters, or procedures returning its type. An **Enum** type name cannot be qualified with a module name. **Public Enum** types in a class module are not members of the class; however, they are written to the type library. **Enum** types defined in standard modules aren't written to type libraries. **Public Enum** types of the same name can't be defined in both standard modules and class modules because they share the same name space. When two **Enum** types in different type libraries have the same name, but different elements, a reference to a variable of the type depends on which type library has higher priority in the **References**. -You can't use an **Enum** type as the target in a **With** block. +An **Enum** type cannot be used as the target in a **With** block. ### Example -The following example shows the **Enum** statement used to define a collection of named constants. In this case, the constants are colors you might choose to design data entry forms for a database. +The following example shows the **Enum** statement used to define a collection of named constants. In this case, the constants are colors that might be used to design data entry forms for a database. ```tb Public Enum InterfaceColors diff --git a/docs/Reference/Core/Eqv.md b/docs/Reference/Core/Eqv.md index a9efcf6b..cd9754af 100644 --- a/docs/Reference/Core/Eqv.md +++ b/docs/Reference/Core/Eqv.md @@ -8,7 +8,7 @@ vba_attribution: true # Eqv operator {: .no_toc } -Used to perform a bitwise equivalence on two expressions — the logical inverse of [**Xor**](Xor). +Used to perform a bitwise equivalence on two expressions --- the logical inverse of [**Xor**](Xor). Syntax: > *result* **=** *expression1* **Eqv** *expression2* diff --git a/docs/Reference/Core/Erase.md b/docs/Reference/Core/Erase.md index 2c21a03b..6ef0caaf 100644 --- a/docs/Reference/Core/Erase.md +++ b/docs/Reference/Core/Erase.md @@ -13,7 +13,7 @@ Reinitializes the elements of fixed-size arrays, or releases dynamic-array stora Syntax: **Erase** *arraylist* *arraylist* -: one or more comma-delimited array variables to be erased +: one or more comma-delimited array variables to be erased **Erase** behaves differently depending on whether an array is fixed-size (ordinary) or dynamic. **Erase** recovers no memory for fixed-size arrays. Erase sets the elements of a fixed array as follows: @@ -26,7 +26,7 @@ Syntax: **Erase** *arraylist* | Array of user-defined types | Sets each element as if it were a separate variable. | | Array of objects | Sets each element to the special value **Nothing**. | -**Erase** frees the memory used by dynamic arrays. Before your program can refer to the dynamic array again, it must redeclare the array variable's dimensions by using a ReDim statement. +**Erase** frees the memory used by dynamic arrays. Before the program can refer to the dynamic array again, it must redeclare the array variable's dimensions by using a ReDim statement. ### Example This example uses the **Erase** statement to reinitialize the elements of fixed-size arrays and deallocate dynamic-array storage space. diff --git a/docs/Reference/Core/Event.md b/docs/Reference/Core/Event.md index c6c85a4c..84d8b748 100644 --- a/docs/Reference/Core/Event.md +++ b/docs/Reference/Core/Event.md @@ -15,16 +15,16 @@ Syntax: [ **Public** ] **Event** *procedurename* [ (*arglist*) ] : Name of the event; follows standard variable naming conventions. *arglist* -: [ **ByVal** \| **ByRef** ] *varname* \[ **()** ] [ **As** *type* ] +: [ **ByVal** \| **ByRef** ] *varname* \[ **()** ] [ **As** *type* ] **ByVal** : *optional* Indicates that the argument is passed by value. **ByRef** - : *optional* Indicates that the argument is passed by reference. **ByRef** is the default in unlike in Visual Basic .NET. + : *optional* Indicates that the argument is passed by reference. **ByRef** is the default, unlike in Visual Basic .NET. *varname* - : Name of the variable representing the argument being passed to the procedure; follows standard variable naming conventions. + : Name of the variable representing the argument being passed to the procedure; follows standard variable naming conventions. *type* : *optional* Data type of the argument passed to the procedure; may be Byte, Boolean, Integer, Long, Currency, Single, Double, Decimal, Date, String (variable length only), Object, Variant, a user-defined type (UDT), or an object type. @@ -41,9 +41,7 @@ Sub End Sub ``` -> [!NOTE] -> -> You can declare event arguments just as you do arguments of procedures, with the following exceptions: events cannot have named arguments, **Optional** arguments, or **ParamArray** arguments. Events don't have return values. +Event arguments are declared the same way as procedure arguments, with the following exceptions: events cannot have named arguments, **Optional** arguments, or **ParamArray** arguments. Events don't have return values. ### Example @@ -51,7 +49,7 @@ The following example uses events to count off seconds during a demonstration of The class that raises an event is the event source, and the classes that implement the event are the sinks. An event source can have multiple sinks for the events it generates. When the class raises the event, that event is fired on every class that has elected to sink events for that instance of the object. -The example also uses a form (`Form1`) with a button (`Command1`), a label (`Label1`), and two text boxes (`Text1` and `Text2`). When you click the button, the first text box displays "From Now" and the second starts to count seconds. When the full time (9.84 seconds) has elapsed, the first text box displays "Until Now" and the second displays "9.84". +The example also uses a form (`Form1`) with a button (`Command1`), a label (`Label1`), and two text boxes (`Text1` and `Text2`). When the button is clicked, the first text box displays "From Now" and the second starts to count seconds. When the full time (9.84 seconds) has elapsed, the first text box displays "Until Now" and the second displays "9.84". The code specifies the initial and terminal states of the form. It also contains the code executed when events are raised. diff --git a/docs/Reference/Core/Exit.md b/docs/Reference/Core/Exit.md index f010fe4b..48abadb2 100644 --- a/docs/Reference/Core/Exit.md +++ b/docs/Reference/Core/Exit.md @@ -7,7 +7,7 @@ vba_attribution: true # Exit {: .no_toc } -Exits a block of **Do…Loop**, **For…Next**, **While...Wend**, **Function**, **Sub**, or **Property** code. +Exits a block of **Do…Loop**, **For…Next**, **While...Wend**, **Function**, **Sub**, or **Property** code. Syntax: diff --git a/docs/Reference/Core/Exponent.md b/docs/Reference/Core/Exponent.md index d9f145e8..20660da2 100644 --- a/docs/Reference/Core/Exponent.md +++ b/docs/Reference/Core/Exponent.md @@ -29,7 +29,7 @@ Usually, the data type of *result* is a **Double** or a **Variant** containing a ### Compound assignment -`x ^= y` is the twinBASIC shorthand for `x = x ^ y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** rules described above. **^=** is a statement, not an expression — it does not produce a value. +`x ^= y` is the twinBASIC shorthand for `x = x ^ y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** rules described above. **^=** is a statement, not an expression --- it does not produce a value. ```tb Dim Value As Double = 2 diff --git a/docs/Reference/Core/For-Each-Next.md b/docs/Reference/Core/For-Each-Next.md index 29897f43..f3b593cf 100644 --- a/docs/Reference/Core/For-Each-Next.md +++ b/docs/Reference/Core/For-Each-Next.md @@ -25,7 +25,7 @@ Syntax: When present it is equivalent to placing `Dim element As type` immediately before the **For Each** statement. *group* -: Name of an object collection or array (except an array of user-defined types (UDTs)). +: Name of an object collection or array (except an array of user-defined types (UDTs)). *statements* : *optional* One or more statements that are executed on each item in *group*. @@ -40,13 +40,13 @@ Syntax: The **For…Each** block is entered if there is at least one element in *group*. After the loop has been entered, all the statements in the loop are executed for the first element in *group*. If there are more elements in *group*, the statements in the loop continue to execute for each element. When there are no more elements in *group*, the loop is exited and execution continues with the statement following the **Next** statement. -You can nest **For...Each...Next** loops by placing one **For…Each…Next** loop within another. However, each loop *element* must be unique. +**For...Each...Next** loops can be nested by placing one **For…Each…Next** loop within another. However, each loop *element* must be unique. > [!NOTE] > -> If you omit *element* in a **Next** statement, execution continues as if *element* is included. If a **Next** statement is encountered before its corresponding **For** statement, an error occurs. +> When *element* is omitted in a **Next** statement, execution continues as if *element* is included. If a **Next** statement is encountered before its corresponding **For** statement, an error occurs. -You can't use the **For...Each...Next** statement with an array of user-defined types because a **Variant** can't contain a user-defined type. +The **For...Each...Next** statement cannot be used with an array of user-defined types because a **Variant** can't contain a user-defined type. ### Example diff --git a/docs/Reference/Core/For-Next.md b/docs/Reference/Core/For-Next.md index 1d63350e..4e5e6b0c 100644 --- a/docs/Reference/Core/For-Next.md +++ b/docs/Reference/Core/For-Next.md @@ -56,9 +56,9 @@ After all statements in the loop have executed, *step* is added to *counter*. At > [!TIP] > -> Changing the value of *counter* while inside a loop can make it more difficult to read and debug your code. +> Changing the value of *counter* while inside a loop can make code harder to read and debug. -You can nest **For...Next** loops by placing one **For...Next** loop within another. Give each loop a unique variable name as its *counter*. The following construction is correct: +**For...Next** loops can be nested by placing one **For...Next** loop within another. Give each loop a unique variable name as its *counter*. The following construction is correct: ```tb For I = 1 To 10 @@ -72,7 +72,7 @@ Next I > [!NOTE] > -> If you omit *counter* in a **Next** statement, execution continues as if *counter* is included. If a **Next** statement is encountered before its corresponding **For** statement, an error occurs. +> When *counter* is omitted in a **Next** statement, execution continues as if *counter* is included. If a **Next** statement is encountered before its corresponding **For** statement, an error occurs. ### Example diff --git a/docs/Reference/Core/Function.md b/docs/Reference/Core/Function.md index 897e07ac..9878c8d7 100644 --- a/docs/Reference/Core/Function.md +++ b/docs/Reference/Core/Function.md @@ -34,16 +34,16 @@ Syntax: : *optional* Used only in a class module. Indicates that the **Function** procedure is visible throughout the project, but not visible to a controller of an instance of an object. **[Protected](Protected)** -: *optional* (twinBASIC) Used only in a class. Indicates that the **Function** procedure is accessible from inside the declaring class and from classes that derive from it via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop), but not from outside callers. +: *optional* (twinBASIC) Used only in a class. Indicates that the **Function** procedure is accessible from inside the declaring class and from classes that derive from it via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop), but not from outside callers. **Static** : *optional* Indicates that the **Function** procedure's local variables are preserved between calls. The **Static** attribute doesn't affect variables that are declared outside the **Function**, even if they are used in the procedure. **Overridable** -: *optional* (twinBASIC) Marks the **Function** as an inheritance hook that classes derived via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop) may replace with an **Overrides** clause. Meaningful only on a member of a class that participates in an **Inherits** hierarchy. +: *optional* (twinBASIC) Marks the **Function** as an inheritance hook that classes derived via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop) may replace with an **Overrides** clause. Meaningful only on a member of a class that participates in an **Inherits** hierarchy. *name* -: Name of the **Function**; follows standard variable naming conventions. +: Name of the **Function**; follows standard variable naming conventions. **Of** *typevars* : *optional* One or more type variable names; following standard variable naming conventions. The names are separated by commas. Causes the function to be a generic function. @@ -55,11 +55,11 @@ Syntax: : *optional* Data type of the value returned by the **Function** procedure; may be Byte, Boolean, Integer, Long, Currency, Single, Double, Decimal, Date, String (except fixed length), Object, Variant, or any user-defined type (UDT). *binding-clause* -: *optional* (twinBASIC) One of three trailing clauses that bind this body to a member declared elsewhere: +: *optional* (twinBASIC) One of three trailing clauses that bind this body to a member declared elsewhere: - - **Handles** *object*.*event* [ **,** *object*.*event* … ] — wires this **Function** up as a handler for the named event(s), replacing the traditional `Object_Event` naming convention. See [**Handles** statement](Handles). - - **Implements** *iface*.*member* [ **,** *iface2*.*member2* … ] — provides the body for the named [**Interface**](Interface) (or [**Class**](Class)) member, replacing the traditional `Iface_Member` naming convention. A comma-separated list lets one body satisfy several interfaces' members at once. See [**Implements** statement](Implements). - - **Overrides** *base*.*member* — supplies the body for an **Overridable** *member* inherited via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop). Combine with **Overridable** on the same header to allow further-derived classes to override again. + - **Handles** *object*.*event* [ **,** *object*.*event* … ] --- connects this **Function** as a handler for the named event(s), replacing the traditional `Object_Event` naming convention. See [**Handles** statement](Handles). + - **Implements** *iface*.*member* [ **,** *iface2*.*member2* … ] --- provides the body for the named [**Interface**](Interface) (or [**Class**](Class)) member, replacing the traditional `Iface_Member` naming convention. A comma-separated list permits one body to satisfy several interfaces' members at once. See [**Implements** statement](Implements). + - **Overrides** *base*.*member* --- supplies the body for an **Overridable** *member* inherited via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop). Combine with **Overridable** on the same header to allow further-derived classes to override again. *statements* : *optional* Any group of statements to be executed within the **Function** procedure. @@ -74,7 +74,7 @@ Syntax: : *optional* Immediately returns from the function with *expression* as the return value. The *expression* is required in this form; a bare **Return** is reserved for the [**GoSub...Return**](GoSub-Return) construct and does not exit a **Function**. **[Exit Function](Exit)** -: *optional* Immediately returns from the function without setting a return value. Use this to leave a function early when no value needs to be returned (the function will yield its default return value: 0 for numeric types, `""` for strings, **Empty** for **Variant**, **Nothing** for object references). +: *optional* Immediately returns from the function without setting a return value. Used to leave a function early when no value needs to be returned (the function will yield its default return value: 0 for numeric types, `""` for strings, **Empty** for **Variant**, **Nothing** for object references). *expression* : *optional* Return value of the **Function**. @@ -94,7 +94,7 @@ Syntax: One or more of : *optional* Indicates that the argument is passed by reference. **ByRef** is the default unlike in Visual Basic .NET. **ParamArray** -: *optional* Used only as the last argument in *arglist* to indicate that the final argument is an **Optional** array of **Variant** elements. The **ParamArray** keyword allows you to provide an arbitrary number of arguments. It may not be used with **ByVal**, **ByRef**, or **Optional**. +: *optional* Used only as the last argument in *arglist* to indicate that the final argument is an **Optional** array of **Variant** elements. The **ParamArray** keyword permits passing an arbitrary number of arguments. It may not be used with **ByVal**, **ByRef**, or **Optional**. *varname* : Name of the variable representing the argument; follows standard variable naming conventions. @@ -114,13 +114,13 @@ The **Friend** keyword can only be used in class modules. However, **Friend** pr **Function** procedures can be recursive; that is, they can call themselves to perform a given task. However, recursion can lead to stack overflow. The **Static** keyword usually isn't used with recursive **Function** procedures. -All executable code must be in procedures. You can't define a **Function** procedure inside another **Function**, **[Sub](Sub)**, or **[Property](Property)** procedure. +All executable code must be in procedures. A **Function** procedure cannot be defined inside another **Function**, **[Sub](Sub)**, or **[Property](Property)** procedure. -The **[Exit Function](Exit)** statement and the **[Return](Return)** *expression* statement both cause an immediate exit from a **Function** procedure. Program execution continues with the statement following the statement that called the **Function** procedure. Any number of these statements can appear anywhere in a **Function** procedure. Use **Exit Function** when you've already assigned the return value (or want the default), and **Return** *expression* when you want to set the return value and exit in a single step. +The **[Exit Function](Exit)** statement and the **[Return](Return)** *expression* statement both cause an immediate exit from a **Function** procedure. Program execution continues with the statement following the statement that called the **Function** procedure. Any number of these statements can appear anywhere in a **Function** procedure. **Exit Function** is the right choice when the return value has already been assigned (or the default is wanted); **Return** *expression* sets the return value and exits in a single step. -Like a **Sub** procedure, a **Function** procedure is a separate procedure that can take arguments, perform a series of statements, and change the values of its arguments. However, unlike a **Sub** procedure, you can use a **Function** procedure on the right side of an expression in the same way you use any intrinsic function, such as **Sqr**, **Cos**, or **Chr**, when you want to use the value returned by the function. +Like a **Sub** procedure, a **Function** procedure is a separate procedure that can take arguments, perform a series of statements, and change the values of its arguments. However, unlike a **Sub** procedure, a **Function** procedure can appear on the right side of an expression in the same way as any intrinsic function --- such as **Sqr**, **Cos**, or **Chr** --- when the value returned by the function is needed. -You call a **Function** procedure by using the function name, followed by the argument list in parentheses, in an expression. See the **[Call](Call)** statement for specific information about how to call **Function** procedures. +A **Function** procedure is called by using the function name, followed by the argument list in parentheses, in an expression. See the **[Call](Call)** statement for specific information about how to call **Function** procedures. To return a value from a function, assign the value to the function name, or provide it as an argument to the **Return** statement. Any number of such assignments and **Return** statements can appear anywhere within the procedure. If no value is assigned to *name*, the procedure returns a default value: a numeric function returns 0, a string function returns a zero-length string (""), and a **Variant** function returns **Empty**. A function that returns an object reference returns **Nothing** if no object reference is assigned to *name* (using **Set** or **Return**) within the **Function**. @@ -142,7 +142,7 @@ Variables used in **Function** procedures fall into two categories: those that a Variables that are explicitly declared in a procedure (using **Dim** or the equivalent) are always local to the procedure. Variables that are used but not explicitly declared in a procedure are also local unless they are explicitly declared at some higher level outside the procedure. -A procedure can use a variable that is not explicitly declared in the procedure, but a naming conflict can occur if anything you defined at the module level has the same name. If your procedure refers to an undeclared variable that has the same name as another procedure, constant, or variable, it is assumed that your procedure refers to that module-level name. Explicitly declare variables to avoid this kind of conflict. Use an **[Option Explicit](Option#Explicit)** statement to force explicit declaration of variables. +A procedure can use a variable that is not explicitly declared in the procedure, but a naming conflict can occur if anything defined at the module level has the same name. When a procedure refers to an undeclared variable that has the same name as another procedure, constant, or variable, it is assumed that the procedure refers to that module-level name. Explicitly declare variables to avoid this kind of conflict. Use an **[Option Explicit](Option#Explicit)** statement to force explicit declaration of variables. Visual Basic may rearrange arithmetic expressions to increase internal efficiency. Avoid using a **Function** procedure in an arithmetic expression when the function changes the value of variables in the same expression. For more information about arithmetic operators, see Operators. diff --git a/docs/Reference/Core/Get.md b/docs/Reference/Core/Get.md index e9ea92fe..f1f7c20c 100644 --- a/docs/Reference/Core/Get.md +++ b/docs/Reference/Core/Get.md @@ -19,12 +19,12 @@ Syntax: : Any valid file number. *recnumber* -: *optional* **Variant** (**Long**). Record number (**Random** mode files) or byte number (**Binary** mode files) at which reading begins. +: *optional* **Variant** (**Long**). Record number (**Random** mode files) or byte number (**Binary** mode files) at which reading begins. *varname* : Valid variable name into which data is read. -Data read with **Get** is usually written to a file with [**Put**](Put). The first record or byte in a file is at position 1, the second record or byte is at position 2, and so on. If you omit *recnumber*, the next record or byte following the last **Get** or **Put** statement (or pointed to by the last [**Seek**](../Modules/FileSystem/Seek) function) is read. You must include the delimiting commas: +Data read with **Get** is usually written to a file with [**Put**](Put). The first record or byte in a file is at position 1, the second record or byte is at position 2, and so on. When *recnumber* is omitted, the next record or byte following the last **Get** or **Put** statement (or pointed to by the last [**Seek**](../Modules/FileSystem/Seek) function) is read. The delimiting commas must be included: ```tb Get #4, , FileBuffer @@ -39,7 +39,7 @@ For files opened in **Random** mode, the following rules apply: - If the variable being read into is a **Variant** of numeric type, **Get** reads 2 bytes identifying the **VarType** of the **Variant** and then the data that goes into the variable. For example, when reading a **Variant** of **VarType** 3, **Get** reads 6 bytes: 2 bytes identifying the **Variant** as **VarType** 3 (**Long**) and 4 bytes containing the **Long** data. The record length specified by the **Len** clause in the **Open** statement must be at least 2 bytes greater than the actual number of bytes required to store the variable. > [!NOTE] - > Use the **Get** statement to read a **Variant** array from disk, but you can't use **Get** to read a scalar **Variant** containing an array. You also can't use **Get** to read objects from disk. + > Use the **Get** statement to read a **Variant** array from disk; **Get** cannot read a scalar **Variant** containing an array. **Get** also cannot read objects from disk. - If the variable being read into is a **Variant** of **VarType** 8 (**String**), **Get** reads 2 bytes identifying the **VarType**, 2 bytes indicating the length of the string, and then reads the string data. The record length specified by the **Len** clause in the **Open** statement must be at least 4 bytes greater than the actual length of the string. diff --git a/docs/Reference/Core/GoSub-Return.md b/docs/Reference/Core/GoSub-Return.md index 3ca1d14f..8d8a5197 100644 --- a/docs/Reference/Core/GoSub-Return.md +++ b/docs/Reference/Core/GoSub-Return.md @@ -22,10 +22,10 @@ Syntax: Use **GoSub** and **Return** anywhere in a procedure, but **GoSub** and the corresponding **Return** statement must be in the same procedure. A subroutine can contain more than one **Return** statement, but the first **Return** statement encountered causes the flow of execution to branch back to the statement immediately following the most recently executed **GoSub** statement. > [!NOTE] -> You can't enter or exit [**Sub**](Sub) procedures with **GoSub...Return**. +> **GoSub...Return** cannot enter or exit [**Sub**](Sub) procedures. > [!TIP] -> Creating separate procedures that you can call may provide a more structured alternative to using **GoSub...Return**. +> Creating separate callable procedures may provide a more structured alternative to using **GoSub...Return**. ### Example diff --git a/docs/Reference/Core/Handles.md b/docs/Reference/Core/Handles.md index b0d09a47..3a3fc411 100644 --- a/docs/Reference/Core/Handles.md +++ b/docs/Reference/Core/Handles.md @@ -9,7 +9,7 @@ permalink: /tB/Core/Handles A trailing clause on a procedure header that binds the procedure as an event handler for one or more specific events. > [!NOTE] -> The **Handles** clause is a twinBASIC extension. Classic VBA connects event handlers solely by name: a `Sub` called `Form_Load` automatically handles the `Load` event of `Form`. twinBASIC still supports that pattern — **Handles** decouples the procedure name from the events it handles and lets one body handle several events at once. Whether the IDE inserts the new syntax when auto-generating event prototypes is controlled by the "IDE: Use new handles/implements syntax" option. +> The **Handles** clause is a twinBASIC extension. Classic VBA connects event handlers solely by name: a `Sub` called `Form_Load` automatically handles the `Load` event of `Form`. twinBASIC still supports that pattern --- **Handles** decouples the procedure name from the events it handles and lets one body handle several events at once. Whether the IDE inserts the new syntax when auto-generating event prototypes is controlled by the "IDE: Use new handles/implements syntax" option. Syntax: > *procedure-header* **Handles** *object*.*event* [ **,** *object*.*event* ] … @@ -25,9 +25,9 @@ Syntax: The procedure's parameter list must match the signatures of every event it handles. When several events are listed they must all share the same signature, so one body can service them interchangeably. -Because **Handles** decouples the procedure's name from the events it handles, you can: +Because **Handles** decouples the procedure's name from the events it handles, the procedure can: -- give the procedure a descriptive name (`OnLoad`, `SyncOpacity`) instead of the compound `<Object>_<Event>` form; +- have a descriptive name (`OnLoad`, `SyncOpacity`) instead of the compound `<Object>_<Event>` form; - factor several related event handlers into a single body without duplicating code; and - handle an event from a procedure whose name happens to collide with the implicit naming pattern. @@ -63,7 +63,7 @@ Private Sub BackColor_OnPropertyLet() End Sub ``` -— and you would need a separate procedure body per event. +--- a separate procedure body would be required per event. ### See Also diff --git a/docs/Reference/Core/If-Then-Else.md b/docs/Reference/Core/If-Then-Else.md index 98bd9f86..cf12f14c 100644 --- a/docs/Reference/Core/If-Then-Else.md +++ b/docs/Reference/Core/If-Then-Else.md @@ -30,13 +30,13 @@ Syntax: : Optional in block form; required in single-line form that has no **Else** clause. One or more statements separated by colons; executed if *condition* is **True**. *condition-n* -: *optional* Same as *condition*. +: *optional* Same as *condition*. *elseifstatements* -: *optional* One or more statements executed if the associated *condition-n* is **True**. +: *optional* One or more statements executed if the associated *condition-n* is **True**. *elsestatements* -: *optional* One or more statements executed if no previous *condition* or *condition-n* expression is **True**. +: *optional* One or more statements executed if no previous *condition* or *condition-n* expression is **True**. Use the single-line form (first syntax) for short, simple tests. The block form (second syntax) provides more structure and flexibility than the single-line form and is usually easier to read, maintain, and debug. @@ -51,7 +51,7 @@ A block form **If** statement must be the first statement on a line. The **Else* To determine whether or not a statement is a block **If**, examine what follows the **Then** keyword. If anything other than a comment appears after **Then** on the same line, the statement is treated as a single-line **If** statement. -The **Else** and **ElseIf** clauses are both optional. You can have as many **ElseIf** clauses as you want in a block **If**, but none can appear after an **Else** clause. Block **If** statements can be nested; that is, contained within one another. +The **Else** and **ElseIf** clauses are both optional. A block **If** can have any number of **ElseIf** clauses, but none can appear after an **Else** clause. Block **If** statements can be nested; that is, contained within one another. When executing a block **If** (second syntax), *condition* is tested. If *condition* is **True**, the statements following **Then** are executed. If *condition* is **False**, each **ElseIf** condition (if any) is evaluated in turn. When a **True** condition is found, the statements immediately following the associated **Then** are executed. If none of the **ElseIf** conditions are **True** (or if there are no **ElseIf** clauses), the statements following **Else** are executed. After executing the statements following **Then** or **Else**, execution continues with the statement following **End If**. diff --git a/docs/Reference/Core/Implements.md b/docs/Reference/Core/Implements.md index d6f4543f..e7e73c53 100644 --- a/docs/Reference/Core/Implements.md +++ b/docs/Reference/Core/Implements.md @@ -13,7 +13,7 @@ Syntax: > **Implements** { *InterfaceName* \| *ClassName* } [ **,** { *InterfaceName* \| *ClassName* } ]… *InterfaceName* -: The name of an interface — either an [**Interface**](Interface) block defined in twinBASIC, or an interface in a referenced type library — whose members will be implemented by the corresponding members in the class. +: The name of an interface --- either an [**Interface**](Interface) block defined in twinBASIC, or an interface in a referenced type library --- whose members will be implemented by the corresponding members in the class. *ClassName* : The name of a class whose default interface will be implemented. @@ -22,27 +22,27 @@ A single **Implements** statement can list several interfaces or classes separat An *interface* is a collection of prototypes representing the members (methods and properties) that the interface encapsulates; that is, it contains only the declarations for the member procedures. A *class* provides an implementation of all the methods and properties of one or more interfaces. Classes provide the code used when each function is called by a controller of the class. All classes implement at least one interface, which is considered the default interface of the class. Any member that isn't explicitly a member of an implemented interface is implicitly a member of the default interface. -When a class implements an interface, the class provides its own versions of all the **Public** procedures specified in the interface. In addition to providing a mapping between the interface prototypes and your procedures, the **Implements** statement causes the class to accept COM `QueryInterface` calls for the specified interface ID. +When a class implements an interface, the class provides its own versions of all the **Public** procedures specified in the interface. In addition to providing a mapping between the interface prototypes and the implementing procedures, the **Implements** statement causes the class to accept COM `QueryInterface` calls for the specified interface ID. -When you implement an interface or class, you must include all the **Public** procedures involved. A missing member in an implementation of an interface or class causes an error. If you don't place code in one of the procedures in a class you are implementing, you can raise the appropriate error (`Const E_NOTIMPL = &H80004001`) so a user of the implementation understands that a member is not implemented. +When implementing an interface or class, all the **Public** procedures involved must be included. A missing member in an implementation of an interface or class causes an error. When code is not placed in one of the implemented procedures, raise the appropriate error (`Const E_NOTIMPL = &H80004001`) so a user of the implementation understands that a member is not implemented. -The **Implements** statement can't appear in a standard module — it is valid only in a [**Class**](Class) block. +The **Implements** statement can't appear in a standard module --- it is valid only in a [**Class**](Class) block. ### twinBASIC enhancements twinBASIC extends classic VBA's **Implements** in several ways. See [Inheritance](../../Features/Language/Inheritance) for the full discussion; the headline differences: -- **Comma-separated list** — one **Implements** statement can name multiple interfaces or classes, e.g. `Implements IFoo, IBar, IBaz`. Classic VBA requires a separate **Implements** statement for each. -- **Inherited interfaces** — `Implements` works directly on a derived interface (e.g. `Implements IFoo2` where `Interface IFoo2 Extends IFoo`). The class need not name `IFoo` separately; `QueryInterface` for the base is satisfied automatically. Classic VBA does not support implementing derived interfaces. -- **Multiple-implementation form** — a single member can implement methods on several interfaces at once via `Implements <iface1>.<member>, <iface2>.<member>, …` after the procedure header. This is useful when several interfaces declare the same member and you want one body to satisfy all of them. -- **`As Any` parameters** — interfaces declared with `As Any` parameters can be implemented (substituting `As LongPtr` for `As Any` in the implementing class). Classic VBA rejects this. +- **Comma-separated list** --- one **Implements** statement can name multiple interfaces or classes, e.g. `Implements IFoo, IBar, IBaz`. Classic VBA requires a separate **Implements** statement for each. +- **Inherited interfaces** --- `Implements` works directly on a derived interface (e.g. `Implements IFoo2` where `Interface IFoo2 Extends IFoo`). The class need not name `IFoo` separately; `QueryInterface` for the base is satisfied automatically. Classic VBA does not support implementing derived interfaces. +- **Multiple-implementation form** --- a single member can implement methods on several interfaces at once via `Implements <iface1>.<member>, <iface2>.<member>, …` after the procedure header. This is useful when several interfaces declare the same member and one body should satisfy all of them. +- **`As Any` parameters** --- interfaces declared with `As Any` parameters can be implemented (substituting `As LongPtr` for `As Any` in the implementing class). Classic VBA rejects this. > [!NOTE] > Use `Private` (or `Friend`) on the implementing procedures so that the interface methods don't also become part of the implementing class's *default* interface. The conventional naming pattern is `<InterfaceName>_<MemberName>`. ### Example -The following example shows how to use the **Implements** statement to make a set of declarations available to multiple classes. By sharing the declarations through the **Implements** statement, neither class has to make any declarations itself. The example also shows how use of an interface allows abstraction: a strongly-typed variable can be declared by using the interface type. It can then be assigned objects of different class types that implement the interface. +The following example shows how to use the **Implements** statement to make a set of declarations available to multiple classes. By sharing the declarations through the **Implements** statement, neither class has to make any declarations itself. The example also shows how use of an interface supports abstraction: a strongly-typed variable can be declared by using the interface type. It can then be assigned objects of different class types that implement the interface. The interface declarations are in a class called `PersonalData`: @@ -97,7 +97,7 @@ Public Property Set PD(Data As PersonalData) End Property ``` -`m_pd` can only access the members of `PersonalData`. Customer-specific or Supplier-specific members are not visible through it — assigning an object to a variable declared by interface type provides polymorphic behavior. +`m_pd` can only access the members of `PersonalData`. Customer-specific or Supplier-specific members are not visible through it --- assigning an object to a variable declared by interface type provides polymorphic behavior. ### See Also diff --git a/docs/Reference/Core/Input.md b/docs/Reference/Core/Input.md index 97e75a20..e4878655 100644 --- a/docs/Reference/Core/Input.md +++ b/docs/Reference/Core/Input.md @@ -35,12 +35,12 @@ The following table illustrates how other input data is treated: Double quotation marks (`"`) within input data are ignored. -> [!NOTE] -> You should not write strings that contain embedded quotation marks (for example, `"1,2""X"`) for use with the **Input #** statement; **Input #** parses this string as two complete and separate strings. +> [!IMPORTANT] +> Do not write strings that contain embedded quotation marks (for example, `"1,2""X"`) for use with the **Input #** statement; **Input #** parses this string as two complete and separate strings. Data items in a file must appear in the same order as the variables in *varlist* and match variables of the same data type. If a variable is numeric and the data is not numeric, a value of zero is assigned to the variable. -If you reach the end of the file while you are inputting a data item, the input is terminated and an error occurs. +If the end of the file is reached while a data item is being read, the input is terminated and an error occurs. > [!NOTE] > To be able to correctly read data from a file into variables by using **Input #**, use the [**Write #**](Write) statement instead of the [**Print #**](Print) statement to write the data to the files. Using **Write #** ensures that each separate data field is properly delimited. diff --git a/docs/Reference/Core/IntegerDivide.md b/docs/Reference/Core/IntegerDivide.md index 0e8ec4df..1fb7840e 100644 --- a/docs/Reference/Core/IntegerDivide.md +++ b/docs/Reference/Core/IntegerDivide.md @@ -33,7 +33,7 @@ Dividing by zero raises a run-time error. ### Compound assignment -`x \= y` is the twinBASIC shorthand for `x = x \ y`. The left-hand side is evaluated once and rounded to an integral type as described above. **\\=** is a statement, not an expression — it does not produce a value. +`x \= y` is the twinBASIC shorthand for `x = x \ y`. The left-hand side is evaluated once and rounded to an integral type as described above. **\\=** is a statement, not an expression --- it does not produce a value. ```tb Dim Value As Long = 100 diff --git a/docs/Reference/Core/Interface.md b/docs/Reference/Core/Interface.md index a33608da..a297a22b 100644 --- a/docs/Reference/Core/Interface.md +++ b/docs/Reference/Core/Interface.md @@ -9,7 +9,7 @@ permalink: /tB/Core/Interface Defines a COM interface using twinBASIC syntax. An interface is a contract: a named set of method and property prototypes, with no implementation. Classes provide implementations of interfaces by using the [**Implements**](Implements) statement. > [!NOTE] -> The **Interface** block is a twinBASIC extension. In classic VBA there is no interface keyword — interfaces could only be defined indirectly via a referenced type library (IDL/C++) or by using a class with no implementation. +> The **Interface** block is a twinBASIC extension. In classic VBA there is no interface keyword --- interfaces could only be defined indirectly via a referenced type library (IDL/C++) or by using a class with no implementation. Syntax: > [ *attributes* ] @@ -20,16 +20,16 @@ Syntax: > **End Interface** *attributes* -: *optional* Interface- and member-level attributes. See [Available attributes](#available-attributes) below. +: *optional* Interface- and member-level attributes. See [Available attributes](#available-attributes) below. *name* : The identifier naming the interface. By convention an interface name begins with an uppercase `I` (`IFoo`, `ICalculator`, ...). *baseinterface* -: *optional* One or more interfaces that *name* extends. An implementing class is required to provide bodies for the inherited methods as well; in twinBASIC, you can `Implements` *name* and rely on the inherited interfaces being satisfied automatically. +: *optional* One or more interfaces that *name* extends. An implementing class is required to provide bodies for the inherited methods as well; in twinBASIC, a class can `Implements` *name* and rely on the inherited interfaces being satisfied automatically. *member-prototype* -: A header-only declaration. May be a [**Sub**](Sub), [**Function**](Function), [**Property Get**](Property), [**Property Let**](Property), or [**Property Set**](Property) signature, with arguments and return type. **Public**/**Private**/**Friend** modifiers are *not* allowed on members. There is no `End Sub` / `End Function` / `End Property` — the prototype ends at end of line. +: A header-only declaration. May be a [**Sub**](Sub), [**Function**](Function), [**Property Get**](Property), [**Property Let**](Property), or [**Property Set**](Property) signature, with arguments and return type. **Public**/**Private**/**Friend** modifiers are *not* allowed on members. There is no `End Sub` / `End Function` / `End Property` --- the prototype ends at end of line. **Interface** blocks are valid only in `.twin` source files (not legacy `.bas` or `.cls` files), and must appear *before* the [**Class**](Class) or [**Module**](Module) statement in the file. Interfaces always have project-wide scope. @@ -37,19 +37,19 @@ Syntax: Interface-level attributes: -- `[InterfaceId("...")]` — fixes the IID for the interface (a string GUID). Set this on any public/exported interface so consumers in other projects bind to a stable identity. -- `[Description("text")]` — exposed as the `helpstring` in the type library. -- `[Hidden]` — hides the interface from IntelliSense and similar lists. -- `[Restricted]` — restricts the interface methods from being called in most contexts. -- `[OleAutomation(True/False)]` — controls whether the attribute is applied in the type library. `True` by default. -- `[ComImport]` — declares the interface as an import from an external COM library (e.g., the Windows shell). -- `[ComExtensible(True/False)]` — controls whether dynamically-added members can be invoked through `IDispatch`. `False` by default. +- `[InterfaceId("...")]` --- fixes the IID for the interface (a string GUID). Set this on any public/exported interface so consumers in other projects bind to a stable identity. +- `[Description("text")]` --- exposed as the `helpstring` in the type library. +- `[Hidden]` --- hides the interface from IntelliSense and similar lists. +- `[Restricted]` --- restricts the interface methods from being called in most contexts. +- `[OleAutomation(True/False)]` --- controls whether the attribute is applied in the type library. `True` by default. +- `[ComImport]` --- declares the interface as an import from an external COM library (e.g., the Windows shell). +- `[ComExtensible(True/False)]` --- controls whether dynamically-added members can be invoked through `IDispatch`. `False` by default. Member-level attributes: - `[Description("text")]` -- `[PreserveSig]` — keeps the raw COM signature (returning `HRESULT`) instead of having the runtime translate negative results into errors. Use this when you need the literal return value, or when negative values mean *acceptable failure* (e.g. an enumerator running out of items). -- `[DispId(number)]` — fixes the dispatch ID associated with the member. +- `[PreserveSig]` --- keeps the raw COM signature (returning `HRESULT`) instead of having the runtime translate negative results into errors. Use this when the literal return value is required, or when negative values mean *acceptable failure* (e.g. an enumerator running out of items). +- `[DispId(number)]` --- fixes the dispatch ID associated with the member. ### Example diff --git a/docs/Reference/Core/Is.md b/docs/Reference/Core/Is.md index f46bf1dd..cf49b7b1 100644 --- a/docs/Reference/Core/Is.md +++ b/docs/Reference/Core/Is.md @@ -19,7 +19,7 @@ Syntax: *object1*, *object2* : Any object references. -If *object1* and *object2* both refer to the same object, *result* is **True**; if they don't, *result* is **False**. **Is** does not compare values inside the objects — it compares whether the two references point to the same instance. +If *object1* and *object2* both refer to the same object, *result* is **True**; if they don't, *result* is **False**. **Is** does not compare values inside the objects --- it compares whether the two references point to the same instance. Two variables can be made to refer to the same object in several ways. In the following example, A has been set to refer to the same object as B: diff --git a/docs/Reference/Core/LSet.md b/docs/Reference/Core/LSet.md index dd71bd0d..149375ed 100644 --- a/docs/Reference/Core/LSet.md +++ b/docs/Reference/Core/LSet.md @@ -30,7 +30,7 @@ Syntax: If *string* is longer than *stringvar*, **LSet** places only the leftmost characters, up to the length of the *stringvar*, in *stringvar*. > [!WARNING] -> Using **LSet** to copy a variable of one user-defined type into a variable of a different user-defined type is not recommended. Copying data of one data type into space reserved for a different data type can cause unpredictable results. When you copy a variable from one user-defined type to another, the binary data from one variable is copied into the memory space of the other, without regard for the data types specified for the elements. +> Using **LSet** to copy a variable of one user-defined type into a variable of a different user-defined type is not recommended. Copying data of one data type into space reserved for a different data type can cause unpredictable results. When a variable is copied from one user-defined type to another, the binary data from one variable is copied into the memory space of the other, without regard for the data types specified for the elements. ### Example diff --git a/docs/Reference/Core/LeftShift.md b/docs/Reference/Core/LeftShift.md index 58965dd3..a310a693 100644 --- a/docs/Reference/Core/LeftShift.md +++ b/docs/Reference/Core/LeftShift.md @@ -28,11 +28,11 @@ Syntax: *count* : Any numeric expression giving the number of bit positions to shift. -The data type of *result* matches the (integral) type of *number*. A shift of more bits than the type can hold yields `0` rather than wrapping. The sign bit is *not* preserved — `<<` is a logical left shift, equivalent to multiplication by 2<sup>*count*</sup> within the available width. +The data type of *result* matches the (integral) type of *number*. A shift of more bits than the type can hold yields `0` rather than wrapping. The sign bit is *not* preserved --- `<<` is a logical left shift, equivalent to multiplication by 2<sup>*count*</sup> within the available width. ### Compound assignment -`x <<= n` is the twinBASIC shorthand for `x = x << n`. **\<<=** is a statement, not an expression — it does not produce a value. +`x <<= n` is the twinBASIC shorthand for `x = x << n`. **\<<=** is a statement, not an expression --- it does not produce a value. ```tb Dim Mask As Long = 1 diff --git a/docs/Reference/Core/Let.md b/docs/Reference/Core/Let.md index 7dd332c2..ca80e2b8 100644 --- a/docs/Reference/Core/Let.md +++ b/docs/Reference/Core/Let.md @@ -13,7 +13,7 @@ Syntax: > [ **Let** ] *varname* **=** *expression* **Let** -: *optional* Explicit use of the **Let** keyword is a matter of style; it is usually omitted. +: *optional* Explicit use of the **Let** keyword is a matter of style; it is usually omitted. *varname* : Name of the variable or property; follows standard variable naming conventions. @@ -21,7 +21,7 @@ Syntax: *expression* : Value assigned to the variable or property. -A value expression can be assigned to a variable or property only if it is of a data type that is compatible with the variable. You can't assign string expressions to numeric variables, and you can't assign numeric expressions to string variables. If you do, an error occurs at compile time. +A value expression can be assigned to a variable or property only if it is of a data type that is compatible with the variable. String expressions cannot be assigned to numeric variables, and numeric expressions cannot be assigned to string variables. Such an assignment raises an error at compile time. **Variant** variables can be assigned to either string or numeric expressions. However, the reverse is not always true. Any **Variant** except a **Null** can be assigned to a string variable, but only a **Variant** whose value can be interpreted as a number can be assigned to a numeric variable. Use the **IsNumeric** function to determine if the **Variant** can be converted to a number. diff --git a/docs/Reference/Core/Like.md b/docs/Reference/Core/Like.md index 198bcdbc..e41ccabb 100644 --- a/docs/Reference/Core/Like.md +++ b/docs/Reference/Core/Like.md @@ -34,13 +34,13 @@ Under **Option Compare Text** the same characters compare equal up to case and a `(A=a) < (À=à) < (B=b) < (E=e) < (Ê=ê) < (Z=z) < (Ø=ø)` -The pattern-matching syntax allows wildcards, character lists, and character ranges. The following characters in *pattern* have special meaning: +The pattern-matching syntax supports wildcards, character lists, and character ranges. The following characters in *pattern* have special meaning: | In *pattern* | Matches in *string* | |:-------------------|:-----------------------------------------------------| | `?` | Any single character. | | `*` | Zero or more characters. | -| `#` | Any single digit (`0`–`9`). | +| `#` | Any single digit (`0`--`9`). | | `[`*charlist*`]` | Any single character in *charlist*. | | `[!`*charlist*`]` | Any single character *not* in *charlist*. | @@ -49,7 +49,7 @@ A group of one or more characters (*charlist*) enclosed in brackets can match an > [!NOTE] > To match the special characters left bracket (`[`), question mark (`?`), number sign (`#`), or asterisk (`*`), enclose them in brackets. The right bracket (`]`) cannot be used inside a group to match itself, but it can be used outside a group as a literal character. -A hyphen (`-`) inside *charlist* separates the upper and lower bounds of a character range — for example, `[A-Z]` matches any uppercase letter. Multiple ranges are placed adjacently inside the same brackets, with no delimiter. +A hyphen (`-`) inside *charlist* separates the upper and lower bounds of a character range --- for example, `[A-Z]` matches any uppercase letter. Multiple ranges are placed adjacently inside the same brackets, with no delimiter. The meaning of a range depends on the active **Option Compare** mode and the system locale. Under **Option Compare Binary** the range `[A-E]` matches `A`, `B`, `E`; under **Option Compare Text** it matches `A`, `a`, `À`, `à`, `B`, `b`, `E`, `e` (but not `Ê`/`ê`, which sort after the basic letters). diff --git a/docs/Reference/Core/Load.md b/docs/Reference/Core/Load.md index 21c9b6c7..8b2f97bd 100644 --- a/docs/Reference/Core/Load.md +++ b/docs/Reference/Core/Load.md @@ -7,7 +7,7 @@ vba_attribution: true # Load {: .no_toc } -Loads an object — typically a form — into memory but does not show it. +Loads an object --- typically a form --- into memory but does not show it. Syntax: > **Load** *object* @@ -17,7 +17,7 @@ Syntax: When an object is loaded, it is placed in memory but is not visible. Use the **Show** method to make it visible. Until an object is visible, the user can't interact with it; the object can be manipulated programmatically inside its **Initialize** event handler. -Use [**Unload**](Unload) to remove the object from memory once you are done with it. +Use [**Unload**](Unload) to remove the object from memory once it is no longer needed. ### Example diff --git a/docs/Reference/Core/Lock.md b/docs/Reference/Core/Lock.md index 16c68be8..0abc56bd 100644 --- a/docs/Reference/Core/Lock.md +++ b/docs/Reference/Core/Lock.md @@ -17,7 +17,7 @@ Syntax: : Any valid file number. *recordrange* -: *optional* The range of records to lock or unlock. The *recordrange* settings are: +: *optional* The range of records to lock or unlock. The *recordrange* settings are: > *recnumber* \| [ *start* ] **To** *end* @@ -34,12 +34,12 @@ The **Lock** and **Unlock** statements are used in environments where several pr **Lock** and **Unlock** statements are always used in pairs. The arguments to **Lock** and **Unlock** must match exactly. -The first record or byte in a file is at position 1, the second record or byte is at position 2, and so on. If you specify just one record, only that record is locked or unlocked. If you specify a range of records and omit a starting record (*start*), all records from the first record to the end of the range (*end*) are locked or unlocked. Using **Lock** without *recnumber* locks the entire file; using **Unlock** without *recnumber* unlocks the entire file. +The first record or byte in a file is at position 1, the second record or byte is at position 2, and so on. When just one record is specified, only that record is locked or unlocked. When a range of records is specified and a starting record (*start*) is omitted, all records from the first record to the end of the range (*end*) are locked or unlocked. Using **Lock** without *recnumber* locks the entire file; using **Unlock** without *recnumber* unlocks the entire file. If the file has been opened for sequential input or output, **Lock** and **Unlock** affect the entire file, regardless of the range specified by *start* and *end*. > [!IMPORTANT] -> Be sure to remove all locks with an **Unlock** statement before closing a file or quitting your program. Failure to remove locks produces unpredictable results. +> Be sure to remove all locks with an **Unlock** statement before closing a file or quitting the program. Failure to remove locks produces unpredictable results. ### Example diff --git a/docs/Reference/Core/Mid-equals.md b/docs/Reference/Core/Mid-equals.md index 6020cc68..8a45457f 100644 --- a/docs/Reference/Core/Mid-equals.md +++ b/docs/Reference/Core/Mid-equals.md @@ -22,7 +22,7 @@ Syntax: : **Variant** (**Long**). Character position in *stringvar* where the replacement of text begins. *length* -: *optional* **Variant** (**Long**). Number of characters to replace. If omitted, all of *string* is used. +: *optional* **Variant** (**Long**). Number of characters to replace. If omitted, all of *string* is used. *string* : String expression that replaces part of *stringvar*. diff --git a/docs/Reference/Core/MidB-equals.md b/docs/Reference/Core/MidB-equals.md index 218ac357..38f6a3f3 100644 --- a/docs/Reference/Core/MidB-equals.md +++ b/docs/Reference/Core/MidB-equals.md @@ -19,7 +19,7 @@ Syntax: : **Variant** (**Long**). Byte position in *stringvar* where the replacement of bytes begins. *length* -: *optional* **Variant** (**Long**). Number of bytes to replace. If omitted, all of *string* is used. +: *optional* **Variant** (**Long**). Number of bytes to replace. If omitted, all of *string* is used. *string* : String expression whose bytes replace part of *stringvar*. diff --git a/docs/Reference/Core/Minus.md b/docs/Reference/Core/Minus.md index 2f7f009b..d84d4fd1 100644 --- a/docs/Reference/Core/Minus.md +++ b/docs/Reference/Core/Minus.md @@ -44,7 +44,7 @@ If one or both expressions are **Null** expressions, *result* is **Null**. If an ### Compound assignment -`x -= y` is the twinBASIC shorthand for `x = x - y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** / **Empty** rules described above. **-=** is a statement, not an expression — it does not produce a value. +`x -= y` is the twinBASIC shorthand for `x = x - y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** / **Empty** rules described above. **-=** is a statement, not an expression --- it does not produce a value. ```tb Dim Total As Long = 100 diff --git a/docs/Reference/Core/Module.md b/docs/Reference/Core/Module.md index 88e5c538..0554ba04 100644 --- a/docs/Reference/Core/Module.md +++ b/docs/Reference/Core/Module.md @@ -6,10 +6,10 @@ permalink: /tB/Core/Module # Module {: .no_toc } -Defines a module — a non-instantiable container for procedures, constants, types, enums, and module-level variables. A module's members are accessed through the module name (or, for **Public** members in a non-private module, directly). +Defines a module --- a non-instantiable container for procedures, constants, types, enums, and module-level variables. A module's members are accessed through the module name (or, for **Public** members in a non-private module, directly). > [!NOTE] -> The explicit **Module** ... **End Module** block is a twinBASIC extension. Classic VBA distinguishes "standard modules" from "class modules" purely by file type (`.bas` vs. `.cls`); the source has no enclosing keyword. In `.twin` files twinBASIC requires (and supports) the explicit block, which lets you put a class and a module in the same file and apply attributes to the module as a whole. +> The explicit **Module** ... **End Module** block is a twinBASIC extension. Classic VBA distinguishes "standard modules" from "class modules" purely by file type (`.bas` vs. `.cls`); the source has no enclosing keyword. In `.twin` files twinBASIC requires (and supports) the explicit block, which permits a class and a module in the same file and allows attributes to apply to the module as a whole. Syntax: > [ *attributes* ] @@ -19,19 +19,19 @@ Syntax: > **End Module** *attributes* -: *optional* One or more attributes applicable to a module. +: *optional* One or more attributes applicable to a module. **Public** -: *optional* In an ActiveX project, marks the module as exported into the type library so that consumers in other projects can see its **Public** members. +: *optional* In an ActiveX project, marks the module as exported into the type library so that consumers in other projects can see its **Public** members. **Private** -: *optional* In an ActiveX project, withholds the module from the type library: its members remain usable within the project, but are not exported. Equivalent to placing [**Option Private Module**](Option) at the top of a classic standard module. +: *optional* In an ActiveX project, withholds the module from the type library: its members remain usable within the project, but are not exported. Equivalent to placing [**Option Private Module**](Option) at the top of a classic standard module. *name* : The identifier naming the module. *modulemember* -: *optional* Any of the following: +: *optional* Any of the following: - constants defined using [**Const**](Const) - module-level variables defined using [**Public**](Public), [**Private**](Private), or [**Dim**](Dim) (modules don't take part in inheritance, so [**Protected**](Protected) is not allowed) diff --git a/docs/Reference/Core/Multiply.md b/docs/Reference/Core/Multiply.md index e6a986eb..f034dbf4 100644 --- a/docs/Reference/Core/Multiply.md +++ b/docs/Reference/Core/Multiply.md @@ -39,7 +39,7 @@ If one or both expressions are **Null** expressions, *result* is **Null**. If an ### Compound assignment -`x *= y` is the twinBASIC shorthand for `x = x * y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** / **Empty** rules described above. **\*=** is a statement, not an expression — it does not produce a value. +`x *= y` is the twinBASIC shorthand for `x = x * y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** / **Empty** rules described above. **\*=** is a statement, not an expression --- it does not produce a value. ```tb Dim Value As Long = 3 diff --git a/docs/Reference/Core/Name.md b/docs/Reference/Core/Name.md index fc3037c4..ba673160 100644 --- a/docs/Reference/Core/Name.md +++ b/docs/Reference/Core/Name.md @@ -20,7 +20,7 @@ Syntax: The **Name** statement renames a file and moves it to a different directory or folder, if necessary. **Name** can move a file across drives, but it can only rename an existing directory or folder when both *newpathname* and *oldpathname* are located on the same drive. **Name** cannot create a new file, directory, or folder. -Using **Name** on an open file produces an error. You must close an open file before renaming it. **Name** arguments cannot include multiple-character (`*`) and single-character (`?`) wildcards. +Using **Name** on an open file produces an error. An open file must be closed before renaming it. **Name** arguments cannot include multiple-character (`*`) and single-character (`?`) wildcards. ### Example diff --git a/docs/Reference/Core/On-Error.md b/docs/Reference/Core/On-Error.md index 2b23b874..92ddefa7 100644 --- a/docs/Reference/Core/On-Error.md +++ b/docs/Reference/Core/On-Error.md @@ -18,12 +18,12 @@ Syntax: : Enables the error-handling routine that starts at *line*. The *line* argument is any line label or line number. If a run-time error occurs, control branches to *line*, making the error handler active. The specified *line* must be in the same procedure as the **On Error** statement; otherwise, a compile-time error occurs. **On Error Resume Next** -: Specifies that when a run-time error occurs, control goes to the statement immediately following the statement where the error occurred and execution continues. Use this form rather than **On Error GoTo** when accessing objects. +: Specifies that when a run-time error occurs, control goes to the statement immediately following the statement where the error occurred and execution continues. This form is preferred over **On Error GoTo** when accessing objects. **On Error GoTo 0** : Disables any enabled error handler in the current procedure. -If you don't use an **On Error** statement, any run-time error that occurs is fatal; that is, an error message is displayed and execution stops. +Without an **On Error** statement, any run-time error that occurs is fatal; that is, an error message is displayed and execution stops. An "enabled" error handler is one that is turned on by an **On Error** statement; an "active" error handler is an enabled handler that is in the process of handling an error. If an error occurs while an error handler is active (between the occurrence of the error and a [**Resume**](Resume), [**Exit Sub**](Exit), **Exit Function**, or **Exit Property** statement), the current procedure's error handler can't handle the error. Control returns to the calling procedure. @@ -36,10 +36,10 @@ Each time the error handler passes control back to a calling procedure, that pro Error-handling routines rely on the value in the **Number** property of the **Err** object to determine the cause of the error. The error-handling routine should test or save relevant property values in the **Err** object before any other error can occur or before a procedure that might cause an error is called. The property values in the **Err** object reflect only the most recent error. The error message associated with **Err.Number** is contained in **Err.Description**. -**On Error Resume Next** causes execution to continue with the statement immediately following the statement that caused the run-time error, or with the statement immediately following the most recent call out of the procedure containing the **On Error Resume Next** statement. This statement allows execution to continue despite a run-time error. You can place the error-handling routine where the error would occur, rather than transferring control to another location within the procedure. An **On Error Resume Next** statement becomes inactive when another procedure is called, so you should execute an **On Error Resume Next** statement in each called routine if you want inline error handling within that routine. +**On Error Resume Next** causes execution to continue with the statement immediately following the statement that caused the run-time error, or with the statement immediately following the most recent call out of the procedure containing the **On Error Resume Next** statement. This statement allows execution to continue despite a run-time error. The error-handling routine can be placed where the error would occur, rather than transferring control to another location within the procedure. An **On Error Resume Next** statement becomes inactive when another procedure is called, so an **On Error Resume Next** statement must be executed in each called routine that requires inline error handling. > [!NOTE] -> The **On Error Resume Next** construct may be preferable to **On Error GoTo** when handling errors generated during access to other objects. Checking **Err** after each interaction with an object removes ambiguity about which object was accessed by the code. You can be sure which object placed the error code in **Err.Number**, as well as which object originally generated the error (the object specified in **Err.Source**). +> The **On Error Resume Next** construct may be preferable to **On Error GoTo** when handling errors generated during access to other objects. Checking **Err** after each interaction with an object removes ambiguity about which object was accessed by the code. It is then clear which object placed the error code in **Err.Number**, as well as which object originally generated the error (the object specified in **Err.Source**). **On Error GoTo 0** disables error handling in the current procedure. It doesn't specify line 0 as the start of the error-handling code, even if the procedure contains a line numbered 0. Without an **On Error GoTo 0** statement, an error handler is automatically disabled when a procedure is exited. @@ -58,14 +58,14 @@ End Sub Here, the error-handling code follows the **Exit Sub** statement and precedes the [**End Sub**](End) statement to separate it from the procedure flow. Error-handling code can be placed anywhere in a procedure. -If you create an object that accesses other objects, you should try to handle errors passed back from them unhandled. If you cannot handle such errors, map the error code in **Err.Number** to one of your own errors, and then pass them back to the caller of your object. You should specify your error by adding your error code to the **vbObjectError** constant. For example, if your error code is 1052, assign it as follows: +When creating an object that accesses other objects, try to handle errors passed back from them unhandled. When such errors cannot be handled, map the error code in **Err.Number** to a project-specific error, and then pass it back to the caller of the object. Specify the error by adding the project error code to the **vbObjectError** constant. For example, if the error code is 1052, assign it as follows: ```tb Err.Number = vbObjectError + 1052 ``` > [!NOTE] -> System errors during calls to Windows dynamic-link libraries (DLLs) don't raise exceptions and cannot be trapped with twinBASIC error trapping. When calling DLL functions, you should check each return value for success or failure (according to the API specifications), and in the event of a failure, check the value in the **Err** object's **LastDLLError** property. +> System errors during calls to Windows dynamic-link libraries (DLLs) don't raise exceptions and cannot be trapped with twinBASIC error trapping. When calling DLL functions, check each return value for success or failure (according to the API specifications), and in the event of a failure, check the value in the **Err** object's **LastDLLError** property. ### Example diff --git a/docs/Reference/Core/On-GoTo.md b/docs/Reference/Core/On-GoTo.md index 6953068f..e71fb1ac 100644 --- a/docs/Reference/Core/On-GoTo.md +++ b/docs/Reference/Core/On-GoTo.md @@ -28,7 +28,7 @@ The value of *expression* determines which line is branched to in *destinationli | Negative | An error occurs. | | Greater than 255 | An error occurs. | -You can mix line numbers and line labels in the same list. Use as many line labels and line numbers as you like with **On...GoSub** and **On...GoTo**. However, if you use more labels or numbers than fit on a single line, you must use the line-continuation character to continue the logical line onto the next physical line. +Line numbers and line labels can be mixed in the same list. Any number of line labels and line numbers can be used with **On...GoSub** and **On...GoTo**. However, when more labels or numbers are present than fit on a single line, the line-continuation character must be used to continue the logical line onto the next physical line. > [!TIP] > [**Select Case**](Select-Case) provides a more structured and flexible way to perform multiple branching. diff --git a/docs/Reference/Core/Open.md b/docs/Reference/Core/Open.md index 69481eaa..c4783ee3 100644 --- a/docs/Reference/Core/Open.md +++ b/docs/Reference/Core/Open.md @@ -21,21 +21,21 @@ Syntax: : Keyword specifying the file mode: **Append**, **Binary**, **Input**, **Output**, or **Random**. If unspecified, the file is opened for **Random** access. *access* -: *optional* Keyword specifying the operations permitted on the open file: **Read**, **Write**, or **Read Write**. +: *optional* Keyword specifying the operations permitted on the open file: **Read**, **Write**, or **Read Write**. *lock* -: *optional* Keyword specifying the operations restricted on the open file by other processes: **Shared**, **Lock Read**, **Lock Write**, or **Lock Read Write**. +: *optional* Keyword specifying the operations restricted on the open file by other processes: **Shared**, **Lock Read**, **Lock Write**, or **Lock Read Write**. *encoding* -: *optional* An encoding identifier — for example **utf_8**, **utf_16**, **windows_1252_western**, or **default_system_ansi**. See [Text Encodings](#text-encodings) below for the full list. The **Encoding** clause applies to text-mode I/O (**Input**, **Output**, **Append**); it has no effect on **Binary** or **Random** mode files. +: *optional* An encoding identifier --- for example **utf_8**, **utf_16**, **windows_1252_western**, or **default_system_ansi**. See [Text Encodings](#text-encodings) below for the full list. The **Encoding** clause applies to text-mode I/O (**Input**, **Output**, **Append**); it has no effect on **Binary** or **Random** mode files. *filenumber* : A valid file number in the range 1 to 511, inclusive. Use the [**FreeFile**](../Modules/FileSystem/FreeFile) function to obtain the next available file number. *reclength* -: *optional* Number less than or equal to 32,767 (bytes). For files opened for random access, this value is the record length. For sequential files, this value is the number of characters buffered. +: *optional* Number less than or equal to 32,767 (bytes). For files opened for random access, this value is the record length. For sequential files, this value is the number of characters buffered. -You must open a file before any I/O operation can be performed on it. **Open** allocates a buffer for I/O to the file and determines the mode of access to use with the buffer. +A file must be opened before any I/O operation can be performed on it. **Open** allocates a buffer for I/O to the file and determines the mode of access to use with the buffer. If the file specified by *pathname* doesn't exist, it is created when a file is opened for **Append**, **Binary**, **Output**, or **Random** modes. @@ -44,7 +44,7 @@ If the file is already opened by another process, and the specified type of acce The **Len** clause is ignored if *mode* is **Binary**. > [!IMPORTANT] -> In **Binary**, **Input**, and **Random** modes, you can open a file by using a different file number without first closing the file. In **Append** and **Output** modes, you must close a file before opening it with a different file number. +> In **Binary**, **Input**, and **Random** modes, a file can be opened with a different file number without first closing the file. In **Append** and **Output** modes, a file must be closed before opening it with a different file number. > [!NOTE] > The **Encoding** clause is a twinBASIC extension. Classic VBA has no equivalent and reads or writes text using the system ANSI code page only. @@ -107,7 +107,7 @@ Close #1 ### Text Encodings -These identifier strings are accepted as the **Encoding** argument. The constants listed below name the well-known encodings; other system-supported encodings with similar identifier strings are also accepted at runtime. All members are marked **[Hidden, Restricted]** — they are omitted from general IntelliSense, but the IDE shows them automatically after the **Encoding** keyword. +These identifier strings are accepted as the **Encoding** argument. The constants listed below name the well-known encodings; other system-supported encodings with similar identifier strings are also accepted at runtime. All members are marked **[Hidden, Restricted]** --- they are omitted from general IntelliSense, but the IDE shows them automatically after the **Encoding** keyword. #### Default and Unicode diff --git a/docs/Reference/Core/Option.md b/docs/Reference/Core/Option.md index 53f47b31..cd5ab046 100644 --- a/docs/Reference/Core/Option.md +++ b/docs/Reference/Core/Option.md @@ -24,7 +24,7 @@ Because the default base is **0**, the **Option Base** statement is never requir If used, the statement must appear in a [module](../Gloss#module) or [class](../Gloss#class) before any procedures, functions, or properties. **Option Base** can appear only once in a module and must precede array [declarations](../Gloss#declaration) that include dimensions. > [!NOTE] -> The **To** clause in the [**Dim**](Dim), [**Private**](Private), [**Public**](Public), [**ReDim**](ReDim), and [**Static**](Static) statements provides a more flexible way to control the range of an array's subscripts. However, if you don't explicitly set the lower bound with a **To** clause, you can use **Option Base** to change the default lower bound to 1. The base of an array created with the [**ParamArray**](ParamArray) keyword is zero; **Option Base** does not affect [**ParamArray**](ParamArray) (or the [**Array**](../../tB/Core/Array) function). +> The **To** clause in the [**Dim**](Dim), [**Private**](Private), [**Public**](Public), [**ReDim**](ReDim), and [**Static**](Static) statements provides a more flexible way to control the range of an array's subscripts. However, when the lower bound is not explicitly set with a **To** clause, **Option Base** can change the default lower bound to 1. The base of an array created with the [**ParamArray**](ParamArray) keyword is zero; **Option Base** does not affect [**ParamArray**](ParamArray) (or the [**Array**](../../tB/Core/Array) function). The **Option Base** statement only affects the lower bound of arrays in the module where the statement is located. @@ -87,14 +87,14 @@ If used, the **Option Explicit** statement must appear in a module before any [p This option makes it mandatory to require variable declarations. There is no complementary option to make the declarations optional. -When **Option Explicit** appears in a module, you must explicitly declare all variables by using the [**Dim**](Dim), [**Private**](Private), [**Public**](Public), [**ReDim**](ReDim), and [**Static**](Static) **Static** statements. If you attempt to use an undeclared variable name, an error occurs at [compile time](../Gloss#compile-time). +When **Option Explicit** appears in a module, all variables must be explicitly declared by using the [**Dim**](Dim), [**Private**](Private), [**Public**](Public), [**ReDim**](ReDim), or [**Static**](Static) statements. Attempting to use an undeclared variable name raises an error at [compile time](../Gloss#compile-time). -If you don't use the **Option Explicit** statement, and when the [**Option Explicit On**](../IDE/Project/Settings#option-explicit-on) project setting is changed to its non-default value of *No*, all undeclared variables are of **Variant** type unless the default type is otherwise specified with a [**Def**_type_](Deftype) statement. +Without the **Option Explicit** statement, and when the [**Option Explicit On**](../IDE/Project/Settings#option-explicit-on) project setting is changed to its non-default value of *No*, all undeclared variables are of **Variant** type unless the default type is otherwise specified with a [**Def**_type_](Deftype) statement. > [!NOTE] > The **Option Explicit On** project setting is *Yes* by default in new projects. -> -> Use **Option Explicit** to avoid incorrectly typing the name of an existing variable or to avoid confusion in code where the [scope](../Gloss#scope) of the variable is not clear. + +**Option Explicit** prevents incorrect typing of an existing variable's name, and removes confusion where the [scope](../Gloss#scope) of a variable is not clear. ### See Also {: .no_toc } @@ -122,7 +122,7 @@ Syntax: **Option Compare** { **Binary** \| **Text** \| **Database** } If used, the **Option Compare** statement must appear in a [module](../Gloss#module) before any [procedures](../Gloss#procedure). -The **Option Compare** statement specifies the [string comparison](../Gloss#string-comparison) method (**Binary**, **Text**, or** Database**) for a module. If a module doesn't include an **Option Compare** statement, the default text comparison method is **Binary**. +The **Option Compare** statement specifies the [string comparison](../Gloss#string-comparison) method (**Binary**, **Text**, or **Database**) for a module. If a module doesn't include an **Option Compare** statement, the default text comparison method is **Binary**. * **Option Compare Binary** results in string comparisons based on a [sort order](../Gloss#sort-order) derived from the internal binary representations of the characters. In Microsoft Windows, sort order is determined by the code page. A typical binary sort order is shown in the following example: @@ -130,7 +130,7 @@ The **Option Compare** statement specifies the [string comparison](../Gloss#stri A < B < E < Z < a < b < e < z < À < Ê < Ø < à < ê < ø ``` -* **Option Compare Text** results in string comparisons based on a case-insensitive text sort order determined by your system's [locale](../Gloss#locale). When the same characters are sorted by using **Option Compare Text**, the following text sort order is produced: +* **Option Compare Text** results in string comparisons based on a case-insensitive text sort order determined by the system's [locale](../Gloss#locale). When the same characters are sorted by using **Option Compare Text**, the following text sort order is produced: ```tb (A=a) < ( À=à) < (B=b) < (E=e) < (Ê=ê) < (Z=z) < (Ø=ø) diff --git a/docs/Reference/Core/Or.md b/docs/Reference/Core/Or.md index 5de51192..5f19c4d8 100644 --- a/docs/Reference/Core/Or.md +++ b/docs/Reference/Core/Or.md @@ -43,7 +43,7 @@ The **Or** operator performs a bitwise comparison of identically positioned bits | 1 | 1 | 1 | > [!NOTE] -> **Or** evaluates *both* operands every time, even when *expression1* alone determines the result. Use [**OrElse**](OrElse) when you want short-circuit evaluation — for example, when *expression2* is expensive, has side effects, or only matters when *expression1* is **False**. +> **Or** evaluates *both* operands every time, even when *expression1* alone determines the result. Use [**OrElse**](OrElse) for short-circuit evaluation --- for example, when *expression2* is expensive, has side effects, or only matters when *expression1* is **False**. ### Example diff --git a/docs/Reference/Core/ParamArray.md b/docs/Reference/Core/ParamArray.md index 1d7efafb..fc29d816 100644 --- a/docs/Reference/Core/ParamArray.md +++ b/docs/Reference/Core/ParamArray.md @@ -7,7 +7,7 @@ vba_attribution: true # ParamArray {: .no_toc } -Used in the argument list of a [**Sub**](Sub), [**Function**](Function), or [**Property**](Property) procedure to indicate that the final parameter is an open-ended list of arguments. The **ParamArray** keyword allows the procedure to accept an arbitrary number of arguments at the call site. +Used in the argument list of a [**Sub**](Sub), [**Function**](Function), or [**Property**](Property) procedure to indicate that the final parameter is an open-ended list of arguments. The **ParamArray** keyword permits the procedure to accept an arbitrary number of arguments at the call site. Syntax: > [ **Public** \| **Private** \| **Friend** ] [ **Static** ] **Sub** \| **Function** \| **Property Get** \| **Property Let** \| **Property Set** *name* **(** [ *arglist*, ] **ParamArray** *varname*[ **()** ] [ **As** *type* ] **)** @@ -16,11 +16,11 @@ Syntax: : Name of the variable representing the **ParamArray**; follows standard variable naming conventions. *type* -: *optional* Must be **Variant** (explicitly or by default). Each argument supplied at the call site can be of a different data type, so **ParamArray** must always be an array of **Variant** elements. +: *optional* Must be **Variant** (explicitly or by default). Each argument supplied at the call site can be of a different data type, so **ParamArray** must always be an array of **Variant** elements. **ParamArray** must be the last parameter in the argument list of a **Sub**, **Function**, or **Property Get** procedure. In a **Property Let** or **Property Set** procedure it must precede the *value*/*reference* parameter and so cannot be the only parameter. -**ParamArray** cannot be combined with **Optional**, **ByVal**, or **ByRef** on the same parameter — arguments supplied to a **ParamArray** are always passed by reference as elements of a **Variant** array. +**ParamArray** cannot be combined with **Optional**, **ByVal**, or **ByRef** on the same parameter --- arguments supplied to a **ParamArray** are always passed by reference as elements of a **Variant** array. When the procedure is called, each argument supplied in the call becomes a corresponding element of the **Variant** array. If no arguments are supplied for the **ParamArray** position, the array is empty. diff --git a/docs/Reference/Core/Plus.md b/docs/Reference/Core/Plus.md index 9b6ce548..3f2cbc07 100644 --- a/docs/Reference/Core/Plus.md +++ b/docs/Reference/Core/Plus.md @@ -8,7 +8,7 @@ vba_attribution: true # + and += operators {: .no_toc } -Used to sum two numbers, or — depending on operand types — to concatenate two strings. The compound form **+=** adds-and-assigns in one step. +Used to sum two numbers, or --- depending on operand types --- to concatenate two strings. The compound form **+=** adds-and-assigns in one step. Syntax: > *result* **=** *expression1* **+** *expression2* @@ -23,7 +23,7 @@ Syntax: *expression*, *expression1*, *expression2* : Any expressions. -When you use the **+** operator, you may not be able to determine whether addition or string concatenation will occur. Use the [**&**](Concat) operator for concatenation to eliminate ambiguity and produce self-documenting code. +When the **+** operator is used, it may not be obvious whether addition or string concatenation will occur. Use the [**&**](Concat) operator for concatenation to eliminate ambiguity and produce self-documenting code. If at least one expression is not a **Variant**, the following rules apply: @@ -62,7 +62,7 @@ If one or both expressions are **Null** expressions, *result* is **Null**. If bo ### Compound assignment -`x += y` is the twinBASIC shorthand for `x = x + y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** / **Empty** rules described above. Like all of twinBASIC's compound-assignment operators, **+=** is a statement, not an expression — it does not produce a value. +`x += y` is the twinBASIC shorthand for `x = x + y`. The left-hand side is evaluated once; the result follows the same type-promotion and **Null** / **Empty** rules described above. Like all of twinBASIC's compound-assignment operators, **+=** is a statement, not an expression --- it does not produce a value. ```tb Dim Total As Long = 0 @@ -75,7 +75,7 @@ Greeting += ", world" ' Greeting is now "Hello, world". ### Example -This example uses the **+** operator to sum numbers. The **+** operator can also be used to concatenate strings, but to eliminate ambiguity you should use the [**&**](Concat) operator instead. +This example uses the **+** operator to sum numbers. The **+** operator can also be used to concatenate strings, but to eliminate ambiguity use the [**&**](Concat) operator instead. ```tb Dim MyNumber, Var1, Var2 diff --git a/docs/Reference/Core/Print.md b/docs/Reference/Core/Print.md index 53d67867..e52512c2 100644 --- a/docs/Reference/Core/Print.md +++ b/docs/Reference/Core/Print.md @@ -19,7 +19,7 @@ Syntax: : Any valid file number. *outputlist* -: *optional* Expression or list of expressions to print. The *outputlist* settings are: +: *optional* Expression or list of expressions to print. The *outputlist* settings are: > [ { **Spc(***n***)** \| **Tab** [ **(***n***)** ] } ] [ *expression* ] [ *charpos* ] @@ -37,13 +37,13 @@ Syntax: Data written with **Print #** is usually read from a file with [**Line Input #**](Line-Input) or [**Input #**](Input). -If you omit *outputlist* and include only a list separator after *filenumber*, a blank line is printed to the file. +When *outputlist* is omitted and only a list separator follows *filenumber*, a blank line is printed to the file. Multiple expressions can be separated with either a space or a semicolon. A space has the same effect as a semicolon. For **Boolean** data, either `True` or `False` is printed. The **True** and **False** keywords are not translated, regardless of the locale. -**Date** data is written to the file by using the standard short date format recognized by your system. When either the date or the time component is missing or zero, only the part provided gets written to the file. +**Date** data is written to the file by using the standard short date format recognized by the system. When either the date or the time component is missing or zero, only the part provided gets written to the file. Nothing is written to the file if *outputlist* data is **Empty**. However, if *outputlist* data is **Null**, `Null` is written to the file. @@ -51,10 +51,10 @@ For **Error** data, the output appears as `Error `*errorcode*. The **Error** key All data written to the file by using **Print #** is internationally-aware; that is, the data is properly formatted by using the appropriate decimal separator. -Because **Print #** writes an image of the data to the file, you must delimit the data so that it prints correctly. If you use **Tab** with no arguments to move the print position to the next print zone, **Print #** also writes the spaces between print fields to the file. +Because **Print #** writes an image of the data to the file, the data must be delimited so that it prints correctly. When **Tab** is used with no arguments to move the print position to the next print zone, **Print #** also writes the spaces between print fields to the file. > [!NOTE] -> If, at some future time, you want to read the data from a file by using the **Input #** statement, use the [**Write #**](Write) statement instead of the **Print #** statement to write the data to the file. Using **Write #** ensures the integrity of each separate data field by properly delimiting it, so that it can be read back in by using **Input #**. Using **Write #** also ensures that it can be correctly read in any locale. +> When the data is later read from a file by using the **Input #** statement, use the [**Write #**](Write) statement instead of the **Print #** statement to write the data to the file. Using **Write #** ensures the integrity of each separate data field by properly delimiting it, so that it can be read back in by using **Input #**. Using **Write #** also ensures that it can be correctly read in any locale. ### Example diff --git a/docs/Reference/Core/Private.md b/docs/Reference/Core/Private.md index 5418f0de..1684602c 100644 --- a/docs/Reference/Core/Private.md +++ b/docs/Reference/Core/Private.md @@ -13,19 +13,19 @@ Syntax: > **Private** [ **WithEvents** ] *varname* [ **(** [ *subscripts* ] **)** ] [ **As** [ **New** ] *type* ] [ **,** [ **WithEvents** ] *varname* [ **(** [ *subscripts* ] **)** ] [ **As** [ **New** ] *type* ]] **. . .** **WithEvents** -: *optional* Keyword that specifies that *varname* is an object variable used to respond to events triggered by an ActiveX object. **WithEvents** is valid only in class modules. You can declare as many individual variables as you like by using **WithEvents**, but you can't create arrays with **WithEvents**, nor can you use **New** with **WithEvents**. +: *optional* Keyword that specifies that *varname* is an object variable used to respond to events triggered by an ActiveX object. **WithEvents** is valid only in class modules. Any number of individual variables may be declared by using **WithEvents**, but arrays cannot be declared with **WithEvents**, nor can **New** be combined with **WithEvents**. *varname* : Name of the variable; follows standard variable naming conventions. *subscripts* -: *optional* Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. +: *optional* Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. **New** -: *optional* Keyword that enables implicit creation of an object. If you use **New** when declaring the object variable, a new instance of the object is created on first reference to it, so you don't have to use the **[Set](Set)** statement to assign the object reference. The **New** keyword can't be used to declare variables of any intrinsic data type or to declare instances of dependent objects, and it can't be used with **WithEvents**. +: *optional* Keyword that enables implicit creation of an object. When **New** is used to declare the object variable, a new instance of the object is created on first reference to it, so the **[Set](Set)** statement is not required to assign the object reference. The **New** keyword can't be used to declare variables of any intrinsic data type or to declare instances of dependent objects, and it can't be used with **WithEvents**. *type* -: *optional* Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type, or an object type. Use a separate **As** *type* clause for each variable being defined. +: *optional* Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type, or an object type. Use a separate **As** *type* clause for each variable being defined. **Private** variables are available only to the module in which they are declared. @@ -35,7 +35,7 @@ Use the **Private** statement to declare the data type of a variable. For exampl Private NumberOfEmployees As Integer ``` -You can also use a **Private** statement to declare the object type of a variable. The following statement declares a variable for a new instance of a worksheet: +A **Private** statement can also declare the object type of a variable. The following statement declares a variable for a new instance of a worksheet: ```tb Private X As New Worksheet @@ -43,9 +43,9 @@ Private X As New Worksheet If the **New** keyword isn't used when declaring an object variable, the variable that refers to the object must be assigned an existing object by using the **Set** statement before it can be used. Until it is assigned an object, the declared object variable has the special value **Nothing**, which indicates that it doesn't refer to any particular instance of an object. -If you don't specify a data type or object type, and there is no [**Deftype**](Deftype) statement in the module, the variable is **Variant** by default. +When no data type or object type is specified, and there is no [**Deftype**](Deftype) statement in the module, the variable is **Variant** by default. -You can also use the **Private** statement with empty parentheses to declare a dynamic array. After declaring a dynamic array, use the **[ReDim](ReDim)** statement within a procedure to define the number of dimensions and elements in the array. If you try to redeclare a dimension for an array variable whose size was explicitly specified in a **Private**, [**Public**](Public), or [**Dim**](Dim) statement, an error occurs. +The **Private** statement with empty parentheses also declares a dynamic array. After declaring a dynamic array, use the **[ReDim](ReDim)** statement within a procedure to define the number of dimensions and elements in the array. Redeclaring a dimension for an array variable whose size was explicitly specified in a **Private**, [**Public**](Public), or [**Dim**](Dim) statement raises an error. When variables are initialized, a numeric variable is initialized to 0, a variable-length string is initialized to a zero-length string (""), and a fixed-length string is filled with zeros. **Variant** variables are initialized to **Empty**. Each element of a user-defined type variable is initialized as if it were a separate variable. diff --git a/docs/Reference/Core/Property.md b/docs/Reference/Core/Property.md index 76d7fc83..e2aa0f13 100644 --- a/docs/Reference/Core/Property.md +++ b/docs/Reference/Core/Property.md @@ -45,40 +45,40 @@ Syntax: : *optional* One or more of the [supported attributes](Attributes) for procedures. **Public** -: *optional* Indicates that the **Property** procedure is accessible to all other procedures in all modules. If used in a module that contains an **Option Private** statement, the procedure is not available outside the project. +: *optional* Indicates that the **Property** procedure is accessible to all other procedures in all modules. If used in a module that contains an **Option Private** statement, the procedure is not available outside the project. **Private** -: *optional* Indicates that the **Property** procedure is accessible only to other procedures in the module where it is declared. +: *optional* Indicates that the **Property** procedure is accessible only to other procedures in the module where it is declared. **Friend** -: *optional* Used only in a class module. Indicates that the **Property** procedure is visible throughout the project, but not visible to a controller of an instance of an object. +: *optional* Used only in a class module. Indicates that the **Property** procedure is visible throughout the project, but not visible to a controller of an instance of an object. **[Protected](Protected)** -: *optional* (twinBASIC) Used only in a class. Indicates that the **Property** procedure is accessible from inside the declaring class and from classes that derive from it via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop), but not from outside callers. All three accessor forms of the same property (**Get**, **Let**, **Set**) should agree on the access modifier. +: *optional* (twinBASIC) Used only in a class. Indicates that the **Property** procedure is accessible from inside the declaring class and from classes that derive from it via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop), but not from outside callers. All three accessor forms of the same property (**Get**, **Let**, **Set**) should agree on the access modifier. **[Static](Static)** -: *optional* Indicates that the **Property** procedure's local variables are preserved between calls. The **Static** attribute doesn't affect variables that are declared outside the **Property** procedure, even if they are used in the procedure. +: *optional* Indicates that the **Property** procedure's local variables are preserved between calls. The **Static** attribute doesn't affect variables that are declared outside the **Property** procedure, even if they are used in the procedure. **Overridable** -: *optional* (twinBASIC) Marks the **Property** as an inheritance hook that classes derived via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop) may replace with an **Overrides** clause. Meaningful only on a member of a class that participates in an **Inherits** hierarchy. +: *optional* (twinBASIC) Marks the **Property** as an inheritance hook that classes derived via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop) may replace with an **Overrides** clause. Meaningful only on a member of a class that participates in an **Inherits** hierarchy. *name* : Name of the **Property** procedure; follows standard variable naming conventions, except that the same name is shared by the matching **Property Get**, **Property Let**, and **Property Set** procedures in the same module. **Of** *typevars* -: *optional* One or more type variable names, following standard variable naming conventions. The names are separated by commas. Causes the procedure to be a generic **Property** procedure. The matching **Property Get**, **Property Let**, and **Property Set** procedures must declare the same generic parameters. +: *optional* One or more type variable names, following standard variable naming conventions. The names are separated by commas. Causes the procedure to be a generic **Property** procedure. The matching **Property Get**, **Property Let**, and **Property Set** procedures must declare the same generic parameters. *arglist* : List of variables representing arguments that are passed to the **Property** procedure when it is called. Multiple arguments are separated by commas. The name and data type of each argument in a **Property Let** or **Property Set** procedure must be the same as the corresponding argument in the matching **Property Get** procedure. See [*arglist*](#arglist) below for syntax. *arglist* is optional for **Property Get**; for **Property Let** and **Property Set** at least the *value*/*reference* parameter is required. **As** *type* -: *optional* Data type of the value returned by the **Property Get** procedure; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (except fixed length), **Object**, **Variant**, a user-defined type, or an array. The return *type* of a **Property Get** procedure must be the same data type as the *value* parameter of the corresponding **Property Let** procedure (if one exists), or compatible with the *reference* parameter of the corresponding **Property Set** procedure. +: *optional* Data type of the value returned by the **Property Get** procedure; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (except fixed length), **Object**, **Variant**, a user-defined type, or an array. The return *type* of a **Property Get** procedure must be the same data type as the *value* parameter of the corresponding **Property Let** procedure (if one exists), or compatible with the *reference* parameter of the corresponding **Property Set** procedure. *statements* -: *optional* Any group of statements to be executed within the body of the **Property** procedure. +: *optional* Any group of statements to be executed within the body of the **Property** procedure. *expression* -: *optional* In **Property Get**, the value (or reference, when assigned with **Set**) returned by the procedure. +: *optional* In **Property Get**, the value (or reference, when assigned with **Set**) returned by the procedure. *value* : In **Property Let**, the variable that contains the value to be assigned to the property. When the procedure is called, this argument appears on the right side of the calling expression. The data type of *value* must be the same as the return type of the corresponding **Property Get** procedure. *value* cannot be **Optional** or a **ParamArray**. @@ -87,17 +87,17 @@ Syntax: : In **Property Set**, the variable containing the object reference used on the right side of the object reference assignment. *reference* cannot be **Optional**. *binding-clause* -: *optional* (twinBASIC) One of three trailing clauses that bind this accessor to a member declared elsewhere: +: *optional* (twinBASIC) One of three trailing clauses that bind this accessor to a member declared elsewhere: - - **Handles** *object*.*event* [ **,** *object*.*event* … ] — wires the property up as a handler for the named event(s), replacing the traditional `Object_Event` naming convention. See [**Handles** statement](Handles). - - **Implements** *iface*.*member* [ **,** *iface2*.*member2* … ] — provides the body for the named [**Interface**](Interface) (or [**Class**](Class)) member, replacing the traditional `Iface_Member` naming convention. A comma-separated list lets one body satisfy several interfaces' members at once. See [**Implements** statement](Implements). - - **Overrides** *base*.*member* — supplies the body for an **Overridable** *member* inherited via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop). Combine with **Overridable** on the same header to allow further-derived classes to override again. + - **Handles** *object*.*event* [ **,** *object*.*event* … ] --- connects the property as a handler for the named event(s), replacing the traditional `Object_Event` naming convention. See [**Handles** statement](Handles). + - **Implements** *iface*.*member* [ **,** *iface2*.*member2* … ] --- provides the body for the named [**Interface**](Interface) (or [**Class**](Class)) member, replacing the traditional `Iface_Member` naming convention. A comma-separated list permits one body to satisfy several interfaces' members at once. See [**Implements** statement](Implements). + - **Overrides** *base*.*member* --- supplies the body for an **Overridable** *member* inherited via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop). Combine with **Overridable** on the same header to allow further-derived classes to override again. **[Exit Property](Exit)** -: *optional* Immediately returns from the **Property** procedure without setting a return value. Valid in **Property Get**, **Property Let**, and **Property Set**. +: *optional* Immediately returns from the **Property** procedure without setting a return value. Valid in **Property Get**, **Property Let**, and **Property Set**. **[Return](Return)** *expression* -: *optional* Valid only in a **Property Get** procedure. Immediately returns from the procedure with *expression* as the property's value. The *expression* is required in this form; a bare **Return** is reserved for the [**GoSub...Return**](GoSub-Return) construct and does not exit a **Property** procedure. +: *optional* Valid only in a **Property Get** procedure. Immediately returns from the procedure with *expression* as the property's value. The *expression* is required in this form; a bare **Return** is reserved for the [**GoSub...Return**](GoSub-Return) construct and does not exit a **Property** procedure. ### *arglist* @@ -105,32 +105,32 @@ Syntax: One or more of [ **Optional** ] [ **ByVal** \| **ByRef** ] [ **[ParamArray](ParamArray)** ] *varname* [ **()** ] [ **As** *type* ] [ **=** *defaultvalue* ] **Optional** -: *optional* Indicates that an argument is not required. If used, all subsequent arguments in *arglist* must also be optional and declared by using the **Optional** keyword. The right side of a **Property Let** or **Property Set** call (the *value* or *reference* parameter) cannot be **Optional**. +: *optional* Indicates that an argument is not required. If used, all subsequent arguments in *arglist* must also be optional and declared by using the **Optional** keyword. The right side of a **Property Let** or **Property Set** call (the *value* or *reference* parameter) cannot be **Optional**. **ByVal** -: *optional* Indicates that the argument is passed by value. +: *optional* Indicates that the argument is passed by value. **ByRef** -: *optional* Indicates that the argument is passed by reference. **ByRef** is the default unlike in Visual Basic .NET. +: *optional* Indicates that the argument is passed by reference. **ByRef** is the default unlike in Visual Basic .NET. **[ParamArray](ParamArray)** -: *optional* Indicates that the argument is an **Optional** array of **Variant** elements. The **ParamArray** keyword allows you to provide an arbitrary number of arguments. It may not be used with **ByVal**, **ByRef**, or **Optional**, and it may not be the *value*/*reference* parameter of a **Property Let** or **Property Set** procedure. +: *optional* Indicates that the argument is an **Optional** array of **Variant** elements. The **ParamArray** keyword permits passing an arbitrary number of arguments. It may not be used with **ByVal**, **ByRef**, or **Optional**, and it may not be the *value*/*reference* parameter of a **Property Let** or **Property Set** procedure. *varname* : Name of the variable representing the argument; follows standard variable naming conventions. *type* -: *optional* Data type of the argument passed to the procedure; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (variable length only), **Object**, **Variant**, a specific object type, or the name of a generic type argument. If the parameter is not **Optional**, a user-defined type may also be specified. +: *optional* Data type of the argument passed to the procedure; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (variable length only), **Object**, **Variant**, a specific object type, or the name of a generic type argument. If the parameter is not **Optional**, a user-defined type may also be specified. If the name of a generic type parameter is used, it becomes bound to the concrete type of the argument passed to the procedure. The name binding has the scope of the body of the procedure. *defaultvalue* -: *optional* Any constant or constant expression. Valid for **Optional** parameters only. If the type is an **Object**, an explicit default value can only be **Nothing**. +: *optional* Any constant or constant expression. Valid for **Optional** parameters only. If the type is an **Object**, an explicit default value can only be **Nothing**. If not explicitly specified by using **Public**, **Private**, or **Friend**, **Property** procedures are public by default. If **Static** isn't used, the value of local variables is not preserved between calls. The **Friend** keyword can only be used in class modules. However, **Friend** procedures can be accessed by procedures in any module of a project. A **Friend** procedure doesn't appear in the type library of its parent class, nor can a **Friend** procedure be late bound. -All executable code must be in procedures. You can't define a **Property** procedure inside another **[Property](Property)**, **[Sub](Sub)**, or **[Function](Function)** procedure. +All executable code must be in procedures. A **Property** procedure cannot be defined inside another **[Property](Property)**, **[Sub](Sub)**, or **[Function](Function)** procedure. The **[Exit Property](Exit)** statement, and the **[Return](Return)** *expression* statement (in **Property Get** only), cause an immediate exit from a **Property** procedure. Program execution continues with the statement following the statement that called the **Property** procedure. Any number of these statements can appear anywhere in a **Property** procedure. diff --git a/docs/Reference/Core/Protected.md b/docs/Reference/Core/Protected.md index 452db94e..c42b1b20 100644 --- a/docs/Reference/Core/Protected.md +++ b/docs/Reference/Core/Protected.md @@ -18,7 +18,7 @@ Syntax: In a variable declaration, **Protected** has the same form as [**Private**](Private)/[**Public**](Public): a comma-separated list of names with optional `WithEvents`/`New` and `As`-clause. **Protected** is valid only at class scope; it cannot be used inside a procedure (use [**Dim**](Dim) or [**Static**](Static)), and it cannot be used in a [**Module**](Module) (modules have no notion of derived types). -In a procedure declaration, **Protected** replaces the **Public**/**Private**/**Friend** modifier. Combined with the **Overridable** keyword, it declares an inheritance hook — a method or property that derived classes are allowed to override. +In a procedure declaration, **Protected** replaces the **Public**/**Private**/**Friend** modifier. Combined with the **Overridable** keyword, it declares an inheritance hook --- a method or property that derived classes are allowed to override. ### Visibility summary diff --git a/docs/Reference/Core/Public.md b/docs/Reference/Core/Public.md index b560a037..2880bc59 100644 --- a/docs/Reference/Core/Public.md +++ b/docs/Reference/Core/Public.md @@ -13,19 +13,19 @@ Syntax: > **Public** [ **WithEvents** ] *varname* [ **(** [ *subscripts* ] **)** ] [ **As** [ **New** ] *type* ] [ **,** [ **WithEvents** ] *varname* [ **(** [ *subscripts* ] **)** ] [ **As** [ **New** ] *type* ]] **. . .** **WithEvents** -: *optional* Keyword specifying that *varname* is an object variable used to respond to events triggered by an ActiveX object. **WithEvents** is valid only in class modules. You can declare as many individual variables as you like by using **WithEvents**, but you can't create arrays with **WithEvents**, nor can you use **New** with **WithEvents**. +: *optional* Keyword specifying that *varname* is an object variable used to respond to events triggered by an ActiveX object. **WithEvents** is valid only in class modules. Any number of individual variables may be declared by using **WithEvents**, but arrays cannot be declared with **WithEvents**, nor can **New** be combined with **WithEvents**. *varname* : Name of the variable; follows standard naming conventions. *subscripts* -: *optional* Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. +: *optional* Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. **New** -: *optional* Keyword that enables implicit creation of an object. If you use **New** when declaring the object variable, a new instance of the object is created on first reference to it, so you don't have to use the **[Set](Set)** statement to assign the object reference. The **New** keyword can't be used to declare variables of any intrinsic data type or to declare instances of dependent objects, and it can't be used with **WithEvents**. +: *optional* Keyword that enables implicit creation of an object. When **New** is used to declare the object variable, a new instance of the object is created on first reference to it, so the **[Set](Set)** statement is not required to assign the object reference. The **New** keyword can't be used to declare variables of any intrinsic data type or to declare instances of dependent objects, and it can't be used with **WithEvents**. *type* -: *optional* Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type, or an object type. Use a separate **As** *type* clause for each variable being defined. +: *optional* Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type, or an object type. Use a separate **As** *type* clause for each variable being defined. Variables declared by using the **Public** statement are available to all procedures in all modules in all applications, unless **[Option Private Module](Option)** is in effect; in which case, the variables are public only within the project in which they reside. @@ -45,9 +45,9 @@ Public X As New Worksheet If the **New** keyword is not used when declaring an object variable, the variable that refers to the object must be assigned an existing object by using the **Set** statement before it can be used. Until it is assigned an object, the declared object variable has the special value **Nothing**, which indicates that it doesn't refer to any particular instance of an object. -You can also use the **Public** statement with empty parentheses to declare a dynamic array. After declaring a dynamic array, use the **[ReDim](ReDim)** statement within a procedure to define the number of dimensions and elements in the array. If you try to redeclare a dimension for an array variable whose size was explicitly specified in a [**Private**](Private), **Public**, or [**Dim**](Dim) statement, an error occurs. +The **Public** statement with empty parentheses also declares a dynamic array. After declaring a dynamic array, use the **[ReDim](ReDim)** statement within a procedure to define the number of dimensions and elements in the array. Redeclaring a dimension for an array variable whose size was explicitly specified in a [**Private**](Private), **Public**, or [**Dim**](Dim) statement raises an error. -If you don't specify a data type or object type, and there is no [**Deftype**](Deftype) statement in the module, the variable is **Variant** by default. +When no data type or object type is specified, and there is no [**Deftype**](Deftype) statement in the module, the variable is **Variant** by default. When variables are initialized, a numeric variable is initialized to 0, a variable-length string is initialized to a zero-length string (""), and a fixed-length string is filled with zeros. **Variant** variables are initialized to **Empty**. Each element of a user-defined type variable is initialized as if it were a separate variable. diff --git a/docs/Reference/Core/Put.md b/docs/Reference/Core/Put.md index db353557..71681fda 100644 --- a/docs/Reference/Core/Put.md +++ b/docs/Reference/Core/Put.md @@ -16,14 +16,14 @@ Syntax: : Any valid file number. *recnumber* -: *optional* **Variant** (**Long**). Record number (**Random** mode files) or byte number (**Binary** mode files) at which writing begins. +: *optional* **Variant** (**Long**). Record number (**Random** mode files) or byte number (**Binary** mode files) at which writing begins. *varname* : Name of the variable containing data to be written to disk. Data written with **Put** is usually read from a file with [**Get**](Get). -The first record or byte in a file is at position 1, the second record or byte is at position 2, and so on. If you omit *recnumber*, the next record or byte after the last **Get** or **Put** statement, or pointed to by the last [**Seek**](../Modules/FileSystem/Seek) function, is written. You must include the delimiting commas: +The first record or byte in a file is at position 1, the second record or byte is at position 2, and so on. When *recnumber* is omitted, the next record or byte after the last **Get** or **Put** statement, or pointed to by the last [**Seek**](../Modules/FileSystem/Seek) function, is written. The delimiting commas must be included: ```tb Put #4, , FileBuffer @@ -38,7 +38,7 @@ For files opened in **Random** mode, the following rules apply: - If the variable being written is a **Variant** of a numeric type, **Put** writes 2 bytes identifying the **VarType** of the **Variant** and then writes the variable. For example, when writing a **Variant** of **VarType** 3, **Put** writes 6 bytes: 2 bytes identifying the **Variant** as **VarType** 3 (**Long**) and 4 bytes containing the **Long** data. The record length specified by the **Len** clause in the **Open** statement must be at least 2 bytes greater than the actual number of bytes required to store the variable. > [!NOTE] - > Use the **Put** statement to write a **Variant** array to disk, but you can't use **Put** to write a scalar **Variant** containing an array to disk. You also can't use **Put** to write objects to disk. + > Use the **Put** statement to write a **Variant** array to disk; **Put** cannot write a scalar **Variant** containing an array to disk. **Put** also cannot write objects to disk. - If the variable being written is a **Variant** of **VarType** 8 (**String**), **Put** writes 2 bytes identifying the **VarType**, 2 bytes indicating the length of the string, and then writes the string data. The record length specified by the **Len** clause in the **Open** statement must be at least 4 bytes greater than the actual length of the string. diff --git a/docs/Reference/Core/RaiseEvent.md b/docs/Reference/Core/RaiseEvent.md index c9e434f8..6b843185 100644 --- a/docs/Reference/Core/RaiseEvent.md +++ b/docs/Reference/Core/RaiseEvent.md @@ -16,11 +16,11 @@ Syntax: : Name of the event to fire. Must be the name of an [**Event**](Event) declared in the same module. *argumentlist* -: *optional* Comma-delimited list of variables, arrays, or expressions to pass as event arguments. The *argumentlist* must be enclosed by parentheses. If the event has no arguments, the parentheses must be omitted. +: *optional* Comma-delimited list of variables, arrays, or expressions to pass as event arguments. The *argumentlist* must be enclosed by parentheses. If the event has no arguments, the parentheses must be omitted. If the event has not been declared within the module in which it is raised, an error occurs. If the event has no arguments, including empty parentheses in the **RaiseEvent** invocation causes an error. -You can't use **RaiseEvent** to fire events that are not explicitly declared in the module. For example, if a form has a built-in **Click** event, you can't fire its **Click** event by using **RaiseEvent**. If you declare a **Click** event in the form module, it shadows the form's own **Click** event. +**RaiseEvent** cannot fire events that are not explicitly declared in the module. For example, even if a form has a built-in **Click** event, **RaiseEvent** cannot fire it. Declaring a **Click** event in the form module shadows the form's own **Click** event. Event firing is done in the order that connections were established. Because events can have **ByRef** parameters, a process that connects late may receive parameters that have been changed by an earlier event handler. diff --git a/docs/Reference/Core/ReDim.md b/docs/Reference/Core/ReDim.md index 752733b3..4aea6e05 100644 --- a/docs/Reference/Core/ReDim.md +++ b/docs/Reference/Core/ReDim.md @@ -13,25 +13,25 @@ Syntax: > **ReDim** [ **Preserve** ] *varname* **(** *subscripts* **)** [ **As** *type* ] [ **,** *varname* **(** *subscripts* **)** [ **As** *type* ] ] **. . .** **Preserve** -: *optional* Keyword used to preserve the data in an existing array when you change the size of the last dimension. +: *optional* Keyword used to preserve the data in an existing array when the size of the last dimension changes. *varname* : Name of the variable; follows standard variable naming conventions. *subscripts* -: Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. +: Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. *type* -: *optional* Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type, or an object type. +: *optional* Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type, or an object type. Use a separate **As** *type* clause for each variable being defined. For a **Variant** containing an array, *type* describes the type of each element of the array, but doesn't change the **Variant** to some other type. The **ReDim** statement is used to size or resize a dynamic array that has already been formally declared by using a [**Private**](Private), [**Public**](Public), or [**Dim**](Dim) statement with empty parentheses (without dimension subscripts). -Use the **ReDim** statement repeatedly to change the number of elements and dimensions in an array. However, you can't declare an array of one data type and later use **ReDim** to change the array to another data type, unless the array is contained in a **Variant**. If the array is contained in a **Variant**, the type of the elements can be changed by using an **As** *type* clause, unless you are using the **Preserve** keyword, in which case no changes of data type are permitted. +Use the **ReDim** statement repeatedly to change the number of elements and dimensions in an array. However, an array declared with one data type cannot later be changed to another data type by **ReDim**, unless the array is contained in a **Variant**. If the array is contained in a **Variant**, the type of the elements can be changed by using an **As** *type* clause, unless the **Preserve** keyword is used, in which case no changes of data type are permitted. -If you use the **Preserve** keyword, you can resize only the last array dimension and you can't change the number of dimensions at all. For example, if your array has only one dimension, you can resize that dimension because it is the last and only dimension. However, if your array has two or more dimensions, you can change the size of only the last dimension and still preserve the contents of the array. +With the **Preserve** keyword, only the last array dimension can be resized, and the number of dimensions cannot change. For example, when the array has only one dimension, that dimension can be resized because it is the last and only dimension. However, when the array has two or more dimensions, only the size of the last dimension can change while still preserving the contents of the array. -The following example shows how you can increase the size of the last dimension of a dynamic array without erasing any existing data contained in the array. +The following example shows how to increase the size of the last dimension of a dynamic array without erasing any existing data contained in the array. ```tb ReDim X(10, 10, 10) @@ -39,9 +39,9 @@ ReDim X(10, 10, 10) ReDim Preserve X(10, 10, 15) ``` -Similarly, when you use **Preserve**, you can change the size of the array only by changing the upper bound; changing the lower bound causes an error. +Similarly, with **Preserve**, the size of the array can only change by changing the upper bound; changing the lower bound causes an error. -If you make an array smaller than it was, data in the eliminated elements will be lost. +When an array becomes smaller than it was, data in the eliminated elements will be lost. When variables are initialized, a numeric variable is initialized to 0, a variable-length string is initialized to a zero-length string (""), and a fixed-length string is filled with zeros. **Variant** variables are initialized to **Empty**. Each element of a user-defined type variable is initialized as if it were a separate variable. @@ -50,7 +50,7 @@ A variable that refers to an object must be assigned an existing object by using The **ReDim** statement acts as a declarative statement if the variable it declares doesn't exist at the module level or procedure level. If another variable with the same name is created later, even in a wider scope, **ReDim** will refer to the later variable and won't necessarily cause a compilation error, even if **Option Explicit** is in effect. To avoid such conflicts, **ReDim** should not be used as a declarative statement, but simply for redimensioning arrays. > [!NOTE] -> To resize an array contained in a **Variant**, you must explicitly declare the **Variant** variable before attempting to resize its array. +> To resize an array contained in a **Variant**, the **Variant** variable must be explicitly declared before attempting to resize its array. ### Example diff --git a/docs/Reference/Core/Resume.md b/docs/Reference/Core/Resume.md index 03e16770..929ebfc0 100644 --- a/docs/Reference/Core/Resume.md +++ b/docs/Reference/Core/Resume.md @@ -23,7 +23,7 @@ Syntax: **Resume** *line* : Execution resumes at the *line* specified. The *line* argument is a line label or line number, and must be in the same procedure as the error handler. -If you use a **Resume** statement anywhere except in an error-handling routine, an error occurs. +Using a **Resume** statement anywhere except in an error-handling routine raises an error. ### Example diff --git a/docs/Reference/Core/Return.md b/docs/Reference/Core/Return.md index 484661e0..eff5182f 100644 --- a/docs/Reference/Core/Return.md +++ b/docs/Reference/Core/Return.md @@ -9,17 +9,17 @@ vba_attribution: true Returns control from the current point of execution to its caller. The **Return** keyword has two distinct uses, distinguished by form and context: -- **Bare `Return`** — valid only as the companion to [**GoSub**](GoSub-Return). Inside a **GoSub** subroutine, **Return** branches back to the statement immediately following the most recently executed **GoSub**. -- **`Return` *expression*** — valid only inside a [**Function**](Function) or [**Property Get**](Property) procedure (twinBASIC extension). It exits the procedure with *expression* as the return value. +- **Bare `Return`** --- valid only as the companion to [**GoSub**](GoSub-Return). Inside a **GoSub** subroutine, **Return** branches back to the statement immediately following the most recently executed **GoSub**. +- **`Return` *expression*** --- valid only inside a [**Function**](Function) or [**Property Get**](Property) procedure (twinBASIC extension). It exits the procedure with *expression* as the return value. -To exit a [**Sub**](Sub), [**Function**](Function), [**Property Get**](Property), [**Property Let**](Property), or [**Property Set**](Property) procedure *without* returning a value, use [**Exit Sub**](Exit), **Exit Function**, or **Exit Property** — there is no bare-`Return` procedure-exit form. +To exit a [**Sub**](Sub), [**Function**](Function), [**Property Get**](Property), [**Property Let**](Property), or [**Property Set**](Property) procedure *without* returning a value, use [**Exit Sub**](Exit), **Exit Function**, or **Exit Property** --- there is no bare-`Return` procedure-exit form. Syntax: - > **Return** - > **Return** *expression* *expression* -: In a [**Function**](Function) or **Property Get** procedure, the value to return to the caller. The type of *expression* must be compatible with the procedure's declared return type. *expression* must be present in this form — it cannot be omitted. +: In a [**Function**](Function) or **Property Get** procedure, the value to return to the caller. The type of *expression* must be compatible with the procedure's declared return type. *expression* must be present in this form --- it cannot be omitted. > [!NOTE] > The **Return** *expression* form is a twinBASIC extension. Classic VBA reserves **Return** exclusively for the [**GoSub...Return**](GoSub-Return) construct, and the only way to set a function's return value is to assign to the function name (e.g., `MyFunc = expr`). twinBASIC supports both styles. @@ -36,7 +36,7 @@ End Function Debug.Print Square(7) ' 49 ``` -Exiting a **Sub** early — note the use of **Exit Sub**, not bare **Return**: +Exiting a **Sub** early --- note the use of **Exit Sub**, not bare **Return**: ```tb Sub LogIfEnabled(ByVal Message As String) @@ -45,7 +45,7 @@ Sub LogIfEnabled(ByVal Message As String) End Sub ``` -Returning from a **GoSub** subroutine — bare **Return** here resumes execution at the statement following the **GoSub**. See [**GoSub...Return**](GoSub-Return) for the full pattern. +Returning from a **GoSub** subroutine --- bare **Return** here resumes execution at the statement following the **GoSub**. See [**GoSub...Return**](GoSub-Return) for the full pattern. ```tb Sub GosubDemo() diff --git a/docs/Reference/Core/RightShift.md b/docs/Reference/Core/RightShift.md index 78ec351f..c25e3f58 100644 --- a/docs/Reference/Core/RightShift.md +++ b/docs/Reference/Core/RightShift.md @@ -32,7 +32,7 @@ The data type of *result* matches the (integral) type of *number*. The right shi ### Compound assignment -`x >>= n` is the twinBASIC shorthand for `x = x >> n`. **\>>=** is a statement, not an expression — it does not produce a value. +`x >>= n` is the twinBASIC shorthand for `x = x >> n`. **\>>=** is a statement, not an expression --- it does not produce a value. ```tb Dim Flags As Long = &H100 diff --git a/docs/Reference/Core/Select-Case.md b/docs/Reference/Core/Select-Case.md index d57f1f17..cb374c1c 100644 --- a/docs/Reference/Core/Select-Case.md +++ b/docs/Reference/Core/Select-Case.md @@ -28,21 +28,21 @@ Syntax: - *expression* **To** *expression* - **Is** *comparisonoperator* *expression* - The **To** keyword specifies a range of values. If you use the **To** keyword, the smaller value must appear before **To**. + The **To** keyword specifies a range of values. When the **To** keyword is used, the smaller value must appear before **To**. Use the **Is** keyword with comparison operators (except **Is** and **Like**) to specify a range of values. If not supplied, the **Is** keyword is automatically inserted. *statements-n* -: *optional* One or more statements executed if *testexpression* matches any part of *expressionlist-n*. +: *optional* One or more statements executed if *testexpression* matches any part of *expressionlist-n*. *elsestatements* -: *optional* One or more statements executed if *testexpression* doesn't match any of the **Case** clauses. +: *optional* One or more statements executed if *testexpression* doesn't match any of the **Case** clauses. If *testexpression* matches any **Case** *expressionlist* expression, the *statements* following that **Case** clause are executed up to the next **Case** clause, or, for the last clause, up to **End Select**. Control then passes to the statement following **End Select**. If *testexpression* matches an *expressionlist* expression in more than one **Case** clause, only the statements following the first match are executed. -The **Case Else** clause is used to indicate the *elsestatements* to be executed if no match is found between the *testexpression* and an *expressionlist* in any of the other **Case** selections. Although not required, it is a good idea to have a **Case Else** statement in your **Select Case** block to handle unforeseen *testexpression* values. If no **Case** *expressionlist* matches *testexpression* and there is no **Case Else** statement, execution continues at the statement following **End Select**. +The **Case Else** clause is used to indicate the *elsestatements* to be executed if no match is found between the *testexpression* and an *expressionlist* in any of the other **Case** selections. Although not required, it is a good idea to have a **Case Else** statement in a **Select Case** block to handle unforeseen *testexpression* values. If no **Case** *expressionlist* matches *testexpression* and there is no **Case Else** statement, execution continues at the statement following **End Select**. -You can use multiple expressions or ranges in each **Case** clause. For example, the following line is valid: +Multiple expressions or ranges can appear in each **Case** clause. For example, the following line is valid: ```tb Case 1 To 4, 7 To 9, 11, 13, Is > MaxNumber @@ -51,7 +51,7 @@ Case 1 To 4, 7 To 9, 11, 13, Is > MaxNumber > [!NOTE] > The **Is** comparison operator is not the same as the **Is** keyword used in the **Select Case** statement. -You can also specify ranges and multiple expressions for character strings. In the following example, **Case** matches strings that are exactly equal to `everything`, strings that fall between `nuts` and `soup` in alphabetic order, and the current value of `TestItem`: +Ranges and multiple expressions can also be specified for character strings. In the following example, **Case** matches strings that are exactly equal to `everything`, strings that fall between `nuts` and `soup` in alphabetic order, and the current value of `TestItem`: ```tb Case "everything", "nuts" To "soup", TestItem diff --git a/docs/Reference/Core/Set.md b/docs/Reference/Core/Set.md index 2d1c4952..c7f8dc3e 100644 --- a/docs/Reference/Core/Set.md +++ b/docs/Reference/Core/Set.md @@ -16,17 +16,17 @@ Syntax: : Name of the variable or property; follows standard variable naming conventions. **[New](New)** -: *optional* **New** is usually used during declaration to enable implicit object creation. When **New** is used with **Set**, it creates a new instance of the class. If *objectvar* contained a reference to an object, that reference is released when the new one is assigned. The **New** keyword can't be used to create new instances of any intrinsic data type and can't be used to create dependent objects. +: *optional* **New** is usually used during declaration to enable implicit object creation. When **New** is used with **Set**, it creates a new instance of the class. If *objectvar* contained a reference to an object, that reference is released when the new one is assigned. The **New** keyword can't be used to create new instances of any intrinsic data type and can't be used to create dependent objects. *objectexpression* : Expression consisting of the name of an object, another declared variable of the same object type, or a function or method that returns an object of the same object type. **Nothing** -: *optional* Discontinues association of *objectvar* with any specific object. Assigning **Nothing** to *objectvar* releases all the system and memory resources associated with the previously referenced object when no other variable refers to it. +: *optional* Discontinues association of *objectvar* with any specific object. Assigning **Nothing** to *objectvar* releases all the system and memory resources associated with the previously referenced object when no other variable refers to it. To be valid, *objectvar* must be an object type consistent with the object being assigned to it. -The [**Dim**](Dim), [**Private**](Private), [**Public**](Public), [**ReDim**](ReDim), and [**Static**](Static) statements only declare a variable that refers to an object. No actual object is referred to until you use the **Set** statement to assign a specific object. +The [**Dim**](Dim), [**Private**](Private), [**Public**](Public), [**ReDim**](ReDim), and [**Static**](Static) statements only declare a variable that refers to an object. No actual object is referred to until the **Set** statement assigns a specific object. The following example illustrates how **Dim** is used to declare an array with the type `Form1`. No instance of `Form1` actually exists. **Set** then assigns references to new instances of `Form1` to the `myChildForms` variable. Such code might be used to create child forms in an MDI application. @@ -38,7 +38,7 @@ Set myChildForms(3) = New Form1 Set myChildForms(4) = New Form1 ``` -Generally, when you use **Set** to assign an object reference to a variable, no copy of the object is created for that variable. Instead, a reference to the object is created. More than one object variable can refer to the same object. Because such variables are references to the object rather than copies of the object, any change in the object is reflected in all variables that refer to it. However, when you use the **New** keyword in the **Set** statement, you are actually creating an instance of the object. +Generally, when **Set** is used to assign an object reference to a variable, no copy of the object is created for that variable. Instead, a reference to the object is created. More than one object variable can refer to the same object. Because such variables are references to the object rather than copies of the object, any change in the object is reflected in all variables that refer to it. However, when the **New** keyword is used in the **Set** statement, an instance of the object is actually created. ### Example diff --git a/docs/Reference/Core/Static.md b/docs/Reference/Core/Static.md index c6597779..8ca9bee2 100644 --- a/docs/Reference/Core/Static.md +++ b/docs/Reference/Core/Static.md @@ -16,13 +16,13 @@ Syntax: : Name of the variable; follows standard variable naming conventions. *subscripts* -: *optional* Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. +: *optional* Dimensions of an array variable; up to 60 multiple dimensions may be declared. The *subscripts* argument uses the following syntax: [ *lower* **To** ] *upper* [ , [ *lower* **To** ] *upper* ] **. . .**. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. **New** -: *optional* Keyword that enables implicit creation of an object. If you use **New** when declaring the object variable, a new instance of the object is created on first reference to it, so you don't have to use the **[Set](Set)** statement to assign the object reference. The **New** keyword can't be used to declare variables of any intrinsic data type or to declare instances of dependent objects. +: *optional* Keyword that enables implicit creation of an object. When **New** is used to declare the object variable, a new instance of the object is created on first reference to it, so the **[Set](Set)** statement is not required to assign the object reference. The **New** keyword can't be used to declare variables of any intrinsic data type or to declare instances of dependent objects. *type* -: *optional* Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type, or an object type. Use a separate **As** *type* clause for each variable being defined. +: *optional* Data type of the variable; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, a user-defined type, or an object type. Use a separate **As** *type* clause for each variable being defined. After module code is running, variables declared with the **Static** statement retain their value until the module is reset or restarted. In class modules, variables declared with the **Static** statement retain their value in each class instance until that instance is destroyed. In form modules, static variables retain their value until the form is closed. @@ -40,17 +40,16 @@ The following statement declares a variable for a new instance of a worksheet: Static X As New Worksheet ``` -If the **New** keyword isn't used when declaring an object variable, the variable that refers to the object must be assigned an existing object by using the **Set** statement before it can be used. Until it is assigned an object, the declared object variable has the special value **Nothing**, which indicates that it doesn't refer to any particular instance of an object. When you use the **New** keyword in the declaration, an instance of the object is created on the first reference to the object. +If the **New** keyword isn't used when declaring an object variable, the variable that refers to the object must be assigned an existing object by using the **Set** statement before it can be used. Until it is assigned an object, the declared object variable has the special value **Nothing**, which indicates that it doesn't refer to any particular instance of an object. When the **New** keyword is used in the declaration, an instance of the object is created on the first reference to the object. -If you don't specify a data type or object type, and there is no [**Deftype**](Deftype) statement in the module, the variable is **Variant** by default. +When no data type or object type is specified, and there is no [**Deftype**](Deftype) statement in the module, the variable is **Variant** by default. > [!NOTE] -> The **Static** statement and the **Static** keyword are similar, but used for different effects. If you declare a procedure by using the **Static** keyword (as in `Static Sub CountSales()`), the storage space for all local variables within the procedure is allocated once, and the value of the variables is preserved for the entire time the program is running. For nonstatic procedures, storage space for variables is allocated each time the procedure is called and released when the procedure is exited. The **Static** statement is used to declare specific variables within nonstatic procedures to preserve their value for as long as the program is running. +> The **Static** statement and the **Static** keyword are similar, but used for different effects. When a procedure is declared by using the **Static** keyword (as in `Static Sub CountSales()`), the storage space for all local variables within the procedure is allocated once, and the value of the variables is preserved for the entire time the program is running. For nonstatic procedures, storage space for variables is allocated each time the procedure is called and released when the procedure is exited. The **Static** statement is used to declare specific variables within nonstatic procedures to preserve their value for as long as the program is running. When variables are initialized, a numeric variable is initialized to 0, a variable-length string is initialized to a zero-length string (""), and a fixed-length string is filled with zeros. **Variant** variables are initialized to **Empty**. Each element of a user-defined type variable is initialized as if it were a separate variable. -> [!NOTE] -> When you use **Static** statements within a procedure, put them at the beginning of the procedure with other declarative statements such as **[Dim](Dim)**. +By convention, **Static** statements within a procedure are placed at the beginning of the procedure with other declarative statements such as **[Dim](Dim)**. ### Example diff --git a/docs/Reference/Core/Stop.md b/docs/Reference/Core/Stop.md index 7c5c39b3..2602d23f 100644 --- a/docs/Reference/Core/Stop.md +++ b/docs/Reference/Core/Stop.md @@ -14,7 +14,7 @@ Syntax: > **Stop** -You can place **Stop** statements anywhere in procedures to suspend execution. Using the **Stop** statement is similar to setting a breakpoint in the code. +**Stop** statements can be placed anywhere in procedures to suspend execution. Using the **Stop** statement is similar to setting a breakpoint in the code. The **Stop** statement suspends execution, but unlike [**End**](End), it doesn't close any files or clear variables, unless it is in a compiled executable (.exe) file. diff --git a/docs/Reference/Core/Sub.md b/docs/Reference/Core/Sub.md index ad828a65..33d9670e 100644 --- a/docs/Reference/Core/Sub.md +++ b/docs/Reference/Core/Sub.md @@ -21,44 +21,44 @@ Syntax: : *optional* One or more of the [supported attributes](Attributes) for procedures. **Public** -: *optional* Indicates that the **Sub** procedure is accessible to all other procedures in all modules. If used in a module that contains an **Option Private**, the procedure is not available outside the project. +: *optional* Indicates that the **Sub** procedure is accessible to all other procedures in all modules. If used in a module that contains an **Option Private**, the procedure is not available outside the project. **Private** -: *optional* Indicates that the **Sub** procedure is accessible only to other procedures in the module where it is declared. +: *optional* Indicates that the **Sub** procedure is accessible only to other procedures in the module where it is declared. **Friend** -: *optional* Used only in a class module. Indicates that the **Sub** procedure is visible throughout the project, but not visible to a controller of an instance of an object. +: *optional* Used only in a class module. Indicates that the **Sub** procedure is visible throughout the project, but not visible to a controller of an instance of an object. **[Protected](Protected)** -: *optional* (twinBASIC) Used only in a class. Indicates that the **Sub** procedure is accessible from inside the declaring class and from classes that derive from it via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop), but not from outside callers. +: *optional* (twinBASIC) Used only in a class. Indicates that the **Sub** procedure is accessible from inside the declaring class and from classes that derive from it via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop), but not from outside callers. **[Static](Static)** -: *optional* Indicates that the **Sub** procedure's local variables are preserved between calls. The **Static** attribute doesn't affect variables that are declared outside the **Sub**, even if they are used in the procedure. +: *optional* Indicates that the **Sub** procedure's local variables are preserved between calls. The **Static** attribute doesn't affect variables that are declared outside the **Sub**, even if they are used in the procedure. **Overridable** -: *optional* (twinBASIC) Marks the **Sub** as an inheritance hook that classes derived via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop) may replace with an **Overrides** clause. Meaningful only on a member of a class that participates in an **Inherits** hierarchy. +: *optional* (twinBASIC) Marks the **Sub** as an inheritance hook that classes derived via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop) may replace with an **Overrides** clause. Meaningful only on a member of a class that participates in an **Inherits** hierarchy. *name* -: Name of the **Sub**; follows standard variable naming conventions. The special name `New` declares an instance constructor — see [Inheritance](../../Features/Language/Inheritance) for chained construction with `*baseclass*.New(...)`. +: Name of the **Sub**; follows standard variable naming conventions. The special name `New` declares an instance constructor --- see [Inheritance](../../Features/Language/Inheritance) for chained construction with `*baseclass*.New(...)`. **Of** *typevars* -: *optional* One or more type variable names, following standard variable naming conventions. The names are separated by commas. Causes the procedure to be a generic **Sub**. +: *optional* One or more type variable names, following standard variable naming conventions. The names are separated by commas. Causes the procedure to be a generic **Sub**. *arglist* -: *optional* List of variables representing arguments that are passed to the **Sub** procedure when it is called. Multiple variables are separated by commas. See [*arglist*](#arglist) below for syntax. +: *optional* List of variables representing arguments that are passed to the **Sub** procedure when it is called. Multiple variables are separated by commas. See [*arglist*](#arglist) below for syntax. *binding-clause* -: *optional* (twinBASIC) One of three trailing clauses that bind this body to a member declared elsewhere: +: *optional* (twinBASIC) One of three trailing clauses that bind this body to a member declared elsewhere: - - **Handles** *object*.*event* [ **,** *object*.*event* … ] — wires this **Sub** up as a handler for the named event(s), replacing the traditional `Object_Event` naming convention. See [**Handles** statement](Handles). - - **Implements** *iface*.*member* [ **,** *iface2*.*member2* … ] — provides the body for the named [**Interface**](Interface) (or [**Class**](Class)) member, replacing the traditional `Iface_Member` naming convention. A comma-separated list lets one body satisfy several interfaces' members at once. See [**Implements** statement](Implements). - - **Overrides** *base*.*member* — supplies the body for an **Overridable** *member* inherited via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop). Combine with **Overridable** on the same header to allow further-derived classes to override again. + - **Handles** *object*.*event* [ **,** *object*.*event* … ] --- connects this **Sub** as a handler for the named event(s), replacing the traditional `Object_Event` naming convention. See [**Handles** statement](Handles). + - **Implements** *iface*.*member* [ **,** *iface2*.*member2* … ] --- provides the body for the named [**Interface**](Interface) (or [**Class**](Class)) member, replacing the traditional `Iface_Member` naming convention. A comma-separated list permits one body to satisfy several interfaces' members at once. See [**Implements** statement](Implements). + - **Overrides** *base*.*member* --- supplies the body for an **Overridable** *member* inherited via [**Inherits**](../../Features/Language/Inheritance#inherits-for-complete-oop). Combine with **Overridable** on the same header to allow further-derived classes to override again. *statements* -: *optional* Any group of statements to be executed within the **Sub** procedure. +: *optional* Any group of statements to be executed within the **Sub** procedure. **[Exit Sub](Exit)** -: *optional* Immediately returns from the **Sub** procedure. (A bare [**Return**](Return) statement does *not* exit a **Sub** — it is reserved for the [**GoSub...Return**](GoSub-Return) construct.) +: *optional* Immediately returns from the **Sub** procedure. (A bare [**Return**](Return) statement does *not* exit a **Sub** --- it is reserved for the [**GoSub...Return**](GoSub-Return) construct.) ### *arglist* @@ -66,26 +66,26 @@ Syntax: One or more of [ **Optional** ] [ **ByVal** \| **ByRef** ] [ **[ParamArray](ParamArray)** ] *varname* [ **()** ] [ **As** *type* ] [ **=** *defaultvalue* ] **Optional** -: *optional* Indicates that an argument is not required. If used, all subsequent arguments in *arglist* must also be optional and declared by using the **Optional** keyword. **Optional** can't be used for any argument if **ParamArray** is used. +: *optional* Indicates that an argument is not required. If used, all subsequent arguments in *arglist* must also be optional and declared by using the **Optional** keyword. **Optional** can't be used for any argument if **ParamArray** is used. **ByVal** -: *optional* Indicates that the argument is passed by value. +: *optional* Indicates that the argument is passed by value. **ByRef** -: *optional* Indicates that the argument is passed by reference. **ByRef** is the default unlike in Visual Basic .NET. +: *optional* Indicates that the argument is passed by reference. **ByRef** is the default unlike in Visual Basic .NET. **[ParamArray](ParamArray)** -: *optional* Used only as the last argument in *arglist* to indicate that the final argument is an **Optional** array of **Variant** elements. The **ParamArray** keyword allows you to provide an arbitrary number of arguments. It may not be used with **ByVal**, **ByRef**, or **Optional**. +: *optional* Used only as the last argument in *arglist* to indicate that the final argument is an **Optional** array of **Variant** elements. The **ParamArray** keyword permits passing an arbitrary number of arguments. It may not be used with **ByVal**, **ByRef**, or **Optional**. *varname* : Name of the variable representing the argument; follows standard variable naming conventions. *type* -: *optional* Data type of the argument passed to the procedure; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (variable length only), **Object**, **Variant**, a specific object type, or the name of a generic type argument. If the parameter is not **Optional**, a user-defined type may also be specified. +: *optional* Data type of the argument passed to the procedure; may be **Byte**, **Boolean**, **Integer**, **Long**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (variable length only), **Object**, **Variant**, a specific object type, or the name of a generic type argument. If the parameter is not **Optional**, a user-defined type may also be specified. If the name of a generic type parameter is used, it becomes bound to the concrete type of the argument passed to the procedure. The name binding has the scope of the body of the procedure. *defaultvalue* -: *optional* Any constant or constant expression. Valid for **Optional** parameters only. If the type is an **Object**, an explicit default value can only be **Nothing**. +: *optional* Any constant or constant expression. Valid for **Optional** parameters only. If the type is an **Object**, an explicit default value can only be **Nothing**. If not explicitly specified by using **Public**, **Private**, or **Friend**, **Sub** procedures are public by default. @@ -95,20 +95,20 @@ The **Friend** keyword can only be used in class modules. However, **Friend** pr **Sub** procedures can be recursive; that is, they can call themselves to perform a given task. However, recursion can lead to stack overflow. The **Static** keyword usually is not used with recursive **Sub** procedures. -All executable code must be in procedures. You can't define a **Sub** procedure inside another **[Sub](Sub)**, **[Function](Function)**, or **[Property](Property)** procedure. +All executable code must be in procedures. A **Sub** procedure cannot be defined inside another **[Sub](Sub)**, **[Function](Function)**, or **[Property](Property)** procedure. The **[Exit Sub](Exit)** statement causes an immediate exit from a **Sub** procedure. Program execution continues with the statement following the statement that called the **Sub** procedure. Any number of **Exit Sub** statements can appear anywhere in a **Sub** procedure. Like a **Function** procedure, a **Sub** procedure is a separate procedure that can take arguments, perform a series of statements, and change the value of its arguments. However, unlike a **Function** procedure, which returns a value, a **Sub** procedure can't be used in an expression. -You call a **Sub** procedure by using the procedure name followed by the argument list. See the **[Call](Call)** statement for specific information about how to call **Sub** procedures. +A **Sub** procedure is called by using the procedure name followed by the argument list. See the **[Call](Call)** statement for specific information about how to call **Sub** procedures. Variables used in **Sub** procedures fall into two categories: those that are explicitly declared within the procedure and those that are not. Variables that are explicitly declared in a procedure (using **Dim** or the equivalent) are always local to the procedure. Variables that are used but not explicitly declared in a procedure are also local unless they are explicitly declared at some higher level outside the procedure. -A procedure can use a variable that is not explicitly declared in the procedure, but a naming conflict can occur if anything you defined at the module level has the same name. If your procedure refers to an undeclared variable that has the same name as another procedure, constant, or variable, it is assumed that your procedure is referring to that module-level name. To avoid this kind of conflict, explicitly declare variables. Use an **[Option Explicit](Option#Explicit)** statement to force explicit declaration of variables. +A procedure can use a variable that is not explicitly declared in the procedure, but a naming conflict can occur if anything defined at the module level has the same name. When a procedure refers to an undeclared variable that has the same name as another procedure, constant, or variable, it is assumed that the procedure is referring to that module-level name. To avoid this kind of conflict, explicitly declare variables. Use an **[Option Explicit](Option#Explicit)** statement to force explicit declaration of variables. > [!NOTE] -> You can't use **GoSub**, **GoTo**, or **Return** to enter or exit a **Sub** procedure. Use [**Exit Sub**](Exit) to leave a **Sub** early. +> **GoSub**, **GoTo**, and **Return** cannot enter or exit a **Sub** procedure. Use [**Exit Sub**](Exit) to leave a **Sub** early. ### Example diff --git a/docs/Reference/Core/Topic-Preprocessor.md b/docs/Reference/Core/Topic-Preprocessor.md index 2ac7d452..caa3ae80 100644 --- a/docs/Reference/Core/Topic-Preprocessor.md +++ b/docs/Reference/Core/Topic-Preprocessor.md @@ -29,7 +29,7 @@ Syntax: The directive's behaviour mirrors the runtime [**If...Then...Else**](If-Then-Else) statement, with the following differences: -- There is no single-line form — `#If`, `#ElseIf`, `#Else`, and `#End If` must each appear on their own line. +- There is no single-line form --- `#If`, `#ElseIf`, `#Else`, and `#End If` must each appear on their own line. - All *expressions* are evaluated regardless of which branch is selected, so every constant they reference must be defined. Undefined conditional compiler constants evaluate as **Empty** (i.e. zero), which is treated as **False**. - Code in unselected branches is *removed* from the compilation rather than skipped at runtime. In twinBASIC, inactive code is not even checked for errors. The IDE greys out inactive blocks based on the current build configuration. @@ -48,13 +48,13 @@ Syntax: *expression* : A literal, another conditional compiler constant, or any combination using arithmetic or logical operators (except [**Is**](Is)). Standard runtime constants (declared with [**Const**](Const)) are *not* allowed here. -Conditional compiler constants declared with `#Const` are private to the module in which they appear. Project-wide conditional constants must be defined in the project's compilation settings — `#Const` cannot create them. +Conditional compiler constants declared with `#Const` are private to the module in which they appear. Project-wide conditional constants must be defined in the project's compilation settings --- `#Const` cannot create them. Conditional compiler constants are always evaluated at the module level regardless of where they appear in code; they can only be used in `#If`/`#ElseIf` expressions. ## Predefined compiler constants -twinBASIC provides a set of built-in compiler constants — `Win64`, `Win32`, `TWINBASIC`, `TWINBASIC_BUILD`, `VBA7`, etc. See the dedicated [Compiler Constants](../../Reference/Compiler-Constants) page for the full list and what each one means. +twinBASIC provides a set of built-in compiler constants --- `Win64`, `Win32`, `TWINBASIC`, `TWINBASIC_BUILD`, `VBA7`, etc. See the dedicated [Compiler Constants](../../Reference/Compiler-Constants) page for the full list and what each one means. ### Example @@ -81,6 +81,6 @@ End Sub ### See Also -- [**If...Then...Else** statement](If-Then-Else) — the runtime counterpart. -- [**Const** statement](Const) — the runtime counterpart of **#Const**. -- [Compiler Constants](../../Reference/Compiler-Constants) — the full list of built-in conditional constants. +- [**If...Then...Else** statement](If-Then-Else) -- the runtime counterpart. +- [**Const** statement](Const) -- the runtime counterpart of **#Const**. +- [Compiler Constants](../../Reference/Compiler-Constants) -- the full list of built-in conditional constants. diff --git a/docs/Reference/Core/Type.md b/docs/Reference/Core/Type.md index 7d066780..e44d4b63 100644 --- a/docs/Reference/Core/Type.md +++ b/docs/Reference/Core/Type.md @@ -20,13 +20,13 @@ Syntax: > **End Type** *attributes* -: *optional* (twinBASIC) Type-level attributes. Most notably [**PackingAlignment**](Attributes#packingalignment), which sets the field-alignment value used when laying out the UDT in memory — useful for interop with C structs declared under `#pragma pack` or `#include <pshpack1.h>`. +: *optional* (twinBASIC) Type-level attributes. Most notably [**PackingAlignment**](Attributes#packingalignment), which sets the field-alignment value used when laying out the UDT in memory --- useful for interop with C structs declared under `#pragma pack` or `#include <pshpack1.h>`. **Public** -: *optional* Used to declare user-defined types that are available to all procedures in all modules in all projects. +: *optional* Used to declare user-defined types that are available to all procedures in all modules in all projects. **Private** -: *optional* Used to declare user-defined types that are available only within the module where the declaration is made. +: *optional* Used to declare user-defined types that are available only within the module where the declaration is made. *varname* : Name of the user-defined type; follows standard variable naming conventions. @@ -35,18 +35,18 @@ Syntax: : Name of an element of the user-defined type. Element names also follow standard variable naming conventions, except that keywords can be used. *subscripts* -: *optional* Dimensions of an array element. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. +: *optional* Dimensions of an array element. When not explicitly stated in *lower*, the lower bound of an array is controlled by the [**Option Base**](Option#Base) statement. The lower bound is zero if no **Option Base** statement is present. *type* : Data type of the element; may be **Byte**, **Boolean**, **Integer**, **Long**, **LongLong**, **LongPtr**, **Currency**, **Single**, **Double**, **Decimal**, **Date**, **String** (for variable-length strings), **String** *length* (for fixed-length strings), **Object**, **Variant**, another user-defined type, or an object type. In a generic **Type** (see below), *type* may also be one of the *typevars* introduced in the **Of** clause. **Of** *typevars* -: *optional* (twinBASIC) One or more type variable names, separated by commas, that make the **Type** a *generic UDT*. Each type variable can be referenced as the *type* of an element. See [Generics](../../Features/Language/Generics). Generic UDTs do not yet support member procedures. +: *optional* (twinBASIC) One or more type variable names, separated by commas, that make the **Type** a *generic UDT*. Each type variable can be referenced as the *type* of an element. See [Generics](../../Features/Language/Generics). Generic UDTs do not yet support member procedures. *member-procedure* -: *optional* (twinBASIC) A [**Sub**](Sub), [**Function**](Function), or [**Property**](Property) procedure, or a [**Declare**](Declare) external procedure, written inside the **Type** body and callable through any variable of that type. See [twinBASIC enhancements](#twinbasic-enhancements) below. +: *optional* (twinBASIC) A [**Sub**](Sub), [**Function**](Function), or [**Property**](Property) procedure, or a [**Declare**](Declare) external procedure, written inside the **Type** body and callable through any variable of that type. See [twinBASIC enhancements](#twinbasic-enhancements) below. -The **Type** statement can be used only at the module level. After you have declared a user-defined type by using the **Type** statement, you can declare a variable of that type anywhere within the scope of the declaration. Use [**Dim**](Dim), [**Private**](Private), [**Public**](Public), [**ReDim**](ReDim), or [**Static**](Static) to declare a variable of a user-defined type. +The **Type** statement can be used only at the module level. After a user-defined type has been declared by using the **Type** statement, a variable of that type can be declared anywhere within the scope of the declaration. Use [**Dim**](Dim), [**Private**](Private), [**Public**](Public), [**ReDim**](ReDim), or [**Static**](Static) to declare a variable of a user-defined type. In standard modules and class modules, user-defined types are public by default. This visibility can be changed by using the **Private** keyword. @@ -67,7 +67,7 @@ Dim Washington(1 To 100) As StateData In the preceding example, `StateData` includes the `CityCode` static array, and the record `Washington` has the same structure as `StateData`. -When you declare a fixed-size array within a user-defined type, its dimensions must be declared with numeric literals or constants rather than variables. +When a fixed-size array is declared within a user-defined type, its dimensions must be declared with numeric literals or constants rather than variables. ### Example @@ -100,11 +100,11 @@ twinBASIC extends classic VBA's **Type** in several ways. UDTs remain stack-allo | Member | Purpose | |:---|:---| -| `Type_Initialize` | Constructor — runs when a variable of the type is created. | -| `Type_Terminate` | Destructor — runs when the variable goes out of scope. | -| `Type_Assignment` | Assignment operator — `=` assigns *RHS* to a variable of the type. The signature is `Sub Type_Assignment(ByVal RHS As ...)`, and several overloads with different *RHS* types may coexist. | -| `Type_Conversion` | Conversion operator — produces a value of another type from the UDT. The signature is `Function Type_Conversion() As ...`, and several overloads with different return types may coexist. | -| `Type_DebugView` | Debugger display — returns a **String** shown in the IDE's variable inspector. | +| `Type_Initialize` | Constructor --- runs when a variable of the type is created. | +| `Type_Terminate` | Destructor --- runs when the variable goes out of scope. | +| `Type_Assignment` | Assignment operator --- `=` assigns *RHS* to a variable of the type. The signature is `Sub Type_Assignment(ByVal RHS As ...)`, and several overloads with different *RHS* types may coexist. | +| `Type_Conversion` | Conversion operator --- produces a value of another type from the UDT. The signature is `Function Type_Conversion() As ...`, and several overloads with different return types may coexist. | +| `Type_DebugView` | Debugger display --- returns a **String** shown in the IDE's variable inspector. | **API declarations inside a UDT.** A [**Declare**](Declare) statement inside a **Type** body works as a regular module-level declaration, except that when its first parameter is named `Me` and is the same type as the UDT, calls on a variable of that type pass the variable as the first argument implicitly: @@ -118,7 +118,7 @@ Dim h As HWND h.BringWindowToTop() ' Passes h as the first argument to the API. ``` -**Custom packing.** The [**PackingAlignment**](Attributes#packingalignment) type-level attribute controls alignment of the UDT's fields. The default packing places each field at a multiple of its own size (with trailing padding so the total size is a multiple of the largest field). Setting `[PackingAlignment(1)]` packs fields with no padding — matching `#pragma pack(push, 1)` in C. +**Custom packing.** The [**PackingAlignment**](Attributes#packingalignment) type-level attribute controls alignment of the UDT's fields. The default packing places each field at a multiple of its own size (with trailing padding so the total size is a multiple of the largest field). Setting `[PackingAlignment(1)]` packs fields with no padding --- matching `#pragma pack(push, 1)` in C. ```tb [PackingAlignment(2)] diff --git a/docs/Reference/Core/Unload.md b/docs/Reference/Core/Unload.md index ae1f8800..34de5a95 100644 --- a/docs/Reference/Core/Unload.md +++ b/docs/Reference/Core/Unload.md @@ -7,7 +7,7 @@ vba_attribution: true # Unload {: .no_toc } -Removes an object — typically a form — from memory. +Removes an object --- typically a form --- from memory. Syntax: > **Unload** *object* diff --git a/docs/Reference/Core/Unlock.md b/docs/Reference/Core/Unlock.md index 6002935d..341c0445 100644 --- a/docs/Reference/Core/Unlock.md +++ b/docs/Reference/Core/Unlock.md @@ -17,7 +17,7 @@ Syntax: The arguments to **Unlock** must match exactly the arguments of the corresponding **Lock** statement. See [**Lock, Unlock**](Lock) for full details. > [!IMPORTANT] -> Be sure to remove all locks with an **Unlock** statement before closing a file or quitting your program. Failure to remove locks produces unpredictable results. +> Be sure to remove all locks with an **Unlock** statement before closing a file or quitting the program. Failure to remove locks produces unpredictable results. ### See Also diff --git a/docs/Reference/Core/While-Wend.md b/docs/Reference/Core/While-Wend.md index 209898d9..4b0b1a00 100644 --- a/docs/Reference/Core/While-Wend.md +++ b/docs/Reference/Core/While-Wend.md @@ -20,7 +20,7 @@ Syntax: : Numeric expression or string expression that evaluates to **True** or **False**. If *condition* is Null, *condition* is treated as **False**. *statements* -: *optional* One or more statements executed while *condition* is **True**. +: *optional* One or more statements executed while *condition* is **True**. If *condition* is **True**, all *statements* are executed until the **Wend** statement is encountered. Control then returns to the **While** statement and *condition* is again checked. If *condition* is still **True**, the process is repeated. If it is not **True**, execution resumes with the statement following the **Wend** statement. diff --git a/docs/Reference/Core/With.md b/docs/Reference/Core/With.md index 29f7f74b..b825238a 100644 --- a/docs/Reference/Core/With.md +++ b/docs/Reference/Core/With.md @@ -20,9 +20,9 @@ Syntax: : Name of an object or a user-defined type. *statements* -: *optional* One or more statements to be executed on *object*. +: *optional* One or more statements to be executed on *object*. -The **With** statement allows you to perform a series of statements on a specified object without requalifying the name of the object. For example, to change a number of different properties on a single object, place the property assignment statements within the **With** control structure, referring to the object once instead of referring to it with each property assignment. +The **With** statement permits a series of statements on a specified object without requalifying the name of the object. For example, to change a number of different properties on a single object, place the property assignment statements within the **With** control structure, referring to the object once instead of referring to it with each property assignment. The following example illustrates use of the **With** statement to assign values to several properties of the same object. @@ -35,12 +35,12 @@ End With ``` > [!NOTE] -> Once a **With** block is entered, *object* can't be changed. As a result, you can't use a single **With** statement to affect a number of different objects. +> Once a **With** block is entered, *object* can't be changed. As a result, a single **With** statement cannot affect a number of different objects. -You can nest **With** statements by placing one **With** block within another. However, because members of outer **With** blocks are masked within the inner **With** blocks, you must provide a fully qualified object reference in an inner **With** block to any member of an object in an outer **With** block. +**With** statements can be nested by placing one **With** block within another. However, because members of outer **With** blocks are masked within the inner **With** blocks, a fully qualified object reference must be supplied in an inner **With** block to any member of an object in an outer **With** block. -> [!NOTE] -> In general, it's recommended that you don't jump into or out of **With** blocks. If statements in a **With** block are executed, but either the **With** or **End With** statement is not executed, a temporary variable containing a reference to the object remains in memory until you exit the procedure. +> [!IMPORTANT] +> Jumping into or out of **With** blocks is not recommended. If statements in a **With** block are executed, but either the **With** or **End With** statement is not executed, a temporary variable containing a reference to the object remains in memory until the procedure exits. ### Example diff --git a/docs/Reference/Core/Write.md b/docs/Reference/Core/Write.md index 625927b0..6baefd45 100644 --- a/docs/Reference/Core/Write.md +++ b/docs/Reference/Core/Write.md @@ -16,11 +16,11 @@ Syntax: : Any valid file number. *outputlist* -: *optional* One or more comma-delimited numeric expressions or string expressions to write to a file. +: *optional* One or more comma-delimited numeric expressions or string expressions to write to a file. Data written with **Write #** is usually read from a file with [**Input #**](Input). -If you omit *outputlist* and include a comma after *filenumber*, a blank line is printed to the file. Multiple expressions can be separated with a space, a semicolon, or a comma. A space has the same effect as a semicolon. +When *outputlist* is omitted and a comma follows *filenumber*, a blank line is printed to the file. Multiple expressions can be separated with a space, a semicolon, or a comma. A space has the same effect as a semicolon. When **Write #** is used to write data to a file, several universal assumptions are followed so that the data can always be read and correctly interpreted by using **Input #**, regardless of locale: @@ -30,10 +30,10 @@ When **Write #** is used to write data to a file, several universal assumptions - Nothing is written to the file if *outputlist* data is **Empty**. However, for **Null** data, `#NULL#` is written. - For **Error** data, the output appears as `#ERROR `*errorcode*`#`. The **Error** keyword is not translated, regardless of locale. -Unlike the [**Print #**](Print) statement, the **Write #** statement inserts commas between items and quotation marks around strings as they are written to the file. You don't have to put explicit delimiters in the list. **Write #** inserts a newline character — that is, a carriage return-linefeed (**Chr**(13) + **Chr**(10)) — after it has written the final character in *outputlist* to the file. +Unlike the [**Print #**](Print) statement, the **Write #** statement inserts commas between items and quotation marks around strings as they are written to the file. Explicit delimiters in the list are not required. **Write #** inserts a newline character --- that is, a carriage return-linefeed (**Chr**(13) + **Chr**(10)) --- after it has written the final character in *outputlist* to the file. -> [!NOTE] -> You should not write strings that contain embedded quotation marks (for example, `"1,2""X"`) for use with the **Input #** statement; **Input #** parses this string as two complete and separate strings. +> [!IMPORTANT] +> Do not write strings that contain embedded quotation marks (for example, `"1,2""X"`) for use with the **Input #** statement; **Input #** parses this string as two complete and separate strings. ### Example diff --git a/docs/Reference/Core/Xor.md b/docs/Reference/Core/Xor.md index f34b61dd..3ea098f5 100644 --- a/docs/Reference/Core/Xor.md +++ b/docs/Reference/Core/Xor.md @@ -19,7 +19,7 @@ Syntax: *expression1*, *expression2* : Any expressions. -If one — and only one — of the expressions evaluates to **True**, *result* is **True**. If either expression is **Null**, *result* is also **Null**. When neither expression is **Null**, *result* is determined according to the following table: +If one --- and only one --- of the expressions evaluates to **True**, *result* is **True**. If either expression is **Null**, *result* is also **Null**. When neither expression is **Null**, *result* is determined according to the following table: | If *expression1* is | And *expression2* is | Then *result* is | |:-----|:-----|:-----| diff --git a/docs/Reference/CustomControls/Enumerations/BorderStyle.md b/docs/Reference/CustomControls/Enumerations/BorderStyle.md index 5c3720b7..5e8b7a4b 100644 --- a/docs/Reference/CustomControls/Enumerations/BorderStyle.md +++ b/docs/Reference/CustomControls/Enumerations/BorderStyle.md @@ -7,15 +7,15 @@ permalink: /tB/Packages/CustomControls/Enumerations/BorderStyle # BorderStyle {: .no_toc } -The Win32 frame style used by a [**WaynesForm**](../WaynesForm/) window. Determines whether the window has a thick or thin border, whether it can be resized by dragging an edge, and whether it shows a normal title bar or the smaller tool-window title bar. Carried by [**WindowsFormOptions.BorderStyle**](../WaynesForm/WindowsFormOptions#borderstyle). +The Win32 frame style used by a [**WaynesForm**](../WaynesForm/) window. Determines whether the window has a thick or thin border, whether it can be resized by dragging an edge, and whether it shows a normal title bar or the smaller tool-window title bar. Used by [**WindowsFormOptions.BorderStyle**](../WaynesForm/WindowsFormOptions#borderstyle). | Constant | Value | Description | |----------|-------|-------------| -| **tbNone**{: #tbNone } | 0 | No border at all — the form is a borderless, captionless rectangle. | +| **tbNone**{: #tbNone } | 0 | No border at all --- the form is a borderless, captionless rectangle. | | **tbFixedSingle**{: #tbFixedSingle } | 1 | Thin single-line border; size is fixed at run time. | | **tbFixedSizable**{: #tbFixedSizable } | 2 | Standard resizable border with a normal title bar. The default for newly-constructed [**WindowsFormOptions**](../WaynesForm/WindowsFormOptions). | | **tbFixedDialog**{: #tbFixedDialog } | 3 | Dialog-frame border; size is fixed and the system menu offers only **Move** / **Close**. | | **tbFixedToolWindow**{: #tbFixedToolWindow } | 4 | Tool-window border with the smaller title bar; size is fixed. | | **tbSizableToolWindow**{: #tbSizableToolWindow } | 5 | Tool-window border with the smaller title bar; the window is resizable. | -Most border styles cannot be combined with **MinimizeButton** or **MaximizeButton** — only **tbFixedSizable** shows full sizing controls. Setting [**MinimizeButton**](../WaynesForm/WindowsFormOptions#minimizebutton) or [**MaximizeButton**](../WaynesForm/WindowsFormOptions#maximizebutton) to **True** on a window style that does not include them has no effect. +Most border styles cannot be combined with **MinimizeButton** or **MaximizeButton** --- only **tbFixedSizable** shows full sizing controls. Setting [**MinimizeButton**](../WaynesForm/WindowsFormOptions#minimizebutton) or [**MaximizeButton**](../WaynesForm/WindowsFormOptions#maximizebutton) to **True** on a window style that does not include them has no effect. diff --git a/docs/Reference/CustomControls/Enumerations/ColorRGBA.md b/docs/Reference/CustomControls/Enumerations/ColorRGBA.md index 7a8c0577..3b34fc76 100644 --- a/docs/Reference/CustomControls/Enumerations/ColorRGBA.md +++ b/docs/Reference/CustomControls/Enumerations/ColorRGBA.md @@ -7,12 +7,12 @@ permalink: /tB/Packages/CustomControls/Enumerations/ColorRGBA # ColorRGBA {: .no_toc } -> [!NOTE] -> **ColorRGBA** is declared as an empty `Enum` block (with a placeholder `[_MAX] = 0` member) only because twinBASIC has not yet exposed a type-alias syntax such as `Type ColorRGBA = Long`. The source has a `FIXME` comment noting the stand-in. Treat **ColorRGBA** as a **Long**-compatible type alias rather than as an enumeration with named members; when alias syntax becomes available, the enum stand-in will be replaced. +A **Long**-compatible type alias used wherever a 32-bit ABGR colour value is expected. The high byte is the alpha channel --- `&HFF000000` is fully opaque, `&H00000000` is fully transparent --- and the low three bytes follow the standard `vbBlue`/`vbGreen`/`vbRed` order used by the [**ColorConstants**](../../VBRUN/Constants/ColorConstants) `Long`-coloured constants. Used by [**FillColorPoint.Color**](../Styles/Fill#color) and by the **RGBA** parameter of [**FillColorPoints.SetSolidColorRGBA**](../Styles/Fill#setsolidcolorrgba) / [**Borders.SetSimpleBorderRGBA**](../Styles/Borders#setsimpleborderrgba). -A **Long**-compatible type alias used wherever a 32-bit ABGR colour value is expected. The high byte is the alpha channel — `&HFF000000` is fully opaque, `&H00000000` is fully transparent — and the low three bytes follow the standard `vbBlue`/`vbGreen`/`vbRed` order used by the [**ColorConstants**](../../VBRUN/Constants/ColorConstants) `Long`-coloured constants. Used by [**FillColorPoint.Color**](../Styles/Fill#color) and by the **RGBA** parameter of [**FillColorPoints.SetSolidColorRGBA**](../Styles/Fill#setsolidcolorrgba) / [**Borders.SetSimpleBorderRGBA**](../Styles/Borders#setsimpleborderrgba). +> [!NOTE] +> **ColorRGBA** is declared as an empty `Enum` block (with a placeholder `[_MAX] = 0` member) only because twinBASIC has not yet exposed a type-alias syntax such as `Type ColorRGBA = Long`. The source has a `FIXME` comment noting the stand-in. **ColorRGBA** should be used as a **Long**-compatible type alias rather than as an enumeration with named members; when alias syntax becomes available, the enum stand-in will be replaced. -To write a fully-opaque colour, OR-in the opaque alpha mask: `&HFF000000 Or vbBlue`. The convenience setters [**FillColorPoints.SetSolidColor**](../Styles/Fill#setsolidcolor) and [**Borders.SetSimpleBorder**](../Styles/Borders#setsimpleborder) take a normal three-byte **Long** colour and apply the opaque mask for you; only the `*RGBA` variants take a raw **ColorRGBA**. +To write a fully-opaque colour, OR-in the opaque alpha mask: `&HFF000000 Or vbBlue`. The convenience setters [**FillColorPoints.SetSolidColor**](../Styles/Fill#setsolidcolor) and [**Borders.SetSimpleBorder**](../Styles/Borders#setsimpleborder) take a normal three-byte **Long** colour and apply the opaque mask automatically; only the `*RGBA` variants take a raw **ColorRGBA**. ```tb Dim translucentRed As ColorRGBA = &H800000FF& ' 50% alpha, full red diff --git a/docs/Reference/CustomControls/Enumerations/CornerShape.md b/docs/Reference/CustomControls/Enumerations/CornerShape.md index 3fc0d1bd..be719142 100644 --- a/docs/Reference/CustomControls/Enumerations/CornerShape.md +++ b/docs/Reference/CustomControls/Enumerations/CornerShape.md @@ -7,13 +7,13 @@ permalink: /tB/Packages/CustomControls/Enumerations/CornerShape # CornerShape {: .no_toc } -Determines how a single corner of a control is shaped. Carried by [**Corner.Shape**](../Styles/Corners#shape), which is set independently for each of the four corners of any control that exposes a [**Corners**](../Styles/Corners) style object. The numeric value of the radius is supplied separately by [**Corner.Radius**](../Styles/Corners#radius). +Determines how a single corner of a control is shaped. Used by [**Corner.Shape**](../Styles/Corners#shape), which is set independently for each of the four corners of any control that exposes a [**Corners**](../Styles/Corners) style object. The numeric value of the radius is supplied separately by [**Corner.Radius**](../Styles/Corners#radius). | Constant | Value | Description | |----------|-------|-------------| | **tbCurve**{: #tbCurve } | 0 | Quarter-circle round corner; the radius gives the curve. | | **tbNotched**{: #tbNotched } | 1 | Diagonal notch across the corner; the radius gives the cut depth. | -| **tbCutOut**{: #tbCutOut } | 2 | Inverse round-corner — the corner area is carved *out* of the control. | +| **tbCutOut**{: #tbCutOut } | 2 | Inverse round-corner --- the corner area is carved *out* of the control. | [**Corners.SetAll**](../Styles/Corners#setall) applies one shape to every corner at once; setting [**TopLeft**](../Styles/Corners#topleft) / [**TopRight**](../Styles/Corners#topright) / [**BottomLeft**](../Styles/Corners#bottomleft) / [**BottomRight**](../Styles/Corners#bottomright) individually lets the shapes mix: diff --git a/docs/Reference/CustomControls/Enumerations/DockMode.md b/docs/Reference/CustomControls/Enumerations/DockMode.md index 2dd52c85..51d137d3 100644 --- a/docs/Reference/CustomControls/Enumerations/DockMode.md +++ b/docs/Reference/CustomControls/Enumerations/DockMode.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/CustomControls/Enumerations/DockMode # DockMode {: .no_toc } -How a control is positioned relative to its container — attached to one edge, filling the whole client area, or not docked at all (positioned absolutely by [**Left**](../#controls) / [**Top**](../#controls) / [**Width**](../#controls) / [**Height**](../#controls)). Carried by the **Dock** property that every concrete custom control inherits. +How a control is positioned relative to its container --- attached to one edge, filling the whole client area, or not docked at all (positioned absolutely by [**Left**](../#controls) / [**Top**](../#controls) / [**Width**](../#controls) / [**Height**](../#controls)). Used by the **Dock** property that every concrete custom control inherits. | Constant | Value | Description | |----------|-------|-------------| @@ -30,4 +30,4 @@ Private Sub Form_Load() End Sub ``` -Setting **Dock** to anything other than **tbDockNone** makes the control's own [**Anchors**](../Styles/Anchors) irrelevant — docking takes over the position and size completely. To return to manual positioning, set **Dock** back to **tbDockNone**. +Setting **Dock** to anything other than **tbDockNone** makes the control's own [**Anchors**](../Styles/Anchors) irrelevant --- docking takes over the position and size completely. Manual positioning resumes when **Dock** is reset to **tbDockNone**. diff --git a/docs/Reference/CustomControls/Enumerations/FillPattern.md b/docs/Reference/CustomControls/Enumerations/FillPattern.md index 2004ddb8..d342ccfd 100644 --- a/docs/Reference/CustomControls/Enumerations/FillPattern.md +++ b/docs/Reference/CustomControls/Enumerations/FillPattern.md @@ -7,11 +7,11 @@ permalink: /tB/Packages/CustomControls/Enumerations/FillPattern # FillPattern {: .no_toc } -Identifies how the colour table held by a [**Fill**](../Styles/Fill) is applied across the area being painted. The same colour stops produce very different results depending on the pattern — a north-to-south gradient with two stops paints a top-to-bottom transition, while a corner gradient with the same stops paints from one corner outward. Carried by [**Fill.Pattern**](../Styles/Fill#pattern). +Identifies how the colour table held by a [**Fill**](../Styles/Fill) is applied across the area being painted. The same colour stops produce very different results depending on the pattern --- a north-to-south gradient with two stops paints a top-to-bottom transition, while a corner gradient with the same stops paints from one corner outward. Used by [**Fill.Pattern**](../Styles/Fill#pattern). | Constant | Value | Description | |----------|-------|-------------| -| **tbPatternNone**{: #tbPatternNone } | 0 | No fill — leaves the region transparent. | +| **tbPatternNone**{: #tbPatternNone } | 0 | No fill --- leaves the region transparent. | | **tbGradientNorthToSouth**{: #tbGradientNorthToSouth } | 1 | Linear gradient from the top edge down to the bottom edge. | | **tbGradientSouthToNorth**{: #tbGradientSouthToNorth } | 2 | Linear gradient from the bottom edge up to the top edge. | | **tbGradientWestToEast**{: #tbGradientWestToEast } | 3 | Linear gradient from the left edge across to the right edge. | @@ -51,4 +51,4 @@ pnlThree.BackgroundFill.SetSimplePattern vbWhite, &H99CCFF, _ Pattern:=tbGradientCornerTopLeft ``` -For a flat region with no gradient at all, use **tbPatternNone** — the `Fill` becomes fully transparent and the area behind the control shows through. +**tbPatternNone** produces a flat region with no gradient --- the `Fill` becomes fully transparent and the area behind the control shows through. diff --git a/docs/Reference/CustomControls/Enumerations/FontWeight.md b/docs/Reference/CustomControls/Enumerations/FontWeight.md index ed2fb508..1764477a 100644 --- a/docs/Reference/CustomControls/Enumerations/FontWeight.md +++ b/docs/Reference/CustomControls/Enumerations/FontWeight.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/CustomControls/Enumerations/FontWeight # FontWeight {: .no_toc } -The weight of a font face, on the standard 100 – 900 scale used by OpenType's `wght` axis and by CSS's `font-weight`. Carried by [**FontStyle.Weight**](../Styles/TextRendering#weight); availability of each weight depends on which faces are installed for the chosen font family. +The weight of a font face, on the standard 100 -- 900 scale used by OpenType's `wght` axis and by CSS's `font-weight`. Assigned to [**FontStyle.Weight**](../Styles/TextRendering#weight); availability of each weight depends on which faces are installed for the chosen font family. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/CustomControls/Enumerations/PixelCount.md b/docs/Reference/CustomControls/Enumerations/PixelCount.md index 6f620f20..4742f33e 100644 --- a/docs/Reference/CustomControls/Enumerations/PixelCount.md +++ b/docs/Reference/CustomControls/Enumerations/PixelCount.md @@ -7,9 +7,9 @@ permalink: /tB/Packages/CustomControls/Enumerations/PixelCount # PixelCount {: .no_toc } -> [!NOTE] -> **PixelCount** is declared as an empty `Enum` block (with a placeholder `[_MAX] = 0` member) only because twinBASIC has not yet exposed a type-alias syntax such as `Type PixelCount = Long`. The source has a `FIXME` comment noting the stand-in. Treat **PixelCount** as a **Long**-compatible type alias rather than as an enumeration with named members; when alias syntax becomes available, the enum stand-in will be replaced. +A **Long**-compatible type alias used wherever a measurement in pixels is expected. Used pervasively across the package --- every control's inherited **Left**, **Top**, **Width**, **Height** are typed as **PixelCount**, as are [**Corner.Radius**](../Styles/Corners#radius), [**Padding**](../Styles/Padding) fields, [**Border.StrokeSize**](../Styles/Borders#strokesize), and many more. -A **Long**-compatible type alias used wherever a measurement in pixels is expected. Used pervasively across the package — every control's inherited **Left**, **Top**, **Width**, **Height** are typed as **PixelCount**, as are [**Corner.Radius**](../Styles/Corners#radius), [**Padding**](../Styles/Padding) fields, [**Border.StrokeSize**](../Styles/Borders#strokesize), and many more. +> [!NOTE] +> **PixelCount** is declared as an empty `Enum` block (with a placeholder `[_MAX] = 0` member) only because twinBASIC has not yet exposed a type-alias syntax such as `Type PixelCount = Long`. The source has a `FIXME` comment noting the stand-in. **PixelCount** should be used as a **Long**-compatible type alias rather than as an enumeration with named members; when alias syntax becomes available, the enum stand-in will be replaced. The package treats one **PixelCount** as one *unscaled* pixel; the design-time canvas is at 96 DPI. The runtime scales the value for the active monitor's DPI when painting, so a 15-pixel corner radius looks the same on a 96-DPI and a 192-DPI display. Inside an [**ICustomControl.Paint**](../Framework/ICustomControl#paint) implementation, the scale factor is available through [**Canvas.RuntimeUICCGetDpiScaleFactor**](../Framework/Canvas#runtimeuiccgetdpiscalefactor). diff --git a/docs/Reference/CustomControls/Enumerations/PointSize.md b/docs/Reference/CustomControls/Enumerations/PointSize.md index db8e156a..9b102458 100644 --- a/docs/Reference/CustomControls/Enumerations/PointSize.md +++ b/docs/Reference/CustomControls/Enumerations/PointSize.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/CustomControls/Enumerations/PointSize # PointSize {: .no_toc } -> [!NOTE] -> **PointSize** is declared as an empty `Enum` block (with a placeholder `[_MAX] = 0` member) only because twinBASIC has not yet exposed a type-alias syntax such as `Type PointSize = Long`. The source contains a `FIXME` comment noting the stand-in. Treat **PointSize** as a **Long**-compatible type alias rather than as an enumeration with named members; when alias syntax becomes available, the enum stand-in will be replaced. - A **Long**-compatible type alias for a font size, expressed in *typographic points* (a point is 1⁄72 of an inch). Used by [**FontStyle.Size**](../Styles/TextRendering#size). New [**FontStyle**](../Styles/TextRendering) objects default to 12 points. + +> [!NOTE] +> **PointSize** is declared as an empty `Enum` block (with a placeholder `[_MAX] = 0` member) only because twinBASIC has not yet exposed a type-alias syntax such as `Type PointSize = Long`. The source contains a `FIXME` comment noting the stand-in. **PointSize** should be used as a **Long**-compatible type alias rather than as an enumeration with named members; when alias syntax becomes available, the enum stand-in will be replaced. diff --git a/docs/Reference/CustomControls/Enumerations/StartupPosition.md b/docs/Reference/CustomControls/Enumerations/StartupPosition.md index 435ca2fc..5479fec7 100644 --- a/docs/Reference/CustomControls/Enumerations/StartupPosition.md +++ b/docs/Reference/CustomControls/Enumerations/StartupPosition.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/CustomControls/Enumerations/StartupPosition # StartupPosition {: .no_toc } -The initial position of a form's window when it is first shown. Carried by [**WindowsFormOptions.StartUpPosition**](../WaynesForm/WindowsFormOptions#startupposition). Honoured once, at the form's first display; subsequent moves are at the user's discretion or controlled by code. +The initial position of a form's window when it is first shown. Used by [**WindowsFormOptions.StartUpPosition**](../WaynesForm/WindowsFormOptions#startupposition). Honoured once, at the form's first display; subsequent moves are at the user's discretion or controlled by code. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/CustomControls/Enumerations/TextAlignment.md b/docs/Reference/CustomControls/Enumerations/TextAlignment.md index 57bbdf89..91907b1f 100644 --- a/docs/Reference/CustomControls/Enumerations/TextAlignment.md +++ b/docs/Reference/CustomControls/Enumerations/TextAlignment.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/CustomControls/Enumerations/TextAlignment # TextAlignment {: .no_toc } -Horizontal and vertical alignment of text drawn inside a control's bounding rectangle. Carried by [**TextRendering.Alignment**](../Styles/TextRendering#alignment); each member combines one of three vertical positions (top, middle, bottom) with one of three horizontal positions (left, centre, right). +Horizontal and vertical alignment of text drawn inside a control's bounding rectangle. Used by [**TextRendering.Alignment**](../Styles/TextRendering#alignment); each member combines one of three vertical positions (top, middle, bottom) with one of three horizontal positions (left, centre, right). | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/CustomControls/Enumerations/TextOverflowMode.md b/docs/Reference/CustomControls/Enumerations/TextOverflowMode.md index 7f394ba0..1262bf43 100644 --- a/docs/Reference/CustomControls/Enumerations/TextOverflowMode.md +++ b/docs/Reference/CustomControls/Enumerations/TextOverflowMode.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/CustomControls/Enumerations/TextOverflowMode # TextOverflowMode {: .no_toc } -Controls how text that does not fit inside the available rectangle is truncated. Carried by [**TextRendering.OverflowMode**](../Styles/TextRendering#overflowmode). +Controls how text that does not fit inside the available rectangle is truncated. Used by [**TextRendering.OverflowMode**](../Styles/TextRendering#overflowmode). | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/CustomControls/Enumerations/WindowState.md b/docs/Reference/CustomControls/Enumerations/WindowState.md index f7b396eb..69adc5d2 100644 --- a/docs/Reference/CustomControls/Enumerations/WindowState.md +++ b/docs/Reference/CustomControls/Enumerations/WindowState.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/CustomControls/Enumerations/WindowState # WindowState {: .no_toc } -The window state of a [**WaynesForm**](../WaynesForm/) — minimized, restored to normal size, or maximized to fill its monitor. Carried by [**WindowsFormOptions.WindowState**](../WaynesForm/WindowsFormOptions#windowstate); honoured once when the form is first shown. +The window state of a [**WaynesForm**](../WaynesForm/) --- minimized, restored to normal size, or maximized to fill its monitor. Used by [**WindowsFormOptions.WindowState**](../WaynesForm/WindowsFormOptions#windowstate); honoured once when the form is first shown. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/CustomControls/Framework/Canvas.md b/docs/Reference/CustomControls/Framework/Canvas.md index 7bcd1a5b..9e90511d 100644 --- a/docs/Reference/CustomControls/Framework/Canvas.md +++ b/docs/Reference/CustomControls/Framework/Canvas.md @@ -9,9 +9,9 @@ has_toc: false # Canvas type (UDT) {: .no_toc } -The drawing surface a custom control paints onto. Passed to [**ICustomControl.Paint**](ICustomControl#paint) on every redraw pass and used exclusively from inside that method — its lifetime is the duration of the single paint pass. +The drawing surface a custom control paints onto. Passed to [**ICustomControl.Paint**](ICustomControl#paint) on every redraw pass and used exclusively from inside that method --- its lifetime is the duration of the single paint pass. -A custom control builds up one or more `ElementDescriptor` records describing the rectangles it wants to draw — each with a position, size, fill, borders, corners, text, cursor, tab-index, and a set of `AddressOf`-registered input callbacks — and hands each descriptor to [**RuntimeUICCCanvasAddElement**](#runtimeuicccanvasaddelement). The framework rasterises the descriptor, routes hit-testing to the registered callbacks, and (where the descriptor opts in) tracks keyboard tab order and focus. +A custom control builds up one or more `ElementDescriptor` records describing the rectangles to draw --- each with a position, size, fill, borders, corners, text, cursor, tab-index, and a set of `AddressOf`-registered input callbacks --- and passes each descriptor to [**RuntimeUICCCanvasAddElement**](#runtimeuicccanvasaddelement). The framework rasterises the descriptor, routes hit-testing to the registered callbacks, and (where the descriptor opts in) tracks keyboard tab order and focus. ```tb Private Sub OnPaint(ByVal Canvas As CustomControls.Canvas) _ @@ -54,7 +54,7 @@ Syntax: *Canvas*.**RuntimeUICCGetDpi** ( ) **As Long** ### RuntimeUICCGetDpiScaleFactor {: .no_toc } -Returns the DPI scale factor — `RuntimeUICCGetDpi / 96` — as a **Double**. Multiply [**PixelCount**](../Enumerations/PixelCount)-typed measurements by this value to convert from design-time pixels to device pixels at paint time. +Returns the DPI scale factor --- `RuntimeUICCGetDpi / 96` --- as a **Double**. Multiply [**PixelCount**](../Enumerations/PixelCount)-typed measurements by this value to convert from design-time pixels to device pixels at paint time. Syntax: *Canvas*.**RuntimeUICCGetDpiScaleFactor** ( ) **As Double** diff --git a/docs/Reference/CustomControls/Framework/CustomControlContext.md b/docs/Reference/CustomControls/Framework/CustomControlContext.md index 16c8dec7..61ffde6e 100644 --- a/docs/Reference/CustomControls/Framework/CustomControlContext.md +++ b/docs/Reference/CustomControls/Framework/CustomControlContext.md @@ -9,7 +9,7 @@ has_toc: false # CustomControlContext class {: .no_toc } -The callback object handed to a custom control's [**Initialize**](ICustomControl#initialize). Holds the connection back into the framework — used to deserialize designer-set property values, request repaints, create timers, and move the keyboard focus between elements the control has drawn. +The callback object passed to a custom control's [**Initialize**](ICustomControl#initialize). Holds the connection back into the framework --- used to deserialize designer-set property values, request repaints, create timers, and move the keyboard focus between elements the control has drawn. Custom controls store the **CustomControlContext** in a private field (typically called **ControlContext**) so that they can call back into the framework at any point after **Initialize** has returned. The form-class counterpart [**CustomFormContext**](CustomFormContext) extends this with **Show** and **Close**. @@ -32,7 +32,7 @@ End Sub ### ChangeFocusedElement {: .no_toc } -Asks the framework to move the keyboard focus to a particular `ElementTabIndex` value, as if the user had pressed **TAB** until reaching that point. Used by [**WaynesGrid**](../WaynesGrid/) when a cell is selected programmatically — the grid changes its **SelectedCellX** / **SelectedCellY** and then calls this method so that the form-level focus tracking matches. +Asks the framework to move the keyboard focus to a particular `ElementTabIndex` value, as if the user had pressed **TAB** until reaching that point. Used by [**WaynesGrid**](../WaynesGrid/) when a cell is selected programmatically --- the grid changes its **SelectedCellX** / **SelectedCellY** and then calls this method so that the form-level focus tracking matches. Syntax: *object*.**ChangeFocusedElement** *ElementTabIndex* @@ -62,4 +62,4 @@ Tells the framework that the control's appearance has changed and that the canva Syntax: *object*.**Repaint** ( ) -Every concrete `Waynes…` control hooks the **OnChanged** events on its state and style sub-objects, and calls **Repaint** from the handler — so a runtime assignment like `btn.NormalState.BackgroundFill.ColorPoints.SetSolidColor vbBlue` triggers an automatic redraw. +Every concrete `Waynes…` control hooks the **OnChanged** events on its state and style sub-objects, and calls **Repaint** from the handler --- so a runtime assignment like `btn.NormalState.BackgroundFill.ColorPoints.SetSolidColor vbBlue` triggers an automatic redraw. diff --git a/docs/Reference/CustomControls/Framework/CustomControlsCollection.md b/docs/Reference/CustomControls/Framework/CustomControlsCollection.md index 891f8645..ca764056 100644 --- a/docs/Reference/CustomControls/Framework/CustomControlsCollection.md +++ b/docs/Reference/CustomControls/Framework/CustomControlsCollection.md @@ -9,7 +9,7 @@ has_toc: false # CustomControlsCollection class {: .no_toc } -The collection of controls hosted on a custom form. Reached as the **Controls** property of a [**WaynesForm**](../WaynesForm/). Supports indexed access by integer or name, enumeration with **For Each**, and runtime add / remove of controls. +The collection of controls hosted on a custom form. Accessed as the **Controls** property of a [**WaynesForm**](../WaynesForm/). Supports indexed access by integer or name, enumeration with **For Each**, and runtime add / remove of controls. ```tb Dim ctl As Object @@ -30,7 +30,7 @@ Syntax: *object*.**Count** ### Item {: .no_toc } -Returns the control at the given index or with the given name. The **Default property** — the **Controls** ( *…* ) shorthand calls **Item**. +Returns the control at the given index or with the given name. The **Default property** --- the **Controls** ( *…* ) shorthand calls **Item**. Syntax: *object*.**Item** ( *IndexOrName* ) **As Object** diff --git a/docs/Reference/CustomControls/Framework/CustomFormContext.md b/docs/Reference/CustomControls/Framework/CustomFormContext.md index 21a09d01..f382cbd3 100644 --- a/docs/Reference/CustomControls/Framework/CustomFormContext.md +++ b/docs/Reference/CustomControls/Framework/CustomFormContext.md @@ -9,7 +9,7 @@ has_toc: false # CustomFormContext class {: .no_toc } -The form-class counterpart to [**CustomControlContext**](CustomControlContext). Extends the base context with **Show** and **Close** — the operations a top-level form needs that an embedded control does not. +The form-class counterpart to [**CustomControlContext**](CustomControlContext). Extends the base context with **Show** and **Close** --- the operations a top-level form needs that an embedded control does not. [**WaynesForm**](../WaynesForm/) receives its context as a [**CustomControlContext**](CustomControlContext) (because it implements [**ICustomControl**](ICustomControl)) and casts it to **CustomFormContext** internally so that it can call **Show** from its own **Show** method and **Close** from its **Close** method. @@ -23,7 +23,7 @@ End Sub ## Inherited -A **CustomFormContext** includes every member from [**CustomControlContext**](CustomControlContext) — [**ChangeFocusedElement**](CustomControlContext#changefocusedelement), [**CreateTimer**](CustomControlContext#createtimer), [**GetSerializer**](CustomControlContext#getserializer), and [**Repaint**](CustomControlContext#repaint) — and adds the two form-specific members below. +A **CustomFormContext** includes every member from [**CustomControlContext**](CustomControlContext) --- [**ChangeFocusedElement**](CustomControlContext#changefocusedelement), [**CreateTimer**](CustomControlContext#createtimer), [**GetSerializer**](CustomControlContext#getserializer), and [**Repaint**](CustomControlContext#repaint) --- and adds the two form-specific members below. ## Methods diff --git a/docs/Reference/CustomControls/Framework/ICustomControl.md b/docs/Reference/CustomControls/Framework/ICustomControl.md index 143c573d..4fe32248 100644 --- a/docs/Reference/CustomControls/Framework/ICustomControl.md +++ b/docs/Reference/CustomControls/Framework/ICustomControl.md @@ -51,14 +51,14 @@ Called once after the framework has constructed the control and deserialized any Syntax: *object*.**Initialize** ( *Context* ) *Context* -: *required* The [**CustomControlContext**](CustomControlContext) for this control instance. Store it (typically as a class field named **ControlContext**) — it is the only way to request repaints, create timers, or check the runtime mode after **Initialize** returns. +: *required* The [**CustomControlContext**](CustomControlContext) for this control instance. Store it (typically as a class field named **ControlContext**) --- it is the only way to request repaints, create timers, or check the runtime mode after **Initialize** returns. A common implementation calls **Context.GetSerializer().RuntimeUISrzDeserialize(Me, False)** to load designer-set property values into the instance; if the call returns **False**, no serialized data was found and the control should apply its own defaults. ### Paint {: .no_toc } -Called every time the framework needs to redraw the control's client area. The implementation builds one or more `ElementDescriptor` records describing the rectangles to draw and hands each to *Canvas*. **RuntimeUICCCanvasAddElement**. +Called every time the framework needs to redraw the control's client area. The implementation builds one or more `ElementDescriptor` records describing the rectangles to draw and passes each to *Canvas*. **RuntimeUICCCanvasAddElement**. Syntax: *object*.**Paint** ( *Canvas* ) @@ -67,4 +67,4 @@ Syntax: *object*.**Paint** ( *Canvas* ) A descriptor may include event callbacks (`OnClick`, `OnMouseDown`, …) as `AddressOf` pointers; the framework dispatches input back through those pointers without the control needing to subscribe explicitly to anything. -A control should request additional repaints by calling [**CustomControlContext.Repaint**](CustomControlContext#repaint), not by calling **Paint** directly — the framework decides when to issue the actual paint pass. +A control should request additional repaints by calling [**CustomControlContext.Repaint**](CustomControlContext#repaint), not by calling **Paint** directly --- the framework controls when to issue the actual paint pass. diff --git a/docs/Reference/CustomControls/Framework/ICustomForm.md b/docs/Reference/CustomControls/Framework/ICustomForm.md index 9dca2372..561d02f7 100644 --- a/docs/Reference/CustomControls/Framework/ICustomForm.md +++ b/docs/Reference/CustomControls/Framework/ICustomForm.md @@ -9,9 +9,9 @@ has_toc: false # ICustomForm interface {: .no_toc } -The form-class counterpart to [**ICustomControl**](ICustomControl). Custom *form* classes — top-level windows that host other custom controls — implement this interface instead. The shape is identical to **ICustomControl** except that the **Initialize** callback receives a [**CustomFormContext**](CustomFormContext) (which extends [**CustomControlContext**](CustomControlContext) with **Show** and **Close**) rather than a plain **CustomControlContext**. +The form-class counterpart to [**ICustomControl**](ICustomControl). Custom *form* classes --- top-level windows that host other custom controls --- implement this interface instead. The shape is identical to **ICustomControl** except that the **Initialize** callback receives a [**CustomFormContext**](CustomFormContext) (which extends [**CustomControlContext**](CustomControlContext) with **Show** and **Close**) rather than a plain **CustomControlContext**. -[**WaynesForm**](../WaynesForm/), the package's only concrete form class, does in fact implement [**ICustomControl**](ICustomControl) and cast its context to **CustomFormContext** internally — the **ICustomForm** interface is published for parity with **ICustomControl** but is not currently consumed by any class shipped with the package. +[**WaynesForm**](../WaynesForm/), the package's only concrete form class, does in fact implement [**ICustomControl**](ICustomControl) and cast its context to **CustomFormContext** internally --- the **ICustomForm** interface is published for parity with **ICustomControl** but is not currently consumed by any class shipped with the package. ## Methods diff --git a/docs/Reference/CustomControls/Framework/SerializeInfo.md b/docs/Reference/CustomControls/Framework/SerializeInfo.md index 69646729..feaa1315 100644 --- a/docs/Reference/CustomControls/Framework/SerializeInfo.md +++ b/docs/Reference/CustomControls/Framework/SerializeInfo.md @@ -9,7 +9,7 @@ has_toc: false # SerializeInfo type (UDT) {: .no_toc } -The per-instance serializer for a custom control, returned by [**CustomControlContext.GetSerializer**](CustomControlContext#getserializer). The main entry point is [**RuntimeUISrzDeserialize**](#runtimeuisrzdeserialize) — called from a control's [**Initialize**](ICustomControl#initialize) to load the designer-set property values that were saved into the form's serialized data. The remaining members expose framework state — design-mode flag, runtime / report mode, owner window handle — that a control may need while initializing. +The per-instance serializer for a custom control, returned by [**CustomControlContext.GetSerializer**](CustomControlContext#getserializer). The main entry point is [**RuntimeUISrzDeserialize**](#runtimeuisrzdeserialize) --- called from a control's [**Initialize**](ICustomControl#initialize) to load the designer-set property values that were saved into the form's serialized data. The remaining members expose framework state --- design-mode flag, runtime / report mode, owner window handle --- that a control may need while initializing. ```tb Private Sub OnInitialize(ByVal Ctx As CustomControls.CustomControlContext) _ @@ -32,7 +32,7 @@ End Sub ### RuntimeUISrzDeserialize {: .no_toc } -Loads the serialized property values for this control instance into *Object*. Returns **True** if serialized data was present and was applied, or **False** if no data was found — in which case the control should apply its own defaults. +Loads the serialized property values for this control instance into *Object*. Returns **True** if serialized data was present and was applied, or **False** if no data was found --- in which case the control should apply its own defaults. Syntax: *SerializeInfo*.**RuntimeUISrzDeserialize** ( *Object*, *UseOuterOwner* ) **As Boolean** @@ -73,7 +73,7 @@ Syntax: *SerializeInfo*.**RuntimeUISrzGetRootClassDispatch** ( ) **As Object** ### RuntimeUISrzIsDesignMode {: .no_toc } -Returns **True** if the control is being created at design time (inside the form designer) rather than at run time. Controls that want to render a placeholder at design time only — like [**WaynesTimer**](../WaynesTimer), which draws its 🕑 glyph only when **IsDesignMode** is **True** — read this flag during **Initialize**. +Returns **True** if the control is being created at design time (inside the form designer) rather than at run time. Controls that want to render a placeholder at design time only --- like [**WaynesTimer**](../WaynesTimer), which draws its 🕑 glyph only when **IsDesignMode** is **True** --- read this flag during **Initialize**. Syntax: *SerializeInfo*.**RuntimeUISrzIsDesignMode** ( ) **As Boolean** diff --git a/docs/Reference/CustomControls/Framework/index.md b/docs/Reference/CustomControls/Framework/index.md index b0d2bf26..775823a2 100644 --- a/docs/Reference/CustomControls/Framework/index.md +++ b/docs/Reference/CustomControls/Framework/index.md @@ -7,13 +7,13 @@ has_toc: false # Framework -The framework half of the [**CustomControls**](..) package — the interfaces, callback objects, and drawing primitives an *author* of a custom control writes against. The eight concrete `Waynes…` controls in the package are themselves built on this framework; the same pieces are available to user code that needs to implement an entirely new custom control. +The framework half of the [**CustomControls**](..) package --- the interfaces, callback objects, and drawing primitives an *author* of a custom control writes against. The eight concrete `Waynes…` controls in the package are themselves built on this framework; the same pieces are available to user code that needs to implement an entirely new custom control. A custom control: 1. Implements [**ICustomControl**](ICustomControl) (or [**ICustomForm**](ICustomForm) for a form-class custom control). -2. Stores the [**CustomControlContext**](CustomControlContext) handed to it on **Initialize** and uses it to request repaints, create timers, or change the focused element. -3. Inside **Paint**, builds one or more `ElementDescriptor` records and hands them to the [**Canvas**](Canvas) via **RuntimeUICCCanvasAddElement** — the framework rasterises them, handles input routing, and dispatches events back through the descriptor's `AddressOf`-registered callbacks. +2. Stores the [**CustomControlContext**](CustomControlContext) passed to it on **Initialize** and uses it to request repaints, create timers, or change the focused element. +3. Inside **Paint**, builds one or more `ElementDescriptor` records and passes them to the [**Canvas**](Canvas) via **RuntimeUICCCanvasAddElement** --- the framework rasterises them, handles input routing, and dispatches events back through the descriptor's `AddressOf`-registered callbacks. ```tb Class MyControl @@ -52,4 +52,4 @@ End Class ## Drawing primitives - [Canvas](Canvas) -- the drawing surface passed to **Paint**; **RuntimeUICCCanvasAddElement**, plus size and DPI accessors -- [SerializeInfo](SerializeInfo) -- the per-instance serializer reached via **CustomControlContext.GetSerializer**; **RuntimeUISrzDeserialize**, design-mode flags, owner handle, runtime mode +- [SerializeInfo](SerializeInfo) -- the per-instance serializer returned by **CustomControlContext.GetSerializer**; **RuntimeUISrzDeserialize**, design-mode flags, owner handle, runtime mode diff --git a/docs/Reference/CustomControls/Styles/Anchors.md b/docs/Reference/CustomControls/Styles/Anchors.md index 973bc476..df82cfd8 100644 --- a/docs/Reference/CustomControls/Styles/Anchors.md +++ b/docs/Reference/CustomControls/Styles/Anchors.md @@ -11,7 +11,7 @@ has_toc: false Determines which sides of a control are attached to its parent container when the container is resized. A control with both **Left** and **Right** set to **True**, for example, keeps its left and right edges at the same distance from the container's edges, stretching horizontally as the container grows. Controls receive this object through their inherited **Anchors** property. -The default is **Left**=**True**, **Top**=**True**, **Right**=**False**, **Bottom**=**False** — the control stays at the same offset from the upper-left corner of the container and does not resize. To make a control fill the bottom of its container as the form is resized, anchor it to **Left**, **Right**, and **Bottom**. +The default is **Left**=**True**, **Top**=**True**, **Right**=**False**, **Bottom**=**False** --- the control stays at the same offset from the upper-left corner of the container and does not resize. To make a control fill the bottom of its container as the form is resized, anchor it to **Left**, **Right**, and **Bottom**. ```tb With txtNotes.Anchors diff --git a/docs/Reference/CustomControls/Styles/Borders.md b/docs/Reference/CustomControls/Styles/Borders.md index 17060903..4a180e43 100644 --- a/docs/Reference/CustomControls/Styles/Borders.md +++ b/docs/Reference/CustomControls/Styles/Borders.md @@ -9,15 +9,15 @@ has_toc: false # Borders class {: .no_toc } -The collection of border strokes drawn around a region. Each stroke is an independent [**Border**](#border-class) sub-object with its own thickness, fill, and blending behaviour, layered in source order. A single thin black outline is a one-element collection — easiest constructed by calling [**SetSimpleBorder**](#setsimpleborder). +The collection of border strokes drawn around a region. Each stroke is an independent [**Border**](#border-class) sub-object with its own thickness, fill, and blending behaviour, layered in source order. A single thin black outline is a one-element collection --- easiest constructed by calling [**SetSimpleBorder**](#setsimpleborder). -Reached as `<state>.Borders`, [**CellRenderingOptions.Borders**](../WaynesGrid/CellRenderingOptions#borders), and the slider's `<sliderState>.BackgroundBorders` / `BlockBorders`. The array of [**Border**](#border-class) sub-objects on a [**TextRendering**](TextRendering)'s **Outlines** member uses the same element type. +Accessed as `<state>.Borders`, [**CellRenderingOptions.Borders**](../WaynesGrid/CellRenderingOptions#borders), and the slider's `<sliderState>.BackgroundBorders` / `BlockBorders`. The array of [**Border**](#border-class) sub-objects on a [**TextRendering**](TextRendering)'s **Outlines** member uses the same element type. ```tb btnGo.NormalState.Borders.SetSimpleBorder StrokeSize:=1, ColorRGB:=vbBlack ``` -Layered borders — multiple [**Border**](#border-class) instances stroked in order — are assigned to the [**Elements**](#elements) array directly. Each element can have its own [**StrokeSize**](#strokesize) and its own [**Fill**](Fill), so a thin black outline can sit on top of a wide coloured band, or three bands of different colours can stack into a "shadow": +Layered borders --- multiple [**Border**](#border-class) instances stroked in order --- are assigned to the [**Elements**](#elements) array directly. Each element can have its own [**StrokeSize**](#strokesize) and its own [**Fill**](Fill), so a thin black outline can sit on top of a wide coloured band, or three bands of different colours can stack into a "shadow": ```tb Dim elems(0 To 2) As Border @@ -33,7 +33,7 @@ elems(2).Fill.ColorPoints.SetSolidColor &H4D7AB4 ' deeper blue btnGo.NormalState.Borders.Elements = elems ``` -A single [**Border**](#border-class) can also display a gradient instead of a solid colour — assign a multi-stop [**Fill**](Fill) to its [**Fill**](#fill) member. Set [**BlendWithBackgroundFill**](#blendwithbackgroundfill) to **True** on a translucent border to make it tint with the control's own **BackgroundFill** rather than with whatever lies under the control. +A single [**Border**](#border-class) can also display a gradient instead of a solid colour --- assign a multi-stop [**Fill**](Fill) to its [**Fill**](#fill) member. Set [**BlendWithBackgroundFill**](#blendwithbackgroundfill) to **True** on a translucent border to make it tint with the control's own **BackgroundFill** rather than with whatever lies under the control. * TOC {:toc} diff --git a/docs/Reference/CustomControls/Styles/Corners.md b/docs/Reference/CustomControls/Styles/Corners.md index 648db0a0..d24ad204 100644 --- a/docs/Reference/CustomControls/Styles/Corners.md +++ b/docs/Reference/CustomControls/Styles/Corners.md @@ -9,7 +9,7 @@ has_toc: false # Corners class {: .no_toc } -The four corners of a rendered region. Each corner is an independent [**Corner**](#corner-class) sub-object — the shape and radius can vary corner by corner — letting a control round one corner while notching another. Reached as `<state>.Corners`, [**CellRenderingOptions.Corners**](../WaynesGrid/CellRenderingOptions#corners), and the slider's `<sliderState>.BackgroundCorners` / `BlockCorners`. +The four corners of a rendered region. Each corner is an independent [**Corner**](#corner-class) sub-object --- the shape and radius can vary corner by corner --- letting a control round one corner while notching another. Accessed as `<state>.Corners`, [**CellRenderingOptions.Corners**](../WaynesGrid/CellRenderingOptions#corners), and the slider's `<sliderState>.BackgroundCorners` / `BlockCorners`. ```tb With btnGo.NormalState.Corners @@ -29,7 +29,7 @@ With btnTab.NormalState.Corners End With ``` -A circular control is just a square one with all four corners set to [**tbCurve**](../Enumerations/CornerShape#tbCurve) and a radius greater than or equal to half the control's smaller dimension — that is what the `Circle` button in the package's sample forms uses. +A circular control is just a square one with all four corners set to [**tbCurve**](../Enumerations/CornerShape#tbCurve) and a radius greater than or equal to half the control's smaller dimension --- that is what the `Circle` button in the package's sample forms uses. * TOC {:toc} @@ -76,7 +76,7 @@ Syntax: *object*.**SetAll** *Shape*, *Radius* ### OnChanged {: .no_toc } -Raised whenever any of the four corner sub-objects changes — either through a direct property set on the **Corners** object or through a propagated **OnChanged** from one of the **Corner** sub-objects. +Raised whenever any of the four corner sub-objects changes --- either through a direct property set on the **Corners** object or through a propagated **OnChanged** from one of the **Corner** sub-objects. ## Corner class diff --git a/docs/Reference/CustomControls/Styles/Fill.md b/docs/Reference/CustomControls/Styles/Fill.md index 4c7343da..16c4d4e2 100644 --- a/docs/Reference/CustomControls/Styles/Fill.md +++ b/docs/Reference/CustomControls/Styles/Fill.md @@ -9,7 +9,7 @@ has_toc: false # Fill class {: .no_toc } -The colour or gradient that paints a region — background of a control, body of a border, fill of a grid line, foreground of text. A **Fill** has two parts: a [**Pattern**](#pattern) that picks the gradient direction (or `tbPatternNone` for transparent), and a [**ColorPoints**](#colorpoints) collection of one or more colour stops that supply the actual colours. +The colour or gradient that paints a region --- background of a control, body of a border, fill of a grid line, foreground of text. A **Fill** has two parts: a [**Pattern**](#pattern) that picks the gradient direction (or `tbPatternNone` for transparent), and a [**ColorPoints**](#colorpoints) collection of one or more colour stops that supply the actual colours. A single solid colour is just a one-stop fill: call [**ColorPoints.SetSolidColor**](#setsolidcolor) with a `Long` colour, or [**SetSimplePattern**](#setsimplepattern) on the parent **Fill** for a two-colour gradient. @@ -19,7 +19,7 @@ btnGo.HoverState.BackgroundFill.SetSimplePattern vbBlue, vbWhite, _ Pattern:=tbGradientNorthToSouth ``` -For three or more colour stops, build [**FillColorPoint**](#fillcolorpoint-class) instances and pass them to [**SetColorPoints**](#setcolorpoints). The stops accept fully-opaque ARGB literals (`&HFF` alpha in the high byte) — see [**ColorRGBA**](../Enumerations/ColorRGBA) for the encoding: +For three or more colour stops, build [**FillColorPoint**](#fillcolorpoint-class) instances and pass them to [**SetColorPoints**](#setcolorpoints). The stops accept fully-opaque ARGB literals (`&HFF` alpha in the high byte) --- see [**ColorRGBA**](../Enumerations/ColorRGBA) for the encoding: ```tb With pnlHeader.BackgroundFill @@ -95,7 +95,7 @@ Raised whenever [**Pattern**](#pattern) is assigned or the [**ColorPoints**](#co ## FillColorPoints class -The collection of [**FillColorPoint**](#fillcolorpoint-class) stops that define a [**Fill**](#)'s colour gradient. Reached as [**Fill.ColorPoints**](#colorpoints). Internally an array of **FillColorPoint** plus a [**Granularity**](#granularity) integer. +The collection of [**FillColorPoint**](#fillcolorpoint-class) stops that define a [**Fill**](#)'s colour gradient. Accessed as [**Fill.ColorPoints**](#colorpoints). Internally an array of **FillColorPoint** plus a [**Granularity**](#granularity) integer. ### Granularity {: .no_toc } @@ -105,7 +105,7 @@ The size of the generated colour table that interpolates the stops. Higher value ### Values {: .no_toc } -The array of [**FillColorPoint**](#fillcolorpoint-class) gradient stops. Read-write, but in practice you populate it through the [**SetSolidColor**](#setsolidcolor), [**SetSolidColorRGBA**](#setsolidcolorrgba), [**SetColorPoints**](#setcolorpoints), or [**SetColorPointsArray**](#setcolorpointsarray) methods rather than assigning the array directly. +The array of [**FillColorPoint**](#fillcolorpoint-class) gradient stops. Read-write, but in practice populated through the [**SetSolidColor**](#setsolidcolor), [**SetSolidColorRGBA**](#setsolidcolorrgba), [**SetColorPoints**](#setcolorpoints), or [**SetColorPointsArray**](#setcolorpointsarray) methods rather than by assigning the array directly. ### SetSolidColor {: .no_toc } @@ -154,7 +154,7 @@ Raised when the array of stops is reassigned or when any single stop raises its ## FillColorPoint class -A single gradient stop — a colour together with the position (0–100 %) at which the colour applies along the gradient. Elements of the [**FillColorPoints.Values**](#values) array. +A single gradient stop --- a colour together with the position (0--100 %) at which the colour applies along the gradient. Elements of the [**FillColorPoints.Values**](#values) array. ### Color {: .no_toc } diff --git a/docs/Reference/CustomControls/Styles/Line.md b/docs/Reference/CustomControls/Styles/Line.md index c8016300..7766cdb2 100644 --- a/docs/Reference/CustomControls/Styles/Line.md +++ b/docs/Reference/CustomControls/Styles/Line.md @@ -9,7 +9,7 @@ has_toc: false # Line class {: .no_toc } -A single stroke used to draw a grid line, divider, or resizer bar — simpler than a full [**Border**](Borders#border-class) (no blend-with-background flag, no surrounding **Elements** array). Reached as [**WaynesGrid.VerticalLineOptions**](../WaynesGrid/#verticallineoptions), [**HorizontalLineOptions**](../WaynesGrid/#horizontallineoptions), and [**ResizerBar**](../WaynesGrid/#resizerbar). +A single stroke used to draw a grid line, divider, or resizer bar --- simpler than a full [**Border**](Borders#border-class) (no blend-with-background flag, no surrounding **Elements** array). Accessed as [**WaynesGrid.VerticalLineOptions**](../WaynesGrid/#verticallineoptions), [**HorizontalLineOptions**](../WaynesGrid/#horizontallineoptions), and [**ResizerBar**](../WaynesGrid/#resizerbar). ```tb With WaynesGrid1.VerticalLineOptions @@ -28,7 +28,7 @@ The [**Fill**](Fill) that supplies the colour or gradient used to draw the line. ### StrokeSize {: .no_toc } -The stroke thickness in pixels. [**PixelCount**](../Enumerations/PixelCount). Default: 0 (the line is not drawn until you assign a non-zero size). +The stroke thickness in pixels. [**PixelCount**](../Enumerations/PixelCount). Default: 0 (the line is not drawn until a non-zero size is assigned). ## Events diff --git a/docs/Reference/CustomControls/Styles/Padding.md b/docs/Reference/CustomControls/Styles/Padding.md index 4131c23a..3c1a6879 100644 --- a/docs/Reference/CustomControls/Styles/Padding.md +++ b/docs/Reference/CustomControls/Styles/Padding.md @@ -9,7 +9,7 @@ has_toc: false # Padding class {: .no_toc } -Per-side padding, in pixels, applied around the text inside a [**TextRendering**](TextRendering). Reached as [**TextRendering.Padding**](TextRendering#padding). The padded region is what the text [**Alignment**](TextRendering#alignment) is applied to — adding 5 pixels of left padding moves left-aligned text 5 pixels to the right, and shrinks the available area by 5 pixels at the left edge. +Per-side padding, in pixels, applied around the text inside a [**TextRendering**](TextRendering). Accessed as [**TextRendering.Padding**](TextRendering#padding). The padded region is what the text [**Alignment**](TextRendering#alignment) is applied to --- adding 5 pixels of left padding moves left-aligned text 5 pixels to the right, and shrinks the available area by 5 pixels at the left edge. ```tb With txtNotes.NormalState.TextRendering.Padding diff --git a/docs/Reference/CustomControls/Styles/TextRendering.md b/docs/Reference/CustomControls/Styles/TextRendering.md index 8c7d3c35..7993cf8e 100644 --- a/docs/Reference/CustomControls/Styles/TextRendering.md +++ b/docs/Reference/CustomControls/Styles/TextRendering.md @@ -9,7 +9,7 @@ has_toc: false # TextRendering class {: .no_toc } -Aggregates everything needed to draw a piece of text inside a control: the font, the padding, the fill that supplies the text colour, an optional array of outlines, the alignment within the available area, and the overflow behaviour. Reached as `<state>.TextRendering`, [**WaynesLabel.TextRendering**](../WaynesLabel#textrendering), and [**CellRenderingOptions.TextRendering**](../WaynesGrid/CellRenderingOptions#textrendering). +Aggregates everything needed to draw a piece of text inside a control: the font, the padding, the fill that supplies the text colour, an optional array of outlines, the alignment within the available area, and the overflow behaviour. Accessed as `<state>.TextRendering`, [**WaynesLabel.TextRendering**](../WaynesLabel#textrendering), and [**CellRenderingOptions.TextRendering**](../WaynesGrid/CellRenderingOptions#textrendering). A newly-constructed **TextRendering** pre-sets its [**Fill**](#fill) to solid black so that text is immediately visible. @@ -22,7 +22,7 @@ With lblTitle.TextRendering End With ``` -[**Fill**](#fill) can hold a gradient just as well as a solid colour, so glyphs themselves can be painted with a top-to-bottom or corner-to-corner colour transition. [**Outlines**](#outlines) is an array of [**Border**](Borders#border-class) elements stroked around the glyphs — a single thin black outline gives a "stickered" look; layering several outlines with different [**StrokeSize**](Borders#strokesize) values produces a glow or drop-shadow: +[**Fill**](#fill) can hold a gradient just as well as a solid colour, so glyphs themselves can be painted with a top-to-bottom or corner-to-corner colour transition. [**Outlines**](#outlines) is an array of [**Border**](Borders#border-class) elements stroked around the glyphs --- a single thin black outline gives a "stickered" look; layering several outlines with different [**StrokeSize**](Borders#strokesize) values produces a glow or drop-shadow: ```tb With lblBanner.TextRendering @@ -39,7 +39,7 @@ With lblBanner.TextRendering End With ``` -Set [**OverflowMode**](#overflowmode) to **tbShrinkToFit** to scale the glyphs down rather than truncating with an ellipsis when the text is too long for the available width — useful on fixed-width labels whose caption is set at runtime from data of unpredictable length. +Setting [**OverflowMode**](#overflowmode) to **tbShrinkToFit** scales the glyphs down rather than truncating with an ellipsis when the text is too long for the available width --- useful on fixed-width labels whose caption is set at runtime from data of unpredictable length. * TOC {:toc} @@ -85,7 +85,7 @@ Raised when [**Alignment**](#alignment) or [**OverflowMode**](#overflowmode) is ## FontStyle class -The font metrics that control how [**TextRendering**](#) lays out text. Reached as [**TextRendering.Font**](#font). +The font metrics that control how [**TextRendering**](#) lays out text. Accessed as [**TextRendering.Font**](#font). ### Italic {: .no_toc } diff --git a/docs/Reference/CustomControls/Styles/index.md b/docs/Reference/CustomControls/Styles/index.md index 771fb01a..e1ef662d 100644 --- a/docs/Reference/CustomControls/Styles/index.md +++ b/docs/Reference/CustomControls/Styles/index.md @@ -7,7 +7,7 @@ has_toc: false # Styles -The shared appearance helper classes used by the [**CustomControls**](..) package's concrete `Waynes…` controls. Each is a small container of related visual settings — a [**Fill**](Fill) is a colour or gradient, a [**Borders**](Borders) is an array of border strokes, a [**Corners**](Corners) is the shape and radius of each corner, and so on. Controls compose them through `Public WithEvents …` properties: a [**WaynesButton**](../WaynesButton/) holds four [**WaynesButtonState**](../WaynesButton/WaynesButtonState) sub-objects (Normal / Hover / Focused / Pressed), each of which has its own [**BackgroundFill**](../WaynesButton/WaynesButtonState#backgroundfill), [**Borders**](../WaynesButton/WaynesButtonState#borders), [**Corners**](../WaynesButton/WaynesButtonState#corners), and [**TextRendering**](../WaynesButton/WaynesButtonState#textrendering). +The shared appearance helper classes used by the [**CustomControls**](..) package's concrete `Waynes…` controls. Each is a small container of related visual settings --- a [**Fill**](Fill) is a colour or gradient, a [**Borders**](Borders) is an array of border strokes, a [**Corners**](Corners) is the shape and radius of each corner, and so on. Controls compose them through `Public WithEvents …` properties: a [**WaynesButton**](../WaynesButton/) holds four [**WaynesButtonState**](../WaynesButton/WaynesButtonState) sub-objects (Normal / Hover / Focused / Pressed), each of which has its own [**BackgroundFill**](../WaynesButton/WaynesButtonState#backgroundfill), [**Borders**](../WaynesButton/WaynesButtonState#borders), [**Corners**](../WaynesButton/WaynesButtonState#corners), and [**TextRendering**](../WaynesButton/WaynesButtonState#textrendering). Every style object raises an **OnChanged** event whenever any of its public fields is assigned. The hosting control listens for that event on each of its sub-objects and asks the framework to repaint, so style changes made at runtime are reflected immediately. @@ -21,4 +21,4 @@ Every style object raises an **OnChanged** event whenever any of its public fiel | [Padding](Padding) | per-side padding around text inside a [**TextRendering**](TextRendering) | | [TextRendering](TextRendering) | font, padding, fill, outlines, alignment, and overflow for text; contains the `FontStyle` sub-object that holds the font metrics | -The style classes are declared `Private Class` in the **CustomControlsPackage** source — they cannot be created with `New` from outside the package, and a variable cannot be typed as e.g. `Dim x As Fill` from a referencing project. Application code reaches every style object exclusively through the property chain that hangs off a concrete control. +The style classes are declared `Private Class` in the **CustomControlsPackage** source --- they cannot be created with `New` from outside the package, and a variable cannot be typed as e.g. `Dim x As Fill` from a referencing project. Application code accesses every style object exclusively through the property chain that hangs off a concrete control. diff --git a/docs/Reference/CustomControls/WaynesButton/WaynesButtonState.md b/docs/Reference/CustomControls/WaynesButton/WaynesButtonState.md index 682939e5..dbee4ebe 100644 --- a/docs/Reference/CustomControls/WaynesButton/WaynesButtonState.md +++ b/docs/Reference/CustomControls/WaynesButton/WaynesButtonState.md @@ -9,11 +9,11 @@ has_toc: false # WaynesButtonState class {: .no_toc } -A bundle of the four style objects that describe a single visual state of a [**WaynesButton**](.) — its corners, background fill, borders, and text rendering. Each button has four parallel instances reachable as [**NormalState**](.#normalstate), [**HoverState**](.#hoverstate), [**FocusedState**](.#focusedstate), and [**PressedState**](.#pressedstate); the button picks one at each repaint depending on the mouse / focus state. +A bundle of the four style objects that describe a single visual state of a [**WaynesButton**](.) --- its corners, background fill, borders, and text rendering. Each button has four parallel instances accessed as [**NormalState**](.#normalstate), [**HoverState**](.#hoverstate), [**FocusedState**](.#focusedstate), and [**PressedState**](.#pressedstate); the button picks one at each repaint depending on the mouse / focus state. Newly-constructed **WaynesButtonState** objects pre-set their **BackgroundFill** to a solid mid-blue and all four corners to a 15-pixel curve. Override per-state to give the button a different look in each state. -The type itself is `Private Class` — you reach instances only through the **WaynesButton.…State** properties and cannot declare a variable typed as **WaynesButtonState** from outside the package. +The type itself is `Private Class` --- instances are accessed only through the **WaynesButton.…State** properties, and a variable typed as **WaynesButtonState** cannot be declared from outside the package. ```tb With btnGo.NormalState @@ -55,7 +55,7 @@ The [**TextRendering**](../Styles/TextRendering) that controls how the button's ### InitializeDefaults {: .no_toc } -Resets the state object to the package's defaults — solid mid-blue **BackgroundFill** and 15-pixel curved corners. Called automatically the first time the parent button is initialized, if no serialized data was loaded. +Resets the state object to the package's defaults --- solid mid-blue **BackgroundFill** and 15-pixel curved corners. Called automatically the first time the parent button is initialized, if no serialized data was loaded. Syntax: *object*.**InitializeDefaults** diff --git a/docs/Reference/CustomControls/WaynesButton/index.md b/docs/Reference/CustomControls/WaynesButton/index.md index 938781ef..13d21af4 100644 --- a/docs/Reference/CustomControls/WaynesButton/index.md +++ b/docs/Reference/CustomControls/WaynesButton/index.md @@ -8,9 +8,9 @@ has_toc: false # WaynesButton class {: .no_toc } -An owner-drawn push-button. Renders a configurable rectangle (with optional gradient fill, borders, rounded / notched / cut-out corners) and a centred [**Caption**](#caption), in one of four visual states — normal, hovered, focused, or pressed — controlled by four parallel [**WaynesButtonState**](WaynesButtonState) sub-objects. +An owner-drawn push-button. Renders a configurable rectangle (with optional gradient fill, borders, rounded / notched / cut-out corners) and a centred [**Caption**](#caption), in one of four visual states --- normal, hovered, focused, or pressed --- controlled by four parallel [**WaynesButtonState**](WaynesButtonState) sub-objects. -The button raises a [**Click**](#click) event when clicked, plus the standard set of mouse, focus, and keyboard events. By default the four state objects are pre-set with a solid mid-blue ([**WAYNESCOLOR_BLUE**](#) — `&HAC7220`) background and 15-pixel curved corners. +The button raises a [**Click**](#click) event when clicked, plus the standard set of mouse, focus, and keyboard events. By default the four state objects are pre-set with a solid mid-blue ([**WAYNESCOLOR_BLUE**](#) --- `&HAC7220`) background and 15-pixel curved corners. ```tb Private Sub Form_Load() @@ -39,7 +39,7 @@ The button paints in one of four states, chosen at each repaint: | [**FocusedState**](#focusedstate) | The control has the keyboard focus and the mouse is not hovering or pressing. | | [**NormalState**](#normalstate) | None of the above. | -Each state is a [**WaynesButtonState**](WaynesButtonState) — a small bundle of [**Corners**](../Styles/Corners), [**BackgroundFill**](../Styles/Fill), [**Borders**](../Styles/Borders), and [**TextRendering**](../Styles/TextRendering). +Each state is a [**WaynesButtonState**](WaynesButtonState) --- a small bundle of [**Corners**](../Styles/Corners), [**BackgroundFill**](../Styles/Fill), [**Borders**](../Styles/Borders), and [**TextRendering**](../Styles/TextRendering). ## Properties @@ -88,7 +88,7 @@ The unique design-time name of the control on its parent form. **String**. Inher ### NormalState {: .no_toc } -The [**WaynesButtonState**](WaynesButtonState) used when the button is idle — not hovered, not focused, not pressed. +The [**WaynesButtonState**](WaynesButtonState) used when the button is idle --- not hovered, not focused, not pressed. ### PressedState {: .no_toc } diff --git a/docs/Reference/CustomControls/WaynesForm/WindowsFormOptions.md b/docs/Reference/CustomControls/WaynesForm/WindowsFormOptions.md index 0a0d4b4a..5c4d35ba 100644 --- a/docs/Reference/CustomControls/WaynesForm/WindowsFormOptions.md +++ b/docs/Reference/CustomControls/WaynesForm/WindowsFormOptions.md @@ -9,11 +9,11 @@ has_toc: false # WindowsFormOptions class {: .no_toc } -The Win32-frame settings of a [**WaynesForm**](.) — border style, initial window state, startup position, taskbar visibility, and the title-bar buttons. Surfaces as [**WaynesForm.WindowsOptions**](.#windowsoptions); a single instance per form, created automatically. +The Win32-frame settings of a [**WaynesForm**](.) --- border style, initial window state, startup position, taskbar visibility, and the title-bar buttons. Exposed as [**WaynesForm.WindowsOptions**](.#windowsoptions); a single instance per form, created automatically. -Most of the fields take effect *once*, when the form is first shown — changing [**StartUpPosition**](#startupposition) or [**WindowState**](#windowstate) on a form that is already visible has no effect. The exception is the title-bar buttons; whether they have a visible effect depends on whether [**BorderStyle**](#borderstyle) is one of the styles that include those buttons in the first place. +Most of the fields take effect *once*, when the form is first shown --- changing [**StartUpPosition**](#startupposition) or [**WindowState**](#windowstate) on a form that is already visible has no effect. The exception is the title-bar buttons; whether they have a visible effect depends on whether [**BorderStyle**](#borderstyle) is one of the styles that include those buttons in the first place. -The type itself is `Private Class` — you reach the instance only through the form's **WindowsOptions** property and cannot declare a variable typed as **WindowsFormOptions** from outside the package. +The type itself is `Private Class` --- the instance is accessed only through the form's **WindowsOptions** property, and a variable typed as **WindowsFormOptions** cannot be declared from outside the package. ```tb Private Sub Form_Load() @@ -31,7 +31,7 @@ End Sub ### BorderStyle {: .no_toc } -The Win32 frame style — thin / thick border, resizable / fixed, normal / tool-window title bar. A member of [**BorderStyle**](../Enumerations/BorderStyle). Default: **tbFixedSizable**. +The Win32 frame style --- thin / thick border, resizable / fixed, normal / tool-window title bar. A member of [**BorderStyle**](../Enumerations/BorderStyle). Default: **tbFixedSizable**. ### ControlBox {: .no_toc } @@ -61,7 +61,7 @@ How the form's window is positioned when first shown. A member of [**StartupPosi ### WindowState {: .no_toc } -The window state of the form when first shown — normal, minimized, or maximized. A member of [**WindowState**](../Enumerations/WindowState). Default: **tbNormal**. +The window state of the form when first shown --- normal, minimized, or maximized. A member of [**WindowState**](../Enumerations/WindowState). Default: **tbNormal**. ## Events diff --git a/docs/Reference/CustomControls/WaynesForm/index.md b/docs/Reference/CustomControls/WaynesForm/index.md index 1eb9d7da..0d970874 100644 --- a/docs/Reference/CustomControls/WaynesForm/index.md +++ b/docs/Reference/CustomControls/WaynesForm/index.md @@ -12,7 +12,7 @@ The top-level form class that hosts the package's custom controls. A **WaynesFor Within the current release of the package every form created with the designer is hard-coded to use **WaynesForm** as its root class; other base form classes are planned but not yet supported. -A form has a [**Caption**](#caption) (shown in the Win32 title bar), a [**BackgroundFill**](#backgroundfill) (painted across its entire client area), and a [**WindowsOptions**](#windowsoptions) sub-object that controls the surrounding Win32 frame — border style, window state, taskbar visibility, minimize / maximize buttons, and so on. Showing the form is done by calling [**Show**](#show); closing it by [**Close**](#close). +A form has a [**Caption**](#caption) (shown in the Win32 title bar), a [**BackgroundFill**](#backgroundfill) (painted across its entire client area), and a [**WindowsOptions**](#windowsoptions) sub-object that controls the surrounding Win32 frame --- border style, window state, taskbar visibility, minimize / maximize buttons, and so on. Call [**Show**](#show) to display the form; call [**Close**](#close) to close it. ```tb Private Sub Form_Load() @@ -26,7 +26,7 @@ Private Sub Form_Load() End Sub ``` -[**BackgroundFill**](#backgroundfill) is an ordinary [**Fill**](../Styles/Fill), so the form can display a gradient backdrop or a solid colour — this is what the package's `HelloWorld` sample form uses to give itself a soft top-to-bottom wash: +[**BackgroundFill**](#backgroundfill) is an ordinary [**Fill**](../Styles/Fill), so the form can display a gradient backdrop or a solid colour --- this is what the package's `HelloWorld` sample form uses to give itself a soft top-to-bottom wash: ```tb Private Sub Form_Load() @@ -40,14 +40,14 @@ End Sub ## Modal display -The current release supports modal display only. Calling [**Show**](#show) with **vbModeless** writes a debug-print message and otherwise does nothing — call **Show vbModal** to display the form. +The current release supports modal display only. Calling [**Show**](#show) with **vbModeless** writes a debug-print message and otherwise does nothing --- call **Show vbModal** to display the form. ## Properties ### BackgroundFill {: .no_toc } -The [**Fill**](../Styles/Fill) that paints the form's entire client area. Defaults to a solid light-grey ([**WAYNESCOLOR_LIGHTGREY**](#) — `&HD0D0D0`). +The [**Fill**](../Styles/Fill) that paints the form's entire client area. Defaults to a solid light-grey ([**WAYNESCOLOR_LIGHTGREY**](#) --- `&HD0D0D0`). ### Caption {: .no_toc } @@ -59,12 +59,12 @@ Syntax: *object*.**Caption** [ = *string* ] ### Controls {: .no_toc } -The [**CustomControlsCollection**](../Framework/CustomControlsCollection) of every control hosted on the form. Inherited from the form base. Read-only — iterate or look up by index / name to reach individual controls. +The [**CustomControlsCollection**](../Framework/CustomControlsCollection) of every control hosted on the form. Inherited from the form base. Read-only --- iterate or look up by index / name to access individual controls. ### FormDesignerId {: .no_toc } -A **String** holding the unique GUID that associates this form instance with its designer-saved metadata. Inherited from the form base. Application code does not normally read or write this — the framework populates it. +A **String** holding the unique GUID that associates this form instance with its designer-saved metadata. Inherited from the form base. Application code does not normally read or write this --- the framework populates it. ### Height {: .no_toc } @@ -74,7 +74,7 @@ The form's height in pixels. [**PixelCount**](../Enumerations/PixelCount). Inher ### Left {: .no_toc } -The form's left position in pixels — honoured only when [**WindowsOptions.StartUpPosition**](WindowsFormOptions#startupposition) is **tbStartUpManual**. [**PixelCount**](../Enumerations/PixelCount). Inherited. +The form's left position in pixels --- honoured only when [**WindowsOptions.StartUpPosition**](WindowsFormOptions#startupposition) is **tbStartUpManual**. [**PixelCount**](../Enumerations/PixelCount). Inherited. ### Name {: .no_toc } @@ -84,7 +84,7 @@ The form's name within the project. **String**. Inherited. ### Top {: .no_toc } -The form's top position in pixels — honoured only when [**WindowsOptions.StartUpPosition**](WindowsFormOptions#startupposition) is **tbStartUpManual**. [**PixelCount**](../Enumerations/PixelCount). Inherited. +The form's top position in pixels --- honoured only when [**WindowsOptions.StartUpPosition**](WindowsFormOptions#startupposition) is **tbStartUpManual**. [**PixelCount**](../Enumerations/PixelCount). Inherited. ### Width {: .no_toc } @@ -94,7 +94,7 @@ The form's width in pixels. [**PixelCount**](../Enumerations/PixelCount). Inheri ### WindowsOptions {: .no_toc } -The [**WindowsFormOptions**](WindowsFormOptions) that controls the Win32 frame — border style, window state, taskbar visibility, minimize / maximize buttons, system menu. +The [**WindowsFormOptions**](WindowsFormOptions) that controls the Win32 frame --- border style, window state, taskbar visibility, minimize / maximize buttons, system menu. ## Methods @@ -108,7 +108,7 @@ Syntax: *object*.**Close** ### Show {: .no_toc } -Shows the form. The current release supports modal display only — calling with **vbModeless** writes a debug message and otherwise does nothing. +Shows the form. The current release supports modal display only --- calling with **vbModeless** writes a debug message and otherwise does nothing. Syntax: *object*.**Show** [ *Modal* ] @@ -118,7 +118,7 @@ Syntax: *object*.**Show** [ *Modal* ] ### StartupShow {: .no_toc } -Shows the form unconditionally — used by the framework to display the project's startup form. Application code can call it but [**Show**](#show) is the normal entry point. +Shows the form unconditionally --- used by the framework to display the project's startup form. Application code can call it but [**Show**](#show) is the normal entry point. Syntax: *object*.**StartupShow** @@ -127,6 +127,6 @@ Syntax: *object*.**StartupShow** ### Click {: .no_toc } -Raised when the user clicks on the form's background — i.e. on a region not occupied by a hosted control. +Raised when the user clicks on the form's background --- i.e. on a region not occupied by a hosted control. Syntax: *object*\_**Click**( ) diff --git a/docs/Reference/CustomControls/WaynesFrame.md b/docs/Reference/CustomControls/WaynesFrame.md index 5f5a7172..28a80519 100644 --- a/docs/Reference/CustomControls/WaynesFrame.md +++ b/docs/Reference/CustomControls/WaynesFrame.md @@ -10,7 +10,7 @@ has_toc: false A rectangular container control whose entire area is painted with a configurable [**BackgroundFill**](#backgroundfill). Used to group other controls on a [**WaynesForm**](WaynesForm/), with the same layout / sizing members as any other custom control. -The default fill is a solid mid-grey ([**WAYNESCOLOR_GREY**](#) — `&H808080`); change it by accessing the **Fill.ColorPoints** collection. +The default fill is a solid mid-grey ([**WAYNESCOLOR_GREY**](#) --- `&H808080`); change it by accessing the **Fill.ColorPoints** collection. ```tb Private Sub Form_Load() @@ -18,7 +18,7 @@ Private Sub Form_Load() End Sub ``` -Frames work well as containers for [**Dock**](Enumerations/DockMode)-positioned children. Set the frame's own **Dock** to **tbDockFill** so it claims the form's body, then dock its children to **tbDockTop** / **tbDockLeft** / **tbDockFill** / etc. — the docking calculation walks the container tree, so children dock to the frame's client area rather than to the form. The order in which the children are added still determines which edges they claim first. +Frames work well as containers for [**Dock**](Enumerations/DockMode)-positioned children. Set the frame's own **Dock** to **tbDockFill** so it claims the form's body, then dock its children to **tbDockTop** / **tbDockLeft** / **tbDockFill** / etc. --- the docking calculation traverses the container tree, so children dock to the frame's client area rather than to the form. The order in which the children are added still determines which edges they claim first. ## Properties diff --git a/docs/Reference/CustomControls/WaynesGrid/CellRenderingOptions.md b/docs/Reference/CustomControls/WaynesGrid/CellRenderingOptions.md index 1606afab..c32aaa79 100644 --- a/docs/Reference/CustomControls/WaynesGrid/CellRenderingOptions.md +++ b/docs/Reference/CustomControls/WaynesGrid/CellRenderingOptions.md @@ -9,7 +9,7 @@ has_toc: false # CellRenderingOptions class {: .no_toc } -A bundle of the style objects that describe one *category* of cell in a [**WaynesGrid**](.). Each grid has six parallel instances — one for column headers, one for row headers, one for normal cells, one for the hovered cell, one for the selected cell, and one for cells inside a full-row or full-column multi-selection — and the grid picks the appropriate instance per cell at paint time. +A bundle of the style objects that describe one *category* of cell in a [**WaynesGrid**](.). Each grid has six parallel instances --- one for column headers, one for row headers, one for normal cells, one for the hovered cell, one for the selected cell, and one for cells inside a full-row or full-column multi-selection --- and the grid picks the appropriate instance per cell at paint time. ```tb With Grid1.SelectedCellOptions @@ -38,7 +38,7 @@ The mouse cursor shown when the pointer is over this category of cell. A member ### Fill {: .no_toc } -The [**Fill**](../Styles/Fill) that paints the cell background. Newly-constructed **CellRenderingOptions** instances default to a solid mid-grey background ([**WAYNESCOLOR_GREY**](#) — `&H808080`). +The [**Fill**](../Styles/Fill) that paints the cell background. Newly-constructed **CellRenderingOptions** instances default to a solid mid-grey background ([**WAYNESCOLOR_GREY**](#) --- `&H808080`). ### TextRendering {: .no_toc } diff --git a/docs/Reference/CustomControls/WaynesGrid/Column.md b/docs/Reference/CustomControls/WaynesGrid/Column.md index e2028d74..98b9fadc 100644 --- a/docs/Reference/CustomControls/WaynesGrid/Column.md +++ b/docs/Reference/CustomControls/WaynesGrid/Column.md @@ -9,7 +9,7 @@ has_toc: false # Column class {: .no_toc } -One column of a [**WaynesGrid**](.). Carries a [**Caption**](#caption) that is shown in the column-header row and a [**Width**](#width) that the user can drag at run time. Elements of [**WaynesGrid.Columns**](.#columns). +One column of a [**WaynesGrid**](.). Has a [**Caption**](#caption) that is shown in the column-header row and a [**Width**](#width) that the user can drag at run time. Elements of [**WaynesGrid.Columns**](.#columns). ```tb ReDim Grid1.Columns(2) diff --git a/docs/Reference/CustomControls/WaynesGrid/index.md b/docs/Reference/CustomControls/WaynesGrid/index.md index 47909294..4203b200 100644 --- a/docs/Reference/CustomControls/WaynesGrid/index.md +++ b/docs/Reference/CustomControls/WaynesGrid/index.md @@ -8,7 +8,7 @@ has_toc: false # WaynesGrid class {: .no_toc } -A tabular data display — a grid of cells with column headers and row headers, resizable columns, optional grid lines, hover and selection highlighting, vertical and horizontal scrolling via the mouse wheel, and full keyboard navigation. The number of rows is set by [**RowCount**](#rowcount); the cells themselves are filled in by handling the [**GetCellText**](#getcelltext) event, which fires once per visible cell as the grid paints. +A tabular data display --- a grid of cells with column headers and row headers, resizable columns, optional grid lines, hover and selection highlighting, vertical and horizontal scrolling via the mouse wheel, and full keyboard navigation. The number of rows is set by [**RowCount**](#rowcount); the cells themselves are filled in by handling the [**GetCellText**](#getcelltext) event, which fires once per visible cell as the grid paints. The grid has an array of [**Column**](Column) objects giving each column its [**Caption**](Column#caption) and [**Width**](Column#width). Five distinct [**CellRenderingOptions**](CellRenderingOptions) sub-objects control the appearance of column headers, row headers, normal cells, the hovered cell, the selected cell, and full-column / full-row multi-selection. @@ -35,7 +35,7 @@ Private Sub Grid1_GetCellText( _ End Sub ``` -The six [**CellRenderingOptions**](CellRenderingOptions) sub-objects ([**ColumnHeaderOptions**](#columnheaderoptions), [**RowHeaderOptions**](#rowheaderoptions), [**CellOptions**](#celloptions), [**HoverCellOptions**](#hovercelloptions), [**SelectedCellOptions**](#selectedcelloptions), [**MultiSelectCellOptions**](#multiselectcelloptions)) give the grid its visual personality. A typical setup gives headers a gradient, body cells left-aligned text with a small left-padding indent, and the selected cell a contrasting border: +The six [**CellRenderingOptions**](CellRenderingOptions) sub-objects ([**ColumnHeaderOptions**](#columnheaderoptions), [**RowHeaderOptions**](#rowheaderoptions), [**CellOptions**](#celloptions), [**HoverCellOptions**](#hovercelloptions), [**SelectedCellOptions**](#selectedcelloptions), [**MultiSelectCellOptions**](#multiselectcelloptions)) control the grid's visual style. A typical setup gives headers a gradient, body cells left-aligned text with a small left-padding indent, and the selected cell a contrasting border: ```tb With Grid1.ColumnHeaderOptions @@ -64,7 +64,7 @@ End With The grid exposes three separate selection states, each tracked through its own pair of properties: -- A single hover-highlight cell — the cell currently under the mouse — controlled by [**HoverCellOptions**](#hovercelloptions). Internal to the grid; not exposed as a property. +- A single hover-highlight cell --- the cell currently under the mouse --- controlled by [**HoverCellOptions**](#hovercelloptions). Internal to the grid; not exposed as a property. - A single selected cell, with coordinates in [**SelectedCellX**](#selectedcellx) and [**SelectedCellY**](#selectedcelly), drawn using [**SelectedCellOptions**](#selectedcelloptions). - A full-row or full-column multi-selection, indicated by clicking the row header or column header. [**SelectedFullColumnX**](#selectedfullcolumnx) and [**SelectedFullRowY**](#selectedfullrowy) hold the indices; the affected cells render with [**MultiSelectCellOptions**](#multiselectcelloptions). @@ -140,7 +140,7 @@ The [**Line**](../Styles/Line) drawn over a column-edge while the user is draggi ### RowCount {: .no_toc } -The total number of rows in the grid. **Long**. Default: -1 (unbounded — the grid paints rows forever as the user scrolls). +The total number of rows in the grid. **Long**. Default: -1 (unbounded --- the grid paints rows forever as the user scrolls). ### RowHeaderOptions {: .no_toc } @@ -221,7 +221,7 @@ Syntax: *object*.**Repaint** ### GetCellText {: .no_toc } -Raised once per visible cell as the grid paints, asking the host for the text to display. The default text is `<column-caption><row-index+1>` — replace *Value* in the handler to show real data. +Raised once per visible cell as the grid paints, asking the host for the text to display. The default text is `<column-caption><row-index+1>` --- replace *Value* in the handler to show real data. Syntax: *object*\_**GetCellText**( **ByVal** *X* **As Long**, **ByVal** *Y* **As Long**, **ByRef** *Value* **As String** ) diff --git a/docs/Reference/CustomControls/WaynesLabel.md b/docs/Reference/CustomControls/WaynesLabel.md index 6468febc..5a5d8676 100644 --- a/docs/Reference/CustomControls/WaynesLabel.md +++ b/docs/Reference/CustomControls/WaynesLabel.md @@ -8,7 +8,7 @@ has_toc: false # WaynesLabel class {: .no_toc } -A static text-display control. Paints a [**Caption**](#caption) string inside its rectangle using the configured [**TextRendering**](#textrendering), on top of a [**BackgroundFill**](#backgroundfill). The label has no interactive states — appearance is the same whether the mouse is hovering over it or not. +A static text-display control. Paints a [**Caption**](#caption) string inside its rectangle using the configured [**TextRendering**](#textrendering), on top of a [**BackgroundFill**](#backgroundfill). The label has no interactive states --- appearance is the same whether the mouse is hovering over it or not. ```tb Private Sub Form_Load() @@ -80,7 +80,7 @@ The unique design-time name of the control on its parent form. **String**. Inher ### TextRendering {: .no_toc } -The [**TextRendering**](Styles/TextRendering) that controls how the [**Caption**](#caption) is drawn — font, padding, fill, outlines, alignment, and overflow. +The [**TextRendering**](Styles/TextRendering) that controls how the [**Caption**](#caption) is drawn --- font, padding, fill, outlines, alignment, and overflow. ### Top {: .no_toc } diff --git a/docs/Reference/CustomControls/WaynesSlider/WaynesSliderState.md b/docs/Reference/CustomControls/WaynesSlider/WaynesSliderState.md index 679c3e0c..18d9719e 100644 --- a/docs/Reference/CustomControls/WaynesSlider/WaynesSliderState.md +++ b/docs/Reference/CustomControls/WaynesSlider/WaynesSliderState.md @@ -11,11 +11,11 @@ has_toc: false A bundle of the style objects that describe a single visual state of a [**WaynesSlider**](.). Each slider holds three parallel instances ([**NormalState**](.#normalstate), [**HoverState**](.#hoverstate), [**FocusedState**](.#focusedstate)); the slider picks one at each repaint depending on the mouse / focus state. -The state has two halves — the *background* (the full track behind the block) and the *block* (the draggable rectangle that indicates [**Value**](.#value)). Each half has its own [**Fill**](../Styles/Fill), [**Borders**](../Styles/Borders), and [**Corners**](../Styles/Corners). A [**TextRendering**](../Styles/TextRendering) on the state controls how the optional [**DisplayFormat**](.#displayformat) text is drawn on the block. +The state has two halves --- the *background* (the full track behind the block) and the *block* (the draggable rectangle that indicates [**Value**](.#value)). Each half has its own [**Fill**](../Styles/Fill), [**Borders**](../Styles/Borders), and [**Corners**](../Styles/Corners). A [**TextRendering**](../Styles/TextRendering) on the state controls how the optional [**DisplayFormat**](.#displayformat) text is drawn on the block. -[**InitializeDefaultValues**](#initializedefaultvalues) pre-sets the block to a solid mid-blue ([**WAYNESCOLOR_BLUE**](#) — `&HAC7220`) fill, a 2-pixel black background border, and a transparent block border that acts as inner padding inside the background. +[**InitializeDefaultValues**](#initializedefaultvalues) pre-sets the block to a solid mid-blue ([**WAYNESCOLOR_BLUE**](#) --- `&HAC7220`) fill, a 2-pixel black background border, and a transparent block border that acts as inner padding inside the background. -The type itself is `Public Class` but cannot be instantiated from outside the package — reach instances only through the slider's **NormalState** / **HoverState** / **FocusedState** properties. +The type itself is `Public Class` but cannot be instantiated from outside the package --- instances are accessed only through the slider's **NormalState** / **HoverState** / **FocusedState** properties. ## Properties @@ -64,7 +64,7 @@ The [**TextRendering**](../Styles/TextRendering) that controls how the optional ### InitializeDefaultValues {: .no_toc } -Resets the state object to the package's defaults — a solid mid-blue block fill, a 2-pixel black background border, and a transparent block border. Called automatically the first time the parent slider is initialized, if no serialized data was loaded. +Resets the state object to the package's defaults --- a solid mid-blue block fill, a 2-pixel black background border, and a transparent block border. Called automatically the first time the parent slider is initialized, if no serialized data was loaded. Syntax: *object*.**InitializeDefaultValues** diff --git a/docs/Reference/CustomControls/WaynesSlider/index.md b/docs/Reference/CustomControls/WaynesSlider/index.md index 06fd07a6..b49d443a 100644 --- a/docs/Reference/CustomControls/WaynesSlider/index.md +++ b/docs/Reference/CustomControls/WaynesSlider/index.md @@ -8,9 +8,9 @@ has_toc: false # WaynesSlider class {: .no_toc } -A horizontal or vertical slider control — a draggable block over a track — for editing an integer value within a range. The user can drag the block, click on the track to step the value by one page, or use the arrow keys when the control has focus; an optional auto-increment timer activates while a mouse button is held down on the track. +A horizontal or vertical slider control --- a draggable block over a track --- for editing an integer value within a range. The user can drag the block, click on the track to step the value by one page, or use the arrow keys when the control has focus; an optional auto-increment timer activates while a mouse button is held down on the track. -The control paints three visual states ([**NormalState**](#normalstate), [**HoverState**](#hoverstate), [**FocusedState**](#focusedstate)) controlled by parallel [**WaynesSliderState**](WaynesSliderState) sub-objects, each of which has independent fill / border / corner styling for the background and for the block. The current [**Value**](#value) is optionally rendered as text on the block — as a raw integer or as a formatted percentage — depending on [**DisplayFormat**](#displayformat). +The control paints three visual states ([**NormalState**](#normalstate), [**HoverState**](#hoverstate), [**FocusedState**](#focusedstate)) controlled by parallel [**WaynesSliderState**](WaynesSliderState) sub-objects, each of which has independent fill / border / corner styling for the background and for the block. The current [**Value**](#value) is optionally rendered as text on the block --- as a raw integer or as a formatted percentage --- depending on [**DisplayFormat**](#displayformat). If the control's [**Height**](#height) is greater than its [**Width**](#width) on first display, the slider defaults to [**Direction**](#direction) = **Vertical**; otherwise it defaults to **Horizontal**. @@ -24,7 +24,7 @@ Private Sub Form_Load() End Sub ``` -[**Value**](#value) is just a **Long** property — assigning to it from outside the control moves the block and triggers a repaint. Combined with a [**WaynesTimer**](../WaynesTimer), the slider can animate itself across its range: +[**Value**](#value) is just a **Long** property --- assigning to it from outside the control moves the block and triggers a repaint. Combined with a [**WaynesTimer**](../WaynesTimer), the slider can animate itself across its range: ```tb Private Sub Form_Load() @@ -63,7 +63,7 @@ How the [**Value**](#value) is rendered on the block, declared inside the **Wayn | Constant | Value | Description | |----------|-------|-------------| | **DisplayValue**{: #displayvalue } | 0 | Show the raw integer value. | -| **DisplayPercentage**{: #displaypercentage } | 1 | Show the value as a percentage of the range — `FormatPercent((Value - MinValue) / (MaxValue - MinValue), 1)`. | +| **DisplayPercentage**{: #displaypercentage } | 1 | Show the value as a percentage of the range --- `FormatPercent((Value - MinValue) / (MaxValue - MinValue), 1)`. | | **DisplayNone**{: #displaynone } | 2 | No text on the block. | ## Properties @@ -131,7 +131,7 @@ The unique design-time name of the control on its parent form. **String**. Inher ### NormalState {: .no_toc } -The [**WaynesSliderState**](WaynesSliderState) used when the slider is idle — not hovered, not focused. +The [**WaynesSliderState**](WaynesSliderState) used when the slider is idle --- not hovered, not focused. ### PagingStepValue {: .no_toc } @@ -141,7 +141,7 @@ How far [**Value**](#value) moves when the user clicks on the track outside the ### StepValue {: .no_toc } -The granularity of the slider — [**Value**](#value) is rounded to a multiple of **StepValue** offset from [**MinValue**](#minvalue) before each paint. **Long**. Default: 1. +The granularity of the slider --- [**Value**](#value) is rounded to a multiple of **StepValue** offset from [**MinValue**](#minvalue) before each paint. **Long**. Default: 1. ### TabIndex {: .no_toc } @@ -178,4 +178,4 @@ The control's width in pixels. [**PixelCount**](../Enumerations/PixelCount). Inh ### WrapAround {: .no_toc } -When **False** (the default), [**Value**](#value) is clamped to the range `[MinValue, MaxValue]`. When **True**, values outside the range are allowed and the block wraps around — the slider paints additional block instances on the opposite edge to give a continuous visual. **Boolean**. +When **False** (the default), [**Value**](#value) is clamped to the range `[MinValue, MaxValue]`. When **True**, values outside the range are allowed and the block wraps around --- the slider paints additional block instances on the opposite edge to give a continuous visual. **Boolean**. diff --git a/docs/Reference/CustomControls/WaynesTextBox/WaynesTextBoxState.md b/docs/Reference/CustomControls/WaynesTextBox/WaynesTextBoxState.md index 0a7ecadb..1715766a 100644 --- a/docs/Reference/CustomControls/WaynesTextBox/WaynesTextBoxState.md +++ b/docs/Reference/CustomControls/WaynesTextBox/WaynesTextBoxState.md @@ -13,9 +13,9 @@ A bundle of the style objects that describe a single visual state of a [**Waynes In addition to the usual background / borders / corners / text-rendering quartet, a **WaynesTextBoxState** adds selection-highlight colours, a caret colour and width, and three decorator fills used for the *ERROR* / *WARNING* / *INFO* literal-substring decorations the textbox draws automatically. -[**InitializeDefaultValues**](#initializedefaultvalues) and [**InitializeDefaultValues_Focused**](#initializedefaultvalues_focused) populate the state with reasonable defaults — the focused variant uses a different selection background and caret colour. +[**InitializeDefaultValues**](#initializedefaultvalues) and [**InitializeDefaultValues_Focused**](#initializedefaultvalues_focused) populate the state with reasonable defaults --- the focused variant uses a different selection background and caret colour. -The type itself is `Public Class` but is `[COMCreatable(False)]` — reach instances only through the textbox's **NormalState** / **HoverState** / **FocusedState** properties. +The type itself is `Public Class` but is `[COMCreatable(False)]` --- instances are accessed only through the textbox's **NormalState** / **HoverState** / **FocusedState** properties. ## Properties @@ -79,7 +79,7 @@ The [**TextRendering**](../Styles/TextRendering) that controls how [**Value**](. ### InitializeDefaultValues {: .no_toc } -Populates every field with the package defaults — used by [**NormalState**](.#normalstate) and [**HoverState**](.#hoverstate). +Populates every field with the package defaults --- used by [**NormalState**](.#normalstate) and [**HoverState**](.#hoverstate). Syntax: *object*.**InitializeDefaultValues** diff --git a/docs/Reference/CustomControls/WaynesTextBox/index.md b/docs/Reference/CustomControls/WaynesTextBox/index.md index 3e513b09..d88a45ca 100644 --- a/docs/Reference/CustomControls/WaynesTextBox/index.md +++ b/docs/Reference/CustomControls/WaynesTextBox/index.md @@ -12,7 +12,7 @@ A single-line editable text field. The user can type, select with the mouse or w The control paints three visual states ([**NormalState**](#normalstate), [**HoverState**](#hoverstate), [**FocusedState**](#focusedstate)) controlled by parallel [**WaynesTextBoxState**](WaynesTextBoxState) sub-objects, each of which has its own background fill, borders, corners, text rendering, selection colours, caret colour, and decorator colours. -The current text is held in [**Value**](#value). Surrogate-pair characters are handled correctly by the cursor / selection logic — the caret never appears between the high and low halves of a pair. +The current text is held in [**Value**](#value). Surrogate-pair characters are handled correctly by the cursor / selection logic --- the caret never appears between the high and low halves of a pair. ```tb Private Sub Form_Load() @@ -22,7 +22,7 @@ Private Sub Form_Load() End Sub ``` -The three states are styled independently — a common pattern is to give the focused state a heavier border in an accent colour and brighten its fill, so the active field stands out from its siblings: +The three states are styled independently --- a common pattern is to give the focused state a heavier border in an accent colour and brighten its fill, so the active field stands out from its siblings: ```tb Private Sub Form_Load() @@ -51,9 +51,9 @@ End Sub As the user types, the control automatically marks any occurrence of three literal strings inside [**Value**](#value): -- `ERROR` — a red squiggle underline (colour from [**WaynesTextBoxState.DecorationERROR**](WaynesTextBoxState#decorationerror)). -- `WARNING` — a dark-blue 2-pixel straight underline (from [**DecorationWARNING**](WaynesTextBoxState#decorationwarning)). -- `INFO` — a light-blue background highlight (from [**DecorationINFO**](WaynesTextBoxState#decorationinfo)). +- `ERROR` --- a red squiggle underline (colour from [**WaynesTextBoxState.DecorationERROR**](WaynesTextBoxState#decorationerror)). +- `WARNING` --- a dark-blue 2-pixel straight underline (from [**DecorationWARNING**](WaynesTextBoxState#decorationwarning)). +- `INFO` --- a light-blue background highlight (from [**DecorationINFO**](WaynesTextBoxState#decorationinfo)). The colours are configurable per visual state. The substrings themselves are hard-coded into the control's paint logic in the current release. @@ -72,7 +72,7 @@ How the control is docked inside its container. A member of [**DockMode**](../En ### FocusedState {: .no_toc } -The [**WaynesTextBoxState**](WaynesTextBoxState) used when the control has the keyboard focus. Pre-set with focus-specific defaults — orange caret, blue selection background. +The [**WaynesTextBoxState**](WaynesTextBoxState) used when the control has the keyboard focus. Pre-set with focus-specific defaults --- orange caret, blue selection background. ### Height {: .no_toc } @@ -97,7 +97,7 @@ The unique design-time name of the control on its parent form. **String**. Inher ### NormalState {: .no_toc } -The [**WaynesTextBoxState**](WaynesTextBoxState) used when the textbox is idle — not focused and not hovered. +The [**WaynesTextBoxState**](WaynesTextBoxState) used when the textbox is idle --- not focused and not hovered. ### TabIndex {: .no_toc } diff --git a/docs/Reference/CustomControls/WaynesTimer.md b/docs/Reference/CustomControls/WaynesTimer.md index ffaecd09..af023c08 100644 --- a/docs/Reference/CustomControls/WaynesTimer.md +++ b/docs/Reference/CustomControls/WaynesTimer.md @@ -8,9 +8,9 @@ has_toc: false # WaynesTimer class {: .no_toc } -A non-visual timer control. Wraps an internal [**CustomControlTimer**](Framework/CustomControlTimer) and exposes its [**Interval**](#interval) / [**Enabled**](#enabled) as designer-visible properties — drop a **WaynesTimer** onto a [**WaynesForm**](WaynesForm/) at design time, set the interval, and handle the [**Timer**](#timer) event to run code on a repeating schedule. +A non-visual timer control. Wraps an internal [**CustomControlTimer**](Framework/CustomControlTimer) and exposes its [**Interval**](#interval) / [**Enabled**](#enabled) as designer-visible properties --- drop a **WaynesTimer** onto a [**WaynesForm**](WaynesForm/) at design time, set the interval, and handle the [**Timer**](#timer) event to run code on a repeating schedule. -At design time the control paints a 🕑 clock-face glyph centred in its rectangle, on a pale grey background, scaled to fit the control. At run time the control is invisible — its visible **Width** and **Height** are clamped to 32×32 on initialize but the control itself draws nothing. +At design time the control paints a 🕑 clock-face glyph centred in its rectangle, on a pale grey background, scaled to fit the control. At run time the control is invisible --- its visible **Width** and **Height** are clamped to 32×32 on initialize but the control itself draws nothing. ```tb Private Sub Form_Load() diff --git a/docs/Reference/CustomControls/index.md b/docs/Reference/CustomControls/index.md index 9456ffc5..1008c031 100644 --- a/docs/Reference/CustomControls/index.md +++ b/docs/Reference/CustomControls/index.md @@ -9,11 +9,11 @@ has_toc: false # CustomControls Package -The **CustomControls** built-in package supplies a set of fully owner-drawn controls — buttons, a form, a frame, a grid, a label, a slider, a textbox, and a timer — together with the framework on which they are built. Every visible pixel is rendered by the package itself rather than by Windows, so the look and feel is identical across systems and is configured entirely through a small vocabulary of style objects ([**Fill**](Styles/Fill), [**Borders**](Styles/Borders), [**Corners**](Styles/Corners), [**TextRendering**](Styles/TextRendering), …) rather than by toggling theme flags. +The **CustomControls** built-in package supplies a set of fully owner-drawn controls --- buttons, a form, a frame, a grid, a label, a slider, a textbox, and a timer --- together with the framework on which they are built. Every visible pixel is rendered by the package itself rather than by Windows, so the look and feel is identical across systems and is configured entirely through a small vocabulary of style objects ([**Fill**](Styles/Fill), [**Borders**](Styles/Borders), [**Corners**](Styles/Corners), [**TextRendering**](Styles/TextRendering), …) rather than by toggling theme flags. -The package ships as two paired components: a **CustomControls DESIGNER** library — the framework half, source-side project `CustomControls` — that defines the rendering surface and the interface every custom control implements; and the **Custom Controls** package — source-side project `CustomControlsPackage` — that supplies the eight concrete `Waynes…` controls. The two are co-versioned with twinBASIC and always ship together; both are MIT-licensed. +The package ships as two paired components: a **CustomControls DESIGNER** library --- the framework half, source-side project `CustomControls` --- that defines the rendering surface and the interface every custom control implements; and the **Custom Controls** package --- source-side project `CustomControlsPackage` --- that supplies the eight concrete `Waynes…` controls. The two are co-versioned with twinBASIC and always ship together; both are MIT-licensed. -Beyond providing ready-to-use controls, the package doubles as a worked example for authoring your own custom controls. The `Waynes…` classes implement the same [**ICustomControl**](Framework/ICustomControl) interface that a hand-written control would, against the same [**CustomControlContext**](Framework/CustomControlContext) callback object and [**Canvas**](Framework/Canvas) drawing surface — see the [Framework](Framework/) page for the host-side contract. +Beyond providing ready-to-use controls, the package doubles as a worked example for authoring new custom controls. The `Waynes…` classes implement the same [**ICustomControl**](Framework/ICustomControl) interface that a hand-written control would, against the same [**CustomControlContext**](Framework/CustomControlContext) callback object and [**Canvas**](Framework/Canvas) drawing surface --- see the [Framework](Framework/) page for the host-side contract. ```tb Private Sub Form_Load() @@ -49,7 +49,7 @@ These members are listed on each control's own page; their definitions are ident ## Style objects -The visual style of every control is controlled by a few small helper classes, instantiated automatically through `Public WithEvents …` properties. They are nested arbitrarily — a [**TextRendering**](Styles/TextRendering) contains a [**Fill**](Styles/Fill) for the text colour, which contains a `Granularity` and an array of `FillColorPoint` gradient stops; an array of [**Border**](Styles/Borders#border-class) objects describes how the outline of a control is stroked; and so on. +The visual style of every control is controlled by a few small helper classes, instantiated automatically through `Public WithEvents …` properties. They are nested arbitrarily --- a [**TextRendering**](Styles/TextRendering) contains a [**Fill**](Styles/Fill) for the text colour, which contains a `Granularity` and an array of `FillColorPoint` gradient stops; an array of [**Border**](Styles/Borders#border-class) objects describes how the outline of a control is stroked; and so on. - [Anchors](Styles/Anchors) -- which sides of a control are attached to its container when the container is resized - [Borders](Styles/Borders) -- one or more border strokes drawn around a control (including the single-stroke `Border` sub-object) @@ -59,11 +59,11 @@ The visual style of every control is controlled by a few small helper classes, i - [Padding](Styles/Padding) -- per-side padding around text inside a [**TextRendering**](Styles/TextRendering) - [TextRendering](Styles/TextRendering) -- font, padding, fill, outlines, alignment, and overflow for the text drawn inside a control (including the `FontStyle` sub-object) -Every style object raises an **OnChanged** event whenever one of its fields is set, and the control that hosts it requests a repaint on each change — assigning style values at runtime triggers an immediate redraw. +Every style object raises an **OnChanged** event whenever one of its fields is set, and the control that hosts it requests a repaint on each change --- assigning style values at runtime triggers an immediate redraw. ## Framework -For authoring your own custom controls or forms, the **CustomControls DESIGNER** half of the package supplies: +For authoring new custom controls or forms, the **CustomControls DESIGNER** half of the package supplies: - [ICustomControl](Framework/ICustomControl) -- the interface every custom control implements: **Initialize**, **Destroy**, **Paint** - [ICustomForm](Framework/ICustomForm) -- the analogous interface for custom form classes @@ -72,7 +72,7 @@ For authoring your own custom controls or forms, the **CustomControls DESIGNER** - [CustomControlTimer](Framework/CustomControlTimer) -- the timer returned by **CustomControlContext.CreateTimer**; has **Interval**, **Enabled**, and an **OnTimer** event - [CustomControlsCollection](Framework/CustomControlsCollection) -- the **Controls** collection on a form - [Canvas](Framework/Canvas) -- the drawing surface passed to **Paint**; the only way to put pixels into a custom control -- [SerializeInfo](Framework/SerializeInfo) -- the per-instance serializer reached via **CustomControlContext.GetSerializer**; used to deserialize designer-set property values and to query the runtime mode +- [SerializeInfo](Framework/SerializeInfo) -- the per-instance serializer returned by **CustomControlContext.GetSerializer**; used to deserialize designer-set property values and to query the runtime mode ## Enumerations diff --git a/docs/Reference/Glossary.md b/docs/Reference/Glossary.md index d34c90b5..1725a8d7 100644 --- a/docs/Reference/Glossary.md +++ b/docs/Reference/Glossary.md @@ -44,7 +44,7 @@ The American Standard Code for Information Interchange (ASCII) 7-bit character s ## attribute -(twinBASIC) Metadata attached to a [module](#module), procedure, parameter, or other declaration, written in square brackets — for example, `[Documentation("...")]`. Some attributes control compiler behaviour (such as `[PackingAlignment]` on a [user-defined type](#user-defined-type) or `[VB_UserMemId]` on a member); others are informational. Attributes are a twinBASIC addition; classic VBA exposes only a small fixed set via the `Attribute` directive. +(twinBASIC) Metadata attached to a [module](#module), procedure, parameter, or other declaration, written in square brackets --- for example, `[Documentation("...")]`. Some attributes control compiler behaviour (such as `[PackingAlignment]` on a [user-defined type](#user-defined-type) or `[VB_UserMemId]` on a member); others are informational. Attributes are a twinBASIC addition; classic VBA exposes only a small fixed set via the `Attribute` directive. ## Automation object @@ -154,7 +154,7 @@ The period during which source code is translated to executable code. ## compiler directive -A command used to alter the action of the compiler — for example, the [conditional compilation](#conditional-compiler-constant) directives `#If`, `#Else`, `#ElseIf`, and `#End If`, or the `#Const` directive. See [Preprocessor directives](Core/Topic-Preprocessor). +A command used to alter the action of the compiler --- for example, the [conditional compilation](#conditional-compiler-constant) directives `#If`, `#Else`, `#ElseIf`, and `#End If`, or the `#Const` directive. See [Preprocessor directives](Core/Topic-Preprocessor). ## conditional compiler constant @@ -236,7 +236,7 @@ Nonexecutable code that names a constant, [variable](#variable), or [procedure]( A [data type](#data-type) that contains decimal numbers scaled by a power of 10. For zero-scaled numbers (integers with no fractional part), the range is +/-79,228,162,514,264,337,593,543,950,335. For numbers with 28 decimal places the range is +/-7.9228162514264337593543950335. The smallest non-zero value that can be represented as a **Decimal** is `0.0000000000000000000000000001`. > [!NOTE] -> Unlike classic VBA — where **Decimal** was usable only as a **Variant** subtype produced by **CDec** — twinBASIC supports **Decimal** as a first-class declared type. You can write `Dim x As Decimal`. +> Unlike classic VBA --- where **Decimal** was usable only as a **Variant** subtype produced by **CDec** --- twinBASIC supports **Decimal** as a first-class declared type. You can write `Dim x As Decimal`. ## designer @@ -678,7 +678,7 @@ Times are stored as part of a real number. Values to the right of the decimal re ## transparent -Describes the background of the object if the background is not visible. Instead of the background, whatever is behind the object is visible — for example, an image or picture used as a backdrop in your application. Use the `BackStyle` property to make the background transparent. +Describes the background of the object if the background is not visible. Instead of the background, whatever is behind the object is visible --- for example, an image or picture used as a backdrop in your application. Use the `BackStyle` property to make the background transparent. ## twip diff --git a/docs/Reference/Operators.md b/docs/Reference/Operators.md index 4345e1ed..3e02286a 100644 --- a/docs/Reference/Operators.md +++ b/docs/Reference/Operators.md @@ -51,7 +51,7 @@ The right operand is evaluated only when the left operand does not already deter ## Bitshift -*(twinBASIC)* Shifts are *logical* — vacated bits are filled with zero, and shifts past the operand's width yield `0` rather than wrapping. +*(twinBASIC)* Shifts are *logical* --- vacated bits are filled with zero, and shifts past the operand's width yield `0` rather than wrapping. - [\<<](../tB/Core/LeftShift) -- (twinBASIC) shifts a numeric value left by a given number of bits - [\>>](../tB/Core/RightShift) -- (twinBASIC) shifts a numeric value right by a given number of bits @@ -102,4 +102,4 @@ Within each category, the order from highest to lowest precedence is: Comparison operators all have equal precedence and evaluate left-to-right. Multiplication and division also evaluate left-to-right when they appear together, as do addition and subtraction. The `&` operator is not strictly arithmetic, but in precedence it follows all arithmetic operators and precedes all comparison operators. -The compound-assignment operators (`+=`, `-=`, `*=`, `/=`, `^=`, `&=`, `<<=`, `>>=`) appear only at statement level — they are not part of any expression, so they do not participate in precedence. +The compound-assignment operators (`+=`, `-=`, `*=`, `/=`, `^=`, `&=`, `<<=`, `>>=`) appear only at statement level --- they are not part of any expression, so they do not participate in precedence. diff --git a/docs/Reference/Packages.md b/docs/Reference/Packages.md index 9b2d264f..5e94629d 100644 --- a/docs/Reference/Packages.md +++ b/docs/Reference/Packages.md @@ -8,26 +8,26 @@ has_toc: false # Packages -A *package* groups related code — modules, classes, controls, and enumerations — under a single namespace, and is referenced from a project as a single dependency. See [Features → Packages](../../Features/Packages/) for how packages are built and distributed in general; the pages below document the *built-in* packages that ship with twinBASIC itself. +A *package* groups related code --- modules, classes, controls, and enumerations --- under a single namespace, and is referenced from a project as a single dependency. See [Features → Packages](../../Features/Packages/) for how packages are built and distributed in general; the pages below document the *built-in* packages that ship with twinBASIC itself. ## Default Packages These packages are included in every project by default. - [VB Package](VB/) -- standard controls (**CheckBox**, **CommandButton**, **TextBox**, …), forms, and the application-level singletons (**App**, **Screen**, **Clipboard**, **Printer**, …) -- [VBA Package](VBA) -- the standard runtime library — **MsgBox**, **CStr**, **Mid**, **Format**, … grouped into modules, plus the **Collection** and **Err** intrinsics and twinBASIC's runtime expression engine -- [VBRUN Package](VBRUN/) -- runtime-only types — ambient properties, asynchronous-read state, structured error context, the **PropertyBag**, the clipboard / drag-and-drop container, and the enumerations used by classic VB6 forms and controls +- [VBA Package](VBA) -- the standard runtime library -- **MsgBox**, **CStr**, **Mid**, **Format**, … grouped into modules, plus the **Collection** and **Err** intrinsics and twinBASIC's runtime expression engine +- [VBRUN Package](VBRUN/) -- runtime-only types -- ambient properties, asynchronous-read state, structured error context, the **PropertyBag**, the clipboard / drag-and-drop container, and the enumerations used by classic VB6 forms and controls ## Built-In Packages These packages are built into twinBASIC and are always available, even offline. To use them, add them to Project → References (Ctrl-T) → Available Packages. -- [Assert Package](Assert/) -- assertion functions for unit tests — three modules (**Exact**, **Strict**, **Permissive**) sharing the same fifteen-member API with different comparison strictness +- [Assert Package](Assert/) -- assertion functions for unit tests -- three modules (**Exact**, **Strict**, **Permissive**) sharing the same fifteen-member API with different comparison strictness - [CustomControls Package](CustomControls/) -- owner-drawn `Waynes…` custom controls (button, form, frame, grid, label, slider, textbox, timer), the shared `Styles/` helpers that paint them, and the DESIGNER framework (interfaces, callback objects, **Canvas**, **SerializeInfo**) for authoring new custom controls - [CEF Package](CEF/) -- the **CefBrowser** control wrapping the Chromium Embedded Framework: cross-platform-ready browser embedding with a choice of three Chromium runtimes (v49 / v109 / v145); currently in BETA - [WebView2 Package](WebView2/) -- the **WebView2** control wrapping the Microsoft Edge runtime, plus its surrounding wrapper objects (request / response / headers / environment options) and the `wv2…` enumerations - [WinEventLogLib Package](WinEventLogLib/) -- writes Windows Event Log entries from twinBASIC; the generic **EventLog**(*Of EventIds, Categories*) class handles registration, registry setup, and the per-event `ReportEventW` call, with message-table resources for *EventIds* and *Categories* synthesised into the EXE at compile time - [WinNamedPipesLib Package](WinNamedPipesLib/) -- Windows named pipes as twinBASIC objects with an asynchronous IOCP-driven I/O model; **NamedPipeServer** + **NamedPipeServerConnection** on the host side, **NamedPipeClientManager** + **NamedPipeClientConnection** on the client side, with message-boundary semantics and a cookie-based correlation pattern across `AsyncRead` / `AsyncWrite` and their matching events - [WinServicesLib Package](WinServicesLib/) -- runs a twinBASIC EXE as one or more Windows services; the **Services** singleton coordinates configuration, install / uninstall, and the SCM dispatcher loop, while user-implemented [**ITbService**](WinServicesLib/ITbService) classes are instantiated through [**ServiceCreator**](WinServicesLib/ServiceCreator)`(Of T)` -- [tbIDE Package](tbIDE/) -- the **addin SDK** for the twinBASIC IDE: every addin is a Standard DLL that exports `tbCreateCompilerAddin`, returns an object implementing the [**AddIn**](tbIDE/AddIn) contract, and from there reaches the IDE's toolbar, tool-window DOM, virtual file system, debug console, current project (and its `Evaluate` debug-console hook), keyboard shortcuts, and themes — all through the [**Host**](tbIDE/Host) object the IDE passes in +- [tbIDE Package](tbIDE/) -- the **addin SDK** for the twinBASIC IDE: every addin is a Standard DLL that exports `tbCreateCompilerAddin`, returns an object implementing the [**AddIn**](tbIDE/AddIn) contract, and from there reaches the IDE's toolbar, tool-window DOM, virtual file system, debug console, current project (and its `Evaluate` debug-console hook), keyboard shortcuts, and themes -- all through the [**Host**](tbIDE/Host) object the IDE passes in - [WinNativeCommonCtls Package](WinNativeCommonCtls/) -- VB6-compatible replacement for **Microsoft Common Controls 6.0** (`MSCOMCTL.OCX`) built on top of the Win32 ComCtl32 controls: eight controls ([**DTPicker**](WinNativeCommonCtls/DTPicker), [**ImageList**](WinNativeCommonCtls/ImageList/), [**ListView**](WinNativeCommonCtls/ListView/), [**MonthView**](WinNativeCommonCtls/MonthView), [**ProgressBar**](WinNativeCommonCtls/ProgressBar), [**Slider**](WinNativeCommonCtls/Slider), [**TreeView**](WinNativeCommonCtls/TreeView/), [**UpDown**](WinNativeCommonCtls/UpDown)) with the original member names preserved, plus the collection sub-objects ([**ListItems**](WinNativeCommonCtls/ListView/ListItems), [**ColumnHeaders**](WinNativeCommonCtls/ListView/ColumnHeaders), [**Nodes**](WinNativeCommonCtls/TreeView/Nodes), [**ListImages**](WinNativeCommonCtls/ImageList/ListImages)) and the user-facing enumerations diff --git a/docs/Reference/Statements.md b/docs/Reference/Statements.md index 5d96e1fc..c24b76b1 100644 --- a/docs/Reference/Statements.md +++ b/docs/Reference/Statements.md @@ -28,7 +28,7 @@ These statements are built into the language itself. They are understood by the * [Declare](../tB/Core/Declare) -- declares references to external procedures in a dynamic-link library (DLL) -* [Delegate](../tB/Core/Delegate) -- (twinBASIC) declares a function-pointer type — a named signature for indirect calls +* [Delegate](../tB/Core/Delegate) -- (twinBASIC) declares a function-pointer type --- a named signature for indirect calls * [Dim](../tB/Core/Dim) -- declares variables and allocates storage space diff --git a/docs/Reference/VB/App/index.md b/docs/Reference/VB/App/index.md index cce1f1af..21648d10 100644 --- a/docs/Reference/VB/App/index.md +++ b/docs/Reference/VB/App/index.md @@ -8,7 +8,7 @@ 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: +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 @@ -22,7 +22,7 @@ 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 few 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. +Most properties are read-only and are populated from the project settings (compiled into the executable's Win32 `VERSIONINFO` resource) at build time. The few 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} @@ -39,19 +39,19 @@ Most properties are read-only and are populated from the project settings (compi - [**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. +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 — useful for build scripts that need to chain steps after an IDE build. +[**LastBuildPath**](#lastbuildpath) is a twinBASIC-specific extension that records the path the most recent IDE build wrote its EXE to --- useful 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. +- [**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. +[**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 @@ -73,7 +73,7 @@ The **CompanyName** field of the application's `VERSIONINFO` resource. **String* ### 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. +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 } @@ -103,7 +103,7 @@ The Win32 module handle (`HINSTANCE`) for the executable. **LongPtr**, read-only ### 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. +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 } diff --git a/docs/Reference/VB/CheckBox/index.md b/docs/Reference/VB/CheckBox/index.md index e9a607ce..e4f559e4 100644 --- a/docs/Reference/VB/CheckBox/index.md +++ b/docs/Reference/VB/CheckBox/index.md @@ -37,7 +37,7 @@ End Sub | **vbChecked** | 1 | The check box is selected. | | **vbGrayed** | 2 | The check box is in an indeterminate (grey) state. | -Clicking an unchecked or grey check box selects it; clicking a checked or grey check box clears it. The grey state is reachable only from code — assign **vbGrayed** to **Value** to display it. Assigning a negative number raises run-time error 380 (*Invalid property value*). +Clicking an unchecked or grey check box selects it; clicking a checked or grey check box clears it. The grey state is reachable only from code --- assign **vbGrayed** to **Value** to display it. Assigning a negative number raises run-time error 380 (*Invalid property value*). ```tb Check1.Value = vbGrayed ' show the indeterminate state @@ -69,7 +69,7 @@ Specifies the side of the box on which the [**Caption**](#caption) text appears. Syntax: *object*.**Alignment** [ = *value* ] *value* -: A member of [**AlignmentConstantsNoCenter**](../../VBRUN/Constants/AlignmentConstantsNoCenter): **tbLeftJustify** (0, default — caption to the right of the box) or **tbRightJustify** (1 — caption to the left of the box). +: A member of [**AlignmentConstantsNoCenter**](../../VBRUN/Constants/AlignmentConstantsNoCenter): **tbLeftJustify** (0, default --- caption to the right of the box) or **tbRightJustify** (1 --- caption to the left of the box). ### Appearance {: .no_toc } @@ -84,7 +84,7 @@ The background colour, as an **OLE_COLOR**. Defaults to the system 3-D face colo ### Caption {: .no_toc } -The text displayed next to the check box. An ampersand marks the next character as a mnemonic; `&&` produces a literal ampersand. The string is read directly from the underlying window — assigning to **Caption** is reflected immediately. +The text displayed next to the check box. An ampersand marks the next character as a mnemonic; `&&` produces a literal ampersand. The string is read directly from the underlying window --- assigning to **Caption** is reflected immediately. Syntax: *object*.**Caption** [ = *string* ] @@ -126,7 +126,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -197,7 +197,7 @@ How the control responds to OLE drops. A restricted member of [**OLEDropConstant ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Padding {: .no_toc } @@ -371,7 +371,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Click {: .no_toc } -Raised after [**Value**](#value) changes — whether the user clicked the box, pressed the access key, or assigned a different value in code. **Default event.** +Raised after [**Value**](#value) changes --- whether the user clicked the box, pressed the access key, or assigned a different value in code. **Default event.** Syntax: *object*\_**Click**( ) diff --git a/docs/Reference/VB/CheckMark/index.md b/docs/Reference/VB/CheckMark/index.md index f10b748e..8dc302e4 100644 --- a/docs/Reference/VB/CheckMark/index.md +++ b/docs/Reference/VB/CheckMark/index.md @@ -8,7 +8,7 @@ has_toc: false # CheckMark class {: .no_toc } -A **CheckMark** is a windowless control that draws a single check glyph — checked, unchecked, or grey — that scales to fill its rectangle. Unlike [**CheckBox**](../CheckBox), it has no caption, no font, and cannot take focus or receive keyboard input; it is essentially the box from a check-box rendered at whatever size the layout requires. This makes it especially useful inside reports and other dense layouts where the fixed-size system check would look out of place, but it is also available on a **Form** or **UserControl**. +A **CheckMark** is a windowless control that draws a single check glyph --- checked, unchecked, or grey --- that scales to fill its rectangle. Unlike [**CheckBox**](../CheckBox), it has no caption, no font, and cannot take focus or receive keyboard input; it is essentially the box from a check-box rendered at whatever size the layout requires. This makes it especially useful inside reports and other dense layouts where the fixed-size system check would look out of place, but it is also available on a **Form** or **UserControl**. The default property is [**Value**](#value) and the default event is [**Click**](#click). @@ -35,7 +35,7 @@ End Sub | **vbChecked** | 1 | The check is selected. | | **vbGrayed** | 2 | The check is in an indeterminate (grey) state. | -A user click toggles **Value** between **vbChecked** and **vbUnchecked** only. The grey state is reachable from code — assign **vbGrayed** to **Value** to display it. +A user click toggles **Value** between **vbChecked** and **vbUnchecked** only. The grey state is reachable from code --- assign **vbGrayed** to **Value** to display it. ```tb Check1.Value = vbGrayed ' show the indeterminate state @@ -45,22 +45,22 @@ Check1.Value = vbGrayed ' show the indeterminate state [**VisualStyles**](#visualstyles) selects how the glyph is rendered: -- **VisualStyles = False** (default) — drawn with the GDI **DrawFrameControl** primitive. Honours [**Appearance**](#appearance): **vbAppear3d** uses the classic raised/sunken look, **vbAppearFlat** uses a single-pixel outline. A disabled check, or one in the **vbGrayed** state, is drawn over the dotted three-state pattern. -- **VisualStyles = True** — drawn through the OS theme engine (UXTHEME), so the glyph uses the current visual-style theme. **Appearance** is ignored in this mode. +- **VisualStyles = False** (default) --- drawn with the GDI **DrawFrameControl** primitive. Honours [**Appearance**](#appearance): **vbAppear3d** uses the classic raised/sunken look, **vbAppearFlat** uses a single-pixel outline. A disabled check, or one in the **vbGrayed** state, is drawn over the dotted three-state pattern. +- **VisualStyles = True** --- drawn through the OS theme engine (UXTHEME), so the glyph uses the current visual-style theme. **Appearance** is ignored in this mode. ## Background [**BackStyle**](#backstyle) controls whether the rectangle behind the glyph is filled before the glyph is drawn: -- **vbBFTransparent** (default) — only the glyph is painted; whatever the container draws shows through. -- **vbBFOpaque** — the rectangle is filled with [**BackColor**](#backcolor) first. +- **vbBFTransparent** (default) --- only the glyph is painted; whatever the container draws shows through. +- **vbBFOpaque** --- the rectangle is filled with [**BackColor**](#backcolor) first. ## Properties ### Anchors {: .no_toc } -The **Anchors** object that determines which sides of the control follow the corresponding sides of its container as the container is resized. Read-only — set the individual sides through the returned object. +The **Anchors** object that determines which sides of the control follow the corresponding sides of its container as the container is resized. Read-only --- set the individual sides through the returned object. ### Appearance {: .no_toc } @@ -100,7 +100,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -256,7 +256,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Click {: .no_toc } -Raised when the user clicks the control with the left mouse button — after [**Value**](#value) has toggled between **vbChecked** and **vbUnchecked**. **Default event.** +Raised when the user clicks the control with the left mouse button --- after [**Value**](#value) has toggled between **vbChecked** and **vbUnchecked**. **Default event.** Syntax: *object*\_**Click**( ) diff --git a/docs/Reference/VB/Clipboard/index.md b/docs/Reference/VB/Clipboard/index.md index ba670ed9..863326af 100644 --- a/docs/Reference/VB/Clipboard/index.md +++ b/docs/Reference/VB/Clipboard/index.md @@ -8,7 +8,7 @@ has_toc: false # Clipboard class {: .no_toc } -The **Clipboard** class wraps the system clipboard — the Win32 inter-application copy-and-paste API — 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. +The **Clipboard** class wraps the system clipboard --- the Win32 inter-application copy-and-paste API --- 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: @@ -28,7 +28,7 @@ End If ## 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: +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 | |-----------------------|-------|------------------------------------------------| @@ -47,7 +47,7 @@ The [**GetText**](#gettext) / [**SetText**](#settext) methods take an optional * ## Picture data -The picture methods — [**GetData**](#getdata) and [**SetData**](#setdata) — are declared but not yet connected. +The picture methods --- [**GetData**](#getdata) and [**SetData**](#setdata) --- are declared but not yet connected. > [!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. @@ -84,7 +84,7 @@ Tests whether the clipboard currently contains data in the given format. Returns Syntax: *object*.**GetFormat**( *Format* ) *Format* -: *required* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) — the format to probe for. +: *required* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) --- the format to probe for. ```tb If Clipboard.GetFormat(vbCFFiles) Then @@ -120,7 +120,7 @@ Syntax: *object*.**SetData** *Picture* [, *Format* ] : *required* A **stdole.StdPicture** holding 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. +: *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. @@ -128,7 +128,7 @@ Syntax: *object*.**SetData** *Picture* [, *Format* ] ### 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. +Places text data onto the clipboard. Note that **SetText** does *not* implicitly clear the clipboard first --- call [**Clear**](#clear) explicitly to ensure that no stale data of other formats survives alongside the new value. Syntax: *object*.**SetText** *Str* [, *Format* ] @@ -136,7 +136,7 @@ Syntax: *object*.**SetText** *Str* [, *Format* ] : *required* The **String** to publish. *Format* -: *optional* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) — **vbCFText** (default), **vbCFUnicodeText**, **vbCFRTF**, or **vbCFLink**. +: *optional* A member of [**ClipboardConstants**](../../VBRUN/Constants/ClipboardConstants) --- **vbCFText** (default), **vbCFUnicodeText**, **vbCFRTF**, or **vbCFLink**. ```tb Clipboard.Clear diff --git a/docs/Reference/VB/ComboBox/index.md b/docs/Reference/VB/ComboBox/index.md index 38532a6b..b5a96a8d 100644 --- a/docs/Reference/VB/ComboBox/index.md +++ b/docs/Reference/VB/ComboBox/index.md @@ -36,13 +36,13 @@ End Sub |---------------------------|-------|--------------------------------------------------------------------------| | **vbComboDropdown** | 0 | Editable text + drop-down button + drop-down list. The default. | | **vbComboSimple** | 1 | Editable text + a permanently visible list (no drop-down button). | -| **vbComboDropdownList** | 2 | Drop-down list only — the user must pick a value; typing is disabled. | +| **vbComboDropdownList** | 2 | Drop-down list only --- the user must pick a value; typing is disabled. | Changing **Style** at run time recreates the underlying window (the existing list contents and selection are preserved). [**Sorted**](#sorted) and [**IntegralHeight**](#integralheight) recreate the window the same way. ## Editing the list -Items are held inside the OS combo-box control; the [**List**](#list) and [**ItemData**](#itemdata) arrays are projections onto that storage. Items are added with [**AddItem**](#additem), removed with [**RemoveItem**](#removeitem), and the whole list is cleared with [**Clear**](#clear). After each [**AddItem**](#additem) call, [**NewIndex**](#newindex) reports the position the item was inserted at — useful when [**Sorted**](#sorted) is **True** and the position is not predictable from the call. +Items are held inside the OS combo-box control; the [**List**](#list) and [**ItemData**](#itemdata) arrays are projections onto that storage. Items are added with [**AddItem**](#additem), removed with [**RemoveItem**](#removeitem), and the whole list is cleared with [**Clear**](#clear). After each [**AddItem**](#additem) call, [**NewIndex**](#newindex) reports the position the item was inserted at --- useful when [**Sorted**](#sorted) is **True** and the position is not predictable from the call. ```tb Combo1.Sorted = True @@ -55,13 +55,13 @@ Combo1.ItemData(Combo1.NewIndex) = 42 [**ListIndex**](#listindex) is the index of the selected item, or `-1` when nothing is selected. Setting it from code highlights the corresponding item and raises [**Click**](#click) (only if the value actually changes). [**TopIndex**](#topindex) controls which item appears at the top of the drop-down portion when it is open. -[**Text**](#text) reads or writes the editable area, except in **vbComboDropdownList** mode where there is no edit field — there, assigning a string searches the list with an exact, case-insensitive match and selects that item if found, doing nothing otherwise. Reading **Text** in any mode returns the current display text. +[**Text**](#text) reads or writes the editable area, except in **vbComboDropdownList** mode where there is no edit field --- there, assigning a string searches the list with an exact, case-insensitive match and selects that item if found, doing nothing otherwise. Reading **Text** in any mode returns the current display text. For the styles that have an edit area (**vbComboDropdown** and **vbComboSimple**), [**SelStart**](#selstart), [**SelLength**](#sellength), and [**SelText**](#seltext) reflect or modify the user's text selection. Reading or writing any of these in **vbComboDropdownList** mode raises run-time error 380. ## OLE drag-and-drop -[**OLEDragMode**](#oledragmode) controls source-side drags (only meaningful for the styles with an edit area — when set to **vbOLEDragAutomatic**, dragging selected text in the edit area starts an OLE drag with that text as the data). [**OLEDropMode**](#oledropmode) controls drop-target behaviour and is restricted to **vbOLEDropNone** or **vbOLEDropManual**. +[**OLEDragMode**](#oledragmode) controls source-side drags (only meaningful for the styles with an edit area --- when set to **vbOLEDragAutomatic**, dragging selected text in the edit area starts an OLE drag with that text as the data). [**OLEDropMode**](#oledropmode) controls drop-target behaviour and is restricted to **vbOLEDropNone** or **vbOLEDropManual**. ## Properties @@ -98,7 +98,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -118,7 +118,7 @@ The text colour, as an **OLE_COLOR**. Defaults to the system window-text colour. ### Height {: .no_toc } -The control's height, in twips by default (or in the container's **ScaleMode** units). For **vbComboDropdown** and **vbComboDropdownList** this is the height of the closed control (the drop-down portion is sized separately — see [**MaxDropDownItems**](#maxdropdownitems)). For **vbComboSimple** it is the total height including the always-visible list. **Single**. +The control's height, in twips by default (or in the container's **ScaleMode** units). For **vbComboDropdown** and **vbComboDropdownList** this is the height of the closed control (the drop-down portion is sized separately --- see [**MaxDropDownItems**](#maxdropdownitems)). For **vbComboSimple** it is the total height including the always-visible list. **Single**. ### HelpContextID {: .no_toc } @@ -163,7 +163,7 @@ The horizontal distance from the left edge of the container to the left edge of ### List {: .no_toc } -The text of an item, indexed by zero-based position. Setting **List(*Index*)** removes the existing item at that position and reinserts the new value at the same index — note that this can change the resulting position when [**Sorted**](#sorted) is **True**. +The text of an item, indexed by zero-based position. Setting **List(*Index*)** removes the existing item at that position and reinserts the new value at the same index --- note that this can change the resulting position when [**Sorted**](#sorted) is **True**. Syntax: *object*.**List**( *Index* ) [ = *string* ] @@ -185,7 +185,7 @@ When **True**, the user can scroll and select within the control but cannot type ### MaxDropDownItems {: .no_toc } -The maximum number of items shown in the drop-down portion when the user opens it. **Long**, default `0` — when zero, the OS chooses a height (typically eight items). +The maximum number of items shown in the drop-down portion when the user opens it. **Long**, default `0` --- when zero, the OS chooses a height (typically eight items). ### MouseIcon {: .no_toc } @@ -210,7 +210,7 @@ The zero-based index at which the most recent [**AddItem**](#additem) call inser ### OLEDragMode {: .no_toc } -Whether the control's edit area can act as an automatic OLE drag source. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default — call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1 — dragging selected text in the edit area starts an OLE drag with that text as the data, and the drop effect **vbDropEffectMove** clears the selection). +Whether the control's edit area can act as an automatic OLE drag source. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default --- call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1 --- dragging selected text in the edit area starts an OLE drag with that text as the data, and the drop effect **vbDropEffectMove** clears the selection). ### OLEDropMode {: .no_toc } @@ -220,7 +220,7 @@ How the control responds to OLE drops. A restricted member of [**OLEDropConstant ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -425,21 +425,21 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Change {: .no_toc } -Raised when the text in the edit area changes — whether the user typed into it or code assigned a different value to [**Text**](#text). Not raised in **vbComboDropdownList** mode (where there is no edit area). **Default event.** +Raised when the text in the edit area changes --- whether the user typed into it or code assigned a different value to [**Text**](#text). Not raised in **vbComboDropdownList** mode (where there is no edit area). **Default event.** Syntax: *object*\_**Change**( ) ### Click {: .no_toc } -Raised after [**ListIndex**](#listindex) changes — whether the user picked an item from the list or code assigned a different value to [**ListIndex**](#listindex). Assigning the current value again does not raise **Click**. +Raised after [**ListIndex**](#listindex) changes --- whether the user picked an item from the list or code assigned a different value to [**ListIndex**](#listindex). Assigning the current value again does not raise **Click**. Syntax: *object*\_**Click**( ) ### CloseUp {: .no_toc } -Raised when the drop-down portion closes — either because the user picked an item, clicked elsewhere, or pressed **Esc**. Not raised in **vbComboSimple** mode (the list is always visible). +Raised when the drop-down portion closes --- either because the user picked an item, clicked elsewhere, or pressed **Esc**. Not raised in **vbComboSimple** mode (the list is always visible). Syntax: *object*\_**CloseUp**( ) @@ -551,7 +551,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Scroll {: .no_toc } -Raised when the drop-down (or always-visible) list is scrolled — by the scroll bar, the keyboard, or the mouse wheel. Wheel-driven scrolling can be silenced by setting [**WheelScrollEvent**](#wheelscrollevent) to **False**. +Raised when the drop-down (or always-visible) list is scrolled --- by the scroll bar, the keyboard, or the mouse wheel. Wheel-driven scrolling can be silenced by setting [**WheelScrollEvent**](#wheelscrollevent) to **False**. Syntax: *object*\_**Scroll**( ) diff --git a/docs/Reference/VB/CommandButton/index.md b/docs/Reference/VB/CommandButton/index.md index caf1fb0e..a6846905 100644 --- a/docs/Reference/VB/CommandButton/index.md +++ b/docs/Reference/VB/CommandButton/index.md @@ -8,7 +8,7 @@ has_toc: false # CommandButton class {: .no_toc } -A **CommandButton** is a Win32 native push-button control used to trigger an action — a click-handler runs every time the user presses it. The control is normally placed on a **Form** or **UserControl** at design time. The default property is [**Value**](#value) and the default event is [**Click**](#click). +A **CommandButton** is a Win32 native push-button control used to trigger an action --- a click-handler runs every time the user presses it. The control is normally placed on a **Form** or **UserControl** at design time. The default property is [**Value**](#value) and the default event is [**Click**](#click). ```tb Private Sub Form_Load() @@ -28,7 +28,7 @@ End Sub ## Triggering a click -A **CommandButton** raises [**Click**](#click) every time the user presses it — by left-clicking, by pressing **Space** or **Enter** while it has focus, by typing the **Alt+** access key marked in the [**Caption**](#caption), by pressing **Esc** when [**Cancel**](#cancel) is **True**, or by pressing **Enter** anywhere on the form when [**Default**](#default) is **True**. Code can fire the same event by assigning **True** to [**Value**](#value): +A **CommandButton** raises [**Click**](#click) every time the user presses it --- by left-clicking, by pressing **Space** or **Enter** while it has focus, by typing the **Alt+** access key marked in the [**Caption**](#caption), by pressing **Esc** when [**Cancel**](#cancel) is **True**, or by pressing **Enter** anywhere on the form when [**Default**](#default) is **True**. Code can fire the same event by assigning **True** to [**Value**](#value): ```tb cmdOK.Value = True ' raises cmdOK_Click @@ -38,7 +38,7 @@ cmdOK.Value = True ' raises cmdOK_Click ## Cancel and Default -[**Cancel**](#cancel) and [**Default**](#default) are mutually-form-exclusive — at most one button on a form can have either set to **True**. Assigning **True** to **Cancel** or **Default** on one button automatically clears the same property on whatever button held it before. Setting **Default = True** also gives the button the bold "default push-button" border. +[**Cancel**](#cancel) and [**Default**](#default) are mutually-form-exclusive --- at most one button on a form can have either set to **True**. Assigning **True** to **Cancel** or **Default** on one button automatically clears the same property on whatever button held it before. Setting **Default = True** also gives the button the bold "default push-button" border. ## Caption and mnemonics @@ -62,17 +62,17 @@ Determines how the control's border is drawn by the OS. A member of [**Appearanc ### BackColor {: .no_toc } -The background colour, as an **OLE_COLOR**. Defaults to the system 3-D face colour. Honoured only when [**Style**](#style) is **vbButtonGraphical** — the standard Win32 button always paints with the theme colour. +The background colour, as an **OLE_COLOR**. Defaults to the system 3-D face colour. Honoured only when [**Style**](#style) is **vbButtonGraphical** --- the standard Win32 button always paints with the theme colour. ### Cancel {: .no_toc } -When **True**, this button is fired by the **Esc** key from anywhere on its form. **Boolean**, default **False**. Only one **CommandButton** on a form can hold this property — assigning **True** to a second button automatically clears it on the previous one. +When **True**, this button is fired by the **Esc** key from anywhere on its form. **Boolean**, default **False**. Only one **CommandButton** on a form can hold this property --- assigning **True** to a second button automatically clears it on the previous one. ### Caption {: .no_toc } -The text displayed on the button. An ampersand marks the next character as a mnemonic; `&&` produces a literal ampersand. The string is read directly from the underlying window — assigning to **Caption** is reflected immediately. +The text displayed on the button. An ampersand marks the next character as a mnemonic; `&&` produces a literal ampersand. The string is read directly from the underlying window --- assigning to **Caption** is reflected immediately. Syntax: *object*.**Caption** [ = *string* ] @@ -89,7 +89,7 @@ A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstant ### Default {: .no_toc } -When **True**, this button is fired by the **Enter** key from anywhere on its form (unless another control is currently consuming **Enter**). The button also displays the bold "default push-button" border. **Boolean**, default **False**. Only one **CommandButton** on a form can hold this property — assigning **True** to a second button automatically clears it on the previous one. +When **True**, this button is fired by the **Enter** key from anywhere on its form (unless another control is currently consuming **Enter**). The button also displays the bold "default push-button" border. **Boolean**, default **False**. Only one **CommandButton** on a form can hold this property --- assigning **True** to a second button automatically clears it on the previous one. ### DisabledPicture {: .no_toc } @@ -109,7 +109,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -180,7 +180,7 @@ How the control responds to OLE drops. A restricted member of [**OLEDropConstant ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Padding {: .no_toc } @@ -355,7 +355,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Click {: .no_toc } -Raised every time the button is pressed — by mouse click, by **Space** or **Enter** while focused, by the **Alt+** access key in the [**Caption**](#caption), by **Esc** when [**Cancel**](#cancel) is **True**, by **Enter** when [**Default**](#default) is **True**, or by an assignment of **True** to [**Value**](#value). **Default event.** +Raised every time the button is pressed --- by mouse click, by **Space** or **Enter** while focused, by the **Alt+** access key in the [**Caption**](#caption), by **Esc** when [**Cancel**](#cancel) is **True**, by **Enter** when [**Default**](#default) is **True**, or by an assignment of **True** to [**Value**](#value). **Default event.** Syntax: *object*\_**Click**( ) diff --git a/docs/Reference/VB/Data/index.md b/docs/Reference/VB/Data/index.md index ad7f7483..5da9f150 100644 --- a/docs/Reference/VB/Data/index.md +++ b/docs/Reference/VB/Data/index.md @@ -8,7 +8,7 @@ has_toc: false # Data class {: .no_toc } -A **Data** control is a Win32 native control that opens a DAO database and exposes a single recordset to other controls on the form through data binding. It draws a strip of four arrow-shaped buttons — **Move-First**, **Move-Previous**, **Move-Next**, **Move-Last** — with a centred [**Caption**](#caption) between them, and lets the user step through the recordset with the mouse. The control is normally placed on a **Form** or **UserControl** at design time. Setting [**DatabaseName**](#databasename) and [**RecordSource**](#recordsource) is enough to populate it; the recordset opens automatically the first time the control is created. The default event is [**Validate**](#validate); the control has no usable default property. +A **Data** control is a Win32 native control that opens a DAO database and exposes a single recordset to other controls on the form through data binding. It draws a strip of four arrow-shaped buttons --- **Move-First**, **Move-Previous**, **Move-Next**, **Move-Last** --- with a centred [**Caption**](#caption) between them, and lets the user step through the recordset with the mouse. The control is normally placed on a **Form** or **UserControl** at design time. Setting [**DatabaseName**](#databasename) and [**RecordSource**](#recordsource) is enough to populate it; the recordset opens automatically the first time the control is created. The default event is [**Validate**](#validate); the control has no usable default property. ```tb Private Sub Form_Load() @@ -41,7 +41,7 @@ End Sub [**DatabaseName**](#databasename) gives the path to the database file (for Jet/ACE) or the DSN (for ODBC); [**Connect**](#connect) is the connection string. The Jet-flavoured default `"Access 2000;"` is rewritten to `"MS Access;"` before the database is opened, matching the VB6 behaviour. [**Exclusive**](#exclusive) and [**ReadOnly**](#readonly) are passed through to **OpenDatabase**, and [**Options**](#options) is the DAO option bit-mask. [**DefaultCursorType**](#defaultcursortype) is consulted only when **DefaultType** is **vbUseODBC**. -[**RecordSource**](#recordsource) is the table name (or SQL statement) opened against the database, and [**RecordsetType**](#recordsettype) chooses between table, dynaset, and snapshot ([**RecordsetTypeConstants**](../../VBRUN/Constants/RecordsetTypeConstants)). Calling [**Refresh**](#refresh) reopens the recordset using the current values of these properties — typically after one of them is changed at run time. +[**RecordSource**](#recordsource) is the table name (or SQL statement) opened against the database, and [**RecordsetType**](#recordsettype) chooses between table, dynaset, and snapshot ([**RecordsetTypeConstants**](../../VBRUN/Constants/RecordsetTypeConstants)). Calling [**Refresh**](#refresh) reopens the recordset using the current values of these properties --- typically after one of them is changed at run time. The opened objects are exposed read-only as [**Database**](#database) and read/write as [**Recordset**](#recordset). Assigning a new value to **Recordset** disconnects from the current database, adopts the new recordset, and re-binds every dependent control. @@ -50,7 +50,7 @@ The opened objects are exposed read-only as [**Database**](#database) and read/w Other controls become *data-bound* by setting their **DataSource** to this **Data** control and their **DataField** to the name of a field in [**Recordset**](#recordset). A bound control reads its value from that field whenever the current record changes, and writes user edits back into the field as part of the next save. The **Data** control mediates both directions, raising [**Reposition**](#reposition) after the bound controls have re-synced and [**Validate**](#validate) before any operation that would discard pending edits. ```tb -' At design time you would normally set these in the property sheet, +' At design time these are normally set in the property sheet, ' but they can also be assigned in code: Set txtTitle.DataSource = Data1 txtTitle.DataField = "Title" @@ -60,11 +60,11 @@ chkInPrint.DataField = "InPrint" ## Navigation and end-of-file behaviour -The four buttons step through the recordset with **MoveFirst**, **MovePrevious**, **MoveNext**, and **MoveLast**. [**BOFAction**](#bofaction) controls what happens when the user moves past the first record ([**DataBOFconstants**](../../VBRUN/Constants/DataBOFconstants)): **vbMoveFirst** (default) snaps back to the first record; **vbBOF** lets the recordset sit on the BOF marker. [**EOFAction**](#eofaction) controls what happens past the last record ([**DataEOFConstants**](../../VBRUN/Constants/DataEOFConstants)): **vbMoveLast** (default), **vbEOF**, or **vbAddNew** — which clears every bound control and starts a new record. +The four buttons step through the recordset with **MoveFirst**, **MovePrevious**, **MoveNext**, and **MoveLast**. [**BOFAction**](#bofaction) controls what happens when the user moves past the first record ([**DataBOFconstants**](../../VBRUN/Constants/DataBOFconstants)): **vbMoveFirst** (default) snaps back to the first record; **vbBOF** lets the recordset sit on the BOF marker. [**EOFAction**](#eofaction) controls what happens past the last record ([**DataEOFConstants**](../../VBRUN/Constants/DataEOFConstants)): **vbMoveLast** (default), **vbEOF**, or **vbAddNew** --- which clears every bound control and starts a new record. ## The validate / save cycle -Whenever the control is about to leave the current record — through a navigation button, a programmatic move, **Refresh**, **Update**, **Delete**, or unloading the form — it fires [**Validate**](#validate) with an *Action* argument from [**DataValidateConstants**](../../VBRUN/Constants/DataValidateConstants) and a *Save* flag indicating whether bound controls hold unsaved edits. Setting *Action* to **vbDataActionCancel** (0) cancels the operation and keeps the current record. If *Save* is non-zero on return and the operation proceeds, the bound controls are flushed back into the recordset before the move occurs. +Whenever the control is about to leave the current record --- through a navigation button, a programmatic move, **Refresh**, **Update**, **Delete**, or unloading the form --- it fires [**Validate**](#validate) with an *Action* argument from [**DataValidateConstants**](../../VBRUN/Constants/DataValidateConstants) and a *Save* flag indicating whether bound controls hold unsaved edits. Setting *Action* to **vbDataActionCancel** (0) cancels the operation and keeps the current record. If *Save* is non-zero on return and the operation proceeds, the bound controls are flushed back into the recordset before the move occurs. [**Reposition**](#reposition) is raised after a successful move, with the bound controls already showing the new record. [**UpdateControls**](#updatecontrols) re-pulls the current record into the bound controls without firing **Reposition**, and [**UpdateRecord**](#updaterecord) is reserved for explicit save-without-move (currently unimplemented). @@ -83,12 +83,12 @@ The fill colour of the band behind the [**Caption**](#caption), as an **OLE_COLO ### BOFAction {: .no_toc } -Controls what happens when the user moves past the start of the recordset. A member of [**DataBOFconstants**](../../VBRUN/Constants/DataBOFconstants): **vbMoveFirst** (0, default — snap back to the first record) or **vbBOF** (1 — let the recordset sit on the beginning-of-file marker, leaving bound controls cleared). +Controls what happens when the user moves past the start of the recordset. A member of [**DataBOFconstants**](../../VBRUN/Constants/DataBOFconstants): **vbMoveFirst** (0, default --- snap back to the first record) or **vbBOF** (1 --- let the recordset sit on the beginning-of-file marker, leaving bound controls cleared). ### Caption {: .no_toc } -The text drawn in the band between the navigation buttons. **String**, default `"Data"`. The string is read directly from the underlying window — assigning to **Caption** is reflected immediately. +The text drawn in the band between the navigation buttons. **String**, default `"Data"`. The string is read directly from the underlying window --- assigning to **Caption** is reflected immediately. Syntax: *object*.**Caption** [ = *string* ] @@ -110,7 +110,7 @@ A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstant ### Database {: .no_toc } -The currently open DAO database. Read-only — assign to [**Recordset**](#recordset) or call [**Refresh**](#refresh) to change it. +The currently open DAO database. Read-only --- assign to [**Recordset**](#recordset) or call [**Refresh**](#refresh) to change it. ### DatabaseName {: .no_toc } @@ -125,7 +125,7 @@ The cursor driver to use when [**DefaultType**](#defaulttype) is **vbUseODBC**. ### DefaultType {: .no_toc } -The database engine to use. A member of [**DatabaseTypeConstants**](../../VBRUN/Constants/DatabaseTypeConstants): **vbUseJet** (2, default), **vbUseODBC** (1), or **vbUseACE** (3 — new in twinBASIC, uses the Access ACE engine). Read once when the recordset is opened. +The database engine to use. A member of [**DatabaseTypeConstants**](../../VBRUN/Constants/DatabaseTypeConstants): **vbUseJet** (2, default), **vbUseODBC** (1), or **vbUseACE** (3 --- new in twinBASIC, uses the Access ACE engine). Read once when the recordset is opened. ### DragIcon {: .no_toc } @@ -135,7 +135,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -145,7 +145,7 @@ Determines whether the control accepts user input. A disabled **Data** control s ### EOFAction {: .no_toc } -Controls what happens when the user moves past the end of the recordset. A member of [**DataEOFConstants**](../../VBRUN/Constants/DataEOFConstants): **vbMoveLast** (0, default — snap back to the last record), **vbEOF** (1 — sit on the end-of-file marker), or **vbAddNew** (2 — clear all bound controls and start a new record ready for editing). +Controls what happens when the user moves past the end of the recordset. A member of [**DataEOFConstants**](../../VBRUN/Constants/DataEOFConstants): **vbMoveLast** (0, default --- snap back to the last record), **vbEOF** (1 --- sit on the end-of-file marker), or **vbAddNew** (2 --- clear all bound controls and start a new record ready for editing). ### Exclusive {: .no_toc } @@ -401,7 +401,7 @@ Syntax: *object*\_**Error**( *DataErr* **As Integer**, *Response* **As Integer** ### Initialize {: .no_toc } -Raised once, immediately after the underlying window is created and before the recordset is opened. Useful for setting [**DatabaseName**](#databasename), [**RecordSource**](#recordsource), or [**Connect**](#connect) from code in time for the first connection. New in twinBASIC — VB6 had no equivalent on the **Data** control. +Raised once, immediately after the underlying window is created and before the recordset is opened. Useful for setting [**DatabaseName**](#databasename), [**RecordSource**](#recordsource), or [**Connect**](#connect) from code in time for the first connection. New in twinBASIC --- VB6 had no equivalent on the **Data** control. Syntax: *object*\_**Initialize**( ) @@ -478,7 +478,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Reposition {: .no_toc } -Raised after the current record has changed — through a navigation button, a programmatic move on [**Recordset**](#recordset), an assignment to **Recordset**, or [**Refresh**](#refresh) — and after every bound control has been re-synced to the new record. The point at which to update derived UI such as a "Record *n* of *m*" caption. +Raised after the current record has changed --- through a navigation button, a programmatic move on [**Recordset**](#recordset), an assignment to **Recordset**, or [**Refresh**](#refresh) --- and after every bound control has been re-synced to the new record. The point at which to update derived UI such as a "Record *n* of *m*" caption. Syntax: *object*\_**Reposition**( ) @@ -493,7 +493,7 @@ Syntax: *object*\_**Resize**( ) ### Validate {: .no_toc } -Raised before any operation that would leave the current record — a navigation button, a programmatic move, **Update**, **Delete**, **Refresh**, **Find**, an **AddNew**, an explicit close, or unloading the form. **Default event.** +Raised before any operation that would leave the current record --- a navigation button, a programmatic move, **Update**, **Delete**, **Refresh**, **Find**, an **AddNew**, an explicit close, or unloading the form. **Default event.** Syntax: *object*\_**Validate**( *Action* **As Integer**, *Save* **As Integer** ) diff --git a/docs/Reference/VB/DirListBox/index.md b/docs/Reference/VB/DirListBox/index.md index 7c7078c1..8969db69 100644 --- a/docs/Reference/VB/DirListBox/index.md +++ b/docs/Reference/VB/DirListBox/index.md @@ -8,7 +8,7 @@ has_toc: false # DirListBox class {: .no_toc } -A **DirListBox** is a Win32 native list control that displays the directory tree for a single path: the ancestors of the current folder are shown above (each with a closed-folder icon, indented by depth), and the immediate subdirectories of the current folder appear below (each with an open-folder icon at full indent). Double-clicking an entry navigates into it, raising a [**Change**](#change) event. The control is normally placed on a **Form** or **UserControl** at design time alongside a [**DriveListBox**](../DriveListBox) and a [**FileListBox**](../FileListBox), wiring their **Change** events together to drive a complete file picker. The default property is [**Path**](#path) and the default event is [**Change**](#change). +A **DirListBox** is a Win32 native list control that displays the directory tree for a single path: the ancestors of the current folder are shown above (each with a closed-folder icon, indented by depth), and the immediate subdirectories of the current folder appear below (each with an open-folder icon at full indent). Double-clicking an entry navigates into it, raising a [**Change**](#change) event. The control is normally placed on a **Form** or **UserControl** at design time alongside a [**DriveListBox**](../DriveListBox) and a [**FileListBox**](../FileListBox), connecting their **Change** events together to build a complete file picker. The default property is [**Path**](#path) and the default event is [**Change**](#change). ```tb Private Sub Form_Load() @@ -33,15 +33,15 @@ 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**](../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 traverses back up the tree; for a subdirectory it concatenates **Path** and the entry's name. +- [**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 traverses back up the tree; for a subdirectory it concatenates **Path** and the entry's name. -Activating an entry — by double-clicking, or by an external caller assigning **Path** — runs the navigation, repopulates the list, and raises [**Change**](#change). Setting **Path** to its current value is a no-op (no event). +Activating an entry --- by double-clicking, or by an external caller assigning **Path** --- runs the navigation, repopulates the list, and raises [**Change**](#change). Setting **Path** to its current value is a no-op (no event). ## List, ListCount, and NewIndex -[**ListCount**](#listcount) is the number of subdirectories of the current folder (it does *not* include the ancestor entries shown above). [**List**](#list) is indexed from zero through `ListCount - 1` and returns the *full path* of the corresponding subdirectory — convenient when iterating from code: +[**ListCount**](#listcount) is the number of subdirectories of the current folder (it does *not* include the ancestor entries shown above). [**List**](#list) is indexed from zero through `ListCount - 1` and returns the *full path* of the corresponding subdirectory --- convenient when iterating from code: ```tb Dim i As Long @@ -89,7 +89,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -190,7 +190,7 @@ How the control responds to OLE drops. A restricted member of [**OLEDropConstant ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -204,9 +204,9 @@ The absolute path of the current directory. **Default property.** Syntax: *object*.**Path** [ = *string* ] -Reading **Path** returns the path the list is currently displaying — drive plus joined ancestor names. Setting **Path** repopulates the list to show the new directory and its subdirectories, raising [**Change**](#change) if the new value differs from the current one. Assigning a path that does not exist (or is not a directory) raises run-time error 76 (*Path not found*). +Reading **Path** returns the path the list is currently displaying --- drive plus joined ancestor names. Setting **Path** repopulates the list to show the new directory and its subdirectories, raising [**Change**](#change) if the new value differs from the current one. Assigning a path that does not exist (or is not a directory) raises run-time error 76 (*Path not found*). -The **DriveListBox** and **DirListBox** controls accept each other's "drive [volume label]" formatting at this property — `Dir1.Path = Drive1.Drive` does the right thing without manual stripping. +The **DriveListBox** and **DirListBox** controls accept each other's "drive [volume label]" formatting at this property --- `Dir1.Path = Drive1.Drive` does the right thing without manual stripping. ### PathSelected {: .no_toc } @@ -308,7 +308,7 @@ Syntax: *object*.**OLEDrag** ### Refresh {: .no_toc } -Re-reads the contents of the current [**Path**](#path) from disk and repaints the control. Useful when the directory has been modified outside the application — the control does not watch the file system on its own. Does not raise [**Change**](#change). +Re-reads the contents of the current [**Path**](#path) from disk and repaints the control. Useful when the directory has been modified outside the application --- the control does not watch the file system on its own. Does not raise [**Change**](#change). Syntax: *object*.**Refresh** @@ -341,14 +341,14 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Change {: .no_toc } -Raised after [**Path**](#path) has changed — whether the user double-clicked an entry or code assigned a different value to **Path**. Not raised for assignments that match the current value, and not raised during the initial population that occurs before [**Initialize**](#initialize). **Default event.** +Raised after [**Path**](#path) has changed --- whether the user double-clicked an entry or code assigned a different value to **Path**. Not raised for assignments that match the current value, and not raised during the initial population that occurs before [**Initialize**](#initialize). **Default event.** Syntax: *object*\_**Change**( ) ### Click {: .no_toc } -Raised after [**ListIndex**](#listindex) changes — whether the user clicked a different entry, used the keyboard to move the selection, or code assigned a different value to [**ListIndex**](#listindex). Also raised when the selection is cancelled (e.g. by clicking the empty area below the last entry). +Raised after [**ListIndex**](#listindex) changes --- whether the user clicked a different entry, used the keyboard to move the selection, or code assigned a different value to [**ListIndex**](#listindex). Also raised when the selection is cancelled (e.g. by clicking the empty area below the last entry). Syntax: *object*\_**Click**( ) @@ -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**](../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**( ) @@ -474,7 +474,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Scroll {: .no_toc } -Raised when the visible portion of the list scrolls — by the scroll bar, the keyboard, or (when [**WheelScrollEvent**](#wheelscrollevent) is **True**) the mouse wheel. The new offset can be read from [**TopIndex**](#topindex). +Raised when the visible portion of the list scrolls --- by the scroll bar, the keyboard, or (when [**WheelScrollEvent**](#wheelscrollevent) is **True**) the mouse wheel. The new offset can be read from [**TopIndex**](#topindex). Syntax: *object*\_**Scroll**( ) diff --git a/docs/Reference/VB/DriveListBox/index.md b/docs/Reference/VB/DriveListBox/index.md index ee82fb96..1af22c20 100644 --- a/docs/Reference/VB/DriveListBox/index.md +++ b/docs/Reference/VB/DriveListBox/index.md @@ -27,7 +27,7 @@ End Sub ## Drive list -The list is populated automatically when the underlying window is created, by asking the OS for every currently-attached drive. Each entry combines the drive letter with the volume label, or — for a network drive — the UNC path the drive is mapped to: +The list is populated automatically when the underlying window is created, by asking the OS for every currently-attached drive. Each entry combines the drive letter with the volume label, or --- for a network drive --- the UNC path the drive is mapped to: | Entry shape | Meaning | |----------------------|------------------------------------------------------------------| @@ -35,15 +35,15 @@ The list is populated automatically when the underlying window is created, by as | `d:` (no brackets) | Drive present but no volume label (unformatted, or empty CD-ROM).| | `z: [\\srv\share]` | Network drive; UNC path in brackets. | -Each entry is owner-drawn with an icon chosen from the drive type — closed disk, removable, fixed, CD-ROM, network, or RAM disk. The list cannot be edited from code: [**AddItem**](../ComboBox/#additem), [**RemoveItem**](../ComboBox/#removeitem), and [**Clear**](../ComboBox/#clear) are present in the type library for VB6 source compatibility but raise run-time error 438 (*Object doesn't support this property or method*) when called. Call [**Refresh**](#refresh) to re-read the drive set from the OS — useful after a removable medium is inserted or a network drive is mapped. +Each entry is owner-drawn with an icon chosen from the drive type --- closed disk, removable, fixed, CD-ROM, network, or RAM disk. The list cannot be edited from code: [**AddItem**](../ComboBox/#additem), [**RemoveItem**](../ComboBox/#removeitem), and [**Clear**](../ComboBox/#clear) are present in the type library for VB6 source compatibility but raise run-time error 438 (*Object doesn't support this property or method*) when called. Call [**Refresh**](#refresh) to re-read the drive set from the OS --- useful after a removable medium is inserted or a network drive is mapped. [**ListCount**](#listcount) is the number of entries, [**List**](#list) returns the text of any entry by zero-based index, and [**TopIndex**](#topindex) controls vertical scrolling within the drop-down portion when it is open. [**NewIndex**](#newindex) reports the position of the last entry added during population (useful only when re-reading the list from code). ## Drive property semantics -Reading [**Drive**](#drive) returns the *displayed text* of the currently selected entry — drive letter, colon, and (where applicable) the bracketed volume label or UNC path, exactly as shown in the combo. +Reading [**Drive**](#drive) returns the *displayed text* of the currently selected entry --- drive letter, colon, and (where applicable) the bracketed volume label or UNC path, exactly as shown in the combo. -Assigning to [**Drive**](#drive) looks only at the **first character** of the value and selects the entry whose drive letter matches (case-insensitively, by prefix). Anything after the first character is ignored, so `"C"`, `"C:"`, and `"C:\Windows"` all select the **C:** drive. If no entry matches the letter — e.g. when the requested drive is not currently attached — the assignment is silently ignored, leaving the previous selection in place. Assigning a value that matches the current selection does not raise [**Change**](#change); assigning a different value does. +Assigning to [**Drive**](#drive) looks only at the **first character** of the value and selects the entry whose drive letter matches (case-insensitively, by prefix). Anything after the first character is ignored, so `"C"`, `"C:"`, and `"C:\Windows"` all select the **C:** drive. If no entry matches the letter --- e.g. when the requested drive is not currently attached --- the assignment is silently ignored, leaving the previous selection in place. Assigning a value that matches the current selection does not raise [**Change**](#change); assigning a different value does. ```tb Drive1.Drive = "D" ' select drive D if present, else no-op @@ -52,7 +52,7 @@ Debug.Print Drive1.Drive ' "d: [Backup]" (the displayed text) ## OLE drag and drop -[**OLEDropMode**](#oledropmode) lets the control act as a drop target (restricted to **vbOLEDropNone** or **vbOLEDropManual**). Source-side automatic OLE drag is not supported on this control — VB6's `OLEDragMode` property was non-functional here and is omitted in twinBASIC. Call [**OLEDrag**](#oledrag) from code if a manual drag is needed. +[**OLEDropMode**](#oledropmode) lets the control act as a drop target (restricted to **vbOLEDropNone** or **vbOLEDropManual**). Source-side automatic OLE drag is not supported on this control --- VB6's `OLEDragMode` property was non-functional here and is omitted in twinBASIC. Call [**OLEDrag**](#oledrag) from code if a manual drag is needed. ## Properties @@ -84,7 +84,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Drive {: .no_toc } @@ -93,7 +93,7 @@ The currently selected drive. **Default property.** Syntax: *object*.**Drive** [ = *string* ] -Reading returns the displayed text of the selected entry — drive letter, colon, and (where applicable) the bracketed volume label or UNC path. Writing examines only the first character of *string* and selects the entry whose drive letter matches; values that do not match any present drive are silently ignored. Assigning a value that changes the selection raises [**Change**](#change). See [Drive property semantics](#drive-property-semantics) above for details. +Reading returns the displayed text of the selected entry --- drive letter, colon, and (where applicable) the bracketed volume label or UNC path. Writing examines only the first character of *string* and selects the entry whose drive letter matches; values that do not match any present drive are silently ignored. Assigning a value that changes the selection raises [**Change**](#change). See [Drive property semantics](#drive-property-semantics) above for details. ### Enabled {: .no_toc } @@ -183,7 +183,7 @@ How the control responds to OLE drops. A restricted member of [**OLEDropConstant ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -285,7 +285,7 @@ Syntax: *object*.**OLEDrag** ### Refresh {: .no_toc } -Re-reads the set of currently-attached drives from the operating system and repopulates the list, then redraws the control. Useful after a removable medium is inserted or a network drive is mapped or disconnected — the control does not watch for these events on its own. Does not raise [**Change**](#change), even if the previously-selected drive is no longer present (the selection moves to entry `0`). +Re-reads the set of currently-attached drives from the operating system and repopulates the list, then redraws the control. Useful after a removable medium is inserted or a network drive is mapped or disconnected --- the control does not watch for these events on its own. Does not raise [**Change**](#change), even if the previously-selected drive is no longer present (the selection moves to entry `0`). Syntax: *object*.**Refresh** @@ -318,14 +318,14 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Change {: .no_toc } -Raised after the selected drive changes — whether the user picked a different entry from the drop-down or code assigned a different value to [**Drive**](#drive) or [**ListIndex**](#listindex). Not raised for assignments that match the current selection, nor during [**Refresh**](#refresh) or the initial population that occurs before [**Initialize**](#initialize). **Default event.** +Raised after the selected drive changes --- whether the user picked a different entry from the drop-down or code assigned a different value to [**Drive**](#drive) or [**ListIndex**](#listindex). Not raised for assignments that match the current selection, nor during [**Refresh**](#refresh) or the initial population that occurs before [**Initialize**](#initialize). **Default event.** Syntax: *object*\_**Change**( ) ### CloseUp {: .no_toc } -Raised when the drop-down portion closes — either because the user picked an entry, clicked elsewhere, or pressed **Esc**. +Raised when the drop-down portion closes --- either because the user picked an entry, clicked elsewhere, or pressed **Esc**. Syntax: *object*\_**CloseUp**( ) @@ -360,7 +360,7 @@ Syntax: *object*\_**GotFocus**( ) ### Initialize {: .no_toc } -Raised once, immediately after the underlying window is created and the initial list of drives 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 list of drives has been loaded. New in twinBASIC --- VB6 had no equivalent on this control. Syntax: *object*\_**Initialize**( ) @@ -437,7 +437,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Scroll {: .no_toc } -Raised when the drop-down list is scrolled — by the scroll bar, the keyboard, or (when [**WheelScrollEvent**](#wheelscrollevent) is **True**) the mouse wheel. The new offset can be read from [**TopIndex**](#topindex). +Raised when the drop-down list is scrolled --- by the scroll bar, the keyboard, or (when [**WheelScrollEvent**](#wheelscrollevent) is **True**) the mouse wheel. The new offset can be read from [**TopIndex**](#topindex). Syntax: *object*\_**Scroll**( ) diff --git a/docs/Reference/VB/FileListBox/index.md b/docs/Reference/VB/FileListBox/index.md index b89e03a4..7816dd95 100644 --- a/docs/Reference/VB/FileListBox/index.md +++ b/docs/Reference/VB/FileListBox/index.md @@ -8,7 +8,7 @@ has_toc: false # FileListBox class {: .no_toc } -A **FileListBox** is a Win32 native list control that displays the files in a single directory, filtered by a wildcard pattern and a set of file-attribute toggles. It is normally placed on a **Form** or **UserControl** at design time and paired with a [**DriveListBox**](../DriveListBox) and a [**DirListBox**](../DirListBox) to make a complete file picker — wire their **Change** events through to **FileListBox.Path** and let the user pick a name from the list. The default property is [**FileName**](#filename) and the default event is [**Click**](#click). +A **FileListBox** is a Win32 native list control that displays the files in a single directory, filtered by a wildcard pattern and a set of file-attribute toggles. It is normally placed on a **Form** or **UserControl** at design time and paired with a [**DriveListBox**](../DriveListBox) and a [**DirListBox**](../DirListBox) to make a complete file picker --- their **Change** events feed into **FileListBox.Path**, and the user selects a name from the list. The default property is [**FileName**](#filename) and the default event is [**Click**](#click). ```tb Private Sub Form_Load() @@ -36,7 +36,7 @@ End Sub ## Path and Pattern -[**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). +[**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. @@ -52,7 +52,7 @@ Five **Boolean** properties decide which files are included after the pattern ma | [**ReadOnly**](#readonly) | **Include read-only files.** | | [**System**](#system) | Include system files. | -A file passes if every attribute it carries is permitted. **Normal** is the odd one out: it gates files that carry *no* attribute at all, so setting **Normal = False** with the others left at their defaults restricts the list to files that explicitly have one of the included attributes. Changing any of these reloads the list and raises [**PatternChange**](#patternchange) — the event is shared with [**Pattern**](#pattern), matching the VB6 behaviour even though the name is misleading. +A file passes if every attribute it carries is permitted. **Normal** is the odd one out: it gates files that carry *no* attribute at all, so setting **Normal = False** with the others left at their defaults restricts the list to files that explicitly have one of the included attributes. Changing any of these reloads the list and raises [**PatternChange**](#patternchange) --- the event is shared with [**Pattern**](#pattern), matching the VB6 behaviour even though the name is misleading. ## Selecting files @@ -111,7 +111,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -190,7 +190,7 @@ The number of files currently shown in the list, as a **Long**. Read-only. ### ListIndex {: .no_toc } -The zero-based index of the focused item, or `-1` if no item is focused. **Long**. In multi-select modes the focused item and the selected items are independent — see [**Selected**](#selected). Assigning a value that differs from the current one focuses that item and raises [**Click**](#click). +The zero-based index of the focused item, or `-1` if no item is focused. **Long**. In multi-select modes the focused item and the selected items are independent --- see [**Selected**](#selected). Assigning a value that differs from the current one focuses that item and raises [**Click**](#click). ### MouseIcon {: .no_toc } @@ -205,7 +205,7 @@ The mouse cursor shown when the pointer is over the control. A member of [**Mous ### MultiSelect {: .no_toc } -The selection mode. A member of [**MultiSelectConstants**](../../VBRUN/Constants/MultiSelectConstants): **vbMultiSelectNone** (0, default — single selection), **vbMultiSelectSimple** (1 — each click toggles), or **vbMultiSelectExtended** (2 — **Shift** for ranges, **Ctrl** for individual toggles). Changing this at run time recreates the underlying window; the current path, pattern, top-index, and focused item are restored, but multi-item selections are not. +The selection mode. A member of [**MultiSelectConstants**](../../VBRUN/Constants/MultiSelectConstants): **vbMultiSelectNone** (0, default --- single selection), **vbMultiSelectSimple** (1 --- each click toggles), or **vbMultiSelectExtended** (2 --- **Shift** for ranges, **Ctrl** for individual toggles). Changing this at run time recreates the underlying window; the current path, pattern, top-index, and focused item are restored, but multi-item selections are not. ### Name {: .no_toc } @@ -220,7 +220,7 @@ When **True** (default), files with no attribute bits set are included in the li ### OLEDragMode {: .no_toc } -Whether the control acts as an automatic OLE drag source. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default — call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1 — dragging an entry starts an OLE drag whose **Text** data is the full path of the selected file, or a list of paths in multi-select mode). +Whether the control acts as an automatic OLE drag source. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default --- call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1 --- dragging an entry starts an OLE drag whose **Text** data is the full path of the selected file, or a list of paths in multi-select mode). ### OLEDropMode {: .no_toc } @@ -230,7 +230,7 @@ How the control responds to OLE drops. A restricted member of [**OLEDropConstant ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -244,7 +244,7 @@ The directory whose files are listed. **String**. Defaults to [**App.Path**](../ Syntax: *object*.**Path** [ = *string* ] -Reading **Path** returns the directory currently shown — without a trailing backslash (except for a drive root, which is always returned as `"C:\"`). Setting **Path** reloads the list and raises [**PathChange**](#pathchange) when the new value differs from the current one. A bare drive specifier with no backslash (`"C:"`) is silently rejected; use `"C:\"`. Assigning a path that does not exist raises run-time error 76 (*Path not found*). +Reading **Path** returns the directory currently shown --- without a trailing backslash (except for a drive root, which is always returned as `"C:\"`). Setting **Path** reloads the list and raises [**PathChange**](#pathchange) when the new value differs from the current one. A bare drive specifier with no backslash (`"C:"`) is silently rejected; use `"C:\"`. Assigning a path that does not exist raises run-time error 76 (*Path not found*). ### PathWithBackslash {: .no_toc } @@ -386,7 +386,7 @@ Syntax: *object*.**OLEDrag** ### Refresh {: .no_toc } -Re-reads the contents of the current [**Path**](#path) from disk and repaints the control. Useful when the directory has been modified outside the application — the control does not watch the file system on its own. Does not raise [**PathChange**](#pathchange) or [**PatternChange**](#patternchange). +Re-reads the contents of the current [**Path**](#path) from disk and repaints the control. Useful when the directory has been modified outside the application --- the control does not watch the file system on its own. Does not raise [**PathChange**](#pathchange) or [**PatternChange**](#patternchange). Syntax: *object*.**Refresh** @@ -433,14 +433,14 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Click {: .no_toc } -Raised after the focused item changes — whether the user clicked a different entry, used the keyboard to move the focus, or code assigned a different value to [**ListIndex**](#listindex) or [**Selected**](#selected). Also raised when the selection is cancelled. **Default event.** +Raised after the focused item changes --- whether the user clicked a different entry, used the keyboard to move the focus, or code assigned a different value to [**ListIndex**](#listindex) or [**Selected**](#selected). Also raised when the selection is cancelled. **Default event.** Syntax: *object*\_**Click**( ) ### DblClick {: .no_toc } -Raised when the user double-clicks an entry. Unlike [**DirListBox**](../DirListBox), the **FileListBox** does *not* navigate on double-click — typically the application listens for **DblClick** to open the file the user has chosen. +Raised when the user double-clicks an entry. Unlike [**DirListBox**](../DirListBox), the **FileListBox** does *not* navigate on double-click --- typically the application listens for **DblClick** to open the file the user has chosen. Syntax: *object*\_**DblClick**( ) @@ -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**](../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**( ) @@ -566,21 +566,21 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### PathChange {: .no_toc } -Raised after [**Path**](#path) has changed — typically because code assigned a new value to it. Not raised for assignments that match the current value. +Raised after [**Path**](#path) has changed --- typically because code assigned a new value to it. Not raised for assignments that match the current value. Syntax: *object*\_**PathChange**( ) ### PatternChange {: .no_toc } -Raised after [**Pattern**](#pattern) has changed *or* after one of the file-attribute filter properties — [**Archive**](#archive), [**Hidden**](#hidden), [**Normal**](#normal), [**ReadOnly**](#readonly), [**System**](#system) — has changed. Not raised for pattern assignments that match the current value. The shared event matches the VB6 behaviour even though the name is misleading. +Raised after [**Pattern**](#pattern) has changed *or* after one of the file-attribute filter properties --- [**Archive**](#archive), [**Hidden**](#hidden), [**Normal**](#normal), [**ReadOnly**](#readonly), [**System**](#system) --- has changed. Not raised for pattern assignments that match the current value. The shared event matches the VB6 behaviour even though the name is misleading. Syntax: *object*\_**PatternChange**( ) ### Scroll {: .no_toc } -Raised when the visible portion of the list scrolls — by the scroll bar, the keyboard, or (when [**WheelScrollEvent**](#wheelscrollevent) is **True**) the mouse wheel. The new offset can be read from [**TopIndex**](#topindex). +Raised when the visible portion of the list scrolls --- by the scroll bar, the keyboard, or (when [**WheelScrollEvent**](#wheelscrollevent) is **True**) the mouse wheel. The new offset can be read from [**TopIndex**](#topindex). Syntax: *object*\_**Scroll**( ) diff --git a/docs/Reference/VB/Form/index.md b/docs/Reference/VB/Form/index.md index 6a375cd9..d72e7914 100644 --- a/docs/Reference/VB/Form/index.md +++ b/docs/Reference/VB/Form/index.md @@ -8,7 +8,7 @@ has_toc: false # Form class {: .no_toc } -A **Form** is a top-level Win32 window that hosts the controls, menus, and drawing surface of a single twinBASIC user interface. Each form designed in the IDE becomes its own class derived from **Form** — its controls become members of that class, its event handlers become methods on it, and the file's name becomes the class name. Code outside the form normally instantiates it implicitly through the global default-instance reference (`MyForm.Show`) or explicitly with `New MyForm`. The default property is [**Controls**](#controls) and the default event is [**Load**](#load). +A **Form** is a top-level Win32 window that hosts the controls, menus, and drawing surface of a single twinBASIC user interface. Each form designed in the IDE becomes its own class derived from **Form** --- its controls become members of that class, its event handlers become methods on it, and the file's name becomes the class name. Code outside the form normally instantiates it implicitly through the global default-instance reference (`MyForm.Show`) or explicitly with `New MyForm`. The default property is [**Controls**](#controls) and the default event is [**Load**](#load). ```tb ' In Form1's code-behind: @@ -49,7 +49,7 @@ Closing a form goes through both **QueryUnload** *and* **Unload**, so either can ## Showing the form -[**Show**](#show) makes the form visible. It accepts an optional [**FormShowConstants**](../../VBRUN/Constants/FormShowConstants) argument: **vbModeless** (default — the call returns immediately and the user can interact with other forms) or **vbModal** (the call blocks until the form is closed, and other forms in the application become unresponsive). MDI child forms cannot be shown modally; attempting to do so raises run-time error 404. +[**Show**](#show) makes the form visible. It accepts an optional [**FormShowConstants**](../../VBRUN/Constants/FormShowConstants) argument: **vbModeless** (default --- the call returns immediately and the user can interact with other forms) or **vbModal** (the call blocks until the form is closed, and other forms in the application become unresponsive). MDI child forms cannot be shown modally; attempting to do so raises run-time error 404. ```tb dlgOptions.Show vbModal, Me ' modal, owned by the calling form @@ -57,7 +57,7 @@ dlgOptions.Show vbModal, Me ' modal, owned by the calling form [**Hide**](#hide) and [**Close**](#close) reverse the effect: **Hide** just clears [**Visible**](#visible); **Close** runs the full unload sequence (**QueryUnload** then **Unload** then **Terminate**). The classic `Unload <FormName>` statement is the language-level equivalent of **Close**. -[**StartUpPosition**](#startupposition) ([**StartUpPositionConstants**](../../VBRUN/Constants/StartUpPositionConstants)) is read at the first **Show** to decide where the form lands; afterwards the user (or code through [**Move**](#move) and [**WindowState**](#windowstate)) controls position. +[**StartUpPosition**](#startupposition) ([**StartUpPositionConstants**](../../VBRUN/Constants/StartUpPositionConstants)) is read at the first **Show** to decide where the form is placed; afterwards the user (or code through [**Move**](#move) and [**WindowState**](#windowstate)) controls position. ## Window appearance @@ -69,9 +69,9 @@ dlgOptions.Show vbModal, Me ' modal, owned by the calling form ## Drawing surface -A **Form** is itself a graphics surface — code can draw lines, shapes, and text directly on it. The coordinate system is governed by [**ScaleMode**](#scalemode) (default **vbTwips** — the classic VB6 behaviour) and the [**ScaleLeft**](#scaleleft) / [**ScaleTop**](#scaletop) / [**ScaleWidth**](#scalewidth) / [**ScaleHeight**](#scaleheight) properties, which together describe the form's logical drawing rectangle. Setting **ScaleMode** to **vbUser** lets the four **Scale\*** properties define an arbitrary rectangle; the [**Scale**](#scale) method does this in a single call. +A **Form** is itself a graphics surface --- code can draw lines, shapes, and text directly on it. The coordinate system is governed by [**ScaleMode**](#scalemode) (default **vbTwips** --- the classic VB6 behaviour) and the [**ScaleLeft**](#scaleleft) / [**ScaleTop**](#scaletop) / [**ScaleWidth**](#scalewidth) / [**ScaleHeight**](#scaleheight) properties, which together describe the form's logical drawing rectangle. Setting **ScaleMode** to **vbUser** lets the four **Scale\*** properties define an arbitrary rectangle; the [**Scale**](#scale) method does this in a single call. -The drawing primitives are [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and the [**Print**](#print) statement (`Form1.Print "Hello"`) — all use [**ForeColor**](#forecolor), [**FillColor**](#fillcolor), [**FillStyle**](#fillstyle), [**DrawWidth**](#drawwidth), [**DrawMode**](#drawmode), and [**DrawStyle**](#drawstyle) for their pen and fill, and the form's [**Font**](#font) for text. The current pen position is tracked by [**CurrentX**](#currentx) and [**CurrentY**](#currenty); [**TextWidth**](#textwidth) and [**TextHeight**](#textheight) measure a string in the current font. [**ScaleX**](#scalex) and [**ScaleY**](#scaley) convert single coordinates between scale modes. +The drawing primitives are [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and the [**Print**](#print) statement (`Form1.Print "Hello"`) --- all use [**ForeColor**](#forecolor), [**FillColor**](#fillcolor), [**FillStyle**](#fillstyle), [**DrawWidth**](#drawwidth), [**DrawMode**](#drawmode), and [**DrawStyle**](#drawstyle) for their pen and fill, and the form's [**Font**](#font) for text. The current pen position is tracked by [**CurrentX**](#currentx) and [**CurrentY**](#currenty); [**TextWidth**](#textwidth) and [**TextHeight**](#textheight) measure a string in the current font. [**ScaleX**](#scalex) and [**ScaleY**](#scaley) convert single coordinates between scale modes. [**AutoRedraw**](#autoredraw) controls whether drawn output persists across paints: when **False** (default), the [**Paint**](#paint) event must redraw on every invalidation; when **True**, the form keeps an off-screen buffer that survives invalidations and the **Paint** event is suppressed. Setting [**Picture**](#picture) puts a bitmap behind the drawing layer; [**Image**](#image) returns the rendered combined surface as a **StdPicture**. @@ -88,9 +88,9 @@ End Sub ## Controls and validation -[**Controls**](#controls) is a collection of every control on the form, indexable by name or zero-based position. **Form** is also enumerable directly — `For Each ctrl In Form1` yields the same items as `For Each ctrl In Form1.Controls`. [**Count**](#count) is shorthand for `Controls.Count`. [**ActiveControl**](#activecontrol) returns the currently focused child, or **Nothing** when no control on this form has the focus. +[**Controls**](#controls) is a collection of every control on the form, indexable by name or zero-based position. **Form** is also enumerable directly --- `For Each ctrl In Form1` yields the same items as `For Each ctrl In Form1.Controls`. [**Count**](#count) is shorthand for `Controls.Count`. [**ActiveControl**](#activecontrol) returns the currently focused child, or **Nothing** when no control on this form has the focus. -[**KeyPreview**](#keypreview) routes keystrokes to the form's [**KeyDown**](#keydown), [**KeyUp**](#keyup), and [**KeyPress**](#keypress) events *before* the focused control sees them — useful for application-wide hotkey handling. [**ValidateControls**](#validatecontrols) explicitly fires the active control's **Validate** event from code; it raises run-time error 380 if the validation handler sets *Cancel*. +[**KeyPreview**](#keypreview) routes keystrokes to the form's [**KeyDown**](#keydown), [**KeyUp**](#keyup), and [**KeyPress**](#keypress) events *before* the focused control sees them --- useful for application-wide hotkey handling. [**ValidateControls**](#validatecontrols) explicitly fires the active control's **Validate** event from code; it raises run-time error 380 if the validation handler sets *Cancel*. ## Menus and pop-ups @@ -127,7 +127,7 @@ Determines how the control's border is drawn by the OS. A member of [**Appearanc Whether drawing performed on the form persists across invalidations. **Boolean**, default **False**. -When **False**, drawing primitives — [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and [**Print**](#print) — paint directly to the screen and the form must redraw them in its [**Paint**](#paint) event whenever the affected area is invalidated. When **True**, the form keeps an off-screen bitmap, drawing primitives paint into it (and immediately to the screen), the bitmap survives invalidations, and the **Paint** event is suppressed. Reading [**Image**](#image) returns this bitmap. +When **False**, drawing primitives --- [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and [**Print**](#print) --- paint directly to the screen and the form must redraw them in its [**Paint**](#paint) event whenever the affected area is invalidated. When **True**, the form keeps an off-screen bitmap, drawing primitives paint into it (and immediately to the screen), the bitmap survives invalidations, and the **Paint** event is suppressed. Reading [**Image**](#image) returns this bitmap. ### BackColor {: .no_toc } @@ -137,7 +137,7 @@ The background colour of the form's client area, as an **OLE_COLOR**. Defaults t ### BorderStyle {: .no_toc } -The window-frame style. A member of [**FormBorderStyleConstants**](../../VBRUN/Constants/FormBorderStyleConstants): **vbBSNone**, **vbFixedSingle**, **vbSizable** (default), **vbFixedDialog**, **vbFixedToolWindow**, **vbSizableToolWindow**, **vbSizableNoTitleBar** (new in twinBASIC), or **vbSizableToolWindowNoTitleBar** (new in twinBASIC). Run-time changes are accepted but only take effect after another change to the window — typically reassigning [**Caption**](#caption). +The window-frame style. A member of [**FormBorderStyleConstants**](../../VBRUN/Constants/FormBorderStyleConstants): **vbBSNone**, **vbFixedSingle**, **vbSizable** (default), **vbFixedDialog**, **vbFixedToolWindow**, **vbSizableToolWindow**, **vbSizableNoTitleBar** (new in twinBASIC), or **vbSizableToolWindowNoTitleBar** (new in twinBASIC). Run-time changes are accepted but only take effect after another change to the window --- typically reassigning [**Caption**](#caption). ### Caption {: .no_toc } @@ -151,7 +151,7 @@ Setting **Caption** updates the title bar immediately and re-syncs the title-bar ### ClipControls {: .no_toc } -Whether child controls are clipped out of the form's drawing region during paint. **Boolean**, default **True**. Read-only at run time — set at design time. +Whether child controls are clipped out of the form's drawing region during paint. **Boolean**, default **True**. Read-only at run time --- set at design time. ### ControlBox {: .no_toc } @@ -161,7 +161,7 @@ Whether the form's title bar shows the system menu (and, with it, the close butt ### Controls {: .no_toc } -The collection of every control hosted by this form, indexable by control name or zero-based position. **Default property.** Read-only — controls are added to the collection by the runtime, not by user code. +The collection of every control hosted by this form, indexable by control name or zero-based position. **Default property.** Read-only --- controls are added to the collection by the runtime, not by user code. ```tb Dim ctrl As Control @@ -253,7 +253,7 @@ The Win32 device context handle for the form, as a **LongPtr**. Read-only. Retur ### HasDC {: .no_toc } -Whether the form keeps a private device context (`CS_OWNDC`) for its drawing surface. **Boolean**, default **True**. Read-only at run time — set at design time. +Whether the form keeps a private device context (`CS_OWNDC`) for its drawing surface. **Boolean**, default **True**. Read-only at run time --- set at design time. ### Height {: .no_toc } @@ -278,7 +278,7 @@ The icon shown on the title bar, in the taskbar, and in Alt-Tab. A **StdPicture* ### Image {: .no_toc } -Returns the rendered drawing surface as a **StdPicture**. Read-only. Most useful when [**AutoRedraw**](#autoredraw) is **True** — the returned picture is the persistent off-screen buffer. +Returns the rendered drawing surface as a **StdPicture**. Read-only. Most useful when [**AutoRedraw**](#autoredraw) is **True** --- the returned picture is the persistent off-screen buffer. ### KeyPreview {: .no_toc } @@ -288,7 +288,7 @@ When **True**, the form's [**KeyDown**](#keydown), [**KeyUp**](#keyup), and [**K ### Left {: .no_toc } -The horizontal position of the form's outer rectangle, in twips (or the calling code's **ScaleMode** units), measured from the left edge of the screen — or, for an MDI child, from the left edge of the MDI parent's client area. **Double**. +The horizontal position of the form's outer rectangle, in twips (or the calling code's **ScaleMode** units), measured from the left edge of the screen --- or, for an MDI child, from the left edge of the MDI parent's client area. **Double**. ### LinkMode {: .no_toc } @@ -320,7 +320,7 @@ The maximum width of the form's *client area*, in twips. **Double**, default `0` ### MDIChild {: .no_toc } -When **True**, the form is hosted as a child inside an [**MDIForm**](../MDIForm). **Boolean**, read-only — set at design time. An MDI child form cannot be shown modally. +When **True**, the form is hosted as a child inside an [**MDIForm**](../MDIForm). **Boolean**, read-only --- set at design time. An MDI child form cannot be shown modally. ### MinButton {: .no_toc } @@ -371,7 +371,7 @@ How the form responds to OLE drops. A restricted member of [**OLEDropConstants** ### Opacity {: .no_toc } -The form's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Values below 100 cause the form to become a layered window. +The form's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Values below 100 cause the form to become a layered window. ### Palette {: .no_toc } @@ -429,12 +429,12 @@ The width of the logical drawing rectangle, in [**ScaleMode**](#scalemode) units ### ShowInTaskbar {: .no_toc } -Whether the form appears in the Windows taskbar and Alt-Tab list. **Boolean**, default **True**. Read-only at run time — set at design time. +Whether the form appears in the Windows taskbar and Alt-Tab list. **Boolean**, default **True**. Read-only at run time --- set at design time. ### StartUpPosition {: .no_toc } -How the form's initial position is determined the first time it is shown. A member of [**StartUpPositionConstants**](../../VBRUN/Constants/StartUpPositionConstants): **vbStartUpManual**, **vbStartUpOwner**, **vbStartUpScreen**, or **vbStartUpWindowsDefault** (default). Read-only at run time — set at design time. +How the form's initial position is determined the first time it is shown. A member of [**StartUpPositionConstants**](../../VBRUN/Constants/StartUpPositionConstants): **vbStartUpManual**, **vbStartUpOwner**, **vbStartUpScreen**, or **vbStartUpWindowsDefault** (default). Read-only at run time --- set at design time. ### TabFocusAutoSelect {: .no_toc } @@ -449,7 +449,7 @@ A free-form **String** the application can use to associate custom data with the ### Top {: .no_toc } -The vertical position of the form's outer rectangle, in twips (or the calling code's **ScaleMode** units), measured from the top edge of the screen — or, for an MDI child, from the top edge of the MDI parent's client area. **Double**. +The vertical position of the form's outer rectangle, in twips (or the calling code's **ScaleMode** units), measured from the top edge of the screen --- or, for an MDI child, from the top edge of the MDI parent's client area. **Double**. ### TopMost {: .no_toc } @@ -459,7 +459,7 @@ Whether the form sits in the always-on-top z-order layer. **Boolean**, read-only ### TransparencyKey {: .no_toc } -An **OLE_COLOR** that, when set, becomes fully transparent in the rendered form — clicks pass through to whatever is underneath, and the corresponding pixels do not paint. Default `-1` disables the effect. +An **OLE_COLOR** that, when set, becomes fully transparent in the rendered form --- clicks pass through to whatever is underneath, and the corresponding pixels do not paint. Default `-1` disables the effect. ### Visible {: .no_toc } @@ -469,7 +469,7 @@ Whether the form is shown. **Boolean**, default **True**. Setting **Visible** to ### WhatsThisButton {: .no_toc } -When **True**, the title bar shows a "?" help button — but only when [**MinButton**](#minbutton) is **False**, [**MaxButton**](#maxbutton) is **False**, [**ControlBox**](#controlbox) is **True**, and [**BorderStyle**](#borderstyle) is not a tool-window style. **Boolean**. +When **True**, the title bar shows a "?" help button --- but only when [**MinButton**](#minbutton) is **False**, [**MaxButton**](#maxbutton) is **False**, [**ControlBox**](#controlbox) is **True**, and [**BorderStyle**](#borderstyle) is not a tool-window style. **Boolean**. ### WhatsThisHelp {: .no_toc } @@ -520,7 +520,7 @@ Syntax: *object*.**Cls** ### Close {: .no_toc } -Initiates the form's unload sequence — [**QueryUnload**](#queryunload), then [**Unload**](#unload), then [**Terminate**](#terminate). Either of the first two events can cancel the close by setting *Cancel* to non-zero. Equivalent to the language statement `Unload Me`. +Initiates the form's unload sequence --- [**QueryUnload**](#queryunload), then [**Unload**](#unload), then [**Terminate**](#terminate). Either of the first two events can cancel the close by setting *Cancel* to non-zero. Equivalent to the language statement `Unload Me`. Syntax: *object*.**Close** @@ -628,7 +628,7 @@ Syntax: *object*.**Point**( *X*, *Y* ) ### Print {: .no_toc } -Writes text to the form's drawing surface using [**Font**](#font), starting at [**CurrentX**](#currentx) / [**CurrentY**](#currenty) and advancing them as it goes. Dispatched through the VB6 **Print** statement so multiple expressions can be separated by `;` (no spacing) or `,` (tab to the next print zone). **Spc(n)** inserts *n* spaces and **Tab(n)** moves to print column *n*. Output honours [**Font**](#font), [**ForeColor**](#forecolor), and [**FontTransparent**](#fonttransparent), and — when [**AutoRedraw**](#autoredraw) is **True** — is recorded into the persistent off-screen bitmap so it survives invalidations. +Writes text to the form's drawing surface using [**Font**](#font), starting at [**CurrentX**](#currentx) / [**CurrentY**](#currenty) and advancing them as it goes. Dispatched through the VB6 **Print** statement so multiple expressions can be separated by `;` (no spacing) or `,` (tab to the next print zone). **Spc(n)** inserts *n* spaces and **Tab(n)** moves to print column *n*. Output honours [**Font**](#font), [**ForeColor**](#forecolor), and [**FontTransparent**](#fonttransparent), and --- when [**AutoRedraw**](#autoredraw) is **True** --- is recorded into the persistent off-screen bitmap so it survives invalidations. Syntax: *object*.**Print** \[ *expressionlist* ] \[ **;** \| **,** ] @@ -728,7 +728,7 @@ Makes the form visible. Triggers [**Load**](#load) on the first call. Syntax: *object*.**Show** [ *Modal* [, *OwnerForm* ] ] *Modal* -: *optional* A member of [**FormShowConstants**](../../VBRUN/Constants/FormShowConstants): **vbModeless** (0, default — the call returns immediately) or **vbModal** (1 — the call blocks until the form is closed and the user cannot interact with other forms). +: *optional* A member of [**FormShowConstants**](../../VBRUN/Constants/FormShowConstants): **vbModeless** (0, default --- the call returns immediately) or **vbModal** (1 --- the call blocks until the form is closed and the user cannot interact with other forms). *OwnerForm* : *optional* For modal shows, the form that is disabled while this form is up; defaults to the currently active form. @@ -763,7 +763,7 @@ Syntax: *object*.**ValidateControls** ### WhatsThisMode {: .no_toc } -Enters Windows' "What's This?" cursor mode — the next click on a control raises that control's help instead of activating it. [**WhatsThisHelp**](#whatsthishelp) must be **True**. +Enters Windows' "What's This?" cursor mode --- the next click on a control raises that control's help instead of activating it. [**WhatsThisHelp**](#whatsthishelp) must be **True**. Syntax: *object*.**WhatsThisMode** @@ -782,7 +782,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Activate {: .no_toc } -Raised when the form becomes the active window in the application — either after [**Load**](#load) for the first show, or whenever it gains activation back from another window. +Raised when the form becomes the active window in the application --- either after [**Load**](#load) for the first show, or whenever it gains activation back from another window. Syntax: *object*\_**Activate**( ) @@ -974,7 +974,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Paint {: .no_toc } -Raised when an invalidated portion of the form needs to be redrawn. Suppressed when [**AutoRedraw**](#autoredraw) is **True** — the form's persistent off-screen buffer is blitted to the screen instead. +Raised when an invalidated portion of the form needs to be redrawn. Suppressed when [**AutoRedraw**](#autoredraw) is **True** --- the form's persistent off-screen buffer is blitted to the screen instead. Syntax: *object*\_**Paint**( ) @@ -989,12 +989,12 @@ Syntax: *object*\_**QueryUnload**( *Cancel* **As Integer**, *UnloadMode* **As In : Set to non-zero (any non-zero value, conventionally **1**) to cancel the close. *UnloadMode* -: A member of [**QueryUnloadConstants**](../../VBRUN/Constants/QueryUnloadConstants) identifying what triggered the close — the close button, code, Windows shutdown, the MDI parent, or the owner form. +: A member of [**QueryUnloadConstants**](../../VBRUN/Constants/QueryUnloadConstants) identifying what triggered the close --- the close button, code, Windows shutdown, the MDI parent, or the owner form. ### Resize {: .no_toc } -Raised when the form is resized — by the user, by code, by the OS following a [**WindowState**](#windowstate) change, or by initial layout during the first show. +Raised when the form is resized --- by the user, by code, by the OS following a [**WindowState**](#windowstate) change, or by initial layout during the first show. Syntax: *object*\_**Resize**( ) diff --git a/docs/Reference/VB/Frame/index.md b/docs/Reference/VB/Frame/index.md index 31c78a3c..ee6610ed 100644 --- a/docs/Reference/VB/Frame/index.md +++ b/docs/Reference/VB/Frame/index.md @@ -8,9 +8,9 @@ has_toc: false # Frame class {: .no_toc } -A **Frame** is a Win32 native container control that groups a set of related controls inside a captioned border. It serves two distinct purposes — a visual cue that the enclosed controls belong together, and a logical grouping for [**OptionButton**](../OptionButton) controls: option buttons inside the same frame are mutually exclusive of one another but independent of option buttons elsewhere on the form. Controls dropped onto a frame at design time become its children, and moving, hiding, disabling, or destroying the frame moves, hides, disables, or destroys the entire group with it. +A **Frame** is a Win32 native container control that groups a set of related controls inside a captioned border. It serves two distinct purposes --- a visual cue that the enclosed controls belong together, and a logical grouping for [**OptionButton**](../OptionButton) controls: option buttons inside the same frame are mutually exclusive of one another but independent of option buttons elsewhere on the form. Controls dropped onto a frame at design time become its children, and moving, hiding, disabling, or destroying the frame moves, hides, disables, or destroys the entire group with it. -A frame cannot itself receive the input focus. The mnemonic marker (`&`) in its [**Caption**](#caption) is honoured, but pressing **Alt+** that character moves the focus to the next control in tab order rather than to the frame itself — exactly like a [**Label**](../Label). +A frame cannot itself receive the input focus. The mnemonic marker (`&`) in its [**Caption**](#caption) is honoured, but pressing **Alt+** that character moves the focus to the next control in tab order rather than to the frame itself --- exactly like a [**Label**](../Label). The default property is [**Caption**](#caption) and the default event is [**Click**](#click). @@ -42,9 +42,9 @@ A frame is a true container: each control inside it has the frame's `hWnd` as it ## Caption, mnemonics, and the border -The text in [**Caption**](#caption) is rendered along the top edge of the border by the standard Win32 group-box style. An ampersand in the caption marks the next character as a keyboard mnemonic; use `&&` to display a literal ampersand. Pressing **Alt+** the marked character moves the focus to the next control in tab order — the frame does not take focus itself. +The text in [**Caption**](#caption) is rendered along the top edge of the border by the standard Win32 group-box style. An ampersand in the caption marks the next character as a keyboard mnemonic; use `&&` to display a literal ampersand. Pressing **Alt+** the marked character moves the focus to the next control in tab order --- the frame does not take focus itself. -[**BorderStyle**](#borderstyle) chooses between the standard captioned single-line border (**vbFixedSingleBorder**, the default) and a borderless mode (**vbNoBorder**). In **vbNoBorder** mode the standard group-box rendering is bypassed entirely — neither the line nor the caption text is drawn — and the frame becomes a plain rectangular region. [**Appearance**](#appearance) further selects between the 3-D and flat variant of the standard border. +[**BorderStyle**](#borderstyle) chooses between the standard captioned single-line border (**vbFixedSingleBorder**, the default) and a borderless mode (**vbNoBorder**). In **vbNoBorder** mode the standard group-box rendering is bypassed entirely --- neither the line nor the caption text is drawn --- and the frame becomes a plain rectangular region. [**Appearance**](#appearance) further selects between the 3-D and flat variant of the standard border. ## OptionButton groups @@ -58,14 +58,14 @@ Each frame defines its own option-button group. When the user selects an [**Opti ## Transparency and opacity -[**Opacity**](#opacity) and [**TransparencyKey**](#transparencykey) enable Windows' layered-window features. Setting [**Opacity**](#opacity) below 100 makes the frame and its contained controls translucent; setting [**TransparencyKey**](#transparencykey) to a colour makes pixels of that colour fully transparent on screen. Both features require Windows 8 or later when the frame contains child controls — otherwise only the frame's own background is affected. +[**Opacity**](#opacity) and [**TransparencyKey**](#transparencykey) enable Windows' layered-window features. Setting [**Opacity**](#opacity) below 100 makes the frame and its contained controls translucent; setting [**TransparencyKey**](#transparencykey) to a colour makes pixels of that colour fully transparent on screen. Both features require Windows 8 or later when the frame contains child controls --- otherwise only the frame's own background is affected. ## Properties ### Anchors {: .no_toc } -The set of edges of the parent that the frame's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the frame's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Appearance {: .no_toc } @@ -80,7 +80,7 @@ The background colour of the frame's client area, as an **OLE_COLOR**. Defaults ### BorderStyle {: .no_toc } -The style of the frame's border. A member of [**ControlBorderStyleConstants**](../../VBRUN/Constants/ControlBorderStyleConstants): **vbFixedSingleBorder** (1, default — the captioned group-box line) or **vbNoBorder** (0). With **vbNoBorder** the caption is also suppressed and the frame becomes a borderless background panel. +The style of the frame's border. A member of [**ControlBorderStyleConstants**](../../VBRUN/Constants/ControlBorderStyleConstants): **vbFixedSingleBorder** (1, default --- the captioned group-box line) or **vbNoBorder** (0). With **vbNoBorder** the caption is also suppressed and the frame becomes a borderless background panel. ### Caption {: .no_toc } @@ -89,7 +89,7 @@ The text rendered along the top edge of the frame's border. **String**. **Defaul Syntax: *object*.**Caption** [ = *string* ] -An ampersand marks the next character as a mnemonic; `&&` produces a literal ampersand. The string is read directly from the underlying window — assigning to **Caption** updates the rendering immediately. +An ampersand marks the next character as a mnemonic; `&&` produces a literal ampersand. The string is read directly from the underlying window --- assigning to **Caption** updates the rendering immediately. ### ClipControls {: .no_toc } @@ -99,7 +99,7 @@ Whether child controls are clipped out of the frame's drawing region during pain ### Container {: .no_toc } -The control that hosts this frame — typically the form, or another frame. Read with **Get**, change with **Set**. Setting **Container** re-parents the frame to a different container at run time. +The control that hosts this frame --- typically the form, or another frame. Read with **Get**, change with **Set**. Setting **Container** re-parents the frame to a different container at run time. ### ControlType {: .no_toc } @@ -119,7 +119,7 @@ A **StdPicture** used as the mouse cursor while the frame is being drag-and-drop ### DragMode {: .no_toc } -Whether the frame should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the frame should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -224,7 +224,7 @@ How the frame responds to OLE drops. A restricted member of [**OLEDropConstants* ### Opacity {: .no_toc } -The frame's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Values below 100 require Windows 8 or later when the frame has child controls; out-of-process child windows are not affected. +The frame's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Values below 100 require Windows 8 or later when the frame has child controls; out-of-process child windows are not affected. ### OriginalMultiFramePosition {: .no_toc } @@ -265,7 +265,7 @@ The vertical distance from the top of the container to the top of the frame. **D ### TransparencyKey {: .no_toc } -An **OLE_COLOR** that, when set, becomes fully transparent in the rendered frame — clicks pass through to whatever is underneath, and the corresponding pixels do not paint. Default `-1` disables the effect. Requires Windows 8 or later when the frame has child controls. +An **OLE_COLOR** that, when set, becomes fully transparent in the rendered frame --- clicks pass through to whatever is underneath, and the corresponding pixels do not paint. Default `-1` disables the effect. Requires Windows 8 or later when the frame has child controls. ### Visible {: .no_toc } diff --git a/docs/Reference/VB/Global/index.md b/docs/Reference/VB/Global/index.md index f9ac195c..d0aa5932 100644 --- a/docs/Reference/VB/Global/index.md +++ b/docs/Reference/VB/Global/index.md @@ -8,7 +8,7 @@ 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. +**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. @@ -29,19 +29,19 @@ Unload Form1 [**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. +- [**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. +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**](#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. +- **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: @@ -52,7 +52,7 @@ For Each f In Forms 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: +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 @@ -65,16 +65,16 @@ Next 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. +- [**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. +[**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. +[**Load**](#load) creates a form (or, for control arrays, a control instance) without showing it; [**Unload**](#unload) destroys it. 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 @@ -85,12 +85,12 @@ The compile-time `FEATURE_PRINTER` flag exposes the **Printer** and **Printers** ### App {: .no_toc } -The application's singleton [**App**](../App/) instance — its identity, version, and process-state metadata. Read-only. +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. +The application's singleton [**Clipboard**](../Clipboard/) instance --- the system clipboard wrapper. Read-only. ### Forms {: .no_toc } @@ -100,7 +100,7 @@ The application's live collection of currently-loaded [**Form**](../Form/) insta ### Printer {: .no_toc } -The currently-selected [**Printer**](../Printer/). Readable and assignable with `Set` — assigning a different printer object switches the application's current printer. +The currently-selected [**Printer**](../Printer/). Readable and assignable with `Set` --- assigning a different printer object switches the application's current printer. ### Printers {: .no_toc } @@ -110,7 +110,7 @@ The [**Printers**](../Printers/) collection of all installed printers on the sys ### Screen {: .no_toc } -The application's singleton [**Screen**](../Screen/) instance — primary-display metrics, active form/control, application-wide mouse pointer. Read-only. +The application's singleton [**Screen**](../Screen/) instance --- primary-display metrics, active form/control, application-wide mouse pointer. Read-only. ## Methods @@ -137,13 +137,13 @@ 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. +: *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. +: *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. +: *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. @@ -156,7 +156,7 @@ 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**. +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* ) @@ -174,7 +174,7 @@ Returns the list of resource IDs in the resource section of the given type, as a Syntax: **LoadResIdList**( *Type* ) *Type* -: *required* The resource type — see [**LoadResData**](#loadresdata). +: *required* The resource type --- see [**LoadResData**](#loadresdata). ### LoadResPicture {: .no_toc } @@ -184,10 +184,10 @@ Loads a picture, icon, or cursor resource from the application's resource sectio Syntax: **LoadResPicture**( *id*, *restype* [, *width* [, *height* ] ] ) *id* -: *required* The resource ID — **Long** (numeric) or **String** (name). +: *required* The resource ID --- **Long** (numeric) or **String** (name). *restype* -: *required* A member of [**LoadResConstants**](../../VBRUN/Constants/LoadResConstants) — **vbResBitmap**, **vbResIcon**, or **vbResCursor**. +: *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. @@ -205,7 +205,7 @@ Syntax: **LoadResString**( *id* ) ### 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. +Destroys 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* diff --git a/docs/Reference/VB/HScrollBar/index.md b/docs/Reference/VB/HScrollBar/index.md index f7e9fa82..3092c556 100644 --- a/docs/Reference/VB/HScrollBar/index.md +++ b/docs/Reference/VB/HScrollBar/index.md @@ -8,7 +8,7 @@ has_toc: false # HScrollBar class {: .no_toc } -An **HScrollBar** is a Win32 native horizontal scroll bar exposed as a stand-alone control. Unlike the scroll bars that automatically appear inside a [**ListBox**](../ListBox), [**ComboBox**](../ComboBox), or [**TextBox**](../TextBox), an **HScrollBar** is independent of any other control — its [**Value**](#value) is whatever your code reads or writes. The typical use is to drive a numeric setting (a volume level, a paginator, a colour channel, the offset of a custom-drawn surface) by binding the **HScrollBar**'s [**Change**](#change) and [**Scroll**](#scroll) events to whatever the value represents. +An **HScrollBar** is a Win32 native horizontal scroll bar exposed as a stand-alone control. Unlike the scroll bars that automatically appear inside a [**ListBox**](../ListBox), [**ComboBox**](../ComboBox), or [**TextBox**](../TextBox), an **HScrollBar** is independent of any other control --- its [**Value**](#value) is whatever code reads or writes. The typical use is to control a numeric setting (a volume level, a paginator, a colour channel, the offset of a custom-drawn surface) by binding the **HScrollBar**'s [**Change**](#change) and [**Scroll**](#scroll) events to whatever the value represents. [**VScrollBar**](../VScrollBar) is the vertical counterpart; the two classes are identical apart from orientation. @@ -39,7 +39,7 @@ End Sub [**Min**](#min) and [**Max**](#max) define the closed range of integer values the scroll bar can represent, and [**Value**](#value) is the position within that range. Defaults are `0`, `32767`, and `0`. Assigning a [**Value**](#value) outside the current `[Min, Max]` interval raises run-time error 380 (*Invalid property value*); assigning the current value is a no-op (no [**Change**](#change) is raised). -The two endpoints may be supplied in either order. When **Min** is greater than **Max** the scroll bar runs *inverted* — moving the thumb to the right decreases [**Value**](#value), and **Max** is the lower bound of the legal range. This is convenient for, for example, a "high-on-the-left" colour or zoom slider: +The two endpoints may be supplied in either order. When **Min** is greater than **Max** the scroll bar runs *inverted* --- moving the thumb to the right decreases [**Value**](#value), and **Max** is the lower bound of the legal range. This is convenient for, for example, a "high-on-the-left" colour or zoom slider: ```tb hsbZoom.Min = 400 ' leftmost == 4.00x @@ -47,7 +47,7 @@ hsbZoom.Max = 100 ' rightmost == 1.00x hsbZoom.Value = 100 ``` -Changing **Min** or **Max** at run time clips the current [**Value**](#value) into the new range silently — no [**Change**](#change) event is raised for the implicit clip. +Changing **Min** or **Max** at run time clips the current [**Value**](#value) into the new range silently --- no [**Change**](#change) event is raised for the implicit clip. ## Increment sizes @@ -64,14 +64,14 @@ Both [**SmallChange**](#smallchange) and [**LargeChange**](#largechange) default ## Change versus Scroll -The split between the two events lets the application choose how often it reacts to user input. [**Scroll**](#scroll) fires repeatedly while the user is dragging the thumb, so a handler can update a live preview as the thumb moves. [**Change**](#change) fires once each time the value settles — after the user releases the thumb, after a click on an arrow or the track, or whenever code assigns a different [**Value**](#value). Many applications wire both events to the same handler so that the bound display updates both during dragging and after. +The split between the two events lets the application choose how often it reacts to user input. [**Scroll**](#scroll) fires repeatedly while the user is dragging the thumb, so a handler can update a live preview as the thumb moves. [**Change**](#change) fires once each time the value settles --- after the user releases the thumb, after a click on an arrow or the track, or whenever code assigns a different [**Value**](#value). Many applications wire both events to the same handler so that the bound display updates both during dragging and after. ## Properties ### Anchors {: .no_toc } -The set of edges of the parent that the scroll bar's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the scroll bar's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### CausesValidation {: .no_toc } @@ -81,7 +81,7 @@ Determines whether the previously focused control's [**Validate**](#validate) ev ### Container {: .no_toc } -The control that hosts this scroll bar — typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. +The control that hosts this scroll bar --- typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. ### ControlType {: .no_toc } @@ -101,7 +101,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -111,7 +111,7 @@ Determines whether the scroll bar accepts user input. A disabled scroll bar is g ### Height {: .no_toc } -The scroll bar's height in twips (or in the container's **ScaleMode** units). **Double**. For a horizontal scroll bar this is the small dimension — typically the OS standard scroll-bar thickness; values larger than that simply enlarge the surrounding hit area. +The scroll bar's height in twips (or in the container's **ScaleMode** units). **Double**. For a horizontal scroll bar this is the small dimension --- typically the OS standard scroll-bar thickness; values larger than that simply enlarge the surrounding hit area. ### HelpContextID {: .no_toc } @@ -141,7 +141,7 @@ The horizontal distance from the left edge of the container to the left edge of ### Max {: .no_toc } -The upper end of the scroll bar's value range. **Long**, default `32767`. May be set lower than [**Min**](#min) to invert the direction of travel — see [Range and value](#range-and-value). +The upper end of the scroll bar's value range. **Long**, default `32767`. May be set lower than [**Min**](#min) to invert the direction of travel --- see [Range and value](#range-and-value). Syntax: *object*.**Max** [ = *value* ] @@ -174,7 +174,7 @@ The unique design-time name of the control on its parent form. Read-only at run ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -247,7 +247,7 @@ A **Long** identifying a "What's This?" help-pop-up topic in the application's h ### Width {: .no_toc } -The scroll bar's width — i.e., the length of the track. **Double**. +The scroll bar's width --- i.e., the length of the track. **Double**. ## Methods @@ -298,7 +298,7 @@ Syntax: *object*.**ShowWhatsThis** ### SyncScrollBar {: .no_toc } -Re-applies the current [**Min**](#min), [**Max**](#max), [**LargeChange**](#largechange), and [**Value**](#value) to the underlying Win32 scroll bar. Property assignments already do this implicitly — call **SyncScrollBar** only when external code (typically a Win32 API call) has reached around the control and changed its native state. +Re-applies the current [**Min**](#min), [**Max**](#max), [**LargeChange**](#largechange), and [**Value**](#value) to the underlying Win32 scroll bar. Property assignments already do this implicitly --- call **SyncScrollBar** only when external code (typically a Win32 API call) has reached around the control and changed its native state. Syntax: *object*.**SyncScrollBar** @@ -317,7 +317,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Change {: .no_toc } -Raised after [**Value**](#value) settles on a new value — when the user releases the thumb after a drag, when the user clicks an arrow or the track, when the user presses **Home**, **End**, or an arrow key with focus on the scroll bar, or when code assigns a different [**Value**](#value). Not raised for the continuous updates that happen during a drag — see [**Scroll**](#scroll) for that. **Default event.** +Raised after [**Value**](#value) settles on a new value --- when the user releases the thumb after a drag, when the user clicks an arrow or the track, when the user presses **Home**, **End**, or an arrow key with focus on the scroll bar, or when code assigns a different [**Value**](#value). Not raised for the continuous updates that happen during a drag --- see [**Scroll**](#scroll) for that. **Default event.** Syntax: *object*\_**Change**( ) @@ -352,7 +352,7 @@ Syntax: *object*\_**Initialize**( ) ### KeyDown {: .no_toc } -Raised when the user presses any key while the control has focus. Note that the scroll bar already handles the arrow keys, **Page Up** / **Page Down**, and **Home** / **End** internally — but **KeyDown** still fires for them in addition to the resulting [**Change**](#change). +Raised when the user presses any key while the control has focus. Note that the scroll bar already handles the arrow keys, **Page Up** / **Page Down**, and **Home** / **End** internally --- but **KeyDown** still fires for them in addition to the resulting [**Change**](#change). Syntax: *object*\_**KeyDown**( *KeyCode* **As Integer**, *Shift* **As Integer** ) @@ -380,7 +380,7 @@ Syntax: *object*\_**LostFocus**( ) ### Scroll {: .no_toc } -Raised continuously while the user is dragging the thumb, once for each tick that produces a different [**Value**](#value). After the user releases the thumb, a single [**Change**](#change) event fires with the final value. Use **Scroll** when you want a live preview while the thumb is moving; use [**Change**](#change) when you want to react only to the final value. +Raised continuously while the user is dragging the thumb, once for each tick that produces a different [**Value**](#value). After the user releases the thumb, a single [**Change**](#change) event fires with the final value. **Scroll** is the right event for a live preview while the thumb is moving; [**Change**](#change) fires only the final value. Syntax: *object*\_**Scroll**( ) diff --git a/docs/Reference/VB/Image/index.md b/docs/Reference/VB/Image/index.md index 7c042263..34e38c98 100644 --- a/docs/Reference/VB/Image/index.md +++ b/docs/Reference/VB/Image/index.md @@ -8,7 +8,7 @@ has_toc: false # Image class {: .no_toc } -An **Image** is a windowless lightweight control for displaying a picture — a bitmap, JPEG, GIF, PNG, icon, cursor, or Windows metafile. It is the small, efficient alternative to [**PictureBox**](../PictureBox): no underlying Win32 window, no drawing surface, no child controls, no focus — just a rectangle on the parent that paints whatever is in [**Picture**](#picture). Image controls are ideal for logos, decorative artwork, custom-drawn buttons, glyph rows, and any other place where a heavy **PictureBox** would be overkill. +An **Image** is a windowless lightweight control for displaying a picture --- a bitmap, JPEG, GIF, PNG, icon, cursor, or Windows metafile. It is the small, efficient alternative to [**PictureBox**](../PictureBox): no underlying Win32 window, no drawing surface, no child controls, no focus --- just a rectangle on the parent that paints whatever is in [**Picture**](#picture). Image controls are ideal for logos, decorative artwork, custom-drawn buttons, glyph rows, and any other place where a heavy **PictureBox** would be overkill. The default property is [**Picture**](#picture) and the default event is [**Click**](#click). @@ -41,16 +41,16 @@ For anything that needs those, use [**PictureBox**](../PictureBox) instead. [**Stretch**](#stretch) is the master switch for sizing behaviour: -- **Stretch = False** (default): the picture is drawn at its natural pixel size and the **Image** auto-resizes itself to match every time a new [**Picture**](#picture) is assigned. The user may still resize the control manually — once that happens the picture is clipped or padded around the natural bounds (it is *not* re-stretched). +- **Stretch = False** (default): the picture is drawn at its natural pixel size and the **Image** auto-resizes itself to match every time a new [**Picture**](#picture) is assigned. The user may still resize the control manually --- once that happens the picture is clipped or padded around the natural bounds (it is *not* re-stretched). - **Stretch = True**: the picture is scaled to fill the **Image**'s rectangle. The resampling algorithm is chosen by [**StretchMode**](#stretchmode); aspect ratio is *not* preserved. -Metafiles (`vbPicTypeMetafile`, `vbPicTypeEMetafile`) are vector — they always scale to fit and the aspect ratio is preserved regardless of [**Stretch**](#stretch). +Metafiles (`vbPicTypeMetafile`, `vbPicTypeEMetafile`) are vector --- they always scale to fit and the aspect ratio is preserved regardless of [**Stretch**](#stretch). -[**PictureDpiScaling**](#picturedpiscaling), when **True**, multiplies the natural pixel dimensions by the current DPI scale factor before drawing — useful for keeping a logo the same physical size on a high-DPI monitor as on a 96-DPI one. +[**PictureDpiScaling**](#picturedpiscaling), when **True**, multiplies the natural pixel dimensions by the current DPI scale factor before drawing --- useful for keeping a logo the same physical size on a high-DPI monitor as on a 96-DPI one. ## Rotation -[**Angle**](#angle) rotates the rendered picture, in degrees, anti-clockwise around the top-left corner of the control's rectangle. `0` is the natural orientation; `90` is a quarter turn anti-clockwise; values between `0` and `360` give arbitrary rotations. The control's bounding rectangle does not change — large rotation angles can therefore push the visible picture outside the rectangle. Hit-testing for [**Click**](#click), [**MouseDown**](#mousedown), and the other mouse events still uses the unrotated rectangle. +[**Angle**](#angle) rotates the rendered picture, in degrees, anti-clockwise around the top-left corner of the control's rectangle. `0` is the natural orientation; `90` is a quarter turn anti-clockwise; values between `0` and `360` give arbitrary rotations. The control's bounding rectangle does not change --- large rotation angles can therefore push the visible picture outside the rectangle. Hit-testing for [**Click**](#click), [**MouseDown**](#mousedown), and the other mouse events still uses the unrotated rectangle. ## Border @@ -72,7 +72,7 @@ Setting [**DataSource**](#datasource) and [**DataField**](#datafield) connects t ### Anchors {: .no_toc } -The set of edges of the parent that the **Image**'s corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the **Image**'s corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Angle {: .no_toc } @@ -92,7 +92,7 @@ The style of border drawn around the rectangle. A member of [**ControlBorderStyl ### Container {: .no_toc } -The control that hosts this **Image** — typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. +The control that hosts this **Image** --- typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. ### ControlType {: .no_toc } @@ -139,7 +139,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself (the manual VB-drag form, distinct from OLE drag) when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself (the manual VB-drag form, distinct from OLE drag) when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -179,7 +179,7 @@ The unique design-time name of the control on its parent form. Read-only at run ### OLEDragMode {: .no_toc } -Whether an OLE drag is started automatically when the user begins dragging the **Image**. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default — application calls [**OLEDrag**](#oledrag)) or **vbOLEDragAutomatic** (1 — the framework copies the current [**Picture**](#picture) into the resulting **DataObject** automatically). +Whether an OLE drag is started automatically when the user begins dragging the **Image**. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default --- application calls [**OLEDrag**](#oledrag)) or **vbOLEDragAutomatic** (1 --- the framework copies the current [**Picture**](#picture) into the resulting **DataObject** automatically). ### OLEDropMode {: .no_toc } @@ -217,14 +217,14 @@ The resampling algorithm used when [**Stretch**](#stretch) is **True** and the p | Constant | Value | Algorithm | |---------------------------|-------|--------------------------------------------------------------------------| -| **vbStretchHalftone** | 0 | GDI `STRETCH_HALFTONE` (default — good general-purpose quality). | -| **vbStretchColorOnColor** | 1 | GDI `STRETCH_COLORONCOLOR` (fastest, lowest quality — nearest neighbour). | +| **vbStretchHalftone** | 0 | GDI `STRETCH_HALFTONE` (default --- good general-purpose quality). | +| **vbStretchColorOnColor** | 1 | GDI `STRETCH_COLORONCOLOR` (fastest, lowest quality --- nearest neighbour). | | **vbStretchLanczos8** | 2 | Custom Lanczos resampler with an 8-lobe kernel (highest quality, slowest). | | **vbStretchLanczos3** | 3 | Custom Lanczos resampler with a 3-lobe kernel (high quality). | | **vbStretchBicubic** | 4 | Custom bicubic resampler. | | **vbStretchBilinear** | 5 | Custom bilinear resampler. | -The Lanczos, bicubic, and bilinear modes only apply to bitmaps that actually need resizing — metafiles and unscaled bitmaps fall back to the GDI mode. +The Lanczos, bicubic, and bilinear modes only apply to bitmaps that actually need resizing --- metafiles and unscaled bitmaps fall back to the GDI mode. ### Tag {: .no_toc } @@ -262,7 +262,7 @@ The control's width, in twips by default (or in the container's **ScaleMode** un ### Drag {: .no_toc } -Begins, completes, or cancels a manual VB-style drag operation. Distinct from OLE drag — see [**OLEDrag**](#oledrag). +Begins, completes, or cancels a manual VB-style drag operation. Distinct from OLE drag --- see [**OLEDrag**](#oledrag). Syntax: *object*.**Drag** [ *Action* ] diff --git a/docs/Reference/VB/Label/index.md b/docs/Reference/VB/Label/index.md index cf9df81f..41e75ca2 100644 --- a/docs/Reference/VB/Label/index.md +++ b/docs/Reference/VB/Label/index.md @@ -8,7 +8,7 @@ has_toc: false # Label class {: .no_toc } -A **Label** is a windowless lightweight control for displaying read-only text. Labels are typically used as static captions next to input controls ("Name:", "Email:"), as status displays that code keeps up to date, or as keyboard-mnemonic anchors that route **Alt+** keystrokes to the next focusable control. Because the **Label** has no `hWnd` of its own, it is much cheaper than a [**TextBox**](../TextBox) configured to be read-only — but it is also non-interactive in the keyboard sense: it cannot take focus, raise key events, or be selected with the **TAB** key. +A **Label** is a windowless lightweight control for displaying read-only text. Labels are typically used as static captions next to input controls ("Name:", "Email:"), as status displays that code keeps up to date, or as keyboard-mnemonic anchors that route **Alt+** keystrokes to the next focusable control. Because the **Label** has no `hWnd` of its own, it is much cheaper than a [**TextBox**](../TextBox) configured to be read-only --- but it is also non-interactive in the keyboard sense: it cannot take focus, raise key events, or be selected with the **TAB** key. The default property is [**Caption**](#caption) and the default event is [**Click**](#click). @@ -39,7 +39,7 @@ For text the user can edit (or that needs to take focus), use [**TextBox**](../T ## Mnemonics and access keys -Labels do not take focus themselves, but they participate in keyboard-mnemonic routing. With [**UseMnemonic**](#usemnemonic) **True** (the default), an ampersand in [**Caption**](#caption) marks the next character as a mnemonic — pressing **Alt+** that character moves the focus to the *next focusable control in tab order* after the label. Use `&&` to display a literal ampersand. Set [**UseMnemonic**](#usemnemonic) to **False** to disable the special handling and have ampersands rendered verbatim. +Labels do not take focus themselves, but they participate in keyboard-mnemonic routing. With [**UseMnemonic**](#usemnemonic) **True** (the default), an ampersand in [**Caption**](#caption) marks the next character as a mnemonic --- pressing **Alt+** that character moves the focus to the *next focusable control in tab order* after the label. Use `&&` to display a literal ampersand. Set [**UseMnemonic**](#usemnemonic) to **False** to disable the special handling and have ampersands rendered verbatim. ```tb lblName.Caption = "&Name:" ' Alt+N → next control (typically txtName) @@ -63,7 +63,7 @@ The convention is to place the **Label** immediately before the control it capti ## Rotation -[**Angle**](#angle) rotates the rendered caption, in degrees, anti-clockwise around the top-left of the control's rectangle. `0` is the natural orientation, `90` is a quarter-turn anti-clockwise, and so on. The control's bounding rectangle does not change — large rotation angles can therefore push the visible text outside the rectangle. Hit-testing for [**Click**](#click) and the mouse events still uses the unrotated rectangle. +[**Angle**](#angle) rotates the rendered caption, in degrees, anti-clockwise around the top-left of the control's rectangle. `0` is the natural orientation, `90` is a quarter-turn anti-clockwise, and so on. The control's bounding rectangle does not change --- large rotation angles can therefore push the visible text outside the rectangle. Hit-testing for [**Click**](#click) and the mouse events still uses the unrotated rectangle. ## Border styles @@ -87,7 +87,7 @@ End With ## Background -[**BackStyle**](#backstyle) chooses between **vbBFOpaque** (default — paint [**BackColor**](#backcolor) under the caption) and **vbBFTransparent** (don't paint a background — whatever the parent has drawn shows through). Transparent labels are essential when overlaying captions on a [**PictureBox**](../PictureBox), an [**Image**](../Image/), or a custom-painted form background. New labels created in *report mode* default to **vbBFTransparent**. +[**BackStyle**](#backstyle) chooses between **vbBFOpaque** (default --- paint [**BackColor**](#backcolor) under the caption) and **vbBFTransparent** (don't paint a background --- whatever the parent has drawn shows through). Transparent labels are essential when overlaying captions on a [**PictureBox**](../PictureBox), an [**Image**](../Image/), or a custom-painted form background. New labels created in *report mode* default to **vbBFTransparent**. ## Data binding @@ -103,7 +103,7 @@ The horizontal placement of [**Caption**](#caption) within the label's rectangle ### Anchors {: .no_toc } -The set of edges of the parent that the label's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the label's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Angle {: .no_toc } @@ -128,7 +128,7 @@ The colour painted behind the caption when [**BackStyle**](#backstyle) is **vbBF ### BackStyle {: .no_toc } -Whether the label paints a background. A member of [**BackFillStyleConstants**](../../VBRUN/Constants/BackFillStyleConstants): **vbBFOpaque** (1, default — paint [**BackColor**](#backcolor)) or **vbBFTransparent** (0 — let whatever the parent has drawn show through). +Whether the label paints a background. A member of [**BackFillStyleConstants**](../../VBRUN/Constants/BackFillStyleConstants): **vbBFOpaque** (1, default --- paint [**BackColor**](#backcolor)) or **vbBFTransparent** (0 --- let whatever the parent has drawn show through). ### BorderCustomOptions {: .no_toc } @@ -152,7 +152,7 @@ An ampersand marks the next character as a mnemonic when [**UseMnemonic**](#usem ### Container {: .no_toc } -The control that hosts this label — typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. +The control that hosts this label --- typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. ### ControlType {: .no_toc } @@ -216,7 +216,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -342,7 +342,7 @@ A reference to the [**Form**](../Form/) (or **UserControl**) that ultimately con {: .no_toc } > [!NOTE] -> Reserved for compatibility with VB6; not currently implemented in twinBASIC. The label is non-focusable, so the value would only affect mnemonic-routing — that is currently controlled by the design-time Z-order instead. +> Reserved for compatibility with VB6; not currently implemented in twinBASIC. The label is non-focusable, so the value would only affect mnemonic-routing --- that is currently controlled by the design-time Z-order instead. ### Tag {: .no_toc } @@ -395,7 +395,7 @@ Whether the caption breaks into multiple lines at white-space when it would othe ### Drag {: .no_toc } -Begins, completes, or cancels a manual VB-style drag operation. Distinct from OLE drag — see [**OLEDrag**](#oledrag). +Begins, completes, or cancels a manual VB-style drag operation. Distinct from OLE drag --- see [**OLEDrag**](#oledrag). Syntax: *object*.**Drag** [ *Action* ] diff --git a/docs/Reference/VB/Line/index.md b/docs/Reference/VB/Line/index.md index f85503a4..fd3f620a 100644 --- a/docs/Reference/VB/Line/index.md +++ b/docs/Reference/VB/Line/index.md @@ -8,7 +8,7 @@ has_toc: false # Line class {: .no_toc } -A **Line** is a windowless lightweight control that draws a single straight line segment from one point to another on its container. It exists purely for visual presentation — to divide regions of a form, underline a heading, draw a leader to an annotation — and has no interactive elements of its own: no mouse events, no focus, no caption. +A **Line** is a windowless lightweight control that draws a single straight line segment from one point to another on its container. It exists purely for visual presentation --- to divide regions of a form, underline a heading, draw a leader to an annotation --- and has no interactive elements of its own: no mouse events, no focus, no caption. A **Line** is positioned by its two endpoints, [**X1**](#x1) / [**Y1**](#y1) and [**X2**](#x2) / [**Y2**](#y2), rather than by a `Left` / `Top` / `Width` / `Height` rectangle. The default property is [**Visible**](#visible) and the default event is [**Initialize**](#initialize). @@ -26,7 +26,7 @@ End Sub ## Endpoints -[**X1**](#x1) / [**Y1**](#y1) is one endpoint of the line; [**X2**](#x2) / [**Y2**](#y2) is the other. Coordinates are in the container's **ScaleMode** units (twips by default) and are measured from the top-left corner of the container's client area. The line is drawn between the two points regardless of which is "earlier" — swapping the endpoints does not change the result. +[**X1**](#x1) / [**Y1**](#y1) is one endpoint of the line; [**X2**](#x2) / [**Y2**](#y2) is the other. Coordinates are in the container's **ScaleMode** units (twips by default) and are measured from the top-left corner of the container's client area. The line is drawn between the two points regardless of which is "earlier" --- swapping the endpoints does not change the result. The control has no `Width` or `Height` of its own; the bounding rectangle is derived from the two endpoints. Resizing a **Line** at design time moves whichever endpoint is being dragged. @@ -34,15 +34,15 @@ The control has no `Width` or `Height` of its own; the bounding rectangle is der The line is drawn with a Win32 GDI pen whose appearance is controlled by: -- [**BorderColor**](#bordercolor) — the colour of the pen (defaults to the system window-text colour). -- [**BorderWidth**](#borderwidth) — the pen width in pixels (default `1`). -- [**BorderStyle**](#borderstyle) — the pen pattern, as a member of [**BorderStyleConstants**](../../VBRUN/Constants/BorderStyleConstants): **vbTransparent** (0), **vbBSSolid** (1, default), **vbBSDash** (2), **vbBSDot** (3), **vbBSDashDot** (4), **vbBSDashDotDot** (5), or **vbBSInsideSolid** (6). +- [**BorderColor**](#bordercolor) -- the colour of the pen (defaults to the system window-text colour). +- [**BorderWidth**](#borderwidth) -- the pen width in pixels (default `1`). +- [**BorderStyle**](#borderstyle) -- the pen pattern, as a member of [**BorderStyleConstants**](../../VBRUN/Constants/BorderStyleConstants): **vbTransparent** (0), **vbBSSolid** (1, default), **vbBSDash** (2), **vbBSDot** (3), **vbBSDashDot** (4), **vbBSDashDotDot** (5), or **vbBSInsideSolid** (6). GDI applies a hard limitation here: when [**BorderWidth**](#borderwidth) is greater than `1`, the OS forces a solid pen even if [**BorderStyle**](#borderstyle) requests a dashed or dotted pattern. Use width `1` if the pattern matters. ## Draw mode -[**DrawMode**](#drawmode) selects the raster operation that combines the pen with the destination pixels. A member of [**DrawModeConstants**](../../VBRUN/Constants/DrawModeConstants): **vbCopyPen** (default — opaque drawing) or one of the XOR / AND / NOT / merge variants. Non-default modes are mainly useful for "rubber-band" feedback drawn over an existing background — the same XOR you draw twice cancels itself out, restoring the original pixels. +[**DrawMode**](#drawmode) selects the raster operation that combines the pen with the destination pixels. A member of [**DrawModeConstants**](../../VBRUN/Constants/DrawModeConstants): **vbCopyPen** (default --- opaque drawing) or one of the XOR / AND / NOT / merge variants. Non-default modes are mainly useful for "rubber-band" feedback drawn over an existing background --- the same XOR applied twice cancels itself out, restoring the original pixels. ## No interaction @@ -68,12 +68,12 @@ The pen width, in pixels. **Long**, default `1`. Widths greater than `1` ignore ### Container {: .no_toc } -The control that hosts this line — typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. +The control that hosts this line --- typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. ### ControlType {: .no_toc } -A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstants) value identifying this control. The **Line** shares the **vbShape** constant with the [**Shape**](../Shape) control — both are windowless, points-based geometric primitives with no dedicated control-type identifier. +A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstants) value identifying this control. The **Line** shares the **vbShape** constant with the [**Shape**](../Shape) control --- both are windowless, points-based geometric primitives with no dedicated control-type identifier. ### DrawMode {: .no_toc } diff --git a/docs/Reference/VB/ListBox/index.md b/docs/Reference/VB/ListBox/index.md index 12ca6ab3..03f952b1 100644 --- a/docs/Reference/VB/ListBox/index.md +++ b/docs/Reference/VB/ListBox/index.md @@ -8,7 +8,7 @@ has_toc: false # ListBox class {: .no_toc } -A **ListBox** is a Win32 native control that displays a vertically-scrolling list of items, optionally laid out in multiple columns, from which the user picks one item — or any number of items, when [**MultiSelect**](#multiselect) is non-zero. Each item is a string, with an optional **LongPtr** value the application can store alongside it through [**ItemData**](#itemdata). The control is normally placed on a **Form** or **UserControl** at design time. The default property is [**Text**](#text) and the default event is [**Click**](#click). +A **ListBox** is a Win32 native control that displays a vertically-scrolling list of items, optionally laid out in multiple columns, from which the user picks one item --- or any number of items, when [**MultiSelect**](#multiselect) is non-zero. Each item is a string, with an optional **LongPtr** value the application can store alongside it through [**ItemData**](#itemdata). The control is normally placed on a **Form** or **UserControl** at design time. The default property is [**Text**](#text) and the default event is [**Click**](#click). ```tb Private Sub Form_Load() @@ -43,11 +43,11 @@ End Sub Changing **Style** at run time recreates the underlying window, preserving the items, [**ItemData**](#itemdata) values, current selection, scroll position, and (in checkbox mode) check states. [**Sorted**](#sorted), [**MultiSelect**](#multiselect), [**IntegralHeight**](#integralheight), and [**UseTabStops**](#usetabstops) recreate the window the same way. -[**MultiSelect**](#multiselect) is meaningful only with **vbListBoxStandard**. The other styles always behave as if **MultiSelect** were **vbMultiSelectNone** — the per-item toggle of **vbListBoxCheckbox** replaces the multi-selection feature, and the colour swatch is purely a display variant. +[**MultiSelect**](#multiselect) is meaningful only with **vbListBoxStandard**. The other styles always behave as if **MultiSelect** were **vbMultiSelectNone** --- the per-item toggle of **vbListBoxCheckbox** replaces the multi-selection feature, and the colour swatch is purely a display variant. ## Editing the list -Items are held inside the OS list-box control; the [**List**](#list) and [**ItemData**](#itemdata) arrays are projections onto that storage. Items are added with [**AddItem**](#additem), removed with [**RemoveItem**](#removeitem), and the whole list is cleared with [**Clear**](#clear). After each [**AddItem**](#additem) call, [**NewIndex**](#newindex) reports the position the item was inserted at — useful when [**Sorted**](#sorted) is **True** and the position is not predictable from the call. +Items are held inside the OS list-box control; the [**List**](#list) and [**ItemData**](#itemdata) arrays are projections onto that storage. Items are added with [**AddItem**](#additem), removed with [**RemoveItem**](#removeitem), and the whole list is cleared with [**Clear**](#clear). After each [**AddItem**](#additem) call, [**NewIndex**](#newindex) reports the position the item was inserted at --- useful when [**Sorted**](#sorted) is **True** and the position is not predictable from the call. ```tb List1.Sorted = True @@ -73,9 +73,9 @@ Assigning a string to [**Text**](#text) searches the list with an exact, case-in ## Multi-column display -When [**Columns**](#columns) is greater than zero, the OS lays the items out in that many side-by-side columns and gives the control a horizontal scroll bar instead of the usual vertical one. The column width is automatically set to the control's pixel width divided by [**Columns**](#columns) — assigning a new [**Width**](#width) does not re-divide the columns; you must reassign [**Columns**](#columns) to refresh the layout. +When [**Columns**](#columns) is greater than zero, the OS lays the items out in that many side-by-side columns and gives the control a horizontal scroll bar instead of the usual vertical one. The column width is automatically set to the control's pixel width divided by [**Columns**](#columns) --- assigning a new [**Width**](#width) does not re-divide the columns; reassign [**Columns**](#columns) to refresh the layout. -The single-column / multi-column distinction is fixed at the moment the underlying window is created. At run time, [**Columns**](#columns) can be raised or lowered between non-zero values to re-divide the same control, but switching between zero and non-zero raises run-time error 380 (*Invalid property value*). Set [**Columns**](#columns) to its desired non-zero value at design time when a multi-column layout is wanted. +The single-column / multi-column distinction is fixed at the moment the underlying window is created. At run time, [**Columns**](#columns) can be raised or lowered between non-zero values to re-divide the same control, but switching between zero and non-zero raises run-time error 380 (*Invalid property value*). A multi-column layout requires [**Columns**](#columns) to be assigned its non-zero value at design time. ## Checkbox style @@ -96,7 +96,7 @@ When [**OLEDragMode**](#oledragmode) is set to **vbOLEDragAutomatic**, dragging ### Anchors {: .no_toc } -The set of edges of the parent that the list box's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the list box's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Appearance {: .no_toc } @@ -130,7 +130,7 @@ Switching between zero and non-zero at run time raises run-time error 380 (*Inva ### Container {: .no_toc } -The control that hosts this list box — typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. +The control that hosts this list box --- typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. ### ControlType {: .no_toc } @@ -177,7 +177,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -229,7 +229,7 @@ Syntax: *object*.**ItemData**( *Index* ) [ = *value* ] *Index* : *required* A **Long** zero-based item position. -In **vbListBoxColorSwatch** mode, **ItemData** is read by the painting code as the **OLE_COLOR** to draw in the swatch — a typical use is to fill it with a list of palette colours and let the user pick one. In the other styles **ItemData** is purely application-defined. +In **vbListBoxColorSwatch** mode, **ItemData** is read by the painting code as the **OLE_COLOR** to draw in the swatch --- a typical use is to fill it with a list of palette colours from which the user selects one. In the other styles **ItemData** is purely application-defined. ```tb List1.AddItem "Highlight" @@ -246,7 +246,7 @@ The horizontal distance from the left edge of the container to the left edge of ### List {: .no_toc } -The text of an item, indexed by zero-based position. Setting **List(*Index*)** removes the existing item at that position and reinserts the new value at the same index — note that this can change the resulting position when [**Sorted**](#sorted) is **True**. +The text of an item, indexed by zero-based position. Setting **List(*Index*)** removes the existing item at that position and reinserts the new value at the same index --- note that this can change the resulting position when [**Sorted**](#sorted) is **True**. Syntax: *object*.**List**( *Index* ) [ = *string* ] @@ -261,7 +261,7 @@ The number of items in the list, as a **Long**. Read-only. ### ListIndex {: .no_toc } -The zero-based index of the focused item, or `-1` if no item is focused. **Long**. In multi-select modes the focused item and the selected items are independent — see [**Selected**](#selected). Assigning a value that differs from the current one focuses that item and raises [**Click**](#click). +The zero-based index of the focused item, or `-1` if no item is focused. **Long**. In multi-select modes the focused item and the selected items are independent --- see [**Selected**](#selected). Assigning a value that differs from the current one focuses that item and raises [**Click**](#click). ### MaxCheckboxSize {: .no_toc } @@ -281,7 +281,7 @@ The mouse cursor shown when the pointer is over the control. A member of [**Mous ### MultiSelect {: .no_toc } -The selection mode. A member of [**MultiSelectConstants**](../../VBRUN/Constants/MultiSelectConstants): **vbMultiSelectNone** (0, default — single selection), **vbMultiSelectSimple** (1 — each click toggles), or **vbMultiSelectExtended** (2 — **Shift** for ranges, **Ctrl** for individual toggles). Changing this at run time recreates the underlying window; the items, [**ItemData**](#itemdata) values, focused item, and (in **vbListBoxCheckbox** mode) check states are restored, but multi-item selections are not. Effective only in **vbListBoxStandard** mode — see [Style](#style). +The selection mode. A member of [**MultiSelectConstants**](../../VBRUN/Constants/MultiSelectConstants): **vbMultiSelectNone** (0, default --- single selection), **vbMultiSelectSimple** (1 --- each click toggles), or **vbMultiSelectExtended** (2 --- **Shift** for ranges, **Ctrl** for individual toggles). Changing this at run time recreates the underlying window; the items, [**ItemData**](#itemdata) values, focused item, and (in **vbListBoxCheckbox** mode) check states are restored, but multi-item selections are not. Effective only in **vbListBoxStandard** mode --- see [Style](#style). ### Name {: .no_toc } @@ -296,7 +296,7 @@ The zero-based index at which the most recent [**AddItem**](#additem) call inser ### OLEDragMode {: .no_toc } -Whether the control acts as an automatic OLE drag source. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default — call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1 — dragging an item starts an OLE drag whose **Text** data is the dragged item's text in single-select mode, or every selected item's text separated by **vbCrLf** in multi-select mode). +Whether the control acts as an automatic OLE drag source. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default --- call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1 --- dragging an item starts an OLE drag whose **Text** data is the dragged item's text in single-select mode, or every selected item's text separated by **vbCrLf** in multi-select mode). ### OLEDropMode {: .no_toc } @@ -306,7 +306,7 @@ How the control responds to OLE drops. A restricted member of [**OLEDropConstant ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -327,7 +327,7 @@ The number of items currently selected, as a **Long**. Read-only. Always `0` or ### Selected {: .no_toc } -The selection state of an individual item — or, in **vbListBoxCheckbox** mode, the check state. +The selection state of an individual item --- or, in **vbListBoxCheckbox** mode, the check state. Syntax: *object*.**Selected**( *Index* ) [ = *boolean* ] @@ -372,7 +372,7 @@ The text of the focused item, or an empty string when [**ListIndex**](#listindex Syntax: *object*.**Text** [ = *string* ] -Reading **Text** returns `List(ListIndex)` — reading it when no item is focused raises run-time error 5 (*Invalid procedure call or argument*). Setting **Text** searches the list for an exact, case-insensitive match (using `LB_FINDSTRINGEXACT`) and selects the matching item if found; if no item matches, [**ListIndex**](#listindex) is set to `-1` and the current selection is cleared. +Reading **Text** returns `List(ListIndex)` --- reading it when no item is focused raises run-time error 5 (*Invalid procedure call or argument*). Setting **Text** searches the list for an exact, case-insensitive match (using `LB_FINDSTRINGEXACT`) and selects the matching item if found; if no item matches, [**ListIndex**](#listindex) is set to `-1` and the current selection is cleared. ### ToolTipText {: .no_toc } @@ -422,7 +422,7 @@ When **True** (default), mouse-wheel notifications over the control raise the [* ### Width {: .no_toc } -The control's width. **Single**. In a multi-column layout, also determines the column width — see [Multi-column display](#multi-column-display). +The control's width. **Single**. In a multi-column layout, also determines the column width --- see [Multi-column display](#multi-column-display). ## Methods @@ -536,14 +536,14 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Click {: .no_toc } -Raised after the focused item changes — whether the user clicked a different entry, used the keyboard to move the focus, or code assigned a different value to [**ListIndex**](#listindex) or [**Selected**](#selected). Also raised when the previously selected item is cancelled (`LBN_SELCANCEL`). **Default event.** +Raised after the focused item changes --- whether the user clicked a different entry, used the keyboard to move the focus, or code assigned a different value to [**ListIndex**](#listindex) or [**Selected**](#selected). Also raised when the previously selected item is cancelled (`LBN_SELCANCEL`). **Default event.** Syntax: *object*\_**Click**( ) ### DblClick {: .no_toc } -Raised when the user double-clicks an entry. Typically used to act on the highlighted item — for example, opening it. +Raised when the user double-clicks an entry. Typically used to act on the highlighted item --- for example, opening it. Syntax: *object*\_**DblClick**( ) @@ -571,14 +571,14 @@ Syntax: *object*\_**GotFocus**( ) ### Initialize {: .no_toc } -Raised once, immediately after the underlying window is created and the design-time items have been added. New in twinBASIC — VB6 had no equivalent on this control. +Raised once, immediately after the underlying window is created and the design-time items have been added. New in twinBASIC --- VB6 had no equivalent on this control. Syntax: *object*\_**Initialize**( ) ### ItemCheck {: .no_toc } -Raised in **vbListBoxCheckbox** mode each time the check state of an item changes — whether the user clicked its check box, pressed **Space**, or code assigned to [**Selected**](#selected). Not raised in the other styles. +Raised in **vbListBoxCheckbox** mode each time the check state of an item changes --- whether the user clicked its check box, pressed **Space**, or code assigned to [**Selected**](#selected). Not raised in the other styles. Syntax: *object*\_**ItemCheck**( *Item* **As Integer** ) @@ -682,7 +682,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Scroll {: .no_toc } -Raised when the visible portion of the list scrolls — by the scroll bar, the keyboard, or (when [**WheelScrollEvent**](#wheelscrollevent) is **True**) the mouse wheel. The new offset can be read from [**TopIndex**](#topindex). +Raised when the visible portion of the list scrolls --- by the scroll bar, the keyboard, or (when [**WheelScrollEvent**](#wheelscrollevent) is **True**) the mouse wheel. The new offset can be read from [**TopIndex**](#topindex). Syntax: *object*\_**Scroll**( ) diff --git a/docs/Reference/VB/MDIForm/index.md b/docs/Reference/VB/MDIForm/index.md index 48213e41..d46fd2bf 100644 --- a/docs/Reference/VB/MDIForm/index.md +++ b/docs/Reference/VB/MDIForm/index.md @@ -8,7 +8,7 @@ has_toc: false # MDIForm class {: .no_toc } -An **MDIForm** is a top-level Win32 window that hosts an *MDI client area* — a recessed working surface in which one or more [**Form**](../Form/) instances marked as MDI children appear, each with its own caption bar inside the parent. A twinBASIC project may contain at most one MDI form. Unlike an ordinary [**Form**](../Form/), an MDIForm has no drawing surface, no font properties, and no graphics primitives — it is purely a frame for its children, plus a host for menus, toolbars, and (optionally) a single background [**Picture**](#picture) drawn behind the children. +An **MDIForm** is a top-level Win32 window that hosts an *MDI client area* --- a recessed working surface in which one or more [**Form**](../Form/) instances marked as MDI children appear, each with its own caption bar inside the parent. A twinBASIC project may contain at most one MDI form. Unlike an ordinary [**Form**](../Form/), an MDIForm has no drawing surface, no font properties, and no graphics primitives --- it is purely a frame for its children, plus a host for menus, toolbars, and (optionally) a single background [**Picture**](#picture) drawn behind the children. The default property is [**Controls**](#controls) and the default event is [**Load**](#load). @@ -58,7 +58,7 @@ An MDI child is any [**Form**](../Form/) whose **MDIChild** property is **True** [**ActiveForm**](#activeform) returns the currently focused child, or **Nothing** when no child is open. [**Activate**](#activate) and [**Deactivate**](#deactivate) on the MDI parent fire only when activation crosses the MDI group's outer boundary; activation moves *within* the group fire **Activate** / **Deactivate** on the affected child forms instead. -[**AutoShowChildren**](#autoshowchildren) decides what happens when an MDI child class is loaded but not explicitly shown — when **True** (default), the child is made visible automatically; when **False**, the child stays hidden until code calls **Show** on it. +[**AutoShowChildren**](#autoshowchildren) decides what happens when an MDI child class is loaded but not explicitly shown --- when **True** (default), the child is made visible automatically; when **False**, the child stays hidden until code calls **Show** on it. [**Arrange**](#arrange) lays the open children out in a single call: cascade, tile horizontally, tile vertically, or arrange the icons of minimised children along the bottom edge. @@ -71,19 +71,19 @@ mnuWindowArrangeIcons.Click => Me.Arrange vbArrangeIcons ## Window appearance -An MDIForm always uses the sizable border style — there is no [**BorderStyle**](../Form/#borderstyle) property, the title bar is always present, the system menu and minimise / maximise buttons are always shown, and the form always appears in the taskbar. [**Caption**](#caption) sets the title-bar text. [**Icon**](#icon) supplies the small/large icon used by the system menu, the taskbar, and Alt-Tab. [**WindowState**](#windowstate) ([**FormWindowStateConstants**](../../VBRUN/Constants/FormWindowStateConstants)) reads or sets normal / minimised / maximised state at run time. +An MDIForm always uses the sizable border style --- there is no [**BorderStyle**](../Form/#borderstyle) property, the title bar is always present, the system menu and minimise / maximise buttons are always shown, and the form always appears in the taskbar. [**Caption**](#caption) sets the title-bar text. [**Icon**](#icon) supplies the small/large icon used by the system menu, the taskbar, and Alt-Tab. [**WindowState**](#windowstate) ([**FormWindowStateConstants**](../../VBRUN/Constants/FormWindowStateConstants)) reads or sets normal / minimised / maximised state at run time. [**MinWidth**](#minwidth), [**MinHeight**](#minheight), [**MaxWidth**](#maxwidth), and [**MaxHeight**](#maxheight) constrain the *client area* in twips during interactive resizing. [**Moveable**](#moveable) decides whether the user can drag the form by its title bar. [**Opacity**](#opacity) and [**TransparencyKey**](#transparencykey) enable Windows' layered-window features for translucent forms and cut-out shapes. -[**BackColor**](#backcolor) paints the MDI client area's background — defaults to the system **vbApplicationWorkspace** colour rather than 3-D face. [**Picture**](#picture), when set, is drawn over **BackColor** as the client-area backdrop, scaled to fill the area for metafiles and centred at its natural size for bitmaps. [**PictureDpiScaling**](#picturedpiscaling) scales bitmaps by the current DPI factor before drawing. There is no on-screen drawing API on an MDIForm — the [**Cls**](../Form/#cls), [**Circle**](../Form/#circle), [**Line**](../Form/#line), [**PSet**](../Form/#pset), [**PaintPicture**](../Form/#paintpicture), and **Print** members of the **Form** interface raise run-time error 438 (*Object doesn't support this property or method*) when called on an MDIForm. +[**BackColor**](#backcolor) paints the MDI client area's background --- defaults to the system **vbApplicationWorkspace** colour rather than 3-D face. [**Picture**](#picture), when set, is drawn over **BackColor** as the client-area backdrop, scaled to fill the area for metafiles and centred at its natural size for bitmaps. [**PictureDpiScaling**](#picturedpiscaling) scales bitmaps by the current DPI factor before drawing. There is no on-screen drawing API on an MDIForm --- the [**Cls**](../Form/#cls), [**Circle**](../Form/#circle), [**Line**](../Form/#line), [**PSet**](../Form/#pset), [**PaintPicture**](../Form/#paintpicture), and **Print** members of the **Form** interface raise run-time error 438 (*Object doesn't support this property or method*) when called on an MDIForm. A vertical and a horizontal scroll bar appear automatically when an MDI child is moved or sized so that its rectangle extends beyond the visible client area; this is fixed at design time through the **ScrollBars** property of the MDI parent and is not exposed at run time. ## Menus and pop-ups -Menu structures designed at form-design time appear automatically in the MDIForm's title bar. When an MDI child is maximised, the child's own menu (if any) is merged into the parent's menu bar, replacing it for as long as the child stays maximised. The classic VB6 *window-list* feature — a menu sub-tree that lists every open MDI child for quick switching — is supported automatically when a [**Menu**](../Menu) on the MDIForm has its **WindowList** property set. +Menu structures designed at form-design time appear automatically in the MDIForm's title bar. When an MDI child is maximised, the child's own menu (if any) is merged into the parent's menu bar, replacing it for as long as the child stays maximised. The classic VB6 *window-list* feature --- a menu sub-tree that lists every open MDI child for quick switching --- is supported automatically when a [**Menu**](../Menu) on the MDIForm has its **WindowList** property set. [**PopUpMenu**](#popupmenu) displays one of the form's menus as a context-menu pop-up at a specified location, raising the menu's **Click** event when the user picks an item. @@ -95,7 +95,7 @@ End Sub ## Differences from Form -Because the MDIForm is a frame, not a drawing surface, the following members of the **Form** interface are *not* supported on it — accessing them raises run-time error 380 (properties) or 438 (methods): +Because the MDIForm is a frame, not a drawing surface, the following members of the **Form** interface are *not* supported on it --- accessing them raises run-time error 380 (properties) or 438 (methods): | Category | Members | |------------------------------|--------------------------------------------------------------------------------------| @@ -148,12 +148,12 @@ The title-bar text. **String**. Syntax: *object*.**Caption** [ = *string* ] -When an MDI child is maximised, Windows decorates **Caption** with the child's caption in square brackets — `Editor - [Untitled]` — and the application normally lets that decoration stay automatic by leaving **Caption** alone. +When an MDI child is maximised, Windows decorates **Caption** with the child's caption in square brackets --- `Editor - [Untitled]` --- and the application normally lets that decoration stay automatic by leaving **Caption** alone. ### Controls {: .no_toc } -The collection of every control hosted by this form, indexable by control name or zero-based position. **Default property.** Read-only — controls are added to the collection by the runtime, not by user code. The collection contains the form's menus, toolbars, status bars, and any aligned controls; MDI children are *not* members of this collection (they are independent top-level forms hosted in the MDI client area, accessible through [**ActiveForm**](#activeform) and the runtime's **Forms** collection). +The collection of every control hosted by this form, indexable by control name or zero-based position. **Default property.** Read-only --- controls are added to the collection by the runtime, not by user code. The collection contains the form's menus, toolbars, status bars, and any aligned controls; MDI children are *not* members of this collection (they are independent top-level forms hosted in the MDI client area, accessible through [**ActiveForm**](#activeform) and the runtime's **Forms** collection). ### ControlType {: .no_toc } @@ -271,7 +271,7 @@ How the form responds to OLE drops over its frame and client area. A restricted ### Opacity {: .no_toc } -The form's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Values below 100 cause the form to become a layered window; the open MDI children become translucent along with the parent. +The form's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Values below 100 cause the form to become a layered window; the open MDI children become translucent along with the parent. ### Picture {: .no_toc } @@ -292,17 +292,17 @@ When **True**, [**Picture**](#picture) is scaled by the current DPI factor befor ### ScaleHeight {: .no_toc } -The height of the MDI *client area* (the inset region that hosts the children), in twips. **Double**, read-only — assigning to it raises run-time error 383 (*'ScaleHeight' property is read-only*). +The height of the MDI *client area* (the inset region that hosts the children), in twips. **Double**, read-only --- assigning to it raises run-time error 383 (*'ScaleHeight' property is read-only*). ### ScaleWidth {: .no_toc } -The width of the MDI *client area*, in twips. **Double**, read-only — assigning to it raises run-time error 383. +The width of the MDI *client area*, in twips. **Double**, read-only --- assigning to it raises run-time error 383. ### StartUpPosition {: .no_toc } -How the form's initial position is determined the first time it is shown. A member of [**StartUpPositionConstants**](../../VBRUN/Constants/StartUpPositionConstants): **vbStartUpManual**, **vbStartUpOwner**, **vbStartUpScreen**, or **vbStartUpWindowsDefault** (default). Read-only at run time — set at design time. +How the form's initial position is determined the first time it is shown. A member of [**StartUpPositionConstants**](../../VBRUN/Constants/StartUpPositionConstants): **vbStartUpManual**, **vbStartUpOwner**, **vbStartUpScreen**, or **vbStartUpWindowsDefault** (default). Read-only at run time --- set at design time. ### TabFocusAutoSelect {: .no_toc } @@ -327,12 +327,12 @@ Whether the form sits in the always-on-top z-order layer. **Boolean**, read-only ### TransparencyKey {: .no_toc } -An **OLE_COLOR** that, when set, becomes fully transparent in the rendered form — clicks pass through to whatever is underneath, and the corresponding pixels do not paint. Default `-1` disables the effect. +An **OLE_COLOR** that, when set, becomes fully transparent in the rendered form --- clicks pass through to whatever is underneath, and the corresponding pixels do not paint. Default `-1` disables the effect. ### Visible {: .no_toc } -Whether the form is shown. **Boolean**, default **True**. Setting **Visible** to **True** when the form was hidden is equivalent to calling [**Show**](#show) **vbModeless**; setting it to **False** is equivalent to calling [**Hide**](#hide). MDI children remain bound to the parent regardless of visibility — hiding the parent hides every child as well. +Whether the form is shown. **Boolean**, default **True**. Setting **Visible** to **True** when the form was hidden is equivalent to calling [**Show**](#show) **vbModeless**; setting it to **False** is equivalent to calling [**Hide**](#hide). MDI children remain bound to the parent regardless of visibility --- hiding the parent hides every child as well. ### WhatsThisHelp {: .no_toc } @@ -359,12 +359,12 @@ Lays the open MDI children out in a single call. Syntax: *object*.**Arrange** *Arrangement* *Arrangement* -: *required* A member of [**FormArrangeConstants**](../../VBRUN/Constants/FormArrangeConstants): **vbCascade** (0), **vbTileHorizontal** (1), **vbTileVertical** (2), or **vbArrangeIcons** (3 — line up the icons of minimised children along the bottom of the client area). Other values raise run-time error 5 (*Invalid procedure call or argument*). +: *required* A member of [**FormArrangeConstants**](../../VBRUN/Constants/FormArrangeConstants): **vbCascade** (0), **vbTileHorizontal** (1), **vbTileVertical** (2), or **vbArrangeIcons** (3 --- line up the icons of minimised children along the bottom of the client area). Other values raise run-time error 5 (*Invalid procedure call or argument*). ### Close {: .no_toc } -Initiates the form's unload sequence — [**QueryUnload**](#queryunload), then [**Unload**](#unload), then [**Terminate**](#terminate) — preceded by the same sequence on every open MDI child. Either of the first two events on either the parent or any child can cancel the close by setting *Cancel* to non-zero. Equivalent to the language statement `Unload Me`. +Initiates the form's unload sequence --- [**QueryUnload**](#queryunload), then [**Unload**](#unload), then [**Terminate**](#terminate) --- preceded by the same sequence on every open MDI child. Either of the first two events on either the parent or any child can cancel the close by setting *Cancel* to non-zero. Equivalent to the language statement `Unload Me`. Syntax: *object*.**Close** @@ -429,7 +429,7 @@ Makes the form visible. Triggers [**Load**](#load) on the first call. Syntax: *object*.**Show** [ *Modal* [, *OwnerForm* ] ] *Modal* -: *optional* A member of [**FormShowConstants**](../../VBRUN/Constants/FormShowConstants): **vbModeless** (0, default — the call returns immediately) or **vbModal** (1). MDI parents are normally shown modeless; modal display is accepted but unusual. +: *optional* A member of [**FormShowConstants**](../../VBRUN/Constants/FormShowConstants): **vbModeless** (0, default --- the call returns immediately) or **vbModal** (1). MDI parents are normally shown modeless; modal display is accepted but unusual. *OwnerForm* : *optional* For modal shows, the form that is disabled while this form is up; defaults to the currently active form. @@ -444,7 +444,7 @@ Syntax: *object*.**ValidateControls** ### WhatsThisMode {: .no_toc } -Enters Windows' "What's This?" cursor mode — the next click on a control raises that control's help instead of activating it. [**WhatsThisHelp**](#whatsthishelp) must be **True**. +Enters Windows' "What's This?" cursor mode --- the next click on a control raises that control's help instead of activating it. [**WhatsThisHelp**](#whatsthishelp) must be **True**. Syntax: *object*.**WhatsThisMode** @@ -463,7 +463,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Activate {: .no_toc } -Raised when the MDI parent or any of its child forms becomes the active window in the application — typically right after [**Load**](#load) for the first show, and whenever activation returns to the MDI group from another window. +Raised when the MDI parent or any of its child forms becomes the active window in the application --- typically right after [**Load**](#load) for the first show, and whenever activation returns to the MDI group from another window. Syntax: *object*\_**Activate**( ) @@ -620,7 +620,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### QueryUnload {: .no_toc } -Raised before the form unloads, giving the application a chance to confirm or cancel the close. Setting *Cancel* to non-zero keeps the form (and all its open MDI children) open. When the MDI parent is closing, **QueryUnload** is raised on every open MDI child *before* it is raised on the parent — any child cancelling stops the cascade. +Raised before the form unloads, giving the application a chance to confirm or cancel the close. Setting *Cancel* to non-zero keeps the form (and all its open MDI children) open. When the MDI parent is closing, **QueryUnload** is raised on every open MDI child *before* it is raised on the parent --- any child cancelling stops the cascade. Syntax: *object*\_**QueryUnload**( *Cancel* **As Integer**, *UnloadMode* **As Integer** ) @@ -628,12 +628,12 @@ Syntax: *object*\_**QueryUnload**( *Cancel* **As Integer**, *UnloadMode* **As In : Set to non-zero (any non-zero value, conventionally **1**) to cancel the close. *UnloadMode* -: A member of [**QueryUnloadConstants**](../../VBRUN/Constants/QueryUnloadConstants) identifying what triggered the close — the close button, code, Windows shutdown, or the MDI parent closing. +: A member of [**QueryUnloadConstants**](../../VBRUN/Constants/QueryUnloadConstants) identifying what triggered the close --- the close button, code, Windows shutdown, or the MDI parent closing. ### Resize {: .no_toc } -Raised when the MDI parent is resized — by the user, by code, by the OS following a [**WindowState**](#windowstate) change, or by initial layout during the first show. The event fires on the parent only; MDI children receive their own **Resize** events when the client-area resize cascades to them. +Raised when the MDI parent is resized --- by the user, by code, by the OS following a [**WindowState**](#windowstate) change, or by initial layout during the first show. The event fires on the parent only; MDI children receive their own **Resize** events when the client-area resize cascades to them. Syntax: *object*\_**Resize**( ) diff --git a/docs/Reference/VB/Menu/index.md b/docs/Reference/VB/Menu/index.md index 9b64fa3f..06845705 100644 --- a/docs/Reference/VB/Menu/index.md +++ b/docs/Reference/VB/Menu/index.md @@ -8,7 +8,7 @@ has_toc: false # Menu class {: .no_toc } -A **Menu** is an item in a Win32 native menu — either a top-level entry on a [**Form**](../Form/)'s or [**MDIForm**](../MDIForm/)'s menu bar, an entry in a drop-down sub-menu, or a separator bar between groups of related commands. Menus are a non-windowed control: they have no [**Left**](#) / [**Top**](#) / [**Width**](#) / [**Height**](#), no font, and no mouse or keyboard events of their own — they are populated, structured, and bound to handlers at design time through the form's menu editor. +A **Menu** is an item in a Win32 native menu --- either a top-level entry on a [**Form**](../Form/)'s or [**MDIForm**](../MDIForm/)'s menu bar, an entry in a drop-down sub-menu, or a separator bar between groups of related commands. Menus are a non-windowed control: they have no [**Left**](#) / [**Top**](#) / [**Width**](#) / [**Height**](#), no font, and no mouse or keyboard events of their own --- they are populated, structured, and bound to handlers at design time through the form's menu editor. The default property is [**Enabled**](#enabled) and the default event is [**Click**](#click). @@ -34,7 +34,7 @@ End Sub [**Caption**](#caption) supplies the text drawn for the menu item. Two Caption values have special meaning: -- An ampersand (`&`) marks the next character as a keyboard mnemonic — pressing **Alt + that letter** while the menu is open invokes the item, and the letter is underlined in the rendered menu. Use `&&` to display a literal ampersand. +- An ampersand (`&`) marks the next character as a keyboard mnemonic --- pressing **Alt + that letter** while the menu is open invokes the item, and the letter is underlined in the rendered menu. Use `&&` to display a literal ampersand. - A Caption consisting of a single hyphen (`"-"`) renders the item as a horizontal separator bar between the surrounding entries. Separator items still receive their own [**Click**](#click) events if invoked programmatically, but the user cannot reach them with the keyboard or mouse. ```tb @@ -45,7 +45,7 @@ mnuFileSaveAs.Caption = "Save &As..." ' Alt+A ## Shortcut keys -[**ShortcutId**](#shortcutid) binds a keyboard accelerator to the menu item. It is typed as [**ShortcutConstants**](../../VBRUN/Constants/ShortcutConstants) — **vbShortcutNone** disables the accelerator, **vbShortcutCtrlS** binds **Ctrl+S**, and so on across the function-key, **Shift+**, and **Ctrl+** ranges. When set, the Win32 runtime appends the corresponding text after a tab character in the rendered Caption — `Save\tCtrl+S` — so the shortcut appears right-aligned in the menu, the conventional way. +[**ShortcutId**](#shortcutid) binds a keyboard accelerator to the menu item. It is typed as [**ShortcutConstants**](../../VBRUN/Constants/ShortcutConstants) --- **vbShortcutNone** disables the accelerator, **vbShortcutCtrlS** binds **Ctrl+S**, and so on across the function-key, **Shift+**, and **Ctrl+** ranges. When set, the Win32 runtime appends the corresponding text after a tab character in the rendered Caption --- `Save\tCtrl+S` --- so the shortcut appears right-aligned in the menu, the conventional way. ```tb mnuFileSave.ShortcutId = vbShortcutCtrlS @@ -79,7 +79,7 @@ End Sub ## Window list (MDI) -When the form hosting the menu is an [**MDIForm**](../MDIForm/), setting [**WindowList**](#windowlist) to **True** at design time turns this menu into the application's *Window* sub-menu — the runtime auto-populates it with one entry per open MDI child, marks the active child with a checkmark, and routes a click on any of those entries to **SetFocus** on the corresponding child. The application typically combines this with an explicit *Cascade* / *Tile* sub-menu that calls [**Arrange**](../MDIForm/#arrange) on the parent. +When the form hosting the menu is an [**MDIForm**](../MDIForm/), setting [**WindowList**](#windowlist) to **True** at design time turns this menu into the application's *Window* sub-menu --- the runtime auto-populates it with one entry per open MDI child, marks the active child with a checkmark, and routes a click on any of those entries to **SetFocus** on the corresponding child. The application typically combines this with an explicit *Cascade* / *Tile* sub-menu that calls [**Arrange**](../MDIForm/#arrange) on the parent. ## Properties @@ -145,7 +145,7 @@ The unique design-time name of the menu on its parent form. **String**, read-onl > [!NOTE] > Reserved for compatibility with VB6's ActiveX-document menu negotiation feature; not currently implemented in twinBASIC. -Typed as [**NegotiatePositionConstants**](../../VBRUN/Constants/NegotiatePositionConstants) (**vbNoNegotiate**, **vbLeft**, **vbMiddle**, **vbRight**) — VB6 used this to decide where a top-level menu should appear in the host application's menu bar when an ActiveX document was activated. +Typed as [**NegotiatePositionConstants**](../../VBRUN/Constants/NegotiatePositionConstants) (**vbNoNegotiate**, **vbLeft**, **vbMiddle**, **vbRight**) --- VB6 used this to decide where a top-level menu should appear in the host application's menu bar when an ActiveX document was activated. ### Parent {: .no_toc } @@ -155,7 +155,7 @@ A reference to the [**Form**](../Form/) (or [**MDIForm**](../MDIForm/) / **UserC ### Picture {: .no_toc } -A **StdPicture** drawn to the left of the caption. **twinBASIC extension** — VB6 menus could not display icons. Assigning **Nothing** removes the icon. Icons are converted to bitmaps internally; pass a bitmap directly to skip the conversion. Pair with [**IconSizeX**](#iconsizex) / [**IconSizeY**](#iconsizey) for multi-resolution `.ico` files. +A **StdPicture** drawn to the left of the caption. **twinBASIC extension** --- VB6 menus could not display icons. Assigning **Nothing** removes the icon. Icons are converted to bitmaps internally; pass a bitmap directly to skip the conversion. Pair with [**IconSizeX**](#iconsizex) / [**IconSizeY**](#iconsizey) for multi-resolution `.ico` files. Syntax: - *object*.**Picture** [ = *picture* ] @@ -165,19 +165,19 @@ Syntax: {: .no_toc } > [!NOTE] -> Hidden, read-only, and unused at run time — exists only to round-trip the raw shortcut text imported from VB6 `.frm` files. Use [**ShortcutId**](#shortcutid) to bind an accelerator. +> Hidden, read-only, and unused at run time --- exists only to round-trip the raw shortcut text imported from VB6 `.frm` files. Use [**ShortcutId**](#shortcutid) to bind an accelerator. ### ShortcutId {: .no_toc } -The keyboard accelerator bound to this menu item. A member of [**ShortcutConstants**](../../VBRUN/Constants/ShortcutConstants) — **vbShortcutNone** (no accelerator, default), **vbShortcutCtrlA** through **vbShortcutCtrlZ**, **vbShortcutF1** through **vbShortcutF12**, and the **Shift+**, **Ctrl+**, and **Shift+Ctrl+** function-key variants. When set, the matching shortcut text is appended to [**Caption**](#caption) (after a tab) when the menu is rendered. +The keyboard accelerator bound to this menu item. A member of [**ShortcutConstants**](../../VBRUN/Constants/ShortcutConstants) --- **vbShortcutNone** (no accelerator, default), **vbShortcutCtrlA** through **vbShortcutCtrlZ**, **vbShortcutF1** through **vbShortcutF12**, and the **Shift+**, **Ctrl+**, and **Shift+Ctrl+** function-key variants. When set, the matching shortcut text is appended to [**Caption**](#caption) (after a tab) when the menu is rendered. Syntax: *object*.**ShortcutId** [ = *value* ] ### Tag {: .no_toc } -A free-form **String** the application can use to associate custom data with the menu item. Ignored by the framework. Inherited from the base control class. Useful for control arrays — e.g. holding the file path that an MRU-list entry should open. +A free-form **String** the application can use to associate custom data with the menu item. Ignored by the framework. Inherited from the base control class. Useful for control arrays --- e.g. holding the file path that an MRU-list entry should open. ### Visible {: .no_toc } @@ -189,14 +189,14 @@ Syntax: *object*.**Visible** [ = *boolean* ] ### WindowList {: .no_toc } -When **True** on a menu hosted by an [**MDIForm**](../MDIForm/), turns this menu into the application's *Window* sub-menu — the runtime auto-populates it with one entry per open MDI child and routes the resulting click to **SetFocus** on the corresponding child. **Boolean**, read-only at run time — set at design time. At most one menu per MDI form should have **WindowList** set. +When **True** on a menu hosted by an [**MDIForm**](../MDIForm/), turns this menu into the application's *Window* sub-menu --- the runtime auto-populates it with one entry per open MDI child and routes the resulting click to **SetFocus** on the corresponding child. **Boolean**, read-only at run time --- set at design time. At most one menu per MDI form should have **WindowList** set. ## Methods ### Container {: .no_toc } -Returns a reference to the **Control** that hosts this menu — typically the [**Form**](../Form/) or [**MDIForm**](../MDIForm/) that owns the menu structure. Equivalent to traversing [**Parent**](#parent) for a top-level menu, but defined on every menu (including sub-items) so it can be called uniformly. +Returns a reference to the **Control** that hosts this menu --- typically the [**Form**](../Form/) or [**MDIForm**](../MDIForm/) that owns the menu structure. Equivalent to traversing [**Parent**](#parent) for a top-level menu, but defined on every menu (including sub-items) so it can be called uniformly. Syntax: *object*.**Container** @@ -205,7 +205,7 @@ Syntax: *object*.**Container** ### Click {: .no_toc } -Raised when the user picks the menu item — by clicking it, pressing its mnemonic while the menu is open, or pressing its [**ShortcutId**](#shortcutid) accelerator. Also raised when [**PopUpMenu**](../Form/#popupmenu) selects an item. **Default event.** +Raised when the user picks the menu item --- by clicking it, pressing its mnemonic while the menu is open, or pressing its [**ShortcutId**](#shortcutid) accelerator. Also raised when [**PopUpMenu**](../Form/#popupmenu) selects an item. **Default event.** Syntax: *object*\_**Click**( ) diff --git a/docs/Reference/VB/MultiFrame/index.md b/docs/Reference/VB/MultiFrame/index.md index d93e1626..d9fbb12d 100644 --- a/docs/Reference/VB/MultiFrame/index.md +++ b/docs/Reference/VB/MultiFrame/index.md @@ -37,19 +37,19 @@ End Sub ## Direction and sizing -[**Direction**](#direction) chooses between **vbDirectionHorizontal** (the default — frames laid out left-to-right) and **vbDirectionVertical** (frames stacked top-to-bottom). Changing **Direction** at run time triggers an immediate re-layout. +[**Direction**](#direction) chooses between **vbDirectionHorizontal** (the default --- frames laid out left-to-right) and **vbDirectionVertical** (frames stacked top-to-bottom). Changing **Direction** at run time triggers an immediate re-layout. -For each contained frame, [**MultiFrameSize**](../Frame#multiframesize) gives its extent as a percentage of the **MultiFrame**'s width (horizontal) or height (vertical). Frames whose **MultiFrameSize** is `0` share the leftover extent equally — so a typical pattern is to give the edge panels fixed percentages and leave one centre panel at `0` so it absorbs window resizes. Percentages are not clamped; if the fixed-size frames already exceed the **MultiFrame**'s extent the auto-sized frames collapse to zero. +For each contained frame, [**MultiFrameSize**](../Frame#multiframesize) gives its extent as a percentage of the **MultiFrame**'s width (horizontal) or height (vertical). Frames whose **MultiFrameSize** is `0` share the leftover extent equally --- so a typical pattern is to give the edge panels fixed percentages and leave one centre panel at `0` so it absorbs window resizes. Percentages are not clamped; if the fixed-size frames already exceed the **MultiFrame**'s extent the auto-sized frames collapse to zero. ## Position and shuffling -Each contained frame is anchored to a sequential position via its [**MultiFramePosition**](../Frame#multiframeposition) property (zero-based). Positions are kept contiguous: assigning a frame a new **MultiFramePosition** at run time makes the **MultiFrame** shuffle the remaining frames up or down so that the old slot closes and the new slot opens at the requested index. Duplicate or out-of-range positions are normalised at the next layout pass — the **MultiFrame** falls back to the original control order on the parent form, renumbering the frames sequentially from `0`. +Each contained frame is anchored to a sequential position via its [**MultiFramePosition**](../Frame#multiframeposition) property (zero-based). Positions are kept contiguous: assigning a frame a new **MultiFramePosition** at run time makes the **MultiFrame** shuffle the remaining frames up or down so that the old slot closes and the new slot opens at the requested index. Duplicate or out-of-range positions are normalised at the next layout pass --- the **MultiFrame** falls back to the original control order on the parent form, renumbering the frames sequentially from `0`. A frame whose [**Container**](../Frame#container) is the **MultiFrame** but whose **MultiFramePosition** is `-1` is appended at the next free slot the first time the layout is built. ## Adopting frames at run time -The mapping from frame to **MultiFrame** is discovered from the parent form's control collection on each layout pass: a frame appears in the strip exactly when its [**Container**](../Frame#container) property points at the **MultiFrame**. The discovered set is then cached. To force the cache to be rebuilt — for example after re-parenting a frame at run time — assign any value to [**FramesCount**](#framescount): +The mapping from frame to **MultiFrame** is discovered from the parent form's control collection on each layout pass: a frame appears in the strip exactly when its [**Container**](../Frame#container) property points at the **MultiFrame**. The discovered set is then cached. To force the cache to be rebuilt --- for example after re-parenting a frame at run time --- assign any value to [**FramesCount**](#framescount): ```tb Set fraExtra.Container = mfPanels @@ -63,17 +63,17 @@ The **MultiFrame** repositions the frame's existing window in place; it does not ### Anchors {: .no_toc } -The set of edges of the parent that the **MultiFrame**'s corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the **MultiFrame**'s corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### BackColor {: .no_toc } -The background colour of the **MultiFrame**'s drawing surface, as an **OLE_COLOR**. Defaults to the system window-background colour. Visible only where the contained frames do not fully cover the extent — e.g. when their **MultiFrameSize**s sum to less than 100%. +The background colour of the **MultiFrame**'s drawing surface, as an **OLE_COLOR**. Defaults to the system window-background colour. Visible only where the contained frames do not fully cover the extent --- e.g. when their **MultiFrameSize**s sum to less than 100%. ### Container {: .no_toc } -The control that hosts this **MultiFrame** — typically the form. Read with **Get**, change with **Set**. Setting **Container** re-parents the **MultiFrame** to a different container at run time. +The control that hosts this **MultiFrame** --- typically the form. Read with **Get**, change with **Set**. Setting **Container** re-parents the **MultiFrame** to a different container at run time. ### ControlType {: .no_toc } @@ -83,7 +83,7 @@ A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstant ### Direction {: .no_toc } -The orientation in which contained frames are laid out. A member of **MultiFrameDirectionConstants**: **vbDirectionHorizontal** (0, default — frames laid out left-to-right) or **vbDirectionVertical** (1 — frames stacked top-to-bottom). Changing **Direction** triggers an immediate re-layout of the contained frames. +The orientation in which contained frames are laid out. A member of **MultiFrameDirectionConstants**: **vbDirectionHorizontal** (0, default --- frames laid out left-to-right) or **vbDirectionVertical** (1 --- frames stacked top-to-bottom). Changing **Direction** triggers an immediate re-layout of the contained frames. ### Dock {: .no_toc } @@ -97,7 +97,7 @@ The number of [**Frame**](../Frame) controls currently in the **MultiFrame**'s l Syntax: *object*.**FramesCount** [ = *value* ] -Reading **FramesCount** returns the size of the current layout cache. Assigning *any* value discards the cache so it is rebuilt on the next layout pass — the assigned number itself is ignored. Use the assignment as a manual refresh after re-parenting a frame at run time. +Reading **FramesCount** returns the size of the current layout cache. Assigning *any* value discards the cache so it is rebuilt on the next layout pass --- the assigned number itself is ignored. Use the assignment as a manual refresh after re-parenting a frame at run time. ### Height {: .no_toc } @@ -135,7 +135,7 @@ A reference to the [**Form**](../Form) that ultimately contains the **MultiFrame The position of the **MultiFrame** in the form's TAB-key navigation order. **Long**. > [!NOTE] -> A **MultiFrame** never takes the focus itself — **TabIndex** is preserved for compatibility but has no observable effect on the user. +> A **MultiFrame** never takes the focus itself --- **TabIndex** is preserved for compatibility but has no observable effect on the user. ### TabStop {: .no_toc } @@ -143,7 +143,7 @@ The position of the **MultiFrame** in the form's TAB-key navigation order. **Lon Whether the **MultiFrame** participates in TAB-key navigation. **Boolean**, default **True**. > [!NOTE] -> A **MultiFrame** never takes the focus itself — **TabStop** is preserved for compatibility but has no observable effect on the user. +> A **MultiFrame** never takes the focus itself --- **TabStop** is preserved for compatibility but has no observable effect on the user. ### Tag {: .no_toc } diff --git a/docs/Reference/VB/OLE/index.md b/docs/Reference/VB/OLE/index.md index cefbc2b8..48909462 100644 --- a/docs/Reference/VB/OLE/index.md +++ b/docs/Reference/VB/OLE/index.md @@ -8,10 +8,10 @@ has_toc: false # OLE class {: .no_toc } -An **OLE** *container* control hosts a linked or embedded OLE Automation object — typically a Word document, an Excel spreadsheet, or any other registered OLE server — directly on a form, and lets the user activate and edit the contained object in place via its registered verbs. +An **OLE** *container* control hosts a linked or embedded OLE Automation object --- typically a Word document, an Excel spreadsheet, or any other registered OLE server --- directly on a form, and lets the user activate and edit the contained object in place via its registered verbs. > [!NOTE] -> The OLE container control is a **VB6 compatibility stub** in twinBASIC. Almost every OLE-specific property, method, and event is currently unimplemented (each is flagged below). The inherited base-control members — positioning, sizing, anchoring, focus, drag, mouse cursor — do work normally, so a project ported from VB6 still parses and lays out the control on its form, but cannot create, embed, link, paste, save, or activate an actual OLE object through it. +> The OLE container control is a **VB6 compatibility stub** in twinBASIC. Almost every OLE-specific property, method, and event is currently unimplemented (each is flagged below). The inherited base-control members --- positioning, sizing, anchoring, focus, drag, mouse cursor --- do work normally, so a project ported from VB6 still parses and lays out the control on its form, but cannot create, embed, link, paste, save, or activate an actual OLE object through it. There is no default property. The default-designer event is [**Click**](#click). @@ -32,17 +32,17 @@ End Sub ## Linked vs embedded objects -An OLE container holds either a *linked* object — a reference to a document on disk that opens in its registered server when activated — or an *embedded* object whose data is stored inside the host form's data stream. [**CreateLink**](#createlink) creates a linked object from an existing file; [**CreateEmbed**](#createembed) creates a fresh embedded object of a given class. [**OLEType**](#oletype) reports which form the current contents take, and [**OLETypeAllowed**](#oletypeallowed) restricts which forms the container will accept at design or run time. +An OLE container holds either a *linked* object --- a reference to a document on disk that opens in its registered server when activated --- or an *embedded* object whose data is stored inside the host form's data stream. [**CreateLink**](#createlink) creates a linked object from an existing file; [**CreateEmbed**](#createembed) creates a fresh embedded object of a given class. [**OLEType**](#oletype) reports which form the current contents take, and [**OLETypeAllowed**](#oletypeallowed) restricts which forms the container will accept at design or run time. [**SourceDoc**](#sourcedoc) and [**SourceItem**](#sourceitem) identify the linked file (and, for partial links, the item within it). [**Class**](#class) holds the ProgID of the embedded server (e.g. `"Word.Document"`, `"Excel.Sheet"`). ## Verbs -Each OLE server registers a set of *verbs* — labelled actions like *Open*, *Edit*, or *Play*. [**FetchVerbs**](#fetchverbs) populates the per-instance verb list, exposed as the indexed [**ObjectVerbs**](#objectverbs), [**ObjectVerbFlags**](#objectverbflags), and [**ObjectVerbsCount**](#objectverbscount) properties. [**DoVerb**](#doverb) executes a verb by index — passing **vbOLEPrimary** runs the server's primary verb, which is the action invoked by a double-click. [**AutoVerbMenu**](#autoverbmenu) controls whether right-clicking the control automatically pops up the verb menu. +Each OLE server registers a set of *verbs* --- labelled actions like *Open*, *Edit*, or *Play*. [**FetchVerbs**](#fetchverbs) populates the per-instance verb list, exposed as the indexed [**ObjectVerbs**](#objectverbs), [**ObjectVerbFlags**](#objectverbflags), and [**ObjectVerbsCount**](#objectverbscount) properties. [**DoVerb**](#doverb) executes a verb by index --- passing **vbOLEPrimary** runs the server's primary verb, which is the action invoked by a double-click. [**AutoVerbMenu**](#autoverbmenu) controls whether right-clicking the control automatically pops up the verb menu. ## Activation and display -[**AutoActivate**](#autoactivate) chooses when the embedded object is activated for in-place editing — manually, on focus, or on a double-click. [**DisplayType**](#displaytype) selects between rendering the object's content directly and rendering a registered icon. [**SizeMode**](#sizemode) chooses how the object's bitmap is fitted into the container (clipped, stretched, auto-sized, or zoomed). +[**AutoActivate**](#autoactivate) chooses when the embedded object is activated for in-place editing --- manually, on focus, or on a double-click. [**DisplayType**](#displaytype) selects between rendering the object's content directly and rendering a registered icon. [**SizeMode**](#sizemode) chooses how the object's bitmap is fitted into the container (clipped, stretched, auto-sized, or zoomed). ## Updates and storage @@ -65,7 +65,7 @@ A run-time-only **Integer** that, when assigned, performs one of the predefined ### Anchors {: .no_toc } -The set of edges of the parent that the OLE control's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the OLE control's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Appearance {: .no_toc } @@ -134,12 +134,12 @@ Determines whether the previously focused control's [**Validate**](#validate) ev > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -The ProgID of the OLE server class for the contained object — for example `"Word.Document"` or `"Excel.Sheet"`. **String**. Used together with [**SourceDoc**](#sourcedoc) and [**SourceItem**](#sourceitem) when populating the container at design time, or as the default class for [**InsertObjDlg**](#insertobjdlg). +The ProgID of the OLE server class for the contained object --- for example `"Word.Document"` or `"Excel.Sheet"`. **String**. Used together with [**SourceDoc**](#sourcedoc) and [**SourceItem**](#sourceitem) when populating the container at design time, or as the default class for [**InsertObjDlg**](#insertobjdlg). ### Container {: .no_toc } -The control that hosts this OLE control — typically the form. Read with **Get**, change with **Set**. Setting **Container** re-parents the control to a different container at run time. +The control that hosts this OLE control --- typically the form. Read with **Get**, change with **Set**. Setting **Container** re-parents the control to a different container at run time. ### ControlType {: .no_toc } @@ -207,7 +207,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -249,7 +249,7 @@ A **Long** identifying a topic in the application's help file, retrieved when th > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -The friendly name the OLE server should display for the host application — e.g. shown in Word's title bar while editing the embedded document in place. **String**. +The friendly name the OLE server should display for the host application --- e.g. shown in Word's title bar while editing the embedded document in place. **String**. ### hWnd {: .no_toc } @@ -280,7 +280,7 @@ A run-time-only **LongPtr** giving the raw `IOleObject` interface pointer of the > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -A bit-mask of miscellaneous container behaviours (see [**OLEContainerConstants**](../../VBRUN/Constants/OLEContainerConstants) — **vbOLEMiscFlagMemStorage**, **vbOLEMiscFlagDisableInPlace**). **Long**. +A bit-mask of miscellaneous container behaviours (see [**OLEContainerConstants**](../../VBRUN/Constants/OLEContainerConstants) --- **vbOLEMiscFlagMemStorage**, **vbOLEMiscFlagDisableInPlace**). **Long**. ### MouseIcon {: .no_toc } @@ -303,7 +303,7 @@ The unique design-time name of the control on its parent form. Read-only at run > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -A run-time-only **Object** reference to the OLE Automation interface of the contained object — the late-bound entry point for scripting it. **Read-only**. +A run-time-only **Object** reference to the OLE Automation interface of the contained object --- the late-bound entry point for scripting it. **Read-only**. ### ObjectAcceptFormats {: .no_toc } @@ -351,7 +351,7 @@ An indexed **Long** property giving the menu-flag bit-mask for each entry in [** > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -An indexed **String** property listing the names of the verbs registered for the contained object — populated by [**FetchVerbs**](#fetchverbs). Pass an index to [**DoVerb**](#doverb) to invoke a verb. +An indexed **String** property listing the names of the verbs registered for the contained object --- populated by [**FetchVerbs**](#fetchverbs). Pass an index to [**DoVerb**](#doverb) to invoke a verb. ### ObjectVerbsCount {: .no_toc } @@ -375,7 +375,7 @@ When **True**, the container accepts OLE objects dragged onto it from outside th > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -A run-time-only **Integer** reporting whether the contained object is currently linked, embedded, or empty (see [**OLEContainerConstants**](../../VBRUN/Constants/OLEContainerConstants) — **vbOLELinked**, **vbOLEEmbedded**, **vbOLEEither**, **vbOLENone**). +A run-time-only **Integer** reporting whether the contained object is currently linked, embedded, or empty (see [**OLEContainerConstants**](../../VBRUN/Constants/OLEContainerConstants) --- **vbOLELinked**, **vbOLEEmbedded**, **vbOLEEither**, **vbOLENone**). ### OLETypeAllowed {: .no_toc } @@ -428,7 +428,7 @@ The full path of the source file used by [**CreateLink**](#createlink) (and the > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -The named item within [**SourceDoc**](#sourcedoc) that the link refers to — for example, an Excel range name. **String**. +The named item within [**SourceDoc**](#sourcedoc) that the link refers to --- for example, an Excel range name. **String**. ### TabIndex {: .no_toc } @@ -554,7 +554,7 @@ Syntax: *object*.**Delete** > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -Invokes a registered verb on the contained object. The standard verb constants are defined in [**OLEContainerConstants**](../../VBRUN/Constants/OLEContainerConstants) — **vbOLEPrimary** (0), **vbOLEShow** (-1), **vbOLEOpen** (-2), **vbOLEHide** (-3), **vbOLEUIActivate** (-4), **vbOLEInPlaceActivate** (-5), **vbOLEDiscardUndoState** (-6); positive indices refer to the per-server entries in [**ObjectVerbs**](#objectverbs). +Invokes a registered verb on the contained object. The standard verb constants are defined in [**OLEContainerConstants**](../../VBRUN/Constants/OLEContainerConstants) --- **vbOLEPrimary** (0), **vbOLEShow** (-1), **vbOLEOpen** (-2), **vbOLEHide** (-3), **vbOLEUIActivate** (-4), **vbOLEInPlaceActivate** (-5), **vbOLEDiscardUndoState** (-6); positive indices refer to the per-server entries in [**ObjectVerbs**](#objectverbs). Syntax: *object*.**DoVerb** [ *Verb* ] @@ -643,7 +643,7 @@ Syntax: *object*.**ReadFromFile** *FileNumber* > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -Writes the container's contents — including the linked or embedded object's data and any presentation cache — to a Basic-style binary file in the current OLE2 stream format. +Writes the container's contents --- including the linked or embedded object's data and any presentation cache --- to a Basic-style binary file in the current OLE2 stream format. Syntax: *object*.**SaveToFile** *FileNumber* @@ -832,7 +832,7 @@ Syntax: *object*\_**MouseUp**( *Button* **As Integer**, *Shift* **As Integer**, > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -Raised when the contained object asks the container to relocate or resize itself — typically in response to in-place editing changes. +Raised when the contained object asks the container to relocate or resize itself --- typically in response to in-place editing changes. Syntax: *object*\_**ObjectMove**( *Left* **As Single**, *Top* **As Single**, *Width* **As Single**, *Height* **As Single** ) @@ -842,7 +842,7 @@ Syntax: *object*\_**ObjectMove**( *Left* **As Single**, *Top* **As Single**, *Wi > [!NOTE] > Reserved for VB6 compatibility; not currently implemented in twinBASIC. -Raised when the contained object reports a new natural size — for example, after an embedded image is replaced with one of different dimensions. +Raised when the contained object reports a new natural size --- for example, after an embedded image is replaced with one of different dimensions. Syntax: *object*\_**Resize**( *HeightNew* **As Single**, *WidthNew* **As Single** ) diff --git a/docs/Reference/VB/OptionButton/index.md b/docs/Reference/VB/OptionButton/index.md index 869ac205..d7247927 100644 --- a/docs/Reference/VB/OptionButton/index.md +++ b/docs/Reference/VB/OptionButton/index.md @@ -30,7 +30,7 @@ End Sub ## Mutual exclusion -Setting [**Value**](#value) to **True** on one option button clears every other option button whose [**Container**](#container) is the same control — typically the parent form or a [**Frame**](../Frame). Option buttons in sibling frames are not affected, so a single form can host any number of independent groups: drop the buttons that belong to one group onto a frame, and the buttons that belong to a different group onto another frame (or directly onto the form). +Setting [**Value**](#value) to **True** on one option button clears every other option button whose [**Container**](#container) is the same control --- typically the parent form or a [**Frame**](../Frame). Option buttons in sibling frames are not affected, so a single form can host any number of independent groups: drop the buttons that belong to one group onto a frame, and the buttons that belong to a different group onto another frame (or directly onto the form). ```tb ' Two independent groups on one form: @@ -38,11 +38,11 @@ Setting [**Value**](#value) to **True** on one option button clears every other ' fraColour: optRed, optGreen, optBlue (children of fraColour) ``` -Setting [**Value**](#value) to **False** never deselects another button — there is no automatic *fallback* to a different option, so applications normally guarantee that exactly one button in each group is selected by setting one of them to **True** at start-up. Assigning **False** to the currently selected button leaves the group with no selection until the user (or code) selects another one. +Setting [**Value**](#value) to **False** never deselects another button --- there is no automatic *fallback* to a different option, so applications normally guarantee that exactly one button in each group is selected by setting one of them to **True** at start-up. Assigning **False** to the currently selected button leaves the group with no selection until the user (or code) selects another one. ## Click semantics -[**Click**](#click) is raised only when [**Value**](#value) transitions from **False** to **True** — whether the user clicked the button, pressed its access key, or assigned **True** in code. Re-clicking an already selected option button does nothing, and assigning **False** to a selected button does *not* raise [**Click**](#click). The event also does not fire while the form is loading; it starts firing once the control's [**Initialize**](#initialize) event has run. +[**Click**](#click) is raised only when [**Value**](#value) transitions from **False** to **True** --- whether the user clicked the button, pressed its access key, or assigned **True** in code. Re-clicking an already selected option button does nothing, and assigning **False** to a selected button does *not* raise [**Click**](#click). The event also does not fire while the form is loading; it starts firing once the control's [**Initialize**](#initialize) event has run. ## Caption and mnemonics @@ -67,12 +67,12 @@ Specifies the side of the selector on which the [**Caption**](#caption) text app Syntax: *object*.**Alignment** [ = *value* ] *value* -: A member of [**AlignmentConstantsNoCenter**](../../VBRUN/Constants/AlignmentConstantsNoCenter): **tbLeftJustify** (0, default — caption to the right of the selector) or **tbRightJustify** (1 — caption to the left of the selector). +: A member of [**AlignmentConstantsNoCenter**](../../VBRUN/Constants/AlignmentConstantsNoCenter): **tbLeftJustify** (0, default --- caption to the right of the selector) or **tbRightJustify** (1 --- caption to the left of the selector). ### Anchors {: .no_toc } -The set of edges of the parent that the option button's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the option button's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Appearance {: .no_toc } @@ -87,7 +87,7 @@ The background colour, as an **OLE_COLOR**. Defaults to the system 3-D face colo ### Caption {: .no_toc } -The text displayed next to the option button. An ampersand marks the next character as a mnemonic; `&&` produces a literal ampersand. The string is read directly from the underlying window — assigning to **Caption** is reflected immediately. +The text displayed next to the option button. An ampersand marks the next character as a mnemonic; `&&` produces a literal ampersand. The string is read directly from the underlying window --- assigning to **Caption** is reflected immediately. Syntax: *object*.**Caption** [ = *string* ] @@ -99,7 +99,7 @@ Determines whether the previously focused control's [**Validate**](#validate) ev ### Container {: .no_toc } -The control that hosts this option button — typically a [**Frame**](../Frame) or the parent form. Read with **Get**, change with **Set**. Setting **Container** at run time re-parents the option button into a different group; it is automatically excluded from the old group's mutual-exclusion set and included in the new one. +The control that hosts this option button --- typically a [**Frame**](../Frame) or the parent form. Read with **Get**, change with **Set**. Setting **Container** at run time re-parents the option button into a different group; it is automatically excluded from the old group's mutual-exclusion set and included in the new one. ### ControlType {: .no_toc } @@ -129,7 +129,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -200,7 +200,7 @@ How the control responds to OLE drops. A restricted member of [**OLEDropConstant ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Padding {: .no_toc } @@ -210,7 +210,7 @@ The number of pixels of empty space inserted between the picture and the caption ### Parent {: .no_toc } -A reference to the [**Form**](../Form) (or **UserControl**) that ultimately contains this control. Read-only. Distinct from [**Container**](#container), which returns the immediate parent — for an option button placed inside a [**Frame**](../Frame), **Container** returns the frame and **Parent** returns the form. +A reference to the [**Form**](../Form) (or **UserControl**) that ultimately contains this control. Read-only. Distinct from [**Container**](#container), which returns the immediate parent --- for an option button placed inside a [**Frame**](../Frame), **Container** returns the frame and **Parent** returns the form. ### Picture {: .no_toc } @@ -374,7 +374,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Click {: .no_toc } -Raised when [**Value**](#value) transitions from **False** to **True** — whether the user clicked the selector, pressed the access key, or assigned **True** in code. Not raised on the form's first display, on a click that doesn't change the value, or when **Value** is set to **False**. **Default event.** +Raised when [**Value**](#value) transitions from **False** to **True** --- whether the user clicked the selector, pressed the access key, or assigned **True** in code. Not raised on the form's first display, on a click that doesn't change the value, or when **Value** is set to **False**. **Default event.** Syntax: *object*\_**Click**( ) diff --git a/docs/Reference/VB/PictureBox/index.md b/docs/Reference/VB/PictureBox/index.md index 2656b4b8..a0a0b495 100644 --- a/docs/Reference/VB/PictureBox/index.md +++ b/docs/Reference/VB/PictureBox/index.md @@ -10,9 +10,9 @@ has_toc: false A **PictureBox** is a Win32 native control that combines three roles in one: -1. A **picture display** — it can show a bitmap, GIF, JPEG, icon, cursor, or metafile loaded into its [**Picture**](#picture) property. -2. A **drawing surface** — it exposes the VB6 graphics methods ([**Line**](#line), [**Circle**](#circle), [**PSet**](#pset), [**Print**](#print), [**PaintPicture**](#paintpicture), …) that write into the control's device context. -3. A **container** — it can host child controls dropped onto it at design time, much like a [**Frame**](../Frame), and can be docked or aligned within its parent. +1. A **picture display** --- it can show a bitmap, GIF, JPEG, icon, cursor, or metafile loaded into its [**Picture**](#picture) property. +2. A **drawing surface** --- it exposes the VB6 graphics methods ([**Line**](#line), [**Circle**](#circle), [**PSet**](#pset), [**Print**](#print), [**PaintPicture**](#paintpicture), …) that write into the control's device context. +3. A **container** --- it can host child controls dropped onto it at design time, much like a [**Frame**](../Frame), and can be docked or aligned within its parent. The control is normally placed on a [**Form**](../Form), [**Frame**](../Frame), or **UserControl** at design time. The default property is [**Picture**](#picture); the default-designer event is [**Click**](#click). @@ -35,7 +35,7 @@ End Sub Setting [**Picture**](#picture) assigns a **StdPicture** to the control. When [**AutoSize**](#autosize) is **True** the control resizes itself in its container's **ScaleMode** units to fit the picture exactly (plus a 1- or 2-pixel border, depending on [**Appearance**](#appearance)); otherwise the picture is drawn at its natural size, anchored at the top-left, and clipped to the control's bounds. Assigning **Nothing** to **Picture** clears the displayed image but does not erase anything drawn through the graphics methods. -The picture is read directly from the file passed to **LoadPicture**, or — when [**DataField**](#datafield) / [**DataSource**](#datasource) are set — from the bound recordset field. Anything assigned to **\_Default** (the control's default property) is forwarded to **Picture**. +The picture is read directly from the file passed to **LoadPicture**, or --- when [**DataField**](#datafield) / [**DataSource**](#datasource) are set --- from the bound recordset field. Anything assigned to **\_Default** (the control's default property) is forwarded to **Picture**. ## Drawing surface @@ -52,13 +52,13 @@ picCanvas.Print "Drawn over a Picture" ' text at the pen ## AutoRedraw and the persistent image -When [**AutoRedraw**](#autoredraw) is **False** (default) the graphics methods write directly into the visible device context, and the OS may erase that drawing whenever the control is uncovered, resized, or redrawn — typically the application redraws it from a [**Paint**](#paint) handler. +When [**AutoRedraw**](#autoredraw) is **False** (default) the graphics methods write directly into the visible device context, and the OS may erase that drawing whenever the control is uncovered, resized, or redrawn --- typically the application redraws it from a [**Paint**](#paint) handler. When [**AutoRedraw**](#autoredraw) is **True**, the graphics methods are recorded into an off-screen persistent bitmap that is automatically blitted onto the control whenever it needs repainting. The control no longer raises [**Paint**](#paint) events; the bitmap is exposed read-only through [**Image**](#image), suitable for saving with **SavePicture** or for assigning to another **PictureBox** or [**Image**](../Image) control. Toggling **AutoRedraw** from **False** to **True** preserves the current contents; toggling it back to **False** discards the persistent bitmap. ## Coordinate system -A **PictureBox** has its own coordinate system, independent of its parent. [**ScaleMode**](#scalemode) selects a built-in unit ([**ScaleModeConstants**](../../VBRUN/Constants/ScaleModeConstants) — **vbTwips**, **vbPoints**, **vbPixels**, **vbCharacters**, **vbInches**, **vbMillimeters**, **vbCentimeters**); assigning [**ScaleLeft**](#scaleleft), [**ScaleTop**](#scaletop), [**ScaleWidth**](#scalewidth), or [**ScaleHeight**](#scaleheight) (or calling [**Scale**](#scale) with two corner points) switches to **vbUser** and remaps the surface so the assigned values address the corners directly — useful for mathematical plots where the natural axes don't match pixel coordinates. +A **PictureBox** has its own coordinate system, independent of its parent. [**ScaleMode**](#scalemode) selects a built-in unit ([**ScaleModeConstants**](../../VBRUN/Constants/ScaleModeConstants) --- **vbTwips**, **vbPoints**, **vbPixels**, **vbCharacters**, **vbInches**, **vbMillimeters**, **vbCentimeters**); assigning [**ScaleLeft**](#scaleleft), [**ScaleTop**](#scaletop), [**ScaleWidth**](#scalewidth), or [**ScaleHeight**](#scaleheight) (or calling [**Scale**](#scale) with two corner points) switches to **vbUser** and remaps the surface so the assigned values address the corners directly --- useful for mathematical plots where the natural axes don't match pixel coordinates. [**ScaleX**](#scalex) and [**ScaleY**](#scaley) convert distances between any two scale modes without changing the active one. @@ -81,7 +81,7 @@ Setting [**DataSource**](#datasource) and [**DataField**](#datafield) binds the ### Anchors {: .no_toc } -The set of edges of the parent that the picture box's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the picture box's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Appearance {: .no_toc } @@ -121,7 +121,7 @@ When **True** (default), child controls are clipped out of the picture box's pai ### Container {: .no_toc } -The control that hosts this picture box — typically the form, a [**Frame**](../Frame), or another picture box. Read with **Get**, change with **Set**. Setting **Container** at run time re-parents the picture box. +The control that hosts this picture box --- typically the form, a [**Frame**](../Frame), or another picture box. Read with **Get**, change with **Set**. Setting **Container** at run time re-parents the picture box. ### ControlType {: .no_toc } @@ -176,12 +176,12 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### DrawMode {: .no_toc } -The raster operation used when drawing through the graphics methods. A member of [**DrawModeConstants**](../../VBRUN/Constants/DrawModeConstants), default **vbCopyPen** (13 — opaque overwrite). +The raster operation used when drawing through the graphics methods. A member of [**DrawModeConstants**](../../VBRUN/Constants/DrawModeConstants), default **vbCopyPen** (13 --- opaque overwrite). ### DrawStyle {: .no_toc } @@ -231,7 +231,7 @@ Shortcut for [**Font**](#font)`.Name`. **String**. ### FontSize {: .no_toc } -Shortcut for [**Font**](#font)`.Size` — the point size. **Single**. +Shortcut for [**Font**](#font)`.Size` --- the point size. **Single**. ### FontStrikethru {: .no_toc } @@ -281,7 +281,7 @@ The Win32 window handle for the picture box, as a **LongPtr**. Read-only. Useful ### Image {: .no_toc } -A read-only **StdPicture** giving the current contents of the picture box — both the assigned [**Picture**](#picture) *and* anything drawn into the surface — as a single bitmap, suitable for saving with **SavePicture**, copying to the clipboard, or assigning to another picture display. Available only when [**AutoRedraw**](#autoredraw) is **True**, or when the persistent bitmap is otherwise present. +A read-only **StdPicture** giving the current contents of the picture box --- both the assigned [**Picture**](#picture) *and* anything drawn into the surface --- as a single bitmap, suitable for saving with **SavePicture**, copying to the clipboard, or assigning to another picture display. Available only when [**AutoRedraw**](#autoredraw) is **True**, or when the persistent bitmap is otherwise present. ### Index {: .no_toc } @@ -343,12 +343,12 @@ The unique design-time name of the control on its parent form. Read-only at run ### OLEDragMode {: .no_toc } -How the picture box initiates OLE drag operations. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default — call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1, which starts a drag with the current [**Picture**](#picture) as the payload as soon as the user begins a drag with the mouse). +How the picture box initiates OLE drag operations. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default --- call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1, which starts a drag with the current [**Picture**](#picture) as the payload as soon as the user begins a drag with the mouse). ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -374,7 +374,7 @@ When **True**, [**Picture**](#picture) and the graphics-method outputs are scale ### ScaleHeight {: .no_toc } -The height of the drawing surface in [**ScaleMode**](#scalemode) units. **Double**. Read-write — assigning a value switches [**ScaleMode**](#scalemode) to **vbUser** and rescales the vertical axis so the control's client area spans the new value. +The height of the drawing surface in [**ScaleMode**](#scalemode) units. **Double**. Read-write --- assigning a value switches [**ScaleMode**](#scalemode) to **vbUser** and rescales the vertical axis so the control's client area spans the new value. ### ScaleLeft {: .no_toc } @@ -394,7 +394,7 @@ The Y coordinate that maps to the top edge of the drawing surface. **Double**, d ### ScaleWidth {: .no_toc } -The width of the drawing surface in [**ScaleMode**](#scalemode) units. **Double**. Read-write — assigning a value switches [**ScaleMode**](#scalemode) to **vbUser**. +The width of the drawing surface in [**ScaleMode**](#scalemode) units. **Double**. Read-write --- assigning a value switches [**ScaleMode**](#scalemode) to **vbUser**. ### TabIndex {: .no_toc } @@ -539,7 +539,7 @@ Draws a picture onto the surface, optionally scaling, clipping, or applying a ra Syntax: *object*.**PaintPicture** *Picture*, *X1*, *Y1* [, *Width1* [, *Height1* [, *X2* [, *Y2* [, *Width2* [, *Height2* [, *Opcode* [, *StretchQuality* ] ] ] ] ] ] ] ] *Picture* -: *required* An **IPictureDisp** to paint — typically the [**Picture**](#picture) or [**Image**](#image) of another picture display. +: *required* An **IPictureDisp** to paint --- typically the [**Picture**](#picture) or [**Image**](#image) of another picture display. *X1*, *Y1* : *required* Destination top-left in [**ScaleMode**](#scalemode) units. @@ -551,7 +551,7 @@ Syntax: *object*.**PaintPicture** *Picture*, *X1*, *Y1* [, *Width1* [, *Height1* : *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`). +: *optional* A raster-operation code passed through to **BitBlt** --- for example **&HCC0020** (`vbSrcCopy`, default) or **&H660046** (`vbSrcInvert`). *StretchQuality* : *optional* `vbStretchQuality` value: **vbQualityNormal** (default) or **vbQualityHigh** (uses half-tone stretching for nicer downscales). @@ -605,10 +605,10 @@ Defines a user coordinate system for the surface. Calling **Scale** with no argu 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). +: *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) is switched to **vbUser**. +: *required* The coordinate that maps to the bottom-right corner --- sets [**ScaleWidth**](#scalewidth) = `X2 - X1` and [**ScaleHeight**](#scaleheight) = `Y2 - Y1`. [**ScaleMode**](#scalemode) is switched to **vbUser**. ### ScaleX {: .no_toc } @@ -647,7 +647,7 @@ Syntax: *object*.**ShowWhatsThis** ### TextHeight {: .no_toc } -Measures the height, in [**ScaleMode**](#scalemode) units, of the given string when rendered in the current [**Font**](#font) — including the line-spacing leading, so the result is suitable for advancing [**CurrentY**](#currenty) between rows of text. Embedded line breaks are honoured. +Measures the height, in [**ScaleMode**](#scalemode) units, of the given string when rendered in the current [**Font**](#font) --- 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 Single** @@ -697,7 +697,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Change {: .no_toc } -Raised when [**Picture**](#picture) is assigned a new value — either from code or from the bound recordset. +Raised when [**Picture**](#picture) is assigned a new value --- either from code or from the bound recordset. Syntax: *object*\_**Change**( ) @@ -819,7 +819,7 @@ Syntax: *object*\_**MouseUp**( *Button* **As Integer**, *Shift* **As Integer**, ### MouseWheel {: .no_toc } -Raised when the user rotates the mouse wheel while the control has focus or the cursor is over it. New in twinBASIC — there is no equivalent VB6 event. +Raised when the user rotates the mouse wheel while the control has focus or the cursor is over it. New in twinBASIC --- there is no equivalent VB6 event. Syntax: *object*\_**MouseWheel**( *Delta* **As Integer**, *Horizontal* **As Boolean** ) @@ -874,7 +874,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Paint {: .no_toc } -Raised when the control needs to redraw its client area — typically because it was uncovered, resized, or [**Refresh**](#refresh) was called. Not raised while [**AutoRedraw**](#autoredraw) is **True**; the persistent bitmap is blitted instead. +Raised when the control needs to redraw its client area --- typically because it was uncovered, resized, or [**Refresh**](#refresh) was called. Not raised while [**AutoRedraw**](#autoredraw) is **True**; the persistent bitmap is blitted instead. Syntax: *object*\_**Paint**( ) diff --git a/docs/Reference/VB/Printer/index.md b/docs/Reference/VB/Printer/index.md index 24178189..b98146f7 100644 --- a/docs/Reference/VB/Printer/index.md +++ b/docs/Reference/VB/Printer/index.md @@ -20,7 +20,7 @@ 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. +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} @@ -38,7 +38,7 @@ Next By default the implicit **Printer** has [**TrackDefault**](#trackdefault) **True**: every property read consults the current system-default printer, so the application reflects 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**: +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") @@ -47,11 +47,11 @@ 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. +`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: +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 | |--------------------|----------------------------------------------------------------------------------------------------------| @@ -59,7 +59,7 @@ The methods that manage the job — [**EndDoc**](#enddoc), [**KillDoc**](#killdo | 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*). +[**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 @@ -72,7 +72,7 @@ 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. +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" @@ -219,7 +219,7 @@ The colour used by the drawing-method pen (lines, circles, points) and by [**Pri 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. +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 } @@ -254,7 +254,7 @@ 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. +: 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 } @@ -264,7 +264,7 @@ 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). +: 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 } @@ -279,7 +279,7 @@ 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. +: 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 } @@ -322,7 +322,7 @@ Setting **TrackDefault** to **False** captures the current default device into t ### TwipsPerPixelX {: .no_toc } -The number of twips that correspond to one device pixel, horizontally — useful for custom DPI-aware sizing. **Double**, read-only. +The number of twips that correspond to one device pixel, horizontally --- useful for custom DPI-aware sizing. **Double**, read-only. ### TwipsPerPixelY {: .no_toc } @@ -430,7 +430,7 @@ Syntax: *object*.**PaintPicture** *Picture*, *X1*, *Y1* [, *Width1* [, *Height1* : *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`). +: *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. @@ -466,10 +466,10 @@ Defines a user coordinate system for the page. Calling **Scale** with no argumen 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). +: *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**. +: *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. @@ -484,7 +484,7 @@ Syntax: *object*.**ScaleX**( *Width*, *FromScale* [, *ToScale* ] ) **As Double** : *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*). +: *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). @@ -499,7 +499,7 @@ 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. +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** @@ -512,7 +512,7 @@ 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. +- [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 index 74e71038..bbce6642 100644 --- a/docs/Reference/VB/Printers/index.md +++ b/docs/Reference/VB/Printers/index.md @@ -8,7 +8,7 @@ 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)`. +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 @@ -24,13 +24,13 @@ Set Printer = Printers("HP LaserJet") ' make this the active printer ## 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 running 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. +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 running 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** therefore appears 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: +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** therefore appears 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 @@ -43,21 +43,21 @@ Next 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*). +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). +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)`. +Returns the [**Printer**](../Printer/) at the given index. **Default property** --- `Printers(0)` is shorthand for `Printers.Item(0)`. Syntax: *object*.**Item**( *Index* ) **As Printer** @@ -66,4 +66,4 @@ Syntax: *object*.**Item**( *Index* ) **As Printer** ## See Also -- [Printer](../Printer/) — the printer object itself, and the implicit **Printer** global. +- [Printer](../Printer/) -- the printer object itself, and the implicit **Printer** global. diff --git a/docs/Reference/VB/PropertyPage/index.md b/docs/Reference/VB/PropertyPage/index.md index a54f3a4b..1aed7d14 100644 --- a/docs/Reference/VB/PropertyPage/index.md +++ b/docs/Reference/VB/PropertyPage/index.md @@ -8,7 +8,7 @@ has_toc: false # PropertyPage class {: .no_toc } -A **PropertyPage** is a container that backs a single tab of a COM property-page dialog — the popup invoked from the **(Custom)** entry on an ActiveX control's property browser. It exposes the **IPropertyPage2** COM interface so that any host that supports ActiveX property pages (the twinBASIC IDE, classic VB6, Office, …) can place it inside its own property-sheet frame, give it the controls the user is editing, and apply the page's changes back to them. +A **PropertyPage** is a container that backs a single tab of a COM property-page dialog --- the popup invoked from the **(Custom)** entry on an ActiveX control's property browser. It exposes the **IPropertyPage2** COM interface so that any host that supports ActiveX property pages (the twinBASIC IDE, classic VB6, Office, …) can place it inside its own property-sheet frame, give it the controls the user is editing, and apply the page's changes back to them. Designing a property page is much like designing a small dialog [**Form**](../Form): drop child controls onto it, write event handlers, and use its drawing surface freely. What sets it apart is the lifecycle, which is controlled by the host rather than by the application: @@ -47,7 +47,7 @@ End Sub [**SelectedControls**](#selectedcontrols) is a read-only collection of the controls the host wants this tab to edit. The host populates it before raising [**SelectionChanged**](#selectionchanged); the page keeps the references for as long as it is alive. The collection supports indexed access (`SelectedControls(0)`), enumeration (`For Each ctl In SelectedControls`), and a **Count** member. -[**Changed**](#changed) is a two-way flag the page uses to talk to the host. Setting it to **True** enables the host's *Apply* button; the framework notifies the host immediately through **IPropertyPageSite.OnStatusChange**. Setting it to **False** clears the flag — the framework does this automatically after raising [**ApplyChanges**](#applychanges). +[**Changed**](#changed) is a two-way flag the page uses to talk to the host. Setting it to **True** enables the host's *Apply* button; the framework notifies the host immediately through **IPropertyPageSite.OnStatusChange**. Setting it to **False** clears the flag --- the framework does this automatically after raising [**ApplyChanges**](#applychanges). [**EditProperty**](#editproperty) is declared for VB6 compatibility but is not currently raised by the runtime; pages that want to react to a per-property edit request from the host need to wait until that wiring lands. @@ -55,19 +55,19 @@ End Sub ## Standard sizes -The VB6 property-page dialog frame draws each tab at one of two standard sizes — small (250 × 62 dialog units) or large (250 × 110 dialog units) — chosen by the host based on the [**StandardSize**](#standardsize) of the largest page in the sheet. Assigning [**StandardSize**](#standardsize) at design time tells the host which size to request; reading it at run time returns the size the page is actually drawn at, or **StandardSizeCustom** when [**Width**](#width) and [**Height**](#height) have been changed away from either preset. The value is in **EnumStandardSize** units: **StandardSizeCustom** (0), **StandardSizeSmall** (1), or **StandardSizeLarge** (2). +The VB6 property-page dialog frame draws each tab at one of two standard sizes --- small (250 × 62 dialog units) or large (250 × 110 dialog units) --- chosen by the host based on the [**StandardSize**](#standardsize) of the largest page in the sheet. Assigning [**StandardSize**](#standardsize) at design time tells the host which size to request; reading it at run time returns the size the page is actually drawn at, or **StandardSizeCustom** when [**Width**](#width) and [**Height**](#height) have been changed away from either preset. The value is in **EnumStandardSize** units: **StandardSizeCustom** (0), **StandardSizeSmall** (1), or **StandardSizeLarge** (2). ## Drawing surface -A **PropertyPage** is a graphics surface in its own right. The full set of VB6 drawing primitives — [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and the [**Print**](#print) statement — write to its device context, using [**ForeColor**](#forecolor), [**FillColor**](#fillcolor)/[**FillStyle**](#fillstyle), [**DrawWidth**](#drawwidth), [**DrawMode**](#drawmode), and [**DrawStyle**](#drawstyle) for the pen and fill, and [**Font**](#font) for text. The current pen position is tracked by [**CurrentX**](#currentx) and [**CurrentY**](#currenty); [**TextWidth**](#textwidth) and [**TextHeight**](#textheight) measure a string in the current font; [**ScaleX**](#scalex) and [**ScaleY**](#scaley) convert single coordinates between scale modes. +A **PropertyPage** is a graphics surface in its own right. The full set of VB6 drawing primitives --- [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and the [**Print**](#print) statement --- write to its device context, using [**ForeColor**](#forecolor), [**FillColor**](#fillcolor)/[**FillStyle**](#fillstyle), [**DrawWidth**](#drawwidth), [**DrawMode**](#drawmode), and [**DrawStyle**](#drawstyle) for the pen and fill, and [**Font**](#font) for text. The current pen position is tracked by [**CurrentX**](#currentx) and [**CurrentY**](#currenty); [**TextWidth**](#textwidth) and [**TextHeight**](#textheight) measure a string in the current font; [**ScaleX**](#scalex) and [**ScaleY**](#scaley) convert single coordinates between scale modes. -The coordinate system is governed by [**ScaleMode**](#scalemode), [**ScaleLeft**](#scaleleft), [**ScaleTop**](#scaletop), [**ScaleWidth**](#scalewidth), and [**ScaleHeight**](#scaleheight), exactly as on a [**Form**](../Form). [**AutoRedraw**](#autoredraw) controls whether drawn output persists across paints — when **False** (default), the [**Paint**](#paint) event must redraw on every invalidation; when **True**, the page keeps an off-screen buffer that survives invalidations and the **Paint** event is suppressed. +The coordinate system is governed by [**ScaleMode**](#scalemode), [**ScaleLeft**](#scaleleft), [**ScaleTop**](#scaletop), [**ScaleWidth**](#scalewidth), and [**ScaleHeight**](#scaleheight), exactly as on a [**Form**](../Form). [**AutoRedraw**](#autoredraw) controls whether drawn output persists across paints --- when **False** (default), the [**Paint**](#paint) event must redraw on every invalidation; when **True**, the page keeps an off-screen buffer that survives invalidations and the **Paint** event is suppressed. ## Controls and containers -[**Controls**](#controls) is the collection of every child control on this page, indexable by name or zero-based position. The page is enumerable directly (`For Each ctrl In Me`) — the [**Count**](#count) and [**\_Default**](#controls) members forward to it. +[**Controls**](#controls) is the collection of every child control on this page, indexable by name or zero-based position. The page is enumerable directly (`For Each ctrl In Me`) --- the [**Count**](#count) and [**\_Default**](#controls) members forward to it. -[**ActiveControl**](#activecontrol) returns the focused child, or **Nothing** if no control on this page has the focus. [**SetFocus**](#setfocus) gives the focus to the page itself, which forwards it to the page's tab order. [**KeyPreview**](#keypreview) routes keystrokes through the page's [**KeyDown**](#keydown), [**KeyUp**](#keyup), and [**KeyPress**](#keypress) events *before* the focused control sees them — useful for handling **Escape** or page-wide hotkeys. +[**ActiveControl**](#activecontrol) returns the focused child, or **Nothing** if no control on this page has the focus. [**SetFocus**](#setfocus) gives the focus to the page itself, which forwards it to the page's tab order. [**KeyPreview**](#keypreview) routes keystrokes through the page's [**KeyDown**](#keydown), [**KeyUp**](#keyup), and [**KeyPress**](#keypress) events *before* the focused control sees them --- useful for handling **Escape** or page-wide hotkeys. ## Properties @@ -89,7 +89,7 @@ A member of [**AppearanceConstants**](../../VBRUN/Constants/AppearanceConstants) Whether drawing performed on the page persists across invalidations. **Boolean**, default **False**. -When **False**, drawing primitives — [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and [**Print**](#print) — paint directly to the screen and the page must redraw them in its [**Paint**](#paint) event whenever the affected area is invalidated. When **True**, the page keeps an off-screen bitmap, drawing primitives paint into it (and immediately to the screen), the bitmap survives invalidations, and the **Paint** event is suppressed. +When **False**, drawing primitives --- [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and [**Print**](#print) --- paint directly to the screen and the page must redraw them in its [**Paint**](#paint) event whenever the affected area is invalidated. When **True**, the page keeps an off-screen bitmap, drawing primitives paint into it (and immediately to the screen), the bitmap survives invalidations, and the **Paint** event is suppressed. ### BackColor {: .no_toc } @@ -110,17 +110,17 @@ The framework reads the current value when the host calls **IPropertyPage2.GetPa Whether the page has unapplied edits. **Boolean**, default **False**. -Setting **Changed** to **True** notifies the host through **IPropertyPageSite.OnStatusChange** that the page is dirty — the host normally enables its *Apply* button as a result. The framework automatically clears the flag back to **False** before raising [**ApplyChanges**](#applychanges), so handlers do not need to reset it themselves. +Setting **Changed** to **True** notifies the host through **IPropertyPageSite.OnStatusChange** that the page is dirty --- the host normally enables its *Apply* button as a result. The framework automatically clears the flag back to **False** before raising [**ApplyChanges**](#applychanges), so handlers do not need to reset it themselves. ### ClipControls {: .no_toc } -Whether child controls are clipped out of the page's drawing region during paint. **Boolean**, default **True**. Read-only at run time — set at design time. +Whether child controls are clipped out of the page's drawing region during paint. **Boolean**, default **True**. Read-only at run time --- set at design time. ### Controls {: .no_toc } -The collection of every control hosted by this page, indexable by control name or zero-based position. **Default property.** Read-only — controls are added to the collection by the runtime, not by user code. +The collection of every control hosted by this page, indexable by control name or zero-based position. **Default property.** Read-only --- controls are added to the collection by the runtime, not by user code. ```tb Dim ctrl As Control @@ -207,7 +207,7 @@ Shortcut for [**Font**](#font)`.Name`. **String**. ### FontSize {: .no_toc } -Shortcut for [**Font**](#font)`.Size` — the point size. **Single**. +Shortcut for [**Font**](#font)`.Size` --- the point size. **Single**. ### FontStrikethru {: .no_toc } @@ -344,9 +344,9 @@ The collection of objects the host has asked this page to edit, as a **SelectedC The returned object exposes three members: -- `Count` **As Long** — the number of selected objects (`0` when the host has not yet called **SetObjects** or has cleared the selection). -- `Item(`*Index*`)` **As Object** — zero-based indexed access. **Default member**, so `SelectedControls(0)` returns the first object. -- `_NewEnum` — supports `For Each ctl In SelectedControls`. +- `Count` **As Long** --- the number of selected objects (`0` when the host has not yet called **SetObjects** or has cleared the selection). +- `Item(`*Index*`)` **As Object** --- zero-based indexed access. **Default member**, so `SelectedControls(0)` returns the first object. +- `_NewEnum` --- supports `For Each ctl In SelectedControls`. The items are returned as **Object**, so use **CallByName** or late-bound member access to read and write their properties. @@ -359,11 +359,11 @@ Next ### StandardSize {: .no_toc } -The standard size of the page in the host's property-sheet frame. A member of **EnumStandardSize**: **StandardSizeCustom** (0), **StandardSizeSmall** (1 — 250 × 62 dialog units), or **StandardSizeLarge** (2 — 250 × 110 dialog units). +The standard size of the page in the host's property-sheet frame. A member of **EnumStandardSize**: **StandardSizeCustom** (0), **StandardSizeSmall** (1 --- 250 × 62 dialog units), or **StandardSizeLarge** (2 --- 250 × 110 dialog units). Syntax: *object*.**StandardSize** [ = *value* ] -Reading **StandardSize** compares the page's current pixel size against the small/large presets and returns **StandardSizeCustom** when neither matches. Assigning **StandardSizeSmall** or **StandardSizeLarge** resizes the page accordingly; assigning **StandardSizeCustom** is a no-op (leave the size as it is). The property is exposed only in code — VB6 exposed it on the design-time property sheet but never in the runtime object model. +Reading **StandardSize** compares the page's current pixel size against the small/large presets and returns **StandardSizeCustom** when neither matches. Assigning **StandardSizeSmall** or **StandardSizeLarge** resizes the page accordingly; assigning **StandardSizeCustom** is a no-op (leave the size as it is). The property is exposed only in code --- VB6 exposed it on the design-time property sheet but never in the runtime object model. ### Tag {: .no_toc } @@ -476,7 +476,7 @@ Syntax: *object*.**Point**( *X*, *Y* ) ### Print {: .no_toc } -Writes text to the page's drawing surface using [**Font**](#font), starting at [**CurrentX**](#currentx) / [**CurrentY**](#currenty) and advancing them as it goes. Dispatched through the VB6 **Print** statement so multiple expressions can be separated by `;` (no spacing) or `,` (tab to the next print zone). **Spc(n)** inserts *n* spaces and **Tab(n)** moves to print column *n*. Output honours [**Font**](#font), [**ForeColor**](#forecolor), and [**FontTransparent**](#fonttransparent), and — when [**AutoRedraw**](#autoredraw) is **True** — is recorded into the persistent off-screen bitmap so it survives invalidations. +Writes text to the page's drawing surface using [**Font**](#font), starting at [**CurrentX**](#currentx) / [**CurrentY**](#currenty) and advancing them as it goes. Dispatched through the VB6 **Print** statement so multiple expressions can be separated by `;` (no spacing) or `,` (tab to the next print zone). **Spc(n)** inserts *n* spaces and **Tab(n)** moves to print column *n*. Output honours [**Font**](#font), [**ForeColor**](#forecolor), and [**FontTransparent**](#fonttransparent), and --- when [**AutoRedraw**](#autoredraw) is **True** --- is recorded into the persistent off-screen bitmap so it survives invalidations. Syntax: *object*.**Print** \[ *expressionlist* ] \[ **;** \| **,** ] @@ -580,7 +580,7 @@ Syntax: *object*.**ValidateControls** ### ApplyChanges {: .no_toc } -Raised when the host calls **IPropertyPage2.Apply** — typically because the user clicked *OK* or *Apply* on the property-sheet dialog. The handler should write the page's current editor values back to every object in [**SelectedControls**](#selectedcontrols). The framework clears [**Changed**](#changed) to **False** before the handler runs. Not raised when [**Changed**](#changed) is already **False** at the time of the apply. +Raised when the host calls **IPropertyPage2.Apply** --- typically because the user clicked *OK* or *Apply* on the property-sheet dialog. The handler should write the page's current editor values back to every object in [**SelectedControls**](#selectedcontrols). The framework clears [**Changed**](#changed) to **False** before the handler runs. Not raised when [**Changed**](#changed) is already **False** at the time of the apply. Syntax: *object*\_**ApplyChanges**( ) @@ -625,7 +625,7 @@ Syntax: *object*\_**DragOver**( *Source* **As Control**, *X* **As Single**, *Y* > [!NOTE] > Declared for VB6 compatibility; not currently raised in twinBASIC. The host's **IPropertyPage2.EditProperty** request is acknowledged but does not propagate to a managed event yet. -When implemented, raised when the host asks the page to give focus to the editor that corresponds to the named property — typically because the user double-clicked that property in the property browser. +When implemented, raised when the host asks the page to give focus to the editor that corresponds to the named property --- typically because the user double-clicked that property in the property browser. Syntax: *object*\_**EditProperty**( *PropertyName* **As String** ) @@ -740,7 +740,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Paint {: .no_toc } -Raised when an invalidated portion of the page needs to be redrawn. Suppressed when [**AutoRedraw**](#autoredraw) is **True** — the page's persistent off-screen buffer is blitted to the screen instead. +Raised when an invalidated portion of the page needs to be redrawn. Suppressed when [**AutoRedraw**](#autoredraw) is **True** --- the page's persistent off-screen buffer is blitted to the screen instead. Syntax: *object*\_**Paint**( ) @@ -754,6 +754,6 @@ Syntax: *object*\_**SelectionChanged**( ) ### Terminate {: .no_toc } -Raised when the page is being destroyed — once when its window is unhooked from the host's property-sheet frame, and again when the class instance's last reference is released. The handler runs while [**SelectedControls**](#selectedcontrols) is still populated, giving it a final chance to read state from the edited objects before they are released. +Raised when the page is being destroyed --- once when its window is unhooked from the host's property-sheet frame, and again when the class instance's last reference is released. The handler runs while [**SelectedControls**](#selectedcontrols) is still populated, giving it a final chance to read state from the edited objects before they are released. Syntax: *object*\_**Terminate**( ) diff --git a/docs/Reference/VB/QRCode/index.md b/docs/Reference/VB/QRCode/index.md index 5423f4bf..fe9a6c95 100644 --- a/docs/Reference/VB/QRCode/index.md +++ b/docs/Reference/VB/QRCode/index.md @@ -8,7 +8,7 @@ has_toc: false # QRCode class {: .no_toc } -A **QRCode** is a windowless lightweight control that renders a QR code generated from its [**Payload**](#payload) — a URL, plain text, or a raw byte array. The encoding is performed in-process by the embedded `qrcodegen` library and the resulting matrix is painted directly on the parent at design time and at run time. The picture is regenerated automatically whenever any of the encoding properties changes, so a QR control can be wired up declaratively to data bindings or to other UI state with no plumbing. +A **QRCode** is a windowless lightweight control that renders a QR code generated from its [**Payload**](#payload) --- a URL, plain text, or a raw byte array. The encoding is performed in-process by the embedded `qrcodegen` library and the resulting matrix is painted directly on the parent at design time and at run time. The picture is regenerated automatically whenever any of the encoding properties changes, so a QR control can be wired up declaratively to data bindings or to other UI state with no plumbing. Like [**Image**](../Image), a QRCode has no `hWnd` and is not focusable. It is the right choice for embedding a scannable code in a form (login, payment, Wi-Fi credentials, contact card, app deep link, etc.) without paying for a heavy [**PictureBox**](../PictureBox). @@ -41,9 +41,9 @@ For a QR code that needs any of those, host the **QRCode** inside a [**PictureBo ## Encoding the payload -The [**Payload**](#payload) property is a **Variant** that accepts either a **String** (text or URL) or a one-dimensional **Byte()** array (for binary data). The encoder picks the most compact segment mode automatically — numeric, alphanumeric, or byte — based on the contents of the string; for a byte array the byte mode is used unconditionally and the data is encoded verbatim. Empty payloads clear [**Picture**](#picture) to **Nothing**; at design time the rectangle then shows a *(no payload text)* placeholder. +The [**Payload**](#payload) property is a **Variant** that accepts either a **String** (text or URL) or a one-dimensional **Byte()** array (for binary data). The encoder picks the most compact segment mode automatically --- numeric, alphanumeric, or byte --- based on the contents of the string; for a byte array the byte mode is used unconditionally and the data is encoded verbatim. Empty payloads clear [**Picture**](#picture) to **Nothing**; at design time the rectangle then shows a *(no payload text)* placeholder. -The QR code is regenerated whenever [**Payload**](#payload), [**ForeColor**](#forecolor), [**ModuleSize**](#modulesize), [**SquareModules**](#squaremodules), [**EccMode**](#eccmode), [**EccBoost**](#eccboost), [**MinVersion**](#minversion), [**MaxVersion**](#maxversion), or [**MaskType**](#masktype) changes, and the new picture becomes visible through [**Picture**](#picture). [**Refresh**](#refresh) only repaints — it does not force re-encoding. +The QR code is regenerated whenever [**Payload**](#payload), [**ForeColor**](#forecolor), [**ModuleSize**](#modulesize), [**SquareModules**](#squaremodules), [**EccMode**](#eccmode), [**EccBoost**](#eccboost), [**MinVersion**](#minversion), [**MaxVersion**](#maxversion), or [**MaskType**](#masktype) changes, and the new picture becomes visible through [**Picture**](#picture). [**Refresh**](#refresh) only repaints --- it does not force re-encoding. ## Error correction @@ -56,19 +56,19 @@ QR codes embed a Reed-Solomon parity stream that lets the decoder recover from d | **vbQRCodegenEccQuartile** | 2 | 25% | | **vbQRCodegenEccHigh** | 3 | 30% | -When [**EccBoost**](#eccboost) is **True** (default), the encoder raises the parity level beyond the configured minimum if doing so still fits the payload in the same QR version — automatically achieving better resilience. +When [**EccBoost**](#eccboost) is **True** (default), the encoder raises the parity level beyond the configured minimum if doing so still fits the payload in the same QR version --- automatically achieving better resilience. ## Version and mask The QR-code *version* (1 to 40) sets the matrix size: version 1 is 21 × 21 modules, version 40 is 177 × 177. [**MinVersion**](#minversion) and [**MaxVersion**](#maxversion) constrain the encoder's search; it picks the smallest version in the range that fits the payload at the chosen [**EccMode**](#eccmode). The defaults (`1` and `40`) span the full range. Values outside `1..40` are clamped, and if **MinVersion** ends up greater than **MaxVersion** it is reset to `1`. -[**MaskType**](#masktype) selects one of eight masks applied to the matrix to break up patterns that confuse the scanner. **vbQRCodegenMaskAuto** (-1, default) picks the mask with the best penalty score; the eight named values **vbQRCodegenMask0** through **vbQRCodegenMask7** force a specific one — useful for reproducibility. +[**MaskType**](#masktype) selects one of eight masks applied to the matrix to break up patterns that confuse the scanner. **vbQRCodegenMaskAuto** (-1, default) picks the mask with the best penalty score; the eight named values **vbQRCodegenMask0** through **vbQRCodegenMask7** force a specific one --- useful for reproducibility. ## Module rendering [**ModuleSize**](#modulesize) is the pixel size of one module of the generated [**Picture**](#picture). Default `120`. The picture is rescaled down to the control's rectangle at paint time, so the choice of [**ModuleSize**](#modulesize) only matters when the picture is being saved or pulled out for use elsewhere (clipboard, drag-drop, **SavePicture**, …). -[**SquareModules**](#squaremodules) chooses how each module is drawn in the picture: as a filled square (**True**, default) or as a filled circle (**False** — a stylistic choice that most scanners still tolerate). +[**SquareModules**](#squaremodules) chooses how each module is drawn in the picture: as a filled square (**True**, default) or as a filled circle (**False** --- a stylistic choice that most scanners still tolerate). [**Square**](#square), in contrast, controls the rendering of the picture *on the control*: with **True** (default) the picture is letter-boxed and centred so it stays square regardless of the control's aspect ratio; with **False** the picture is stretched to fill the rectangle. @@ -80,22 +80,22 @@ The QR-code *version* (1 to 40) sets the matrix size: version 1 is 21 × 21 modu A **QRCode** supports both ends of an OLE drag-drop operation: -- [**OLEDragMode**](#oledragmode) controls the source side. With **vbOLEDragAutomatic**, holding the mouse over the control and beginning a drag automatically copies the current [**Picture**](#picture) into the resulting **DataObject** — convenient for dragging the generated QR onto another picture display or out to a file in Explorer. With **vbOLEDragManual** (default) drags must be initiated by calling [**OLEDrag**](#oledrag) from a [**MouseDown**](#mousedown) handler. -- [**OLEDropMode**](#oledropmode) controls the destination side. With **vbOLEDropManual** the [**OLEDragOver**](#oledragover) and [**OLEDragDrop**](#oledragdrop) events fire so the application can decide what to do — for example, set [**Payload**](#payload) to the dropped text. **vbOLEDropAutomatic** is not supported on a **QRCode** and assigning it raises run-time error 5 (*Invalid procedure call or argument*). +- [**OLEDragMode**](#oledragmode) controls the source side. With **vbOLEDragAutomatic**, holding the mouse over the control and beginning a drag automatically copies the current [**Picture**](#picture) into the resulting **DataObject** -- convenient for dragging the generated QR onto another picture display or out to a file in Explorer. With **vbOLEDragManual** (default) drags must be initiated by calling [**OLEDrag**](#oledrag) from a [**MouseDown**](#mousedown) handler. +- [**OLEDropMode**](#oledropmode) controls the destination side. With **vbOLEDropManual** the [**OLEDragOver**](#oledragover) and [**OLEDragDrop**](#oledragdrop) events fire so the application can decide what to do -- for example, set [**Payload**](#payload) to the dropped text. **vbOLEDropAutomatic** is not supported on a **QRCode** and assigning it raises run-time error 5 (*Invalid procedure call or argument*). ## Data binding Setting [**DataSource**](#datasource) and [**DataField**](#datafield) connects the control to a field of a [**Data**](../Data) control's recordset. Binding is asymmetric: - *Inbound* (recordset → control): non-null, non-empty field values are interpreted as text and assigned to [**Payload**](#payload); the QR is then re-encoded and repainted. Null and empty values clear [**Picture**](#picture) to **Nothing**. -- *Outbound* (control → recordset): the current QR [**Picture**](#picture) is serialised as a byte array and written back to the bound field — useful for storing a snapshot of the rendered code, but note that what comes out of the binding is not the same as what went in. +- *Outbound* (control → recordset): the current QR [**Picture**](#picture) is serialised as a byte array and written back to the bound field --- useful for storing a snapshot of the rendered code, but note that what comes out of the binding is not the same as what went in. ## Properties ### Anchors {: .no_toc } -The set of edges of the parent that the control's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the control's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Appearance {: .no_toc } @@ -110,12 +110,12 @@ The style of border drawn around the rectangle. A member of [**ControlBorderStyl ### Container {: .no_toc } -The control that hosts this **QRCode** — typically the form, a [**Frame**](../Frame), a [**PictureBox**](../PictureBox), or a **UserControl**. Read with **Get**, change with **Set**. +The control that hosts this **QRCode** --- typically the form, a [**Frame**](../Frame), a [**PictureBox**](../PictureBox), or a **UserControl**. Read with **Get**, change with **Set**. ### ControlType {: .no_toc } -A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstants) value identifying the underlying control kind. Always **vbImage** — the QRCode shares its control-type tag with [**Image**](../Image). +A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstants) value identifying the underlying control kind. Always **vbImage** --- the QRCode shares its control-type tag with [**Image**](../Image). ### DataChanged {: .no_toc } @@ -155,7 +155,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself (the manual VB-drag form, distinct from OLE drag) when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself (the manual VB-drag form, distinct from OLE drag) when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### EccBoost {: .no_toc } @@ -184,7 +184,7 @@ Determines whether the control accepts mouse input. A disabled **QRCode** still ### ForeColor {: .no_toc } -The colour of the dark modules in the generated QR code, as an **OLE_COLOR**. Default **vbBlack**. The light modules are always transparent — the control's parent shows through them, so place the **QRCode** over a contrasting background. +The colour of the dark modules in the generated QR code, as an **OLE_COLOR**. Default **vbBlack**. The light modules are always transparent --- the control's parent shows through them, so place the **QRCode** over a contrasting background. ### Height {: .no_toc } @@ -204,7 +204,7 @@ The horizontal distance from the left edge of the container to the left edge of ### MaskType {: .no_toc } -The mask applied to the encoded matrix to break up patterns that confuse the scanner. A member of **QRCodegenMaskConstants** (defined in the VB package): **vbQRCodegenMaskAuto** (-1, default — pick the mask with the lowest penalty score) or one of **vbQRCodegenMask0** … **vbQRCodegenMask7** (force the corresponding numbered mask). Out-of-range values fall back to **vbQRCodegenMaskAuto**. +The mask applied to the encoded matrix to break up patterns that confuse the scanner. A member of **QRCodegenMaskConstants** (defined in the VB package): **vbQRCodegenMaskAuto** (-1, default --- pick the mask with the lowest penalty score) or one of **vbQRCodegenMask0** … **vbQRCodegenMask7** (force the corresponding numbered mask). Out-of-range values fall back to **vbQRCodegenMaskAuto**. ### MaxVersion {: .no_toc } @@ -239,7 +239,7 @@ The unique design-time name of the control on its parent form. Read-only at run ### OLEDragMode {: .no_toc } -Whether an OLE drag is started automatically when the user begins dragging the control. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default — application calls [**OLEDrag**](#oledrag)) or **vbOLEDragAutomatic** (1 — the framework copies the current [**Picture**](#picture) into the resulting **DataObject** automatically). +Whether an OLE drag is started automatically when the user begins dragging the control. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default --- application calls [**OLEDrag**](#oledrag)) or **vbOLEDragAutomatic** (1 --- the framework copies the current [**Picture**](#picture) into the resulting **DataObject** automatically). ### OLEDropMode {: .no_toc } @@ -258,17 +258,17 @@ The data encoded in the QR code. **Variant**, default `"https://www.twinbasic.co Syntax: *object*.**Payload** [ = *value* ] -Accepts a **String** for text or URL payloads, or a one-dimensional **Byte()** array for arbitrary binary data. The encoder picks the most compact segment mode automatically — numeric, alphanumeric, or byte — based on the contents of the string. Assigning an empty value clears [**Picture**](#picture) to **Nothing**. +Accepts a **String** for text or URL payloads, or a one-dimensional **Byte()** array for arbitrary binary data. The encoder picks the most compact segment mode automatically --- numeric, alphanumeric, or byte --- based on the contents of the string. Assigning an empty value clears [**Picture**](#picture) to **Nothing**. ### Picture {: .no_toc } -The generated QR code, as a **StdPicture**. **Default property.** Read-only — produced by the encoder from [**Payload**](#payload) and the other encoding properties. Returns **Nothing** when [**Payload**](#payload) is empty. +The generated QR code, as a **StdPicture**. **Default property.** Read-only --- produced by the encoder from [**Payload**](#payload) and the other encoding properties. Returns **Nothing** when [**Payload**](#payload) is empty. ### Square {: .no_toc } -Whether the generated picture is rendered with a 1:1 aspect ratio inside the control's rectangle (**True**, default — picture is centred and letter-boxed) or stretched to fill it (**False**). **Boolean**. +Whether the generated picture is rendered with a 1:1 aspect ratio inside the control's rectangle (**True**, default --- picture is centred and letter-boxed) or stretched to fill it (**False**). **Boolean**. ### SquareModules {: .no_toc } @@ -310,7 +310,7 @@ The control's width, in twips by default (or in the container's **ScaleMode** un ### Drag {: .no_toc } -Begins, completes, or cancels a manual VB-style drag operation. Distinct from OLE drag — see [**OLEDrag**](#oledrag). +Begins, completes, or cancels a manual VB-style drag operation. Distinct from OLE drag --- see [**OLEDrag**](#oledrag). Syntax: *object*.**Drag** [ *Action* ] @@ -333,14 +333,14 @@ Syntax: *object*.**Move** *Left* [, *Top* [, *Width* [, *Height* ] ] ] ### OLEDrag {: .no_toc } -Initiates an OLE drag operation from the control, raising the [**OLEStartDrag**](#olestartdrag) event so the application can populate the **DataObject** (or, if the source has already been pre-populated, kicks off the drag immediately). +Initiates an OLE drag operation from the control, raising the [**OLEStartDrag**](#olestartdrag) event so the application can populate the **DataObject** (or, if the source has already been pre-populated, begins the drag immediately). Syntax: *object*.**OLEDrag** ### Refresh {: .no_toc } -Forces an immediate repaint of the control's rectangle on the parent's drawing surface. Does *not* re-encode the QR — for that, reassign [**Payload**](#payload) (or any of the encoding properties) which triggers regeneration automatically. +Forces an immediate repaint of the control's rectangle on the parent's drawing surface. Does *not* re-encode the QR --- for that, reassign [**Payload**](#payload) (or any of the encoding properties) which triggers regeneration automatically. Syntax: *object*.**Refresh** diff --git a/docs/Reference/VB/Report/index.md b/docs/Reference/VB/Report/index.md index b346bf2f..9e3b43f7 100644 --- a/docs/Reference/VB/Report/index.md +++ b/docs/Reference/VB/Report/index.md @@ -8,7 +8,7 @@ has_toc: false # Report class {: .no_toc } -A **Report** is a top-level Win32 window — much like a [**Form**](../Form/) — specialised for rendering the print preview of a banded report. Each report designed in the IDE becomes its own class derived from **Report**: its sections (report header / page header / detail / page footer / report footer) and the controls placed in them become members of that class. At run time, code assigns a recordset to [**Recordset**](#recordset), calls [**Show**](#show), and the framework iterates the recordset, evaluates expressions on the controls, and paints the resulting pages into a built-in preview window with a navigation toolbar at the bottom. [**PrintReport**](#printreport) sends the same pages to the printer. The default property is [**Controls**](#controls) and the default event is [**Load**](#load). +A **Report** is a top-level Win32 window --- much like a [**Form**](../Form/) --- specialised for rendering the print preview of a banded report. Each report designed in the IDE becomes its own class derived from **Report**: its sections (report header / page header / detail / page footer / report footer) and the controls placed in them become members of that class. At run time, code assigns a recordset to [**Recordset**](#recordset), calls [**Show**](#show), and the framework iterates the recordset, evaluates expressions on the controls, and paints the resulting pages into a built-in preview window with a navigation toolbar at the bottom. [**PrintReport**](#printreport) sends the same pages to the printer. The default property is [**Controls**](#controls) and the default event is [**Load**](#load). ```tb ' In the report's code-behind (rptSales): @@ -38,15 +38,15 @@ A report is composed of up to five sections, laid out vertically on each page: | **PageFooter** | At the bottom of every page. | | **ReportFooter** | Once, at the end of the last page after the final detail row. | -Sections are designed in the IDE — each is a container that holds [**Label**](../Label/), [**Image**](../Image/), [**QRCode**](../QRCode/), and other controls. A section's `KeepTogether` property prevents it from splitting across a page break; its `BackStyle` and back colour control the section background; the framework picks an alternating-row colour for the detail section automatically when the section requests it. +Sections are designed in the IDE --- each is a container that holds [**Label**](../Label/), [**Image**](../Image/), [**QRCode**](../QRCode/), and other controls. A section's `KeepTogether` property prevents it from splitting across a page break; its `BackStyle` and back colour control the section background; the framework picks an alternating-row colour for the detail section automatically when the section requests it. ## Recordset binding -[**Recordset**](#recordset) accepts any object that exposes the classic ADO/DAO interface — `EOF`, `MoveNext`, and a `Fields` collection indexable by name. The framework wraps non-tB recordsets transparently. `Recordset` may also be left **Nothing**, in which case the detail section is rendered exactly once with no field data. +[**Recordset**](#recordset) accepts any object that exposes the classic ADO/DAO interface --- `EOF`, `MoveNext`, and a `Fields` collection indexable by name. The framework wraps non-tB recordsets transparently. `Recordset` may also be left **Nothing**, in which case the detail section is rendered exactly once with no field data. -A control in a section opts into binding by setting its `DataField` to a recordset field name; the framework reads that field for each detail row and writes it back into the control's value (or [**Caption**](../Label/#caption) for [**Label**](../Label/)s, **Payload** for [**QRCode**](../QRCode/)). For richer cases, prefix `DataField` with `=` to make it an *expression* — any twinBASIC expression that mixes recordset fields, the report's own [**Page**](#page) / [**Pages**](#pages) / [**Caption**](#caption), and standard library calls. A label whose **DataField** is `="Page " & Report.Page & " of " & Report.Pages` updates itself as each page is rendered. +A control in a section opts into binding by setting its `DataField` to a recordset field name; the framework reads that field for each detail row and writes it back into the control's value (or [**Caption**](../Label/#caption) for [**Label**](../Label/)s, **Payload** for [**QRCode**](../QRCode/)). For richer cases, prefix `DataField` with `=` to make it an *expression* --- any twinBASIC expression that mixes recordset fields, the report's own [**Page**](#page) / [**Pages**](#pages) / [**Caption**](#caption), and standard library calls. A label whose **DataField** is `="Page " & Report.Page & " of " & Report.Pages` updates itself as each page is rendered. -When **DataField** is empty and a [**Label**](../Label/)'s [**Caption**](../Label/#caption) contains `%`-placeholders, those placeholders are converted to an expression automatically — see [Caption placeholders](#caption-placeholders) below. Setting `DataFieldAggregate` on a Label additionally accumulates the expression's value across rows for running totals. +When **DataField** is empty and a [**Label**](../Label/)'s [**Caption**](../Label/#caption) contains `%`-placeholders, those placeholders are converted to an expression automatically --- see [Caption placeholders](#caption-placeholders) below. Setting `DataFieldAggregate` on a Label additionally accumulates the expression's value across rows for running totals. ## Caption placeholders @@ -68,15 +68,15 @@ Use `%%` to embed a literal `%`. A caption with no recognised placeholder is lef The bottom strip of the report window is a fixed toolbar with three groups of controls: -- **Record selectors** — first / previous / next / last buttons around a page-number readout. -- **Zoom controls** — minus / plus buttons around a percentage readout. -- **Print button** — sends the report to the default printer (calls [**PrintReport**](#printreport) with `ShowDialog := False`). +- **Record selectors** --- first / previous / next / last buttons around a page-number readout. +- **Zoom controls** --- minus / plus buttons around a percentage readout. +- **Print button** --- sends the report to the default printer (calls [**PrintReport**](#printreport) with `ShowDialog := False`). The toolbar always paints; it cannot be hidden. The plus and minus buttons step [**ZoomPercent**](#zoompercent) by [**ZoomStep**](#zoomstep) (default `10`) and switch [**ZoomAutoFit**](#zoomautofit) to **vbZoomAutoFitNever**. Scroll bars appear automatically when the zoomed page does not fit the available area; the mouse wheel scrolls vertically and **Shift+Wheel** scrolls horizontally. ## Zoom and page sizing -[**PixelsReportWidth**](#pixelsreportwidth) and [**PixelsReportHeight**](#pixelsreportheight) define the page size *between the margins*; [**PixelsLeftMargin**](#pixelsleftmargin), [**PixelsRightMargin**](#pixelsrightmargin), [**PixelsTopMargin**](#pixelstopmargin), and [**PixelsBottomMargin**](#pixelsbottommargin) define the margins. All five values are in *scaled pixels* (1 px ≈ 1/96 inch at 100% DPI). The defaults — `300` × `900` for the page and `96/2.54` (≈ 1 cm) for each margin — are placeholders rather than a real paper size; the IDE designer's [**ChangePageSize**](#changepagesize) helper writes the values for the standard paper sizes. +[**PixelsReportWidth**](#pixelsreportwidth) and [**PixelsReportHeight**](#pixelsreportheight) define the page size *between the margins*; [**PixelsLeftMargin**](#pixelsleftmargin), [**PixelsRightMargin**](#pixelsrightmargin), [**PixelsTopMargin**](#pixelstopmargin), and [**PixelsBottomMargin**](#pixelsbottommargin) define the margins. All five values are in *scaled pixels* (1 px ≈ 1/96 inch at 100% DPI). The defaults --- `300` × `900` for the page and `96/2.54` (≈ 1 cm) for each margin --- are placeholders rather than a real paper size; the IDE designer's [**ChangePageSize**](#changepagesize) helper writes the values for the standard paper sizes. ### ZoomAutoFitConstants @@ -92,7 +92,7 @@ Clicking the toolbar's plus or minus button automatically switches [**ZoomAutoFi ## Drawing inside sections -Every section's repaint raises [**BeforePaintSection**](#beforepaintsection) on the report, with the [**Section**](#beforepaintsection) being drawn as the argument. During this event, [**hDC**](#hdc) returns the metafile device context that the section is being recorded into — drawing primitives ([**Line**](#line), [**Circle**](#circle), [**PSet**](#pset), [**PaintPicture**](#paintpicture), [**Print**](#print), and direct GDI calls through [**hDC**](#hdc)) write straight into that section's image. Outside the event, [**hDC**](#hdc) returns the report window's own DC, suitable for screen drawing only. +Every section's repaint raises [**BeforePaintSection**](#beforepaintsection) on the report, with the [**Section**](#beforepaintsection) being drawn as the argument. During this event, [**hDC**](#hdc) returns the metafile device context that the section is being recorded into --- drawing primitives ([**Line**](#line), [**Circle**](#circle), [**PSet**](#pset), [**PaintPicture**](#paintpicture), [**Print**](#print), and direct GDI calls through [**hDC**](#hdc)) write straight into that section's image. Outside the event, [**hDC**](#hdc) returns the report window's own DC, suitable for screen drawing only. ```tb Private Sub Report_BeforePaintSection(Section As ControlsSection) @@ -106,9 +106,9 @@ End Sub A report mixes three coordinate systems: -- **Window dimensions** — [**Width**](#width), [**Height**](#height), [**Left**](#left), and [**Top**](#top) describe the report window itself, in twips (the size of the on-screen frame, including the toolbar). -- **Client constraints** — [**MinWidth**](#minwidth), [**MinHeight**](#minheight), [**MaxWidth**](#maxwidth), and [**MaxHeight**](#maxheight) constrain the *client area* of the window during interactive resize, in twips. -- **Page dimensions** — [**PixelsReportWidth**](#pixelsreportwidth), [**PixelsReportHeight**](#pixelsreportheight), and the margin properties describe the *printed page*, in scaled pixels. +- **Window dimensions** --- [**Width**](#width), [**Height**](#height), [**Left**](#left), and [**Top**](#top) describe the report window itself, in twips (the size of the on-screen frame, including the toolbar). +- **Client constraints** --- [**MinWidth**](#minwidth), [**MinHeight**](#minheight), [**MaxWidth**](#maxwidth), and [**MaxHeight**](#maxheight) constrain the *client area* of the window during interactive resize, in twips. +- **Page dimensions** --- [**PixelsReportWidth**](#pixelsreportwidth), [**PixelsReportHeight**](#pixelsreportheight), and the margin properties describe the *printed page*, in scaled pixels. The graphics primitives inherited from the form-style drawing surface ([**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**Print**](#print), …) use the report's own [**ScaleMode**](#scalemode) and [**Scale\***](#scaleleft) properties for their coordinate inputs. @@ -120,7 +120,7 @@ The graphics primitives inherited from the form-style drawing surface ([**Cls**] rptSales.PrintReport ShowDialog:=False ``` -The print dialog is not yet supported in this beta; calling **PrintReport** with **ShowDialog := True** raises run-time error 5. Paper size is currently locked to A4 — a message box reminds the user of this on each print job. +The print dialog is not yet supported in this beta; calling **PrintReport** with **ShowDialog := True** raises run-time error 5. Paper size is currently locked to A4 --- a message box reminds the user of this on each print job. ## Properties @@ -163,7 +163,7 @@ A member of **ReportSizeConstants**: blank (default), **A4 Portrait**, **A4 Land ### ClipControls {: .no_toc } -Whether child controls are clipped out of the report window's drawing region during paint. **Boolean**, default **True**. Read-only at run time — set at design time. +Whether child controls are clipped out of the report window's drawing region during paint. **Boolean**, default **True**. Read-only at run time --- set at design time. ### ControlBox {: .no_toc } @@ -173,7 +173,7 @@ Whether the title bar shows the system menu (and, with it, the close button). ** ### Controls {: .no_toc } -The collection of every control hosted by this report's sections, indexable by control name or zero-based position. **Default property.** Read-only — controls are added to the collection by the runtime, not by user code. +The collection of every control hosted by this report's sections, indexable by control name or zero-based position. **Default property.** Read-only --- controls are added to the collection by the runtime, not by user code. ### ControlType {: .no_toc } @@ -223,7 +223,7 @@ The pen width in pixels for drawing primitives. **Long**, default `1`. Widths gr ### Enabled {: .no_toc } -Determines whether the report window accepts user input. A disabled report ignores keyboard and mouse input — including the toolbar buttons. **Boolean**, default **True**. +Determines whether the report window accepts user input. A disabled report ignores keyboard and mouse input --- including the toolbar buttons. **Boolean**, default **True**. ### FillColor {: .no_toc } @@ -258,7 +258,7 @@ The Win32 device context handle currently relevant to drawing, as a **LongPtr**. ### HasDC {: .no_toc } -Whether the report window keeps a private device context (`CS_OWNDC`) for its drawing surface. **Boolean**, default **True**. Read-only at run time — set at design time. +Whether the report window keeps a private device context (`CS_OWNDC`) for its drawing surface. **Boolean**, default **True**. Read-only at run time --- set at design time. ### Height {: .no_toc } @@ -293,7 +293,7 @@ When **True**, the report's [**KeyDown**](#keydown), [**KeyUp**](#keyup), and [* ### Left {: .no_toc } -The horizontal position of the report window's outer rectangle, in twips, measured from the left edge of the screen — or, for an MDI child, from the left edge of the MDI parent's client area. **Double**. +The horizontal position of the report window's outer rectangle, in twips, measured from the left edge of the screen --- or, for an MDI child, from the left edge of the MDI parent's client area. **Double**. ### MaxButton {: .no_toc } @@ -313,7 +313,7 @@ The maximum width of the report window's *client area*, in twips. **Double**, de ### MDIChild {: .no_toc } -When **True**, the report is hosted as a child inside an [**MDIForm**](../MDIForm/). **Boolean**, read-only — set at design time. An MDI child report cannot be shown modally. +When **True**, the report is hosted as a child inside an [**MDIForm**](../MDIForm/). **Boolean**, read-only --- set at design time. An MDI child report cannot be shown modally. ### MinButton {: .no_toc } @@ -353,7 +353,7 @@ The unique design-time name of the report. Read-only at run time. Also the class ### Opacity {: .no_toc } -The report window's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Values below 100 cause the window to become a layered window. +The report window's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Values below 100 cause the window to become a layered window. ### Page {: .no_toc } @@ -371,7 +371,7 @@ The total number of pages in the report. **Long**. Initialised to `999` and revi The colour of the simulated paper behind the rendered page in the preview. **OLE_COLOR**, default **vbWhite**. > [!NOTE] -> This affects the *preview* only — it does not change the colour sent to the printer. +> This affects the *preview* only --- it does not change the colour sent to the printer. ### Picture {: .no_toc } @@ -423,7 +423,7 @@ Syntax: **Set** *object*.**Recordset** = *value* *value* : Any object with `EOF`, `MoveNext`, and a `Fields` collection (a tB **ITbRecordset** is used directly; other recordsets are wrapped transparently). May be **Nothing**, in which case the detail section is rendered exactly once with no field data. -Assigning **Recordset** does not by itself reset paging — call `Page = 1` (or **Refresh**) to start the preview at the new first page. +Assigning **Recordset** does not by itself reset paging --- call `Page = 1` (or **Refresh**) to start the preview at the new first page. ### RecordNum {: .no_toc } @@ -464,12 +464,12 @@ The width of the logical drawing rectangle, in [**ScaleMode**](#scalemode) units ### ShowInTaskbar {: .no_toc } -Whether the report window appears in the Windows taskbar and Alt-Tab list. **Boolean**, default **True**. Read-only at run time — set at design time. +Whether the report window appears in the Windows taskbar and Alt-Tab list. **Boolean**, default **True**. Read-only at run time --- set at design time. ### StartUpPosition {: .no_toc } -How the report window's initial position is determined the first time it is shown. A member of [**StartUpPositionConstants**](../../VBRUN/Constants/StartUpPositionConstants): **vbStartUpManual**, **vbStartUpOwner**, **vbStartUpScreen**, or **vbStartUpWindowsDefault** (default). Read-only at run time — set at design time. +How the report window's initial position is determined the first time it is shown. A member of [**StartUpPositionConstants**](../../VBRUN/Constants/StartUpPositionConstants): **vbStartUpManual**, **vbStartUpOwner**, **vbStartUpScreen**, or **vbStartUpWindowsDefault** (default). Read-only at run time --- set at design time. ### Tag {: .no_toc } @@ -479,7 +479,7 @@ A free-form **String** the application can use to associate custom data with the ### Top {: .no_toc } -The vertical position of the report window's outer rectangle, in twips, measured from the top edge of the screen — or, for an MDI child, from the top edge of the MDI parent's client area. **Double**. +The vertical position of the report window's outer rectangle, in twips, measured from the top edge of the screen --- or, for an MDI child, from the top edge of the MDI parent's client area. **Double**. ### TopMost {: .no_toc } @@ -489,7 +489,7 @@ Whether the report window sits in the always-on-top z-order layer. **Boolean**, ### TransparencyKey {: .no_toc } -An **OLE_COLOR** that, when set, becomes fully transparent in the rendered report window — clicks pass through to whatever is underneath, and the corresponding pixels do not paint. Default `-1` disables the effect. +An **OLE_COLOR** that, when set, becomes fully transparent in the rendered report window --- clicks pass through to whatever is underneath, and the corresponding pixels do not paint. Default `-1` disables the effect. ### Visible {: .no_toc } @@ -548,7 +548,7 @@ Syntax: *object*.**Circle** [ **Step** ] ( *X*, *Y* ), *Radius* [, [ *Color* ] [ ### Close {: .no_toc } -Initiates the report window's unload sequence — [**QueryUnload**](#queryunload), then [**Unload**](#unload), then [**Terminate**](#terminate). Either of the first two events can cancel the close by setting *Cancel* to non-zero. +Initiates the report window's unload sequence --- [**QueryUnload**](#queryunload), then [**Unload**](#unload), then [**Terminate**](#terminate). Either of the first two events can cancel the close by setting *Cancel* to non-zero. Syntax: *object*.**Close** @@ -633,10 +633,10 @@ Writes text to the current drawing surface using [**Font**](#font), starting at Syntax: *object*.**Print** \[ *expressionlist* ] \[ **;** \| **,** ] -A trailing `;` or `,` suppresses the newline so the next **Print** call continues on the same line. **Print** is the language-level statement, not a function call — multiple expressions can be separated by `;` (no spacing) or `,` (tab to the next print zone), and **Spc(n)** / **Tab(n)** insert spaces or move to a column. +A trailing `;` or `,` suppresses the newline so the next **Print** call continues on the same line. **Print** is the language-level statement, not a function call --- multiple expressions can be separated by `;` (no spacing) or `,` (tab to the next print zone), and **Spc(n)** / **Tab(n)** insert spaces or move to a column. > [!NOTE] -> To send a report to the printer, use [**PrintReport**](#printreport) — not **Print**. +> To send a report to the printer, use [**PrintReport**](#printreport) --- not **Print**. ### PrintReport {: .no_toc } @@ -646,7 +646,7 @@ Sends every page of the report to the [**Printer**](../../VB/Printer) object. It Syntax: *object*.**PrintReport** [ *ShowDialog* [, *Range* [, *PageFrom* [, *PageTo* ] ] ] ] *ShowDialog* -: *optional* When **True** (default), display the standard print dialog before printing. **Not yet supported** — calling **PrintReport** with **ShowDialog := True** raises run-time error 5. +: *optional* When **True** (default), display the standard print dialog before printing. **Not yet supported** --- calling **PrintReport** with **ShowDialog := True** raises run-time error 5. *Range* : *optional* A member of **PageRangeConstants**: **rptRangeAllPages** (0, default) or **rptRangeFromTo** (1). @@ -731,7 +731,7 @@ Makes the report window visible. Triggers [**Load**](#load) on the first call. Syntax: *object*.**Show** [ *Modal* [, *OwnerForm* ] ] *Modal* -: *optional* A member of [**FormShowConstants**](../../VBRUN/Constants/FormShowConstants): **vbModeless** (0, default — the call returns immediately) or **vbModal** (1 — the call blocks until the report is closed). +: *optional* A member of [**FormShowConstants**](../../VBRUN/Constants/FormShowConstants): **vbModeless** (0, default --- the call returns immediately) or **vbModal** (1 --- the call blocks until the report is closed). *OwnerForm* : *optional* For modal shows, the form that is disabled while the report is up; defaults to the currently active form. @@ -771,7 +771,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Activate {: .no_toc } -Raised when the report window becomes the active window in the application — either after [**Load**](#load) for the first show, or whenever it gains activation back from another window. +Raised when the report window becomes the active window in the application --- either after [**Load**](#load) for the first show, or whenever it gains activation back from another window. Syntax: *object*\_**Activate**( ) @@ -899,7 +899,7 @@ Syntax: *object*\_**QueryUnload**( *Cancel* **As Integer**, *UnloadMode* **As In ### Resize {: .no_toc } -Raised when the report window is resized — by the user, by code, by the OS following a [**WindowState**](#windowstate) change, or by initial layout during the first show. +Raised when the report window is resized --- by the user, by code, by the OS following a [**WindowState**](#windowstate) change, or by initial layout during the first show. Syntax: *object*\_**Resize**( ) diff --git a/docs/Reference/VB/Screen/index.md b/docs/Reference/VB/Screen/index.md index 4647c78c..c98c196d 100644 --- a/docs/Reference/VB/Screen/index.md +++ b/docs/Reference/VB/Screen/index.md @@ -8,7 +8,7 @@ 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: +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 @@ -26,10 +26,10 @@ Screen.MousePointer = vbDefault ## 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: +[**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. +- [**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. @@ -40,7 +40,7 @@ On a 96-DPI display these are both `15` (1440 twips per logical inch ÷ 96 pixel [**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 accessing 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: +The most common idiom is accessing 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) @@ -57,7 +57,7 @@ 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. +[**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 @@ -68,7 +68,7 @@ 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. +[**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**. diff --git a/docs/Reference/VB/Shape/index.md b/docs/Reference/VB/Shape/index.md index f9e1f246..75c4409e 100644 --- a/docs/Reference/VB/Shape/index.md +++ b/docs/Reference/VB/Shape/index.md @@ -8,9 +8,9 @@ has_toc: false # Shape class {: .no_toc } -A **Shape** is a windowless lightweight control that draws one of a fixed set of geometric primitives — rectangle, square, oval, circle, rounded rectangle, rounded square, five-pointed star, or an arrow pointing in any of the four cardinal directions — directly on its container. It exists purely for visual presentation: backgrounds, decorative artwork, panel dividers, highlighting, and any other place where a heavy [**PictureBox**](../PictureBox/) would be overkill. +A **Shape** is a windowless lightweight control that draws one of a fixed set of geometric primitives --- rectangle, square, oval, circle, rounded rectangle, rounded square, five-pointed star, or an arrow pointing in any of the four cardinal directions --- directly on its container. It exists purely for visual presentation: backgrounds, decorative artwork, panel dividers, highlighting, and any other place where a heavy [**PictureBox**](../PictureBox/) would be overkill. -A **Shape** has no interactive elements — no focus, no caption, and no mouse, keyboard, or drag events. The shape kind and its appearance are chosen entirely through properties; the only event raised by the control is [**Initialize**](#initialize). The default property is [**Shape**](#shape) and the default event is [**Initialize**](#initialize). +A **Shape** has no interactive elements --- no focus, no caption, and no mouse, keyboard, or drag events. The shape kind and its appearance are chosen entirely through properties; the only event raised by the control is [**Initialize**](#initialize). The default property is [**Shape**](#shape) and the default event is [**Initialize**](#initialize). ```tb Private Sub Form_Load() @@ -28,10 +28,10 @@ End Sub ## Windowless rendering -A **Shape** has no `hWnd`. The framework paints it onto its parent's drawing surface during the parent's paint cycle, so the control is cheap — no Win32 window is created on its behalf and no per-instance overhead beyond a small piece of state. The trade-offs are the same as for any windowless control: +A **Shape** has no `hWnd`. The framework paints it onto its parent's drawing surface during the parent's paint cycle, so the control is cheap --- no Win32 window is created on its behalf and no per-instance overhead beyond a small piece of state. The trade-offs are the same as for any windowless control: - No focus, no keyboard input, no `KeyDown` / `KeyPress` / `KeyUp` / `GotFocus` / `LostFocus` / `Validate`. -- No mouse events of any kind — to make a region clickable, place a transparent [**Label**](../Label/) on top. +- No mouse events of any kind --- to make a region clickable, place a transparent [**Label**](../Label/) on top. - No `hWnd` to pass to API functions, and no `SetFocus`. - Cannot host child controls. @@ -44,9 +44,9 @@ For anything that needs those, use [**PictureBox**](../PictureBox/) or a custom | Constant | Value | Drawn as | |-------------------------------|-------|-----------------------------------------------------------------------------| | **vbShapeRectangle** | 0 | Rectangle filling the control's bounds. | -| **vbShapeSquare** | 1 | Square inscribed in the bounds — the shorter side determines the size, the longer side is centred. | +| **vbShapeSquare** | 1 | Square inscribed in the bounds --- the shorter side determines the size, the longer side is centred. | | **vbShapeOval** | 2 | Ellipse filling the bounds. | -| **vbShapeCircle** | 3 | Circle inscribed in the bounds — the shorter side determines the diameter. | +| **vbShapeCircle** | 3 | Circle inscribed in the bounds --- the shorter side determines the diameter. | | **vbShapeRoundedRectangle** | 4 | Rectangle with rounded corners; corner radius from [**RoundedCornerSize**](#roundedcornersize). | | **vbShapeRoundedSquare** | 5 | Square inscribed in the bounds, with rounded corners. | | **vbShapeStar** | 6 | Regular star polygon; configured through [**VariationA**](#variationa), [**VariationB**](#variationb), and [**VariationC**](#variationc). | @@ -63,14 +63,14 @@ Stars and arrows are parameterised through the three **Variation** properties, a For **vbShapeStar**: -- [**VariationA**](#variationa) — number of points, clamped to the inclusive range `2`–`30`. Default `5`. -- [**VariationB**](#variationb) — inner-radius factor controlling how "thin" the star's arms are. Larger values produce thinner arms. Default chosen so the inner radius is half the outer radius. -- [**VariationC**](#variationc) — vertex-spread divisor, an integer from `1` to `12`. Lower values produce closely-bunched points; higher values produce a more conventional star. Default `12` (effectively a divisor of `2`). +- [**VariationA**](#variationa) -- number of points, clamped to the inclusive range `2`--`30`. Default `5`. +- [**VariationB**](#variationb) -- inner-radius factor controlling how "thin" the star's arms are. Larger values produce thinner arms. Default chosen so the inner radius is half the outer radius. +- [**VariationC**](#variationc) -- vertex-spread divisor, an integer from `1` to `12`. Lower values produce closely-bunched points; higher values produce a more conventional star. Default `12` (effectively a divisor of `2`). For **vbShapeArrowLeft**, **vbShapeArrowRight**, **vbShapeArrowUp**, **vbShapeArrowDown**: -- [**VariationA**](#variationa) — arrowhead "height" along the arrow's axis, as a percentage (`0`–`100`) of the control's cross-axis dimension. Default `30` (i.e. `0.30`). -- [**VariationB**](#variationb) — arrowhead "depth" along the arrow's tip-to-tail axis, as a percentage (`0`–`100`) of the control's axis dimension. Default `50` (i.e. `0.50`). +- [**VariationA**](#variationa) -- arrowhead "height" along the arrow's axis, as a percentage (`0`--`100`) of the control's cross-axis dimension. Default `30` (i.e. `0.30`). +- [**VariationB**](#variationb) -- arrowhead "depth" along the arrow's tip-to-tail axis, as a percentage (`0`--`100`) of the control's axis dimension. Default `50` (i.e. `0.50`). [**VariationC**](#variationc) is unused for arrows. @@ -87,7 +87,7 @@ A **Shape** is painted in three logical layers: | Constant | Value | Interior | |---------------------------|-------|----------------------------------------------------------------| | **vbFSSolid** | 0 | Filled with [**FillColor**](#fillcolor). | -| **vbFSTransparent** | 1 | No fill (default — the shape's interior shows through). | +| **vbFSTransparent** | 1 | No fill (default --- the shape's interior shows through). | | **vbHorizontalLine** | 2 | Horizontal hatch in [**FillColor**](#fillcolor). | | **vbVerticalLine** | 3 | Vertical hatch in [**FillColor**](#fillcolor). | | **vbUpwardDiagonal** | 4 | `/`-direction diagonal hatch. | @@ -103,28 +103,28 @@ The gradient styles (**vbGradientNS**, **vbGradientWE**) use the Win32 `Gradient The outline is drawn with a Win32 GDI pen: -- [**BorderColor**](#bordercolor) — the pen colour (defaults to the system window-text colour). -- [**BorderWidth**](#borderwidth) — the pen width in pixels (default `1`). -- [**BorderStyle**](#borderstyle) — the pen pattern, as a member of [**BorderStyleConstants**](../../VBRUN/Constants/BorderStyleConstants): **vbTransparent** (0 — no outline), **vbBSSolid** (1, default), **vbBSDash** (2), **vbBSDot** (3), **vbBSDashDot** (4), **vbBSDashDotDot** (5), or **vbBSInsideSolid** (6). +- [**BorderColor**](#bordercolor) -- the pen colour (defaults to the system window-text colour). +- [**BorderWidth**](#borderwidth) -- the pen width in pixels (default `1`). +- [**BorderStyle**](#borderstyle) -- the pen pattern, as a member of [**BorderStyleConstants**](../../VBRUN/Constants/BorderStyleConstants): **vbTransparent** (0 --- no outline), **vbBSSolid** (1, default), **vbBSDash** (2), **vbBSDot** (3), **vbBSDashDot** (4), **vbBSDashDotDot** (5), or **vbBSInsideSolid** (6). -As with [**Line**](../Line/), GDI forces a solid pen whenever [**BorderWidth**](#borderwidth) is greater than `1` — dashed and dotted patterns are only honoured at width `1`. +As with [**Line**](../Line/), GDI forces a solid pen whenever [**BorderWidth**](#borderwidth) is greater than `1` --- dashed and dotted patterns are only honoured at width `1`. ## Rotation -[**Angle**](#angle) rotates the rendered shape around the control's top-left point, in degrees, anti-clockwise. `0` (default) is the natural orientation; `90` is a quarter turn anti-clockwise; values between `0` and `360` give arbitrary rotations. The control's bounding rectangle on the parent does not change — large rotation angles can therefore push the visible shape outside the rectangle. The rendered pixels are bounded only by the parent's clip, not by the **Shape**'s own rectangle. +[**Angle**](#angle) rotates the rendered shape around the control's top-left point, in degrees, anti-clockwise. `0` (default) is the natural orientation; `90` is a quarter turn anti-clockwise; values between `0` and `360` give arbitrary rotations. The control's bounding rectangle on the parent does not change --- large rotation angles can therefore push the visible shape outside the rectangle. The rendered pixels are bounded only by the parent's clip, not by the **Shape**'s own rectangle. -Gradient fill styles do not honour rotation — see [Background, fill, and gradients](#background-fill-and-gradients). +Gradient fill styles do not honour rotation --- see [Background, fill, and gradients](#background-fill-and-gradients). ## Draw mode -[**DrawMode**](#drawmode) selects the raster operation that combines the drawn pixels with the destination. A member of [**DrawModeConstants**](../../VBRUN/Constants/DrawModeConstants): **vbCopyPen** (default — opaque drawing) or one of the XOR / AND / NOT / merge variants. Non-default modes are mainly useful for "rubber-band" feedback drawn over an existing background — the same XOR applied twice cancels itself out, restoring the original pixels. +[**DrawMode**](#drawmode) selects the raster operation that combines the drawn pixels with the destination. A member of [**DrawModeConstants**](../../VBRUN/Constants/DrawModeConstants): **vbCopyPen** (default --- opaque drawing) or one of the XOR / AND / NOT / merge variants. Non-default modes are mainly useful for "rubber-band" feedback drawn over an existing background --- the same XOR applied twice cancels itself out, restoring the original pixels. ## Properties ### Anchors {: .no_toc } -The set of edges of the parent that the **Shape**'s corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the **Shape**'s corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Angle {: .no_toc } @@ -159,12 +159,12 @@ The outline pen width, in pixels. **Long**, default `1`. Widths greater than `1` ### Container {: .no_toc } -The control that hosts this **Shape** — typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. +The control that hosts this **Shape** --- typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. ### ControlType {: .no_toc } -A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstants) value identifying this control. Always **vbShape**. This constant is shared with the [**Line**](../Line/) control — both are windowless geometric primitives. +A read-only [**ControlTypeConstants**](../../VBRUN/Constants/ControlTypeConstants) value identifying this control. Always **vbShape**. This constant is shared with the [**Line**](../Line/) control --- both are windowless geometric primitives. ### Dock {: .no_toc } @@ -189,7 +189,7 @@ The secondary colour used as the end of a gradient fill. **OLE_COLOR**, defaults ### FillStyle {: .no_toc } -The pattern used to fill the shape's interior, as a member of [**FillStyleConstantsEx**](../../VBRUN/Constants/FillStyleConstantsEx). Default **vbFSTransparent** (1) — the interior is not painted and shows through to the underlying parent pixels. See [Background, fill, and gradients](#background-fill-and-gradients) for the full table and the caveat for gradients combined with rotation. +The pattern used to fill the shape's interior, as a member of [**FillStyleConstantsEx**](../../VBRUN/Constants/FillStyleConstantsEx). Default **vbFSTransparent** (1) --- the interior is not painted and shows through to the underlying parent pixels. See [Background, fill, and gradients](#background-fill-and-gradients) for the full table and the caveat for gradients combined with rotation. ### Height {: .no_toc } diff --git a/docs/Reference/VB/TextBox/index.md b/docs/Reference/VB/TextBox/index.md index 685de17b..d8b179e0 100644 --- a/docs/Reference/VB/TextBox/index.md +++ b/docs/Reference/VB/TextBox/index.md @@ -31,16 +31,16 @@ End Sub [**MultiLine**](#multiline) selects between the single-line edit (the default) and a multi-line editor: -- **Single-line.** The control accepts a single row of text. Pressing **Enter** does not insert a newline — it is handled by the form's default button, if any. [**ScrollBars**](#scrollbars) and most line-wrapping settings are ignored. +- **Single-line.** The control accepts a single row of text. Pressing **Enter** does not insert a newline --- it is handled by the form's default button, if any. [**ScrollBars**](#scrollbars) and most line-wrapping settings are ignored. - **Multi-line.** The control accepts and displays multiple lines, with line wrapping based on the client width. **Enter** inserts a line break inside the control. [**ScrollBars**](#scrollbars) decides whether horizontal, vertical, both, or no scroll bars are shown. -Changing [**MultiLine**](#multiline), [**ScrollBars**](#scrollbars), or [**HideSelection**](#hideselection) at run time recreates the underlying window — the contents, current [**MaxLength**](#maxlength), [**PasswordChar**](#passwordchar), and [**Locked**](#locked) state are preserved across the recreate. +Changing [**MultiLine**](#multiline), [**ScrollBars**](#scrollbars), or [**HideSelection**](#hideselection) at run time recreates the underlying window --- the contents, current [**MaxLength**](#maxlength), [**PasswordChar**](#passwordchar), and [**Locked**](#locked) state are preserved across the recreate. ## Password masking When [**PasswordChar**](#passwordchar) is set to a non-empty string, the first character of that string is displayed in place of each character the user types. Reading [**Text**](#text) still returns the real characters. Setting [**PasswordChar**](#passwordchar) back to an empty string restores normal display. -Password masking is a single-line edit feature — assigning [**PasswordChar**](#passwordchar) while [**MultiLine**](#multiline) is **True** has no visible effect on the displayed text. +Password masking is a single-line edit feature --- assigning [**PasswordChar**](#passwordchar) while [**MultiLine**](#multiline) is **True** has no visible effect on the displayed text. ```tb txtPassword.PasswordChar = "•" ' display a bullet for each character @@ -48,17 +48,17 @@ txtPassword.PasswordChar = "•" ' display a bullet for each character ## Cue banner -[**TextHint**](#texthint) sets a placeholder string that appears, in a dimmed colour, while [**Text**](#text) is empty — useful for hinting at the expected content without occupying it. By default the hint is hidden as soon as the control receives the focus; set [**TextHintAlways**](#texthintalways) to **True** to keep it visible even when the empty control has focus (until the user starts typing). +[**TextHint**](#texthint) sets a placeholder string that appears, in a dimmed colour, while [**Text**](#text) is empty --- useful for hinting at the expected content without occupying it. By default the hint is hidden as soon as the control receives the focus; set [**TextHintAlways**](#texthintalways) to **True** to keep it visible even when the empty control has focus (until the user starts typing). ## Selection [**SelStart**](#selstart), [**SelLength**](#sellength), and [**SelText**](#seltext) read and modify the user's text selection. Reading any of them when no selection is active returns the caret position and an empty [**SelText**](#seltext). Assigning [**SelStart**](#selstart) or [**SelLength**](#sellength) scrolls the caret into view; assigning [**SelText**](#seltext) replaces the current selection with the assigned string and positions the caret immediately after the inserted text. -By default the selection is hidden whenever the control loses focus. Set [**HideSelection**](#hideselection) to **False** to keep the highlight visible even when another control has the focus — useful when the application needs to draw the user's attention to a particular range of text after a search or validation. +By default the selection is hidden whenever the control loses focus. Set [**HideSelection**](#hideselection) to **False** to keep the highlight visible even when another control has the focus --- useful when the application needs to draw the user's attention to a particular range of text after a search or validation. ## Numbers only -When [**NumbersOnly**](#numbersonly) is **True**, the edit control silently rejects any keystroke that is not a decimal digit. Sign characters, decimal separators, and thousand separators are *not* accepted — the property is a thin wrapper around the OS **ES_NUMBER** style and provides only digit filtering. Use a [**KeyPress**](#keypress) handler if you need more elaborate validation. +When [**NumbersOnly**](#numbersonly) is **True**, the edit control silently rejects any keystroke that is not a decimal digit. Sign characters, decimal separators, and thousand separators are *not* accepted --- the property is a thin wrapper around the OS **ES_NUMBER** style and provides only digit filtering. Use a [**KeyPress**](#keypress) handler for more elaborate validation. ## OLE drag-and-drop @@ -68,7 +68,7 @@ When [**NumbersOnly**](#numbersonly) is **True**, the edit control silently reje ## Data binding -Setting [**DataSource**](#datasource) and [**DataField**](#datafield) connects the control's [**Text**](#text) to a field of a [**Data**](../Data) control's recordset. The bound value is read as a string on each row change (a **Null** field becomes an empty string), and the current [**Text**](#text) is written back when the row is saved. Modifying [**Text**](#text) — either by user input or by code — sets [**DataChanged**](#datachanged) and marks the recordset row as dirty. +Setting [**DataSource**](#datasource) and [**DataField**](#datafield) connects the control's [**Text**](#text) to a field of a [**Data**](../Data) control's recordset. The bound value is read as a string on each row change (a **Null** field becomes an empty string), and the current [**Text**](#text) is written back when the row is saved. Modifying [**Text**](#text) --- either by user input or by code --- sets [**DataChanged**](#datachanged) and marks the recordset row as dirty. ## Properties @@ -85,12 +85,12 @@ Syntax: *object*.**Alignment** [ = *value* ] ### Anchors {: .no_toc } -The set of edges of the parent that the text box's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the text box's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### Appearance {: .no_toc } -Determines how the control's border is drawn by the OS. A member of [**AppearanceConstants**](../../VBRUN/Constants/AppearanceConstants): **vbAppearFlat** or **vbAppear3d** (default). Only meaningful when [**BorderStyle**](#borderstyle) is **vbFixedSingleBorder** — chooses between a sunken 3-D edge and a thin flat border. +Determines how the control's border is drawn by the OS. A member of [**AppearanceConstants**](../../VBRUN/Constants/AppearanceConstants): **vbAppearFlat** or **vbAppear3d** (default). Only meaningful when [**BorderStyle**](#borderstyle) is **vbFixedSingleBorder** --- chooses between a sunken 3-D edge and a thin flat border. ### BackColor {: .no_toc } @@ -110,7 +110,7 @@ Determines whether the previously focused control's [**Validate**](#validate) ev ### Container {: .no_toc } -The control that hosts this text box — typically the form, a [**Frame**](../Frame), or a [**PictureBox**](../PictureBox). Read with **Get**, change with **Set**. Setting **Container** at run time re-parents the text box. +The control that hosts this text box --- typically the form, a [**Frame**](../Frame), or a [**PictureBox**](../PictureBox). Read with **Get**, change with **Set**. Setting **Container** at run time re-parents the text box. ### ControlType {: .no_toc } @@ -161,7 +161,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -191,7 +191,7 @@ Shortcut for [**Font**](#font)`.Name`. **String**. ### FontSize {: .no_toc } -Shortcut for [**Font**](#font)`.Size` — the point size. **Single**. +Shortcut for [**Font**](#font)`.Size` --- the point size. **Single**. ### FontStrikethru {: .no_toc } @@ -267,12 +267,12 @@ A member of [**LinkModeConstants**](../../VBRUN/Constants/LinkModeConstants). ### Locked {: .no_toc } -When **True**, the user can scroll, select, and copy text but cannot modify it. **Boolean**, default **False**. Distinct from [**Enabled**](#enabled) — a locked text box is still drawn normally and continues to raise focus and mouse events, whereas a disabled one is dimmed and ignores input entirely. +When **True**, the user can scroll, select, and copy text but cannot modify it. **Boolean**, default **False**. Distinct from [**Enabled**](#enabled) --- a locked text box is still drawn normally and continues to raise focus and mouse events, whereas a disabled one is dimmed and ignores input entirely. ### MaxLength {: .no_toc } -The maximum number of characters the user can type into the control. **Long**, default `0` — when zero, the OS imposes its own limit (typically 32 767 characters for single-line, much larger for multi-line). Setting **MaxLength** below the current text length does not truncate what is already there, but blocks further typing until the user deletes enough characters. +The maximum number of characters the user can type into the control. **Long**, default `0` --- when zero, the OS imposes its own limit (typically 32 767 characters for single-line, much larger for multi-line). Setting **MaxLength** below the current text length does not truncate what is already there, but blocks further typing until the user deletes enough characters. ### MouseIcon {: .no_toc } @@ -297,12 +297,12 @@ The unique design-time name of the control on its parent form. Read-only at run ### NumbersOnly {: .no_toc } -When **True**, the edit control rejects keystrokes other than the decimal digits **0**–**9**. **Boolean**, default **False**. Does not validate code-assigned values, sign characters, decimal points, or thousand separators — use a [**KeyPress**](#keypress) handler for additional validation. +When **True**, the edit control rejects keystrokes other than the decimal digits **0**--**9**. **Boolean**, default **False**. Does not validate code-assigned values, sign characters, decimal points, or thousand separators --- use a [**KeyPress**](#keypress) handler for additional validation. ### OLEDragMode {: .no_toc } -Whether the control's selected text can act as an automatic OLE drag source. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default — call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1). +Whether the control's selected text can act as an automatic OLE drag source. A member of [**OLEDragConstants**](../../VBRUN/Constants/OLEDragConstants): **vbOLEDragManual** (0, default --- call [**OLEDrag**](#oledrag) from code) or **vbOLEDragAutomatic** (1). ### OLEDropMode {: .no_toc } @@ -312,7 +312,7 @@ How the control responds to OLE drops. A member of [**OLEDropConstants**](../../ ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -335,7 +335,7 @@ A **String** whose first character is displayed in place of each typed character Which scroll bars the multi-line text box displays. A member of [**ScrollBarConstants**](../../VBRUN/Constants/ScrollBarConstants): **vbSBNone** (0, default), **vbHorizontal** (1), **vbVertical** (2), or **vbBoth** (3). Ignored when [**MultiLine**](#multiline) is **False**. Changing this at run time recreates the underlying window. -When the vertical scroll bar is enabled in a wrapping multi-line box, the horizontal scroll bar disables word wrap — lines extend past the right edge instead of wrapping. +When the vertical scroll bar is enabled in a wrapping multi-line box, the horizontal scroll bar disables word wrap --- lines extend past the right edge instead of wrapping. ### SelLength {: .no_toc } @@ -355,7 +355,7 @@ The text currently selected. Assigning a string replaces the selection with that ### TabFocusAutoSelect {: .no_toc } -When **True** (default), the entire contents of the text box are automatically selected when the user moves focus to it with the **TAB** key. **Boolean**. The parent form's `TabFocusAutoSelect` property must also be **True** for this setting to take effect — when the form-level switch is **False**, the per-control value is ignored. +When **True** (default), the entire contents of the text box are automatically selected when the user moves focus to it with the **TAB** key. **Boolean**. The parent form's `TabFocusAutoSelect` property must also be **True** for this setting to take effect --- when the form-level switch is **False**, the per-control value is ignored. ### TabIndex {: .no_toc } @@ -384,7 +384,7 @@ Assigning a value that differs from the current one raises a [**Change**](#chang ### TextHint {: .no_toc } -A placeholder **String** displayed in a dimmed colour when [**Text**](#text) is empty — the Win32 *cue banner*. Default empty (no cue). The hint disappears as soon as the user starts typing. +A placeholder **String** displayed in a dimmed colour when [**Text**](#text) is empty --- the Win32 *cue banner*. Default empty (no cue). The hint disappears as soon as the user starts typing. ### TextHintAlways {: .no_toc } @@ -523,7 +523,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Change {: .no_toc } -Raised whenever [**Text**](#text) changes — either through user input or by code assigning a new value. Not raised during [**Initialize**](#initialize); the very first text load from the serialized form does not produce a **Change** event. **Default-designer event.** +Raised whenever [**Text**](#text) changes --- either through user input or by code assigning a new value. Not raised during [**Initialize**](#initialize); the very first text load from the serialized form does not produce a **Change** event. **Default-designer event.** Syntax: *object*\_**Change**( ) @@ -645,7 +645,7 @@ Syntax: *object*\_**MouseUp**( *Button* **As Integer**, *Shift* **As Integer**, ### MouseWheel {: .no_toc } -Raised when the user rotates the mouse wheel while the control has focus or the cursor is over it. New in twinBASIC — there is no equivalent VB6 event. +Raised when the user rotates the mouse wheel while the control has focus or the cursor is over it. New in twinBASIC --- there is no equivalent VB6 event. Syntax: *object*\_**MouseWheel**( *Delta* **As Integer**, *Horizontal* **As Boolean** ) @@ -700,7 +700,7 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Scroll {: .no_toc } -Raised when a multi-line text box is scrolled — by the scroll bar (including thumb-track dragging), the keyboard, or the mouse wheel. Wheel-driven scrolling can be silenced by setting [**WheelScrollEvent**](#wheelscrollevent) to **False**. New in twinBASIC — there is no equivalent VB6 event. +Raised when a multi-line text box is scrolled --- by the scroll bar (including thumb-track dragging), the keyboard, or the mouse wheel. Wheel-driven scrolling can be silenced by setting [**WheelScrollEvent**](#wheelscrollevent) to **False**. New in twinBASIC --- there is no equivalent VB6 event. Syntax: *object*\_**Scroll**( ) diff --git a/docs/Reference/VB/Timer/index.md b/docs/Reference/VB/Timer/index.md index ba900acf..e1ee6661 100644 --- a/docs/Reference/VB/Timer/index.md +++ b/docs/Reference/VB/Timer/index.md @@ -8,7 +8,7 @@ has_toc: false # Timer class {: .no_toc } -A **Timer** is a non-visual Win32 control that raises a [**Timer**](#timer) event at a programmable interval. Drop one onto a [**Form**](../Form/) (or **UserControl**) at design time, set [**Interval**](#interval) to the desired millisecond period, set [**Enabled**](#enabled) to **True**, and handle the [**Timer**](#timer) event. Timers are invisible at run time — they appear only as icons in the designer. +A **Timer** is a non-visual Win32 control that raises a [**Timer**](#timer) event at a programmable interval. Drop one onto a [**Form**](../Form/) (or **UserControl**) at design time, set [**Interval**](#interval) to the desired millisecond period, set [**Enabled**](#enabled) to **True**, and handle the [**Timer**](#timer) event. Timers are invisible at run time --- they appear only as icons in the designer. The default property is [**Enabled**](#enabled) and the default event is [**Timer**](#timer). @@ -33,7 +33,7 @@ Two properties between them decide whether the [**Timer**](#timer) event fires: - [**Enabled**](#enabled) is the master switch. While it is **False**, the timer is dormant regardless of [**Interval**](#interval). - [**Interval**](#interval) is the period between events, in milliseconds. Setting it to `0` stops events from firing even while [**Enabled**](#enabled) remains **True**. -Either property can be flipped from inside the [**Timer**](#timer) handler itself — a one-shot timer disables itself on the first tick: +Either property can be flipped from inside the [**Timer**](#timer) handler itself --- a one-shot timer disables itself on the first tick: ```tb Private Sub tmrStartup_Timer() @@ -48,8 +48,8 @@ Assigning a negative value to [**Interval**](#interval) raises run-time error 38 The control wraps Win32's per-window timer queue, which runs on the standard message pump. Two consequences follow: -- **Resolution is coarse.** The OS quantises timer ticks to the system clock-tick period — typically ~15.6 ms on desktop Windows. Intervals shorter than that are silently rounded up. For sub-millisecond pacing use a multimedia timer or `QueryPerformanceCounter` directly. -- **Ticks can be skipped under load.** If the message pump is blocked when a tick is due, no events queue up — the runtime delivers a single [**Timer**](#timer) event when the pump resumes, *not* one for each missed period. Long-running work inside the handler therefore lengthens the next interval rather than producing a backlog. +- **Resolution is coarse.** The OS quantises timer ticks to the system clock-tick period --- typically ~15.6 ms on desktop Windows. Intervals shorter than that are silently rounded up. For sub-millisecond pacing use a multimedia timer or `QueryPerformanceCounter` directly. +- **Ticks can be skipped under load.** If the message pump is blocked when a tick is due, no events queue up --- the runtime delivers a single [**Timer**](#timer) event when the pump resumes, *not* one for each missed period. Long-running work inside the handler therefore lengthens the next interval rather than producing a backlog. For periodic UI updates (a clock, a progress animation, a poll for external state) the **Timer** is exactly the right tool. For precise wall-clock pacing, audio scheduling, or anything that must keep up under heavy CPU load, it is not. @@ -103,7 +103,7 @@ The effective resolution is the OS clock-tick period (~15.6 ms on desktop Window ### Left {: .no_toc } -The horizontal position of the timer icon in the designer, in the container's **ScaleMode** units. **Single**. The runtime value has no visual effect — the timer is invisible — but it is preserved so the designer can place the icon back where it was. +The horizontal position of the timer icon in the designer, in the container's **ScaleMode** units. **Single**. The runtime value has no visual effect --- the timer is invisible --- but it is preserved so the designer can place the icon back where it was. ### Name {: .no_toc } @@ -118,7 +118,7 @@ A reference to the [**Form**](../Form/) (or **UserControl**) that contains this ### Tag {: .no_toc } -A free-form **String** the application can use to associate custom data with the timer. Ignored by the framework. Inherited from the base control class. Useful for control arrays — e.g. holding the name of the operation a poll-timer is responsible for. +A free-form **String** the application can use to associate custom data with the timer. Ignored by the framework. Inherited from the base control class. Useful for control arrays --- e.g. holding the name of the operation a poll-timer is responsible for. ### Top {: .no_toc } @@ -138,4 +138,4 @@ For a timer that is part of a control array, the handler receives the array [**I Syntax: *object*\_**Timer**( *Index* **As Integer** ) -The event is delivered through the normal Win32 message pump — see [Accuracy and resolution](#accuracy-and-resolution) for the implications. +The event is delivered through the normal Win32 message pump --- see [Accuracy and resolution](#accuracy-and-resolution) for the implications. diff --git a/docs/Reference/VB/UserControl/index.md b/docs/Reference/VB/UserControl/index.md index e0bf7012..1a0cbea7 100644 --- a/docs/Reference/VB/UserControl/index.md +++ b/docs/Reference/VB/UserControl/index.md @@ -8,11 +8,11 @@ has_toc: false # UserControl class {: .no_toc } -A **UserControl** is the base class for designing a reusable ActiveX control in twinBASIC. Each control designed in the IDE becomes its own class derived from **UserControl** — its child controls become members of that class, its event handlers become methods on it, and the file's name becomes the COM class name registered with the runtime. Hosts that embed the control (the twinBASIC IDE, classic VB6, Office, any other ActiveX container) talk to it through the standard ActiveX control interfaces, while the design-time code-behind talks to it as a regular twinBASIC class. +A **UserControl** is the base class for designing a reusable ActiveX control in twinBASIC. Each control designed in the IDE becomes its own class derived from **UserControl** --- its child controls become members of that class, its event handlers become methods on it, and the file's name becomes the COM class name registered with the runtime. Hosts that embed the control (the twinBASIC IDE, classic VB6, Office, any other ActiveX container) talk to it through the standard ActiveX control interfaces, while the design-time code-behind talks to it as a regular twinBASIC class. A **UserControl** is not directly visible at run time as a property of an outer form. The host wraps it in an **Extender** object that adds the standard container properties (**Top**, **Left**, **Width**, **Height**, **Name**, **Visible**, **TabIndex**, …) and the user code reaches the extender through [**Extender**](#extender). The inner **UserControl** keeps a graphics surface, a private property bag, and the lifecycle events through which the host loads and saves the control's persistent state. -The default-designer event is [**Initialize**](#initialize) — double-clicking the control surface in the IDE adds a `UserControl_Initialize` handler. +The default-designer event is [**Initialize**](#initialize) --- double-clicking the control surface in the IDE adds a `UserControl_Initialize` handler. ```tb ' In MyMonthView's code-behind: @@ -54,8 +54,8 @@ A user control instance goes through up to seven distinct events from creation t | [**InitProperties**](#initproperties) | Once, for a brand-new instance with no saved property bag (a fresh drop on a design surface). | | [**ReadProperties**](#readproperties) | Once, for an instance reloaded from a property bag (every load after the first save). | | [**Resize**](#resize) | When the host first sizes the control, and on every subsequent size change. | -| [**Show**](#show) / [**Hide**](#hide) | When the host changes the container's visibility — typically as the host's design view / run view changes. | -| [**WriteProperties**](#writeproperties)| When the host asks the control to persist its state — design-time saves, host-initiated serialisation. | +| [**Show**](#show) / [**Hide**](#hide) | When the host changes the container's visibility --- typically as the host's design view / run view changes. | +| [**WriteProperties**](#writeproperties)| When the host asks the control to persist its state --- design-time saves, host-initiated serialisation. | | [**Terminate**](#terminate) | After the window has been destroyed and the class instance is about to be released. | For each instance, exactly one of **InitProperties** or **ReadProperties** runs after [**Initialize**](#initialize), depending on whether the host had a saved property bag. [**WriteProperties**](#writeproperties) is only raised when [**PropertyChanged**](#propertychanged) has been called at least once since the last save, so handlers that never mark themselves dirty are never asked to write. @@ -73,7 +73,7 @@ End Property ## Host integration -[**Extender**](#extender) returns the host's wrapper around this control — usually an object exposing **Top**, **Left**, **Width**, **Height**, **Name**, **Visible**, **TabIndex**, **TabStop**, **Container**, **Parent**, and any host-specific extras. [**Parent**](#parent) is shorthand for `Extender.Parent` — the form (or sheet, or page) that ultimately hosts the control. [**ParentControls**](#parentcontrols) is a live enumerator over every sibling control on that parent, useful for design-time inspection. +[**Extender**](#extender) returns the host's wrapper around this control --- usually an object exposing **Top**, **Left**, **Width**, **Height**, **Name**, **Visible**, **TabIndex**, **TabStop**, **Container**, **Parent**, and any host-specific extras. [**Parent**](#parent) is shorthand for `Extender.Parent` --- the form (or sheet, or page) that ultimately hosts the control. [**ParentControls**](#parentcontrols) is a live enumerator over every sibling control on that parent, useful for design-time inspection. [**Ambient**](#ambient) exposes the host's ambient properties (the colours, font, locale, and design/run-mode flags the host wants child controls to honour). Changes to any of those raise the [**AmbientChanged**](#ambientchanged) event with the name of the affected property. @@ -81,25 +81,25 @@ End Property ## Drawing surface -A **UserControl** is a graphics surface in its own right. The full set of VB6 drawing primitives — [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and the [**Print**](#print) statement — write to its device context, using [**ForeColor**](#forecolor), [**FillColor**](#fillcolor)/[**FillStyle**](#fillstyle), [**DrawWidth**](#drawwidth), [**DrawMode**](#drawmode), and [**DrawStyle**](#drawstyle) for the pen and fill, and [**Font**](#font) for text. The current pen position is tracked by [**CurrentX**](#currentx) and [**CurrentY**](#currenty); [**TextWidth**](#textwidth) and [**TextHeight**](#textheight) measure a string in the current font; [**ScaleX**](#scalex) and [**ScaleY**](#scaley) convert single coordinates between scale modes. +A **UserControl** is a graphics surface in its own right. The full set of VB6 drawing primitives --- [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and the [**Print**](#print) statement --- write to its device context, using [**ForeColor**](#forecolor), [**FillColor**](#fillcolor)/[**FillStyle**](#fillstyle), [**DrawWidth**](#drawwidth), [**DrawMode**](#drawmode), and [**DrawStyle**](#drawstyle) for the pen and fill, and [**Font**](#font) for text. The current pen position is tracked by [**CurrentX**](#currentx) and [**CurrentY**](#currenty); [**TextWidth**](#textwidth) and [**TextHeight**](#textheight) measure a string in the current font; [**ScaleX**](#scalex) and [**ScaleY**](#scaley) convert single coordinates between scale modes. -The coordinate system is governed by [**ScaleMode**](#scalemode), [**ScaleLeft**](#scaleleft), [**ScaleTop**](#scaletop), [**ScaleWidth**](#scalewidth), and [**ScaleHeight**](#scaleheight), exactly as on a [**Form**](../Form). [**AutoRedraw**](#autoredraw) controls whether drawn output persists across paints — when **False** (default), the [**Paint**](#paint) event must redraw on every invalidation; when **True**, the control keeps an off-screen buffer that survives invalidations and the **Paint** event is suppressed. +The coordinate system is governed by [**ScaleMode**](#scalemode), [**ScaleLeft**](#scaleleft), [**ScaleTop**](#scaletop), [**ScaleWidth**](#scalewidth), and [**ScaleHeight**](#scaleheight), exactly as on a [**Form**](../Form). [**AutoRedraw**](#autoredraw) controls whether drawn output persists across paints --- when **False** (default), the [**Paint**](#paint) event must redraw on every invalidation; when **True**, the control keeps an off-screen buffer that survives invalidations and the **Paint** event is suppressed. -[**BackStyle**](#backstyle) chooses between an opaque background (the default — **BackColor** fills the surface) and a transparent one (the background is left untouched so that whatever is behind the control shows through). Transparent **UserControl**s are commonly windowless ([**Windowless**](#windowless) = **True**) so that mouse hit-testing follows the painted shape rather than the bounding rectangle. +[**BackStyle**](#backstyle) chooses between an opaque background (the default --- **BackColor** fills the surface) and a transparent one (the background is left untouched so that whatever is behind the control shows through). Transparent **UserControl**s are commonly windowless ([**Windowless**](#windowless) = **True**) so that mouse hit-testing follows the painted shape rather than the bounding rectangle. ## Windowless mode -Setting [**Windowless**](#windowless) to **True** asks the host to embed the control without giving it its own **HWND**. The control's painting goes through `IViewObject::Draw`, mouse hit-testing through `IViewObjectEx::QueryHitPoint`, and so on; the [**HitTest**](#hittest) event raises for each hit-test request so the control can refine which pixels register as "hits". Many hosts support windowless activation (the twinBASIC IDE, Office); some hosts do not — the framework transparently falls back to a windowed mode at activation time when that happens. +Setting [**Windowless**](#windowless) to **True** asks the host to embed the control without giving it its own **HWND**. The control's painting goes through `IViewObject::Draw`, mouse hit-testing through `IViewObjectEx::QueryHitPoint`, and so on; the [**HitTest**](#hittest) event raises for each hit-test request so the control can refine which pixels register as "hits". Many hosts support windowless activation (the twinBASIC IDE, Office); some hosts do not --- the framework transparently falls back to a windowed mode at activation time when that happens. -[**hWnd**](#hwnd) returns `0` while the control is windowless-activated. [**PreKeyEvents**](#prekeyevents) — and the [**PreKeyDown**](#prekeydown) / [**PreKeyUp**](#prekeyup) events — are not available on a windowless **UserControl**. +[**hWnd**](#hwnd) returns `0` while the control is windowless-activated. [**PreKeyEvents**](#prekeyevents) --- and the [**PreKeyDown**](#prekeydown) / [**PreKeyUp**](#prekeyup) events --- are not available on a windowless **UserControl**. ## Children and focus -The **UserControl** can host child controls dropped onto it at design time. [**Controls**](#controls) is the collection of every such child, indexable by control name or zero-based position. The control is enumerable directly (`For Each ctrl In UserControl`) — [**Count**](#count) and [**InternalEnumerator**](#internalenumerator) forward to it. [**ContainedControls**](#containedcontrols) enumerates the same collection but as raw `IUnknown` references for low-level COM work. +The **UserControl** can host child controls dropped onto it at design time. [**Controls**](#controls) is the collection of every such child, indexable by control name or zero-based position. The control is enumerable directly (`For Each ctrl In UserControl`) --- [**Count**](#count) and [**InternalEnumerator**](#internalenumerator) forward to it. [**ContainedControls**](#containedcontrols) enumerates the same collection but as raw `IUnknown` references for low-level COM work. -[**ActiveControl**](#activecontrol) returns the focused child, or **Nothing** when no control on this surface has the focus. [**SetFocus**](#setfocus) gives the focus to the **UserControl** itself, which forwards it to its tab order. [**KeyPreview**](#keypreview) routes keystrokes through the **UserControl**'s [**KeyDown**](#keydown), [**KeyUp**](#keyup), and [**KeyPress**](#keypress) events *before* the focused child sees them — useful for handling **Escape**, **Tab**, or container-wide hotkeys. +[**ActiveControl**](#activecontrol) returns the focused child, or **Nothing** when no control on this surface has the focus. [**SetFocus**](#setfocus) gives the focus to the **UserControl** itself, which forwards it to its tab order. [**KeyPreview**](#keypreview) routes keystrokes through the **UserControl**'s [**KeyDown**](#keydown), [**KeyUp**](#keyup), and [**KeyPress**](#keypress) events *before* the focused child sees them --- useful for handling **Escape**, **Tab**, or container-wide hotkeys. -[**EnterFocus**](#enterfocus) and [**ExitFocus**](#exitfocus) fire when the focus enters or leaves the **UserControl** as a whole (the control itself or any descendant); [**GotFocus**](#gotfocus) and [**LostFocus**](#lostfocus) fire only when the **UserControl**'s own window — and no child — holds the focus. +[**EnterFocus**](#enterfocus) and [**ExitFocus**](#exitfocus) fire when the focus enters or leaves the **UserControl** as a whole (the control itself or any descendant); [**GotFocus**](#gotfocus) and [**LostFocus**](#lostfocus) fire only when the **UserControl**'s own window --- and no child --- holds the focus. ## Properties @@ -128,14 +128,14 @@ A snapshot of the host's [**AmbientProperties**](../../VBRUN/AmbientProperties/) ### Appearance {: .no_toc } -A member of [**AppearanceConstants**](../../VBRUN/Constants/AppearanceConstants): **vbAppearFlat** or **vbAppear3d** (default). Only meaningful when [**BorderStyle**](#borderstyle) is **vbFixedSingleBorder** — controls whether the border is drawn flat or 3-D. +A member of [**AppearanceConstants**](../../VBRUN/Constants/AppearanceConstants): **vbAppearFlat** or **vbAppear3d** (default). Only meaningful when [**BorderStyle**](#borderstyle) is **vbFixedSingleBorder** --- controls whether the border is drawn flat or 3-D. ### AutoRedraw {: .no_toc } Whether drawing performed on the control persists across invalidations. **Boolean**, default **False**. -When **False**, drawing primitives — [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and [**Print**](#print) — paint directly to the screen and the control must redraw them in its [**Paint**](#paint) event whenever the affected area is invalidated. When **True**, the control keeps an off-screen bitmap, drawing primitives paint into it (and immediately to the screen), the bitmap survives invalidations, and the **Paint** event is suppressed. Reading [**Image**](#image) returns this bitmap. +When **False**, drawing primitives --- [**Cls**](#cls), [**Circle**](#circle), [**Line**](#line), [**PSet**](#pset), [**PaintPicture**](#paintpicture), and [**Print**](#print) --- paint directly to the screen and the control must redraw them in its [**Paint**](#paint) event whenever the affected area is invalidated. When **True**, the control keeps an off-screen bitmap, drawing primitives paint into it (and immediately to the screen), the bitmap survives invalidations, and the **Paint** event is suppressed. Reading [**Image**](#image) returns this bitmap. ### BackColor {: .no_toc } @@ -145,7 +145,7 @@ The background colour of the control's surface, as an **OLE_COLOR**. Defaults to ### BackStyle {: .no_toc } -Whether the control's background is opaque or transparent. A member of [**BackFillStyleConstants**](../../VBRUN/Constants/BackFillStyleConstants): **vbBFTransparent** (0) or **vbBFOpaque** (1, default). Setting **BackStyle** to **vbBFTransparent** stops the framework from clearing the surface to [**BackColor**](#backcolor) on each paint — useful when the control wants to draw a non-rectangular shape over whatever is behind it. Typically used with [**Windowless**](#windowless) = **True**. +Whether the control's background is opaque or transparent. A member of [**BackFillStyleConstants**](../../VBRUN/Constants/BackFillStyleConstants): **vbBFTransparent** (0) or **vbBFOpaque** (1, default). Setting **BackStyle** to **vbBFTransparent** stops the framework from clearing the surface to [**BackColor**](#backcolor) on each paint --- useful when the control wants to draw a non-rectangular shape over whatever is behind it. Typically used with [**Windowless**](#windowless) = **True**. ### BorderStyle {: .no_toc } @@ -180,7 +180,7 @@ Whether the **UserControl** acts as a container that can host other ActiveX cont ### Controls {: .no_toc } -The collection of every child control hosted by this **UserControl**, indexable by control name or zero-based position. Read-only — controls are added to the collection by the runtime, not by user code. +The collection of every child control hosted by this **UserControl**, indexable by control name or zero-based position. Read-only --- controls are added to the collection by the runtime, not by user code. ```tb Dim ctrl As Control @@ -271,7 +271,7 @@ Whether the host has temporarily suspended event delivery to the control. **Bool ### Extender {: .no_toc } -The host's extender wrapper around this **UserControl**, as an **Object**. Read-only. The extender is the object the host exposes to user code as the control on the form — it provides standard container properties (**Top**, **Left**, **Width**, **Height**, **Name**, **Visible**, **TabIndex**, **TabStop**, **Container**, **Parent**, **DragMode**, **DragIcon**, …) plus whatever host-specific extras it likes. Returns **Nothing** when no extender is available (the control has not yet been embedded, or the host is too primitive to provide one). +The host's extender wrapper around this **UserControl**, as an **Object**. Read-only. The extender is the object the host exposes to user code as the control on the form --- it provides standard container properties (**Top**, **Left**, **Width**, **Height**, **Name**, **Visible**, **TabIndex**, **TabStop**, **Container**, **Parent**, **DragMode**, **DragIcon**, …) plus whatever host-specific extras it likes. Returns **Nothing** when no extender is available (the control has not yet been embedded, or the host is too primitive to provide one). ### FillColor {: .no_toc } @@ -306,7 +306,7 @@ Shortcut for [**Font**](#font)`.Name`. **String**. ### FontSize {: .no_toc } -Shortcut for [**Font**](#font)`.Size` — the point size. **Single**. +Shortcut for [**Font**](#font)`.Size` --- the point size. **Single**. ### FontStrikethru {: .no_toc } @@ -342,12 +342,12 @@ The pen colour used by [**Circle**](#circle), [**Line**](#line), [**PSet**](#pse ### FormDesignerId {: .no_toc } -A unique GUID-formatted **String** associating a designed code-behind class with a specific designer file. Read-only at run time — set by the IDE. +A unique GUID-formatted **String** associating a designed code-behind class with a specific designer file. Read-only at run time --- set by the IDE. ### HasDC {: .no_toc } -Whether the control keeps a private device context (`CS_OWNDC`) for its drawing surface. **Boolean**, default **True**. Read-only at run time — set at design time. +Whether the control keeps a private device context (`CS_OWNDC`) for its drawing surface. **Boolean**, default **True**. Read-only at run time --- set at design time. ### HitBehavior {: .no_toc } @@ -374,7 +374,7 @@ The Win32 window handle for the control, as a **LongPtr**. Read-only. Returns `0 ### Image {: .no_toc } -Returns the rendered drawing surface as a **StdPicture**. Read-only. Most useful when [**AutoRedraw**](#autoredraw) is **True** — the returned picture is the persistent off-screen buffer. +Returns the rendered drawing surface as a **StdPicture**. Read-only. Most useful when [**AutoRedraw**](#autoredraw) is **True** --- the returned picture is the persistent off-screen buffer. ### Index {: .no_toc } @@ -421,7 +421,7 @@ The mouse cursor shown when the pointer is over the control. A member of [**Mous ### Name {: .no_toc } -The unique design-time name of the **UserControl** class. Read-only at run time. Also the class name of the generated user-control class. The host's extender exposes its own **Name** that identifies the instance on the form — the inner **UserControl**'s **Name** identifies the *class*. +The unique design-time name of the **UserControl** class. Read-only at run time. Also the class name of the generated user-control class. The host's extender exposes its own **Name** that identifies the instance on the form --- the inner **UserControl**'s **Name** identifies the *class*. ### Palette {: .no_toc } @@ -443,7 +443,7 @@ The form (or other host object) that contains this **UserControl**, as an **Obje ### ParentControls {: .no_toc } -A live collection of every sibling control on the host's parent — useful at design time for inspecting or coordinating with other controls on the same surface. Read-only. Supports indexed access (`ParentControls(0)`), enumeration (`For Each ctl In ParentControls`), and a **Count** member. Its **ParentControlsType** property toggles between the *extender*-wrapped view (the default — items are the host's extender objects) and the *raw* view (items are the inner `IUnknown` of each control). +A live collection of every sibling control on the host's parent --- useful at design time for inspecting or coordinating with other controls on the same surface. Read-only. Supports indexed access (`ParentControls(0)`), enumeration (`For Each ctl In ParentControls`), and a **Count** member. Its **ParentControlsType** property toggles between the *extender*-wrapped view (the default --- items are the host's extender objects) and the *raw* view (items are the inner `IUnknown` of each control). ### PictureDpiScaling {: .no_toc } @@ -459,12 +459,12 @@ A **StdPicture** drawn as the control's background. Painted before any drawing p ### PreKeyEvents {: .no_toc } -Whether the [**PreKeyDown**](#prekeydown) and [**PreKeyUp**](#prekeyup) events are raised for descendants of this **UserControl**. **Boolean**, read-only at run time — set at design time. Not available when [**Windowless**](#windowless) is **True**. +Whether the [**PreKeyDown**](#prekeydown) and [**PreKeyUp**](#prekeyup) events are raised for descendants of this **UserControl**. **Boolean**, read-only at run time --- set at design time. Not available when [**Windowless**](#windowless) is **True**. ### PropertyPages {: .no_toc } -An array of **String** **CLSID**s identifying the [**PropertyPage**](../PropertyPage) classes the host should offer through the **(Custom)** entry on the property browser. Read at the host's `ISpecifyPropertyPages::GetPages` call. Order matters — the array order is the tab order in the property-sheet dialog. +An array of **String** **CLSID**s identifying the [**PropertyPage**](../PropertyPage) classes the host should offer through the **(Custom)** entry on the property browser. Read at the host's `ISpecifyPropertyPages::GetPages` call. Order matters --- the array order is the tab order in the property-sheet dialog. ```tb Private Sub UserControl_Initialize() @@ -524,7 +524,7 @@ The vertical position of the **UserControl** inside its host container, in the h ### Verbs {: .no_toc } -An array of **String** names registered with the host's `IOleObject::EnumVerbs` enumerator — each entry appears on the host's right-click menu for this control. Invoking one raises [**VerbInvoked**](#verbinvoked) with the verb's name. +An array of **String** names registered with the host's `IOleObject::EnumVerbs` enumerator --- each entry appears on the host's right-click menu for this control. Invoking one raises [**VerbInvoked**](#verbinvoked) with the verb's name. ```tb Private Sub UserControl_Initialize() @@ -554,7 +554,7 @@ The control's height. **Double**. Setting it resizes the control and raises [**R ### Windowless {: .no_toc } -Whether the control supports windowless activation. **Boolean**, default **False**. Read-only at run time — set at design time. See [Windowless mode](#windowless-mode). +Whether the control supports windowless activation. **Boolean**, default **False**. Read-only at run time --- set at design time. See [Windowless mode](#windowless-mode). ## Methods @@ -578,7 +578,7 @@ Syntax: *object*.**CancelAsyncRead** [ *Property* ] {: .no_toc } > [!NOTE] -> Declared for VB6 compatibility; not currently implemented in twinBASIC. In VB6 this returned **True** if the named property of the **DataSource** was writable — used by data-bound controls before pushing edited values back to the source. +> Declared for VB6 compatibility; not currently implemented in twinBASIC. In VB6 this returned **True** if the named property of the **DataSource** was writable --- used by data-bound controls before pushing edited values back to the source. Syntax: *object*.**CanPropertyChange**( *PropertyName* ) @@ -690,14 +690,14 @@ Syntax: *object*.**Point**( *X*, *Y* ) {: .no_toc } > [!NOTE] -> Declared for VB6 compatibility; not currently implemented on **UserControl** in twinBASIC. A **UserControl** has no menu structure of its own — invoke a host pop-up through the extender or the parent form's [**PopUpMenu**](../Form/#popupmenu). +> Declared for VB6 compatibility; not currently implemented on **UserControl** in twinBASIC. A **UserControl** has no menu structure of its own --- invoke a host pop-up through the extender or the parent form's [**PopUpMenu**](../Form/#popupmenu). Syntax: *object*.**PopUpMenu** *Menu* [, *Flags* [, *X* [, *Y* [, *DefaultMenu* ] ] ] ] ### Print {: .no_toc } -Writes text to the control's drawing surface using [**Font**](#font), starting at [**CurrentX**](#currentx) / [**CurrentY**](#currenty) and advancing them as it goes. Dispatched through the VB6 **Print** statement so multiple expressions can be separated by `;` (no spacing) or `,` (tab to the next print zone). **Spc(n)** inserts *n* spaces and **Tab(n)** moves to print column *n*. Output honours [**Font**](#font), [**ForeColor**](#forecolor), and [**FontTransparent**](#fonttransparent), and — when [**AutoRedraw**](#autoredraw) is **True** — is recorded into the persistent off-screen bitmap so it survives invalidations. +Writes text to the control's drawing surface using [**Font**](#font), starting at [**CurrentX**](#currentx) / [**CurrentY**](#currenty) and advancing them as it goes. Dispatched through the VB6 **Print** statement so multiple expressions can be separated by `;` (no spacing) or `,` (tab to the next print zone). **Spc(n)** inserts *n* spaces and **Tab(n)** moves to print column *n*. Output honours [**Font**](#font), [**ForeColor**](#forecolor), and [**FontTransparent**](#fonttransparent), and --- when [**AutoRedraw**](#autoredraw) is **True** --- is recorded into the persistent off-screen bitmap so it survives invalidations. Syntax: *object*.**Print** \[ *expressionlist* ] \[ **;** \| **,** ] @@ -823,19 +823,19 @@ Syntax: *object*.**ValidateControls** {: .no_toc } > [!NOTE] -> Declared for VB6 compatibility; only partially implemented in twinBASIC. The runtime currently raises this event when the host calls `IOleControl::OnMnemonic` with the **Escape**, **Return**, or **Execute** keys — typically because [**DefaultCancel**](#defaultcancel) (or a default-button equivalent) routed a default-action keystroke to the control. +> Declared for VB6 compatibility; only partially implemented in twinBASIC. The runtime currently raises this event when the host calls `IOleControl::OnMnemonic` with the **Escape**, **Return**, or **Execute** keys --- typically because [**DefaultCancel**](#defaultcancel) (or a default-button equivalent) routed a default-action keystroke to the control. Syntax: *object*\_**AccessKeyPress**( *KeyAscii* **As Integer** ) ### AmbientChanged {: .no_toc } -Raised when the host changes one of the ambient properties exposed through [**Ambient**](#ambient) — typically when its [**Font**](#font), colours, locale, or run/design mode flag shifts. The *PropertyName* argument names the ambient property that changed. +Raised when the host changes one of the ambient properties exposed through [**Ambient**](#ambient) --- typically when its [**Font**](#font), colours, locale, or run/design mode flag shifts. The *PropertyName* argument names the ambient property that changed. Syntax: *object*\_**AmbientChanged**( *PropertyName* **As String** ) *PropertyName* -: A **String** identifying the ambient property — for example, `"BackColor"`, `"Font"`, `"LocaleID"`, `"UserMode"`. +: A **String** identifying the ambient property --- for example, `"BackColor"`, `"Font"`, `"LocaleID"`, `"UserMode"`. ### AsyncReadComplete {: .no_toc } @@ -893,14 +893,14 @@ Syntax: *object*\_**DragOver**( *Source* **As Control**, *X* **As Single**, *Y* ### EnterFocus {: .no_toc } -Raised when the input focus moves into the **UserControl** — either the **UserControl** itself or any of its descendants. Fires before any child's **GotFocus**. +Raised when the input focus moves into the **UserControl** --- either the **UserControl** itself or any of its descendants. Fires before any child's **GotFocus**. Syntax: *object*\_**EnterFocus**( ) ### ExitFocus {: .no_toc } -Raised when the input focus leaves the **UserControl** — i.e. moves out to a control that is not a descendant. Fires after the leaving child's **LostFocus**. +Raised when the input focus leaves the **UserControl** --- i.e. moves out to a control that is not a descendant. Fires after the leaving child's **LostFocus**. Syntax: *object*\_**ExitFocus**( ) @@ -922,14 +922,14 @@ Syntax: *object*\_**GotFocus**( ) ### Hide {: .no_toc } -Raised when the host hides the container — typically as it switches from a run view to a design view, or as it makes a containing tab inactive. +Raised when the host hides the container --- typically as it switches from a run view to a design view, or as it makes a containing tab inactive. Syntax: *object*\_**Hide**( ) ### HitTest {: .no_toc } -Raised for each `IViewObjectEx::QueryHitPoint` request from the host when the control is windowless. Setting *HitResult* to a non-zero **HitResult** value tells the host whether the given pixel is "hit" for mouse-routing purposes — useful for non-rectangular windowless controls. +Raised for each `IViewObjectEx::QueryHitPoint` request from the host when the control is windowless. Setting *HitResult* to a non-zero **HitResult** value tells the host whether the given pixel is "hit" for mouse-routing purposes --- useful for non-rectangular windowless controls. Syntax: *object*\_**HitTest**( *X* **As Single**, *Y* **As Single**, *HitResult* **As Integer** ) @@ -943,7 +943,7 @@ Syntax: *object*\_**Initialize**( ) ### InitProperties {: .no_toc } -Raised once on the first ever activation of a brand-new **UserControl** instance — before a property bag exists for it. The classic place to assign initial values to persistent properties. Not raised on subsequent loads; on those, [**ReadProperties**](#readproperties) runs instead. +Raised once on the first ever activation of a brand-new **UserControl** instance --- before a property bag exists for it. The classic place to assign initial values to persistent properties. Not raised on subsequent loads; on those, [**ReadProperties**](#readproperties) runs instead. Syntax: *object*\_**InitProperties**( ) @@ -1048,14 +1048,14 @@ Syntax: *object*\_**OLEStartDrag**( *Data* **As DataObject**, *AllowedEffects* * ### Paint {: .no_toc } -Raised when an invalidated portion of the control needs to be redrawn. Suppressed when [**AutoRedraw**](#autoredraw) is **True** — the control's persistent off-screen buffer is blitted to the screen instead. +Raised when an invalidated portion of the control needs to be redrawn. Suppressed when [**AutoRedraw**](#autoredraw) is **True** --- the control's persistent off-screen buffer is blitted to the screen instead. Syntax: *object*\_**Paint**( ) ### PreKeyDown {: .no_toc } -Raised for every key press anywhere on the **UserControl** or any of its descendants, *before* the focused child sees it — so handlers can consume the keystroke. Requires [**PreKeyEvents**](#prekeyevents) **True**. Not raised when [**Windowless**](#windowless) is **True**. New in twinBASIC. +Raised for every key press anywhere on the **UserControl** or any of its descendants, *before* the focused child sees it --- so handlers can consume the keystroke. Requires [**PreKeyEvents**](#prekeyevents) **True**. Not raised when [**Windowless**](#windowless) is **True**. New in twinBASIC. Syntax: *object*\_**PreKeyDown**( *KeyCode* **As Integer**, *Shift* **As Integer** ) @@ -1069,7 +1069,7 @@ Syntax: *object*\_**PreKeyUp**( *KeyCode* **As Integer**, *Shift* **As Integer** ### ReadProperties {: .no_toc } -Raised when the host hands the control a property bag containing previously saved state — i.e. on every load except the very first. The handler reads the values it cares about from *PropBag* and applies them to its fields. *PropBag*'s **ReadProperty** method takes a key, a default value, and a type hint. +Raised when the host hands the control a property bag containing previously saved state --- i.e. on every load except the very first. The handler reads the values it cares about from *PropBag* and applies them to its fields. *PropBag*'s **ReadProperty** method takes a key, a default value, and a type hint. Syntax: *object*\_**ReadProperties**( *PropBag* **As PropertyBag** ) @@ -1079,14 +1079,14 @@ Syntax: *object*\_**ReadProperties**( *PropBag* **As PropertyBag** ) ### Resize {: .no_toc } -Raised when the **UserControl** is resized — by the host during initial layout, by user code assigning [**Width**](#width) or [**Height**](#height), or by the host responding to a designer drag. +Raised when the **UserControl** is resized --- by the host during initial layout, by user code assigning [**Width**](#width) or [**Height**](#height), or by the host responding to a designer drag. Syntax: *object*\_**Resize**( ) ### Show {: .no_toc } -Raised when the host makes the container visible — typically as it switches from a design view to a run view, or as it makes a containing tab active. +Raised when the host makes the container visible --- typically as it switches from a design view to a run view, or as it makes a containing tab active. Syntax: *object*\_**Show**( ) @@ -1100,7 +1100,7 @@ Syntax: *object*\_**Terminate**( ) ### VerbInvoked {: .no_toc } -Raised when the host invokes one of the verbs declared in [**Verbs**](#verbs) — typically because the user picked it from the host's right-click context menu. +Raised when the host invokes one of the verbs declared in [**Verbs**](#verbs) --- typically because the user picked it from the host's right-click context menu. Syntax: *object*\_**VerbInvoked**( *Verb* **As String** ) @@ -1110,7 +1110,7 @@ Syntax: *object*\_**VerbInvoked**( *Verb* **As String** ) ### WriteProperties {: .no_toc } -Raised when the host asks the control to persist its current state — design-time saves and host-initiated serialisation. The handler writes each persistent value to *PropBag* through **WriteProperty**, which takes a key, the value, and (optionally) the same default the [**ReadProperties**](#readproperties) handler used so that round-trip defaults are not written. Only raised when at least one call to [**PropertyChanged**](#propertychanged) has happened since the last save. +Raised when the host asks the control to persist its current state --- design-time saves and host-initiated serialisation. The handler writes each persistent value to *PropBag* through **WriteProperty**, which takes a key, the value, and (optionally) the same default the [**ReadProperties**](#readproperties) handler used so that round-trip defaults are not written. Only raised when at least one call to [**PropertyChanged**](#propertychanged) has happened since the last save. Syntax: *object*\_**WriteProperties**( *PropBag* **As PropertyBag** ) diff --git a/docs/Reference/VB/VScrollBar/index.md b/docs/Reference/VB/VScrollBar/index.md index 17b6c1f9..ed114b94 100644 --- a/docs/Reference/VB/VScrollBar/index.md +++ b/docs/Reference/VB/VScrollBar/index.md @@ -8,7 +8,7 @@ has_toc: false # VScrollBar class {: .no_toc } -A **VScrollBar** is a Win32 native vertical scroll bar exposed as a stand-alone control. Unlike the scroll bars that automatically appear inside a [**ListBox**](../ListBox), [**ComboBox**](../ComboBox), or [**TextBox**](../TextBox), a **VScrollBar** is independent of any other control — its [**Value**](#value) is whatever your code reads or writes. The typical use is to drive a numeric setting (a scroll offset, a brightness or opacity level, a colour channel, the vertical position of a custom-drawn surface) by binding the **VScrollBar**'s [**Change**](#change) and [**Scroll**](#scroll) events to whatever the value represents. +A **VScrollBar** is a Win32 native vertical scroll bar exposed as a stand-alone control. Unlike the scroll bars that automatically appear inside a [**ListBox**](../ListBox), [**ComboBox**](../ComboBox), or [**TextBox**](../TextBox), a **VScrollBar** is independent of any other control --- its [**Value**](#value) is whatever code reads or writes. The typical use is to control a numeric setting (a scroll offset, a brightness or opacity level, a colour channel, the vertical position of a custom-drawn surface) by binding the **VScrollBar**'s [**Change**](#change) and [**Scroll**](#scroll) events to whatever the value represents. [**HScrollBar**](../HScrollBar) is the horizontal counterpart; the two classes are identical apart from orientation. @@ -39,7 +39,7 @@ End Sub [**Min**](#min) and [**Max**](#max) define the closed range of integer values the scroll bar can represent, and [**Value**](#value) is the position within that range. Defaults are `0`, `32767`, and `0`. Assigning a [**Value**](#value) outside the current `[Min, Max]` interval raises run-time error 380 (*Invalid property value*); assigning the current value is a no-op (no [**Change**](#change) is raised). -The two endpoints may be supplied in either order. When **Min** is greater than **Max** the scroll bar runs *inverted* — moving the thumb downward decreases [**Value**](#value), and **Max** is the lower bound of the legal range. This is convenient for, for example, a "high-at-top" volume or brightness slider: +The two endpoints may be supplied in either order. When **Min** is greater than **Max** the scroll bar runs *inverted* --- moving the thumb downward decreases [**Value**](#value), and **Max** is the lower bound of the legal range. This is convenient for, for example, a "high-at-top" volume or brightness slider: ```tb vsbVolume.Min = 100 ' topmost == loudest @@ -47,7 +47,7 @@ vsbVolume.Max = 0 ' bottommost == silent vsbVolume.Value = 75 ``` -Changing **Min** or **Max** at run time clips the current [**Value**](#value) into the new range silently — no [**Change**](#change) event is raised for the implicit clip. +Changing **Min** or **Max** at run time clips the current [**Value**](#value) into the new range silently --- no [**Change**](#change) event is raised for the implicit clip. ## Increment sizes @@ -64,14 +64,14 @@ Both [**SmallChange**](#smallchange) and [**LargeChange**](#largechange) default ## Change versus Scroll -The split between the two events lets the application choose how often it reacts to user input. [**Scroll**](#scroll) fires repeatedly while the user is dragging the thumb, so a handler can update a live preview as the thumb moves. [**Change**](#change) fires once each time the value settles — after the user releases the thumb, after a click on an arrow or the track, or whenever code assigns a different [**Value**](#value). Many applications wire both events to the same handler so that the bound display updates both during dragging and after. +The split between the two events lets the application choose how often it reacts to user input. [**Scroll**](#scroll) fires repeatedly while the user is dragging the thumb, so a handler can update a live preview as the thumb moves. [**Change**](#change) fires once each time the value settles --- after the user releases the thumb, after a click on an arrow or the track, or whenever code assigns a different [**Value**](#value). Many applications wire both events to the same handler so that the bound display updates both during dragging and after. ## Properties ### Anchors {: .no_toc } -The set of edges of the parent that the scroll bar's corresponding edges follow when the parent resizes. Read-only — assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. +The set of edges of the parent that the scroll bar's corresponding edges follow when the parent resizes. Read-only --- assign individual `.Left`, `.Top`, `.Right`, `.Bottom` flags through the returned **Anchors** object. ### CausesValidation {: .no_toc } @@ -81,7 +81,7 @@ Determines whether the previously focused control's [**Validate**](#validate) ev ### Container {: .no_toc } -The control that hosts this scroll bar — typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. +The control that hosts this scroll bar --- typically the form, a [**Frame**](../Frame/), or a **UserControl**. Read with **Get**, change with **Set**. ### ControlType {: .no_toc } @@ -101,7 +101,7 @@ A **StdPicture** used as the mouse cursor while the control is being drag-and-dr ### DragMode {: .no_toc } -Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). +Whether the control should drag itself when the user holds the mouse over it. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). ### Enabled {: .no_toc } @@ -111,7 +111,7 @@ Determines whether the scroll bar accepts user input. A disabled scroll bar is g ### Height {: .no_toc } -The scroll bar's height in twips (or in the container's **ScaleMode** units). **Double**. For a vertical scroll bar this is the long dimension — i.e., the length of the track. +The scroll bar's height in twips (or in the container's **ScaleMode** units). **Double**. For a vertical scroll bar this is the long dimension --- i.e., the length of the track. ### HelpContextID {: .no_toc } @@ -141,7 +141,7 @@ The horizontal distance from the left edge of the container to the left edge of ### Max {: .no_toc } -The upper end of the scroll bar's value range. **Long**, default `32767`. May be set lower than [**Min**](#min) to invert the direction of travel — see [Range and value](#range-and-value). +The upper end of the scroll bar's value range. **Long**, default `32767`. May be set lower than [**Min**](#min) to invert the direction of travel --- see [Range and value](#range-and-value). Syntax: *object*.**Max** [ = *value* ] @@ -174,7 +174,7 @@ The unique design-time name of the control on its parent form. Read-only at run ### Opacity {: .no_toc } -The control's opacity as a percentage (0–100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. +The control's opacity as a percentage (0--100, default 100). Values outside the range are clamped on **Initialize**. Requires Windows 8 or later for child controls. ### Parent {: .no_toc } @@ -247,7 +247,7 @@ A **Long** identifying a "What's This?" help-pop-up topic in the application's h ### Width {: .no_toc } -The scroll bar's width in twips (or in the container's **ScaleMode** units). **Double**. For a vertical scroll bar this is the small dimension — typically the OS standard scroll-bar thickness; values larger than that simply enlarge the surrounding hit area. +The scroll bar's width in twips (or in the container's **ScaleMode** units). **Double**. For a vertical scroll bar this is the small dimension --- typically the OS standard scroll-bar thickness; values larger than that simply enlarge the surrounding hit area. ## Methods @@ -298,7 +298,7 @@ Syntax: *object*.**ShowWhatsThis** ### SyncScrollBar {: .no_toc } -Re-applies the current [**Min**](#min), [**Max**](#max), [**LargeChange**](#largechange), and [**Value**](#value) to the underlying Win32 scroll bar. Property assignments already do this implicitly — call **SyncScrollBar** only when external code (typically a Win32 API call) has reached around the control and changed its native state. +Re-applies the current [**Min**](#min), [**Max**](#max), [**LargeChange**](#largechange), and [**Value**](#value) to the underlying Win32 scroll bar. Property assignments already do this implicitly --- call **SyncScrollBar** only when external code (typically a Win32 API call) has reached around the control and changed its native state. Syntax: *object*.**SyncScrollBar** @@ -317,7 +317,7 @@ Syntax: *object*.**ZOrder** [ *Position* ] ### Change {: .no_toc } -Raised after [**Value**](#value) settles on a new value — when the user releases the thumb after a drag, when the user clicks an arrow or the track, when the user presses **Home**, **End**, or an arrow key with focus on the scroll bar, or when code assigns a different [**Value**](#value). Not raised for the continuous updates that happen during a drag — see [**Scroll**](#scroll) for that. **Default event.** +Raised after [**Value**](#value) settles on a new value --- when the user releases the thumb after a drag, when the user clicks an arrow or the track, when the user presses **Home**, **End**, or an arrow key with focus on the scroll bar, or when code assigns a different [**Value**](#value). Not raised for the continuous updates that happen during a drag --- see [**Scroll**](#scroll) for that. **Default event.** Syntax: *object*\_**Change**( ) @@ -352,7 +352,7 @@ Syntax: *object*\_**Initialize**( ) ### KeyDown {: .no_toc } -Raised when the user presses any key while the control has focus. Note that the scroll bar already handles the arrow keys, **Page Up** / **Page Down**, and **Home** / **End** internally — but **KeyDown** still fires for them in addition to the resulting [**Change**](#change). +Raised when the user presses any key while the control has focus. Note that the scroll bar already handles the arrow keys, **Page Up** / **Page Down**, and **Home** / **End** internally --- but **KeyDown** still fires for them in addition to the resulting [**Change**](#change). Syntax: *object*\_**KeyDown**( *KeyCode* **As Integer**, *Shift* **As Integer** ) @@ -380,7 +380,7 @@ Syntax: *object*\_**LostFocus**( ) ### Scroll {: .no_toc } -Raised continuously while the user is dragging the thumb, once for each tick that produces a different [**Value**](#value). After the user releases the thumb, a single [**Change**](#change) event fires with the final value. Use **Scroll** when you want a live preview while the thumb is moving; use [**Change**](#change) when you want to react only to the final value. +Raised continuously while the user is dragging the thumb, once for each tick that produces a different [**Value**](#value). After the user releases the thumb, a single [**Change**](#change) event fires with the final value. **Scroll** is the right event for a live preview while the thumb is moving; [**Change**](#change) fires only the final value. Syntax: *object*\_**Scroll**( ) diff --git a/docs/Reference/VB/index.md b/docs/Reference/VB/index.md index b1baca4a..00581433 100644 --- a/docs/Reference/VB/index.md +++ b/docs/Reference/VB/index.md @@ -17,7 +17,7 @@ These classes are in the VB built-in package, which provides the standard set of - [App](App) -- singleton wrapping the running application's identity, version metadata, and process-level state - [Clipboard](Clipboard) -- singleton wrapper around the system clipboard for inter-application copy and paste -- [Global](Global) -- the application's app object — singleton whose members (**App**, **Screen**, **Clipboard**, **Forms**, …) are reachable without qualification +- [Global](Global) -- the application's app object -- singleton whose members (**App**, **Screen**, **Clipboard**, **Forms**, …) are reachable without qualification - [Printer](Printer) -- drawing-surface wrapper around one Windows printer device, recording graphics calls into a spooled print job - [Printers](Printers) -- read-only collection of every printer installed on the system - [Screen](Screen) -- singleton wrapping the primary display's metrics, font list, active form and control, and application-wide mouse pointer @@ -25,7 +25,7 @@ These classes are in the VB built-in package, which provides the standard set of ### Controls - [CheckBox](CheckBox) -- Win32 native two- or three-state check-box with a caption and optional keyboard mnemonic -- [CheckMark](CheckMark) -- windowless scalable check glyph with no caption or focus — a check-box rendered at any size +- [CheckMark](CheckMark) -- windowless scalable check glyph with no caption or focus -- a check-box rendered at any size - [ComboBox](ComboBox) -- Win32 native edit field combined with a drop-down list of items - [CommandButton](CommandButton) -- Win32 native push-button that triggers an action when clicked - [Data](Data) -- Win32 native control that opens a DAO database and exposes a bound recordset to other controls @@ -35,14 +35,14 @@ These classes are in the VB built-in package, which provides the standard set of - [Form](Form) -- top-level Win32 window that hosts the controls, menus, and drawing surface of a single user interface - [Frame](Frame) -- Win32 native captioned container that groups controls and forms an option-button group - [HScrollBar](HScrollBar) -- Win32 native stand-alone horizontal scroll bar -- [Image](Image) -- windowless lightweight picture display — the cheap alternative to **PictureBox** +- [Image](Image) -- windowless lightweight picture display -- the cheap alternative to **PictureBox** - [Label](Label) -- windowless lightweight control for displaying read-only text and keyboard-mnemonic anchors - [Line](Line) -- windowless lightweight control that draws a single straight line segment between two endpoints - [ListBox](ListBox) -- Win32 native vertically-scrolling list of items, single- or multi-select - [MDIForm](MDIForm) -- top-level window that hosts an MDI client area for **Form** instances marked as MDI children -- [Menu](Menu) -- a single item — top-level entry, sub-menu entry, or separator — in a Win32 native menu +- [Menu](Menu) -- a single item -- top-level entry, sub-menu entry, or separator --- in a Win32 native menu - [MultiFrame](MultiFrame) -- layout container that arranges **Frame** controls in a horizontal or vertical strip -- [OLE](OLE) -- container that hosts a linked or embedded OLE Automation object (VB6 compatibility stub — mostly unimplemented) +- [OLE](OLE) -- container that hosts a linked or embedded OLE Automation object (VB6 compatibility stub -- mostly unimplemented) - [OptionButton](OptionButton) -- Win32 native round selector, mutually exclusive within its container - [PictureBox](PictureBox) -- Win32 native picture display, drawing surface, and control container combined - [PropertyPage](PropertyPage) -- container backing a single tab of a COM property-page dialog diff --git a/docs/Reference/VBA/Collection/Add.md b/docs/Reference/VBA/Collection/Add.md index aeb66fb8..1b001fb5 100644 --- a/docs/Reference/VBA/Collection/Add.md +++ b/docs/Reference/VBA/Collection/Add.md @@ -21,10 +21,10 @@ Syntax: *object*.**Add** *item* [ **,** *key* ] [ **,** *before* ] [ **,** *afte : *optional* A unique string expression that specifies a key string that can be used, instead of a positional index, to access a member of the collection. *before* -: *optional* An expression that specifies a relative position in the collection. The member to be added is placed in the collection before the member identified by the *before* argument. If a numeric expression, *before* must be a number from 1 to the value of the collection's [**Count**](Count) property. If a string expression, *before* must correspond to the *key* specified when the member being referred to was added to the collection. You can specify a *before* position or an *after* position, but not both. +: *optional* An expression that specifies a relative position in the collection. The member to be added is placed in the collection before the member identified by the *before* argument. If a numeric expression, *before* must be a number from 1 to the value of the collection's [**Count**](Count) property. If a string expression, *before* must correspond to the *key* specified when the member being referred to was added to the collection. Specify a *before* position or an *after* position, but not both. *after* -: *optional* An expression that specifies a relative position in the collection. The member to be added is placed in the collection after the member identified by the *after* argument. The same numeric and string-key constraints as *before* apply. You can specify a *before* position or an *after* position, but not both. +: *optional* An expression that specifies a relative position in the collection. The member to be added is placed in the collection after the member identified by the *after* argument. The same numeric and string-key constraints as *before* apply. Specify a *before* position or an *after* position, but not both. If neither *before* nor *after* is specified, the new item is added at the end of the collection. diff --git a/docs/Reference/VBA/Collection/Clear.md b/docs/Reference/VBA/Collection/Clear.md index e76abf3f..f8c2e134 100644 --- a/docs/Reference/VBA/Collection/Clear.md +++ b/docs/Reference/VBA/Collection/Clear.md @@ -18,7 +18,7 @@ Syntax: *object*.**Clear** > > **Clear** is a twinBASIC extension; the classic VBA **Collection** object has no **Clear** method. The same effect in VBA requires repeatedly removing the first item until the collection is empty. -Use **Clear** to reset a **Collection** to its initial, empty state when you want to reuse the object without creating a new instance. +**Clear** resets a **Collection** to its initial, empty state --- useful when the object is to be reused without creating a new instance. ### Example diff --git a/docs/Reference/VBA/Collection/Items.md b/docs/Reference/VBA/Collection/Items.md index 306c3e24..d9872996 100644 --- a/docs/Reference/VBA/Collection/Items.md +++ b/docs/Reference/VBA/Collection/Items.md @@ -20,7 +20,7 @@ Syntax: *object*.**Items()** If the collection is empty, **Items** returns an empty array. -The **Items** method is useful when you need to pass the collection's contents to a procedure expecting an array, or to iterate without holding a reference to the collection. +The **Items** method is useful when passing the collection's contents to a procedure expecting an array, or to iterate without holding a reference to the collection. ### Example diff --git a/docs/Reference/VBA/Collection/Remove.md b/docs/Reference/VBA/Collection/Remove.md index 8051be79..980ba85b 100644 --- a/docs/Reference/VBA/Collection/Remove.md +++ b/docs/Reference/VBA/Collection/Remove.md @@ -19,7 +19,7 @@ Syntax: *object*.**Remove(** *index* **)** If *index* doesn't match an existing member of the collection, an error occurs. -When an item is removed, the indexes of subsequent items decrease by one. Take this into account when iterating over a collection while removing items — see the example below. +When an item is removed, the indexes of subsequent items decrease by one. Take this into account when iterating over a collection while removing items --- see the example below. Key comparison is governed by the [**KeyCompareMode**](KeyCompareMode) property. diff --git a/docs/Reference/VBA/Collection/index.md b/docs/Reference/VBA/Collection/index.md index bf289f4f..3653f8d1 100644 --- a/docs/Reference/VBA/Collection/index.md +++ b/docs/Reference/VBA/Collection/index.md @@ -8,11 +8,11 @@ has_toc: false # Collection class -A **Collection** is an ordered set of items that can be referred to as a unit. The members of a collection do not have to share a data type — any value or object reference is acceptable. Items are accessed by their one-based numeric position in the collection or, if they were added with a key, by that key. +A **Collection** is an ordered set of items that can be referred to as a unit. The members of a collection do not have to share a data type --- any value or object reference is acceptable. Items are accessed by their one-based numeric position in the collection or, if they were added with a key, by that key. ## Creating, populating, and disposing of a collection -A collection is created with **New**, populated with [**Add**](Add), and reduced with [**Remove**](Remove) (one item at a time) or [**Clear**](Clear) (every item at once). When the variable referring to the collection goes out of scope, or is set to **Nothing**, the collection — together with any object references it holds — is released. +A collection is created with **New**, populated with [**Add**](Add), and reduced with [**Remove**](Remove) (one item at a time) or [**Clear**](Clear) (every item at once). When the variable referring to the collection goes out of scope, or is set to **Nothing**, the collection --- together with any object references it holds --- is released. ```tb Sub Demo() diff --git a/docs/Reference/VBA/Compilation/CurrentComponentCLSID.md b/docs/Reference/VBA/Compilation/CurrentComponentCLSID.md index a51bda97..83b5833e 100644 --- a/docs/Reference/VBA/Compilation/CurrentComponentCLSID.md +++ b/docs/Reference/VBA/Compilation/CurrentComponentCLSID.md @@ -13,7 +13,7 @@ Syntax: **CurrentComponentCLSID** [ **()** ] The value is the GUID assigned to the enclosing class by its [`[ClassId(...)]`](../../Core/Attributes#classid) attribute. If no **ClassId** is set, the function returns the all-zero GUID. > [!NOTE] -> **CurrentComponentCLSID** is a compile-time intrinsic — the CLSID is read from the class's attributes when the source is compiled, not looked up from the COM registry at run time. It uses special internal bindings and may not behave like an ordinary function. +> **CurrentComponentCLSID** is a compile-time intrinsic --- the CLSID is read from the class's attributes when the source is compiled, not looked up from the COM registry at run time. It uses special internal bindings and may not behave like an ordinary function. ### Example diff --git a/docs/Reference/VBA/Compilation/CurrentComponentName.md b/docs/Reference/VBA/Compilation/CurrentComponentName.md index b7c83cd1..b36b8c04 100644 --- a/docs/Reference/VBA/Compilation/CurrentComponentName.md +++ b/docs/Reference/VBA/Compilation/CurrentComponentName.md @@ -10,7 +10,7 @@ Returns the name of the current component (module or class) as a literal **Strin Syntax: **CurrentComponentName** [ **()** ] -The value identifies the source unit — the **Module**, **Class**, **Form**, or other component — that lexically contains the call site. +The value identifies the source unit --- the **Module**, **Class**, **Form**, or other component --- that lexically contains the call site. > [!NOTE] > **CurrentComponentName** is a compile-time intrinsic: the literal string is embedded in the compiled code at the point of the call. It does not change at run time, even when the call is reached through a forwarded or inherited member. diff --git a/docs/Reference/VBA/Compilation/CurrentProcedureName.md b/docs/Reference/VBA/Compilation/CurrentProcedureName.md index 0473f931..9682e90c 100644 --- a/docs/Reference/VBA/Compilation/CurrentProcedureName.md +++ b/docs/Reference/VBA/Compilation/CurrentProcedureName.md @@ -13,7 +13,7 @@ Syntax: **CurrentProcedureName** [ **()** ] The value is the name of the **Sub**, **Function**, or **Property** that lexically contains the call. > [!NOTE] -> **CurrentProcedureName** is a compile-time intrinsic: the literal string is determined when the source is compiled, from the procedure that surrounds the call. It is not derived from the runtime call stack — wrapping the call in a helper records the helper's name, not the original caller's. +> **CurrentProcedureName** is a compile-time intrinsic: the literal string is determined when the source is compiled, from the procedure that surrounds the call. It is not derived from the runtime call stack --- wrapping the call in a helper records the helper's name, not the original caller's. ### Example diff --git a/docs/Reference/VBA/Compilation/CurrentProjectName.md b/docs/Reference/VBA/Compilation/CurrentProjectName.md index 7c1e5e95..200af6e0 100644 --- a/docs/Reference/VBA/Compilation/CurrentProjectName.md +++ b/docs/Reference/VBA/Compilation/CurrentProjectName.md @@ -13,7 +13,7 @@ Syntax: **CurrentProjectName** [ **()** ] The value is the name of the project (executable or library) that owns the call site. > [!NOTE] -> **CurrentProjectName** is a compile-time intrinsic — the literal string is embedded in the compiled code from the project's metadata at the point of the call. +> **CurrentProjectName** is a compile-time intrinsic --- the literal string is embedded in the compiled code from the project's metadata at the point of the call. ### Example diff --git a/docs/Reference/VBA/Compilation/index.md b/docs/Reference/VBA/Compilation/index.md index 7bdf4f04..e1a75867 100644 --- a/docs/Reference/VBA/Compilation/index.md +++ b/docs/Reference/VBA/Compilation/index.md @@ -7,11 +7,11 @@ has_toc: false # Compilation module -The **Compilation** module groups together intrinsics that report on how — and from where — the running code was built. Most of its members are *compile-time* intrinsics: they do not look anything up at run time but instead bake a literal value into the compiled code at the point of the call, recording the surrounding project, component, procedure, or source file as it stood when the compiler ran. +The **Compilation** module groups together intrinsics that report on how --- and from where --- the running code was built. Most of its members are *compile-time* intrinsics: they do not look anything up at run time but instead embed a literal value into the compiled code at the point of the call, recording the surrounding project, component, procedure, or source file as it stood when the compiler ran. ## Build identity -[**CompilerVersion**](CompilerVersion) returns the build number of the twinBASIC compiler that produced the running code, and [**ProcessorArchitecture**](ProcessorArchitecture) returns a [**VbArchitecture**](../Constants/VbArchitecture) constant — **vbArchWin32** or **vbArchWin64** — identifying whether the binary was built for 32-bit or 64-bit execution. Together they characterise *which* compiler emitted the running code and *what kind* of process it is running in. +[**CompilerVersion**](CompilerVersion) returns the build number of the twinBASIC compiler that produced the running code, and [**ProcessorArchitecture**](ProcessorArchitecture) returns a [**VbArchitecture**](../Constants/VbArchitecture) constant --- **vbArchWin32** or **vbArchWin64** --- identifying whether the binary was built for 32-bit or 64-bit execution. Together they characterise *which* compiler emitted the running code and *what kind* of process it is running in. ```tb Debug.Print "twinBASIC build #" & CompilerVersion() @@ -26,7 +26,7 @@ End If The `Current...` family records the source location of the call site as a literal string, captured when the source is compiled. [**CurrentProjectName**](CurrentProjectName) names the project (executable or library) that owns the call, [**CurrentComponentName**](CurrentComponentName) names the enclosing module, class, or form, [**CurrentProcedureName**](CurrentProcedureName) names the surrounding **Sub**, **Function**, or **Property**, and [**CurrentSourceFile**](CurrentSourceFile) returns the full path of the source file as it was on the build machine. For COM classes, [**CurrentComponentCLSID**](CurrentComponentCLSID) returns the GUID supplied by the class's [`[ClassId(...)]`](../../Core/Attributes#classid) attribute, or the all-zero GUID when none is set. -Because each value is fixed at compile time, wrapping a call in a helper records the *helper's* name rather than its caller's. These intrinsics are most useful in diagnostic output — logging, tracing, assertions — where they replace hard-coded identifier strings that would otherwise drift as code is renamed. +Because each value is fixed at compile time, wrapping a call in a helper records the *helper's* name rather than its caller's. These intrinsics are most useful in diagnostic output --- logging, tracing, assertions --- where they replace hard-coded identifier strings that would otherwise drift as code is renamed. ```tb Public Sub Log(Message As String) diff --git a/docs/Reference/VBA/Constants/VbDateTimeFormat.md b/docs/Reference/VBA/Constants/VbDateTimeFormat.md index f4cc0803..77eaef45 100644 --- a/docs/Reference/VBA/Constants/VbDateTimeFormat.md +++ b/docs/Reference/VBA/Constants/VbDateTimeFormat.md @@ -18,7 +18,7 @@ Format codes for the [**FormatDateTime**](../Strings/FormatDateTime) function. | Constant | Value | Description | |----------|-------|-------------| -| **vbGeneralDate**{: #vbGeneralDate } | 0 | Display a date and/or time. For real numbers, display a date and time; if there is no fractional part, display a date only; if there is no integer part, display a time only. Date and time display is determined by your system settings. | +| **vbGeneralDate**{: #vbGeneralDate } | 0 | Display a date and/or time. For real numbers, display a date and time; if there is no fractional part, display a date only; if there is no integer part, display a time only. Date and time display is determined by the system settings. | | **vbLongDate**{: #vbLongDate } | 1 | Display a date in the long date format specified by the system regional settings. | | **vbShortDate**{: #vbShortDate } | 2 | Display a date in the short date format specified by the system regional settings. | | **vbLongTime**{: #vbLongTime } | 3 | Display a time in the long time format specified by the system regional settings. | diff --git a/docs/Reference/VBA/Constants/VbIMEStatus.md b/docs/Reference/VBA/Constants/VbIMEStatus.md index ccda28a7..c98aa664 100644 --- a/docs/Reference/VBA/Constants/VbIMEStatus.md +++ b/docs/Reference/VBA/Constants/VbIMEStatus.md @@ -31,7 +31,7 @@ vba_attribution: true Input Method Editor mode constants. Each value is exposed under both the legacy `vbIME...` name and the newer `vbIMEMode...` name; the two names with the same value are interchangeable. -The constants applicable to a given mode depend on the system locale. Values 4–8 apply to Japanese locales, and values 9 and 10 apply to Korean locales. +The constants applicable to a given mode depend on the system locale. Values 4--8 apply to Japanese locales, and values 9 and 10 apply to Korean locales. | Constants | Value | Description | |-----------|-------|-------------| diff --git a/docs/Reference/VBA/Constants/VbMsgBoxStyle.md b/docs/Reference/VBA/Constants/VbMsgBoxStyle.md index c57f7d08..d1218ff8 100644 --- a/docs/Reference/VBA/Constants/VbMsgBoxStyle.md +++ b/docs/Reference/VBA/Constants/VbMsgBoxStyle.md @@ -30,7 +30,7 @@ vba_attribution: true # VbMsgBoxStyle {: .no_toc } -Buttons, icons, default-button, modality, and other behaviour flags for the **MsgBox** dialog. Combine values from different groups with **Or** (or addition) to specify the desired combination — for example, `vbYesNo Or vbCritical Or vbDefaultButton2`. +Buttons, icons, default-button, modality, and other behaviour flags for the **MsgBox** dialog. Combine values from different groups with **Or** (or addition) to specify the desired combination --- for example, `vbYesNo Or vbCritical Or vbDefaultButton2`. ### Buttons diff --git a/docs/Reference/VBA/Constants/VbVarType.md b/docs/Reference/VBA/Constants/VbVarType.md index 5072a765..3c11ed87 100644 --- a/docs/Reference/VBA/Constants/VbVarType.md +++ b/docs/Reference/VBA/Constants/VbVarType.md @@ -28,7 +28,7 @@ vba_attribution: true # VbVarType {: .no_toc } -Variant subtype codes returned by the **VarType** function. Most calls return a single value from the table below. Arrays are reported as **vbArray** added to the element subtype — for example, an array of **Long** returns `vbArray + vbLong` = 8195. +Variant subtype codes returned by the **VarType** function. Most calls return a single value from the table below. Arrays are reported as **vbArray** added to the element subtype --- for example, an array of **Long** returns `vbArray + vbLong` = 8195. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/VBA/Constants/index.md b/docs/Reference/VBA/Constants/index.md index 7a7be3e2..45f84c78 100644 --- a/docs/Reference/VBA/Constants/index.md +++ b/docs/Reference/VBA/Constants/index.md @@ -10,25 +10,25 @@ has_toc: false ## Constants **vbBack**{: #vbBack } -: The backspace character — **Chr(8)**. +: The backspace character --- **Chr(8)**. **vbCr**{: #vbCr } -: The carriage return character — **Chr(13)**. +: The carriage return character --- **Chr(13)**. **vbCrLf**{: #vbCrLf } -: The carriage return + linefeed pair — **Chr(13) & Chr(10)**. +: The carriage return + linefeed pair --- **Chr(13) & Chr(10)**. **vbFormFeed**{: #vbFormFeed } -: The form feed character — **Chr(12)**. +: The form feed character --- **Chr(12)**. **vbLf**{: #vbLf } -: The linefeed character — **Chr(10)**. +: The linefeed character --- **Chr(10)**. **vbNewLine**{: #vbNewLine } : The platform-appropriate newline character. In twinBASIC, identical to **vbCrLf**. **vbNullChar**{: #vbNullChar } -: The null character — **Chr(0)**. +: The null character --- **Chr(0)**. **vbNullPtr**{: #vbNullPtr } : A null pointer of type **LongPtr** (zero), for use with API declarations that take a pointer or handle argument. @@ -37,13 +37,13 @@ has_toc: false : A null string pointer. Distinct from the zero-length string `""`; used when calling external procedures that differentiate between a null pointer and an empty string. **vbObjectError**{: #vbObjectError } -: The base value for user-defined error numbers — **&H80040000** (-2147221504). User-defined error numbers should be greater than this; for example, `Err.Raise vbObjectError + 1000`. +: The base value for user-defined error numbers --- **&H80040000** (-2147221504). User-defined error numbers should be greater than this; for example, `Err.Raise vbObjectError + 1000`. **vbTab**{: #vbTab } -: The tab character — **Chr(9)**. +: The tab character --- **Chr(9)**. **vbVerticalTab**{: #vbVerticalTab } -: The vertical tab character — **Chr(11)**. +: The vertical tab character --- **Chr(11)**. ## Enumerations diff --git a/docs/Reference/VBA/Conversion/CBool.md b/docs/Reference/VBA/Conversion/CBool.md index 6bb4291c..e133ad1c 100644 --- a/docs/Reference/VBA/Conversion/CBool.md +++ b/docs/Reference/VBA/Conversion/CBool.md @@ -20,7 +20,7 @@ The return type is **Boolean**. If *expression* evaluates to a nonzero value, ** If *expression* cannot be interpreted as a numeric value, a run-time error occurs. -In general, you can document your code using the data-type conversion functions to show that the result of some operation should be expressed as a particular data type rather than the default data type. +The data-type conversion functions document code by showing that the result of some operation should be expressed as a particular data type rather than the default data type. ### Example diff --git a/docs/Reference/VBA/Conversion/CByte.md b/docs/Reference/VBA/Conversion/CByte.md index 8d2123e1..3e1dc2ab 100644 --- a/docs/Reference/VBA/Conversion/CByte.md +++ b/docs/Reference/VBA/Conversion/CByte.md @@ -16,7 +16,7 @@ Syntax: **CByte(** *expression* **)** *expression* : *required* Any valid string or numeric expression in the range `0` to `255`. -The return type is **Byte**. If *expression* is outside the range of a **Byte**, a run-time error occurs. Fractions are rounded — when the fractional part is exactly `0.5`, **CByte** rounds to the nearest even number. +The return type is **Byte**. If *expression* is outside the range of a **Byte**, a run-time error occurs. Fractions are rounded --- when the fractional part is exactly `0.5`, **CByte** rounds to the nearest even number. ### Example diff --git a/docs/Reference/VBA/Conversion/CCur.md b/docs/Reference/VBA/Conversion/CCur.md index 68f7cc8c..377a18e7 100644 --- a/docs/Reference/VBA/Conversion/CCur.md +++ b/docs/Reference/VBA/Conversion/CCur.md @@ -18,9 +18,9 @@ Syntax: **CCur(** *expression* **)** The return type is **Currency**. If *expression* is outside that range, a run-time error occurs. -Use **CCur** to force currency arithmetic in cases where single-precision, double-precision, or integer arithmetic normally would occur. +**CCur** forces currency arithmetic in cases where single-precision, double-precision, or integer arithmetic would normally occur. -You should use **CCur** instead of **Val** to provide internationally aware conversions from one data type to another. **CCur** recognizes different decimal separators, different thousand separators, and various currency options properly, depending on the locale setting of your computer. +**CCur** is the internationally aware alternative to **Val** for converting between data types. **CCur** recognizes different decimal separators, different thousand separators, and various currency options properly, depending on the system's locale setting. ### Example diff --git a/docs/Reference/VBA/Conversion/CDate.md b/docs/Reference/VBA/Conversion/CDate.md index 021c7153..1a6fe500 100644 --- a/docs/Reference/VBA/Conversion/CDate.md +++ b/docs/Reference/VBA/Conversion/CDate.md @@ -14,13 +14,13 @@ Coerces an expression to a **Date**. Syntax: **CDate(** *expression* **)** *expression* -: *required* Any valid date expression — a date literal, a date/time string, or a number that falls within the range of acceptable dates. +: *required* Any valid date expression --- a date literal, a date/time string, or a number that falls within the range of acceptable dates. The return type is **Date**. Use the **IsDate** function to determine whether *expression* can be converted to a date or time. **CDate** recognizes date literals and time literals as well as some numbers that fall within the range of acceptable dates. When converting a number to a date, the whole-number portion is converted to a date. Any fractional part of the number is converted to a time of day, starting at midnight. -**CDate** recognizes date formats according to the locale setting of your system. The correct order of day, month, and year may not be determined if it is provided in a format other than one of the recognized date settings. In addition, a long date format is not recognized if it also contains the day-of-the-week string. +**CDate** recognizes date formats according to the system locale setting. The correct order of day, month, and year may not be determined if it is provided in a format other than one of the recognized date settings. In addition, a long date format is not recognized if it also contains the day-of-the-week string. [**CVDate**](CVDate) is also provided for compatibility with previous versions of Visual Basic. The syntax of **CVDate** is identical to **CDate**; however, **CVDate** returns a **Variant** whose subtype is **Date** instead of an actual **Date** type. diff --git a/docs/Reference/VBA/Conversion/CDbl.md b/docs/Reference/VBA/Conversion/CDbl.md index c2b388a1..3ed2c2e2 100644 --- a/docs/Reference/VBA/Conversion/CDbl.md +++ b/docs/Reference/VBA/Conversion/CDbl.md @@ -14,11 +14,11 @@ Coerces an expression to a **Double**. Syntax: **CDbl(** *expression* **)** *expression* -: *required* Any valid string or numeric expression in the **Double** range — `-1.79769313486231E308` to `-4.94065645841247E-324` for negative values, and `4.94065645841247E-324` to `1.79769313486232E308` for positive values. +: *required* Any valid string or numeric expression in the **Double** range --- `-1.79769313486231E308` to `-4.94065645841247E-324` for negative values, and `4.94065645841247E-324` to `1.79769313486232E308` for positive values. The return type is **Double**. If *expression* is outside the range of a **Double**, a run-time error occurs. -Use **CDbl** instead of [**Val**](Val) to provide internationally aware conversions from a string to a numeric type. **CDbl** recognizes different decimal separators and different thousand separators properly, depending on the locale setting of your computer. +**CDbl** is the internationally aware alternative to [**Val**](Val) for converting a string to a numeric type. **CDbl** recognizes different decimal separators and different thousand separators properly, depending on the system's locale setting. ### Example diff --git a/docs/Reference/VBA/Conversion/CDec.md b/docs/Reference/VBA/Conversion/CDec.md index b23acab6..810d51dd 100644 --- a/docs/Reference/VBA/Conversion/CDec.md +++ b/docs/Reference/VBA/Conversion/CDec.md @@ -19,9 +19,9 @@ Syntax: **CDec(** *expression* **)** The return type is **Decimal**. > [!NOTE] -> In VBA, **CDec** does not return a discrete data type; it always returns a **Variant** whose value has been converted to a **Decimal** subtype. In twinBASIC, **Decimal** is a full first-class data type, so **CDec** returns a **Decimal** directly. You can still assign the result to a **Variant** to obtain VBA-compatible behavior. +> In VBA, **CDec** does not return a discrete data type; it always returns a **Variant** whose value has been converted to a **Decimal** subtype. In twinBASIC, **Decimal** is a full first-class data type, so **CDec** returns a **Decimal** directly. The result can be assigned to a **Variant** for VBA-compatible behavior. -Use **CDec** instead of [**Val**](Val) to provide internationally aware conversions from a string to a numeric type. +**CDec** is the internationally aware alternative to [**Val**](Val) for converting a string to a numeric type. ### Example diff --git a/docs/Reference/VBA/Conversion/CInt.md b/docs/Reference/VBA/Conversion/CInt.md index ee719c7b..5f0d8fcf 100644 --- a/docs/Reference/VBA/Conversion/CInt.md +++ b/docs/Reference/VBA/Conversion/CInt.md @@ -20,7 +20,7 @@ The return type is **Integer**. If *expression* is outside the range of an **Int When the fractional part is exactly `0.5`, **CInt** always rounds it to the nearest even number. For example, `0.5` rounds to `0`, and `1.5` rounds to `2`. **CInt** differs from the [**Fix**](Fix) and [**Int**](Int) functions, which truncate, rather than round, the fractional part of a number. Also, **Fix** and **Int** always return a value of the same type as is passed in. -Use **CInt** instead of [**Val**](Val) to provide internationally aware conversions from a string to a numeric type. +**CInt** is the internationally aware alternative to [**Val**](Val) for converting a string to a numeric type. ### Example diff --git a/docs/Reference/VBA/Conversion/CLngLng.md b/docs/Reference/VBA/Conversion/CLngLng.md index 6c9f297d..a940b4c0 100644 --- a/docs/Reference/VBA/Conversion/CLngLng.md +++ b/docs/Reference/VBA/Conversion/CLngLng.md @@ -24,7 +24,7 @@ When the fractional part is exactly `0.5`, **CLngLng** always rounds it to the n > Conversion functions must be used to explicitly assign **LongLong** to smaller integral types. Implicit conversions of **LongLong** to smaller integrals are not allowed. > [!NOTE] -> In VBA, **LongLong** (and therefore **CLngLng**) is restricted to 64-bit hosts. twinBASIC supports **LongLong** in both 32-bit and 64-bit modes — see [Data Types](../../../Features/Language/Data-Types). +> In VBA, **LongLong** (and therefore **CLngLng**) is restricted to 64-bit hosts. twinBASIC supports **LongLong** in both 32-bit and 64-bit modes --- see [Data Types](../../../Features/Language/Data-Types). ### Example diff --git a/docs/Reference/VBA/Conversion/CSng.md b/docs/Reference/VBA/Conversion/CSng.md index f7386ede..e41dcd80 100644 --- a/docs/Reference/VBA/Conversion/CSng.md +++ b/docs/Reference/VBA/Conversion/CSng.md @@ -14,11 +14,11 @@ Coerces an expression to a **Single**. Syntax: **CSng(** *expression* **)** *expression* -: *required* Any valid string or numeric expression in the **Single** range — `-3.402823E38` to `-1.401298E-45` for negative values, and `1.401298E-45` to `3.402823E38` for positive values. +: *required* Any valid string or numeric expression in the **Single** range --- `-3.402823E38` to `-1.401298E-45` for negative values, and `1.401298E-45` to `3.402823E38` for positive values. The return type is **Single**. If *expression* is outside the range of a **Single**, a run-time error occurs. -Use **CSng** instead of [**Val**](Val) to provide internationally aware conversions from a string to a numeric type. +**CSng** is the internationally aware alternative to [**Val**](Val) for converting a string to a numeric type. ### Example diff --git a/docs/Reference/VBA/Conversion/CStr.md b/docs/Reference/VBA/Conversion/CStr.md index a1620a3d..e75de4dd 100644 --- a/docs/Reference/VBA/Conversion/CStr.md +++ b/docs/Reference/VBA/Conversion/CStr.md @@ -21,13 +21,13 @@ The return type is **String**. The result depends on the type of *expression*: | If *expression* is | CStr returns | |--------------------|---------------------------------------------------------------| | **Boolean** | A string containing `"True"` or `"False"`. | -| **Date** | A string containing a date in the short date format of your system. | +| **Date** | A string containing a date in the system's short date format. | | **Empty** | A zero-length string (`""`). | | **Error** | A string containing the word `Error` followed by the error number. | | **Null** | A run-time error. | | Other numeric | A string containing the number. | -Use **CStr** instead of [**Str**](Str) to provide internationally aware conversions from a number to a string. **CStr** recognizes different decimal separators properly, depending on the locale setting of your computer. +**CStr** is the internationally aware alternative to [**Str**](Str) for converting a number to a string. **CStr** recognizes different decimal separators properly, depending on the system's locale setting. ### Example diff --git a/docs/Reference/VBA/Conversion/CType.md b/docs/Reference/VBA/Conversion/CType.md index 8b03e375..d0c3b8fb 100644 --- a/docs/Reference/VBA/Conversion/CType.md +++ b/docs/Reference/VBA/Conversion/CType.md @@ -25,7 +25,7 @@ The return type matches *type*. **CType** has two roles: -1. **As an explicit cast**, used wherever an implicit conversion would either be disallowed or produce a compiler warning. It conveys the same intent as [**CInt**](CInt), [**CLng**](CLng), and the rest of the C-prefix functions, but for any target type — most usefully when the target is an **Enum** or an interface. For example, assigning a numeric literal or another **Enum** member to an **Enum**-typed variable triggers a compiler warning that **CType** silences: +1. **As an explicit cast**, used wherever an implicit conversion would either be disallowed or produce a compiler warning. It conveys the same intent as [**CInt**](CInt), [**CLng**](CLng), and the rest of the C-prefix functions, but for any target type --- most usefully when the target is an **Enum** or an interface. For example, assigning a numeric literal or another **Enum** member to an **Enum**-typed variable triggers a compiler warning that **CType** silences: ```tb Dim day As VbDayOfWeek diff --git a/docs/Reference/VBA/Conversion/CVDate.md b/docs/Reference/VBA/Conversion/CVDate.md index a15ef838..52a0c2a2 100644 --- a/docs/Reference/VBA/Conversion/CVDate.md +++ b/docs/Reference/VBA/Conversion/CVDate.md @@ -14,7 +14,7 @@ Converts a valid date and time expression to a **Variant** of subtype **Date**. Syntax: **CVDate(** *expression* **)** *expression* -: *required* Any expression that can be converted to a date — a date literal, a date/time string, or a number that falls within the range of acceptable dates. +: *required* Any expression that can be converted to a date --- a date literal, a date/time string, or a number that falls within the range of acceptable dates. The return type is **Variant** (**Date**). An error occurs if *expression* cannot be converted to a date. diff --git a/docs/Reference/VBA/Conversion/CVErr.md b/docs/Reference/VBA/Conversion/CVErr.md index 94a3fea1..16c820ca 100644 --- a/docs/Reference/VBA/Conversion/CVErr.md +++ b/docs/Reference/VBA/Conversion/CVErr.md @@ -16,9 +16,9 @@ Syntax: **CVErr(** *errornumber* **)** *errornumber* : *required* Any valid error number. -Use the **CVErr** function to create user-defined errors in user-created procedures. For example, if you create a function that accepts several arguments and normally returns a string, you can have your function evaluate the input arguments to ensure they are within an acceptable range. If they aren't, it is likely your function will not return what you expect. In this event, **CVErr** allows you to return an error number that tells the caller what action to take. +Use the **CVErr** function to create user-defined errors in user-created procedures. For example, a function that accepts several arguments and normally returns a string can evaluate the input arguments to ensure they are within an acceptable range. If they aren't, the function is unlikely to return the expected result. In this event, **CVErr** returns an error number that tells the caller what action to take. -Note that implicit conversion of an **Error** is not allowed. For example, you can't directly assign the return value of **CVErr** to a variable that is not a **Variant**. However, you can perform an explicit conversion (by using [**CInt**](CInt), [**CDbl**](CDbl), and so on) of the value returned by **CVErr** and assign that to a variable of the appropriate data type. +Note that implicit conversion of an **Error** is not allowed. For example, the return value of **CVErr** cannot be directly assigned to a variable that is not a **Variant**. An explicit conversion (using [**CInt**](CInt), [**CDbl**](CDbl), and so on) of the value returned by **CVErr** can be assigned to a variable of the appropriate data type. ### Example diff --git a/docs/Reference/VBA/Conversion/MacID.md b/docs/Reference/VBA/Conversion/MacID.md index 81e93a63..75c0c1f3 100644 --- a/docs/Reference/VBA/Conversion/MacID.md +++ b/docs/Reference/VBA/Conversion/MacID.md @@ -14,11 +14,11 @@ Used on the Macintosh to convert a 4-character constant to a value that may be u Syntax: **MacID(** *constant* **)** *constant* -: *required* A **String** of 4 characters used to specify a resource type, file type, application signature, or Apple Event — for example, `"TEXT"`, `"OBIN"`, `"XLS5"` for Excel files (`"XLS8"` for Excel 97); Microsoft Word uses `"W6BN"` (`"W8BN"` for Word 97). +: *required* A **String** of 4 characters used to specify a resource type, file type, application signature, or Apple Event --- for example, `"TEXT"`, `"OBIN"`, `"XLS5"` for Excel files (`"XLS8"` for Excel 97); Microsoft Word uses `"W6BN"` (`"W8BN"` for Word 97). The return type is **Long**. -**MacID** is used with **Dir** and **Kill** to specify a Macintosh file type. Because the Macintosh does not support `*` and `?` as wildcards, you can use a four-character constant instead to identify groups of files. For example, the following statement returns `TEXT`-type files from the current folder: +**MacID** is used with **Dir** and **Kill** to specify a Macintosh file type. Because the Macintosh does not support `*` and `?` as wildcards, a four-character constant identifies groups of files instead. For example, the following statement returns `TEXT`-type files from the current folder: ```tb Dir("SomePath", MacID("TEXT")) diff --git a/docs/Reference/VBA/Conversion/Nz.md b/docs/Reference/VBA/Conversion/Nz.md index 02226615..df241a79 100644 --- a/docs/Reference/VBA/Conversion/Nz.md +++ b/docs/Reference/VBA/Conversion/Nz.md @@ -21,7 +21,7 @@ Syntax: **Nz(** *value* [ **,** *valueIfNull* ] **)** The return type is **Variant**. -**Nz** is useful for handling expressions that may evaluate to **Null** — most commonly, fields read from a database recordset where a column permits **Null**. Unlike a direct comparison with **Null** (which itself yields **Null**), **Nz** returns a usable substitute value. +**Nz** is useful for handling expressions that may evaluate to **Null** --- most commonly, fields read from a database recordset where a column permits **Null**. Unlike a direct comparison with **Null** (which itself yields **Null**), **Nz** returns a usable substitute value. If *value* is anything other than **Null**, **Nz** returns *value* unchanged. diff --git a/docs/Reference/VBA/Conversion/Oct.md b/docs/Reference/VBA/Conversion/Oct.md index ecf6f442..69d59a53 100644 --- a/docs/Reference/VBA/Conversion/Oct.md +++ b/docs/Reference/VBA/Conversion/Oct.md @@ -27,7 +27,7 @@ The `$`-suffixed form returns a **String**; the unsuffixed form returns a **Vari | **Empty** | Zero (`"0"`) | | Any other number | Up to 11 octal characters | -You can represent octal numbers directly by preceding numbers in the proper range with `&O`. For example, `&O10` is the octal notation for decimal 8. +Octal numbers can be represented directly by preceding numbers in the proper range with `&O`. For example, `&O10` is the octal notation for decimal 8. ### Example diff --git a/docs/Reference/VBA/Conversion/Str.md b/docs/Reference/VBA/Conversion/Str.md index f0124b14..fc5cb92a 100644 --- a/docs/Reference/VBA/Conversion/Str.md +++ b/docs/Reference/VBA/Conversion/Str.md @@ -23,7 +23,7 @@ The `$`-suffixed form returns a **String**; the unsuffixed form returns a **Vari When numbers are converted to strings, a leading space is always reserved for the sign of *number*. If *number* is positive, the returned string contains a leading space and the plus sign is implied. -Use the [**Format**](../Strings/Format) function to convert numeric values that you want formatted as dates, times, or currency or in other user-defined formats. Unlike **Str**, the **Format** function doesn't include a leading space for the sign of *number*. +Use the [**Format**](../Strings/Format) function to convert numeric values to be formatted as dates, times, or currency, or in other user-defined formats. Unlike **Str**, the **Format** function doesn't include a leading space for the sign of *number*. > [!NOTE] > The **Str** function recognizes only the period (`.`) as a valid decimal separator. When different decimal separators may be used (for example, in international applications), use [**CStr**](CStr) to convert a number to a string. diff --git a/docs/Reference/VBA/Conversion/index.md b/docs/Reference/VBA/Conversion/index.md index bde65253..3ab1224b 100644 --- a/docs/Reference/VBA/Conversion/index.md +++ b/docs/Reference/VBA/Conversion/index.md @@ -7,24 +7,24 @@ has_toc: false # Conversion module -The **Conversion** module groups together the procedures that produce a value of one type from a value of another — coercing between the intrinsic numeric types, parsing numbers out of strings, formatting numbers as strings, and a handful of related utilities for handling **Null**, error values, and alternate numeric bases. +The **Conversion** module groups together the procedures that produce a value of one type from a value of another --- coercing between the intrinsic numeric types, parsing numbers out of strings, formatting numbers as strings, and a handful of related utilities for handling **Null**, error values, and alternate numeric bases. ## Coercing to a specific type The largest group is the family of **C**-prefixed functions, one per intrinsic data type. Each accepts any valid expression and produces a value of the named type, raising a run-time error if the conversion is not possible: [**CBool**](CBool), [**CByte**](CByte), [**CCur**](CCur), [**CDate**](CDate), [**CDbl**](CDbl), [**CDec**](CDec), [**CInt**](CInt), [**CLng**](CLng), [**CLngLng**](CLngLng), [**CLngPtr**](CLngPtr), [**CSng**](CSng), [**CStr**](CStr), and [**CVar**](CVar). -Beyond their narrowing or widening behaviour, the C-prefix functions are *locale-aware* — they honour the current decimal separator and short date format — which makes them the right choice for parsing values that originated as user input. They also serve as documentation: writing `CLng(x)` makes the intended type of an intermediate result explicit even where the surrounding context would coerce *x* implicitly. +Beyond their narrowing or widening behaviour, the C-prefix functions are *locale-aware* --- they honour the current decimal separator and short date format --- which makes them the right choice for parsing values that originated as user input. They also serve as documentation: writing `CLng(x)` makes the intended type of an intermediate result explicit even where the surrounding context would coerce *x* implicitly. ```tb Dim Amount As Currency Amount = CCur("1,234.56") ' parses with the local decimal separator ``` -Two further constructors return a **Variant** whose subtype is fixed: [**CVDate**](CVDate) builds a **Variant** of subtype **Date** (kept for compatibility with code written before **Date** became an intrinsic type), and [**CVErr**](CVErr) builds a **Variant** of subtype **Error** containing a chosen error number — the canonical way for a **Variant**-returning function to signal "this call failed with this error code" without raising a run-time error. +Two further constructors return a **Variant** whose subtype is fixed: [**CVDate**](CVDate) builds a **Variant** of subtype **Date** (kept for compatibility with code written before **Date** became an intrinsic type), and [**CVErr**](CVErr) builds a **Variant** of subtype **Error** containing a chosen error number --- the canonical way for a **Variant**-returning function to signal "this call failed with this error code" without raising a run-time error. ## Generic conversion -[**CType**](CType) is a twinBASIC extension that takes its target type as a generic parameter, written `CType(Of `*type*`)(`*value*`)`. It plays the same role as the C-prefix functions but for any type known to the compiler, which makes it the standard cast for **Enum** values, interfaces, and user-defined types where no fixed-name function exists. **CType** doubles as a pointer-to-UDT cast — see [Enhanced Pointer Functionality](../../../Features/Language/Pointers#ctypeof-type). +[**CType**](CType) is a twinBASIC extension that takes its target type as a generic parameter, written `CType(Of `*type*`)(`*value*`)`. It plays the same role as the C-prefix functions but for any type known to the compiler, which makes it the standard cast for **Enum** values, interfaces, and user-defined types where no fixed-name function exists. **CType** doubles as a pointer-to-UDT cast --- see [Enhanced Pointer Functionality](../../../Features/Language/Pointers#ctypeof-type). ```tb Dim day As VbDayOfWeek @@ -42,9 +42,9 @@ Debug.Print Fix(-8.4) ' -8 ## Numbers, strings, and bases -[**Str**](Str), [**Hex**](Hex), and [**Oct**](Oct) all return a printable string representation of a number — **Str** in decimal, **Hex** in base 16, and **Oct** in base 8. Going the other way, [**Val**](Val) and [**ValDec**](ValDec) parse leading digits out of a string, returning a **Double** or **Decimal** respectively; both stop at the first unrecognised character and both honour the `&H` and `&O` radix prefixes for hexadecimal and octal literals. +[**Str**](Str), [**Hex**](Hex), and [**Oct**](Oct) all return a printable string representation of a number --- **Str** in decimal, **Hex** in base 16, and **Oct** in base 8. Going the other way, [**Val**](Val) and [**ValDec**](ValDec) parse leading digits out of a string, returning a **Double** or **Decimal** respectively; both stop at the first unrecognised character and both honour the `&H` and `&O` radix prefixes for hexadecimal and octal literals. -These five functions are *culture-invariant* — they always use the period (`.`) as the decimal separator and never read or write a thousands separator — which makes them appropriate for round-tripping through a fixed file format or wire protocol. For locale-aware conversion to and from text, use [**CStr**](CStr) and [**CDbl**](CDbl) (or [**CDec**](CDec)) instead. +These five functions are *culture-invariant* --- they always use the period (`.`) as the decimal separator and never read or write a thousands separator --- which makes them appropriate for round-tripping through a fixed file format or wire protocol. For locale-aware conversion to and from text, use [**CStr**](CStr) and [**CDbl**](CDbl) (or [**CDec**](CDec)) instead. ```tb Debug.Print Hex(255) ' "FF" @@ -56,7 +56,7 @@ Debug.Print Val("&HFF") ' 255 [**Nz**](Nz) returns a substitute value when its argument is **Null**, leaving any other value unchanged. It is most useful for reading nullable columns from a database recordset, where directly concatenating or arithmetically combining the field with another value would otherwise propagate **Null** through the rest of the expression. -[**Error**](Error) returns the descriptive text associated with an error number — the same text that would appear as the **Description** of an [**ErrObject**](../ErrObject) raised with that number. It is the function counterpart to the same-named [**Error** statement](../../Core/Error), which *raises* a run-time error rather than describing one. +[**Error**](Error) returns the descriptive text associated with an error number --- the same text that would appear as the **Description** of an [**ErrObject**](../ErrObject) raised with that number. It is the function counterpart to the same-named [**Error** statement](../../Core/Error), which *raises* a run-time error rather than describing one. ## Macintosh compatibility diff --git a/docs/Reference/VBA/DateTime/Calendar.md b/docs/Reference/VBA/DateTime/Calendar.md index 3d7c2b94..4a038ff3 100644 --- a/docs/Reference/VBA/DateTime/Calendar.md +++ b/docs/Reference/VBA/DateTime/Calendar.md @@ -9,7 +9,7 @@ vba_attribution: true # Calendar {: .no_toc } -Returns or sets a value specifying the type of calendar to use with your project. +Returns or sets a value specifying the type of calendar used by the project. Syntax: **Calendar** [ **=** *calendartype* ] diff --git a/docs/Reference/VBA/DateTime/Date.md b/docs/Reference/VBA/DateTime/Date.md index 64283b67..1af1b929 100644 --- a/docs/Reference/VBA/DateTime/Date.md +++ b/docs/Reference/VBA/DateTime/Date.md @@ -43,17 +43,16 @@ Sets the current system date from a value with a Variant or Date type. Syntax: **Date** **=** *date* -date +*date* +: *required* For systems running Microsoft Windows 95, the *date* specification must be a date from January 1, 1980, through December 31, 2099. For systems running Microsoft Windows NT, *date* must be a date from January 1, 1980, through December 31, 2079. For the Macintosh, *date* must be a date from January 1, 1904, through February 5, 2040. -: For systems running Microsoft Windows 95, the required *date* specification must be a date from January 1, 1980, through December 31, 2099. For systems running Microsoft Windows NT, *date* must be a date from January 1, 1980, through December 31, 2079. For the Macintosh, *date* must be a date from January 1, 1904, through February 5, 2040. - -> [!NOTE] +> [!IMPORTANT] > > In some versions of Microsoft Windows, including Windows 10 and 11, setting the system date is a privileged operation that requires the process to have relevant permissions. Without those permissions, assignment to **Date** results in a Permission Denied runtime error. #### Example -This example uses the **Date** property to set the computer system date. In the development environment, the date literal is displayed in short date format by using the locale settings of your code. +This example uses the **Date** property to set the computer system date. In the development environment, the date literal is displayed in short date format by using the locale settings of the code. ```tb Dim MyDate As Date @@ -64,7 +63,7 @@ Date= MyDate ' Change system date. ## Date$ Property {: #date-1 } -The behavior of the **Date$** property relies on the [**Calendar**](Calendar) property setting. If the calendar is Hijri, **Date$** returns or accepts a 10-character string of the form *mm-dd-yyyy*, where *mm* (01–12), *dd* (01–30) and *yyyy* (1400–1523) are the Hijri month, day, and year. The equivalent Gregorian range is Jan 1, 1980, through Dec 31, 2099. +The behavior of the **Date$** property relies on the [**Calendar**](Calendar) property setting. If the calendar is Hijri, **Date$** returns or accepts a 10-character string of the form *mm-dd-yyyy*, where *mm* (01--12), *dd* (01--30) and *yyyy* (1400--1523) are the Hijri month, day, and year. The equivalent Gregorian range is Jan 1, 1980, through Dec 31, 2099. ### Get {: #date-get-1 } @@ -89,17 +88,16 @@ Sets the current system date from a string. Syntax: **Date$** **=** *date* -date +*date* +: *required* For systems running Microsoft Windows 95, the *date* specification must be a date from January 1, 1980, through December 31, 2099. For systems running Microsoft Windows NT, *date* must be a date from January 1, 1980, through December 31, 2079. For the Macintosh, *date* must be a date from January 1, 1904, through February 5, 2040. -: For systems running Microsoft Windows 95, the required *date* specification must be a date from January 1, 1980, through December 31, 2099. For systems running Microsoft Windows NT, *date* must be a date from January 1, 1980, through December 31, 2079. For the Macintosh, *date* must be a date from January 1, 1904, through February 5, 2040. - -> [!NOTE] +> [!IMPORTANT] > > In some versions of Microsoft Windows, including Windows 10 and 11, setting the system date is a privileged operation that requires the process to have relevant permissions. Without those permissions, assignment to **Date**$ results in a Permission Denied runtime error. #### Example -This example uses the **Date$** property to set the computer system date. In the development environment, the date literal is displayed in short date format by using the locale settings of your code. +This example uses the **Date$** property to set the computer system date. In the development environment, the date literal is displayed in short date format by using the locale settings of the code. ```tb Dim MyDate$ @@ -110,4 +108,5 @@ Date$ = MyDate ' Change the system date. ### See Also - [Time](Time) property -- [Format](../Strings/Format) and [Now](Now) functions \ No newline at end of file +- [Format](../Strings/Format) function +- [Now](Now) function \ No newline at end of file diff --git a/docs/Reference/VBA/DateTime/DateAdd.md b/docs/Reference/VBA/DateTime/DateAdd.md index 7fb3a401..c0ba8b1a 100644 --- a/docs/Reference/VBA/DateTime/DateAdd.md +++ b/docs/Reference/VBA/DateTime/DateAdd.md @@ -37,10 +37,10 @@ Syntax: **DateAdd** ( *interval*, *number*, *date* ) | **n** | Minute | | **s** | Second | -To add days to *date*, you can use Day of Year ("y"), Day ("d"), or Weekday ("w"). +To add days to *date*, use Day of Year ("y"), Day ("d"), or Weekday ("w"). > [!NOTE] -> When you use the "w" interval to add days to a date, **DateAdd** adds the total number of days that you specified, not just workdays (Monday through Friday). +> When the "w" interval is used to add days to a date, **DateAdd** adds the total number of days specified, not just workdays (Monday through Friday). **DateAdd** won't return an invalid date. The following example adds one month to January 31: diff --git a/docs/Reference/VBA/DateTime/DateDiff.md b/docs/Reference/VBA/DateTime/DateDiff.md index ec6ce2d3..acd46592 100644 --- a/docs/Reference/VBA/DateTime/DateDiff.md +++ b/docs/Reference/VBA/DateTime/DateDiff.md @@ -62,13 +62,13 @@ Syntax: **DateDiff** ( *interval*, *date1*, *date2* [, *firstdayofweek* [, *firs | **vbFirstFourDays** | 2 | First week that has at least four days in the new year. | | **vbFirstFullWeek** | 3 | First full week of the year. | -To calculate the number of days between *date1* and *date2*, you can use either Day of Year ("y") or Day ("d"). When *interval* is Weekday ("w"), **DateDiff** returns the number of weeks between the two dates. If *date1* falls on a Monday, **DateDiff** counts the number of Mondays until *date2*. It counts *date2* but not *date1*. +To calculate the number of days between *date1* and *date2*, use either Day of Year ("y") or Day ("d"). When *interval* is Weekday ("w"), **DateDiff** returns the number of weeks between the two dates. If *date1* falls on a Monday, **DateDiff** counts the number of Mondays until *date2*. It counts *date2* but not *date1*. If *interval* is Week ("ww"), however, **DateDiff** returns the number of calendar weeks between the two dates. It counts the number of Sundays between *date1* and *date2*. **DateDiff** counts *date2* if it falls on a Sunday, but it doesn't count *date1*, even if it does fall on a Sunday. If *date1* refers to a later point in time than *date2*, the function returns a negative number. The *firstdayofweek* argument affects calculations that use the "w" and "ww" interval symbols. -If *date1* or *date2* is a date literal, the specified year becomes a permanent part of that date. If *date1* or *date2* is enclosed in double quotation marks and you omit the year, the current year is inserted each time the expression is evaluated. +If *date1* or *date2* is a date literal, the specified year becomes a permanent part of that date. If *date1* or *date2* is enclosed in double quotation marks and the year is omitted, the current year is inserted each time the expression is evaluated. When comparing December 31 to January 1 of the immediately succeeding year, **DateDiff** for Year ("yyyy") returns 1 even though only a day has elapsed. diff --git a/docs/Reference/VBA/DateTime/DatePart.md b/docs/Reference/VBA/DateTime/DatePart.md index cea13951..a8fd8a0a 100644 --- a/docs/Reference/VBA/DateTime/DatePart.md +++ b/docs/Reference/VBA/DateTime/DatePart.md @@ -64,7 +64,7 @@ Syntax: **DatePart** ( *interval*, *date* [, *firstdayofweek* [, *firstweekofyea The *firstdayofweek* argument affects calculations that use the "w" and "ww" interval symbols. -If *date* is a date literal, the specified year becomes a permanent part of that date. If *date* is enclosed in double quotation marks and you omit the year, the current year is inserted each time the expression is evaluated. +If *date* is a date literal, the specified year becomes a permanent part of that date. If *date* is enclosed in double quotation marks and the year is omitted, the current year is inserted each time the expression is evaluated. If the [**Calendar**](Calendar) property setting is Gregorian, the supplied date must be Gregorian. If the calendar is Hijri, the supplied date must be Hijri. The returned date part is in the time period units of the current calendar. diff --git a/docs/Reference/VBA/DateTime/DateSerial.md b/docs/Reference/VBA/DateTime/DateSerial.md index 00987d76..311912e6 100644 --- a/docs/Reference/VBA/DateTime/DateSerial.md +++ b/docs/Reference/VBA/DateTime/DateSerial.md @@ -22,15 +22,15 @@ Syntax: **DateSerial** ( *year*, *month*, *day* ) *day* : *required* **Integer**. Any numeric expression. -To specify a date, such as December 31, 1991, the range of numbers for each **DateSerial** argument should be in the accepted range for the unit (1–31 for days, 1–12 for months). However, you can also specify relative dates for each argument by using any numeric expression that represents some number of days, months, or years before or after a certain date. +To specify a date, such as December 31, 1991, the range of numbers for each **DateSerial** argument should be in the accepted range for the unit (1--31 for days, 1--12 for months). Relative dates can also be specified for each argument by using any numeric expression that represents some number of days, months, or years before or after a certain date. -The following example uses numeric expressions instead of absolute date numbers. The **DateSerial** function returns a date that is the day before the first day (`1 - 1`), two months before August (`8 - 2`), 10 years before 1990 (`1990 - 10`) — in other words, May 31, 1980. +The following example uses numeric expressions instead of absolute date numbers. The **DateSerial** function returns a date that is the day before the first day (`1 - 1`), two months before August (`8 - 2`), 10 years before 1990 (`1990 - 10`) --- in other words, May 31, 1980. -When any argument exceeds the accepted range, it increments to the next larger unit as appropriate. For example, if you specify 35 days, it is evaluated as one month and some number of days, depending on where in the year it is applied. If any single argument is outside the range -32,768 to 32,767, an error occurs. If the date specified by the three arguments falls outside the acceptable range of dates, an error occurs. +When any argument exceeds the accepted range, it increments to the next larger unit as appropriate. For example, 35 days is evaluated as one month and some number of days, depending on where in the year it is applied. If any single argument is outside the range -32,768 to 32,767, an error occurs. If the date specified by the three arguments falls outside the acceptable range of dates, an error occurs. -Two-digit years for the *year* argument are interpreted based on user-defined machine settings. The default settings are that values between 0 and 29 are interpreted as the years 2000–2029, and values between 30 and 99 are interpreted as the years 1930–1999. For all other *year* arguments, use a four-digit year. +Two-digit years for the *year* argument are interpreted based on user-defined machine settings. The default settings are that values between 0 and 29 are interpreted as the years 2000--2029, and values between 30 and 99 are interpreted as the years 1930--1999. For all other *year* arguments, use a four-digit year. -If the [**Calendar**](Calendar) property setting is Gregorian, the supplied value is assumed to be Gregorian. If the setting is Hijri, the supplied value is assumed to be Hijri, and two-digit *year* values between 0 and 99 are interpreted as the years 1400–1499. +If the [**Calendar**](Calendar) property setting is Gregorian, the supplied value is assumed to be Gregorian. If the setting is Hijri, the supplied value is assumed to be Hijri, and two-digit *year* values between 0 and 99 are interpreted as the years 1400--1499. ### Example diff --git a/docs/Reference/VBA/DateTime/DateValue.md b/docs/Reference/VBA/DateTime/DateValue.md index 49c182ba..01c71443 100644 --- a/docs/Reference/VBA/DateTime/DateValue.md +++ b/docs/Reference/VBA/DateTime/DateValue.md @@ -16,9 +16,9 @@ Syntax: **DateValue** ( *date* ) *date* : *required* String expression representing a date from January 1, 100, through December 31, 9999. However, *date* can also be any expression that can represent a date, a time, or both a date and time, in that range. -If *date* is a string that includes only numbers separated by valid date separators, **DateValue** recognizes the order for month, day, and year according to the Short Date format specified for your system. **DateValue** also recognizes unambiguous dates that contain month names, either in long or abbreviated form. For example, in addition to recognizing 12/30/1991 and 12/30/91, **DateValue** also recognizes December 30, 1991 and Dec 30, 1991. +If *date* is a string that includes only numbers separated by valid date separators, **DateValue** recognizes the order for month, day, and year according to the Short Date format specified by the system. **DateValue** also recognizes unambiguous dates that contain month names, either in long or abbreviated form. For example, in addition to recognizing 12/30/1991 and 12/30/91, **DateValue** also recognizes December 30, 1991 and Dec 30, 1991. -If the year part of *date* is omitted, **DateValue** uses the current year from your computer's system date. +If the year part of *date* is omitted, **DateValue** uses the current year from the system date. If the *date* argument includes time information, **DateValue** doesn't return it. However, if *date* includes invalid time information (such as "89:98"), an error occurs. diff --git a/docs/Reference/VBA/DateTime/Now.md b/docs/Reference/VBA/DateTime/Now.md index 69f556c9..23788afd 100644 --- a/docs/Reference/VBA/DateTime/Now.md +++ b/docs/Reference/VBA/DateTime/Now.md @@ -9,7 +9,7 @@ vba_attribution: true # Now {: .no_toc } -Returns a **Variant** (**Date**) specifying the current date and time according to your computer's system date and time. +Returns a **Variant** (**Date**) specifying the current date and time according to the system date and time. Syntax: **Now** [ **()** ] diff --git a/docs/Reference/VBA/DateTime/Time.md b/docs/Reference/VBA/DateTime/Time.md index e20758ac..d0a87570 100644 --- a/docs/Reference/VBA/DateTime/Time.md +++ b/docs/Reference/VBA/DateTime/Time.md @@ -45,7 +45,7 @@ Syntax: **Time** **=** *time* : *required* Any numeric expression, string expression, or any combination that can represent a time. -If *time* is a string, **Time** attempts to convert it to a time by using the time separators specified for your system. If it cannot be converted to a valid time, an error occurs. +If *time* is a string, **Time** attempts to convert it to a time by using the time separators specified by the system. If it cannot be converted to a valid time, an error occurs. > [!NOTE] > diff --git a/docs/Reference/VBA/DateTime/TimeSerial.md b/docs/Reference/VBA/DateTime/TimeSerial.md index eeb77dc8..66638acb 100644 --- a/docs/Reference/VBA/DateTime/TimeSerial.md +++ b/docs/Reference/VBA/DateTime/TimeSerial.md @@ -22,7 +22,7 @@ Syntax: **TimeSerial** ( *hour*, *minute*, *second* ) *second* : *required* **Integer**. Any numeric expression. -To specify a time, such as 11:59:59, the range of numbers for each **TimeSerial** argument should be in the normal range for the unit: 0–23 for hours and 0–59 for minutes and seconds. However, you can also specify relative times for each argument by using any numeric expression that represents some number of hours, minutes, or seconds before or after a certain time. +To specify a time, such as 11:59:59, the range of numbers for each **TimeSerial** argument should be in the normal range for the unit: 0--23 for hours and 0--59 for minutes and seconds. Relative times can also be specified for each argument by using any numeric expression that represents some number of hours, minutes, or seconds before or after a certain time. The following example uses expressions instead of absolute time numbers. The **TimeSerial** function returns a time for 15 minutes before (`-15`) six hours before noon (`12 - 6`), or 5:45:00 A.M. @@ -30,7 +30,7 @@ The following example uses expressions instead of absolute time numbers. The **T TimeSerial(12 - 6, -15, 0) ``` -When any argument exceeds the normal range for that argument, it increments to the next larger unit as appropriate. For example, if you specify 75 minutes, it is evaluated as one hour and 15 minutes. If any single argument is outside the range -32,768 to 32,767, an error occurs. If the time specified by the three arguments causes the date to fall outside the acceptable range of dates, an error occurs. +When any argument exceeds the normal range for that argument, it increments to the next larger unit as appropriate. For example, 75 minutes is evaluated as one hour and 15 minutes. If any single argument is outside the range -32,768 to 32,767, an error occurs. If the time specified by the three arguments causes the date to fall outside the acceptable range of dates, an error occurs. ### Example diff --git a/docs/Reference/VBA/DateTime/TimeValue.md b/docs/Reference/VBA/DateTime/TimeValue.md index 28f7324d..33df5128 100644 --- a/docs/Reference/VBA/DateTime/TimeValue.md +++ b/docs/Reference/VBA/DateTime/TimeValue.md @@ -16,7 +16,7 @@ Syntax: **TimeValue** ( *time* ) *time* : *required* Normally a string expression representing a time from 0:00:00 (12:00:00 A.M.) to 23:59:59 (11:59:59 P.M.), inclusive. However, *time* can also be any expression that represents a time in that range. If *time* contains **Null**, **Null** is returned. -You can enter valid times by using a 12-hour or 24-hour clock. For example, `"2:24PM"` and `"14:24"` are both valid *time* arguments. +Valid times can be entered using a 12-hour or 24-hour clock. For example, `"2:24PM"` and `"14:24"` are both valid *time* arguments. If the *time* argument contains date information, **TimeValue** doesn't return it. However, if *time* includes invalid date information, an error occurs. diff --git a/docs/Reference/VBA/DateTime/index.md b/docs/Reference/VBA/DateTime/index.md index cdc7d934..e62eb998 100644 --- a/docs/Reference/VBA/DateTime/index.md +++ b/docs/Reference/VBA/DateTime/index.md @@ -7,16 +7,16 @@ has_toc: false # DateTime module -The **DateTime** module groups together the procedures for reading the system clock, building **Date** values from their components, parsing them out of strings, taking them apart again, and shifting them forward or backward by a chosen unit. A single setting — the [**Calendar**](Calendar) property — switches the whole module between the Gregorian and Hijri calendars. +The **DateTime** module groups together the procedures for reading the system clock, building **Date** values from their components, parsing them out of strings, taking them apart again, and shifting them forward or backward by a chosen unit. A single setting --- the [**Calendar**](Calendar) property --- switches the whole module between the Gregorian and Hijri calendars. ## Reading the system clock -[**Now**](Now) returns the current system date *and* time as a single **Variant** of subtype **Date**; [**Date**](Date) returns just the date portion and [**Time**](Time) just the time portion. Each of the latter two has a `$`-suffixed sibling — **Date$** and **Time$** — that returns the same value as a formatted **String** rather than a **Date**. All four are also writable: assigning to them changes the system clock, subject to the operating system's privilege requirements. +[**Now**](Now) returns the current system date *and* time as a single **Variant** of subtype **Date**; [**Date**](Date) returns just the date portion and [**Time**](Time) just the time portion. Each of the latter two has a `$`-suffixed sibling --- **Date$** and **Time$** --- that returns the same value as a formatted **String** rather than a **Date**. All four are also writable: assigning to them changes the system clock, subject to the operating system's privilege requirements. > [!NOTE] > In twinBASIC, **Date**, **Date$**, **Time**, and **Time$** are implemented as module-level properties rather than the functions/statements they were in VBx. The syntax and semantics are otherwise unchanged. -[**Timer**](Timer) returns a **Single** giving the number of seconds — with fractional precision — elapsed since midnight, and is the conventional way to measure elapsed time within a run. +[**Timer**](Timer) returns a **Single** giving the number of seconds --- with fractional precision --- elapsed since midnight, and is the conventional way to measure elapsed time within a run. ```tb Dim Started As Single @@ -27,18 +27,18 @@ Debug.Print "Elapsed: " & (Timer - Started) & " seconds" ## Building dates and times from components -[**DateSerial**](DateSerial) builds a **Date** from year, month, and day arguments; [**TimeSerial**](TimeSerial) builds one from hour, minute, and second. Both honour out-of-range arguments by carrying — passing 13 as the month rolls into the next year, and passing 75 as the minute rolls into the next hour — which makes them well-suited to expressing relative dates as plain arithmetic on the components. +[**DateSerial**](DateSerial) builds a **Date** from year, month, and day arguments; [**TimeSerial**](TimeSerial) builds one from hour, minute, and second. Both honour out-of-range arguments by carrying --- passing 13 as the month rolls into the next year, and passing 75 as the minute rolls into the next hour --- which makes them well-suited to expressing relative dates as plain arithmetic on the components. ```tb Dim FirstOfNextMonth As Date FirstOfNextMonth = DateSerial(Year(Now), Month(Now) + 1, 1) ``` -[**DateValue**](DateValue) parses a date out of a string in the system's short date format — recognising both numeric forms and unambiguous month names — and discards any time portion. [**TimeValue**](TimeValue) is the corresponding parser for time strings; it discards any date portion. For values that originate as date literals in source code, the surrounding `#...#` syntax is usually a better fit than either parser. +[**DateValue**](DateValue) parses a date out of a string in the system's short date format --- recognising both numeric forms and unambiguous month names --- and discards any time portion. [**TimeValue**](TimeValue) is the corresponding parser for time strings; it discards any date portion. For values that originate as date literals in source code, the surrounding `#...#` syntax is usually a better fit than either parser. ## Extracting parts of a date -The single-component accessors each return one part of a **Date** as an **Integer**: [**Year**](Year), [**Month**](Month), [**Day**](Day), [**Weekday**](Weekday), [**Hour**](Hour), [**Minute**](Minute), and [**Second**](Second). [**DatePart**](DatePart) generalises the same idea, taking the chosen part as a string interval code (`"yyyy"`, `"q"`, `"m"`, `"d"`, ...) — useful when the unit itself is a parameter. +The single-component accessors each return one part of a **Date** as an **Integer**: [**Year**](Year), [**Month**](Month), [**Day**](Day), [**Weekday**](Weekday), [**Hour**](Hour), [**Minute**](Minute), and [**Second**](Second). [**DatePart**](DatePart) generalises the same idea, taking the chosen part as a string interval code (`"yyyy"`, `"q"`, `"m"`, `"d"`, ...) --- useful when the unit itself is a parameter. ```tb Dim D As Date @@ -51,7 +51,7 @@ Debug.Print Weekday(D) ' 4 — Wednesday ## Date arithmetic -[**DateAdd**](DateAdd) shifts a date by a chosen number of intervals — years, quarters, months, weeks, days, hours, minutes, or seconds — taking calendar irregularities (varying month lengths, leap years) into account, and clamping to the last day of the target month when a literal day-of-month would be invalid. [**DateDiff**](DateDiff) does the inverse: it returns the count of whole intervals between two dates. Both share the same string interval codes used by **DatePart**. +[**DateAdd**](DateAdd) shifts a date by a chosen number of intervals --- years, quarters, months, weeks, days, hours, minutes, or seconds --- taking calendar irregularities (varying month lengths, leap years) into account, and clamping to the last day of the target month when a literal day-of-month would be invalid. [**DateDiff**](DateDiff) does the inverse: it returns the count of whole intervals between two dates. Both share the same string interval codes used by **DatePart**. ```tb Debug.Print DateAdd("m", 1, #1/31/2026#) ' 2/28/2026 — clamped to last day of February @@ -60,7 +60,7 @@ Debug.Print DateDiff("d", #1/1/2026#, #5/9/2026#) ' 128 ## Calendar selection -The [**Calendar**](Calendar) property selects the calendar — **vbCalGreg** (Gregorian, the default) or **vbCalHijri** (Hijri) — used by the rest of the module. The setting controls how **Date$** formats the system date, how arguments to **DateSerial**, **DateValue**, **DateAdd**, and **DateDiff** are interpreted, and how the parts returned by **DatePart**, **Year**, **Month**, **Day**, and **Weekday** are reported. +The [**Calendar**](Calendar) property selects the calendar --- **vbCalGreg** (Gregorian, the default) or **vbCalHijri** (Hijri) --- used by the rest of the module. The setting controls how **Date$** formats the system date, how arguments to **DateSerial**, **DateValue**, **DateAdd**, and **DateDiff** are interpreted, and how the parts returned by **DatePart**, **Year**, **Month**, **Day**, and **Weekday** are reported. ## Members diff --git a/docs/Reference/VBA/ErrObject/Clear.md b/docs/Reference/VBA/ErrObject/Clear.md index 02943c59..93eddaab 100644 --- a/docs/Reference/VBA/ErrObject/Clear.md +++ b/docs/Reference/VBA/ErrObject/Clear.md @@ -7,7 +7,7 @@ vba_attribution: true # Clear {: .no_toc } -Clears all property settings of the **Err** object — [**Number**](Number) is reset to **0**, the string properties to zero-length strings, and [**HelpContext**](HelpContext) to **0**. +Clears all property settings of the **Err** object --- [**Number**](Number) is reset to **0**, the string properties to zero-length strings, and [**HelpContext**](HelpContext) to **0**. Syntax: **Err**.**Clear** @@ -19,11 +19,11 @@ Use **Clear** to explicitly reset the **Err** object after an error has been han > [!NOTE] > -> The **On Error Resume Next** construct may be preferable to **On Error GoTo** when handling errors generated during access to other objects. Checking **Err** after each interaction with an object removes ambiguity about which object the error came from. You can be sure which object placed the code in [**Err.Number**](Number) and which object originally generated the error (the object specified in [**Err.Source**](Source)). +> The **On Error Resume Next** construct may be preferable to **On Error GoTo** when handling errors generated during access to other objects. Checking **Err** after each interaction with an object removes ambiguity about which object the error came from --- both the object that placed the code in [**Err.Number**](Number) and the object that originally generated the error (specified in [**Err.Source**](Source)) can be identified, and they may be distinct. ### Example -This example uses **Err.Clear** to reset the **Err** object's numeric properties to zero and its string properties to zero-length strings between iterations of a loop. If **Clear** were omitted, the error message dialog box would be displayed on every iteration after an error first occurred — whether or not the next calculation actually generated an error. +This example uses **Err.Clear** to reset the **Err** object's numeric properties to zero and its string properties to zero-length strings between iterations of a loop. If **Clear** were omitted, the error message dialog box would be displayed on every iteration after an error first occurred --- whether or not the next calculation actually generated an error. ```tb Dim result(10) As Integer ' Declare an array whose elements diff --git a/docs/Reference/VBA/ErrObject/Description.md b/docs/Reference/VBA/ErrObject/Description.md index 4db8e0bc..889062c8 100644 --- a/docs/Reference/VBA/ErrObject/Description.md +++ b/docs/Reference/VBA/ErrObject/Description.md @@ -16,9 +16,9 @@ Syntax: *errorDescription* : A **String** describing the error. When read, **Description** returns the descriptive text for the active error, or a zero-length string if no error is active. -The **Description** setting consists of a short description of the error. Use this property to alert the user to an error that you either can't or don't want to handle. +The **Description** setting consists of a short description of the error. Use this property to alert the user to an error that the code cannot or does not handle. -When generating a user-defined error, assign a short description of your error to the **Description** property. If **Description** isn't filled in and the value of [**Number**](Number) corresponds to a built-in run-time error, the string returned by the [**Error**](../Conversion/Error) function is placed in **Description** when the error is generated. +When generating a user-defined error, assign a short description of the error to the **Description** property. If **Description** isn't filled in and the value of [**Number**](Number) corresponds to a built-in run-time error, the string returned by the [**Error**](../Conversion/Error) function is placed in **Description** when the error is generated. ### Example diff --git a/docs/Reference/VBA/ErrObject/HelpContext.md b/docs/Reference/VBA/ErrObject/HelpContext.md index d2589096..da18386b 100644 --- a/docs/Reference/VBA/ErrObject/HelpContext.md +++ b/docs/Reference/VBA/ErrObject/HelpContext.md @@ -20,9 +20,7 @@ The **HelpContext** property is used to automatically display the Help topic spe If both **HelpFile** and **HelpContext** are empty, the value of [**Number**](Number) is checked. If **Number** corresponds to a built-in run-time error, the Help context ID for that error is used. If the **Number** value doesn't correspond to a built-in error, the contents page of the Help file is displayed. -> [!NOTE] -> -> Write routines in your application to handle typical errors. When programming with an object, you can use the object's Help file to improve the quality of your error handling, or to display a meaningful message to the user when an error isn't recoverable. +Write routines to handle typical errors. When programming with an object, the object's Help file can improve error handling or display a meaningful message to the user when an error isn't recoverable. ### Example diff --git a/docs/Reference/VBA/ErrObject/HelpFile.md b/docs/Reference/VBA/ErrObject/HelpFile.md index 9f908a39..9d685657 100644 --- a/docs/Reference/VBA/ErrObject/HelpFile.md +++ b/docs/Reference/VBA/ErrObject/HelpFile.md @@ -18,9 +18,7 @@ Syntax: If a Help file is specified in **HelpFile**, it is automatically called when the user presses the **Help** button (or **F1**) in the error message dialog box. If the [**HelpContext**](HelpContext) property contains a valid context ID for the specified file, that topic is displayed automatically. -> [!NOTE] -> -> Write routines in your application to handle typical errors. When programming with an object, you can use the object's Help file to improve the quality of your error handling, or to display a meaningful message to the user when an error isn't recoverable. +Write routines to handle typical errors. When programming with an object, the object's Help file can improve error handling or display a meaningful message to the user when an error isn't recoverable. ### Example diff --git a/docs/Reference/VBA/ErrObject/LastHresult.md b/docs/Reference/VBA/ErrObject/LastHresult.md index 1566dee7..20b04662 100644 --- a/docs/Reference/VBA/ErrObject/LastHresult.md +++ b/docs/Reference/VBA/ErrObject/LastHresult.md @@ -17,7 +17,7 @@ To inspect both success and non-failure status codes, read **LastHresult** immed ### Example ```tb -' Assume comObject exposes a method whose HRESULT carries status information. +' Assume comObject exposes a method whose HRESULT contains status information. Sub CheckHresult() comObject.SomeMethod Dim status As Long diff --git a/docs/Reference/VBA/ErrObject/Number.md b/docs/Reference/VBA/ErrObject/Number.md index 9962fec3..b90178cc 100644 --- a/docs/Reference/VBA/ErrObject/Number.md +++ b/docs/Reference/VBA/ErrObject/Number.md @@ -16,7 +16,7 @@ Syntax: *errorNumber* : A **Long** error code to assign to the **Err** object. When read, **Number** returns the current error code, or **0** if no error is active. -When returning a user-defined error from an object, set **Err.Number** by adding the number you selected as an error code to the [**vbObjectError**](../Constants/#vbObjectError) constant. For example, the following code returns 1051 as an error code: +When returning a user-defined error from an object, set **Err.Number** by adding the chosen error code to the [**vbObjectError**](../Constants/#vbObjectError) constant. For example, the following code returns 1051 as an error code: ```tb Err.Raise Number:=vbObjectError + 1051, Source:="SomeClass" diff --git a/docs/Reference/VBA/ErrObject/Raise.md b/docs/Reference/VBA/ErrObject/Raise.md index 635594f8..10f8400e 100644 --- a/docs/Reference/VBA/ErrObject/Raise.md +++ b/docs/Reference/VBA/ErrObject/Raise.md @@ -12,7 +12,7 @@ Generates a run-time error. Syntax: **Err**.**Raise** *number* [ **,** *source* [ **,** *description* [ **,** *helpfile* [ **,** *helpcontext* ] ] ] ] *number* -: *required* A **Long** that identifies the nature of the error. Built-in errors fall in the range 0–65535; the range 0–512 is reserved for system errors and 513–65535 is available for user-defined errors. When raising a user-defined error from a class module, add the chosen number to the [**vbObjectError**](../Constants/#vbObjectError) constant — for example, `vbObjectError + 513`. +: *required* A **Long** that identifies the nature of the error. Built-in errors fall in the range 0--65535; the range 0--512 is reserved for system errors and 513--65535 is available for user-defined errors. When raising a user-defined error from a class module, add the chosen number to the [**vbObjectError**](../Constants/#vbObjectError) constant --- for example, `vbObjectError + 513`. *source* : *optional* A **String** naming the object or application that generated the error. When setting the [**Source**](Source) property for an object, use the form *project.class*. If *source* is not specified, the programmatic ID of the current twinBASIC project is used. @@ -26,7 +26,7 @@ Syntax: **Err**.**Raise** *number* [ **,** *source* [ **,** *description* [ **,* *helpcontext* : *optional* The context ID identifying a topic within *helpfile* that provides help for the error. If omitted, the [**HelpContext**](HelpContext) property is cleared. -All of the arguments are optional except *number*. If you call **Raise** without specifying some arguments, and the corresponding properties of the **Err** object still hold values from an earlier error, those values serve as the values for your error. +All of the arguments are optional except *number*. When **Raise** is called without specifying some arguments, and the corresponding properties of the **Err** object still hold values from an earlier error, those values serve as the values for the current error. **Raise** is preferred over the [**Error**](../../Core/Error) statement when generating run-time errors, particularly inside class modules: the **Err** object holds richer information than the **Error** statement can supply. With **Raise** the source that generated the error can be specified in the [**Source**](Source) property, online Help for the error can be referenced through [**HelpFile**](HelpFile) and [**HelpContext**](HelpContext), and so on. diff --git a/docs/Reference/VBA/ErrObject/Source.md b/docs/Reference/VBA/ErrObject/Source.md index 08cc371c..1e9a1366 100644 --- a/docs/Reference/VBA/ErrObject/Source.md +++ b/docs/Reference/VBA/ErrObject/Source.md @@ -18,17 +18,17 @@ Syntax: The **Source** property holds a string representing the object that generated the error; the expression is usually the object's class name or programmatic ID. -Use **Source** to provide information when your code is unable to handle an error generated in an accessed object. For example, if you call into an Automation server and it raises a `Division by zero` error, the server sets **Err.Number** to its error code for that error and sets **Source** to its programmatic ID. +Use **Source** to provide information when handling code cannot handle an error generated in an accessed object. For example, when a call into an Automation server raises a `Division by zero` error, the server sets **Err.Number** to its error code for that error and sets **Source** to its programmatic ID. -When generating an error from your own code, **Source** is your application's programmatic ID. For class modules, **Source** should contain a name in the form *project.class*. +When generating an error from user code, **Source** is the application's programmatic ID. For class modules, **Source** should contain a name in the form *project.class*. -When an unexpected error occurs in your code, the **Source** property is automatically filled in. For errors in a standard module, **Source** contains the project name. For errors in a class module, **Source** contains a name in *project.class* form. +When an unexpected error occurs, the **Source** property is automatically filled in. For errors in a standard module, **Source** contains the project name. For errors in a class module, **Source** contains a name in *project.class* form. ### Example This example assigns the programmatic ID of an Automation object to the variable `myObjectID`, and then assigns that to the **Source** property of the **Err** object when it generates an error with the [**Raise**](Raise) method. -When handling errors, you should not rely on the **Source** property (or any **Err** properties other than [**Number**](Number)) for control flow. The intended use of properties other than **Number** is to display detailed information to an end user when you can't handle an error. +When handling errors, do not rely on the **Source** property (or any **Err** properties other than [**Number**](Number)) for control flow. The intended use of properties other than **Number** is to display detailed information to an end user when an error cannot be handled. ```tb Dim myObjectID As String, myHelpFile As String, myHelpContext As Long diff --git a/docs/Reference/VBA/ErrObject/index.md b/docs/Reference/VBA/ErrObject/index.md index 97f14846..7150cc76 100644 --- a/docs/Reference/VBA/ErrObject/index.md +++ b/docs/Reference/VBA/ErrObject/index.md @@ -8,7 +8,7 @@ has_toc: false # ErrObject class -The **Err** object holds information about the most recent run-time error. It is a global, intrinsic singleton — there is no need to declare it or construct one with **New**, just reference it as **Err**. The default property is [**Number**](Number), so a bare **Err** is equivalent to `Err.Number`. +The **Err** object holds information about the most recent run-time error. It is a global, intrinsic singleton --- there is no need to declare it or construct one with **New**, just reference it as **Err**. The default property is [**Number**](Number), so a bare **Err** is equivalent to `Err.Number`. ## Inspecting an error diff --git a/docs/Reference/VBA/FileSystem/ChDir.md b/docs/Reference/VBA/FileSystem/ChDir.md index d47ea1a0..cca3dfed 100644 --- a/docs/Reference/VBA/FileSystem/ChDir.md +++ b/docs/Reference/VBA/FileSystem/ChDir.md @@ -14,9 +14,9 @@ Changes the current directory or folder. Syntax: **ChDir** *path* path -: A string expression that identifies which directory or folder becomes the new default directory or folder. The *path* may include the drive. If no drive is specified, **ChDir** changes the default directory or folder on the current drive. +: A string expression that identifies which directory or folder becomes the new default directory or folder. The *path* may include the drive. If no drive is specified, **ChDir** changes the default directory or folder on the current drive. -The **ChDir** statement changes the default directory but not the default drive. For example, if the default drive is C, the following statement changes the default directory on drive D, but C remains the default drive: +The **ChDir** statement changes the default directory but not the default drive. For example, if the default drive is C, the following statement changes the default directory on drive D, but C remains the default drive: ```tb ChDir "D:\TMP" ' Make "D:\TMP" the current folder. @@ -46,7 +46,7 @@ On MacOS, the default drive name is "HD" and portions of the pathname are separa ### Example -This example uses the **ChDir** statement to change the current directory or folder. +This example uses the **ChDir** statement to change the current directory or folder. ```tb ' Change current directory or folder to "MYDIR". diff --git a/docs/Reference/VBA/FileSystem/ChDrive.md b/docs/Reference/VBA/FileSystem/ChDrive.md index 3dcca1b0..e4ed21d6 100644 --- a/docs/Reference/VBA/FileSystem/ChDrive.md +++ b/docs/Reference/VBA/FileSystem/ChDrive.md @@ -15,7 +15,7 @@ Syntax: **ChDrive** *drive* drive -: A string expression that specifies an existing drive. If you supply a zero-length string (""), the current drive doesn't change. If the *drive* argument is a multiple-character string, **ChDrive** uses only the first letter. +: A string expression that specifies an existing drive. If *drive* is a zero-length string (""), the current drive doesn't change. If the *drive* argument is a multiple-character string, **ChDrive** uses only the first letter. ### See Also diff --git a/docs/Reference/VBA/FileSystem/Dir.md b/docs/Reference/VBA/FileSystem/Dir.md index 790b33a6..daa04e5e 100644 --- a/docs/Reference/VBA/FileSystem/Dir.md +++ b/docs/Reference/VBA/FileSystem/Dir.md @@ -32,14 +32,14 @@ The *attributes* argument settings are: **Dir** supports the use of multiple-character (`*`) and single-character (`?`) wildcards to specify multiple files. -You must specify *pathname* the first time you call the **Dir** function, or an error occurs. If you also specify file attributes, *pathname* must be included. +The first call to **Dir** must specify *pathname*, or an error occurs. When file attributes are also specified, *pathname* must be included. -**Dir** returns the first file name that matches *pathname*. To get any additional file names that match *pathname*, call **Dir** again with no arguments. When no more file names match, **Dir** returns a zero-length string (`""`). After a zero-length string is returned, you must specify *pathname* in subsequent calls, or an error occurs. +**Dir** returns the first file name that matches *pathname*. To get any additional file names that match *pathname*, call **Dir** again with no arguments. When no more file names match, **Dir** returns a zero-length string (`""`). After a zero-length string is returned, subsequent calls must specify *pathname*, or an error occurs. -You can change to a new *pathname* without retrieving all of the file names that match the current *pathname*. However, you can't call the **Dir** function recursively. Calling **Dir** with the **vbDirectory** attribute does not continually return subdirectories. +A new *pathname* can be specified without first retrieving all of the file names that match the current *pathname*. However, **Dir** cannot be called recursively. Calling **Dir** with the **vbDirectory** attribute does not continually return subdirectories. > [!TIP] -> Because file names are retrieved in case-insensitive order on Windows, you may want to store returned file names in an array, and then sort the array. +> Because file names are retrieved in case-insensitive order on Windows, consider storing returned file names in an array and sorting the array. ### See Also diff --git a/docs/Reference/VBA/FileSystem/FileCopy.md b/docs/Reference/VBA/FileSystem/FileCopy.md index 55fb57e2..63bc4663 100644 --- a/docs/Reference/VBA/FileSystem/FileCopy.md +++ b/docs/Reference/VBA/FileSystem/FileCopy.md @@ -19,7 +19,7 @@ Syntax: **FileCopy** *source*, *destination* *destination* : String expression that specifies the target file name. The *destination* may include directory or folder, and drive. -If you try to use the **FileCopy** statement on a file that is currently open, an error occurs. +An error occurs when **FileCopy** is used on a file that is currently open. ### Example diff --git a/docs/Reference/VBA/FileSystem/FileDateTime.md b/docs/Reference/VBA/FileSystem/FileDateTime.md index 92822553..b532a5ef 100644 --- a/docs/Reference/VBA/FileSystem/FileDateTime.md +++ b/docs/Reference/VBA/FileSystem/FileDateTime.md @@ -18,7 +18,7 @@ Syntax: **FileDateTime(** *pathname* **)** ### Example -This example uses the **FileDateTime** function to determine the date and time a file was created or last modified. The format of the date and time displayed is based on the locale settings of your system. +This example uses the **FileDateTime** function to determine the date and time a file was created or last modified. The format of the date and time displayed is based on the system's locale settings. ```tb Dim MyStamp diff --git a/docs/Reference/VBA/FileSystem/FreeFile.md b/docs/Reference/VBA/FileSystem/FreeFile.md index f13ee88c..f170b38c 100644 --- a/docs/Reference/VBA/FileSystem/FreeFile.md +++ b/docs/Reference/VBA/FileSystem/FreeFile.md @@ -14,7 +14,7 @@ Returns an **Integer** representing the next file number available for use by th Syntax: **FreeFile** [ **(** *rangenumber* **)** ] *rangenumber* -: *optional* **Variant** that specifies the range from which the next free file number is to be returned. Specify **0** (default) to return a file number in the range 1–255, inclusive. Specify **1** to return a file number in the range 256–511. +: *optional* **Variant** that specifies the range from which the next free file number is to be returned. Specify **0** (default) to return a file number in the range 1--255, inclusive. Specify **1** to return a file number in the range 256--511. Use **FreeFile** to supply a file number that is not already in use. diff --git a/docs/Reference/VBA/FileSystem/GetAttr.md b/docs/Reference/VBA/FileSystem/GetAttr.md index 05168827..fbf9e3e6 100644 --- a/docs/Reference/VBA/FileSystem/GetAttr.md +++ b/docs/Reference/VBA/FileSystem/GetAttr.md @@ -29,7 +29,7 @@ The value returned by **GetAttr** is the sum of the following attribute values: | **vbDirectory** | 16 | Directory or folder. | | **vbArchive** | 32 | File has changed since last backup. | -To determine which attributes are set, use the **And** operator to perform a bitwise comparison of the value returned by **GetAttr** and the value of the individual file attribute you want. If the result is not zero, that attribute is set for the named file. +To determine which attributes are set, use the **And** operator to perform a bitwise comparison of the value returned by **GetAttr** and the value of the individual file attribute being tested. If the result is not zero, that attribute is set for the named file. ```tb Result = GetAttr(FName) And vbArchive diff --git a/docs/Reference/VBA/FileSystem/Input.md b/docs/Reference/VBA/FileSystem/Input.md index d2cfedbe..748c0852 100644 --- a/docs/Reference/VBA/FileSystem/Input.md +++ b/docs/Reference/VBA/FileSystem/Input.md @@ -12,8 +12,8 @@ vba_attribution: true Returns a fixed number of characters read from a file opened in **Input** or **Binary** mode. Syntax: -- **Input(** *Number* **,** [ **#** ] *FileNumber* **)** — returns a **Variant**. -- **Input$(** *Number* **,** [ **#** ] *FileNumber* **)** — returns a **String**. +- **Input(** *Number* **,** [ **#** ] *FileNumber* **)** --- returns a **Variant**. +- **Input$(** *Number* **,** [ **#** ] *FileNumber* **)** --- returns a **String**. *Number* : *required* The number of characters to return. diff --git a/docs/Reference/VBA/FileSystem/InputB.md b/docs/Reference/VBA/FileSystem/InputB.md index 0502fe27..78e43841 100644 --- a/docs/Reference/VBA/FileSystem/InputB.md +++ b/docs/Reference/VBA/FileSystem/InputB.md @@ -12,8 +12,8 @@ vba_attribution: true Returns a fixed number of bytes read from a file opened in **Input** or **Binary** mode. Syntax: -- **InputB(** *Number* **,** [ **#** ] *FileNumber* **)** — returns a **Variant**. -- **InputB$(** *Number* **,** [ **#** ] *FileNumber* **)** — returns a **String** whose underlying bytes are the bytes that were read. +- **InputB(** *Number* **,** [ **#** ] *FileNumber* **)** --- returns a **Variant**. +- **InputB$(** *Number* **,** [ **#** ] *FileNumber* **)** --- returns a **String** whose underlying bytes are the bytes that were read. *Number* : *required* The number of bytes to return. @@ -21,7 +21,7 @@ Syntax: *FileNumber* : *required* The file number used to open the file with the [**Open**](../../Core/Open) statement. -**InputB** is the byte-oriented counterpart of [**Input**](Input). Where **Input** counts and returns characters (two bytes per character in twinBASIC's UTF-16 buffer), **InputB** counts and returns raw bytes — useful when reading binary data through a textually-opened channel. +**InputB** is the byte-oriented counterpart of [**Input**](Input). Where **Input** counts and returns characters (two bytes per character in twinBASIC's UTF-16 buffer), **InputB** counts and returns raw bytes --- useful when reading binary data through a textually-opened channel. The bytes are packed into the result without any character-set translation; the **String** form simply reinterprets the byte run as a UTF-16 string for storage. diff --git a/docs/Reference/VBA/FileSystem/Kill.md b/docs/Reference/VBA/FileSystem/Kill.md index ee7b317d..f206eeb7 100644 --- a/docs/Reference/VBA/FileSystem/Kill.md +++ b/docs/Reference/VBA/FileSystem/Kill.md @@ -18,7 +18,7 @@ Syntax: **Kill** *pathname* **Kill** supports the use of multiple-character (`*`) and single-character (`?`) wildcards to specify multiple files. -An error occurs if you try to use **Kill** to delete an open file. +An error occurs when **Kill** is used to delete an open file. > [!NOTE] > To delete directories, use the [**RmDir**](RmDir) statement. diff --git a/docs/Reference/VBA/FileSystem/RmDir.md b/docs/Reference/VBA/FileSystem/RmDir.md index 44f05fb3..65108272 100644 --- a/docs/Reference/VBA/FileSystem/RmDir.md +++ b/docs/Reference/VBA/FileSystem/RmDir.md @@ -16,7 +16,7 @@ Syntax: **RmDir** *path* *path* : A string expression that identifies the directory or folder to be removed. The *path* may include the drive. If no drive is specified, **RmDir** removes the directory or folder on the current drive. -An error occurs if you try to use **RmDir** on a directory or folder containing files. Use the [**Kill**](Kill) statement to delete all files before attempting to remove a directory or folder. +An error occurs when **RmDir** is used on a directory or folder containing files. Use the [**Kill**](Kill) statement to delete all files before attempting to remove a directory or folder. ### See Also diff --git a/docs/Reference/VBA/FileSystem/Seek.md b/docs/Reference/VBA/FileSystem/Seek.md index 51979a5a..3bd4a712 100644 --- a/docs/Reference/VBA/FileSystem/Seek.md +++ b/docs/Reference/VBA/FileSystem/Seek.md @@ -37,7 +37,7 @@ Syntax: **Seek** [ **#** ] *filenumber*, *position* : *required* Any valid file number. *position* -: *required* Number in the range 1–2,147,483,647 indicating where the next read/write operation should occur. +: *required* Number in the range 1--2,147,483,647 indicating where the next read/write operation should occur. Record numbers specified in [Get](../../Core/Get) and [Put](../../Core/Put) statements override file positioning performed by **Seek**. diff --git a/docs/Reference/VBA/FileSystem/SetAttr.md b/docs/Reference/VBA/FileSystem/SetAttr.md index c34be736..a3db5c17 100644 --- a/docs/Reference/VBA/FileSystem/SetAttr.md +++ b/docs/Reference/VBA/FileSystem/SetAttr.md @@ -31,7 +31,7 @@ The *attributes* settings are: | **vbSystem** | 4 | System file. | | **vbArchive** | 32 | File has changed since last backup. | -A run-time error occurs if you try to set the attributes of an open file. +A run-time error occurs when setting the attributes of an open file. ### Example diff --git a/docs/Reference/VBA/FileSystem/Width.md b/docs/Reference/VBA/FileSystem/Width.md index 1bc95c2a..a003ce15 100644 --- a/docs/Reference/VBA/FileSystem/Width.md +++ b/docs/Reference/VBA/FileSystem/Width.md @@ -18,11 +18,11 @@ Syntax: **Width #** *FileNumber* **,** *Width* : *required* The file number used to open the file. *Width* -: *required* A numeric expression in the range 0–255, inclusive, indicating how many characters appear on a line before a new line is started. If *Width* equals `0`, there is no limit to the length of a line. The default is `0`. +: *required* A numeric expression in the range 0--255, inclusive, indicating how many characters appear on a line before a new line is started. If *Width* equals `0`, there is no limit to the length of a line. The default is `0`. ### Example -This example sets the output line width to 5 — five characters are written per line before the channel wraps. +This example sets the output line width to 5 --- five characters are written per line before the channel wraps. ```tb Dim I As Long diff --git a/docs/Reference/VBA/FileSystem/index.md b/docs/Reference/VBA/FileSystem/index.md index 4879e989..5caf4829 100644 --- a/docs/Reference/VBA/FileSystem/index.md +++ b/docs/Reference/VBA/FileSystem/index.md @@ -7,11 +7,11 @@ has_toc: false # FileSystem module -The **FileSystem** module groups together the procedures and statements for working with files and directories on disk. Its members divide cleanly into two camps: *pathname-based* operations that act on something named in the filesystem (creating and deleting files and directories, querying their attributes, walking a directory listing), and *file-number-based* operations that act on a handle previously returned by the **Open** statement (reading, positioning, formatting, and tracking the channel). +The **FileSystem** module groups together the procedures and statements for working with files and directories on disk. Its members divide cleanly into two camps: *pathname-based* operations that act on something named in the filesystem (creating and deleting files and directories, querying their attributes, iterating over a directory listing), and *file-number-based* operations that act on a handle previously returned by the **Open** statement (reading, positioning, formatting, and tracking the channel). ## Navigating directories -[**ChDrive**](ChDrive) changes the current drive, [**ChDir**](ChDir) changes the current directory on a given drive, and [**CurDir**](CurDir) returns the path of the current drive — or of any other drive, if one is named. [**MkDir**](MkDir) and [**RmDir**](RmDir) create and remove directories. +[**ChDrive**](ChDrive) changes the current drive, [**ChDir**](ChDir) changes the current directory on a given drive, and [**CurDir**](CurDir) returns the path of the current drive --- or of any other drive, if one is named. [**MkDir**](MkDir) and [**RmDir**](RmDir) create and remove directories. ```tb ChDrive "D" @@ -22,7 +22,7 @@ MkDir "D:\Projects\Output" ## Inspecting files and directories -[**Dir**](Dir) is the wildcard matcher: pass it a pathname containing `*` or `?` and it returns the first matching name, then call it again with no arguments to step through subsequent matches until it returns `""`. [**FileLen**](FileLen) returns the size of a file in bytes without opening it, and [**FileDateTime**](FileDateTime) returns its last-modified timestamp. [**GetAttr**](GetAttr) and [**SetAttr**](SetAttr) read and write the [**VbFileAttribute**](../Constants/VbFileAttribute) flag bits — read-only, hidden, system, archive — and **GetAttr** also reports whether a name refers to a directory by setting the **vbDirectory** bit. +[**Dir**](Dir) is the wildcard matcher: pass it a pathname containing `*` or `?` and it returns the first matching name, then call it again with no arguments to step through subsequent matches until it returns `""`. [**FileLen**](FileLen) returns the size of a file in bytes without opening it, and [**FileDateTime**](FileDateTime) returns its last-modified timestamp. [**GetAttr**](GetAttr) and [**SetAttr**](SetAttr) read and write the [**VbFileAttribute**](../Constants/VbFileAttribute) flag bits --- read-only, hidden, system, archive --- and **GetAttr** also reports whether a name refers to a directory by setting the **vbDirectory** bit. ```tb Dim Name As String @@ -44,7 +44,7 @@ Kill "C:\Backup\*.tmp" ## Opening and tracking file numbers -The lower-level read/write statements — **Open**, **Close**, **Get**, **Put**, **Print**, **Write**, **Input**, and **Line Input** — work in terms of a *file number* in the range 1–511. [**FreeFile**](FreeFile) returns the next number that isn't currently in use, sparing the caller from picking one by hand and racing other code to it. Once a file is open, [**FileAttr**](FileAttr) reports the access mode — **Input**, **Output**, **Random**, **Append**, or **Binary** — that the file number was opened with. [**Reset**](Reset) closes every file number currently open and flushes its buffers, and is most useful as a last-ditch cleanup before exit. +The lower-level read/write statements --- **Open**, **Close**, **Get**, **Put**, **Print**, **Write**, **Input**, and **Line Input** --- work in terms of a *file number* in the range 1--511. [**FreeFile**](FreeFile) returns the next number that isn't currently in use, sparing the caller from picking one by hand and racing other code to it. Once a file is open, [**FileAttr**](FileAttr) reports the access mode --- **Input**, **Output**, **Random**, **Append**, or **Binary** --- that the file number was opened with. [**Reset**](Reset) closes every file number currently open and flushes its buffers, and is most useful as a last-ditch cleanup before exit. ```tb Dim N As Long @@ -56,7 +56,7 @@ Close #N ## Position within an open file -For an open file number, [**EOF**](EOF) returns **True** once a sequential read has run past the last record, [**LOF**](LOF) returns the file's total length in bytes, and [**Loc**](Loc) returns the current read/write position. The unit of *position* depends on the open mode — record number for **Random**, byte offset for **Binary**, and the byte position divided by 128 for sequential modes — so the per-mode tables on each function's page are the authoritative reference. [**Seek**](Seek) doubles as a function and a statement: the function returns the position of the **next** read or write (whereas **Loc** reports the position of the *last*), and the statement repositions the file pointer ahead of the next operation. +For an open file number, [**EOF**](EOF) returns **True** once a sequential read has run past the last record, [**LOF**](LOF) returns the file's total length in bytes, and [**Loc**](Loc) returns the current read/write position. The unit of *position* depends on the open mode --- record number for **Random**, byte offset for **Binary**, and the byte position divided by 128 for sequential modes --- so the per-mode tables on each function's page are the authoritative reference. [**Seek**](Seek) doubles as a function and a statement: the function returns the position of the **next** read or write (whereas **Loc** reports the position of the *last*), and the statement repositions the file pointer ahead of the next operation. ```tb Dim N As Long, Line As String @@ -70,7 +70,7 @@ Close #N ## Reading and formatting through open file numbers -[**Input**](Input) and [**Input$**](Input) return a fixed number of characters read from a file number opened with **Open**, as a **Variant** or a **String** respectively; [**InputB**](InputB) and [**InputB$**](InputB) are their byte-oriented counterparts, counting raw bytes rather than UTF-16 characters. They differ from the **Input #** statement in that they return every character they read — commas, newlines, quotation marks, leading spaces, and all — making them the right choice when the bytes on disk are not a stream of comma-delimited values. +[**Input**](Input) and [**Input$**](Input) return a fixed number of characters read from a file number opened with **Open**, as a **Variant** or a **String** respectively; [**InputB**](InputB) and [**InputB$**](InputB) are their byte-oriented counterparts, counting raw bytes rather than UTF-16 characters. They differ from the **Input #** statement in that they return every character they read --- commas, newlines, quotation marks, leading spaces, and all --- making them the right choice when the bytes on disk are not a stream of comma-delimited values. [**Width**](Width) sets the output line width on a sequential output channel: subsequent **Print #** wraps to a new line once the chosen number of characters has been written, or never wraps at all when *Width* is `0`. diff --git a/docs/Reference/VBA/Financial/DDB.md b/docs/Reference/VBA/Financial/DDB.md index 68d1347f..40d25112 100644 --- a/docs/Reference/VBA/Financial/DDB.md +++ b/docs/Reference/VBA/Financial/DDB.md @@ -7,7 +7,7 @@ vba_attribution: true # DDB {: .no_toc } -Returns a **Double** specifying the depreciation of an asset for a specific time period by using the double-declining balance method or some other method you specify. +Returns a **Double** specifying the depreciation of an asset for a specific time period by using the double-declining balance method or another specified method. Syntax: **DDB(** *cost*, *salvage*, *life*, *period* [ **,** *factor* ] **)** diff --git a/docs/Reference/VBA/Financial/FV.md b/docs/Reference/VBA/Financial/FV.md index 56b31ed3..8e4bf8df 100644 --- a/docs/Reference/VBA/Financial/FV.md +++ b/docs/Reference/VBA/Financial/FV.md @@ -12,19 +12,19 @@ Returns a **Double** specifying the future value of an annuity based on periodic Syntax: **FV(** *rate*, *nper*, *pmt* [ **,** *pv* [ **,** *type* ] ] **)** *rate* -: *required* **Double** specifying interest rate per period. For example, if you get a car loan at an annual percentage rate (APR) of 10 percent and make monthly payments, the rate per period is 0.1/12, or 0.0083. +: *required* **Double** specifying interest rate per period. For example, for a car loan at an annual percentage rate (APR) of 10 percent with monthly payments, the rate per period is 0.1/12, or 0.0083. *nper* -: *required* **Integer** specifying total number of payment periods in the annuity. For example, if you make monthly payments on a four-year car loan, your loan has a total of 4 * 12 (or 48) payment periods. +: *required* **Integer** specifying total number of payment periods in the annuity. For example, monthly payments on a four-year car loan total 4 * 12 (or 48) payment periods. *pmt* : *required* **Double** specifying payment to be made each period. Payments usually contain principal and interest that doesn't change over the life of the annuity. *pv* -: *optional* **Variant** specifying present value (or lump sum) of a series of future payments. For example, when you borrow money to buy a car, the loan amount is the present value to the lender of the monthly car payments you'll make. If omitted, 0 is assumed. +: *optional* **Variant** specifying present value (or lump sum) of a series of future payments. For example, when borrowing money to buy a car, the loan amount is the present value to the lender of the monthly car payments to be made. If omitted, 0 is assumed. *type* -: *optional* **Variant** specifying when payments are due. Use 0 if payments are due at the end of the payment period, or use 1 if payments are due at the beginning of the period. If omitted, 0 is assumed. +: *optional* **Variant** specifying when payments are due. 0 means payments are due at the end of the period; 1 means payments are due at the beginning. If omitted, 0 is assumed. An annuity is a series of fixed cash payments made over a period of time. An annuity can be a loan (such as a home mortgage) or an investment (such as a monthly savings plan). diff --git a/docs/Reference/VBA/Financial/IPmt.md b/docs/Reference/VBA/Financial/IPmt.md index abf9f8af..1fdbdd54 100644 --- a/docs/Reference/VBA/Financial/IPmt.md +++ b/docs/Reference/VBA/Financial/IPmt.md @@ -12,22 +12,22 @@ Returns a **Double** specifying the interest payment for a given period of an an Syntax: **IPmt(** *rate*, *per*, *nper*, *pv* [ **,** *fv* [ **,** *type* ] ] **)** *rate* -: *required* **Double** specifying interest rate per period. For example, if you get a car loan at an annual percentage rate (APR) of 10 percent and make monthly payments, the rate per period is 0.1/12, or 0.0083. +: *required* **Double** specifying interest rate per period. For example, for a car loan at an annual percentage rate (APR) of 10 percent with monthly payments, the rate per period is 0.1/12, or 0.0083. *per* : *required* **Double** specifying payment period in the range 1 through *nper*. *nper* -: *required* **Double** specifying total number of payment periods in the annuity. For example, if you make monthly payments on a four-year car loan, your loan has a total of 4 * 12 (or 48) payment periods. +: *required* **Double** specifying total number of payment periods in the annuity. For example, monthly payments on a four-year car loan total 4 * 12 (or 48) payment periods. *pv* -: *required* **Double** specifying present value, or value today, of a series of future payments or receipts. For example, when you borrow money to buy a car, the loan amount is the present value to the lender of the monthly car payments you'll make. +: *required* **Double** specifying present value, or value today, of a series of future payments or receipts. For example, when borrowing money to buy a car, the loan amount is the present value to the lender of the monthly car payments to be made. *fv* -: *optional* **Variant** specifying future value or cash balance you want after you've made the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, if you want to save $50,000 over 18 years for your child's education, $50,000 is the future value. If omitted, 0 is assumed. +: *optional* **Variant** specifying future value or cash balance remaining after the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, to save $50,000 over 18 years for a child's education, $50,000 is the future value. If omitted, 0 is assumed. *type* -: *optional* **Variant** specifying when payments are due. Use 0 if payments are due at the end of the payment period, or use 1 if payments are due at the beginning of the period. If omitted, 0 is assumed. +: *optional* **Variant** specifying when payments are due. 0 means payments are due at the end of the period; 1 means payments are due at the beginning. If omitted, 0 is assumed. An annuity is a series of fixed cash payments made over a period of time. An annuity can be a loan (such as a home mortgage) or an investment (such as a monthly savings plan). diff --git a/docs/Reference/VBA/Financial/IRR.md b/docs/Reference/VBA/Financial/IRR.md index 573edf86..96ec8aa7 100644 --- a/docs/Reference/VBA/Financial/IRR.md +++ b/docs/Reference/VBA/Financial/IRR.md @@ -15,11 +15,11 @@ Syntax: **IRR(** *values()* [ **,** *guess* ] **)** : *required* Array of **Double** specifying cash flow values. The array must contain at least one negative value (a payment) and one positive value (a receipt). *guess* -: *optional* **Variant** specifying value that you estimate will be returned by **IRR**. If omitted, *guess* is 0.1 (10 percent). +: *optional* **Variant** specifying an estimate of the value to be returned by **IRR**. If omitted, *guess* is 0.1 (10 percent). The internal rate of return is the interest rate received for an investment consisting of payments and receipts that occur at regular intervals. -The **IRR** function uses the order of values within the array to interpret the order of payments and receipts. Be sure to enter your payment and receipt values in the correct sequence. The cash flow for each period doesn't have to be fixed, as it is for an annuity. +The **IRR** function uses the order of values within the array to interpret the order of payments and receipts. The payment and receipt values must be in the correct sequence. The cash flow for each period doesn't have to be fixed, as it is for an annuity. **IRR** is calculated by iteration. Starting with the value of *guess*, **IRR** cycles through the calculation until the result is accurate to within 0.00001 percent. If **IRR** can't find a result after 20 tries, it fails. diff --git a/docs/Reference/VBA/Financial/MIRR.md b/docs/Reference/VBA/Financial/MIRR.md index 9438675f..b6996153 100644 --- a/docs/Reference/VBA/Financial/MIRR.md +++ b/docs/Reference/VBA/Financial/MIRR.md @@ -24,7 +24,7 @@ The modified internal rate of return is the internal rate of return when payment The *finance_rate* and *reinvest_rate* arguments are percentages expressed as decimal values. For example, 12 percent is expressed as 0.12. -The **MIRR** function uses the order of values within the array to interpret the order of payments and receipts. Be sure to enter your payment and receipt values in the correct sequence. +The **MIRR** function uses the order of values within the array to interpret the order of payments and receipts. The payment and receipt values must be in the correct sequence. ### Example diff --git a/docs/Reference/VBA/Financial/NPV.md b/docs/Reference/VBA/Financial/NPV.md index 49200584..e9e68e1b 100644 --- a/docs/Reference/VBA/Financial/NPV.md +++ b/docs/Reference/VBA/Financial/NPV.md @@ -19,11 +19,11 @@ Syntax: **NPV(** *rate*, *values()* **)** The net present value of an investment is the current value of a future series of payments and receipts. -The **NPV** function uses the order of values within the array to interpret the order of payments and receipts. Be sure to enter your payment and receipt values in the correct sequence. +The **NPV** function uses the order of values within the array to interpret the order of payments and receipts. The payment and receipt values must be in the correct sequence. The **NPV** investment begins one period before the date of the first cash flow value and ends with the last cash flow value in the array. -The net present value calculation is based on future cash flows. If your first cash flow occurs at the beginning of the first period, the first value must be added to the value returned by **NPV** and must not be included in the cash flow values of *values()*. +The net present value calculation is based on future cash flows. If the first cash flow occurs at the beginning of the first period, the first value must be added to the value returned by **NPV** and must not be included in the cash flow values of *values()*. The **NPV** function is similar to the [**PV**](PV) function (present value) except that the **PV** function allows cash flows to begin either at the end or the beginning of a period. Unlike the variable **NPV** cash flow values, **PV** cash flows must be fixed throughout the investment. diff --git a/docs/Reference/VBA/Financial/NPer.md b/docs/Reference/VBA/Financial/NPer.md index ca69cdc9..7322c38e 100644 --- a/docs/Reference/VBA/Financial/NPer.md +++ b/docs/Reference/VBA/Financial/NPer.md @@ -12,19 +12,19 @@ Returns a **Double** specifying the number of periods for an annuity based on pe Syntax: **NPer(** *rate*, *pmt*, *pv* [ **,** *fv* [ **,** *type* ] ] **)** *rate* -: *required* **Double** specifying interest rate per period. For example, if you get a car loan at an annual percentage rate (APR) of 10 percent and make monthly payments, the rate per period is 0.1/12, or 0.0083. +: *required* **Double** specifying interest rate per period. For example, for a car loan at an annual percentage rate (APR) of 10 percent with monthly payments, the rate per period is 0.1/12, or 0.0083. *pmt* : *required* **Double** specifying payment to be made each period. Payments usually contain principal and interest that doesn't change over the life of the annuity. *pv* -: *required* **Double** specifying present value, or value today, of a series of future payments or receipts. For example, when you borrow money to buy a car, the loan amount is the present value to the lender of the monthly car payments you'll make. +: *required* **Double** specifying present value, or value today, of a series of future payments or receipts. For example, when borrowing money to buy a car, the loan amount is the present value to the lender of the monthly car payments to be made. *fv* -: *optional* **Variant** specifying future value or cash balance you want after you've made the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, if you want to save $50,000 over 18 years for your child's education, $50,000 is the future value. If omitted, 0 is assumed. +: *optional* **Variant** specifying future value or cash balance remaining after the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, to save $50,000 over 18 years for a child's education, $50,000 is the future value. If omitted, 0 is assumed. *type* -: *optional* **Variant** specifying when payments are due. Use 0 if payments are due at the end of the payment period, or use 1 if payments are due at the beginning of the period. If omitted, 0 is assumed. +: *optional* **Variant** specifying when payments are due. 0 means payments are due at the end of the period; 1 means payments are due at the beginning. If omitted, 0 is assumed. An annuity is a series of fixed cash payments made over a period of time. An annuity can be a loan (such as a home mortgage) or an investment (such as a monthly savings plan). diff --git a/docs/Reference/VBA/Financial/PPmt.md b/docs/Reference/VBA/Financial/PPmt.md index e31b85ee..81b40a2a 100644 --- a/docs/Reference/VBA/Financial/PPmt.md +++ b/docs/Reference/VBA/Financial/PPmt.md @@ -12,22 +12,22 @@ Returns a **Double** specifying the principal payment for a given period of an a Syntax: **PPmt(** *rate*, *per*, *nper*, *pv* [ **,** *fv* [ **,** *type* ] ] **)** *rate* -: *required* **Double** specifying interest rate per period. For example, if you get a car loan at an annual percentage rate (APR) of 10 percent and make monthly payments, the rate per period is 0.1/12, or 0.0083. +: *required* **Double** specifying interest rate per period. For example, for a car loan at an annual percentage rate (APR) of 10 percent with monthly payments, the rate per period is 0.1/12, or 0.0083. *per* : *required* **Integer** specifying payment period in the range 1 through *nper*. *nper* -: *required* **Integer** specifying total number of payment periods in the annuity. For example, if you make monthly payments on a four-year car loan, your loan has a total of 4 * 12 (or 48) payment periods. +: *required* **Integer** specifying total number of payment periods in the annuity. For example, monthly payments on a four-year car loan total 4 * 12 (or 48) payment periods. *pv* -: *required* **Double** specifying present value, or value today, of a series of future payments or receipts. For example, when you borrow money to buy a car, the loan amount is the present value to the lender of the monthly car payments you'll make. +: *required* **Double** specifying present value, or value today, of a series of future payments or receipts. For example, when borrowing money to buy a car, the loan amount is the present value to the lender of the monthly car payments to be made. *fv* -: *optional* **Variant** specifying future value or cash balance you want after you've made the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, if you want to save $50,000 over 18 years for your child's education, $50,000 is the future value. If omitted, 0 is assumed. +: *optional* **Variant** specifying future value or cash balance remaining after the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, to save $50,000 over 18 years for a child's education, $50,000 is the future value. If omitted, 0 is assumed. *type* -: *optional* **Variant** specifying when payments are due. Use 0 if payments are due at the end of the payment period, or use 1 if payments are due at the beginning of the period. If omitted, 0 is assumed. +: *optional* **Variant** specifying when payments are due. 0 means payments are due at the end of the period; 1 means payments are due at the beginning. If omitted, 0 is assumed. An annuity is a series of fixed cash payments made over a period of time. An annuity can be a loan (such as a home mortgage) or an investment (such as a monthly savings plan). diff --git a/docs/Reference/VBA/Financial/PV.md b/docs/Reference/VBA/Financial/PV.md index 79b0dae8..4c7924f4 100644 --- a/docs/Reference/VBA/Financial/PV.md +++ b/docs/Reference/VBA/Financial/PV.md @@ -12,19 +12,19 @@ Returns a **Double** specifying the present value of an annuity based on periodi Syntax: **PV(** *rate*, *nper*, *pmt* [ **,** *fv* [ **,** *type* ] ] **)** *rate* -: *required* **Double** specifying interest rate per period. For example, if you get a car loan at an annual percentage rate (APR) of 10 percent and make monthly payments, the rate per period is 0.1/12, or 0.0083. +: *required* **Double** specifying interest rate per period. For example, for a car loan at an annual percentage rate (APR) of 10 percent with monthly payments, the rate per period is 0.1/12, or 0.0083. *nper* -: *required* **Integer** specifying total number of payment periods in the annuity. For example, if you make monthly payments on a four-year car loan, your loan has a total of 4 * 12 (or 48) payment periods. +: *required* **Integer** specifying total number of payment periods in the annuity. For example, monthly payments on a four-year car loan total 4 * 12 (or 48) payment periods. *pmt* : *required* **Double** specifying payment to be made each period. Payments usually contain principal and interest that doesn't change over the life of the annuity. *fv* -: *optional* **Variant** specifying future value or cash balance you want after you've made the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, if you want to save $50,000 over 18 years for your child's education, $50,000 is the future value. If omitted, 0 is assumed. +: *optional* **Variant** specifying future value or cash balance remaining after the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, to save $50,000 over 18 years for a child's education, $50,000 is the future value. If omitted, 0 is assumed. *type* -: *optional* **Variant** specifying when payments are due. Use 0 if payments are due at the end of the payment period, or use 1 if payments are due at the beginning of the period. If omitted, 0 is assumed. +: *optional* **Variant** specifying when payments are due. 0 means payments are due at the end of the period; 1 means payments are due at the beginning. If omitted, 0 is assumed. An annuity is a series of fixed cash payments made over a period of time. An annuity can be a loan (such as a home mortgage) or an investment (such as a monthly savings plan). diff --git a/docs/Reference/VBA/Financial/Pmt.md b/docs/Reference/VBA/Financial/Pmt.md index 8e20b503..e104b57a 100644 --- a/docs/Reference/VBA/Financial/Pmt.md +++ b/docs/Reference/VBA/Financial/Pmt.md @@ -12,19 +12,19 @@ Returns a **Double** specifying the payment for an annuity based on periodic, fi Syntax: **Pmt(** *rate*, *nper*, *pv* [ **,** *fv* [ **,** *type* ] ] **)** *rate* -: *required* **Double** specifying interest rate per period. For example, if you get a car loan at an annual percentage rate (APR) of 10 percent and make monthly payments, the rate per period is 0.1/12, or 0.0083. +: *required* **Double** specifying interest rate per period. For example, for a car loan at an annual percentage rate (APR) of 10 percent with monthly payments, the rate per period is 0.1/12, or 0.0083. *nper* -: *required* **Integer** specifying total number of payment periods in the annuity. For example, if you make monthly payments on a four-year car loan, your loan has a total of 4 * 12 (or 48) payment periods. +: *required* **Integer** specifying total number of payment periods in the annuity. For example, monthly payments on a four-year car loan total 4 * 12 (or 48) payment periods. *pv* -: *required* **Double** specifying present value (or lump sum) that a series of payments to be paid in the future is worth now. For example, when you borrow money to buy a car, the loan amount is the present value to the lender of the monthly car payments you'll make. +: *required* **Double** specifying present value (or lump sum) that a series of payments to be paid in the future is worth now. For example, when borrowing money to buy a car, the loan amount is the present value to the lender of the monthly car payments to be made. *fv* -: *optional* **Variant** specifying future value or cash balance you want after you've made the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, if you want to save $50,000 over 18 years for your child's education, $50,000 is the future value. If omitted, 0 is assumed. +: *optional* **Variant** specifying future value or cash balance remaining after the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, to save $50,000 over 18 years for a child's education, $50,000 is the future value. If omitted, 0 is assumed. *type* -: *optional* **Variant** specifying when payments are due. Use 0 if payments are due at the end of the payment period, or use 1 if payments are due at the beginning of the period. If omitted, 0 is assumed. +: *optional* **Variant** specifying when payments are due. 0 means payments are due at the end of the period; 1 means payments are due at the beginning. If omitted, 0 is assumed. An annuity is a series of fixed cash payments made over a period of time. An annuity can be a loan (such as a home mortgage) or an investment (such as a monthly savings plan). diff --git a/docs/Reference/VBA/Financial/Rate.md b/docs/Reference/VBA/Financial/Rate.md index 8ae00c67..3cb8b8b9 100644 --- a/docs/Reference/VBA/Financial/Rate.md +++ b/docs/Reference/VBA/Financial/Rate.md @@ -12,28 +12,28 @@ Returns a **Double** specifying the interest rate per period for an annuity. Syntax: **Rate(** *nper*, *pmt*, *pv* [ **,** *fv* [ **,** *type* [ **,** *guess* ] ] ] **)** *nper* -: *required* **Double** specifying total number of payment periods in the annuity. For example, if you make monthly payments on a four-year car loan, your loan has a total of 4 * 12 (or 48) payment periods. +: *required* **Double** specifying total number of payment periods in the annuity. For example, monthly payments on a four-year car loan total 4 * 12 (or 48) payment periods. *pmt* : *required* **Double** specifying payment to be made each period. Payments usually contain principal and interest that doesn't change over the life of the annuity. *pv* -: *required* **Double** specifying present value, or value today, of a series of future payments or receipts. For example, when you borrow money to buy a car, the loan amount is the present value to the lender of the monthly car payments you'll make. +: *required* **Double** specifying present value, or value today, of a series of future payments or receipts. For example, when borrowing money to buy a car, the loan amount is the present value to the lender of the monthly car payments to be made. *fv* -: *optional* **Variant** specifying future value or cash balance you want after you make the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, if you want to save $50,000 over 18 years for your child's education, $50,000 is the future value. If omitted, 0 is assumed. +: *optional* **Variant** specifying future value or cash balance remaining after the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, to save $50,000 over 18 years for a child's education, $50,000 is the future value. If omitted, 0 is assumed. *type* -: *optional* **Variant** specifying a number indicating when payments are due. Use 0 if payments are due at the end of the payment period, or use 1 if payments are due at the beginning of the period. If omitted, 0 is assumed. +: *optional* **Variant** specifying when payments are due. 0 means payments are due at the end of the period; 1 means payments are due at the beginning. If omitted, 0 is assumed. *guess* -: *optional* **Variant** specifying value you estimate will be returned by **Rate**. If omitted, *guess* is 0.1 (10 percent). +: *optional* **Variant** specifying an estimate of the value to be returned by **Rate**. If omitted, *guess* is 0.1 (10 percent). An annuity is a series of fixed cash payments made over a period of time. An annuity can be a loan (such as a home mortgage) or an investment (such as a monthly savings plan). For all arguments, cash paid out (such as deposits to savings) is represented by negative numbers; cash received (such as dividend checks) is represented by positive numbers. -**Rate** is calculated by iteration. Starting with the value of *guess*, **Rate** cycles through the calculation until the result is accurate to within 0.00001 percent. If **Rate** can't find a result after 20 tries, it fails. If your guess is 10 percent and **Rate** fails, try a different value for *guess*. +**Rate** is calculated by iteration. Starting with the value of *guess*, **Rate** cycles through the calculation until the result is accurate to within 0.00001 percent. If **Rate** can't find a result after 20 tries, it fails. If the default 10 percent fails, try a different value for *guess*. ### Example diff --git a/docs/Reference/VBA/Financial/index.md b/docs/Reference/VBA/Financial/index.md index 94e84acc..73c9e471 100644 --- a/docs/Reference/VBA/Financial/index.md +++ b/docs/Reference/VBA/Financial/index.md @@ -7,13 +7,13 @@ has_toc: false # Financial module -The **Financial** module groups together the procedures that solve standard time-value-of-money problems — annuity calculations for loans and savings plans with fixed periodic cash flows, return and present-value analysis for irregular cash flow streams, and asset depreciation under three different accounting conventions. +The **Financial** module groups together the procedures that solve standard time-value-of-money problems --- annuity calculations for loans and savings plans with fixed periodic cash flows, return and present-value analysis for irregular cash flow streams, and asset depreciation under three different accounting conventions. ## Annuities An *annuity* is a series of fixed cash payments made at equally spaced intervals. Seven of the module's functions describe the same underlying annuity model and differ only in *which* of its quantities they solve for: [**FV**](FV) returns the future value (the cash balance after the final payment), [**PV**](PV) the present value (the value today of the future cash flows), [**Pmt**](Pmt) the periodic payment amount, [**NPer**](NPer) the number of periods, and [**Rate**](Rate) the interest rate per period. [**IPmt**](IPmt) and [**PPmt**](PPmt) decompose a single payment into its interest and principal portions. -All seven take the same core arguments — *rate*, *nper*, *pmt*, *pv*, *fv*, *type* — in different orders, with the unknown one omitted. *rate* is the interest rate per period (an annual percentage divided by the number of periods per year); *nper* is the total number of payment periods; *pmt* is the payment per period; *pv* and *fv* are the present and future values; *type* is `0` if payments fall at the end of the period and `1` if at the beginning. **Rate** additionally accepts a *guess* argument — it solves its equation iteratively, and a starting estimate can be supplied when the default of 10 % fails to converge in twenty cycles. +All seven take the same core arguments --- *rate*, *nper*, *pmt*, *pv*, *fv*, *type* --- in different orders, with the unknown one omitted. *rate* is the interest rate per period (an annual percentage divided by the number of periods per year); *nper* is the total number of payment periods; *pmt* is the payment per period; *pv* and *fv* are the present and future values; *type* is `0` if payments fall at the end of the period and `1` if at the beginning. **Rate** additionally accepts a *guess* argument --- it solves its equation iteratively, and a starting estimate can be supplied when the default of 10 % fails to converge in twenty cycles. ```tb Const APR As Double = 0.06 @@ -23,7 +23,7 @@ Monthly = -Pmt(APR / 12, 30 * 12, 200000) ' fixed monthly payment on a 30-year ## Variable cash flows -For investments whose cash flows vary period to period, three functions take an array of values rather than a single payment amount. [**NPV**](NPV) returns the net present value of the cash flows discounted at a chosen rate; [**IRR**](IRR) returns the internal rate of return — the discount rate that would make **NPV** zero; and [**MIRR**](MIRR) returns the modified internal rate of return, where outflows and reinvested inflows are discounted at separate rates. The order of values within the array is significant — element *i* is the cash flow for period *i* — and the array must contain at least one negative entry (a payment) and one positive entry (a receipt). Like **Rate**, both **IRR** and **MIRR** are computed iteratively and accept an optional *guess*. +For investments whose cash flows vary period to period, three functions take an array of values rather than a single payment amount. [**NPV**](NPV) returns the net present value of the cash flows discounted at a chosen rate; [**IRR**](IRR) returns the internal rate of return --- the discount rate that would make **NPV** zero; and [**MIRR**](MIRR) returns the modified internal rate of return, where outflows and reinvested inflows are discounted at separate rates. The order of values within the array is significant --- element *i* is the cash flow for period *i* --- and the array must contain at least one negative entry (a payment) and one positive entry (a receipt). Like **Rate**, both **IRR** and **MIRR** are computed iteratively and accept an optional *guess*. ```tb Dim CashFlows(0 To 4) As Double @@ -36,13 +36,13 @@ Debug.Print NPV(0.0625, CashFlows) ' net present value at a 6.25 % discount rat ## Depreciation -Three functions return the depreciation of an asset over a chosen period under three different accounting conventions, all parameterised by the asset's initial *cost*, its *salvage* value at the end of its useful life, and its *life* in periods. [**SLN**](SLN) applies straight-line depreciation, spreading the lost value uniformly across each period. [**DDB**](DDB) applies the double-declining balance method (or a chosen multiplier), front-loading the depreciation so it is highest in the first period and decreases geometrically thereafter. [**SYD**](SYD) applies sum-of-years' digits depreciation — also accelerated, but linearly tapered. +Three functions return the depreciation of an asset over a chosen period under three different accounting conventions, all parameterised by the asset's initial *cost*, its *salvage* value at the end of its useful life, and its *life* in periods. [**SLN**](SLN) applies straight-line depreciation, spreading the lost value uniformly across each period. [**DDB**](DDB) applies the double-declining balance method (or a chosen multiplier), front-loading the depreciation so it is highest in the first period and decreases geometrically thereafter. [**SYD**](SYD) applies sum-of-years' digits depreciation --- also accelerated, but linearly tapered. **SLN** returns the same value for every period; **DDB** and **SYD** therefore both take an additional *period* argument naming which period to report. ## Sign conventions and units -Two conventions span the entire module. First, **cash flows carry a sign**: money paid *out* (mortgage payments, deposits to savings, investment outlays) is represented by a negative number, and money received (loan proceeds, savings withdrawals, dividends) by a positive number. The same convention applies whether the value appears as a single argument (*pmt*, *pv*, *fv*) or as an element of a cash flow array — entering a payment as a positive number is the most common cause of an unexpected result. +Two conventions span the entire module. First, **cash flows have a sign**: money paid *out* (mortgage payments, deposits to savings, investment outlays) is represented by a negative number, and money received (loan proceeds, savings withdrawals, dividends) by a positive number. The same convention applies whether the value appears as a single argument (*pmt*, *pv*, *fv*) or as an element of a cash flow array --- entering a payment as a positive number is the most common cause of an unexpected result. Second, **rates and counts must share a time unit**. If *nper* is given in months, *rate* must be the monthly rate (typically the annual rate divided by twelve); if *nper* is given in years, *rate* must be the annual rate. The same applies to depreciation: the *life* of the asset and the *period* being queried must be expressed in the same units. diff --git a/docs/Reference/VBA/HiddenModule/AllocMem.md b/docs/Reference/VBA/HiddenModule/AllocMem.md index 9419ddae..363e9207 100644 --- a/docs/Reference/VBA/HiddenModule/AllocMem.md +++ b/docs/Reference/VBA/HiddenModule/AllocMem.md @@ -13,7 +13,7 @@ Syntax: **AllocMem(** *BytesToAlloc* **)** **As LongPtr** *BytesToAlloc* : *required* **Long**. The size of the block to allocate, in bytes. -The contents of the new block are unspecified. Release the block with [**FreeMem**](FreeMem) when you are done with it; passing the address to anything else (e.g. a Win32 `HeapFree`) will not work, since the block is owned by the twinBASIC runtime's heap. +The contents of the new block are unspecified. Release the block with [**FreeMem**](FreeMem) when no longer needed; passing the address to anything else (e.g. a Win32 `HeapFree`) will not work, since the block is owned by the twinBASIC runtime's heap. If the allocation fails, **AllocMem** raises a run-time error. diff --git a/docs/Reference/VBA/HiddenModule/CreateGUID.md b/docs/Reference/VBA/HiddenModule/CreateGUID.md index c4a87542..9b0b0fc2 100644 --- a/docs/Reference/VBA/HiddenModule/CreateGUID.md +++ b/docs/Reference/VBA/HiddenModule/CreateGUID.md @@ -10,9 +10,9 @@ Generates a fresh GUID and returns it as a registry-formatted string. Syntax: **CreateGUID()** **As String** -The result is a fresh, unique GUID in the form `{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}` — the same format used by **InterfaceId**, **ClassId**, and the like. Each call returns a different value. +The result is a fresh, unique GUID in the form `{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}` --- the same format used by **InterfaceId**, **ClassId**, and the like. Each call returns a different value. -This is a thin wrapper over the operating system's GUID generator (`CoCreateGuid` on Windows). The resulting GUID is suitable for use as an interface or class identifier; it is not, however, a cryptographically random number — do not use it where unpredictability matters. +This is a thin wrapper over the operating system's GUID generator (`CoCreateGuid` on Windows). The resulting GUID is suitable for use as an interface or class identifier; it is not, however, a cryptographically random number --- do not use it where unpredictability matters. ### Example diff --git a/docs/Reference/VBA/HiddenModule/CreateStdPictureFromHandle.md b/docs/Reference/VBA/HiddenModule/CreateStdPictureFromHandle.md index 123786fc..3dd8ad61 100644 --- a/docs/Reference/VBA/HiddenModule/CreateStdPictureFromHandle.md +++ b/docs/Reference/VBA/HiddenModule/CreateStdPictureFromHandle.md @@ -11,7 +11,7 @@ Wraps a GDI handle in an **stdole.StdPicture** so it can be assigned to a contro Syntax: **CreateStdPictureFromHandle(** *Handle* **,** *Type* **,** *TakeOwnership* **)** **As Object** *Handle* -: *required* **LongPtr**. The GDI handle to wrap — typically an `HBITMAP`, `HICON`, `HCURSOR`, `HENHMETAFILE`, or `HMETAFILE`. +: *required* **LongPtr**. The GDI handle to wrap --- typically an `HBITMAP`, `HICON`, `HCURSOR`, `HENHMETAFILE`, or `HMETAFILE`. *Type* : *required* **Long**. The picture type. Pass one of the **PictureTypeConstants** values (`vbPicTypeBitmap`, `vbPicTypeIcon`, `vbPicTypeMetafile`, `vbPicTypeEnhMetafile`) corresponding to *Handle*'s flavour. diff --git a/docs/Reference/VBA/HiddenModule/Emit.md b/docs/Reference/VBA/HiddenModule/Emit.md index 72a330a5..48872444 100644 --- a/docs/Reference/VBA/HiddenModule/Emit.md +++ b/docs/Reference/VBA/HiddenModule/Emit.md @@ -13,7 +13,7 @@ Syntax: **Emit** *Values* ... *Values* : *required* A **ParamArray** of **Byte** values that are emitted, in order, at the location of the call. -The bytes are written into the procedure's machine code at the spot where **Emit** appears — there is no run-time call. Used together with the **Naked** procedure modifier to write inline assembly. +The bytes are written into the procedure's machine code at the spot where **Emit** appears --- there is no run-time call. Used together with the **Naked** procedure modifier to write inline assembly. ### Example diff --git a/docs/Reference/VBA/HiddenModule/EmitAny.md b/docs/Reference/VBA/HiddenModule/EmitAny.md index 526edbe6..57db43cf 100644 --- a/docs/Reference/VBA/HiddenModule/EmitAny.md +++ b/docs/Reference/VBA/HiddenModule/EmitAny.md @@ -11,9 +11,9 @@ Splices typed literal values into the codegen output of the enclosing procedure. Syntax: **EmitAny** *Values* ... *Values* -: *required* A **ParamArray** of typed literals. Each value contributes its in-memory representation — one byte for **Byte**, two for **Integer**, four for **Long** or **Single**, eight for **Currency**, **Double**, or **LongLong**, and pointer-sized for **LongPtr**. +: *required* A **ParamArray** of typed literals. Each value contributes its in-memory representation --- one byte for **Byte**, two for **Integer**, four for **Long** or **Single**, eight for **Currency**, **Double**, or **LongLong**, and pointer-sized for **LongPtr**. -The values are written into the procedure's machine code at the spot where **EmitAny** appears. Useful when an instruction's operand mixes opcodes and a multi-byte immediate — letting **EmitAny** size the immediate correctly avoids splitting it into a sequence of [**Emit**](Emit) calls. +The values are written into the procedure's machine code at the spot where **EmitAny** appears. Useful when an instruction's operand mixes opcodes and a multi-byte immediate --- letting **EmitAny** size the immediate correctly avoids splitting it into a sequence of [**Emit**](Emit) calls. ### Example diff --git a/docs/Reference/VBA/HiddenModule/Eval.md b/docs/Reference/VBA/HiddenModule/Eval.md index 6feb483a..6f3c3cc4 100644 --- a/docs/Reference/VBA/HiddenModule/Eval.md +++ b/docs/Reference/VBA/HiddenModule/Eval.md @@ -11,11 +11,11 @@ Compiles and evaluates a twinBASIC expression supplied as a string, returning th Syntax: **Eval(** *Expression* **)** **As Variant** *Expression* -: *required* **String**. A twinBASIC expression that resolves to a value — for example, `"2 + 2"`, `"Sqr(2)"`, or `"UCase(""hello"")"`. +: *required* **String**. A twinBASIC expression that resolves to a value --- for example, `"2 + 2"`, `"Sqr(2)"`, or `"UCase(""hello"")"`. A fresh [**TbExpressionService**](../TbExpressionService/) is built for every call, with the standard library binder registered so the standard runtime functions ([**Sin**](../Math/Sin), [**Sqr**](../Math/Sqr), [**Len**](../Strings/Len), [**CStr**](../Conversion/CStr), and the rest) are visible. The expression is then compiled and evaluated once, and the service is discarded. -For repeated evaluation of the same source, or for expressions that need to see your own application objects, build the service yourself and reuse a compiled [**ITbExpression**](../TbExpressionService/#itbexpression-interface). +For repeated evaluation of the same source, or for expressions that need to see application objects, construct the service explicitly and reuse a compiled [**ITbExpression**](../TbExpressionService/#itbexpression-interface). ### Example diff --git a/docs/Reference/VBA/HiddenModule/FreeMem.md b/docs/Reference/VBA/HiddenModule/FreeMem.md index 89562233..ab589391 100644 --- a/docs/Reference/VBA/HiddenModule/FreeMem.md +++ b/docs/Reference/VBA/HiddenModule/FreeMem.md @@ -13,7 +13,7 @@ Syntax: **FreeMem** *MemPointer* *MemPointer* : *required* **LongPtr**. The address returned by a previous call to [**AllocMem**](AllocMem). -The pointer is invalid after the call returns. Passing a pointer that did not come from **AllocMem** — including zero, or one that has already been freed — has undefined behaviour. +The pointer is invalid after the call returns. Passing a pointer that did not come from **AllocMem** --- including zero, or one that has already been freed --- has undefined behaviour. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/GetDeclaredMaxEnumValue.md b/docs/Reference/VBA/HiddenModule/GetDeclaredMaxEnumValue.md index 4713cc72..7c208ed8 100644 --- a/docs/Reference/VBA/HiddenModule/GetDeclaredMaxEnumValue.md +++ b/docs/Reference/VBA/HiddenModule/GetDeclaredMaxEnumValue.md @@ -13,7 +13,7 @@ Syntax: **GetDeclaredMaxEnumValue(Of** *T* **)()** **As Long** *T* : *required* The enumeration type to query. -Walks the members of *T* and returns the highest assigned value. Resolved at compile time and folded into the generated code as a numeric constant — there is no run-time iteration. +Iterates over the members of *T* and returns the highest assigned value. Resolved at compile time and folded into the generated code as a numeric constant --- there is no run-time iteration. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/GetDeclaredMinEnumValue.md b/docs/Reference/VBA/HiddenModule/GetDeclaredMinEnumValue.md index cad1f698..c4bc0d8d 100644 --- a/docs/Reference/VBA/HiddenModule/GetDeclaredMinEnumValue.md +++ b/docs/Reference/VBA/HiddenModule/GetDeclaredMinEnumValue.md @@ -13,7 +13,7 @@ Syntax: **GetDeclaredMinEnumValue(Of** *T* **)()** **As Long** *T* : *required* The enumeration type to query. -Walks the members of *T* and returns the lowest assigned value. Resolved at compile time and folded into the generated code as a numeric constant — there is no run-time iteration. +Iterates over the members of *T* and returns the lowest assigned value. Resolved at compile time and folded into the generated code as a numeric constant --- there is no run-time iteration. ### Example diff --git a/docs/Reference/VBA/HiddenModule/GetDeclaredTypeClsid.md b/docs/Reference/VBA/HiddenModule/GetDeclaredTypeClsid.md index f75683e3..fd164e13 100644 --- a/docs/Reference/VBA/HiddenModule/GetDeclaredTypeClsid.md +++ b/docs/Reference/VBA/HiddenModule/GetDeclaredTypeClsid.md @@ -13,7 +13,7 @@ Syntax: **GetDeclaredTypeClsid(Of** *T* **)()** **As String** *T* : *required* The type to query for. Typically a coclass declared with the **CoClassId** attribute or imported from a type library. -The CLSID is returned in registry format (`{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`). The lookup happens at compile time and the result is stored in the generated code as a string literal — there is no run-time call. +The CLSID is returned in registry format (`{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`). The lookup happens at compile time and the result is stored in the generated code as a string literal --- there is no run-time call. Returns an empty string if the type has no associated CLSID. diff --git a/docs/Reference/VBA/HiddenModule/GetDeclaredTypeEventIid.md b/docs/Reference/VBA/HiddenModule/GetDeclaredTypeEventIid.md index f93db4fa..4c351849 100644 --- a/docs/Reference/VBA/HiddenModule/GetDeclaredTypeEventIid.md +++ b/docs/Reference/VBA/HiddenModule/GetDeclaredTypeEventIid.md @@ -13,7 +13,7 @@ Syntax: **GetDeclaredTypeEventIid(Of** *T* **)()** **As String** *T* : *required* The type to query for. Typically a coclass that exposes events via the **EventInterfaceId** attribute or imported from a type library. -The IID is returned in registry format (`{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`). The lookup happens at compile time and the result is stored in the generated code as a string literal — there is no run-time call. +The IID is returned in registry format (`{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`). The lookup happens at compile time and the result is stored in the generated code as a string literal --- there is no run-time call. Returns an empty string if the type has no associated event interface. diff --git a/docs/Reference/VBA/HiddenModule/GetDeclaredTypeIid.md b/docs/Reference/VBA/HiddenModule/GetDeclaredTypeIid.md index 8af23590..266f9165 100644 --- a/docs/Reference/VBA/HiddenModule/GetDeclaredTypeIid.md +++ b/docs/Reference/VBA/HiddenModule/GetDeclaredTypeIid.md @@ -13,7 +13,7 @@ Syntax: **GetDeclaredTypeIid(Of** *T* **)()** **As String** *T* : *required* The type to query for. Typically an interface declared with the **InterfaceId** attribute or imported from a type library. -The IID is returned in registry format (`{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`). The lookup happens at compile time and the result is stored in the generated code as a string literal — there is no run-time call. +The IID is returned in registry format (`{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`). The lookup happens at compile time and the result is stored in the generated code as a string literal --- there is no run-time call. Useful when calling [**vbaCastObj**](vbaCastObj) or any API that takes an interface IID as a string. diff --git a/docs/Reference/VBA/HiddenModule/GetDeclaredTypeProgId.md b/docs/Reference/VBA/HiddenModule/GetDeclaredTypeProgId.md index 9ed619c3..072f9619 100644 --- a/docs/Reference/VBA/HiddenModule/GetDeclaredTypeProgId.md +++ b/docs/Reference/VBA/HiddenModule/GetDeclaredTypeProgId.md @@ -13,7 +13,7 @@ Syntax: **GetDeclaredTypeProgId(Of** *T* **)()** **As String** *T* : *required* The type to query for. Typically a coclass declared with the **CoClassId** attribute or imported from a type library. -The ProgID is the human-readable name (`Application.Object`, `Scripting.Dictionary`, ...) that matches *T*'s CLSID in the registry. The lookup happens at compile time and the result is stored in the generated code as a string literal — there is no run-time call. +The ProgID is the human-readable name (`Application.Object`, `Scripting.Dictionary`, ...) that matches *T*'s CLSID in the registry. The lookup happens at compile time and the result is stored in the generated code as a string literal --- there is no run-time call. Returns an empty string if the type has no associated ProgID. diff --git a/docs/Reference/VBA/HiddenModule/GetInheritedOwner.md b/docs/Reference/VBA/HiddenModule/GetInheritedOwner.md index 99a6953e..0a9e9fa6 100644 --- a/docs/Reference/VBA/HiddenModule/GetInheritedOwner.md +++ b/docs/Reference/VBA/HiddenModule/GetInheritedOwner.md @@ -13,5 +13,5 @@ Syntax: **GetInheritedOwner(** *Value* **)** **As Object** *Value* : *required* **Object**. The control whose inherited owner is wanted. -For controls that participate in a control-container hierarchy, the inherited owner is the topmost owning object that supplies ambient settings — typically the form. Returns **Nothing** when no inherited owner is set. +For controls that participate in a control-container hierarchy, the inherited owner is the topmost owning object that supplies ambient settings --- typically the form. Returns **Nothing** when no inherited owner is set. diff --git a/docs/Reference/VBA/HiddenModule/GetMem2.md b/docs/Reference/VBA/HiddenModule/GetMem2.md index b6d996e9..609d47b5 100644 --- a/docs/Reference/VBA/HiddenModule/GetMem2.md +++ b/docs/Reference/VBA/HiddenModule/GetMem2.md @@ -16,7 +16,7 @@ Syntax: **GetMem2** *Address* **,** *retVal* *retVal* : *required* **Integer**. The variable to receive the value read from *Address*. -The bytes are interpreted in the host's native byte order — little-endian on x86 and x64. The address is read directly with no bounds or alignment check. +The bytes are interpreted in the host's native byte order --- little-endian on x86 and x64. The address is read directly with no bounds or alignment check. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/GetMem4.md b/docs/Reference/VBA/HiddenModule/GetMem4.md index 51dcc229..e6d1daf3 100644 --- a/docs/Reference/VBA/HiddenModule/GetMem4.md +++ b/docs/Reference/VBA/HiddenModule/GetMem4.md @@ -16,7 +16,7 @@ Syntax: **GetMem4** *Address* **,** *retVal* *retVal* : *required* **Long**. The variable to receive the value read from *Address*. -The bytes are interpreted in the host's native byte order — little-endian on x86 and x64. The address is read directly with no bounds or alignment check. +The bytes are interpreted in the host's native byte order --- little-endian on x86 and x64. The address is read directly with no bounds or alignment check. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/GetMemPtr.md b/docs/Reference/VBA/HiddenModule/GetMemPtr.md index 45dafdb3..ca36bb45 100644 --- a/docs/Reference/VBA/HiddenModule/GetMemPtr.md +++ b/docs/Reference/VBA/HiddenModule/GetMemPtr.md @@ -16,7 +16,7 @@ Syntax: **GetMemPtr** *Address* **,** *retVal* *retVal* : *required* **LongPtr**. The variable to receive the pointer-sized value read from *Address*. -The number of bytes read matches the host's pointer width — four bytes in 32-bit builds, eight bytes in 64-bit builds. The bytes are interpreted in the host's native byte order. The address is read directly with no bounds or alignment check. +The number of bytes read matches the host's pointer width --- four bytes in 32-bit builds, eight bytes in 64-bit builds. The bytes are interpreted in the host's native byte order. The address is read directly with no bounds or alignment check. ### Example diff --git a/docs/Reference/VBA/HiddenModule/GetShortcutTextByEnum.md b/docs/Reference/VBA/HiddenModule/GetShortcutTextByEnum.md index ee9682b1..2aaac071 100644 --- a/docs/Reference/VBA/HiddenModule/GetShortcutTextByEnum.md +++ b/docs/Reference/VBA/HiddenModule/GetShortcutTextByEnum.md @@ -13,7 +13,7 @@ Syntax: **GetShortcutTextByEnum(** *ShortcutEnumId* **)** **As String** *ShortcutEnumId* : *required* **Long**. The numeric identifier of the shortcut, as used by the **Shortcut** property of menu and toolbar items. -The returned string is the user-facing label for the shortcut — e.g. `"Ctrl+S"`, `"Ctrl+Shift+P"`, `"F5"` — formatted in the system UI language. Returns an empty string for an unknown identifier. +The returned string is the user-facing label for the shortcut --- e.g. `"Ctrl+S"`, `"Ctrl+Shift+P"`, `"F5"` --- formatted in the system UI language. Returns an empty string for an unknown identifier. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/InterlockedCompareExchange32.md b/docs/Reference/VBA/HiddenModule/InterlockedCompareExchange32.md index 71a1ff9b..0b270de4 100644 --- a/docs/Reference/VBA/HiddenModule/InterlockedCompareExchange32.md +++ b/docs/Reference/VBA/HiddenModule/InterlockedCompareExchange32.md @@ -19,7 +19,7 @@ Syntax: **InterlockedCompareExchange32(** *Target* **,** *NewValue* **,** *OldVa *OldValueCompare* : *required* **Long**. The expected current value of *Target*. -The compare-and-swap happens as one atomic operation. The return value is the value that was in *Target* at the start of the call — equal to *OldValueCompare* on success, anything else on failure (in which case *Target* is left unchanged). Wraps the Win32 `InterlockedCompareExchange` intrinsic. +The compare-and-swap happens as one atomic operation. The return value is the value that was in *Target* at the start of the call --- equal to *OldValueCompare* on success, anything else on failure (in which case *Target* is left unchanged). Wraps the Win32 `InterlockedCompareExchange` intrinsic. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/InterlockedCompareExchange64.md b/docs/Reference/VBA/HiddenModule/InterlockedCompareExchange64.md index 841a5ac9..96b3503b 100644 --- a/docs/Reference/VBA/HiddenModule/InterlockedCompareExchange64.md +++ b/docs/Reference/VBA/HiddenModule/InterlockedCompareExchange64.md @@ -19,7 +19,7 @@ Syntax: **InterlockedCompareExchange64(** *Target* **,** *NewValue* **,** *OldVa *OldValueCompare* : *required* **LongLong**. The expected current value of *Target*. -The compare-and-swap happens as one atomic operation. The return value is the value that was in *Target* at the start of the call — equal to *OldValueCompare* on success, anything else on failure (in which case *Target* is left unchanged). Wraps the Win32 `InterlockedCompareExchange64` intrinsic. +The compare-and-swap happens as one atomic operation. The return value is the value that was in *Target* at the start of the call --- equal to *OldValueCompare* on success, anything else on failure (in which case *Target* is left unchanged). Wraps the Win32 `InterlockedCompareExchange64` intrinsic. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/InterlockedCompareExchangePointer.md b/docs/Reference/VBA/HiddenModule/InterlockedCompareExchangePointer.md index eb3e40ea..c7ff47ec 100644 --- a/docs/Reference/VBA/HiddenModule/InterlockedCompareExchangePointer.md +++ b/docs/Reference/VBA/HiddenModule/InterlockedCompareExchangePointer.md @@ -19,7 +19,7 @@ Syntax: **InterlockedCompareExchangePointer(** *Target* **,** *NewValue* **,** * *OldValueCompare* : *required* **LongPtr**. The expected current value of *Target*. -The compare-and-swap happens as one atomic operation. The return value is the value that was in *Target* at the start of the call — equal to *OldValueCompare* on success, anything else on failure (in which case *Target* is left unchanged). Wraps the Win32 `InterlockedCompareExchangePointer` intrinsic. +The compare-and-swap happens as one atomic operation. The return value is the value that was in *Target* at the start of the call --- equal to *OldValueCompare* on success, anything else on failure (in which case *Target* is left unchanged). Wraps the Win32 `InterlockedCompareExchangePointer` intrinsic. ### Example diff --git a/docs/Reference/VBA/HiddenModule/InterlockedDecrement32.md b/docs/Reference/VBA/HiddenModule/InterlockedDecrement32.md index 4dc1d0d0..863c3ecb 100644 --- a/docs/Reference/VBA/HiddenModule/InterlockedDecrement32.md +++ b/docs/Reference/VBA/HiddenModule/InterlockedDecrement32.md @@ -13,7 +13,7 @@ Syntax: **InterlockedDecrement32(** *Target* **)** **As Long** *Target* : *required* **Long**. The 32-bit variable to decrement, passed by reference. -The read, subtract, and write happen as one atomic operation. The return value is the post-decrement value of *Target* — testing against zero is the canonical way to spot the last release of a refcounted resource. Wraps the Win32 `InterlockedDecrement` intrinsic. +The read, subtract, and write happen as one atomic operation. The return value is the post-decrement value of *Target* --- testing against zero is the canonical way to spot the last release of a refcounted resource. Wraps the Win32 `InterlockedDecrement` intrinsic. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/PictureToByteArray.md b/docs/Reference/VBA/HiddenModule/PictureToByteArray.md index fe841f9c..7d9a054c 100644 --- a/docs/Reference/VBA/HiddenModule/PictureToByteArray.md +++ b/docs/Reference/VBA/HiddenModule/PictureToByteArray.md @@ -11,7 +11,7 @@ Serialises an **IPicture** into a **Byte** array. Syntax: **PictureToByteArray(** *Picture* **)** **As Variant** *Picture* -: *required* **IUnknown**. The picture to serialise — an **stdole.StdPicture**, or any object that implements **IPicture** / **IPictureDisp**. +: *required* **IUnknown**. The picture to serialise --- an **stdole.StdPicture**, or any object that implements **IPicture** / **IPictureDisp**. The result is a **Variant** wrapping a `Byte()` array containing the bytes the picture would write to a stream via **IPersistStream**. The companion deserialiser is the global **LoadPicture**, which accepts a byte array as input and returns a fresh picture. diff --git a/docs/Reference/VBA/HiddenModule/PutMem2.md b/docs/Reference/VBA/HiddenModule/PutMem2.md index 68300bf0..cb090693 100644 --- a/docs/Reference/VBA/HiddenModule/PutMem2.md +++ b/docs/Reference/VBA/HiddenModule/PutMem2.md @@ -16,7 +16,7 @@ Syntax: **PutMem2** *Address* **,** *Value* *Value* : *required* **Integer**. The 16-bit value to store at *Address*. -The bytes are written in the host's native byte order — little-endian on x86 and x64. The address is written directly with no bounds or alignment check. +The bytes are written in the host's native byte order --- little-endian on x86 and x64. The address is written directly with no bounds or alignment check. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/PutMem4.md b/docs/Reference/VBA/HiddenModule/PutMem4.md index b489281f..c9466f22 100644 --- a/docs/Reference/VBA/HiddenModule/PutMem4.md +++ b/docs/Reference/VBA/HiddenModule/PutMem4.md @@ -16,7 +16,7 @@ Syntax: **PutMem4** *Address* **,** *Value* *Value* : *required* **Long**. The 32-bit value to store at *Address*. -The bytes are written in the host's native byte order — little-endian on x86 and x64. The address is written directly with no bounds or alignment check. +The bytes are written in the host's native byte order --- little-endian on x86 and x64. The address is written directly with no bounds or alignment check. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/PutMem8.md b/docs/Reference/VBA/HiddenModule/PutMem8.md index 9b9d9fe5..0c0c600b 100644 --- a/docs/Reference/VBA/HiddenModule/PutMem8.md +++ b/docs/Reference/VBA/HiddenModule/PutMem8.md @@ -16,7 +16,7 @@ Syntax: **PutMem8** *Address* **,** *Value* *Value* : *required* **Currency**. A **Currency** carrier whose underlying eight bytes are stored at *Address*. -**Currency** is used as the eight-byte carrier — its in-memory representation is a raw 64-bit pattern, scaled by the type's fixed factor of 10000 only at the point of arithmetic. To pack an arbitrary 64-bit integer, [**LSet**](../../Core/LSet) it into a **Currency** before calling **PutMem8**. +**Currency** is used as the eight-byte carrier --- its in-memory representation is a raw 64-bit pattern, scaled by the type's fixed factor of 10000 only at the point of arithmetic. To pack an arbitrary 64-bit integer, [**LSet**](../../Core/LSet) it into a **Currency** before calling **PutMem8**. The address is written directly with no bounds or alignment check. diff --git a/docs/Reference/VBA/HiddenModule/PutMemPtr.md b/docs/Reference/VBA/HiddenModule/PutMemPtr.md index bb6295f1..775acd06 100644 --- a/docs/Reference/VBA/HiddenModule/PutMemPtr.md +++ b/docs/Reference/VBA/HiddenModule/PutMemPtr.md @@ -16,7 +16,7 @@ Syntax: **PutMemPtr** *Address* **,** *Value* *Value* : *required* **LongPtr**. The pointer-sized value to store at *Address*. -The number of bytes written matches the host's pointer width — four bytes in 32-bit builds, eight bytes in 64-bit builds. The bytes are written in the host's native byte order. The address is written directly with no bounds or alignment check. +The number of bytes written matches the host's pointer width --- four bytes in 32-bit builds, eight bytes in 64-bit builds. The bytes are written in the host's native byte order. The address is written directly with no bounds or alignment check. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/StackArgsSize.md b/docs/Reference/VBA/HiddenModule/StackArgsSize.md index 2a635e44..08c524f1 100644 --- a/docs/Reference/VBA/HiddenModule/StackArgsSize.md +++ b/docs/Reference/VBA/HiddenModule/StackArgsSize.md @@ -10,7 +10,7 @@ Returns the total size, in bytes, of the arguments passed on the stack of the en Syntax: **StackArgsSize()** **As Long** -The result is resolved at compile time and folded into the generated code as a numeric constant. Used inside a **Naked** procedure when the assembly needs to know how much to clean off the stack on return — for example, to issue the right `ret n` opcode under the `_stdcall` convention. +The result is resolved at compile time and folded into the generated code as a numeric constant. Used inside a **Naked** procedure when the assembly needs to know how much to clean off the stack on return --- for example, to issue the right `ret n` opcode under the `_stdcall` convention. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/Start.md b/docs/Reference/VBA/HiddenModule/Start.md index 18f3e6f0..530e5e3d 100644 --- a/docs/Reference/VBA/HiddenModule/Start.md +++ b/docs/Reference/VBA/HiddenModule/Start.md @@ -13,7 +13,7 @@ Syntax: *hook*.**Start** *hook* : *required* An [**IGetMessageHook**](./#igetmessagehook-interface) instance whose subscriptions have been set up with [**RegisterMessage**](RegisterMessage). -Calling **Start** on a hook that is already started has no effect. Calling it on a hook with no subscriptions is harmless but accomplishes nothing — register first, then start. +Calling **Start** on a hook that is already started has no effect. Calling it on a hook with no subscriptions is harmless but accomplishes nothing --- register first, then start. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/Stop.md b/docs/Reference/VBA/HiddenModule/Stop.md index b2c39906..f9606706 100644 --- a/docs/Reference/VBA/HiddenModule/Stop.md +++ b/docs/Reference/VBA/HiddenModule/Stop.md @@ -13,7 +13,7 @@ Syntax: *hook*.**Stop** *hook* : *required* An [**IGetMessageHook**](./#igetmessagehook-interface) instance. -Subscriptions remain registered after **Stop** — call [**Start**](Start) again to resume delivery without re-registering. Calling **Stop** on a hook that is already stopped has no effect. +Subscriptions remain registered after **Stop** --- call [**Start**](Start) again to resume delivery without re-registering. Calling **Stop** on a hook that is already stopped has no effect. > [!NOTE] > This is the **Stop** method of the [**IGetMessageHook**](./#igetmessagehook-interface) interface. The unrelated [**Stop**](../../Core/Stop) statement is a language keyword that suspends execution and breaks into the debugger. diff --git a/docs/Reference/VBA/HiddenModule/UnprotectedAccess.md b/docs/Reference/VBA/HiddenModule/UnprotectedAccess.md index 99c83ae9..d37eb637 100644 --- a/docs/Reference/VBA/HiddenModule/UnprotectedAccess.md +++ b/docs/Reference/VBA/HiddenModule/UnprotectedAccess.md @@ -13,7 +13,7 @@ Syntax: **UnprotectedAccess(** *Variable* **)** **As Object** *Variable* : *required* The value to wrap. The value passed is taken **As Any** so the call works for any type. -The returned object exposes *Variable*'s members — including **Private** and **Friend** ones — without triggering the access enforcement that the compiler ordinarily applies. Useful for testing, serialization, and other reflection-style scenarios that legitimately need to reach inside an encapsulation boundary. +The returned object exposes *Variable*'s members --- including **Private** and **Friend** ones --- without triggering the access enforcement that the compiler ordinarily applies. Useful for testing, serialization, and other reflection-style scenarios that legitimately need to reach inside an encapsulation boundary. > [!WARNING] > Use this function sparingly. Bypassing access protection makes the surrounding code coupled to the target type's private layout, which is by definition not a stable API. diff --git a/docs/Reference/VBA/HiddenModule/index.md b/docs/Reference/VBA/HiddenModule/index.md index d4c77099..cd5071eb 100644 --- a/docs/Reference/VBA/HiddenModule/index.md +++ b/docs/Reference/VBA/HiddenModule/index.md @@ -9,7 +9,7 @@ has_toc: false # (Default) module -The **(Default)** module — known internally as **\_HiddenModule** — gathers together the unqualified intrinsic procedures that the compiler emits calls into and that are also callable directly: raw-memory helpers, atomic operations, compile-time reflection, codegen and stack-inspection primitives, and a long tail of runtime utilities. Members of this module are referenced without a qualifier, the same way **MsgBox** and **CStr** are. +The **(Default)** module --- known internally as **\_HiddenModule** --- gathers together the unqualified intrinsic procedures that the compiler emits calls into and that are also callable directly: raw-memory helpers, atomic operations, compile-time reflection, codegen and stack-inspection primitives, and a long tail of runtime utilities. Members of this module are referenced without a qualifier, the same way **MsgBox** and **CStr** are. Most of these procedures are deliberately hidden from IntelliSense and exist for advanced or low-level use; use them only when the higher-level alternatives in **[Math](../Math/)**, **[Strings](../Strings/)**, **[Information](../Information/)**, or **[Interaction](../Interaction/)** don't cover the case. Several have additional internal-only members that are not listed here at all. @@ -17,7 +17,7 @@ The pointer functions [**ObjPtr**](../Information/ObjPtr), [**StrPtr**](../Infor ## Reading and writing memory -Memory at a known address is read and written one machine word at a time with the **GetMem*** / **PutMem*** family — [**GetMem1**](GetMem1), [**GetMem2**](GetMem2), [**GetMem4**](GetMem4), [**GetMem8**](GetMem8), and [**GetMemPtr**](GetMemPtr) for reads, with matching [**PutMem1**](PutMem1), [**PutMem2**](PutMem2), [**PutMem4**](PutMem4), [**PutMem8**](PutMem8), and [**PutMemPtr**](PutMemPtr). [**vbaCopyBytes**](vbaCopyBytes) and [**vbaCopyBytesZero**](vbaCopyBytesZero) move blocks; [**AllocMem**](AllocMem) and [**FreeMem**](FreeMem) manage heap allocations. The pointer constructors that feed these helpers — [**ObjPtr**](../Information/ObjPtr), [**StrPtr**](../Information/StrPtr), [**VarPtr**](../Information/VarPtr) — live in [**Information**](../Information/). +Memory at a known address is read and written one machine word at a time with the **GetMem*** / **PutMem*** family --- [**GetMem1**](GetMem1), [**GetMem2**](GetMem2), [**GetMem4**](GetMem4), [**GetMem8**](GetMem8), and [**GetMemPtr**](GetMemPtr) for reads, with matching [**PutMem1**](PutMem1), [**PutMem2**](PutMem2), [**PutMem4**](PutMem4), [**PutMem8**](PutMem8), and [**PutMemPtr**](PutMemPtr). [**vbaCopyBytes**](vbaCopyBytes) and [**vbaCopyBytesZero**](vbaCopyBytesZero) move blocks; [**AllocMem**](AllocMem) and [**FreeMem**](FreeMem) manage heap allocations. The pointer constructors that feed these helpers --- [**ObjPtr**](../Information/ObjPtr), [**StrPtr**](../Information/StrPtr), [**VarPtr**](../Information/VarPtr) --- live in [**Information**](../Information/). ```tb Dim Buffer As LongPtr = AllocMem(16) @@ -35,15 +35,15 @@ FreeMem Buffer ## Atomic operations -The **Interlocked*** family wraps the corresponding Windows kernel atomics — building blocks for lock-free counters and pointer swaps: [**InterlockedExchangePointer**](InterlockedExchangePointer), [**InterlockedCompareExchangePointer**](InterlockedCompareExchangePointer), [**InterlockedCompareExchange32**](InterlockedCompareExchange32), [**InterlockedCompareExchange64**](InterlockedCompareExchange64), [**InterlockedIncrement32**](InterlockedIncrement32), and [**InterlockedDecrement32**](InterlockedDecrement32). +The **Interlocked*** family wraps the corresponding Windows kernel atomics --- building blocks for lock-free counters and pointer swaps: [**InterlockedExchangePointer**](InterlockedExchangePointer), [**InterlockedCompareExchangePointer**](InterlockedCompareExchangePointer), [**InterlockedCompareExchange32**](InterlockedCompareExchange32), [**InterlockedCompareExchange64**](InterlockedCompareExchange64), [**InterlockedIncrement32**](InterlockedIncrement32), and [**InterlockedDecrement32**](InterlockedDecrement32). ## Compile-time reflection -A handful of intrinsics ask questions about the surrounding type without running anything; they are resolved by the compiler and burn in as constants. [**GetDeclaredTypeProgId**](GetDeclaredTypeProgId), [**GetDeclaredTypeClsid**](GetDeclaredTypeClsid), [**GetDeclaredTypeIid**](GetDeclaredTypeIid), and [**GetDeclaredTypeEventIid**](GetDeclaredTypeEventIid) report a type's COM identifiers. [**GetDeclaredMinEnumValue**](GetDeclaredMinEnumValue) and [**GetDeclaredMaxEnumValue**](GetDeclaredMaxEnumValue) return the minimum and maximum value of a declared enumeration. +A few intrinsics ask questions about the surrounding type without running anything; they are resolved by the compiler and embedded as constants. [**GetDeclaredTypeProgId**](GetDeclaredTypeProgId), [**GetDeclaredTypeClsid**](GetDeclaredTypeClsid), [**GetDeclaredTypeIid**](GetDeclaredTypeIid), and [**GetDeclaredTypeEventIid**](GetDeclaredTypeEventIid) report a type's COM identifiers. [**GetDeclaredMinEnumValue**](GetDeclaredMinEnumValue) and [**GetDeclaredMaxEnumValue**](GetDeclaredMaxEnumValue) return the minimum and maximum value of a declared enumeration. ## Codegen injection and stack inspection -[**Emit**](Emit) and [**EmitAny**](EmitAny) splice raw bytes or typed literals into the codegen output of the enclosing procedure — the vehicle for inline assembly. [**StackOffset**](StackOffset) and [**StackArgsSize**](StackArgsSize) report layout information at the current call site; [**UnprotectedAccess**](UnprotectedAccess) returns an object reference that bypasses the usual access checks on private members. +[**Emit**](Emit) and [**EmitAny**](EmitAny) splice raw bytes or typed literals into the codegen output of the enclosing procedure --- the vehicle for inline assembly. [**StackOffset**](StackOffset) and [**StackArgsSize**](StackArgsSize) report layout information at the current call site; [**UnprotectedAccess**](UnprotectedAccess) returns an object reference that bypasses the usual access checks on private members. ## Runtime expression evaluation @@ -108,7 +108,7 @@ A handful of intrinsics ask questions about the surrounding type without running ## IGetMessageHook interface -The **IGetMessageHook** interface taps into the Windows message stream for a chosen window — and optionally its descendants — and forwards messages of a chosen type to a user-supplied callback. Obtain an instance with [**RuntimeCreateGetMessageHook**](RuntimeCreateGetMessageHook); connect callbacks with [**RegisterMessage**](RegisterMessage); then call [**Start**](Start) to activate every registered subscription, and [**Stop**](Stop) to remove them. +The **IGetMessageHook** interface hooks into the Windows message stream for a chosen window --- and optionally its descendants --- and forwards messages of a chosen type to a user-supplied callback. Obtain an instance with [**RuntimeCreateGetMessageHook**](RuntimeCreateGetMessageHook); connect callbacks with [**RegisterMessage**](RegisterMessage); then call [**Start**](Start) to activate every registered subscription, and [**Stop**](Stop) to remove them. The interface inherits directly from **stdole.IUnknown** (it is not dispatch-based), and the callbacks supplied to **RegisterMessage** are typed as [**GetMessageHookHelper.GetMessageHandler**](#getmessagehandler). @@ -141,7 +141,7 @@ Selects the window scope passed to [**RegisterMessage**](RegisterMessage): | Constant | Value | Description | |------------------------------------------|-------|-------------| | **ExactWindow**{: #ExactWindow } | 1 | Hook only the specified window. | -| **AllDescendants**{: #AllDescendants } | 2 | Hook the specified window and every descendant — children, grandchildren, and so on. | +| **AllDescendants**{: #AllDescendants } | 2 | Hook the specified window and every descendant --- children, grandchildren, and so on. | | **DirectChildren**{: #DirectChildren } | 4 | Hook the specified window and its immediate children only. | ## GetMessageHookHelper module diff --git a/docs/Reference/VBA/HiddenModule/vbaAryMove.md b/docs/Reference/VBA/HiddenModule/vbaAryMove.md index 892b2ee1..08badc92 100644 --- a/docs/Reference/VBA/HiddenModule/vbaAryMove.md +++ b/docs/Reference/VBA/HiddenModule/vbaAryMove.md @@ -16,7 +16,7 @@ Syntax: **vbaAryMove** *Dest* **,** *Source* *Source* : *required* An array variable whose contents are transferred to *Dest*. After the call, *Source* is in the unallocated state. -The **SAFEARRAY** descriptor pointer is moved without copying its elements — equivalent to a swap-and-release rather than an element-wise copy. Both arrays must have compatible element types. +The **SAFEARRAY** descriptor pointer is moved without copying its elements --- equivalent to a swap-and-release rather than an element-wise copy. Both arrays must have compatible element types. This is the building block for returning a freshly built array from a function without paying for a copy on the way out. diff --git a/docs/Reference/VBA/HiddenModule/vbaCastObj.md b/docs/Reference/VBA/HiddenModule/vbaCastObj.md index c0094eac..f806dcda 100644 --- a/docs/Reference/VBA/HiddenModule/vbaCastObj.md +++ b/docs/Reference/VBA/HiddenModule/vbaCastObj.md @@ -14,7 +14,7 @@ Syntax: **vbaCastObj(** *Obj* **,** *IID* **)** **As IUnknown** : *required* **stdole.IUnknown**. The object to cast. *IID* -: *required* **Any**. The interface ID to query for — accepted as a 16-byte **GUID** structure or as a **String** in registry format (`{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`). +: *required* **Any**. The interface ID to query for --- accepted as a 16-byte **GUID** structure or as a **String** in registry format (`{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`). A direct wrapper over **IUnknown::QueryInterface**: the object is asked whether it implements the requested interface, and if so a reference to that interface is returned. If not, **Nothing** is returned. diff --git a/docs/Reference/VBA/HiddenModule/vbaCopyBytes.md b/docs/Reference/VBA/HiddenModule/vbaCopyBytes.md index 019e9926..77f6c796 100644 --- a/docs/Reference/VBA/HiddenModule/vbaCopyBytes.md +++ b/docs/Reference/VBA/HiddenModule/vbaCopyBytes.md @@ -19,7 +19,7 @@ Syntax: **vbaCopyBytes(** *Length* **,** *Dest* **,** *Src* **)** **As LongPtr** *Src* : *required* **LongPtr**. The source address. -The behaviour for overlapping ranges is unspecified — use a temporary buffer if the ranges may overlap. The return value is *Dest* (the same address that was passed in), provided as a convenience for chaining. +The behaviour for overlapping ranges is unspecified --- use a temporary buffer if the ranges may overlap. The return value is *Dest* (the same address that was passed in), provided as a convenience for chaining. ### Example diff --git a/docs/Reference/VBA/HiddenModule/vbaObjAddref.md b/docs/Reference/VBA/HiddenModule/vbaObjAddref.md index a6b5a9b2..4e74473e 100644 --- a/docs/Reference/VBA/HiddenModule/vbaObjAddref.md +++ b/docs/Reference/VBA/HiddenModule/vbaObjAddref.md @@ -11,11 +11,11 @@ Calls **IUnknown::AddRef** on the COM object at a given address. Syntax: **vbaObjAddref** *Address* *Address* -: *required* **LongPtr**. The address of an **IUnknown**-derived COM object — typically the value returned by [**ObjPtr**](ObjPtr). +: *required* **LongPtr**. The address of an **IUnknown**-derived COM object --- typically the value returned by [**ObjPtr**](ObjPtr). The reference count of the object is incremented by one. The runtime does not validate that *Address* points at a real COM object; an invalid pointer will crash the host. -This is a low-level primitive. Ordinary code does not need it — assigning to an **Object** variable already addrefs. +This is a low-level primitive. Ordinary code does not need it --- assigning to an **Object** variable already addrefs. ### See Also diff --git a/docs/Reference/VBA/HiddenModule/vbaObjSet.md b/docs/Reference/VBA/HiddenModule/vbaObjSet.md index 560d7360..5d056e5d 100644 --- a/docs/Reference/VBA/HiddenModule/vbaObjSet.md +++ b/docs/Reference/VBA/HiddenModule/vbaObjSet.md @@ -16,12 +16,12 @@ Syntax: **vbaObjSet(** *DstObject* **,** *SrcObjPtr* **)** **As LongPtr** *SrcObjPtr* : *required* **LongPtr**. The pointer to the COM object that *DstObject* should refer to. The pointer's existing reference count is **not** incremented. -This is the move-without-addref primitive — used to wrap a freshly-handed-out raw pointer (from a Win32 `IUnknown**` out-parameter, for example) into an **Object** variable without leaking a reference. +This is the move-without-addref primitive --- used to wrap a freshly-handed-out raw pointer (from a Win32 `IUnknown**` out-parameter, for example) into an **Object** variable without leaking a reference. The return value mirrors the assigned pointer. ### See Also -- [vbaObjSetAddref](vbaObjSetAddref) function — copy-with-addref counterpart +- [vbaObjSetAddref](vbaObjSetAddref) function -- copy-with-addref counterpart - [vbaObjAddref](vbaObjAddref) procedure - [ObjPtr](ObjPtr) function diff --git a/docs/Reference/VBA/HiddenModule/vbaObjSetAddref.md b/docs/Reference/VBA/HiddenModule/vbaObjSetAddref.md index 58ccd0b5..5badda60 100644 --- a/docs/Reference/VBA/HiddenModule/vbaObjSetAddref.md +++ b/docs/Reference/VBA/HiddenModule/vbaObjSetAddref.md @@ -16,12 +16,12 @@ Syntax: **vbaObjSetAddref(** *DstObject* **,** *SrcObjPtr* **)** **As LongPtr** *SrcObjPtr* : *required* **LongPtr**. The pointer to the COM object that *DstObject* should refer to. **IUnknown::AddRef** is called on the pointer. -This is the copy-with-addref primitive — equivalent to a regular `Set DstObject = obj` when *obj* is held only as a raw **LongPtr**. +This is the copy-with-addref primitive --- equivalent to a regular `Set DstObject = obj` when *obj* is held only as a raw **LongPtr**. The return value mirrors the assigned pointer. ### See Also -- [vbaObjSet](vbaObjSet) function — move-without-addref counterpart +- [vbaObjSet](vbaObjSet) function -- move-without-addref counterpart - [vbaObjAddref](vbaObjAddref) procedure - [ObjPtr](ObjPtr) function diff --git a/docs/Reference/VBA/HiddenModule/vbaRefVarAry.md b/docs/Reference/VBA/HiddenModule/vbaRefVarAry.md index 446372fe..6355febf 100644 --- a/docs/Reference/VBA/HiddenModule/vbaRefVarAry.md +++ b/docs/Reference/VBA/HiddenModule/vbaRefVarAry.md @@ -13,7 +13,7 @@ Syntax: **vbaRefVarAry(** *Variant* **)** **As LongPtr** *Variant* : *required* A **Variant** that contains an array, passed by reference. -The returned address is the location of the **SAFEARRAY*** field inside the **Variant** — that is, the dereference yields the **SAFEARRAY** pointer that the **Variant** wraps. Useful when calling Win32 APIs that expect to receive or fill a **SAFEARRAY** through a `VARIANT*` argument. +The returned address is the location of the **SAFEARRAY*** field inside the **Variant** --- that is, the dereference yields the **SAFEARRAY** pointer that the **Variant** wraps. Useful when calling Win32 APIs that expect to receive or fill a **SAFEARRAY** through a `VARIANT*` argument. If *Variant* does not contain an array, the result is undefined. diff --git a/docs/Reference/VBA/Information/Array.md b/docs/Reference/VBA/Information/Array.md index 6d683541..03bf349f 100644 --- a/docs/Reference/VBA/Information/Array.md +++ b/docs/Reference/VBA/Information/Array.md @@ -10,11 +10,11 @@ vba_attribution: true # Array {: .no_toc } -Returns a **Variant** containing an array built from a comma-separated list of values, or — when used on the left of an assignment — destructures an array on the right-hand side into the supplied variables. +Returns a **Variant** containing an array built from a comma-separated list of values, or --- when used on the left of an assignment --- destructures an array on the right-hand side into the supplied variables. Syntax: -- *result* **= Array(** [ *ArgList* ] **)** — array creation. -- **Array(** *Var1*, *Var2*, ... **) =** *RhsArray* — destructuring assignment. +- *result* **= Array(** [ *ArgList* ] **)** --- array creation. +- **Array(** *Var1*, *Var2*, ... **) =** *RhsArray* --- destructuring assignment. *ArgList* : *optional* A comma-delimited list of values that are assigned to the elements of the new array. If no arguments are supplied, an empty array is returned. diff --git a/docs/Reference/VBA/Information/Err.md b/docs/Reference/VBA/Information/Err.md index 851f2ace..6ecf8186 100644 --- a/docs/Reference/VBA/Information/Err.md +++ b/docs/Reference/VBA/Information/Err.md @@ -18,9 +18,9 @@ Syntax: *errorNumber* : A **Long** error code to assign to the **Err** object. This is shorthand for `Err.Number = errorNumber`, since [**Number**](../ErrObject/Number) is the default property of **ErrObject**. -The **Err** object is intrinsic and global — there is no need to declare or construct one. Its properties are populated when a run-time error is raised, and reset to zero or zero-length strings when the active error handler exits via **Resume**, **Resume Next**, or any **Exit** statement, or when [**Err.Clear**](../ErrObject/Clear) is called explicitly. +The **Err** object is intrinsic and global --- there is no need to declare or construct one. Its properties are populated when a run-time error is raised, and reset to zero or zero-length strings when the active error handler exits via **Resume**, **Resume Next**, or any **Exit** statement, or when [**Err.Clear**](../ErrObject/Clear) is called explicitly. -To generate a run-time error from your own code, use the [**Raise**](../ErrObject/Raise) method rather than the **Error** statement, especially for class-module and Automation errors. +To generate a run-time error from user code, use the [**Raise**](../ErrObject/Raise) method rather than the **Error** statement, especially for class-module and Automation errors. ### Example diff --git a/docs/Reference/VBA/Information/IsArrayInitialized.md b/docs/Reference/VBA/Information/IsArrayInitialized.md index 1cd86458..00a8ae41 100644 --- a/docs/Reference/VBA/Information/IsArrayInitialized.md +++ b/docs/Reference/VBA/Information/IsArrayInitialized.md @@ -13,7 +13,7 @@ Syntax: **IsArrayInitialized(** *varname* **)** *varname* : *required* The array variable to test. -A dynamic array declared with empty parentheses (`Dim a() As Long`) holds a special "uninitialized" state until **ReDim** allocates storage for it. **IsArrayInitialized** returns **False** in that state and **True** once the array has dimensions. Calling [**LBound**](LBound) or [**UBound**](UBound) on an uninitialized array, or accessing any of its elements, raises a run-time error — so **IsArrayInitialized** is the safe way to test before reading. +A dynamic array declared with empty parentheses (`Dim a() As Long`) holds a special "uninitialized" state until **ReDim** allocates storage for it. **IsArrayInitialized** returns **False** in that state and **True** once the array has dimensions. Calling [**LBound**](LBound) or [**UBound**](UBound) on an uninitialized array, or accessing any of its elements, raises a run-time error --- so **IsArrayInitialized** is the safe way to test before reading. If *varname* is not an array, **IsArrayInitialized** returns **False**. diff --git a/docs/Reference/VBA/Information/IsMissing.md b/docs/Reference/VBA/Information/IsMissing.md index 87e29b1f..214460eb 100644 --- a/docs/Reference/VBA/Information/IsMissing.md +++ b/docs/Reference/VBA/Information/IsMissing.md @@ -20,7 +20,7 @@ Syntax: **IsMissing(** *argname* **)** If **IsMissing** is used on a **ParamArray** argument, it always returns **False**. To detect an empty **ParamArray**, test whether the array's upper bound is less than its lower bound. -**IsMissing** does not work on simple data types such as **Integer** or **Double**: unlike **Variant**s, they have no provision for a "missing" flag. For typed optional arguments, specify a default value instead — if the argument is omitted, it takes that default. In many cases the default-value form removes the need for a separate **IsMissing** check entirely. +**IsMissing** does not work on simple data types such as **Integer** or **Double**: unlike **Variant**s, they have no provision for a "missing" flag. For typed optional arguments, specify a default value instead --- if the argument is omitted, it takes that default. In many cases the default-value form removes the need for a separate **IsMissing** check entirely. ```tb Sub MySub(Optional ByVal MyVar As String = "specialvalue") diff --git a/docs/Reference/VBA/Information/IsObject.md b/docs/Reference/VBA/Information/IsObject.md index b2341c6e..52f12921 100644 --- a/docs/Reference/VBA/Information/IsObject.md +++ b/docs/Reference/VBA/Information/IsObject.md @@ -16,7 +16,7 @@ Syntax: **IsObject(** *identifier* **)** *identifier* : *required* A variable name. -**IsObject** is useful only for determining whether a **Variant** holds **VarType vbObject**. This is the case if the **Variant** actually references — or once referenced — an object, or if it contains **Nothing**. +**IsObject** is useful only for determining whether a **Variant** holds **VarType vbObject**. This is the case if the **Variant** actually references --- or once referenced --- an object, or if it contains **Nothing**. **IsObject** returns **True** if *identifier* is a variable declared with **Object** type or any valid class type, or if *identifier* is a **Variant** of **VarType vbObject**, or a user-defined object; otherwise, it returns **False**. diff --git a/docs/Reference/VBA/Information/ObjPtr.md b/docs/Reference/VBA/Information/ObjPtr.md index cd55beb1..de667a33 100644 --- a/docs/Reference/VBA/Information/ObjPtr.md +++ b/docs/Reference/VBA/Information/ObjPtr.md @@ -15,9 +15,9 @@ Syntax: **ObjPtr(** *Object* **)** *Object* : *required* The object reference whose pointer is to be obtained. The argument is taken as **IUnknown**. -The returned value is the address of the object's **IUnknown** vtable — the same value the COM runtime uses to test object identity. Two **Object** variables refer to the same instance if and only if their **ObjPtr** values are equal. +The returned value is the address of the object's **IUnknown** vtable --- the same value the COM runtime uses to test object identity. Two **Object** variables refer to the same instance if and only if their **ObjPtr** values are equal. -The pointer is valid only as long as the underlying object stays alive; nothing about taking **ObjPtr** holds a reference. Pass the result to API functions that need a raw object address, or stash it for an identity check, but do not assume it remains meaningful after the last reference is released. +The pointer is valid only as long as the underlying object stays alive; nothing about taking **ObjPtr** holds a reference. Pass the result to API functions that need a raw object address, or store it for an identity check, but do not assume it remains meaningful after the last reference is released. ### Example diff --git a/docs/Reference/VBA/Information/QBColor.md b/docs/Reference/VBA/Information/QBColor.md index 32627423..23959779 100644 --- a/docs/Reference/VBA/Information/QBColor.md +++ b/docs/Reference/VBA/Information/QBColor.md @@ -14,7 +14,7 @@ Returns a **Long** representing the RGB colour code corresponding to the specifi Syntax: **QBColor(** *color* **)** *color* -: *required* A whole number in the range 0–15. +: *required* A whole number in the range 0--15. The *color* argument has these settings: @@ -29,7 +29,7 @@ The *color* argument has these settings: | 6 | Yellow | 14 | Light Yellow | | 7 | White | 15 | Bright White | -The *color* argument represents colour values used by earlier versions of Basic — Microsoft Visual Basic for MS-DOS and the QuickBASIC compiler. Starting with the least-significant byte, the returned value specifies the red, green, and blue components used to set the corresponding colour in the RGB system, exactly as if [**RGB**](RGB) had been called with those components. +The *color* argument represents colour values used by earlier versions of Basic --- Microsoft Visual Basic for MS-DOS and the QuickBASIC compiler. Starting with the least-significant byte, the returned value specifies the red, green, and blue components used to set the corresponding colour in the RGB system, exactly as if [**RGB**](RGB) had been called with those components. ### Example diff --git a/docs/Reference/VBA/Information/RGB.md b/docs/Reference/VBA/Information/RGB.md index 0043d856..0e57e692 100644 --- a/docs/Reference/VBA/Information/RGB.md +++ b/docs/Reference/VBA/Information/RGB.md @@ -14,13 +14,13 @@ Returns a **Long** representing an RGB colour value. Syntax: **RGB(** *red* **,** *green* **,** *blue* **)** *red* -: *required* A number in the range 0–255 representing the red component of the colour. +: *required* A number in the range 0--255 representing the red component of the colour. *green* -: *required* A number in the range 0–255 representing the green component of the colour. +: *required* A number in the range 0--255 representing the green component of the colour. *blue* -: *required* A number in the range 0–255 representing the blue component of the colour. +: *required* A number in the range 0--255 representing the blue component of the colour. Application methods and properties that accept a colour specification expect a number representing an RGB colour value: the relative intensity of red, green, and blue that produces a particular shade. The value of any argument that exceeds 255 is treated as 255. diff --git a/docs/Reference/VBA/Information/RGBA.md b/docs/Reference/VBA/Information/RGBA.md index d129394a..00e1acd2 100644 --- a/docs/Reference/VBA/Information/RGBA.md +++ b/docs/Reference/VBA/Information/RGBA.md @@ -11,16 +11,16 @@ Returns a **Long** representing an RGBA colour value, packing red, green, blue, Syntax: **RGBA(** *red* **,** *green* **,** *blue* **,** *alpha* **)** *red* -: *required* A number in the range 0–255 representing the red component of the colour. +: *required* A number in the range 0--255 representing the red component of the colour. *green* -: *required* A number in the range 0–255 representing the green component of the colour. +: *required* A number in the range 0--255 representing the green component of the colour. *blue* -: *required* A number in the range 0–255 representing the blue component of the colour. +: *required* A number in the range 0--255 representing the blue component of the colour. *alpha* -: *required* A number in the range 0–255 representing the alpha (opacity) component of the colour. **0** is fully transparent; **255** is fully opaque. +: *required* A number in the range 0--255 representing the alpha (opacity) component of the colour. **0** is fully transparent; **255** is fully opaque. **RGBA** extends [**RGB**](RGB) with an alpha channel for use with APIs that accept transparency. The component values can be read back with [**RGB_R**](RGB_R), [**RGB_G**](RGB_G), [**RGB_B**](RGB_B), and [**RGBA_A**](RGBA_A). diff --git a/docs/Reference/VBA/Information/RGBA_A.md b/docs/Reference/VBA/Information/RGBA_A.md index f013ba45..e2d84b5b 100644 --- a/docs/Reference/VBA/Information/RGBA_A.md +++ b/docs/Reference/VBA/Information/RGBA_A.md @@ -13,7 +13,7 @@ Syntax: **RGBA_A(** *RGBA* **)** *RGBA* : *required* A **Long** RGBA colour value, of the kind returned by [**RGBA**](RGBA). -The return value is the alpha (opacity) component in the range 0–255: **0** is fully transparent and **255** is fully opaque. +The return value is the alpha (opacity) component in the range 0--255: **0** is fully transparent and **255** is fully opaque. ### Example diff --git a/docs/Reference/VBA/Information/RGB_B.md b/docs/Reference/VBA/Information/RGB_B.md index fe07447c..6220bf72 100644 --- a/docs/Reference/VBA/Information/RGB_B.md +++ b/docs/Reference/VBA/Information/RGB_B.md @@ -13,7 +13,7 @@ Syntax: **RGB_B(** *RGBA* **)** *RGBA* : *required* A **Long** RGBA colour value, of the kind returned by [**RGB**](RGB) or [**RGBA**](RGBA). -The return value is the blue component in the range 0–255. +The return value is the blue component in the range 0--255. ### Example diff --git a/docs/Reference/VBA/Information/RGB_G.md b/docs/Reference/VBA/Information/RGB_G.md index b5b3cf3e..d09d775c 100644 --- a/docs/Reference/VBA/Information/RGB_G.md +++ b/docs/Reference/VBA/Information/RGB_G.md @@ -13,7 +13,7 @@ Syntax: **RGB_G(** *RGBA* **)** *RGBA* : *required* A **Long** RGBA colour value, of the kind returned by [**RGB**](RGB) or [**RGBA**](RGBA). -The return value is the green component in the range 0–255. +The return value is the green component in the range 0--255. ### Example diff --git a/docs/Reference/VBA/Information/RGB_R.md b/docs/Reference/VBA/Information/RGB_R.md index 08fe0d41..78e42dfc 100644 --- a/docs/Reference/VBA/Information/RGB_R.md +++ b/docs/Reference/VBA/Information/RGB_R.md @@ -13,7 +13,7 @@ Syntax: **RGB_R(** *RGBA* **)** *RGBA* : *required* A **Long** RGBA colour value, of the kind returned by [**RGB**](RGB) or [**RGBA**](RGBA). -The return value is the red component in the range 0–255. +The return value is the red component in the range 0--255. ### Example diff --git a/docs/Reference/VBA/Information/StrPtr.md b/docs/Reference/VBA/Information/StrPtr.md index 9b4925b3..7d3f86cb 100644 --- a/docs/Reference/VBA/Information/StrPtr.md +++ b/docs/Reference/VBA/Information/StrPtr.md @@ -15,7 +15,7 @@ Syntax: **StrPtr(** *String* **)** *String* : *required* The **String** whose buffer address is wanted. -twinBASIC stores a **String** as a Unicode (UTF-16) BSTR — a length-prefixed buffer that **StrPtr** returns the start of. The returned value points at the first character, not at the four-byte length prefix that precedes it. +twinBASIC stores a **String** as a Unicode (UTF-16) BSTR --- a length-prefixed buffer that **StrPtr** returns the start of. The returned value points at the first character, not at the four-byte length prefix that precedes it. If *String* is **vbNullString** the result is zero. For an empty string `""`, the result is the address of a valid (but zero-length) buffer; passing it to an API that distinguishes a null pointer from an empty string is the usual reason to prefer **vbNullString** over `""` in declarations. diff --git a/docs/Reference/VBA/Information/VarPtr.md b/docs/Reference/VBA/Information/VarPtr.md index 3257a81d..71cfadaa 100644 --- a/docs/Reference/VBA/Information/VarPtr.md +++ b/docs/Reference/VBA/Information/VarPtr.md @@ -15,9 +15,9 @@ Syntax: **VarPtr(** *Var* **)** *Var* : *required* The variable whose pointer is to be obtained. Any type is accepted. -The returned address is the storage location of *Var* itself — the same place the runtime would write to for an assignment. For a numeric or fixed-length type the value of the variable lives at that address; for a **String** or **Variant** the value at the address is the variable's BSTR pointer or **VARIANT** descriptor. +The returned address is the storage location of *Var* itself --- the same place the runtime would write to for an assignment. For a numeric or fixed-length type the value of the variable lives at that address; for a **String** or **Variant** the value at the address is the variable's BSTR pointer or **VARIANT** descriptor. -Pass the result to an API function that needs a raw address, or hand it to one of the [**GetMem*** / **PutMem***](../HiddenModule/) helpers to read or write the underlying bytes. The pointer is valid only for as long as *Var* is alive in its scope; locals, arguments, and elements of expanded arrays can move when their owning frame or array is reallocated. +Pass the result to an API function that needs a raw address, or pass it to one of the [**GetMem*** / **PutMem***](../HiddenModule/) helpers to read or write the underlying bytes. The pointer is valid only for as long as *Var* is alive in its scope; locals, arguments, and elements of expanded arrays can move when their owning frame or array is reallocated. ### Example diff --git a/docs/Reference/VBA/Information/index.md b/docs/Reference/VBA/Information/index.md index 9fb4c475..e334fca1 100644 --- a/docs/Reference/VBA/Information/index.md +++ b/docs/Reference/VBA/Information/index.md @@ -7,7 +7,7 @@ has_toc: false # Information module -The **Information** module groups together standalone procedures for asking questions about a value at run time — its subtype, whether it has been initialised, whether an optional argument was supplied — together with related utilities for querying array bounds, building **Variant** arrays, taking raw addresses, decomposing colour values, and reaching the current run-time error state. +The **Information** module groups together standalone procedures for asking questions about a value at run time --- its subtype, whether it has been initialised, whether an optional argument was supplied --- together with related utilities for querying array bounds, building **Variant** arrays, taking raw addresses, decomposing colour values, and reaching the current run-time error state. ## Inspecting a value @@ -45,7 +45,7 @@ Array(x, y, z) = a ' destructuring assignment ## Raw pointers -Three functions return raw addresses for use with API calls or unsafe interop: [**ObjPtr**](ObjPtr) for an object's COM identity, [**StrPtr**](StrPtr) for the underlying buffer of a **String**, and [**VarPtr**](VarPtr) for any variable. The result is a **LongPtr** valid only while the underlying object, string, or variable stays alive — taking a pointer never holds a reference of its own. To read or write the memory at a known address, pair these with the [**GetMem**](../HiddenModule/GetMem4) / [**PutMem**](../HiddenModule/PutMem4) family from the [(Default)](../HiddenModule/) module. +Three functions return raw addresses for use with API calls or unsafe interop: [**ObjPtr**](ObjPtr) for an object's COM identity, [**StrPtr**](StrPtr) for the underlying buffer of a **String**, and [**VarPtr**](VarPtr) for any variable. The result is a **LongPtr** valid only while the underlying object, string, or variable stays alive --- taking a pointer never holds a reference of its own. To read or write the memory at a known address, pair these with the [**GetMem**](../HiddenModule/GetMem4) / [**PutMem**](../HiddenModule/PutMem4) family from the [(Default)](../HiddenModule/) module. ```tb Dim n As Long = &H12345678 @@ -68,7 +68,7 @@ Debug.Print RGB_B(C) ' 150 ## Run-time error state -[**Err**](Err) returns the [**ErrObject**](../ErrObject) describing the run-time error currently in effect — its number, description, source, and so on. [**Erl**](Erl) returns the line number of the statement that raised the most recent error, when one was supplied as a numeric label. +[**Err**](Err) returns the [**ErrObject**](../ErrObject) describing the run-time error currently in effect --- its number, description, source, and so on. [**Erl**](Erl) returns the line number of the statement that raised the most recent error, when one was supplied as a numeric label. ## Members diff --git a/docs/Reference/VBA/Interaction/AppActivate.md b/docs/Reference/VBA/Interaction/AppActivate.md index 9f2331d0..3f759dc3 100644 --- a/docs/Reference/VBA/Interaction/AppActivate.md +++ b/docs/Reference/VBA/Interaction/AppActivate.md @@ -14,29 +14,24 @@ Activates an application window. Syntax: - **AppActivate** *title* [ **,** *wait* ] - title - : *required* A string expression specifying the title in the title bar of the application window you want to activate. + *title* + : *required* A string expression specifying the title in the title bar of the application window to activate. - wait - : *optional* A Boolean value specifying whether the calling application has the focus before activating another. If **False** (default), the specified application is immediately activated, even if the calling application does not have the focus. If **True**, the calling application waits until it has the focus, then activates the specified application. + *wait* + : *optional* A Boolean value specifying whether the calling application has the focus before activating another. If **False** (default), the specified application is immediately activated, even if the calling application does not have the focus. If **True**, the calling application waits until it has the focus, then activates the specified application. -- **AppActivate** *taskId* [ **,** *wait ] +- **AppActivate** *taskId* [ **,** *wait* ] *taskId* - : *required* The task ID returned by the [**Shell**](Shell) function can be used in place of *title* to activate an application. + : *required* The task ID returned by the [**Shell**](Shell) function can be used in place of *title* to activate an application. -The **AppActivate** statement changes the focus to the named application or window but does not affect whether it is maximized or minimized. Focus moves from the activated application window when the user takes some action to change the focus or close the window. Use the [**Shell**](Shell) function to start an application and set the window style. +The **AppActivate** statement changes the focus to the named application or window but does not affect whether it is maximized or minimized. Focus moves from the activated application window when the user takes some action to change the focus or close the window. Use the [**Shell**](Shell) function to start an application and set the window style. -In determining which application to activate, *title* is compared to the title string of each running application. If there is no exact match, any application whose title string begins with *title* is activated. If there is more than one instance of the application named by *title*, one instance is arbitrarily activated. - -### See Also - -- [SendKeys](SendKeys) statement -- [Shell](Shell) function +In determining which application to activate, *title* is compared to the title string of each running application. If there is no exact match, any application whose title string begins with *title* is activated. If there is more than one instance of the application named by *title*, one instance is arbitrarily activated. ### Example -This example illustrates various uses of the **AppActivate** statement to activate an application window. The **Shell** statements assume the applications are in the paths specified. +This example illustrates various uses of the **AppActivate** statement to activate an application window. The **Shell** statements assume the applications are in the paths specified. <!-- On the Macintosh, the default drive name is "HD" and portions of the pathname are separated by colons instead of backslashes. --> ```tb @@ -53,4 +48,9 @@ AppActivate MyAppID ' Activate Microsoft ReturnValue = Shell("c:\EXCEL\EXCEL.EXE",1) ' Run Microsoft Excel. AppActivate ReturnValue ' Activate Microsoft ' Excel. -``` \ No newline at end of file +``` + +### See Also + +- [SendKeys](SendKeys) statement +- [Shell](Shell) function \ No newline at end of file diff --git a/docs/Reference/VBA/Interaction/Beep.md b/docs/Reference/VBA/Interaction/Beep.md index 31558561..4adf3070 100644 --- a/docs/Reference/VBA/Interaction/Beep.md +++ b/docs/Reference/VBA/Interaction/Beep.md @@ -13,11 +13,11 @@ Sounds a tone through the computer's speaker. Syntax: **Beep** -The frequency and duration of the beep depend on your hardware and system software, and vary among computers. +The frequency and duration of the beep depend on the hardware and system software, and vary among computers. ### Example -This example uses the **Beep** statement to sound three consecutive tones through the computer's speaker. +This example uses the **Beep** statement to sound three consecutive tones through the computer's speaker. ```tb Dim I% diff --git a/docs/Reference/VBA/Interaction/CallByDispId.md b/docs/Reference/VBA/Interaction/CallByDispId.md index 3d449e7a..ecd982b8 100644 --- a/docs/Reference/VBA/Interaction/CallByDispId.md +++ b/docs/Reference/VBA/Interaction/CallByDispId.md @@ -6,7 +6,7 @@ permalink: /tB/Modules/Interaction/CallByDispId # CallByDispId {: .no_toc } -Calls a method, or reads or writes a property, on an object — looked up by raw IDispatch dispatch ID at run time. **CallByDispId** is a twinBASIC addition; the by-name variant, [**CallByName**](CallByName), exists in VBA as well. +Calls a method, or reads or writes a property, on an object --- looked up by raw IDispatch dispatch ID at run time. **CallByDispId** is a twinBASIC addition; the by-name variant, [**CallByName**](CallByName), exists in VBA as well. Syntax: **CallByDispId(** *object* **,** *dispid* **,** *calltype* [ **,** *args* ... ] **)** @@ -24,11 +24,11 @@ Syntax: **CallByDispId(** *object* **,** *dispid* **,** *calltype* [ **,** *args The return value is a **Variant** containing whatever the call returned. For methods that return nothing, or for property assignments, the result is **Empty**. -**CallByDispId** skips the name lookup that [**CallByName**](CallByName) performs, which is useful in two situations: when you already know the dispatch ID and want to avoid the cost of a `GetIDsOfNames` round trip, and when the target member is not exposed by name (e.g. a default member with `DISPID_VALUE = 0`, an explicit-DISPID extension, or a hidden/restricted member). +**CallByDispId** skips the name lookup that [**CallByName**](CallByName) performs, which is useful in two situations: when the dispatch ID is already known and the cost of a `GetIDsOfNames` round trip should be avoided, and when the target member is not exposed by name (e.g. a default member with `DISPID_VALUE = 0`, an explicit-DISPID extension, or a hidden/restricted member). ### Example -This example invokes the default member of an object — `DISPID_VALUE`, defined as 0 — by dispatch ID. +This example invokes the default member of an object --- `DISPID_VALUE`, defined as 0 --- by dispatch ID. ```tb Const DISPID_VALUE As Long = 0 diff --git a/docs/Reference/VBA/Interaction/CallByName.md b/docs/Reference/VBA/Interaction/CallByName.md index ddb81348..5655c9ad 100644 --- a/docs/Reference/VBA/Interaction/CallByName.md +++ b/docs/Reference/VBA/Interaction/CallByName.md @@ -9,7 +9,7 @@ vba_attribution: true # CallByName {: .no_toc } -Calls a method, or reads or writes a property, on an object — looked up by name at run time. +Calls a method, or reads or writes a property, on an object --- looked up by name at run time. Syntax: **CallByName(** *object* **,** *procname* **,** *calltype* [ **,** *args* ... ] **)** diff --git a/docs/Reference/VBA/Interaction/Choose.md b/docs/Reference/VBA/Interaction/Choose.md index 78af0b12..c0980542 100644 --- a/docs/Reference/VBA/Interaction/Choose.md +++ b/docs/Reference/VBA/Interaction/Choose.md @@ -22,7 +22,7 @@ Syntax: **Choose(** *index* **,** *choice-1* [ **,** *choice-2* **, ...** [ **,* If *index* is 1, **Choose** returns *choice-1*; if *index* is 2, it returns *choice-2*; and so on. If *index* is less than 1 or greater than the number of choices listed, **Choose** returns **Null**. Non-integer values of *index* are rounded to the nearest whole number before being evaluated. > [!NOTE] -> **Choose** evaluates *every* choice in the list, not only the one it returns. Watch for side effects: a [**MsgBox**](MsgBox) call inside any of the choices is invoked once per choice, not just for the selected one. To avoid this — for example, when one of the branches would error out — use the short-circuiting [**If**](If) function instead. +> **Choose** evaluates *every* choice in the list, not only the one it returns. Watch for side effects: a [**MsgBox**](MsgBox) call inside any of the choices is invoked once per choice, not just for the selected one. To avoid this --- for example, when one of the branches would error out --- use the short-circuiting [**If**](If) function instead. ### Example diff --git a/docs/Reference/VBA/Interaction/CreateObject.md b/docs/Reference/VBA/Interaction/CreateObject.md index 96983843..931517b8 100644 --- a/docs/Reference/VBA/Interaction/CreateObject.md +++ b/docs/Reference/VBA/Interaction/CreateObject.md @@ -14,10 +14,10 @@ Creates and returns a reference to a new instance of a COM/Automation object. Syntax: **CreateObject(** *class* [ **,** *servername* ] **)** *class* -: *required* **Variant** (**String**). The application name and class of the object to create, in the form *appname*.*objecttype* — for example, `"Excel.Application"`. A CLSID may also be supplied in the form `"new:{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"`. +: *required* **Variant** (**String**). The application name and class of the object to create, in the form *appname*.*objecttype* --- for example, `"Excel.Application"`. A CLSID may also be supplied in the form `"new:{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"`. *servername* -: *optional* **Variant** (**String**). The name of the network server on which to create the object — the same as the *Machine Name* portion of a UNC share name. For a share named `\\MyServer\Public`, *servername* is `"MyServer"`. If *servername* is omitted or supplied as a zero-length string (`""`), the object is created on the local machine. +: *optional* **Variant** (**String**). The name of the network server on which to create the object --- the same as the *Machine Name* portion of a UNC share name. For a share named `\\MyServer\Public`, *servername* is `"MyServer"`. If *servername* is omitted or supplied as a zero-length string (`""`), the object is created on the local machine. To use the returned object, assign it to an object variable. Declaring the variable `As Object` causes late binding (binding occurs at run time); declaring it with a specific class type produces early binding (binding occurs at compile time), which is faster and gives access to IntelliSense for the object's members but limits the variable to that one type. @@ -30,7 +30,7 @@ ExcelApp.Visible = True If a remote *servername* is supplied but the remote machine doesn't exist or is unreachable, a run-time error occurs. If an object has registered itself as single-instance, only one instance is ever created, no matter how many times **CreateObject** is invoked. > [!NOTE] -> Use **CreateObject** when you want a new instance of the object. To attach to an *already-running* instance — or to start the object's application with a particular file loaded — use [**GetObject**](GetObject) instead. +> **CreateObject** obtains a new instance of the object. [**GetObject**](GetObject) attaches to an *already-running* instance --- or starts the object's application with a particular file loaded. ### Example diff --git a/docs/Reference/VBA/Interaction/DeleteSetting.md b/docs/Reference/VBA/Interaction/DeleteSetting.md index 27024752..cb3b97f2 100644 --- a/docs/Reference/VBA/Interaction/DeleteSetting.md +++ b/docs/Reference/VBA/Interaction/DeleteSetting.md @@ -25,7 +25,7 @@ Syntax: **DeleteSetting** *appname*, *section*, [ *key* ] : *optional* The name of the key to delete within the specified *section*. If omitted, the entire **section** and all keys within are deleted. -A run-time error occurs if you attempt to use the **DeleteSetting** statement on a non-existent *appname*, *section* or *key*. +A run-time error occurs when **DeleteSetting** is called for a non-existent *appname*, *section*, or *key*. The root of these registry settings is: `Computer\HKEY_CURRENT_USER\Software\VB and VBA Program Settings`. diff --git a/docs/Reference/VBA/Interaction/DoEvents.md b/docs/Reference/VBA/Interaction/DoEvents.md index 5acc634b..160f6aee 100644 --- a/docs/Reference/VBA/Interaction/DoEvents.md +++ b/docs/Reference/VBA/Interaction/DoEvents.md @@ -19,8 +19,8 @@ Returns an **Integer** indicating the number of open forms in the application; r **DoEvents** is most useful for simple things like keeping a UI responsive during a tight loop, or letting the user cancel a long-running operation. For genuinely long-running work, prefer a timer or a background worker (e.g. an out-of-process ActiveX EXE) so the operating system handles the multitasking. -> [!NOTE] -> Whenever you yield the processor inside an event procedure, make sure that procedure cannot be re-entered from a different code path before the original call returns; otherwise the program may behave unpredictably. Likewise, avoid **DoEvents** when other applications might interact with your procedure in unforeseen ways during the time you have yielded control. +> [!IMPORTANT] +> Whenever the processor is yielded inside an event procedure, that procedure must not be re-entered from a different code path before the original call returns; otherwise the program may behave unpredictably. Likewise, avoid **DoEvents** when other applications might interact with the procedure in unforeseen ways during the time control is yielded. ### Example diff --git a/docs/Reference/VBA/Interaction/Environ.md b/docs/Reference/VBA/Interaction/Environ.md index 3036a785..bb636d1f 100644 --- a/docs/Reference/VBA/Interaction/Environ.md +++ b/docs/Reference/VBA/Interaction/Environ.md @@ -24,13 +24,13 @@ Syntax: The `$`-suffixed forms return a **String**; the unsuffixed forms return a **Variant** (**String**). -When called with *envstring*, **Environ** returns the value assigned to that environment variable — that is, the text following the equal sign (`=`) in the environment-string table for that variable. If *envstring* can't be found in the table, a zero-length string (`""`) is returned. +When called with *envstring*, **Environ** returns the value assigned to that environment variable --- that is, the text following the equal sign (`=`) in the environment-string table for that variable. If *envstring* can't be found in the table, a zero-length string (`""`) is returned. When called with *number*, **Environ** returns the entire entry at that position, including the variable name, the equal sign, and the value (e.g. `"PATH=C:\Windows;C:\Windows\System32"`). If there is no entry at that position, a zero-length string is returned. ### Example -This example walks the environment-string table to find the entry number and the value length for `PATH`. +This example iterates over the environment-string table to find the entry number and the value length for `PATH`. ```tb Dim EnvString As String, Indx As Long, PathLen As Long diff --git a/docs/Reference/VBA/Interaction/GetObject.md b/docs/Reference/VBA/Interaction/GetObject.md index e0810a79..b80f00ce 100644 --- a/docs/Reference/VBA/Interaction/GetObject.md +++ b/docs/Reference/VBA/Interaction/GetObject.md @@ -9,7 +9,7 @@ vba_attribution: true # GetObject {: .no_toc } -Returns a reference to a COM/Automation object — either an already-running instance, or one bound to a file. +Returns a reference to a COM/Automation object --- either an already-running instance, or one bound to a file. Syntax: **GetObject(** [ *pathname* ] [ **,** *class* ] **)** @@ -17,7 +17,7 @@ Syntax: **GetObject(** [ *pathname* ] [ **,** *class* ] **)** : *optional* **Variant** (**String**). The full path and name of a file containing the object to retrieve. If *pathname* is omitted, *class* is required. *class* -: *optional* **Variant** (**String**). The class of the object to retrieve, in the form *appname*.*objecttype* — for example, `"Excel.Application"`. +: *optional* **Variant** (**String**). The class of the object to retrieve, in the form *appname*.*objecttype* --- for example, `"Excel.Application"`. To assign the returned reference to a variable, use **Set**: @@ -30,13 +30,13 @@ When the call is made with a *pathname*, the application registered for that fil If *pathname* is a zero-length string (`""`), **GetObject** returns a *new* instance of the type named by *class*. If *pathname* is omitted altogether, **GetObject** attempts to attach to a *currently running* instance of the type named by *class*; if no such instance exists, a run-time error occurs. -Some applications support activating a *part* of a file. Append `!` and an application-specific identifier to the file name — for example, the third layer of a CAD drawing: +Some applications support activating a *part* of a file. Append `!` and an application-specific identifier to the file name --- for example, the third layer of a CAD drawing: ```tb Set LayerObject = GetObject("C:\CAD\SCHEMA.CAD!Layer3") ``` -If you don't specify *class*, the operating system determines the application to start and the object to activate based on the file name you provide. Some files, however, may support more than one class of object. To be specific, supply both arguments: +When *class* is not specified, the operating system determines the application to start and the object to activate based on the supplied file name. Some files, however, may support more than one class of object. To be specific, supply both arguments: ```tb Dim MyObject As Object @@ -44,7 +44,7 @@ Set MyObject = GetObject("C:\Drawings\Sample.drw", "Figment.Drawing") ``` > [!NOTE] -> Use **GetObject** when there is already a current instance of the object, or when you want to create the object with a file already loaded. If there is no current instance and you don't want the object started with a file loaded, use [**CreateObject**](CreateObject) instead. +> **GetObject** attaches to a current instance of the object, or creates the object with a file already loaded. When there is no current instance and the object should not be started with a file loaded, [**CreateObject**](CreateObject) creates a new instance. For an object registered as single-instance, **GetObject** with the zero-length-string syntax always returns the same instance, and the form with *pathname* omitted causes an error. diff --git a/docs/Reference/VBA/Interaction/GetSetting.md b/docs/Reference/VBA/Interaction/GetSetting.md index 48f025bd..548277c7 100644 --- a/docs/Reference/VBA/Interaction/GetSetting.md +++ b/docs/Reference/VBA/Interaction/GetSetting.md @@ -20,7 +20,7 @@ Syntax: **GetSetting(** *appname* **,** *section* **,** *key* [ **,** *default* *section* -: String expression containing the name of the ection where the key setting is found. +: String expression containing the name of the section where the key setting is found. *key* diff --git a/docs/Reference/VBA/Interaction/IIf.md b/docs/Reference/VBA/Interaction/IIf.md index b5ce85b4..65f737a3 100644 --- a/docs/Reference/VBA/Interaction/IIf.md +++ b/docs/Reference/VBA/Interaction/IIf.md @@ -22,8 +22,8 @@ Syntax: **IIf(** *expr* **,** *truepart* **,** *falsepart* **)** *falsepart* : *required* Value or expression returned if *expr* is **False**. -> [!NOTE] -> **IIf** always evaluates both *truepart* and *falsepart*, even though it returns only one of them. Watch for side effects: if the unused branch would raise an error (for example, division by zero), the error still occurs. Use the short-circuiting [**If**](If) function — a twinBASIC addition — when you need to guard against errors in the unused branch. +> [!IMPORTANT] +> **IIf** always evaluates both *truepart* and *falsepart*, even though it returns only one of them. Watch for side effects: if the unused branch would raise an error (for example, division by zero), the error still occurs. Use the short-circuiting [**If**](If) function --- a twinBASIC addition --- to guard against errors in the unused branch. ### Example diff --git a/docs/Reference/VBA/Interaction/If.md b/docs/Reference/VBA/Interaction/If.md index a6bdc937..7c67925e 100644 --- a/docs/Reference/VBA/Interaction/If.md +++ b/docs/Reference/VBA/Interaction/If.md @@ -25,12 +25,12 @@ Syntax: : *required* Value or expression returned when *expression* is **False**, or when *expressiontruepart* is **Null**, **Empty**, or **Nothing**. Evaluated only when actually needed. *expressiontruepart* -: *required* (in the two-argument form) Expression that serves as both the test and the value to return when it is "set". The function returns *expressiontruepart* unless it is **Null**, **Empty**, or a **Nothing** object reference, in which case it returns *falsepart*. Useful for null-coalescing — for example, `If(MaybeNothing, FallbackValue)`. +: *required* (in the two-argument form) Expression that serves as both the test and the value to return when it is "set". The function returns *expressiontruepart* unless it is **Null**, **Empty**, or a **Nothing** object reference, in which case it returns *falsepart*. Useful for null-coalescing --- for example, `If(MaybeNothing, FallbackValue)`. The three-argument form is the inline conditional: it returns *truepart* when *expression* is **True**, *falsepart* otherwise, and only the chosen branch is evaluated. This makes expressions such as `If(Divisor <> 0, 100 / Divisor, "n/a")` safe even when *Divisor* is zero. > [!NOTE] -> **If** uses special internal bindings in the compiler and may not behave exactly like a regular function — in particular, `Application.Run "If", ...` and other reflective callers will not invoke it. +> **If** uses special internal bindings in the compiler and may not behave exactly like a regular function --- in particular, `Application.Run "If", ...` and other reflective callers will not invoke it. ### Example diff --git a/docs/Reference/VBA/Interaction/MsgBox.md b/docs/Reference/VBA/Interaction/MsgBox.md index dec04918..a38abaae 100644 --- a/docs/Reference/VBA/Interaction/MsgBox.md +++ b/docs/Reference/VBA/Interaction/MsgBox.md @@ -35,7 +35,7 @@ The return value is one of the constants from the [**VbMsgBoxResult**](../Consta If the dialog box displays a **Cancel** button, pressing the ESC key has the same effect as clicking **Cancel**. When both *helpfile* and *context* are supplied, the user can press F1 to view the relevant Help topic; if the dialog also contains a **Help** button, clicking it invokes context-sensitive Help. The dialog stays open and **MsgBox** does not return until one of the non-Help buttons is clicked. > [!NOTE] -> To pass any argument by name (other than the first), use **MsgBox** in an expression context — for example, assign its result to a variable. To skip a positional argument, include the corresponding comma delimiter. +> To pass any argument by name (other than the first), use **MsgBox** in an expression context --- for example, assign its result to a variable. To skip a positional argument, include the corresponding comma delimiter. ### Example diff --git a/docs/Reference/VBA/Interaction/Partition.md b/docs/Reference/VBA/Interaction/Partition.md index 3e3565e7..ec8544bf 100644 --- a/docs/Reference/VBA/Interaction/Partition.md +++ b/docs/Reference/VBA/Interaction/Partition.md @@ -25,7 +25,7 @@ Syntax: **Partition(** *number* **,** *start* **,** *stop* **,** *interval* **)* *interval* : *required* The width of each individual range. May not be less than 1. -The return value identifies the particular range in which *number* falls, formatted as `"<lowervalue>: <uppervalue>"`. **Partition** is most useful in queries — for example, an SQL `SELECT` that groups orders by freight-cost band. +The return value identifies the particular range in which *number* falls, formatted as `"<lowervalue>: <uppervalue>"`. **Partition** is most useful in queries --- for example, an SQL `SELECT` that groups orders by freight-cost band. The following table shows how the ranges are determined for three sample sets of *start*, *stop*, and *interval*. The *Before First* column is what **Partition** returns for a *number* below *start*; the *After Last* column is what it returns for a *number* above *stop*. diff --git a/docs/Reference/VBA/Interaction/RaiseEventByName.md b/docs/Reference/VBA/Interaction/RaiseEventByName.md index 5cc3d864..2849e903 100644 --- a/docs/Reference/VBA/Interaction/RaiseEventByName.md +++ b/docs/Reference/VBA/Interaction/RaiseEventByName.md @@ -19,10 +19,10 @@ Syntax: **RaiseEventByName(** *object* **,** *procname* [ **,** *argsarray* ] ** *argsarray* : *optional* **Variant**. A one-dimensional array containing the arguments to pass to the event handler(s), in declaration order. Pass an uninitialized **Variant** for an event that takes no parameters. -Returns a **Variant**. The returned value is the value left in the last `ByRef` event argument by the handler — useful only when the event has a `ByRef` "out" or "cancel" parameter. +Returns a **Variant**. The returned value is the value left in the last `ByRef` event argument by the handler --- useful only when the event has a `ByRef` "out" or "cancel" parameter. > [!NOTE] -> The variable-length-argument variant of this function — [**RaiseEventByName2**](RaiseEventByName2) — accepts arguments directly via **ParamArray**, which is usually more readable when the event signature is fixed. Use **RaiseEventByName** when the argument list is itself constructed dynamically. +> The variable-length-argument variant of this function --- [**RaiseEventByName2**](RaiseEventByName2) --- accepts arguments directly via **ParamArray**, which is usually more readable when the event signature is fixed. Use **RaiseEventByName** when the argument list is itself constructed dynamically. If *procname* doesn't match any event declared on *object*, or the supplied arity doesn't match the event declaration, a run-time error occurs. diff --git a/docs/Reference/VBA/Interaction/RaiseEventByName2.md b/docs/Reference/VBA/Interaction/RaiseEventByName2.md index 09ec9b1d..22b5fece 100644 --- a/docs/Reference/VBA/Interaction/RaiseEventByName2.md +++ b/docs/Reference/VBA/Interaction/RaiseEventByName2.md @@ -19,10 +19,10 @@ Syntax: **RaiseEventByName2(** *object* **,** *procname* [ **,** *arg1* **,** *a *arg1*, *arg2*, ... : *optional* **ParamArray** of **Variant**. The arguments to pass to the event handler(s), in declaration order. -Returns a **Variant**. The returned value is the value left in the last `ByRef` event argument by the handler — useful only when the event has a `ByRef` "out" or "cancel" parameter. +Returns a **Variant**. The returned value is the value left in the last `ByRef` event argument by the handler --- useful only when the event has a `ByRef` "out" or "cancel" parameter. > [!NOTE] -> The array-based variant of this function — [**RaiseEventByName**](RaiseEventByName) — takes the argument list as a single packed **Variant** array, which is more convenient when the argument list is itself constructed dynamically. Use **RaiseEventByName2** when the argument list is fixed at the call site. +> The array-based variant of this function --- [**RaiseEventByName**](RaiseEventByName) --- takes the argument list as a single packed **Variant** array, which is more convenient when the argument list is itself constructed dynamically. Use **RaiseEventByName2** when the argument list is fixed at the call site. If *procname* doesn't match any event declared on *object*, or the supplied arity doesn't match the event declaration, a run-time error occurs. diff --git a/docs/Reference/VBA/Interaction/SendKeys.md b/docs/Reference/VBA/Interaction/SendKeys.md index 813508b7..88705140 100644 --- a/docs/Reference/VBA/Interaction/SendKeys.md +++ b/docs/Reference/VBA/Interaction/SendKeys.md @@ -19,9 +19,9 @@ Syntax: **SendKeys** *string* [ **,** *wait* ] *wait* : *optional* **Boolean** specifying the wait mode. If **False** (default), control is returned to the procedure as soon as the keys have been queued. If **True**, the keystrokes must be processed by the receiving window before control returns. -Each key is represented by one or more characters. To specify a single keyboard character, use the character itself — for example, `"A"` for the letter A, or `"ABC"` for A, B, then C in sequence. +Each key is represented by one or more characters. To specify a single keyboard character, use the character itself --- for example, `"A"` for the letter A, or `"ABC"` for A, B, then C in sequence. -The plus sign (`+`), caret (`^`), percent sign (`%`), tilde (`~`), and parentheses `( )` have special meanings to **SendKeys**. To send one of these characters as itself, enclose it in braces: for example, `"{+}"` for the plus sign. Brackets `[ ]` have no special meaning to **SendKeys** itself, but you must enclose them in braces because other applications may treat them specially during dynamic data exchange (DDE). To send brace characters, use `{% raw %}"{{}"{% endraw %}` and `"{% raw %}{}}{% endraw %}"`. +The plus sign (`+`), caret (`^`), percent sign (`%`), tilde (`~`), and parentheses `( )` have special meanings to **SendKeys**. To send one of these characters as itself, enclose it in braces: for example, `"{+}"` for the plus sign. Brackets `[ ]` have no special meaning to **SendKeys** itself, but they must be enclosed in braces because other applications may treat them specially during dynamic data exchange (DDE). To send brace characters, use `{% raw %}"{{}"{% endraw %}` and `"{% raw %}{}}{% endraw %}"`. To send keys that don't correspond to a printable character, use the codes in the following table: @@ -47,7 +47,7 @@ To send keys that don't correspond to a printable character, use the codes in th | SCROLL LOCK | `{SCROLLLOCK}` | | TAB | `{TAB}` | | UP ARROW | `{UP}` | -| F1–F16 | `{F1}` … `{F16}` | +| F1--F16 | `{F1}` … `{F16}` | To combine a key with SHIFT, CTRL, or ALT, prefix the key code with one or more of the following modifier codes: @@ -59,7 +59,7 @@ To combine a key with SHIFT, CTRL, or ALT, prefix the key code with one or more To hold one or more modifiers down while a sequence of keys is pressed, enclose the keys in parentheses. For example, `"+(EC)"` holds SHIFT down while E and C are pressed. -To repeat a key, use the form `{key number}` — for example, `"{LEFT 42}"` to press LEFT 42 times, or `"{h 10}"` to type `h` ten times. The space between *key* and *number* is required. +To repeat a key, use the form `{key number}` --- for example, `"{LEFT 42}"` to press LEFT 42 times, or `"{h 10}"` to type `h` ten times. The space between *key* and *number* is required. > [!NOTE] > **SendKeys** can't send keystrokes to applications that aren't running in Windows, and it cannot send the PRINT SCREEN key (`{PRTSC}`) to any application. diff --git a/docs/Reference/VBA/Interaction/Shell.md b/docs/Reference/VBA/Interaction/Shell.md index e29c4bc5..5aa558ea 100644 --- a/docs/Reference/VBA/Interaction/Shell.md +++ b/docs/Reference/VBA/Interaction/Shell.md @@ -19,10 +19,10 @@ Syntax: **Shell(** *pathname* [ **,** *windowstyle* ] **)** *windowstyle* : *optional* A [**VbAppWinStyle**](../Constants/VbAppWinStyle) value specifying the style of window in which the program is run. If omitted, the program is started minimized with focus (`vbMinimizedFocus`). -If **Shell** successfully launches the named program, it returns the new process's task ID — a unique number identifying the running program. If **Shell** can't start the named program, a run-time error is raised. +If **Shell** successfully launches the named program, it returns the new process's task ID --- a unique number identifying the running program. If **Shell** can't start the named program, a run-time error is raised. > [!NOTE] -> By default, **Shell** runs other programs *asynchronously*: a program started with **Shell** may not have finished — or even fully started — by the time the statements following **Shell** are executed. To wait for the program to finish, hold on to the returned task ID and poll the process by way of the Win32 `OpenProcess`/`WaitForSingleObject` APIs (or use a higher-level helper). +> By default, **Shell** runs other programs *asynchronously*: a program started with **Shell** may not have finished --- or even fully started --- by the time the statements following **Shell** are executed. To wait for the program to finish, retain the returned task ID and poll the process via the Win32 `OpenProcess`/`WaitForSingleObject` APIs (or use a higher-level helper). ### Example diff --git a/docs/Reference/VBA/Interaction/index.md b/docs/Reference/VBA/Interaction/index.md index f6b917d8..f2fbc536 100644 --- a/docs/Reference/VBA/Interaction/index.md +++ b/docs/Reference/VBA/Interaction/index.md @@ -7,11 +7,11 @@ has_toc: false # Interaction module -The **Interaction** module groups together standalone procedures for everything that happens at the edges of a program — talking to the user, branching on a value, launching another process, reading the environment or the registry, and creating, calling into, or raising events on COM objects. +The **Interaction** module groups together standalone procedures for everything that happens at the edges of a program --- talking to the user, branching on a value, launching another process, reading the environment or the registry, and creating, calling into, or raising events on COM objects. ## Asking the user something -[**MsgBox**](MsgBox) shows a modal dialog with a message, an icon, and a chosen set of buttons; it returns a [**VbMsgBoxResult**](../Constants/VbMsgBoxResult) value identifying the button that was clicked. [**InputBox**](InputBox) shows a similar dialog with a text-entry field and returns the string the user typed (or an empty string if the user cancels). [**Beep**](Beep) sounds the system alert tone — useful as an audible cue when a long-running operation finishes. +[**MsgBox**](MsgBox) shows a modal dialog with a message, an icon, and a chosen set of buttons; it returns a [**VbMsgBoxResult**](../Constants/VbMsgBoxResult) value identifying the button that was clicked. [**InputBox**](InputBox) shows a similar dialog with a text-entry field and returns the string the user typed (or an empty string if the user cancels). [**Beep**](Beep) sounds the system alert tone --- useful as an audible cue when a long-running operation finishes. ```tb Dim Answer As VbMsgBoxResult @@ -22,10 +22,10 @@ Answer = MsgBox("Save changes before closing?", vbYesNoCancel + vbQuestion, "Con The module offers four ways to pick one of several values inline: -- [**If**](If) is the short-circuiting inline conditional — a twinBASIC addition. Only the branch matching the condition is evaluated, so `If(Divisor <> 0, 100 / Divisor, "n/a")` is safe even when *Divisor* is zero. +- [**If**](If) is the short-circuiting inline conditional -- a twinBASIC addition. Only the branch matching the condition is evaluated, so `If(Divisor <> 0, 100 / Divisor, "n/a")` is safe even when *Divisor* is zero. - [**IIf**](IIf) is the historical VBA inline conditional. Both *truepart* and *falsepart* are always evaluated, so it cannot guard against errors in the unused branch. -- [**Choose**](Choose) returns the *index*-th item from a list of values — a one-based equivalent of array indexing for a fixed-length argument list. -- [**Switch**](Switch) walks pairs of *(condition, value)* arguments and returns the value paired with the first **True** condition — a compact stand-in for an **If...ElseIf** ladder. +- [**Choose**](Choose) returns the *index*-th item from a list of values -- a one-based equivalent of array indexing for a fixed-length argument list. +- [**Switch**](Switch) iterates over pairs of *(condition, value)* arguments and returns the value paired with the first **True** condition -- a compact stand-in for an **If...ElseIf** ladder. ```tb Dim Status As Variant @@ -57,9 +57,9 @@ DeleteSetting "MyApp", "Window", "Maximised" ## COM objects and dynamic dispatch -[**CreateObject**](CreateObject) instantiates a new COM/Automation object given its ProgID or CLSID — optionally on a remote machine when a *servername* is supplied. [**GetObject**](GetObject) is the dual: it either binds to a file (loading the application that owns it) or attaches to an already-running instance of an object class. +[**CreateObject**](CreateObject) instantiates a new COM/Automation object given its ProgID or CLSID --- optionally on a remote machine when a *servername* is supplied. [**GetObject**](GetObject) is the dual: it either binds to a file (loading the application that owns it) or attaches to an already-running instance of an object class. -Once an object reference is in hand, [**CallByName**](CallByName) and [**CallByDispId**](CallByDispId) invoke a method or property on it dynamically, when the member to call is only known at run time — by name in the first case, or by raw IDispatch dispatch ID in the second. [**RaiseEventByName**](RaiseEventByName) and [**RaiseEventByName2**](RaiseEventByName2) raise an event on an object by event-name string — the run-time equivalent of the **RaiseEvent** statement, useful when the event being raised isn't known at compile time. The two forms differ only in how the event arguments are supplied: as a packed **Variant** array, or as a variable-length argument list. +Once an object reference is in hand, [**CallByName**](CallByName) and [**CallByDispId**](CallByDispId) invoke a method or property on it dynamically, when the member to call is only known at run time --- by name in the first case, or by raw IDispatch dispatch ID in the second. [**RaiseEventByName**](RaiseEventByName) and [**RaiseEventByName2**](RaiseEventByName2) raise an event on an object by event-name string --- the run-time equivalent of the **RaiseEvent** statement, useful when the event being raised isn't known at compile time. The two forms differ only in how the event arguments are supplied: as a packed **Variant** array, or as a variable-length argument list. ## Members diff --git a/docs/Reference/VBA/Math/Log.md b/docs/Reference/VBA/Math/Log.md index e5977d5b..405f1864 100644 --- a/docs/Reference/VBA/Math/Log.md +++ b/docs/Reference/VBA/Math/Log.md @@ -16,7 +16,7 @@ Syntax: **Log(** *number* **)** The natural logarithm is the logarithm to the base *e*. The constant *e* is approximately 2.718282. -You can calculate base-*n* logarithms for any number *x* by dividing the natural logarithm of *x* by the natural logarithm of *n* as follows: +Base-*n* logarithms for any number *x* can be calculated by dividing the natural logarithm of *x* by the natural logarithm of *n* as follows: Log<sub>*n*</sub>(*x*) = **Log(** *x* **)** / **Log(** *n* **)** diff --git a/docs/Reference/VBA/Math/Randomize.md b/docs/Reference/VBA/Math/Randomize.md index 9ca746df..d04fc98f 100644 --- a/docs/Reference/VBA/Math/Randomize.md +++ b/docs/Reference/VBA/Math/Randomize.md @@ -14,7 +14,7 @@ Syntax: **Randomize** [ *number* ] *number* : *optional* A **Variant** or any valid numeric expression. -**Randomize** uses *number* to initialize the [**Rnd**](Rnd) function's random-number generator, giving it a new seed value. If you omit *number*, the value returned by the system timer is used as the new seed value. +**Randomize** uses *number* to initialize the [**Rnd**](Rnd) function's random-number generator, giving it a new seed value. If *number* is omitted, the value returned by the system timer is used as the new seed value. If **Randomize** is not used, the **Rnd** function (with no arguments) uses the same number as a seed the first time it is called, and thereafter uses the last generated number as a seed value. diff --git a/docs/Reference/VBA/Math/index.md b/docs/Reference/VBA/Math/index.md index 950631ce..d87abeac 100644 --- a/docs/Reference/VBA/Math/index.md +++ b/docs/Reference/VBA/Math/index.md @@ -7,11 +7,11 @@ has_toc: false # Math module -The **Math** module groups together the standard numeric functions — sign and magnitude, trigonometry, exponentials and logarithms, the square root, rounding to a chosen number of decimal places, and pseudo-random number generation. Most members return a **Double**, so intermediate results stay in floating point until they are written back to a narrower variable. +The **Math** module groups together the standard numeric functions --- sign and magnitude, trigonometry, exponentials and logarithms, the square root, rounding to a chosen number of decimal places, and pseudo-random number generation. Most members return a **Double**, so intermediate results stay in floating point until they are written back to a narrower variable. ## Sign and magnitude -[**Abs**](Abs) returns the absolute value of its argument — its distance from zero, with the sign discarded — and preserves the argument's data type, so `Abs(-3#)` is a **Double** and `Abs(-3)` an **Integer**. [**Sgn**](Sgn) is the complement: it discards the magnitude and returns just the sign, as `-1`, `0`, or `+1`. Together they decompose a number into its sign and magnitude. +[**Abs**](Abs) returns the absolute value of its argument --- its distance from zero, with the sign discarded --- and preserves the argument's data type, so `Abs(-3#)` is a **Double** and `Abs(-3)` an **Integer**. [**Sgn**](Sgn) is the complement: it discards the magnitude and returns just the sign, as `-1`, `0`, or `+1`. Together they decompose a number into its sign and magnitude. ```tb Debug.Print Abs(-7.5) ' 7.5 @@ -20,7 +20,7 @@ Debug.Print Sgn(-7.5) ' -1 ## Trigonometry -[**Sin**](Sin), [**Cos**](Cos), and [**Tan**](Tan) take an angle in radians and return its sine, cosine, and tangent. [**Atn**](Atn) goes the other way — given a tangent, it returns the angle whose tangent that is, in the range `-pi/2` to `pi/2`. All four work exclusively in radians; multiply degrees by `pi / 180` to convert to radians, or radians by `180 / pi` to convert back. +[**Sin**](Sin), [**Cos**](Cos), and [**Tan**](Tan) take an angle in radians and return its sine, cosine, and tangent. [**Atn**](Atn) goes the other way --- given a tangent, it returns the angle whose tangent that is, in the range `-pi/2` to `pi/2`. All four work exclusively in radians; multiply degrees by `pi / 180` to convert to radians, or radians by `180 / pi` to convert back. ```tb Const Pi As Double = 3.14159265358979 @@ -28,7 +28,7 @@ Debug.Print Sin(Pi / 2) ' 1 Debug.Print Atn(1) * 4 ' 3.14159265358979 — pi ``` -The other inverse trigonometric functions (arcsine, arccosine) and the hyperbolic functions are not provided directly, but each can be derived from **Atn**, **Log**, **Exp**, and **Sqr** in a couple of lines — see the worked examples on [**Atn**](Atn), [**Log**](Log), and [**Cos**](Cos). +The other inverse trigonometric functions (arcsine, arccosine) and the hyperbolic functions are not provided directly, but each can be derived from **Atn**, **Log**, **Exp**, and **Sqr** in a couple of lines --- see the worked examples on [**Atn**](Atn), [**Log**](Log), and [**Cos**](Cos). ## Exponentials and logarithms @@ -45,11 +45,11 @@ Debug.Print Log(100) / Log(10) ' 2 — base-10 log of 100 ## Rounding -[**Round**](Round) rounds a number to a chosen number of decimal places using *banker's rounding* — when the value lies exactly half-way between two possible results, it rounds toward the nearest **even** digit, so `Round(0.5, 0)` is `0` and `Round(1.5, 0)` is `2`. This avoids the systematic upward bias of always-round-half-up and matches VBA's behaviour. For *truncation* rather than rounding, see [**Int**](../Conversion/Int) and [**Fix**](../Conversion/Fix) in the [**Conversion**](../Conversion/) module; for narrowing-with-rounding to a specific integer type, see [**CInt**](../Conversion/CInt) and [**CLng**](../Conversion/CLng). +[**Round**](Round) rounds a number to a chosen number of decimal places using *banker's rounding* --- when the value lies exactly half-way between two possible results, it rounds toward the nearest **even** digit, so `Round(0.5, 0)` is `0` and `Round(1.5, 0)` is `2`. This avoids the systematic upward bias of always-round-half-up and matches VBA's behaviour. For *truncation* rather than rounding, see [**Int**](../Conversion/Int) and [**Fix**](../Conversion/Fix) in the [**Conversion**](../Conversion/) module; for narrowing-with-rounding to a specific integer type, see [**CInt**](../Conversion/CInt) and [**CLng**](../Conversion/CLng). ## Random numbers -[**Randomize**](Randomize) seeds the pseudo-random number generator, and [**Rnd**](Rnd) draws from it, returning a **Single** in the half-open range `[0, 1)`. Without an explicit call to **Randomize**, **Rnd** produces the same sequence every time the program runs — convenient for reproducible tests; for unpredictable output, call **Randomize** once at startup with no argument so the system timer is used as the seed. +[**Randomize**](Randomize) seeds the pseudo-random number generator, and [**Rnd**](Rnd) draws from it, returning a **Single** in the half-open range `[0, 1)`. Without an explicit call to **Randomize**, **Rnd** produces the same sequence every time the program runs --- convenient for reproducible tests; for unpredictable output, call **Randomize** once at startup with no argument so the system timer is used as the seed. The standard idiom for a uniformly distributed integer between *lower* and *upper* (inclusive) combines **Rnd** with [**Int**](../Conversion/Int): diff --git a/docs/Reference/VBA/Strings/Asc.md b/docs/Reference/VBA/Strings/Asc.md index 624d73bc..da4eea1e 100644 --- a/docs/Reference/VBA/Strings/Asc.md +++ b/docs/Reference/VBA/Strings/Asc.md @@ -18,7 +18,7 @@ Syntax: *string* : *required* Any valid string expression. If *string* contains no characters, a run-time error occurs. -The range for returns from **Asc** is 0–255 on non-DBCS systems, but -32768–32767 on DBCS systems. +The range for returns from **Asc** is 0--255 on non-DBCS systems, but -32768--32767 on DBCS systems. > [!NOTE] > The **AscB** function is used with byte data contained in a string. Instead of returning the character code for the first character, **AscB** returns the first byte. The **AscW** function returns the Unicode character code. diff --git a/docs/Reference/VBA/Strings/Chr.md b/docs/Reference/VBA/Strings/Chr.md index 698637be..7d611bdb 100644 --- a/docs/Reference/VBA/Strings/Chr.md +++ b/docs/Reference/VBA/Strings/Chr.md @@ -20,7 +20,7 @@ Syntax: The `$`-suffixed forms return a **String**; the unsuffixed forms return a **Variant** (**String**). -Numbers from 0–31 are the same as standard, nonprintable ASCII codes. For example, `Chr(10)` returns a linefeed character. The normal range for *charcode* is 0–255. However, on DBCS systems, the actual range for *charcode* is -32768–65535. +Numbers from 0--31 are the same as standard, nonprintable ASCII codes. For example, `Chr(10)` returns a linefeed character. The normal range for *charcode* is 0--255. However, on DBCS systems, the actual range for *charcode* is -32768--65535. > [!NOTE] > The **ChrB** function is used with byte data contained in a **String**. Instead of returning a character, which may be one or two bytes, **ChrB** always returns a single byte. diff --git a/docs/Reference/VBA/Strings/Format.md b/docs/Reference/VBA/Strings/Format.md index e41e6de3..71160e17 100644 --- a/docs/Reference/VBA/Strings/Format.md +++ b/docs/Reference/VBA/Strings/Format.md @@ -52,13 +52,13 @@ The *firstWeekOfYear* argument has these settings. | Numbers | Use predefined named numeric formats or create user-defined numeric formats. | | Dates and times | Use predefined named date/time formats or create user-defined date/time formats. | | Date and time serial numbers | Use date and time formats or numeric formats. | -| Strings | Create your own user-defined string formats. | +| Strings | Create user-defined string formats. | **Format** truncates *format* to 257 characters. -If you try to format a number without specifying *format*, **Format** provides functionality similar to the **Str** function, although it is internationally aware. However, positive numbers formatted as strings using **Format** don't include a leading space reserved for the sign of the value; those converted using **Str** retain the leading space. +When formatting a number without specifying *format*, **Format** provides functionality similar to the **Str** function, although it is internationally aware. However, positive numbers formatted as strings using **Format** don't include a leading space reserved for the sign of the value; those converted using **Str** retain the leading space. -If you are formatting a non-localized numeric string, you should use a user-defined numeric format to ensure that you get the look you want. +When formatting a non-localized numeric string, use a user-defined numeric format to ensure the desired appearance. > [!NOTE] > If the [**Calendar**](../DateTime/Calendar) property setting is `Gregorian` and *format* specifies date formatting, the supplied *expression* must be Gregorian. If the **Calendar** property setting is `Hijri`, the supplied *expression* must be Hijri. @@ -96,7 +96,7 @@ If the calendar is Gregorian, the meaning of *format* expression symbols is unch ### Example -This example shows various uses of the **Format** function to format values using both named formats and user-defined formats. For the date separator (`/`), time separator (`:`), and AM/PM literal, the actual formatted output displayed by your system depends on the locale settings on which the code is running. When times and dates are displayed in the development environment, the short time format and short date format of the code locale are used. When displayed by running code, the short time format and short date format of the system locale are used, which may differ from the code locale. For this example, English/U.S. is assumed. `MyTime` and `MyDate` are displayed in the development environment using the current system short time setting and short date setting. +This example shows various uses of the **Format** function to format values using both named formats and user-defined formats. For the date separator (`/`), time separator (`:`), and AM/PM literal, the actual formatted output displayed by the system depends on the locale settings on which the code is running. When times and dates are displayed in the development environment, the short time format and short date format of the code locale are used. When displayed by running code, the short time format and short date format of the system locale are used, which may differ from the code locale. For this example, English/U.S. is assumed. `MyTime` and `MyDate` are displayed in the development environment using the current system short time setting and short date setting. ```tb Dim MyTime, MyDate, MyStr @@ -129,18 +129,18 @@ MyStr = Format("This is it", ">") ' Returns "THIS IS IT". A user-defined format expression for numbers can have from one to four sections separated by semicolons. If the *format* argument contains one of the named numeric formats, only one section is allowed. -| If you use | The result is | -|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| One section only| The format expression applies to all values. | -| Two sections | The first section applies to positive values and zeros, the second to negative values. | -| Three sections | The first section applies to positive values, the second to negative values, and the third to zeros. | -| Four sections | The first section applies to positive values, the second to negative values, the third to zeros, and the fourth to **Null** values. | +| Sections | The result is | +|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| One section only | The format expression applies to all values. | +| Two sections | The first section applies to positive values and zeros, the second to negative values. | +| Three sections | The first section applies to positive values, the second to negative values, and the third to zeros. | +| Four sections | The first section applies to positive values, the second to negative values, the third to zeros, and the fourth to **Null** values. | ```tb "$#,##0;($#,##0)" ``` -If you include semicolons with nothing between them, the missing section is printed using the format of the positive value. For example, the following format displays positive and negative values using the format in the first section and displays "Zero" if the value is zero. +When semicolons are included with nothing between them, the missing section is printed using the format of the positive value. For example, the following format displays positive and negative values using the format in the first section and displays "Zero" if the value is zero. ```tb "$#,##0;;\Z\e\r\o" @@ -150,7 +150,7 @@ If you include semicolons with nothing between them, the missing section is prin A format expression for strings can have one section or two sections separated by a semicolon (`;`). -| If you use | The result is | +| Sections | The result is | |------------------|--------------------------------------------------------------------------------------------| | One section only | The format applies to all string data. | | Two sections | The first section applies to string data, the second to **Null** values and zero-length strings (`""`). | @@ -161,11 +161,11 @@ The following table identifies the predefined date and time format names. | Format name | Description | |-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **General Date** | Display a date and/or time, for example, 4/3/93 05:34 PM. If there is no fractional part, display only a date, for example, 4/3/93. If there is no integer part, display time only, for example, 05:34 PM. Date display is determined by your system settings. | -| **Long Date** | Display a date according to your system's long date format. | +| **General Date** | Display a date and/or time, for example, 4/3/93 05:34 PM. If there is no fractional part, display only a date, for example, 4/3/93. If there is no integer part, display time only, for example, 05:34 PM. Date display is determined by the system settings. | +| **Long Date** | Display a date according to the system long date format. | | **Medium Date** | Display a date using the medium date format appropriate for the language version of the host application. | -| **Short Date** | Display a date using your system's short date format. | -| **Long Time** | Display a time using your system's long time format; includes hours, minutes, seconds. | +| **Short Date** | Display a date using the system short date format. | +| **Long Time** | Display a time using the system long time format; includes hours, minutes, seconds. | | **Medium Time** | Display time in 12-hour format using hours and minutes and the AM/PM designator. | | **Short Time** | Display a time using the 24-hour format, for example, 17:45. | @@ -199,52 +199,52 @@ Use any of the following characters to create a format expression for strings. ### User-defined date/time formats -The following table identifies characters you can use to create user-defined date/time formats. +The following table identifies the characters available for creating user-defined date/time formats. | Character | Description | |--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `:` | Time separator. In some locales, other characters may be used to represent the time separator. The time separator separates hours, minutes, and seconds when time values are formatted. The actual character used as the time separator in formatted output is determined by your system settings. | -| `/` | Date separator. In some locales, other characters may be used to represent the date separator. The date separator separates the day, month, and year when date values are formatted. The actual character used as the date separator in formatted output is determined by your system settings. | +| `:` | Time separator. In some locales, other characters may be used to represent the time separator. The time separator separates hours, minutes, and seconds when time values are formatted. The actual character used as the time separator in formatted output is determined by the system settings. | +| `/` | Date separator. In some locales, other characters may be used to represent the date separator. The date separator separates the day, month, and year when date values are formatted. The actual character used as the date separator in formatted output is determined by the system settings. | | `c` | Display the date as `ddddd` and display the time as `ttttt`, in that order. Display only date information if there is no fractional part to the date serial number; display only time information if there is no integer portion. | -| `d` | Display the day as a number without a leading zero (1–31). | -| `dd` | Display the day as a number with a leading zero (01–31). | -| `ddd` | Display the day as an abbreviation (Sun–Sat). Localized. | -| `dddd` | Display the day as a full name (Sunday–Saturday). Localized. | -| `ddddd` | Display the date as a complete date (including day, month, and year), formatted according to your system's short date format setting. The default short date format is `m/d/yy`. | -| `dddddd` | Display a date serial number as a complete date (including day, month, and year) formatted according to the long date setting recognized by your system. The default long date format is `mmmm dd, yyyy`. | +| `d` | Display the day as a number without a leading zero (1--31). | +| `dd` | Display the day as a number with a leading zero (01--31). | +| `ddd` | Display the day as an abbreviation (Sun--Sat). Localized. | +| `dddd` | Display the day as a full name (Sunday--Saturday). Localized. | +| `ddddd` | Display the date as a complete date (including day, month, and year), formatted according to the system short date format setting. The default short date format is `m/d/yy`. | +| `dddddd` | Display a date serial number as a complete date (including day, month, and year) formatted according to the long date setting recognized by the system. The default long date format is `mmmm dd, yyyy`. | | `w` | Display the day of the week as a number (1 for Sunday through 7 for Saturday). | -| `ww` | Display the week of the year as a number (1–54). | -| `m` | Display the month as a number without a leading zero (1–12). If `m` immediately follows `h` or `hh`, the minute rather than the month is displayed. | -| `mm` | Display the month as a number with a leading zero (01–12). If `m` immediately follows `h` or `hh`, the minute rather than the month is displayed. | -| `mmm` | Display the month as an abbreviation (Jan–Dec). Localized. | -| `mmmm` | Display the month as a full month name (January–December). Localized. | -| `q` | Display the quarter of the year as a number (1–4). | -| `y` | Display the day of the year as a number (1–366). | -| `yy` | Display the year as a 2-digit number (00–99). | -| `yyyy` | Display the year as a 4-digit number (100–9999). | -| `h` | Display the hour as a number without a leading zero (0–23). | -| `hh` | Display the hour as a number with a leading zero (00–23). | -| `n` | Display the minute as a number without a leading zero (0–59). | -| `nn` | Display the minute as a number with a leading zero (00–59). | -| `s` | Display the second as a number without a leading zero (0–59). | -| `ss` | Display the second as a number with a leading zero (00–59). | -| `ttttt` | Display a time as a complete time (including hour, minute, and second), formatted using the time separator defined by the time format recognized by your system. A leading zero is displayed if the leading zero option is selected and the time is before 10:00 A.M. or P.M. The default time format is `h:mm:ss`. | +| `ww` | Display the week of the year as a number (1--54). | +| `m` | Display the month as a number without a leading zero (1--12). If `m` immediately follows `h` or `hh`, the minute rather than the month is displayed. | +| `mm` | Display the month as a number with a leading zero (01--12). If `m` immediately follows `h` or `hh`, the minute rather than the month is displayed. | +| `mmm` | Display the month as an abbreviation (Jan--Dec). Localized. | +| `mmmm` | Display the month as a full month name (January--December). Localized. | +| `q` | Display the quarter of the year as a number (1--4). | +| `y` | Display the day of the year as a number (1--366). | +| `yy` | Display the year as a 2-digit number (00--99). | +| `yyyy` | Display the year as a 4-digit number (100--9999). | +| `h` | Display the hour as a number without a leading zero (0--23). | +| `hh` | Display the hour as a number with a leading zero (00--23). | +| `n` | Display the minute as a number without a leading zero (0--59). | +| `nn` | Display the minute as a number with a leading zero (00--59). | +| `s` | Display the second as a number without a leading zero (0--59). | +| `ss` | Display the second as a number with a leading zero (00--59). | +| `ttttt` | Display a time as a complete time (including hour, minute, and second), formatted using the time separator defined by the time format recognized by the system. A leading zero is displayed if the leading zero option is selected and the time is before 10:00 A.M. or P.M. The default time format is `h:mm:ss`. | | `AM/PM` | Use the 12-hour clock and display an uppercase AM with any hour before noon; display an uppercase PM with any hour between noon and 11:59 P.M. | | `am/pm` | Use the 12-hour clock and display a lowercase AM with any hour before noon; display a lowercase PM with any hour between noon and 11:59 P.M. | | `A/P` | Use the 12-hour clock and display an uppercase A with any hour before noon; display an uppercase P with any hour between noon and 11:59 P.M. | | `a/p` | Use the 12-hour clock and display a lowercase A with any hour before noon; display a lowercase P with any hour between noon and 11:59 P.M. | -| `AMPM` | Use the 12-hour clock and display the AM string literal as defined by your system with any hour before noon; display the PM string literal as defined by your system with any hour between noon and 11:59 P.M. | +| `AMPM` | Use the 12-hour clock and display the AM string literal as defined by the system with any hour before noon; display the PM string literal as defined by the system with any hour between noon and 11:59 P.M. | ### User-defined numeric formats -The following table identifies characters you can use to create user-defined number formats. +The following table identifies the characters available for creating user-defined number formats. | Character | Description | |--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | None | Display the number with no formatting. | | `0` | Digit placeholder. Display a digit or a zero. If the expression has a digit in the position where the `0` appears in the format string, display it; otherwise, display a zero in that position. If the number has fewer digits than there are zeros (on either side of the decimal) in the format expression, display leading or trailing zeros. If the number has more digits to the right of the decimal separator than there are zeros to the right of the decimal separator in the format expression, round the number to as many decimal places as there are zeros. If the number has more digits to the left of the decimal separator than there are zeros to the left of the decimal separator in the format expression, display the extra digits without modification. | | `#` | Digit placeholder. Display a digit or nothing. If the expression has a digit in the position where the `#` appears in the format string, display it; otherwise, display nothing in that position. This symbol works like the `0` digit placeholder, except that leading and trailing zeros aren't displayed if the number has the same or fewer digits than there are `#` characters on either side of the decimal separator in the format expression. | -| `.` | Decimal placeholder. The decimal placeholder determines how many digits are displayed to the left and right of the decimal separator. If the format expression contains only number signs to the left of this symbol, numbers smaller than 1 begin with a decimal separator. To display a leading zero with fractional numbers, use 0 as the first digit placeholder to the left of the decimal separator. The actual character used as a decimal placeholder in the formatted output depends on the Number Format recognized by your system. | +| `.` | Decimal placeholder. The decimal placeholder determines how many digits are displayed to the left and right of the decimal separator. If the format expression contains only number signs to the left of this symbol, numbers smaller than 1 begin with a decimal separator. To display a leading zero with fractional numbers, use 0 as the first digit placeholder to the left of the decimal separator. The actual character used as a decimal placeholder in the formatted output depends on the Number Format recognized by the system. | | `%` | Percentage placeholder. The expression is multiplied by 100. The percent character (`%`) is inserted in the position where it appears in the format string. | | `,` | Thousand separator. Standard use of the thousand separator is specified if the format contains a thousand separator surrounded by digit placeholders (`0` or `#`). Two adjacent thousand separators or a thousand separator immediately to the left of the decimal separator means "scale the number by dividing it by 1000, rounding as needed." | | `:` | Time separator. See above. | @@ -252,7 +252,7 @@ The following table identifies characters you can use to create user-defined num | `E- E+ e- e+` | Scientific format. If the format expression contains at least one digit placeholder (`0` or `#`) to the right of `E-`, `E+`, `e-`, or `e+`, the number is displayed in scientific format and `E` or `e` is inserted between the number and its exponent. Use `E-` or `e-` to place a minus sign next to negative exponents. Use `E+` or `e+` to place a minus sign next to negative exponents and a plus sign next to positive exponents. | | `- + $ ( )` | Display a literal character. To display a character other than one of those listed, precede it with a backslash (`\`) or enclose it in double quotation marks (`" "`). | | `\` | Display the next character in the format string. Using a backslash is the same as enclosing the next character in double quotation marks. To display a backslash, use two backslashes (`\\`). | -| `"ABC"` | Display the string inside the double quotation marks (`" "`). To include a string in *format* from within code, you must use `Chr(34)` to enclose the text (34 is the character code for a quotation mark `"`). | +| `"ABC"` | Display the string inside the double quotation marks (`" "`). To include a string in *format* from within code, use `Chr(34)` to enclose the text (34 is the character code for a quotation mark `"`). | ### See Also diff --git a/docs/Reference/VBA/Strings/FormatDateTime.md b/docs/Reference/VBA/Strings/FormatDateTime.md index 4d5762e6..f2d88413 100644 --- a/docs/Reference/VBA/Strings/FormatDateTime.md +++ b/docs/Reference/VBA/Strings/FormatDateTime.md @@ -22,9 +22,9 @@ The *namedFormat* argument has the following settings: | Constant | Value | Description | |--------------------|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **vbGeneralDate** | 0 | Display a date and/or time. If there is a date part, display it as a short date. If there is a time part, display it as a long time. If present, both parts are displayed. | -| **vbLongDate** | 1 | Display a date by using the long date format specified in your computer's regional settings. | -| **vbShortDate** | 2 | Display a date by using the short date format specified in your computer's regional settings. | -| **vbLongTime** | 3 | Display a time by using the time format specified in your computer's regional settings. | +| **vbLongDate** | 1 | Display a date by using the long date format specified in the system regional settings. | +| **vbShortDate** | 2 | Display a date by using the short date format specified in the system regional settings. | +| **vbLongTime** | 3 | Display a time by using the time format specified in the system regional settings. | | **vbShortTime** | 4 | Display a time by using the 24-hour format (`hh:mm`). | ### See Also diff --git a/docs/Reference/VBA/Strings/InStrRev.md b/docs/Reference/VBA/Strings/InStrRev.md index a8377a3c..7790f0cd 100644 --- a/docs/Reference/VBA/Strings/InStrRev.md +++ b/docs/Reference/VBA/Strings/InStrRev.md @@ -44,7 +44,7 @@ The *compare* argument can have the following values: | *start* > **Len**(*stringcheck*) | 0 | > [!NOTE] -> The syntax for the **InStrRev** function is not the same as the syntax for the [**InStr**](InStr) function — note the swapped order of the search arguments. +> The syntax for the **InStrRev** function is not the same as the syntax for the [**InStr**](InStr) function --- note the swapped order of the search arguments. **InStrRev** will not find an instance of *stringmatch* unless the position of the end character of *stringmatch* is less than or equal to *start*. diff --git a/docs/Reference/VBA/Strings/Space.md b/docs/Reference/VBA/Strings/Space.md index ae7f4fa6..4dcfafb7 100644 --- a/docs/Reference/VBA/Strings/Space.md +++ b/docs/Reference/VBA/Strings/Space.md @@ -12,7 +12,7 @@ Returns a **String** consisting of the specified number of spaces. Syntax: **Space$(** *number* **)**, **Space(** *number* **)** *number* -: *required* The number of spaces you want in the string. +: *required* The number of spaces in the string. The `$`-suffixed form returns a **String**; the unsuffixed form returns a **Variant** (**String**). diff --git a/docs/Reference/VBA/Strings/StrConv.md b/docs/Reference/VBA/Strings/StrConv.md index 9506636b..6f849e63 100644 --- a/docs/Reference/VBA/Strings/StrConv.md +++ b/docs/Reference/VBA/Strings/StrConv.md @@ -35,7 +35,7 @@ The *conversion* argument settings are: | **vbFromUnicode** | 128 | Converts the string from Unicode to the default code page of the system. | > [!NOTE] -> These constants are specified by twinBASIC. As a result, they may be used anywhere in your code in place of the actual values. Most can be combined, for example, **vbUpperCase + vbWide**, except when they are mutually exclusive, for example, **vbUnicode + vbFromUnicode**. The constants **vbWide**, **vbNarrow**, **vbKatakana**, and **vbHiragana** cause run-time errors when used in locales where they don't apply. +> These constants are specified by twinBASIC. As a result, they may be used anywhere in code in place of the actual values. Most can be combined, for example, **vbUpperCase + vbWide**, except when they are mutually exclusive, for example, **vbUnicode + vbFromUnicode**. The constants **vbWide**, **vbNarrow**, **vbKatakana**, and **vbHiragana** cause run-time errors when used in locales where they don't apply. The following are valid word separators for proper casing: **Null** (`Chr$(0)`), horizontal tab (`Chr$(9)`), linefeed (`Chr$(10)`), vertical tab (`Chr$(11)`), form feed (`Chr$(12)`), carriage return (`Chr$(13)`), space (SBCS) (`Chr$(32)`). The actual value for a space varies by country/region for DBCS. diff --git a/docs/Reference/VBA/Strings/String.md b/docs/Reference/VBA/Strings/String.md index e83fe62d..7999c449 100644 --- a/docs/Reference/VBA/Strings/String.md +++ b/docs/Reference/VBA/Strings/String.md @@ -19,7 +19,7 @@ Syntax: **String$(** *number*, *character* **)**, **String(** *number*, *charact The `$`-suffixed form returns a **String**; the unsuffixed form returns a **Variant** (**String**). -If you specify a number for *character* greater than 255, **String** converts the number to a valid character code by using this formula: *character* **Mod** 256. +When *character* is a number greater than 255, **String** converts the number to a valid character code by using this formula: *character* **Mod** 256. ### Example diff --git a/docs/Reference/VBA/Strings/index.md b/docs/Reference/VBA/Strings/index.md index 0a59dd6a..f2314e3e 100644 --- a/docs/Reference/VBA/Strings/index.md +++ b/docs/Reference/VBA/Strings/index.md @@ -7,11 +7,11 @@ has_toc: false # Strings module -The **Strings** module groups together the runtime's text-processing primitives — measuring strings, looking inside them, building new ones from old ones, splitting and joining arrays of them, and formatting non-string values as text. Most members come in two callable forms: a `$`-suffixed form (e.g. **Left$**) that returns a **String**, and an unsuffixed form (e.g. **Left**) that returns a **Variant** (**String**) and propagates **Null** through the call. Several also have a `B` variant — **AscB**, **ChrB**, **InStrB**, **LeftB**, **LenB**, **MidB**, **RightB** — that operates on byte positions rather than character positions, for use with byte-buffer data held in a **String**. +The **Strings** module groups together the runtime's text-processing primitives --- measuring strings, looking inside them, building new ones from old ones, splitting and joining arrays of them, and formatting non-string values as text. Most members come in two callable forms: a `$`-suffixed form (e.g. **Left$**) that returns a **String**, and an unsuffixed form (e.g. **Left**) that returns a **Variant** (**String**) and propagates **Null** through the call. Several also have a `B` variant --- **AscB**, **ChrB**, **InStrB**, **LeftB**, **LenB**, **MidB**, **RightB** --- that operates on byte positions rather than character positions, for use with byte-buffer data held in a **String**. ## Length and character codes -[**Len**](Len) returns the number of characters in a string, or — when given a non-string variable — the number of bytes the variable occupies. [**Asc**](Asc) returns the character code of a string's first character; [**Chr**](Chr) is its inverse, building a single-character string from a code point. The `W` variants ([**AscW**](Asc), [**ChrW**](Chr)) work in Unicode regardless of the system code page. +[**Len**](Len) returns the number of characters in a string, or --- when given a non-string variable --- the number of bytes the variable occupies. [**Asc**](Asc) returns the character code of a string's first character; [**Chr**](Chr) is its inverse, building a single-character string from a code point. The `W` variants ([**AscW**](Asc), [**ChrW**](Chr)) work in Unicode regardless of the system code page. ```tb Debug.Print Len("Hello") ' 5 @@ -31,7 +31,7 @@ Debug.Print StrComp("ABC", "abc", vbTextCompare) ' 0 (equal under text compare) ## Substrings, padding, and trimming -[**Left**](Left), [**Mid**](Mid), and [**Right**](Right) extract a substring from the start, middle, or end of a string. **Mid** doubles as an l-value via the [**Mid =**](../../Core/Mid-equals) statement, which writes characters back into a string in place. [**Space**](Space) returns a run of spaces and [**String**](String) returns a run of any chosen character — both useful for padding fixed-width output. [**LTrim**](LTrim), [**RTrim**](RTrim), and [**Trim**](Trim) strip leading, trailing, or both kinds of whitespace from a string. +[**Left**](Left), [**Mid**](Mid), and [**Right**](Right) extract a substring from the start, middle, or end of a string. **Mid** doubles as an l-value via the [**Mid =**](../../Core/Mid-equals) statement, which writes characters back into a string in place. [**Space**](Space) returns a run of spaces and [**String**](String) returns a run of any chosen character --- both useful for padding fixed-width output. [**LTrim**](LTrim), [**RTrim**](RTrim), and [**Trim**](Trim) strip leading, trailing, or both kinds of whitespace from a string. ```tb Dim S As String @@ -43,7 +43,7 @@ Debug.Print String(3, "*") & " " & Space(2) & "!" ' "*** !" ## Case folding and other transformations -[**LCase**](LCase) and [**UCase**](UCase) fold a string to lowercase or uppercase. [**StrReverse**](StrReverse) reverses the character order. [**StrConv**](StrConv) bundles a wider set of conversions — case folding, proper-casing, narrow/wide and Hiragana/Katakana mapping for DBCS locales, and Unicode-to-ANSI byte-array round-tripping — selected by an additive flag argument. +[**LCase**](LCase) and [**UCase**](UCase) fold a string to lowercase or uppercase. [**StrReverse**](StrReverse) reverses the character order. [**StrConv**](StrConv) bundles a wider set of conversions --- case folding, proper-casing, narrow/wide and Hiragana/Katakana mapping for DBCS locales, and Unicode-to-ANSI byte-array round-tripping --- selected by an additive flag argument. ```tb Debug.Print UCase("Hello") ' "HELLO" @@ -53,7 +53,7 @@ Debug.Print StrConv("hello world", vbProperCase) ' "Hello World" ## Splitting, joining, replacing, filtering -[**Split**](Split) breaks a string apart at a delimiter into a zero-based array of substrings; [**Join**](Join) reverses the operation, gluing an array back together with a chosen separator between elements. [**Replace**](Replace) substitutes one substring for another across a string, optionally limited to a fixed number of replacements or starting from a given offset. [**Filter**](Filter) reduces a string array to only those elements that contain — or, with *include* set to **False**, do not contain — a chosen substring. +[**Split**](Split) breaks a string apart at a delimiter into a zero-based array of substrings; [**Join**](Join) reverses the operation, gluing an array back together with a chosen separator between elements. [**Replace**](Replace) substitutes one substring for another across a string, optionally limited to a fixed number of replacements or starting from a given offset. [**Filter**](Filter) reduces a string array to only those elements that contain --- or, with *include* set to **False**, do not contain --- a chosen substring. ```tb Dim Parts() As String @@ -64,7 +64,7 @@ Debug.Print Replace("red,green,blue", ",", "; ") ' "red; green; blue" ## Formatting values as text -[**Format**](Format) is the general-purpose formatter: it takes any expression — number, date, or string — together with a named or user-defined format string, and returns the rendered text. The four named-formatter functions [**FormatCurrency**](FormatCurrency), [**FormatNumber**](FormatNumber), [**FormatPercent**](FormatPercent), and [**FormatDateTime**](FormatDateTime) wrap the most common cases with explicit parameters in place of a format string, so the call site reads as the intent rather than as a recipe. [**MonthName**](MonthName) and [**WeekdayName**](WeekdayName) return the localised name (or abbreviation) of a month or day of the week, given its numeric index. +[**Format**](Format) is the general-purpose formatter: it takes any expression --- number, date, or string --- together with a named or user-defined format string, and returns the rendered text. The four named-formatter functions [**FormatCurrency**](FormatCurrency), [**FormatNumber**](FormatNumber), [**FormatPercent**](FormatPercent), and [**FormatDateTime**](FormatDateTime) wrap the most common cases with explicit parameters in place of a format string, so the call site reads as the intent rather than as a recipe. [**MonthName**](MonthName) and [**WeekdayName**](WeekdayName) return the localised name (or abbreviation) of a month or day of the week, given its numeric index. ```tb Debug.Print Format(1234.5, "#,##0.00") ' "1,234.50" diff --git a/docs/Reference/VBA/TbExpressionService/AddCustomBinder.md b/docs/Reference/VBA/TbExpressionService/AddCustomBinder.md index 97c60e0d..8d58b2b9 100644 --- a/docs/Reference/VBA/TbExpressionService/AddCustomBinder.md +++ b/docs/Reference/VBA/TbExpressionService/AddCustomBinder.md @@ -18,13 +18,13 @@ Syntax: *service*.**AddCustomBinder** *customBinder* *customBinder* : *required* An object that implements [**ITbCustomBinder**](./#itbcustombinder-interface). -Use **AddCustomBinder** when [**AddCustomBinderObject**](AddCustomBinderObject) doesn't fit — for example, when the names available to the expression are not statically known, when a name should resolve to something other than a member access on a fixed object, or when the implementer needs to inspect the argument count at the call site as part of resolution. +Use **AddCustomBinder** when [**AddCustomBinderObject**](AddCustomBinderObject) doesn't fit --- for example, when the names available to the expression are not statically known, when a name should resolve to something other than a member access on a fixed object, or when the implementer needs to inspect the argument count at the call site as part of resolution. The engine calls [**Bind**](Bind) on each registered custom binder during compilation, once per unresolved symbol. The first binder that returns a non-**Nothing** result wins. Multiple custom binders can be registered with one service, and they are consulted in registration order. ### Example -This example registers a class instance as both a property source (via [**AddCustomBinderObject**](AddCustomBinderObject) with [**IsAppObject**](./#IsAppObject)) and a custom binder. Bare symbols in the expression are first looked up as members of `Me` via the property source; whatever isn't matched there falls through to `Me.Bind`, which can resolve it dynamically — for example, against a live recordset. +This example registers a class instance as both a property source (via [**AddCustomBinderObject**](AddCustomBinderObject) with [**IsAppObject**](./#IsAppObject)) and a custom binder. Bare symbols in the expression are first looked up as members of `Me` via the property source; whatever isn't matched there falls through to `Me.Bind`, which can resolve it dynamically --- for example, against a live recordset. ```tb ' Inside a class that does: Implements ITbCustomBinder diff --git a/docs/Reference/VBA/TbExpressionService/AddCustomBinderObject.md b/docs/Reference/VBA/TbExpressionService/AddCustomBinderObject.md index fe117da8..869a9dc7 100644 --- a/docs/Reference/VBA/TbExpressionService/AddCustomBinderObject.md +++ b/docs/Reference/VBA/TbExpressionService/AddCustomBinderObject.md @@ -24,7 +24,7 @@ Syntax: *service*.**AddCustomBinderObject** *name*, *object* [ **,** *flags* ] *flags* : *optional* A combination of [**ExpressionEngineBinderFlags**](./#expressionenginebinderflags) values. The default is `0`, in which case the object's members are reachable only when qualified by *name* (e.g. `Report.Title`). Pass [**IsAppObject**](./#IsAppObject) to additionally make the members reachable without qualification, the way an Office host's **Application** members are. -Member resolution is performed by name through the standard COM/IDispatch protocol — any property or method that is callable from outside the object is callable from the expression. The object must remain alive for as long as expressions might be evaluated against it. +Member resolution is performed by name through the standard COM/IDispatch protocol --- any property or method that is callable from outside the object is callable from the expression. The object must remain alive for as long as expressions might be evaluated against it. Multiple objects can be bound to the same service, each under its own *name*. They are consulted in the order they were added. diff --git a/docs/Reference/VBA/TbExpressionService/AddStdLibraryBinder.md b/docs/Reference/VBA/TbExpressionService/AddStdLibraryBinder.md index e87c20a3..7c29f81d 100644 --- a/docs/Reference/VBA/TbExpressionService/AddStdLibraryBinder.md +++ b/docs/Reference/VBA/TbExpressionService/AddStdLibraryBinder.md @@ -15,9 +15,9 @@ Syntax: *service*.**AddStdLibraryBinder** *service* : *required* An object expression that evaluates to a **TbExpressionService** object. -After **AddStdLibraryBinder** has been called, expressions compiled by *service* can reference any procedure or property in the standard runtime library — math functions like [**Sqr**](../Math/Sqr), [**Sin**](../Math/Sin), and [**Round**](../Math/Round); string functions like [**Len**](../Strings/Len), [**Mid**](../Strings/Mid), and [**Format**](../Strings/Format); conversion functions like [**CStr**](../Conversion/CStr) and [**CInt**](../Conversion/CInt); and so on. +After **AddStdLibraryBinder** has been called, expressions compiled by *service* can reference any procedure or property in the standard runtime library --- math functions like [**Sqr**](../Math/Sqr), [**Sin**](../Math/Sin), and [**Round**](../Math/Round); string functions like [**Len**](../Strings/Len), [**Mid**](../Strings/Mid), and [**Format**](../Strings/Format); conversion functions like [**CStr**](../Conversion/CStr) and [**CInt**](../Conversion/CInt); and so on. -A new **TbExpressionService** has no binders registered. Without at least one binder, compiled expressions can do little more than evaluate literal arithmetic — any reference to a named symbol fails compilation with a run-time error. +A new **TbExpressionService** has no binders registered. Without at least one binder, compiled expressions can do little more than evaluate literal arithmetic --- any reference to a named symbol fails compilation with a run-time error. ### Example diff --git a/docs/Reference/VBA/TbExpressionService/Bind.md b/docs/Reference/VBA/TbExpressionService/Bind.md index f4ec6239..fbd0b4c2 100644 --- a/docs/Reference/VBA/TbExpressionService/Bind.md +++ b/docs/Reference/VBA/TbExpressionService/Bind.md @@ -16,14 +16,14 @@ Syntax: *binder*.**Bind(** *symbol*, *argCount* **)** : *required* An object expression that evaluates to an [**ITbCustomBinder**](./#itbcustombinder-interface) object. *symbol* -: *required* A **String** containing the name being looked up — the identifier as it appears in the source of the expression being compiled. +: *required* A **String** containing the name being looked up --- the identifier as it appears in the source of the expression being compiled. *argCount* : *required* A **Long** giving the number of arguments at the call site, or `0` if *symbol* is referenced as a bare value (a property-style access). The return value is an [**ITbExpression**](./#itbexpression-interface) whose [**Evaluate**](Evaluate) method produces the value of *symbol* when invoked, or **Nothing** to indicate that this binder cannot resolve *symbol* and the engine should fall through to the next binder. -**Bind** is called by the engine during compilation — once per unresolved symbol encountered in the expression source — not at evaluation time. The implementer is expected either to construct an **ITbExpression** that, when later evaluated, produces the value, or to return **Nothing** so that another binder gets a chance. +**Bind** is called by the engine during compilation --- once per unresolved symbol encountered in the expression source --- not at evaluation time. The implementer is expected either to construct an **ITbExpression** that, when later evaluated, produces the value, or to return **Nothing** so that another binder gets a chance. The *argCount* parameter lets the implementer distinguish a property-style reference (`MyName`, where *argCount* is `0`) from a function-style call (`MyName(1, 2, 3)`, where *argCount* is `3`), and bind them to different things. diff --git a/docs/Reference/VBA/TbExpressionService/Compile.md b/docs/Reference/VBA/TbExpressionService/Compile.md index 904631a9..279dddc2 100644 --- a/docs/Reference/VBA/TbExpressionService/Compile.md +++ b/docs/Reference/VBA/TbExpressionService/Compile.md @@ -16,13 +16,13 @@ Syntax: *service*.**Compile(** *expression* **)** : *required* An object expression that evaluates to a **TbExpressionService** object. *expression* -: *required* A **String** containing a twinBASIC-syntax expression — for example, `"Sqr(2) + 1"` or `"UCase(FirstName) & "" "" & UCase(LastName)"`. +: *required* A **String** containing a twinBASIC-syntax expression --- for example, `"Sqr(2) + 1"` or `"UCase(FirstName) & "" "" & UCase(LastName)"`. The return value is an [**ITbExpression**](./#itbexpression-interface). Calling [**Evaluate**](Evaluate) on it runs the expression and produces the current value; the same instance can be evaluated as many times as needed. -Symbols referenced in *expression* — function names, object members, properties — are resolved against the binders registered with *service* at the time of the call. At least one binder must be registered before **Compile** is called; the most common starting point is [**AddStdLibraryBinder**](AddStdLibraryBinder), which exposes the standard runtime library. +Symbols referenced in *expression* --- function names, object members, properties --- are resolved against the binders registered with *service* at the time of the call. At least one binder must be registered before **Compile** is called; the most common starting point is [**AddStdLibraryBinder**](AddStdLibraryBinder), which exposes the standard runtime library. -Compilation is the relatively expensive step; evaluation reuses the compiled form. When a piece of source text will be used for repeated evaluation — a formula column refreshed every row, a watch expression sampled in a debugger — compile it once and keep the **ITbExpression** around. +Compilation is the relatively expensive step; evaluation reuses the compiled form. When a piece of source text will be used for repeated evaluation --- a formula column refreshed every row, a watch expression sampled in a debugger --- compile it once and keep the **ITbExpression** around. If *expression* is malformed, or references a symbol that no registered binder can resolve, **Compile** raises a run-time error. diff --git a/docs/Reference/VBA/TbExpressionService/Evaluate.md b/docs/Reference/VBA/TbExpressionService/Evaluate.md index a7500c41..c8bfbf33 100644 --- a/docs/Reference/VBA/TbExpressionService/Evaluate.md +++ b/docs/Reference/VBA/TbExpressionService/Evaluate.md @@ -15,11 +15,11 @@ Syntax: *expression*.**Evaluate()** *expression* : *required* An object expression that evaluates to an [**ITbExpression**](./#itbexpression-interface), typically the value returned by [**Compile**](Compile). -The return value is a **Variant** holding the result of the expression. Its subtype reflects the natural type of the value — for example, **Double** for a numeric expression, **String** for a text-producing one, **Boolean** for a comparison. +The return value is a **Variant** holding the result of the expression. Its subtype reflects the natural type of the value --- for example, **Double** for a numeric expression, **String** for a text-producing one, **Boolean** for a comparison. -Each call re-runs the expression against the current state of its bindings. If the bound objects expose properties whose values can change between calls — host application state, the current row of a recordset, configurable parameters — evaluating the same compiled expression twice may legitimately return different values. +Each call re-runs the expression against the current state of its bindings. If the bound objects expose properties whose values can change between calls --- host application state, the current row of a recordset, configurable parameters --- evaluating the same compiled expression twice may legitimately return different values. -A run-time error raised inside the expression — division by zero, type mismatch, an invalid call into a bound object — propagates out of **Evaluate** like any other run-time error. +A run-time error raised inside the expression --- division by zero, type mismatch, an invalid call into a bound object --- propagates out of **Evaluate** like any other run-time error. ### Example diff --git a/docs/Reference/VBA/TbExpressionService/index.md b/docs/Reference/VBA/TbExpressionService/index.md index 043386ec..1f6ad52b 100644 --- a/docs/Reference/VBA/TbExpressionService/index.md +++ b/docs/Reference/VBA/TbExpressionService/index.md @@ -14,9 +14,9 @@ has_toc: false It is exposed as one class and two interfaces: -- [**TbExpressionService**](#tbexpressionservice-class) — the engine; instantiate one with **New**, register its binders, then [**Compile**](Compile) expressions against it. -- [**ITbExpression**](#itbexpression-interface) — a compiled expression handle returned by [**Compile**](Compile), evaluated with [**Evaluate**](Evaluate). -- [**ITbCustomBinder**](#itbcustombinder-interface) — implement this to provide fully custom symbol resolution. +- [**TbExpressionService**](#tbexpressionservice-class) -- the engine; instantiate one with **New**, register its binders, then [**Compile**](Compile) expressions against it. +- [**ITbExpression**](#itbexpression-interface) -- a compiled expression handle returned by [**Compile**](Compile), evaluated with [**Evaluate**](Evaluate). +- [**ITbCustomBinder**](#itbcustombinder-interface) -- implement this to provide fully custom symbol resolution. ## Compiling and evaluating an expression @@ -32,9 +32,9 @@ Sub Demo() End Sub ``` -## Binding to your own objects +## Binding to user objects -Anything beyond the standard library — application objects, configuration values, helper functions, recordset fields — has to be made visible to the engine through a *binder*. +Anything beyond the standard library --- application objects, configuration values, helper functions, recordset fields --- has to be made visible to the engine through a *binder*. The simplest form is [**AddCustomBinderObject**](AddCustomBinderObject), which takes a name and an object and exposes the object's public members under that name. Pass the **IsAppObject** flag to make the object behave like an Office host's **Application**: its members become reachable both qualified (`Report.Title`) and unqualified (`Title`). @@ -49,7 +49,7 @@ Sub UseCustomObject() End Sub ``` -For full control over symbol resolution — for example, to look up names dynamically against a recordset, virtualize a name into something other than a member access, or fall through to a custom default — implement [**ITbCustomBinder**](#itbcustombinder-interface) and register it with [**AddCustomBinder**](AddCustomBinder). Multiple binders can coexist; the engine consults them in registration order until one returns a non-**Nothing** result. +For full control over symbol resolution --- for example, to look up names dynamically against a recordset, virtualize a name into something other than a member access, or fall through to a custom default --- implement [**ITbCustomBinder**](#itbcustombinder-interface) and register it with [**AddCustomBinder**](AddCustomBinder). Multiple binders can coexist; the engine consults them in registration order until one returns a non-**Nothing** result. ## TbExpressionService class @@ -80,7 +80,7 @@ A handle to a compiled expression. Returned by [**Compile**](Compile) and by an ## ITbCustomBinder interface -Implement this interface to register a fully custom resolver with [**AddCustomBinder**](AddCustomBinder). The engine calls [**Bind**](Bind) during compilation for each unresolved symbol it encounters in the expression source, supplying the symbol name and the number of arguments at the call site, and expects an **ITbExpression** that produces the value when **Evaluate** is called — or **Nothing** to defer to the next binder. +Implement this interface to register a fully custom resolver with [**AddCustomBinder**](AddCustomBinder). The engine calls [**Bind**](Bind) during compilation for each unresolved symbol it encounters in the expression source, supplying the symbol name and the number of arguments at the call site, and expects an **ITbExpression** that produces the value when **Evaluate** is called --- or **Nothing** to defer to the next binder. ### Members diff --git a/docs/Reference/VBA/index.md b/docs/Reference/VBA/index.md index a8a37a19..bd720eb8 100644 --- a/docs/Reference/VBA/index.md +++ b/docs/Reference/VBA/index.md @@ -11,17 +11,17 @@ has_toc: false # VBA Package -The VBA built-in package collects the standard runtime library — the modules grouping the standalone procedures (**MsgBox**, **CStr**, **Mid**, **Format**, …), plus a small number of intrinsic classes (**Collection**, **Err**) and twinBASIC's runtime expression engine. +The VBA built-in package collects the standard runtime library --- the modules grouping the standalone procedures (**MsgBox**, **CStr**, **Mid**, **Format**, …), plus a small number of intrinsic classes (**Collection**, **Err**) and twinBASIC's runtime expression engine. ## Classes - [Collection](../Modules/Collection) -- ordered set of values or object references, accessed by 1-based index or by optional string key - [ErrObject](../Modules/ErrObject) -- the singleton **Err** object holding information about the most recent run-time error -- [TbExpressionService](../Modules/ExpressionService) -- runtime expression engine — parse and evaluate twinBASIC-syntax expressions supplied as strings +- [TbExpressionService](../Modules/ExpressionService) -- runtime expression engine -- parse and evaluate twinBASIC-syntax expressions supplied as strings ## Modules -- [(Default)](../Modules/HiddenModule) -- unqualified low-level intrinsics — the **GetMem** / **PutMem** family, **AllocMem**, atomic operations, compile-time reflection, codegen and stack-inspection primitives, … +- [(Default)](../Modules/HiddenModule) -- unqualified low-level intrinsics -- the **GetMem** / **PutMem** family, **AllocMem**, atomic operations, compile-time reflection, codegen and stack-inspection primitives, … - [Compilation](../Modules/Compilation) -- compile-time intrinsics that record the project, component, procedure, and source file at the call site - [Constants](../Modules/Constants) -- global character, pointer, and error-base constants reachable without qualification (**vbCrLf**, **vbNullString**, **vbObjectError**, …) - [Conversion](../Modules/Conversion) -- type coercion (**CBool**, **CDate**, **CType**, …), number ↔ string parsing, base conversion, and **Variant**-with-error construction diff --git a/docs/Reference/VBRUN/AmbientProperties/DisplayAsDefault.md b/docs/Reference/VBRUN/AmbientProperties/DisplayAsDefault.md index ba8c4316..59cbb1b9 100644 --- a/docs/Reference/VBRUN/AmbientProperties/DisplayAsDefault.md +++ b/docs/Reference/VBRUN/AmbientProperties/DisplayAsDefault.md @@ -13,7 +13,7 @@ Syntax: *object*.**DisplayAsDefault** *object* : *required* An object expression that evaluates to an **AmbientProperties** object. -The default control on a form is the one activated when the user presses **Enter** without first giving focus to another control — most often a command button. A control that wants to advertise its default-button status should paint itself with the heavier border or other distinguishing visual when **DisplayAsDefault** is **True**. +The default control on a form is the one activated when the user presses **Enter** without first giving focus to another control --- most often a command button. A control that wants to advertise its default-button status should paint itself with the heavier border or other distinguishing visual when **DisplayAsDefault** is **True**. ### See Also diff --git a/docs/Reference/VBRUN/AmbientProperties/DisplayName.md b/docs/Reference/VBRUN/AmbientProperties/DisplayName.md index 863fa3bd..e55890de 100644 --- a/docs/Reference/VBRUN/AmbientProperties/DisplayName.md +++ b/docs/Reference/VBRUN/AmbientProperties/DisplayName.md @@ -13,7 +13,7 @@ Syntax: *object*.**DisplayName** *object* : *required* An object expression that evaluates to an **AmbientProperties** object. -The host typically returns the name by which the user identifies the control — for example `"Form1!Command1"` in a designer, or whatever label has been chosen at run time. A control can include this string in error messages, log entries, or property browsers so that the user can tell which instance the message refers to. +The host typically returns the name by which the user identifies the control --- for example `"Form1!Command1"` in a designer, or whatever label has been chosen at run time. A control can include this string in error messages, log entries, or property browsers so that the user can tell which instance the message refers to. ### See Also diff --git a/docs/Reference/VBRUN/AmbientProperties/LocaleID.md b/docs/Reference/VBRUN/AmbientProperties/LocaleID.md index 5d3f67a2..f9fb5c85 100644 --- a/docs/Reference/VBRUN/AmbientProperties/LocaleID.md +++ b/docs/Reference/VBRUN/AmbientProperties/LocaleID.md @@ -13,7 +13,7 @@ Syntax: *object*.**LocaleID** *object* : *required* An object expression that evaluates to an **AmbientProperties** object. -The Locale ID (LCID) is a 32-bit Windows identifier that names a language and a regional formatting convention — for example `&H0409&` for English (United States) or `&H0407&` for German (Germany). A control should use this value when formatting numbers, dates, currencies, and message text, so that its output matches the language and conventions the host application is presenting to the user. +The Locale ID (LCID) is a 32-bit Windows identifier that names a language and a regional formatting convention --- for example `&H0409&` for English (United States) or `&H0407&` for German (Germany). A control should use this value when formatting numbers, dates, currencies, and message text, so that its output matches the language and conventions the host application is presenting to the user. ### See Also diff --git a/docs/Reference/VBRUN/AmbientProperties/MessageReflect.md b/docs/Reference/VBRUN/AmbientProperties/MessageReflect.md index 29a9b0b1..a4a1dcf7 100644 --- a/docs/Reference/VBRUN/AmbientProperties/MessageReflect.md +++ b/docs/Reference/VBRUN/AmbientProperties/MessageReflect.md @@ -13,7 +13,7 @@ Syntax: *object*.**MessageReflect** *object* : *required* An object expression that evaluates to an **AmbientProperties** object. -Some Windows notification messages — such as **WM_COMMAND**, **WM_NOTIFY**, and the **WM_CTLCOLOR\*** family — are by default delivered to the parent window of the control that produced them. When **MessageReflect** is **True**, the container reflects those notifications back to the control's own window procedure as **OCM_\*** messages, so the control can handle them itself; when **False**, the container handles them and the control will not see them. +Some Windows notification messages --- such as **WM_COMMAND**, **WM_NOTIFY**, and the **WM_CTLCOLOR\*** family --- are by default delivered to the parent window of the control that produced them. When **MessageReflect** is **True**, the container reflects those notifications back to the control's own window procedure as **OCM_\*** messages, so the control can handle them itself; when **False**, the container handles them and the control will not see them. ### See Also diff --git a/docs/Reference/VBRUN/AmbientProperties/ScaleUnits.md b/docs/Reference/VBRUN/AmbientProperties/ScaleUnits.md index 849acf8b..c112227b 100644 --- a/docs/Reference/VBRUN/AmbientProperties/ScaleUnits.md +++ b/docs/Reference/VBRUN/AmbientProperties/ScaleUnits.md @@ -13,7 +13,7 @@ Syntax: *object*.**ScaleUnits** *object* : *required* An object expression that evaluates to an **AmbientProperties** object. -Common values include `"Twip"`, `"Pixel"`, `"Inch"`, `"Centimeter"`, `"Millimeter"`, `"Point"`, and `"Character"`, but the container is free to return any string and to localise it for the current language. The value is a hint for display purposes — for example, in a status bar or a property sheet — and not a fixed enumeration that should be parsed. +Common values include `"Twip"`, `"Pixel"`, `"Inch"`, `"Centimeter"`, `"Millimeter"`, `"Point"`, and `"Character"`, but the container is free to return any string and to localise it for the current language. The value is a hint for display purposes --- for example, in a status bar or a property sheet --- and not a fixed enumeration that should be parsed. ### See Also diff --git a/docs/Reference/VBRUN/AmbientProperties/SupportsMnemonics.md b/docs/Reference/VBRUN/AmbientProperties/SupportsMnemonics.md index 2b1c56bc..9287c712 100644 --- a/docs/Reference/VBRUN/AmbientProperties/SupportsMnemonics.md +++ b/docs/Reference/VBRUN/AmbientProperties/SupportsMnemonics.md @@ -13,7 +13,7 @@ Syntax: *object*.**SupportsMnemonics** *object* : *required* An object expression that evaluates to an **AmbientProperties** object. -A mnemonic is the underlined letter in a caption such as `&File` — it gives the user a way to invoke the control with **Alt+F**. When **SupportsMnemonics** is **True**, the container forwards mnemonic keystrokes to the control; the control should then underline its mnemonic letter when displaying the caption. When the property is **False**, the host will not forward mnemonics, and the control should display its caption without underlining. +A mnemonic is the underlined letter in a caption such as `&File` --- it gives the user a way to invoke the control with **Alt+F**. When **SupportsMnemonics** is **True**, the container forwards mnemonic keystrokes to the control; the control should then underline its mnemonic letter when displaying the caption. When the property is **False**, the host will not forward mnemonics, and the control should display its caption without underlining. ### See Also diff --git a/docs/Reference/VBRUN/AmbientProperties/TextAlign.md b/docs/Reference/VBRUN/AmbientProperties/TextAlign.md index 30ed8997..a1ddc558 100644 --- a/docs/Reference/VBRUN/AmbientProperties/TextAlign.md +++ b/docs/Reference/VBRUN/AmbientProperties/TextAlign.md @@ -17,7 +17,7 @@ A control that displays text and does not have its own alignment explicitly set | Value | Meaning | |-------|--------------------------------------------------------| -| 0 | General — numeric values right-aligned, text left-aligned | +| 0 | General --- numeric values right-aligned, text left-aligned | | 1 | Left-aligned | | 2 | Centred | | 3 | Right-aligned | diff --git a/docs/Reference/VBRUN/AmbientProperties/UIDead.md b/docs/Reference/VBRUN/AmbientProperties/UIDead.md index 8286d776..0fc95d85 100644 --- a/docs/Reference/VBRUN/AmbientProperties/UIDead.md +++ b/docs/Reference/VBRUN/AmbientProperties/UIDead.md @@ -13,7 +13,7 @@ Syntax: *object*.**UIDead** *object* : *required* An object expression that evaluates to an **AmbientProperties** object. -The host sets **UIDead** to **True** when the application is in a state where it cannot meaningfully respond to user input — most commonly while execution is paused inside the debugger, but also during long modal operations. While **UIDead** is **True** a control should suppress animations, hover effects, and any input it would otherwise process, since the host's main thread cannot deliver a useful follow-up. +The host sets **UIDead** to **True** when the application is in a state where it cannot meaningfully respond to user input --- most commonly while execution is paused inside the debugger, but also during long modal operations. While **UIDead** is **True** a control should suppress animations, hover effects, and any input it would otherwise process, since the host's main thread cannot deliver a useful follow-up. ### See Also diff --git a/docs/Reference/VBRUN/AmbientProperties/UserMode.md b/docs/Reference/VBRUN/AmbientProperties/UserMode.md index 64fd5036..f4a49b7c 100644 --- a/docs/Reference/VBRUN/AmbientProperties/UserMode.md +++ b/docs/Reference/VBRUN/AmbientProperties/UserMode.md @@ -13,7 +13,7 @@ Syntax: *object*.**UserMode** *object* : *required* An object expression that evaluates to an **AmbientProperties** object. -This is the most-checked ambient property. A control should consult **UserMode** before doing anything that only makes sense at run time — connecting to a database, starting a timer, animating its own appearance — because at design time the host is showing a static representation of the control on a layout surface. When **UserMode** is **False**, the control should also be willing to draw selection adornments such as [**ShowGrabHandles**](ShowGrabHandles) and [**ShowHatching**](ShowHatching) on request. +This is the most-checked ambient property. A control should consult **UserMode** before doing anything that only makes sense at run time --- connecting to a database, starting a timer, animating its own appearance --- because at design time the host is showing a static representation of the control on a layout surface. When **UserMode** is **False**, the control should also be willing to draw selection adornments such as [**ShowGrabHandles**](ShowGrabHandles) and [**ShowHatching**](ShowHatching) on request. ### See Also diff --git a/docs/Reference/VBRUN/AmbientProperties/index.md b/docs/Reference/VBRUN/AmbientProperties/index.md index 0559e63f..88694807 100644 --- a/docs/Reference/VBRUN/AmbientProperties/index.md +++ b/docs/Reference/VBRUN/AmbientProperties/index.md @@ -10,7 +10,7 @@ has_toc: false # AmbientProperties class -The **AmbientProperties** object exposes information about the environment in which a control is hosted. The container — a form, a property page, the IDE designer surface — populates this object with hints about its appearance, locale, and operating mode so that an embedded control can adapt itself to fit in. Every property is read-only: the container, not the control, decides what these values should be. +The **AmbientProperties** object exposes information about the environment in which a control is hosted. The container --- a form, a property page, the IDE designer surface --- populates this object with hints about its appearance, locale, and operating mode so that an embedded control can adapt itself to fit in. Every property is read-only: the container, not the control, decides what these values should be. ## Detecting design-time versus run-time @@ -32,11 +32,11 @@ The container suggests a default colour scheme and typeface so that embedded con ## Layout and other UI hints -[**ScaleUnits**](ScaleUnits) names the unit of measure the container uses to size itself — for example `"Twip"` or `"Pixel"`. [**SupportsMnemonics**](SupportsMnemonics) is **True** when the container will dispatch keyboard mnemonics — the underlined letters following an `&` — to its controls. [**DisplayAsDefault**](DisplayAsDefault) is **True** if the container is treating this control as its default control, so the control can paint itself with a heavier border. [**MessageReflect**](MessageReflect) indicates whether the container reflects window messages addressed to the control back to the control's own message handler. +[**ScaleUnits**](ScaleUnits) names the unit of measure the container uses to size itself --- for example `"Twip"` or `"Pixel"`. [**SupportsMnemonics**](SupportsMnemonics) is **True** when the container will dispatch keyboard mnemonics --- the underlined letters following an `&` --- to its controls. [**DisplayAsDefault**](DisplayAsDefault) is **True** if the container is treating this control as its default control, so the control can paint itself with a heavier border. [**MessageReflect**](MessageReflect) indicates whether the container reflects window messages addressed to the control back to the control's own message handler. ## Locale and identity -[**LocaleID**](LocaleID) returns the Locale ID of the container, so a control can format text and numbers consistently with its host. [**DisplayName**](DisplayName) returns the name the container has assigned to the control — a useful string for error messages or property browsers. +[**LocaleID**](LocaleID) returns the Locale ID of the container, so a control can format text and numbers consistently with its host. [**DisplayName**](DisplayName) returns the name the container has assigned to the control --- a useful string for error messages or property browsers. ## Members diff --git a/docs/Reference/VBRUN/AsyncProperty/AsyncType.md b/docs/Reference/VBRUN/AsyncProperty/AsyncType.md index 90e5023b..43f9b156 100644 --- a/docs/Reference/VBRUN/AsyncProperty/AsyncType.md +++ b/docs/Reference/VBRUN/AsyncProperty/AsyncType.md @@ -15,9 +15,9 @@ Syntax: *object*.**AsyncType** The value mirrors the *AsyncType* argument passed to **UserControl.AsyncRead** when the read was started. It also determines the subtype of [**Value**](Value) once the read completes: -- `vbAsyncTypePicture` (0) — the data is being delivered as an **stdole.IPictureDisp**. -- `vbAsyncTypeFile` (1) — the data is being saved to a temporary file; **Value** holds its path as a **String**. -- `vbAsyncTypeByteArray` (2) — the data is being delivered as a **Byte** array. +- `vbAsyncTypePicture` (0) --- the data is being delivered as an **stdole.IPictureDisp**. +- `vbAsyncTypeFile` (1) --- the data is being saved to a temporary file; **Value** holds its path as a **String**. +- `vbAsyncTypeByteArray` (2) --- the data is being delivered as a **Byte** array. ### See Also diff --git a/docs/Reference/VBRUN/AsyncProperty/BytesMax.md b/docs/Reference/VBRUN/AsyncProperty/BytesMax.md index bb800287..cf8d683f 100644 --- a/docs/Reference/VBRUN/AsyncProperty/BytesMax.md +++ b/docs/Reference/VBRUN/AsyncProperty/BytesMax.md @@ -13,7 +13,7 @@ Syntax: *object*.**BytesMax** *object* : *required* An object expression that evaluates to an **AsyncProperty** object. -Used together with [**BytesRead**](BytesRead) to update a progress indicator during an **AsyncReadProgress** event. **BytesMax** can be zero when the server has not advertised a content length — for example with an HTTP chunked transfer — in which case the total size is not known until the read completes and a determinate progress bar cannot be shown. +Used together with [**BytesRead**](BytesRead) to update a progress indicator during an **AsyncReadProgress** event. **BytesMax** can be zero when the server has not advertised a content length --- for example with an HTTP chunked transfer --- in which case the total size is not known until the read completes and a determinate progress bar cannot be shown. ### See Also diff --git a/docs/Reference/VBRUN/AsyncProperty/PropertyName.md b/docs/Reference/VBRUN/AsyncProperty/PropertyName.md index 178164db..58c2db77 100644 --- a/docs/Reference/VBRUN/AsyncProperty/PropertyName.md +++ b/docs/Reference/VBRUN/AsyncProperty/PropertyName.md @@ -13,7 +13,7 @@ Syntax: *object*.**PropertyName** *object* : *required* An object expression that evaluates to an **AsyncProperty** object. -The value is the *PropertyName* argument that was passed to **UserControl.AsyncRead** when the read was started. A user control can have several reads in flight at once, so an event handler typically uses **PropertyName** in a **Select Case** to decide what to do with [**Value**](Value) when the read completes — for example, which property of the control to assign the result to. +The value is the *PropertyName* argument that was passed to **UserControl.AsyncRead** when the read was started. A user control can have several reads pending at once, so an event handler typically uses **PropertyName** in a **Select Case** to decide what to do with [**Value**](Value) when the read completes --- for example, which property of the control to assign the result to. ### See Also diff --git a/docs/Reference/VBRUN/AsyncProperty/Status.md b/docs/Reference/VBRUN/AsyncProperty/Status.md index a51b5bab..38c51a58 100644 --- a/docs/Reference/VBRUN/AsyncProperty/Status.md +++ b/docs/Reference/VBRUN/AsyncProperty/Status.md @@ -13,7 +13,7 @@ Syntax: *object*.**Status** *object* : *required* An object expression that evaluates to an **AsyncProperty** object. -The value is a short message such as `"Finding resource"`, `"Connecting"`, or `"Receiving response"`, suitable for display in a status bar or tooltip while the read is in progress. For programmatic logic, examine [**StatusCode**](StatusCode) instead — its values are stable, whereas **Status** is intended for human consumption and may be localised. +The value is a short message such as `"Finding resource"`, `"Connecting"`, or `"Receiving response"`, suitable for display in a status bar or tooltip while the read is in progress. For programmatic logic, examine [**StatusCode**](StatusCode) instead --- its values are stable, whereas **Status** is intended for human consumption and may be localised. ### See Also diff --git a/docs/Reference/VBRUN/AsyncProperty/StatusCode.md b/docs/Reference/VBRUN/AsyncProperty/StatusCode.md index 9c97b545..e76f9c9b 100644 --- a/docs/Reference/VBRUN/AsyncProperty/StatusCode.md +++ b/docs/Reference/VBRUN/AsyncProperty/StatusCode.md @@ -13,7 +13,7 @@ Syntax: *object*.**StatusCode** *object* : *required* An object expression that evaluates to an **AsyncProperty** object. -The value identifies the step the read is currently on — `vbAsyncStatusCodeFindingResource`, `vbAsyncStatusCodeConnecting`, `vbAsyncStatusCodeBeginDownloadData`, `vbAsyncStatusCodeEndDownloadData`, and so on. `vbAsyncStatusCodeError` (0) indicates that the read failed; the [**Status**](Status) property contains the matching human-readable description. +The value identifies the step the read is currently on --- `vbAsyncStatusCodeFindingResource`, `vbAsyncStatusCodeConnecting`, `vbAsyncStatusCodeBeginDownloadData`, `vbAsyncStatusCodeEndDownloadData`, and so on. `vbAsyncStatusCodeError` (0) indicates that the read failed; the [**Status**](Status) property contains the matching human-readable description. ### See Also diff --git a/docs/Reference/VBRUN/AsyncProperty/Target.md b/docs/Reference/VBRUN/AsyncProperty/Target.md index 993338d9..65d12505 100644 --- a/docs/Reference/VBRUN/AsyncProperty/Target.md +++ b/docs/Reference/VBRUN/AsyncProperty/Target.md @@ -13,7 +13,7 @@ Syntax: *object*.**Target** *object* : *required* An object expression that evaluates to an **AsyncProperty** object. -The value is the *Target* argument that was passed to **UserControl.AsyncRead** when the read was started — typically an absolute or relative URL, but local file paths are also accepted. It is the location the data is being fetched from, and remains the same across every **AsyncReadProgress** notification and the final **AsyncReadComplete** event for that read. +The value is the *Target* argument that was passed to **UserControl.AsyncRead** when the read was started --- typically an absolute or relative URL, but local file paths are also accepted. It is the location the data is being fetched from, and remains the same across every **AsyncReadProgress** notification and the final **AsyncReadComplete** event for that read. ### See Also diff --git a/docs/Reference/VBRUN/AsyncProperty/Value.md b/docs/Reference/VBRUN/AsyncProperty/Value.md index eb5fa552..a50ad265 100644 --- a/docs/Reference/VBRUN/AsyncProperty/Value.md +++ b/docs/Reference/VBRUN/AsyncProperty/Value.md @@ -13,11 +13,11 @@ Syntax: *object*.**Value** *object* : *required* An object expression that evaluates to an **AsyncProperty** object. -**Value** is only meaningful in the **AsyncReadComplete** event — during a progress notification the read has not yet finished. The concrete subtype of **Value** is determined by [**AsyncType**](AsyncType): +**Value** is only meaningful in the **AsyncReadComplete** event --- during a progress notification the read has not yet finished. The concrete subtype of **Value** is determined by [**AsyncType**](AsyncType): -- `vbAsyncTypePicture` — an **stdole.IPictureDisp**, which can be assigned to a **Picture** property. -- `vbAsyncTypeFile` — a **String** holding the path of a temporary file containing the downloaded data. -- `vbAsyncTypeByteArray` — a **Byte** array (`Byte()`) holding the raw bytes. +- `vbAsyncTypePicture` --- an **stdole.IPictureDisp**, which can be assigned to a **Picture** property. +- `vbAsyncTypeFile` --- a **String** holding the path of a temporary file containing the downloaded data. +- `vbAsyncTypeByteArray` --- a **Byte** array (`Byte()`) holding the raw bytes. ### See Also diff --git a/docs/Reference/VBRUN/AsyncProperty/index.md b/docs/Reference/VBRUN/AsyncProperty/index.md index e5e39854..0a0ef79f 100644 --- a/docs/Reference/VBRUN/AsyncProperty/index.md +++ b/docs/Reference/VBRUN/AsyncProperty/index.md @@ -10,11 +10,11 @@ has_toc: false # AsyncProperty class -The **AsyncProperty** object holds the results of an asynchronous read started with **UserControl.AsyncRead**. It is passed to the **AsyncReadComplete** and **AsyncReadProgress** events, where it identifies which read this notification refers to, reports how far the download has got, and — once complete — supplies the downloaded value. Every property is read-only: the runtime fills the object in before raising the event. +The **AsyncProperty** object holds the results of an asynchronous read started with **UserControl.AsyncRead**. It is passed to the **AsyncReadComplete** and **AsyncReadProgress** events, where it identifies which read this notification refers to, reports how far the download has got, and --- once complete --- supplies the downloaded value. Every property is read-only: the runtime fills the object in before raising the event. ## Identifying the read -A user control may have several outstanding asynchronous reads at once, so the **AsyncProperty** passed to each event has to identify the one the event is for. [**PropertyName**](PropertyName) returns the name supplied to **AsyncRead** when the request was started — typically the name of the property the control is going to assign the value to. [**Target**](Target) returns the URL or file path that was being downloaded. [**AsyncType**](AsyncType) returns an **AsyncTypeConstants** value identifying how the data is being delivered — as a picture, a file, or a byte array. +A user control may have several outstanding asynchronous reads at once, so the **AsyncProperty** passed to each event has to identify the one the event is for. [**PropertyName**](PropertyName) returns the name supplied to **AsyncRead** when the request was started --- typically the name of the property the control is going to assign the value to. [**Target**](Target) returns the URL or file path that was being downloaded. [**AsyncType**](AsyncType) returns an **AsyncTypeConstants** value identifying how the data is being delivered --- as a picture, a file, or a byte array. ```tb Private Sub UserControl_AsyncReadComplete(ByVal Prop As AsyncProperty) @@ -29,11 +29,11 @@ End Sub ## The downloaded value -Once the read finishes, [**Value**](Value) holds the result. Its concrete subtype is determined by **AsyncType**: an **stdole.IPictureDisp** when the data was requested as a picture, a **String** containing the path of a downloaded temporary file when it was requested as a file, or a **Byte** array when the raw bytes were requested. **Value** is only meaningful in the **AsyncReadComplete** event — during a progress notification the read has not yet finished. +Once the read finishes, [**Value**](Value) holds the result. Its concrete subtype is determined by **AsyncType**: an **stdole.IPictureDisp** when the data was requested as a picture, a **String** containing the path of a downloaded temporary file when it was requested as a file, or a **Byte** array when the raw bytes were requested. **Value** is only meaningful in the **AsyncReadComplete** event --- during a progress notification the read has not yet finished. ## Tracking progress -While a read is in flight, the runtime raises **AsyncReadProgress** periodically so the control can update a progress indicator. [**BytesRead**](BytesRead) reports how many bytes have arrived so far, and [**BytesMax**](BytesMax) the total number expected — though **BytesMax** may be zero when the server has not advertised a content length. [**Status**](Status) returns a human-readable description of the current step ("Connecting", "Receiving response", and so on), and [**StatusCode**](StatusCode) returns the corresponding **AsyncStatusCodeConstants** value for programmatic inspection. +While a read is in progress, the runtime raises **AsyncReadProgress** periodically so the control can update a progress indicator. [**BytesRead**](BytesRead) reports how many bytes have arrived so far, and [**BytesMax**](BytesMax) the total number expected --- though **BytesMax** may be zero when the server has not advertised a content length. [**Status**](Status) returns a human-readable description of the current step ("Connecting", "Receiving response", and so on), and [**StatusCode**](StatusCode) returns the corresponding **AsyncStatusCodeConstants** value for programmatic inspection. ## Members diff --git a/docs/Reference/VBRUN/Constants/AlignConstants.md b/docs/Reference/VBRUN/Constants/AlignConstants.md index 70f8750b..86a0867e 100644 --- a/docs/Reference/VBRUN/Constants/AlignConstants.md +++ b/docs/Reference/VBRUN/Constants/AlignConstants.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/VBRUN/Constants/AlignConstants # AlignConstants {: .no_toc } -Values for the **Align** property of forms and controls — picture boxes, data controls, and toolbars — that anchor a control to one edge of its container. +Values for the **Align** property of forms and controls --- picture boxes, data controls, and toolbars --- that anchor a control to one edge of its container. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/VBRUN/Constants/AlignmentConstantsNoCenter.md b/docs/Reference/VBRUN/Constants/AlignmentConstantsNoCenter.md index 3979f6ea..46369402 100644 --- a/docs/Reference/VBRUN/Constants/AlignmentConstantsNoCenter.md +++ b/docs/Reference/VBRUN/Constants/AlignmentConstantsNoCenter.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/VBRUN/Constants/AlignmentConstantsNoCenter # AlignmentConstantsNoCenter {: .no_toc } -Text alignment values for properties whose appearance does not include a centred option — for example, scroll-bar–aligned values or text fields that only support left/right justification. +Text alignment values for properties whose appearance does not include a centred option --- for example, scroll-bar--aligned values or text fields that only support left/right justification. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/VBRUN/Constants/ApplicationStartConstants.md b/docs/Reference/VBRUN/Constants/ApplicationStartConstants.md index c371c129..c51b0e3a 100644 --- a/docs/Reference/VBRUN/Constants/ApplicationStartConstants.md +++ b/docs/Reference/VBRUN/Constants/ApplicationStartConstants.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/VBRUN/Constants/ApplicationStartConstants # ApplicationStartConstants {: .no_toc } -Mode values reported by the application's start-up logic — whether it was launched as a stand-alone program or invoked via Automation by another application. +Mode values reported by the application's start-up logic --- whether it was launched as a stand-alone program or invoked via Automation by another application. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/VBRUN/Constants/BackFillStyleConstants.md b/docs/Reference/VBRUN/Constants/BackFillStyleConstants.md index 083009dd..dd53054b 100644 --- a/docs/Reference/VBRUN/Constants/BackFillStyleConstants.md +++ b/docs/Reference/VBRUN/Constants/BackFillStyleConstants.md @@ -11,5 +11,5 @@ Whether a control's background fill is opaque or transparent. | Constant | Value | Description | |----------|-------|-------------| -| **vbBFTransparent**{: #vbBFTransparent } | 0 | The background of the control is transparent — whatever is behind it shows through. | +| **vbBFTransparent**{: #vbBFTransparent } | 0 | The background of the control is transparent --- whatever is behind it shows through. | | **vbBFOpaque**{: #vbBFOpaque } | 1 | The background of the control is filled solidly with its **BackColor**. | diff --git a/docs/Reference/VBRUN/Constants/ColorConstants.md b/docs/Reference/VBRUN/Constants/ColorConstants.md index 2b22f452..7d333dba 100644 --- a/docs/Reference/VBRUN/Constants/ColorConstants.md +++ b/docs/Reference/VBRUN/Constants/ColorConstants.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/VBRUN/Constants/ColorConstants # ColorConstants {: .no_toc } -Common named RGB colour values, suitable wherever a colour is supplied as a **Long** or **OLE_COLOR**. The numeric values follow the GDI byte order — `&H00BBGGRR`. +Common named RGB colour values, suitable wherever a colour is supplied as a **Long** or **OLE_COLOR**. The numeric values follow the GDI byte order --- `&H00BBGGRR`. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/VBRUN/Constants/ControlTypeConstants.md b/docs/Reference/VBRUN/Constants/ControlTypeConstants.md index 950b79f8..9f023825 100644 --- a/docs/Reference/VBRUN/Constants/ControlTypeConstants.md +++ b/docs/Reference/VBRUN/Constants/ControlTypeConstants.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/VBRUN/Constants/ControlTypeConstants # ControlTypeConstants {: .no_toc } -Identifiers for the standard intrinsic and bundled control types, used by runtime introspection — for example by code that inspects the contents of a form's **Controls** collection. +Identifiers for the standard intrinsic and bundled control types, used by runtime introspection --- for example by code that inspects the contents of a form's **Controls** collection. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/VBRUN/Constants/DrawModeConstants.md b/docs/Reference/VBRUN/Constants/DrawModeConstants.md index eb604b52..8a007c41 100644 --- a/docs/Reference/VBRUN/Constants/DrawModeConstants.md +++ b/docs/Reference/VBRUN/Constants/DrawModeConstants.md @@ -21,7 +21,7 @@ GDI raster-operation values for the **DrawMode** property, controlling how the p | **vbNotMaskPen**{: #vbNotMaskPen } | 8 | Inverse of **vbMaskPen**. | | **vbMaskPen**{: #vbMaskPen } | 9 | Combination of the colours common to both the pen and the screen. | | **vbNotXorPen**{: #vbNotXorPen } | 10 | Inverse of **vbXorPen**. | -| **vbNop**{: #vbNop } | 11 | No drawing — the screen is left unchanged. | +| **vbNop**{: #vbNop } | 11 | No drawing --- the screen is left unchanged. | | **vbMergeNotPen**{: #vbMergeNotPen } | 12 | Combination of the screen and the inverse of the pen. | | **vbCopyPen**{: #vbCopyPen } | 13 | Output is the pen colour (the default). | | **vbMergePenNot**{: #vbMergePenNot } | 14 | Combination of the pen and the inverse of the screen. | diff --git a/docs/Reference/VBRUN/Constants/FillStyleConstants.md b/docs/Reference/VBRUN/Constants/FillStyleConstants.md index ce61f772..6e02eb5c 100644 --- a/docs/Reference/VBRUN/Constants/FillStyleConstants.md +++ b/docs/Reference/VBRUN/Constants/FillStyleConstants.md @@ -12,7 +12,7 @@ Pattern values for the **FillStyle** property of forms, picture boxes, and shape | Constant | Value | Description | |----------|-------|-------------| | **vbFSSolid**{: #vbFSSolid } | 0 | Solid fill in **FillColor**. | -| **vbFSTransparent**{: #vbFSTransparent } | 1 | No fill — the background shows through. | +| **vbFSTransparent**{: #vbFSTransparent } | 1 | No fill --- the background shows through. | | **vbHorizontalLine**{: #vbHorizontalLine } | 2 | Horizontal lines. | | **vbVerticalLine**{: #vbVerticalLine } | 3 | Vertical lines. | | **vbUpwardDiagonal**{: #vbUpwardDiagonal } | 4 | Upward-sloping diagonal lines. | diff --git a/docs/Reference/VBRUN/Constants/FillStyleConstantsEx.md b/docs/Reference/VBRUN/Constants/FillStyleConstantsEx.md index aa01ff17..2a0c741d 100644 --- a/docs/Reference/VBRUN/Constants/FillStyleConstantsEx.md +++ b/docs/Reference/VBRUN/Constants/FillStyleConstantsEx.md @@ -12,12 +12,12 @@ Extended fill-pattern values for controls that support twinBASIC's gradient fill | Constant | Value | Description | |----------|-------|-------------| | **vbFSSolid**{: #vbFSSolid } | 0 | Solid fill in **FillColor**. | -| **vbFSTransparent**{: #vbFSTransparent } | 1 | No fill — the background shows through. | +| **vbFSTransparent**{: #vbFSTransparent } | 1 | No fill --- the background shows through. | | **vbHorizontalLine**{: #vbHorizontalLine } | 2 | Horizontal lines. | | **vbVerticalLine**{: #vbVerticalLine } | 3 | Vertical lines. | | **vbUpwardDiagonal**{: #vbUpwardDiagonal } | 4 | Upward-sloping diagonal lines. | | **vbDownwardDiagonal**{: #vbDownwardDiagonal } | 5 | Downward-sloping diagonal lines. | | **vbCross**{: #vbCross } | 6 | Crossed horizontal and vertical lines. | | **vbDiagonalCross**{: #vbDiagonalCross } | 7 | Crossed diagonal lines. | -| **vbGradientNS**{: #vbGradientNS } | 8 | Vertical (north–south) linear gradient. *(twinBASIC addition.)* | -| **vbGradientWE**{: #vbGradientWE } | 9 | Horizontal (west–east) linear gradient. *(twinBASIC addition.)* | +| **vbGradientNS**{: #vbGradientNS } | 8 | Vertical (north--south) linear gradient. *(twinBASIC addition.)* | +| **vbGradientWE**{: #vbGradientWE } | 9 | Horizontal (west--east) linear gradient. *(twinBASIC addition.)* | diff --git a/docs/Reference/VBRUN/Constants/KeyCodeConstants.md b/docs/Reference/VBRUN/Constants/KeyCodeConstants.md index 6da17bc1..24f467b2 100644 --- a/docs/Reference/VBRUN/Constants/KeyCodeConstants.md +++ b/docs/Reference/VBRUN/Constants/KeyCodeConstants.md @@ -58,19 +58,19 @@ Virtual-key codes reported in the *KeyCode* argument of **KeyDown** and **KeyUp* | Constant | Value | Description | |----------|-------|-------------| -| **vbKeyA**{: #vbKeyA } – **vbKeyZ**{: #vbKeyZ } | 65 – 90 | The letters **A** through **Z**. | +| **vbKeyA**{: #vbKeyA } -- **vbKeyZ**{: #vbKeyZ } | 65 -- 90 | The letters **A** through **Z**. | ## Number keys | Constant | Value | Description | |----------|-------|-------------| -| **vbKey0**{: #vbKey0 } – **vbKey9**{: #vbKey9 } | 48 – 57 | The digits **0** through **9** on the main keyboard. | +| **vbKey0**{: #vbKey0 } -- **vbKey9**{: #vbKey9 } | 48 -- 57 | The digits **0** through **9** on the main keyboard. | ## Numeric keypad | Constant | Value | Description | |----------|-------|-------------| -| **vbKeyNumpad0**{: #vbKeyNumpad0 } – **vbKeyNumpad9**{: #vbKeyNumpad9 } | 96 – 105 | The digits **0** through **9** on the numeric keypad. | +| **vbKeyNumpad0**{: #vbKeyNumpad0 } -- **vbKeyNumpad9**{: #vbKeyNumpad9 } | 96 -- 105 | The digits **0** through **9** on the numeric keypad. | | **vbKeyMultiply**{: #vbKeyMultiply } | 106 | **\*** on the numeric keypad. | | **vbKeyAdd**{: #vbKeyAdd } | 107 | **+** on the numeric keypad. | | **vbKeySeparator**{: #vbKeySeparator } | 108 | Numeric-keypad separator. | @@ -82,4 +82,4 @@ Virtual-key codes reported in the *KeyCode* argument of **KeyDown** and **KeyUp* | Constant | Value | Description | |----------|-------|-------------| -| **vbKeyF1**{: #vbKeyF1 } – **vbKeyF16**{: #vbKeyF16 } | 112 – 127 | The function keys **F1** through **F16**. | +| **vbKeyF1**{: #vbKeyF1 } -- **vbKeyF16**{: #vbKeyF16 } | 112 -- 127 | The function keys **F1** through **F16**. | diff --git a/docs/Reference/VBRUN/Constants/MenuAccelConstants.md b/docs/Reference/VBRUN/Constants/MenuAccelConstants.md index 7122bbf9..e5b2e8be 100644 --- a/docs/Reference/VBRUN/Constants/MenuAccelConstants.md +++ b/docs/Reference/VBRUN/Constants/MenuAccelConstants.md @@ -13,13 +13,13 @@ Keyboard-accelerator codes for the **Shortcut** property of menu items, identify | Constant | Value | Description | |----------|-------|-------------| -| **vbMenuAccelCtrlA**{: #vbMenuAccelCtrlA } – **vbMenuAccelCtrlZ**{: #vbMenuAccelCtrlZ } | 1 – 26 | **Ctrl** + **A** through **Ctrl** + **Z**. | +| **vbMenuAccelCtrlA**{: #vbMenuAccelCtrlA } -- **vbMenuAccelCtrlZ**{: #vbMenuAccelCtrlZ } | 1 -- 26 | **Ctrl** + **A** through **Ctrl** + **Z**. | ## Function keys | Constant | Value | Description | |----------|-------|-------------| -| **vbMenuAccelF1**{: #vbMenuAccelF1 } – **vbMenuAccelF9**{: #vbMenuAccelF9 } | 27 – 35 | **F1** through **F9**. | +| **vbMenuAccelF1**{: #vbMenuAccelF1 } -- **vbMenuAccelF9**{: #vbMenuAccelF9 } | 27 -- 35 | **F1** through **F9**. | | **vbMenuAccelF11**{: #vbMenuAccelF11 } | 36 | **F11**. | | **vbMenuAccelF12**{: #vbMenuAccelF12 } | 37 | **F12**. | @@ -27,7 +27,7 @@ Keyboard-accelerator codes for the **Shortcut** property of menu items, identify | Constant | Value | Description | |----------|-------|-------------| -| **vbMenuAccelCtrlF1**{: #vbMenuAccelCtrlF1 } – **vbMenuAccelCtrlF9**{: #vbMenuAccelCtrlF9 } | 38 – 46 | **Ctrl** + **F1** through **Ctrl** + **F9**. | +| **vbMenuAccelCtrlF1**{: #vbMenuAccelCtrlF1 } -- **vbMenuAccelCtrlF9**{: #vbMenuAccelCtrlF9 } | 38 -- 46 | **Ctrl** + **F1** through **Ctrl** + **F9**. | | **vbMenuAccelCtrlF11**{: #vbMenuAccelCtrlF11 } | 47 | **Ctrl** + **F11**. | | **vbMenuAccelCtrlF12**{: #vbMenuAccelCtrlF12 } | 48 | **Ctrl** + **F12**. | @@ -37,7 +37,7 @@ Keyboard-accelerator codes for the **Shortcut** property of menu items, identify |----------|-------|-------------| | **vbMenuAccelShiftF1**{: #vbMenuAccelShiftF1 } | 49 | **Shift** + **F1**. | | **vbMenuAccelShfitF2**{: #vbMenuAccelShfitF2 } | 50 | **Shift** + **F2**. *(Spelling preserved as in source.)* | -| **vbMenuAccelShiftF3**{: #vbMenuAccelShiftF3 } – **vbMenuAccelShiftF9**{: #vbMenuAccelShiftF9 } | 51 – 57 | **Shift** + **F3** through **Shift** + **F9**. | +| **vbMenuAccelShiftF3**{: #vbMenuAccelShiftF3 } -- **vbMenuAccelShiftF9**{: #vbMenuAccelShiftF9 } | 51 -- 57 | **Shift** + **F3** through **Shift** + **F9**. | | **vbMenuAccelShiftF11**{: #vbMenuAccelShiftF11 } | 58 | **Shift** + **F11**. | | **vbMenuAccelShiftF12**{: #vbMenuAccelShiftF12 } | 59 | **Shift** + **F12**. | @@ -45,7 +45,7 @@ Keyboard-accelerator codes for the **Shortcut** property of menu items, identify | Constant | Value | Description | |----------|-------|-------------| -| **vbMenuAccelShiftCtrlF1**{: #vbMenuAccelShiftCtrlF1 } – **vbMenuAccelShiftCtrlF9**{: #vbMenuAccelShiftCtrlF9 } | 60 – 68 | **Shift** + **Ctrl** + **F1** through **Shift** + **Ctrl** + **F9**. | +| **vbMenuAccelShiftCtrlF1**{: #vbMenuAccelShiftCtrlF1 } -- **vbMenuAccelShiftCtrlF9**{: #vbMenuAccelShiftCtrlF9 } | 60 -- 68 | **Shift** + **Ctrl** + **F1** through **Shift** + **Ctrl** + **F9**. | | **vbMenuAccelShiftCtrlF11**{: #vbMenuAccelShiftCtrlF11 } | 69 | **Shift** + **Ctrl** + **F11**. | | **vbMenuAccelShiftCtrlF12**{: #vbMenuAccelShiftCtrlF12 } | 70 | **Shift** + **Ctrl** + **F12**. | diff --git a/docs/Reference/VBRUN/Constants/MousePointerConstants.md b/docs/Reference/VBRUN/Constants/MousePointerConstants.md index df6e3391..69d63542 100644 --- a/docs/Reference/VBRUN/Constants/MousePointerConstants.md +++ b/docs/Reference/VBRUN/Constants/MousePointerConstants.md @@ -13,7 +13,7 @@ Cursor-shape values for the **MousePointer** property of forms and controls. | Constant | Value | Description | |----------|-------|-------------| -| **vbDefault**{: #vbDefault } | 0 | The default — usually an arrow. | +| **vbDefault**{: #vbDefault } | 0 | The default --- usually an arrow. | | **vbArrow**{: #vbArrow } | 1 | Arrow. | | **vbCrosshair**{: #vbCrosshair } | 2 | Crosshair. | | **vbIbeam**{: #vbIbeam } | 3 | I-beam (text-edit cursor). | @@ -43,8 +43,8 @@ Cursor-shape values for the **MousePointer** property of forms and controls. | **vbScrollS**{: #vbScrollS } | 21 | Auto-scroll arrow pointing south. | | **vbScrollE**{: #vbScrollE } | 22 | Auto-scroll arrow pointing east. | | **vbScrollW**{: #vbScrollW } | 23 | Auto-scroll arrow pointing west. | -| **vbScrollNS**{: #vbScrollNS } | 24 | Auto-scroll arrow pointing north–south. | -| **vbScrollWE**{: #vbScrollWE } | 25 | Auto-scroll arrow pointing west–east. | +| **vbScrollNS**{: #vbScrollNS } | 24 | Auto-scroll arrow pointing north--south. | +| **vbScrollWE**{: #vbScrollWE } | 25 | Auto-scroll arrow pointing west--east. | | **vbScrollNW**{: #vbScrollNW } | 26 | Auto-scroll arrow pointing north-west. | | **vbScrollNE**{: #vbScrollNE } | 27 | Auto-scroll arrow pointing north-east. | | **vbScrollSW**{: #vbScrollSW } | 28 | Auto-scroll arrow pointing south-west. | diff --git a/docs/Reference/VBRUN/Constants/OLEContainerConstants.md b/docs/Reference/VBRUN/Constants/OLEContainerConstants.md index 0d70f756..9f874808 100644 --- a/docs/Reference/VBRUN/Constants/OLEContainerConstants.md +++ b/docs/Reference/VBRUN/Constants/OLEContainerConstants.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/VBRUN/Constants/OLEContainerConstants # OLEContainerConstants {: .no_toc } -A combined enumeration containing every option value used by the **OLE** container control. Each logical group of values has a more specific enumeration of its own — see the See Also section — but **OLEContainerConstants** retains all of the original VB6 names so existing code continues to compile. +A combined enumeration containing every option value used by the **OLE** container control. Each logical group of values has a more specific enumeration of its own --- see the See Also section --- but **OLEContainerConstants** retains all of the original VB6 names so existing code continues to compile. ## OLE type diff --git a/docs/Reference/VBRUN/Constants/OLEDropEffectConstants.md b/docs/Reference/VBRUN/Constants/OLEDropEffectConstants.md index e463f70a..3b4dd6e6 100644 --- a/docs/Reference/VBRUN/Constants/OLEDropEffectConstants.md +++ b/docs/Reference/VBRUN/Constants/OLEDropEffectConstants.md @@ -13,7 +13,7 @@ Bit flags for the *Effect* argument of OLE drag-and-drop events, controlling wha |----------|-------|-------------| | **vbDropEffectNone**{: #vbDropEffectNone } | 0 | The drop is not allowed. | | **vbDropEffectCopy**{: #vbDropEffectCopy } | 1 | The data should be copied to the target. | -| **vbDropEffectMove**{: #vbDropEffectMove } | 2 | The data should be moved to the target — the source removes it after a successful drop. | +| **vbDropEffectMove**{: #vbDropEffectMove } | 2 | The data should be moved to the target --- the source removes it after a successful drop. | | **vbDropEffectLink**{: #vbDropEffectLink } | 4 | A link to the data should be created at the target. *(twinBASIC addition.)* | | **vbDropEffectScroll**{: #vbDropEffectScroll } | -2147483648 | The target is scrolling because the cursor is near its edge. | diff --git a/docs/Reference/VBRUN/Constants/PrinterObjectConstants.md b/docs/Reference/VBRUN/Constants/PrinterObjectConstants.md index 036abfad..5e2c1bbe 100644 --- a/docs/Reference/VBRUN/Constants/PrinterObjectConstants.md +++ b/docs/Reference/VBRUN/Constants/PrinterObjectConstants.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/VBRUN/Constants/PrinterObjectConstants # PrinterObjectConstants {: .no_toc } -A combined enumeration containing every option value used by the **Printer** object — colour mode, duplex mode, orientation, paper bin, paper size, and print quality. Each logical group also has a more specific enumeration of its own — see the See Also section. +A combined enumeration containing every option value used by the **Printer** object --- colour mode, duplex mode, orientation, paper bin, paper size, and print quality. Each logical group also has a more specific enumeration of its own --- see the See Also section. ## Colour mode diff --git a/docs/Reference/VBRUN/Constants/RecordsetTypeConstants.md b/docs/Reference/VBRUN/Constants/RecordsetTypeConstants.md index 1ae08494..e8c71960 100644 --- a/docs/Reference/VBRUN/Constants/RecordsetTypeConstants.md +++ b/docs/Reference/VBRUN/Constants/RecordsetTypeConstants.md @@ -11,6 +11,6 @@ Recordset-type values for the **RecordsetType** property of a Data control. | Constant | Value | Description | |----------|-------|-------------| -| **vbRSTypeTable**{: #vbRSTypeTable } | 0 | A table-type recordset — direct read/write access to a single table. | -| **vbRSTypeDynaset**{: #vbRSTypeDynaset } | 1 | A dynaset-type recordset — an updatable, dynamic view of a query result. | -| **vbRSTypeSnapShot**{: #vbRSTypeSnapShot } | 2 | A snapshot-type recordset — a read-only fixed copy of a query result. | +| **vbRSTypeTable**{: #vbRSTypeTable } | 0 | A table-type recordset --- direct read/write access to a single table. | +| **vbRSTypeDynaset**{: #vbRSTypeDynaset } | 1 | A dynaset-type recordset --- an updatable, dynamic view of a query result. | +| **vbRSTypeSnapShot**{: #vbRSTypeSnapShot } | 2 | A snapshot-type recordset --- a read-only fixed copy of a query result. | diff --git a/docs/Reference/VBRUN/Constants/ScaleModeConstants.md b/docs/Reference/VBRUN/Constants/ScaleModeConstants.md index 98c00b42..dfe8c785 100644 --- a/docs/Reference/VBRUN/Constants/ScaleModeConstants.md +++ b/docs/Reference/VBRUN/Constants/ScaleModeConstants.md @@ -13,13 +13,13 @@ Measurement-unit values for the **ScaleMode** property of forms and containers, |----------|-------|-------------| | **vbScaledPixels**{: #vbScaledPixels } | -1 | Pixels, scaled by the system DPI factor. *(twinBASIC addition.)* | | **vbUser**{: #vbUser } | 0 | A user-defined coordinate system set explicitly with **Scale**. | -| **vbTwips**{: #vbTwips } | 1 | Twips — 1/1440 inch (the default). | -| **vbPoints**{: #vbPoints } | 2 | Points — 1/72 inch. | +| **vbTwips**{: #vbTwips } | 1 | Twips --- 1/1440 inch (the default). | +| **vbPoints**{: #vbPoints } | 2 | Points --- 1/72 inch. | | **vbPixels**{: #vbPixels } | 3 | Pixels of the underlying device. | | **vbCharacters**{: #vbCharacters } | 4 | Characters of the current font (12 horizontal, 24 vertical points). | | **vbInches**{: #vbInches } | 5 | Inches. | | **vbMillimeters**{: #vbMillimeters } | 6 | Millimetres. | | **vbCentimeters**{: #vbCentimeters } | 7 | Centimetres. | -| **vbHimetric**{: #vbHimetric } | 8 | HiMetric units — 0.01 millimetre. | +| **vbHimetric**{: #vbHimetric } | 8 | HiMetric units --- 0.01 millimetre. | | **vbContainerPosition**{: #vbContainerPosition } | 9 | The container's coordinates, used for positioning. | | **vbContainerSize**{: #vbContainerSize } | 10 | The container's coordinates, used for sizing. | diff --git a/docs/Reference/VBRUN/Constants/ShortcutConstants.md b/docs/Reference/VBRUN/Constants/ShortcutConstants.md index dcdc9d3b..825c088e 100644 --- a/docs/Reference/VBRUN/Constants/ShortcutConstants.md +++ b/docs/Reference/VBRUN/Constants/ShortcutConstants.md @@ -19,13 +19,13 @@ Shortcut-key identifiers for menu items, used by the menu editor and the runtime | Constant | Value | Description | |----------|-------|-------------| -| **vbShortcutCtrlA**{: #vbShortcutCtrlA } – **vbShortcutCtrlZ**{: #vbShortcutCtrlZ } | 1 – 26 | **Ctrl** + **A** through **Ctrl** + **Z**. | +| **vbShortcutCtrlA**{: #vbShortcutCtrlA } -- **vbShortcutCtrlZ**{: #vbShortcutCtrlZ } | 1 -- 26 | **Ctrl** + **A** through **Ctrl** + **Z**. | ## Function keys | Constant | Value | Description | |----------|-------|-------------| -| **vbShortcutF1**{: #vbShortcutF1 } – **vbShortcutF9**{: #vbShortcutF9 } | 27 – 35 | **F1** through **F9**. | +| **vbShortcutF1**{: #vbShortcutF1 } -- **vbShortcutF9**{: #vbShortcutF9 } | 27 -- 35 | **F1** through **F9**. | | **vbShortcutF11**{: #vbShortcutF11 } | 36 | **F11**. | | **vbShortcutF12**{: #vbShortcutF12 } | 37 | **F12**. | @@ -33,7 +33,7 @@ Shortcut-key identifiers for menu items, used by the menu editor and the runtime | Constant | Value | Description | |----------|-------|-------------| -| **vbShortcutShiftF1**{: #vbShortcutShiftF1 } – **vbShortcutShiftF9**{: #vbShortcutShiftF9 } | 38 – 46 | **Shift** + **F1** through **Shift** + **F9**. | +| **vbShortcutShiftF1**{: #vbShortcutShiftF1 } -- **vbShortcutShiftF9**{: #vbShortcutShiftF9 } | 38 -- 46 | **Shift** + **F1** through **Shift** + **F9**. | | **vbShortcutShiftF11**{: #vbShortcutShiftF11 } | 47 | **Shift** + **F11**. | | **vbShortcutShiftF12**{: #vbShortcutShiftF12 } | 48 | **Shift** + **F12**. | @@ -41,7 +41,7 @@ Shortcut-key identifiers for menu items, used by the menu editor and the runtime | Constant | Value | Description | |----------|-------|-------------| -| **vbShortcutCtrlF1**{: #vbShortcutCtrlF1 } – **vbShortcutCtrlF9**{: #vbShortcutCtrlF9 } | 49 – 57 | **Ctrl** + **F1** through **Ctrl** + **F9**. | +| **vbShortcutCtrlF1**{: #vbShortcutCtrlF1 } -- **vbShortcutCtrlF9**{: #vbShortcutCtrlF9 } | 49 -- 57 | **Ctrl** + **F1** through **Ctrl** + **F9**. | | **vbShortcutCtrlF11**{: #vbShortcutCtrlF11 } | 58 | **Ctrl** + **F11**. | | **vbShortcutCtrlF12**{: #vbShortcutCtrlF12 } | 59 | **Ctrl** + **F12**. | @@ -49,7 +49,7 @@ Shortcut-key identifiers for menu items, used by the menu editor and the runtime | Constant | Value | Description | |----------|-------|-------------| -| **vbShortcutShiftCtrlF1**{: #vbShortcutShiftCtrlF1 } – **vbShortcutShiftCtrlF9**{: #vbShortcutShiftCtrlF9 } | 60 – 68 | **Shift** + **Ctrl** + **F1** through **Shift** + **Ctrl** + **F9**. | +| **vbShortcutShiftCtrlF1**{: #vbShortcutShiftCtrlF1 } -- **vbShortcutShiftCtrlF9**{: #vbShortcutShiftCtrlF9 } | 60 -- 68 | **Shift** + **Ctrl** + **F1** through **Shift** + **Ctrl** + **F9**. | | **vbShortcutShiftCtrlF11**{: #vbShortcutShiftCtrlF11 } | 69 | **Shift** + **Ctrl** + **F11**. | | **vbShortcutShiftCtrlF12**{: #vbShortcutShiftCtrlF12 } | 70 | **Shift** + **Ctrl** + **F12**. | diff --git a/docs/Reference/VBRUN/Constants/StorageTypeContants.md b/docs/Reference/VBRUN/Constants/StorageTypeContants.md index 3c91852f..d703eb3f 100644 --- a/docs/Reference/VBRUN/Constants/StorageTypeContants.md +++ b/docs/Reference/VBRUN/Constants/StorageTypeContants.md @@ -10,7 +10,7 @@ permalink: /tB/Packages/VBRUN/Constants/StorageTypeContants OLE data-storage medium identifiers used by [**DataObjectFormat.StorageType**](../DataObject/DataObjectFormat#storagetype) and other low-level data-transfer routines, identifying how the bytes are physically stored. > [!NOTE] -> The enum is named `StorageTypeContants` (note the missing `s`) in the runtime — a long-standing VB6 holdover that twinBASIC preserves for source compatibility. +> The enum is named `StorageTypeContants` (note the missing `s`) in the runtime --- a long-standing VB6 holdover that twinBASIC preserves for source compatibility. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/VBRUN/Constants/SystemColorConstants.md b/docs/Reference/VBRUN/Constants/SystemColorConstants.md index ef0cc227..734a5f12 100644 --- a/docs/Reference/VBRUN/Constants/SystemColorConstants.md +++ b/docs/Reference/VBRUN/Constants/SystemColorConstants.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/VBRUN/Constants/SystemColorConstants # SystemColorConstants {: .no_toc } -Reference values for system palette entries — the colours the user has chosen for various standard parts of the Windows UI. Values have the high bit set so that the runtime can distinguish them from RGB colours; pass them through [**TranslateColor**](../../../Modules/Information/TranslateColor) to obtain a plain RGB value. +Reference values for system palette entries --- the colours the user has chosen for various standard parts of the Windows UI. Values have the high bit set so that the runtime can distinguish them from RGB colours; pass them through [**TranslateColor**](../../../Modules/Information/TranslateColor) to obtain a plain RGB value. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/VBRUN/Constants/index.md b/docs/Reference/VBRUN/Constants/index.md index bfdbe6c9..5d02149c 100644 --- a/docs/Reference/VBRUN/Constants/index.md +++ b/docs/Reference/VBRUN/Constants/index.md @@ -7,9 +7,9 @@ has_toc: false # Constants module -The VBRUN **Constants** module collects the named-integer enumerations that classic VB6 forms, intrinsic controls, and runtime services use to spell out their option values — colours, mouse pointers, key codes, drag/drop states, OLE container behaviour, printer setup values, and so on. There are no standalone constants in this module; everything is grouped into an enumeration so that **IntelliSense** can offer the right options at each property or argument. +The VBRUN **Constants** module collects the named-integer enumerations that classic VB6 forms, intrinsic controls, and runtime services use to spell out their option values --- colours, mouse pointers, key codes, drag/drop states, OLE container behaviour, printer setup values, and so on. There are no standalone constants in this module; everything is grouped into an enumeration so that **IntelliSense** can offer the right options at each property or argument. -Some enumerations are tagged **\[MustBeQualified\]** in the source — their members must be referenced through the enum name (e.g. `ControlBorderStyleConstantsCustom.vbCustomBorder`) to avoid clashing with members of similarly named enumerations. This is noted on those enum's pages. +Some enumerations are tagged **\[MustBeQualified\]** in the source --- their members must be referenced through the enum name (e.g. `ControlBorderStyleConstantsCustom.vbCustomBorder`) to avoid clashing with members of similarly named enumerations. This is noted on those enum's pages. ## Enumerations diff --git a/docs/Reference/VBRUN/ContainedControls/index.md b/docs/Reference/VBRUN/ContainedControls/index.md index f3f368a7..abcdb245 100644 --- a/docs/Reference/VBRUN/ContainedControls/index.md +++ b/docs/Reference/VBRUN/ContainedControls/index.md @@ -10,7 +10,7 @@ has_toc: false # ContainedControls class -The **ContainedControls** object is a collection that exposes the controls placed inside an instance of a **UserControl** that has been set up as a control container. The author of the **UserControl** uses this collection to enumerate or inspect those constituent controls at run time. The author of the **UserControl** sees only what the consumer added — controls placed on the **UserControl** at design time by the author themselves are not part of this collection. +The **ContainedControls** object is a collection that exposes the controls placed inside an instance of a **UserControl** that has been set up as a control container. The author of the **UserControl** uses this collection to enumerate or inspect those constituent controls at run time. The author of the **UserControl** sees only what the consumer added --- controls placed on the **UserControl** at design time by the author themselves are not part of this collection. The collection is read-only: items cannot be added or removed through it, and the indexer returns existing controls only. To use it, the **UserControl**'s **ControlContainer** property must have been set to **True** at design time. diff --git a/docs/Reference/VBRUN/DataMembers/index.md b/docs/Reference/VBRUN/DataMembers/index.md index d9191560..293f9b74 100644 --- a/docs/Reference/VBRUN/DataMembers/index.md +++ b/docs/Reference/VBRUN/DataMembers/index.md @@ -10,7 +10,7 @@ has_toc: false # DataMembers class -The **DataMembers** object is a collection of names that a data source class advertises at design time, so that a consumer binding to the data source can choose which member to bind to. Each entry is a **String** — the name of a data member the source can supply on request. The data source manages the list directly with [**Add**](#add), [**Remove**](#remove), and [**Clear**](#clear); the design-time environment reads it back through [**Count**](#count), [**Item**](#item), and **For Each** iteration to populate the data member picker. +The **DataMembers** object is a collection of names that a data source class advertises at design time, so that a consumer binding to the data source can choose which member to bind to. Each entry is a **String** --- the name of a data member the source can supply on request. The data source manages the list directly with [**Add**](#add), [**Remove**](#remove), and [**Clear**](#clear); the design-time environment reads it back through [**Count**](#count), [**Item**](#item), and **For Each** iteration to populate the data member picker. ```tb ' Inside a class whose DataSourceBehavior is set to make it a data source. @@ -44,7 +44,7 @@ Syntax: *object*.**Clear** *object* : *required* An object expression that evaluates to a **DataMembers** object. -After **Clear**, [**Count**](#count) is `0`. Use this when the set of data members the source can supply changes wholesale — for example, after the source is reconfigured. +After **Clear**, [**Count**](#count) is `0`. Use this when the set of data members the source can supply changes wholesale --- for example, after the source is reconfigured. ### Count diff --git a/docs/Reference/VBRUN/DataObject/AvailableFormats.md b/docs/Reference/VBRUN/DataObject/AvailableFormats.md index ed0f134a..49521943 100644 --- a/docs/Reference/VBRUN/DataObject/AvailableFormats.md +++ b/docs/Reference/VBRUN/DataObject/AvailableFormats.md @@ -13,7 +13,7 @@ Syntax: *object*.**AvailableFormats** *object* : *required* An object expression that evaluates to a **DataObject**. -Each element of the returned collection is a [**DataObjectFormat**](DataObjectFormat) descriptor with the format's `Name`, its `FormatType` from **ClipboardConstants**, and information about how the format is stored. Use this when the consumer side does not know in advance which formats the source has supplied — typically in OLE drag-and-drop or paste operations from another application. +Each element of the returned collection is a [**DataObjectFormat**](DataObjectFormat) descriptor with the format's `Name`, its `FormatType` from **ClipboardConstants**, and information about how the format is stored. Use this when the consumer side does not know in advance which formats the source has supplied --- typically in OLE drag-and-drop or paste operations from another application. > [!NOTE] > **AvailableFormats** is a twinBASIC addition; VB6 callers had to probe each format of interest with **GetFormat** instead. diff --git a/docs/Reference/VBRUN/DataObject/DataObjectFiles.md b/docs/Reference/VBRUN/DataObject/DataObjectFiles.md index 4362b11c..de9d2ab9 100644 --- a/docs/Reference/VBRUN/DataObject/DataObjectFiles.md +++ b/docs/Reference/VBRUN/DataObject/DataObjectFiles.md @@ -6,7 +6,7 @@ permalink: /tB/Packages/VBRUN/DataObject/DataObjectFiles # DataObjectFiles {: .no_toc } -A **DataObjectFiles** object is the collection of file paths held by a [**DataObject**](.) — typically the payload of a Windows shell drag-and-drop, which arrives under the `vbCFFiles` clipboard format. Each element is a fully qualified path stored as a **String**. The collection is reachable through the [**Files**](Files) property of the parent **DataObject**. +A **DataObjectFiles** object is the collection of file paths held by a [**DataObject**](.) --- typically the payload of a Windows shell drag-and-drop, which arrives under the `vbCFFiles` clipboard format. Each element is a fully qualified path stored as a **String**. The collection is reachable through the [**Files**](Files) property of the parent **DataObject**. The collection is mutable: the source side of a drag-and-drop or clipboard operation can build a list with [**Add**](#add), and the destination side reads it back with [**Item**](#item) or **For Each** iteration. diff --git a/docs/Reference/VBRUN/DataObject/DataObjectFormat.md b/docs/Reference/VBRUN/DataObject/DataObjectFormat.md index e184ef21..56b669fb 100644 --- a/docs/Reference/VBRUN/DataObject/DataObjectFormat.md +++ b/docs/Reference/VBRUN/DataObject/DataObjectFormat.md @@ -6,7 +6,7 @@ permalink: /tB/Packages/VBRUN/DataObject/DataObjectFormat # DataObjectFormat {: .no_toc } -A **DataObjectFormat** describes one of the formats a [**DataObject**](.) holds a value in. The descriptor is what you get when iterating a [**DataObjectFormats**](DataObjectFormats) collection, and exposes everything the runtime needs to negotiate a transfer: which clipboard format type the data is in, which aspect (rendering) of it is on offer, and how the bytes are stored. +A **DataObjectFormat** describes one of the formats a [**DataObject**](.) holds a value in. The descriptor is the element type yielded when iterating a [**DataObjectFormats**](DataObjectFormats) collection, and exposes everything the runtime needs to negotiate a transfer: which clipboard format type the data is in, which aspect (rendering) of it is on offer, and how the bytes are stored. ## Members @@ -16,7 +16,7 @@ Returns or sets a one-based index into the chosen [**AspectType**](#aspecttype), Syntax: *object*.**AspectIndex** [ **=** *value* ] -For aspects that have several pages or frames — for example a multi-page metafile rendered with `dvaspect_Content` — **AspectIndex** picks which one this descriptor refers to. For single-aspect formats, leave at the default. +For aspects that have several pages or frames --- for example a multi-page metafile rendered with `dvaspect_Content` --- **AspectIndex** picks which one this descriptor refers to. For single-aspect formats, leave at the default. ### AspectType @@ -48,7 +48,7 @@ Returns or sets how the data is stored, as a **StorageTypeConstants** value. Syntax: *object*.**StorageType** [ **=** *value* ] -Identifies the medium used to transfer the bytes — a global memory handle, a file path, an `IStream`, an `IStorage`, a GDI handle, a metafile, or an enhanced metafile. The runtime normally negotiates this automatically; setting it directly is only needed when interoperating with another component that requires a specific medium. +Identifies the medium used to transfer the bytes --- a global memory handle, a file path, an `IStream`, an `IStorage`, a GDI handle, a metafile, or an enhanced metafile. The runtime normally negotiates this automatically; setting it directly is only needed when interoperating with another component that requires a specific medium. ## See Also diff --git a/docs/Reference/VBRUN/DataObject/DataObjectFormats.md b/docs/Reference/VBRUN/DataObject/DataObjectFormats.md index 201910cb..1419cf3f 100644 --- a/docs/Reference/VBRUN/DataObject/DataObjectFormats.md +++ b/docs/Reference/VBRUN/DataObject/DataObjectFormats.md @@ -6,7 +6,7 @@ permalink: /tB/Packages/VBRUN/DataObject/DataObjectFormats # DataObjectFormats {: .no_toc } -A **DataObjectFormats** object is the read-only collection of [**DataObjectFormat**](DataObjectFormat) descriptors a [**DataObject**](.) currently exposes — one element per clipboard format the object holds a value in. The collection is returned by the [**AvailableFormats**](AvailableFormats) method and is the only general way to discover, at run time, which formats a **DataObject** received from another application has on offer. +A **DataObjectFormats** object is the read-only collection of [**DataObjectFormat**](DataObjectFormat) descriptors a [**DataObject**](.) currently exposes --- one element per clipboard format the object holds a value in. The collection is returned by the [**AvailableFormats**](AvailableFormats) method and is the only general way to discover, at run time, which formats a **DataObject** received from another application has on offer. ## Members diff --git a/docs/Reference/VBRUN/DataObject/Files.md b/docs/Reference/VBRUN/DataObject/Files.md index e4b62e61..2dedcc8d 100644 --- a/docs/Reference/VBRUN/DataObject/Files.md +++ b/docs/Reference/VBRUN/DataObject/Files.md @@ -15,7 +15,7 @@ Syntax: *object*.**Files** This is the typical way to read the payload of a Windows shell drag-and-drop, which arrives as a list of fully qualified paths under the `vbCFFiles` clipboard format. Each element of the collection is a **String**. -The source side may also fill the **DataObject** with a list of files by adding paths to this collection — see [**DataObjectFiles.Add**](DataObjectFiles#add). +The source side may also fill the **DataObject** with a list of files by adding paths to this collection --- see [**DataObjectFiles.Add**](DataObjectFiles#add). ### Example diff --git a/docs/Reference/VBRUN/DataObject/GetData.md b/docs/Reference/VBRUN/DataObject/GetData.md index 30181a65..1fbc6ab9 100644 --- a/docs/Reference/VBRUN/DataObject/GetData.md +++ b/docs/Reference/VBRUN/DataObject/GetData.md @@ -14,7 +14,7 @@ Syntax: *object*.**GetData(** *Format* **)** : *required* An object expression that evaluates to a **DataObject**. *Format* -: *required* A **ClipboardConstants** value identifying the format to read back — for example `vbCFText`, `vbCFUnicodeText`, `vbCFBitmap`. If the **DataObject** does not contain data in *Format*, the result is **Empty**; check first with [**GetFormat**](GetFormat) when the format may not be present. +: *required* A **ClipboardConstants** value identifying the format to read back --- for example `vbCFText`, `vbCFUnicodeText`, `vbCFBitmap`. If the **DataObject** does not contain data in *Format*, the result is **Empty**; check first with [**GetFormat**](GetFormat) when the format may not be present. The concrete subtype of the returned **Variant** depends on *Format*: text formats yield a **String**, `vbCFBitmap` yields an **stdole.IPictureDisp**, `vbCFFiles` yields a path or a path collection, and so on. To pull data out by a textual format name rather than a numeric clipboard constant, use [**GetDataByName**](GetDataByName). diff --git a/docs/Reference/VBRUN/DataObject/GetDataByName.md b/docs/Reference/VBRUN/DataObject/GetDataByName.md index fa89654c..83a841e4 100644 --- a/docs/Reference/VBRUN/DataObject/GetDataByName.md +++ b/docs/Reference/VBRUN/DataObject/GetDataByName.md @@ -14,7 +14,7 @@ Syntax: *object*.**GetDataByName(** *Format* **)** : *required* An object expression that evaluates to a **DataObject**. *Format* -: *required* A **String** giving the name of the format to read back — typically the name a custom clipboard format was registered under with `RegisterClipboardFormat`. If the **DataObject** does not contain data in *Format*, the result is **Empty**; check first with [**GetFormatByName**](GetFormatByName) when the format may not be present. +: *required* A **String** giving the name of the format to read back --- typically the name a custom clipboard format was registered under with `RegisterClipboardFormat`. If the **DataObject** does not contain data in *Format*, the result is **Empty**; check first with [**GetFormatByName**](GetFormatByName) when the format may not be present. > [!NOTE] > **GetDataByName** is a twinBASIC addition; it has no equivalent in VB6. Use it when the consumer side knows the format only by its registered name and does not have the corresponding numeric identifier available. For the standard built-in formats, [**GetData**](GetData) with a **ClipboardConstants** value is more direct. diff --git a/docs/Reference/VBRUN/DataObject/GetFormat.md b/docs/Reference/VBRUN/DataObject/GetFormat.md index ae25e786..ee0dab26 100644 --- a/docs/Reference/VBRUN/DataObject/GetFormat.md +++ b/docs/Reference/VBRUN/DataObject/GetFormat.md @@ -14,7 +14,7 @@ Syntax: *object*.**GetFormat(** *Format* **)** : *required* An object expression that evaluates to a **DataObject**. *Format* -: *required* A **ClipboardConstants** value identifying the format to test for — for example `vbCFText`, `vbCFUnicodeText`, `vbCFBitmap`, `vbCFFiles`. +: *required* A **ClipboardConstants** value identifying the format to test for --- for example `vbCFText`, `vbCFUnicodeText`, `vbCFBitmap`, `vbCFFiles`. The result is **True** if the **DataObject** can produce a value in *Format*, **False** otherwise. Use this before calling [**GetData**](GetData) when the format may not be present, so that an unknown format does not silently return **Empty**. diff --git a/docs/Reference/VBRUN/DataObject/GetFormatByName.md b/docs/Reference/VBRUN/DataObject/GetFormatByName.md index a102cb5b..e5644df0 100644 --- a/docs/Reference/VBRUN/DataObject/GetFormatByName.md +++ b/docs/Reference/VBRUN/DataObject/GetFormatByName.md @@ -14,7 +14,7 @@ Syntax: *object*.**GetFormatByName(** *Format* **)** : *required* An object expression that evaluates to a **DataObject**. *Format* -: *required* A **String** giving the name of the format to test for — typically the name a custom clipboard format was registered under with `RegisterClipboardFormat`. +: *required* A **String** giving the name of the format to test for --- typically the name a custom clipboard format was registered under with `RegisterClipboardFormat`. The result is **True** if the **DataObject** can produce a value in *Format*, **False** otherwise. Use this before calling [**GetDataByName**](GetDataByName) when the format may not be present. diff --git a/docs/Reference/VBRUN/DataObject/SetData.md b/docs/Reference/VBRUN/DataObject/SetData.md index 1c40c32d..9b7702a1 100644 --- a/docs/Reference/VBRUN/DataObject/SetData.md +++ b/docs/Reference/VBRUN/DataObject/SetData.md @@ -6,7 +6,7 @@ permalink: /tB/Packages/VBRUN/DataObject/SetData # SetData {: .no_toc } -Stores a value in the **DataObject** under a given clipboard format. Calling **SetData** several times against the same object lets one logical payload be made available under several formats — for example as `vbCFText` and `vbCFUnicodeText` — so each consumer can pick the representation it understands. +Stores a value in the **DataObject** under a given clipboard format. Calling **SetData** several times against the same object lets one logical payload be made available under several formats --- for example as `vbCFText` and `vbCFUnicodeText` --- so each consumer can pick the representation it understands. Syntax: *object*.**SetData** [ *Value* [ **,** *Format* ] ] @@ -14,10 +14,10 @@ Syntax: *object*.**SetData** [ *Value* [ **,** *Format* ] ] : *required* An object expression that evaluates to a **DataObject**. *Value* -: *optional* The value to store. May be any expression assignable to a **Variant** — text, a byte array, an **stdole.IPictureDisp**, and so on. +: *optional* The value to store. May be any expression assignable to a **Variant** --- text, a byte array, an **stdole.IPictureDisp**, and so on. *Format* -: *optional* A **ClipboardConstants** value — `vbCFText`, `vbCFUnicodeText`, `vbCFBitmap`, `vbCFFiles`, and so on — naming the clipboard format under which *Value* is stored. If omitted, the **DataObject** chooses a default format based on the run-time type of *Value*. +: *optional* A **ClipboardConstants** value --- `vbCFText`, `vbCFUnicodeText`, `vbCFBitmap`, `vbCFFiles`, and so on --- naming the clipboard format under which *Value* is stored. If omitted, the **DataObject** chooses a default format based on the run-time type of *Value*. When using a custom (private) clipboard format, register it with the system through `RegisterClipboardFormat` before passing its identifier to **SetData**; otherwise other applications will not be able to read the data back. diff --git a/docs/Reference/VBRUN/DataObject/index.md b/docs/Reference/VBRUN/DataObject/index.md index b2a8a2a5..6d4a5498 100644 --- a/docs/Reference/VBRUN/DataObject/index.md +++ b/docs/Reference/VBRUN/DataObject/index.md @@ -10,13 +10,13 @@ has_toc: false # DataObject class -A **DataObject** is a container for one piece of information held in one or more clipboard formats — the same payload represented as plain text, Unicode text, RTF, a bitmap, a list of file paths, and so on. The runtime hands a **DataObject** to clipboard and OLE drag-and-drop operations: the source side fills it with [**SetData**](SetData), and the destination side inspects what's available with [**GetFormat**](GetFormat) (or [**AvailableFormats**](AvailableFormats)) and pulls the bytes out with [**GetData**](GetData). +A **DataObject** is a container for one piece of information held in one or more clipboard formats --- the same payload represented as plain text, Unicode text, RTF, a bitmap, a list of file paths, and so on. The runtime hands a **DataObject** to clipboard and OLE drag-and-drop operations: the source side fills it with [**SetData**](SetData), and the destination side inspects what's available with [**GetFormat**](GetFormat) (or [**AvailableFormats**](AvailableFormats)) and pulls the bytes out with [**GetData**](GetData). A new **DataObject** is created with **New** and starts out empty. ## Storing and retrieving data -[**SetData**](SetData) places a value into the **DataObject** under a given clipboard format — typically a value from the **ClipboardConstants** enumeration such as `vbCFText`, `vbCFUnicodeText`, or `vbCFBitmap`. A single object can hold the same logical payload under several formats at once, so consumers with different requirements can each find a representation they understand. +[**SetData**](SetData) places a value into the **DataObject** under a given clipboard format --- typically a value from the **ClipboardConstants** enumeration such as `vbCFText`, `vbCFUnicodeText`, or `vbCFBitmap`. A single object can hold the same logical payload under several formats at once, so consumers with different requirements can each find a representation they understand. ```tb Dim Data As New DataObject @@ -24,13 +24,13 @@ Data.SetData "Hello, world!", vbCFText Data.SetData StrConv("Hello, world!", vbUnicode), vbCFUnicodeText ``` -[**GetData**](GetData) pulls the value back out for a chosen format. [**Clear**](Clear) removes every format and value at once — useful when reusing a single **DataObject** for several operations. +[**GetData**](GetData) pulls the value back out for a chosen format. [**Clear**](Clear) removes every format and value at once --- useful when reusing a single **DataObject** for several operations. twinBASIC also accepts format names as plain strings: [**GetDataByName**](GetDataByName) is the string-keyed counterpart to [**GetData**](GetData), and is convenient for custom or registered formats whose numeric identifier is not known up front. ## Discovering what's there -A consumer that did not place the data itself usually does not know which formats are present. [**GetFormat**](GetFormat) returns **True** if a given clipboard format is available, and [**GetFormatByName**](GetFormatByName) does the same for a named format. To discover the full set, [**AvailableFormats**](AvailableFormats) returns a [**DataObjectFormats**](DataObjectFormats) collection of [**DataObjectFormat**](DataObjectFormat) descriptors — each with a `Name`, a `FormatType` from **ClipboardConstants**, and information about how the format is stored. +A consumer that did not place the data itself usually does not know which formats are present. [**GetFormat**](GetFormat) returns **True** if a given clipboard format is available, and [**GetFormatByName**](GetFormatByName) does the same for a named format. To discover the full set, [**AvailableFormats**](AvailableFormats) returns a [**DataObjectFormats**](DataObjectFormats) collection of [**DataObjectFormat**](DataObjectFormat) descriptors --- each with a `Name`, a `FormatType` from **ClipboardConstants**, and information about how the format is stored. ```tb Dim F As DataObjectFormat @@ -44,7 +44,7 @@ Next F ## Files -When a **DataObject** contains a list of file paths — for example, the payload of a Windows shell drag-and-drop — [**Files**](Files) returns a [**DataObjectFiles**](DataObjectFiles) collection holding each path as a **String**. +When a **DataObject** contains a list of file paths --- for example, the payload of a Windows shell drag-and-drop --- [**Files**](Files) returns a [**DataObjectFiles**](DataObjectFiles) collection holding each path as a **String**. ```tb Dim Path As Variant diff --git a/docs/Reference/VBRUN/ErrorCallstack/index.md b/docs/Reference/VBRUN/ErrorCallstack/index.md index acb9ab5e..c9170261 100644 --- a/docs/Reference/VBRUN/ErrorCallstack/index.md +++ b/docs/Reference/VBRUN/ErrorCallstack/index.md @@ -10,9 +10,9 @@ has_toc: false # ErrorCallstack class -An **ErrorCallstack** object is a snapshot of the chain of procedures that were active on the call stack at the moment a run-time error was raised — outermost frame first, innermost (the procedure that actually raised the error) last. Each frame is exposed as an [**ErrorStackFrame**](../ErrorStackFrame), describing one procedure by its project, module, and procedure names. +An **ErrorCallstack** object is a snapshot of the chain of procedures that were active on the call stack at the moment a run-time error was raised --- outermost frame first, innermost (the procedure that actually raised the error) last. Each frame is exposed as an [**ErrorStackFrame**](../ErrorStackFrame), describing one procedure by its project, module, and procedure names. -The snapshot is read through the **Callstack** property of an **ErrorContext** object, which is itself accessible from the structured error-handling machinery — typically inside a `Catch` block or an **On Error** handler. +The snapshot is read through the **Callstack** property of an **ErrorContext** object, which is itself accessible from the structured error-handling machinery --- typically inside a `Catch` block or an **On Error** handler. ```tb Sub LogStackTrace(ByVal Stack As ErrorCallstack) @@ -25,7 +25,7 @@ Sub LogStackTrace(ByVal Stack As ErrorCallstack) End Sub ``` -The collection is read-only and has no `_NewEnum` member, so it cannot be iterated with **For Each** — use a numeric loop from `1` to [**Count**](#count) and read each frame with [**Items**](#items). +The collection is read-only and has no `_NewEnum` member, so it cannot be iterated with **For Each** --- use a numeric loop from `1` to [**Count**](#count) and read each frame with [**Items**](#items). ## Members @@ -50,6 +50,6 @@ Syntax: *object*.**Items(** *Index* **)** : *required* An object expression that evaluates to an **ErrorCallstack** object. *Index* -: *required* A **Long** giving the one-based position of the frame to return. Frame `1` is the outermost procedure on the stack; frame [**Count**](#count) is the innermost — the procedure that raised the error. *Index* must be between `1` and **Count**; otherwise an error occurs. +: *required* A **Long** giving the one-based position of the frame to return. Frame `1` is the outermost procedure on the stack; frame [**Count**](#count) is the innermost --- the procedure that raised the error. *Index* must be between `1` and **Count**; otherwise an error occurs. The result is an [**ErrorStackFrame**](../ErrorStackFrame) describing the procedure at that position. diff --git a/docs/Reference/VBRUN/ErrorContext/index.md b/docs/Reference/VBRUN/ErrorContext/index.md index aaabc3b0..d81e5efc 100644 --- a/docs/Reference/VBRUN/ErrorContext/index.md +++ b/docs/Reference/VBRUN/ErrorContext/index.md @@ -12,7 +12,7 @@ has_toc: false An **ErrorContext** object captures everything the runtime knows about a run-time error: its identity ([**Number**](#number), [**Description**](#description), [**Source**](#source)), its help references ([**HelpFile**](#helpfile), [**HelpContext**](#helpcontext)), the operating-system error code at the time it was raised ([**LastDLLError**](#lastdllerror)), the [**State**](#state) of the error-handling machinery, and a snapshot of the [**Callstack**](#callstack) from the moment of the failure. It is twinBASIC's structured counterpart to the simpler [**Err**](../../../Modules/ErrObject) object. -The error-identity properties (**Number**, **Description**, **Source**, **HelpFile**, **HelpContext**, **LastDLLError**) have the same meaning here as on the **Err** object — see the [**ErrObject**](../../../Modules/ErrObject) module for a discussion of each. **State** and **Callstack** are unique to **ErrorContext** and reflect the structured error-handling machinery that has no equivalent on the legacy **Err** object. +The error-identity properties (**Number**, **Description**, **Source**, **HelpFile**, **HelpContext**, **LastDLLError**) have the same meaning here as on the **Err** object --- see the [**ErrObject**](../../../Modules/ErrObject) module for a discussion of each. **State** and **Callstack** are unique to **ErrorContext** and reflect the structured error-handling machinery that has no equivalent on the legacy **Err** object. ## Members @@ -25,7 +25,7 @@ Syntax: *object*.**Callstack** *object* : *required* An object expression that evaluates to an **ErrorContext** object. -The snapshot lists every active procedure outermost-first; the innermost frame is the procedure that raised the error. The collection is read-only — see [**ErrorCallstack**](../ErrorCallstack) for how to walk it. +The snapshot lists every active procedure outermost-first; the innermost frame is the procedure that raised the error. The collection is read-only --- see [**ErrorCallstack**](../ErrorCallstack) for how to iterate it. ### Description @@ -69,7 +69,7 @@ Syntax: *object*.**LastDLLError** *object* : *required* An object expression that evaluates to an **ErrorContext** object. -twinBASIC's error trapping does not catch failures inside `Declare`d Windows API calls — those calls report failure through their return value, and the calling code has to inspect this property to learn the underlying Win32 error. The value is meaningful only on Windows. +twinBASIC's error trapping does not catch failures inside `Declare`d Windows API calls --- those calls report failure through their return value, and the calling code has to inspect this property to learn the underlying Win32 error. The value is meaningful only on Windows. ### Number @@ -102,12 +102,12 @@ Syntax: *object*.**State** [ **=** *value* ] *object* : *required* An object expression that evaluates to an **ErrorContext** object. -The runtime updates **State** as control flows through error handlers, **Try**/**Catch**/**Finally** blocks, and the various propagation paths. Reading the property tells diagnostic code which construct it is being invoked from. Assigning to it overrides the runtime's idea of what to do next — a deliberately advanced operation, useful mainly to diagnostic tools and to libraries that manage their own error flow. +The runtime updates **State** as control flows through error handlers, **Try**/**Catch**/**Finally** blocks, and the various propagation paths. Reading the property tells diagnostic code which construct it is being invoked from. Assigning to it overrides the runtime's idea of what to do next --- a deliberately advanced operation, useful mainly to diagnostic tools and to libraries that manage their own error flow. The **OnErrorStatus** enumeration values are: `OnErrorGoto0` (`&H1`) -: An **On Error GoTo 0** is currently in effect — no handler is installed. +: An **On Error GoTo 0** is currently in effect --- no handler is installed. `OnErrorResumeNext` (`&H2`) : An **On Error Resume Next** is currently in effect. diff --git a/docs/Reference/VBRUN/ErrorStackFrame/index.md b/docs/Reference/VBRUN/ErrorStackFrame/index.md index 3b9df960..5bdbe2c6 100644 --- a/docs/Reference/VBRUN/ErrorStackFrame/index.md +++ b/docs/Reference/VBRUN/ErrorStackFrame/index.md @@ -10,7 +10,7 @@ has_toc: false # ErrorStackFrame class -An **ErrorStackFrame** describes one procedure that was active on the call stack at the moment a run-time error was raised — the project it belongs to, the module that contains it, and its own name. Frames are produced by walking an [**ErrorCallstack**](../ErrorCallstack) snapshot, which in turn is reachable from the [**Callstack**](../ErrorContext#callstack) property of an [**ErrorContext**](../ErrorContext). Every property is read-only. +An **ErrorStackFrame** describes one procedure that was active on the call stack at the moment a run-time error was raised --- the project it belongs to, the module that contains it, and its own name. Frames are produced by iterating an [**ErrorCallstack**](../ErrorCallstack) snapshot, which in turn is reachable from the [**Callstack**](../ErrorContext#callstack) property of an [**ErrorContext**](../ErrorContext). Every property is read-only. ```tb Sub LogStackTrace(ByVal Stack As ErrorCallstack) @@ -27,7 +27,7 @@ End Sub ### ModuleName -Returns the name of the module — the standard module, class module, form, or user control — that contains the procedure for this frame, as a **String**. +Returns the name of the module --- the standard module, class module, form, or user control --- that contains the procedure for this frame, as a **String**. Syntax: *object*.**ModuleName** diff --git a/docs/Reference/VBRUN/Hyperlink/index.md b/docs/Reference/VBRUN/Hyperlink/index.md index e808fac7..5cf4aca9 100644 --- a/docs/Reference/VBRUN/Hyperlink/index.md +++ b/docs/Reference/VBRUN/Hyperlink/index.md @@ -10,7 +10,7 @@ has_toc: false # Hyperlink class -The **Hyperlink** object lets a control or form ask its container to navigate to a target document, the way clicking a link in a browser would. It is used from a control's code through the host's **Hyperlink** property — for example **UserControl.Hyperlink** — and works in containers that participate in browser-style navigation (Internet Explorer, Office binders, and a handful of other hyperlink-aware hosts). When the host does not support hyperlink navigation, the runtime falls back to launching the system's default handler for the target. +The **Hyperlink** object lets a control or form ask its container to navigate to a target document, the way clicking a link in a browser would. It is used from a control's code through the host's **Hyperlink** property --- for example **UserControl.Hyperlink** --- and works in containers that participate in browser-style navigation (Internet Explorer, Office binders, and a few other hyperlink-aware hosts). When the host does not support hyperlink navigation, the runtime falls back to launching the system's default handler for the target. ```tb Private Sub HelpButton_Click() @@ -52,10 +52,10 @@ Syntax: *object*.**NavigateTo** *Target* [ **,** *Location* [ **,** *FrameName* : *required* An object expression that evaluates to a **Hyperlink** object. *Target* -: *required* A **String** giving the destination — a URL, a UNC path, or a local file path. The container is responsible for resolving the string and dispatching it to the right handler. +: *required* A **String** giving the destination --- a URL, a UNC path, or a local file path. The container is responsible for resolving the string and dispatching it to the right handler. *Location* -: *optional* A **String** naming an anchor or bookmark within *Target* — for example the fragment after `#` in an HTML URL — that the container should scroll to once the document has been loaded. +: *optional* A **String** naming an anchor or bookmark within *Target* --- for example the fragment after `#` in an HTML URL --- that the container should scroll to once the document has been loaded. *FrameName* : *optional* A **String** naming a frame within an HTML frameset that should receive the navigation, instead of the top-level window. Ignored by hosts that do not understand HTML frames. diff --git a/docs/Reference/VBRUN/ParentControls/index.md b/docs/Reference/VBRUN/ParentControls/index.md index 8714f295..35bca6df 100644 --- a/docs/Reference/VBRUN/ParentControls/index.md +++ b/docs/Reference/VBRUN/ParentControls/index.md @@ -10,9 +10,9 @@ has_toc: false # ParentControls class -The **ParentControls** object is the collection of other controls that live in the same container as a **UserControl** — its siblings on the host form, frame, or page. It is reachable inside a **UserControl** through **UserControl.ParentControls** and lets the control discover and interact with the other controls around it without being given explicit references. +The **ParentControls** object is the collection of other controls that live in the same container as a **UserControl** --- its siblings on the host form, frame, or page. It is reachable inside a **UserControl** through **UserControl.ParentControls** and lets the control discover and interact with the other controls around it without being given explicit references. -By default each item is returned wrapped in its host **Extender** — the container's per-control adapter that adds layout properties (**Top**, **Left**, **Tag**, **Visible**, **Name**, and so on) on top of the control's own interface. Set [**ParentControlsType**](#parentcontrolstype) to **vbNoExtender** to receive the bare controls instead. The collection itself is read-only: items cannot be added or removed through it. +By default each item is returned wrapped in its host **Extender** --- the container's per-control adapter that adds layout properties (**Top**, **Left**, **Tag**, **Visible**, **Name**, and so on) on top of the control's own interface. Set [**ParentControlsType**](#parentcontrolstype) to **vbNoExtender** to receive the bare controls instead. The collection itself is read-only: items cannot be added or removed through it. ```tb ' Inside a UserControl: print the name and type of every sibling control. diff --git a/docs/Reference/VBRUN/PropertyBag/index.md b/docs/Reference/VBRUN/PropertyBag/index.md index 311aff53..1371368e 100644 --- a/docs/Reference/VBRUN/PropertyBag/index.md +++ b/docs/Reference/VBRUN/PropertyBag/index.md @@ -43,7 +43,7 @@ Syntax: *object*.**Contents** [ **=** *value* ] *value* : A **Variant** containing a **Byte** array previously obtained from another **PropertyBag**'s **Contents**. -Reading **Contents** serialises the whole bag — every name/value pair currently in it — into a self-contained byte array suitable for writing to a file, sending across a network, or storing in another medium. Assigning to **Contents** discards the current state and replaces it with the state encoded in *value*; the byte array must be one previously produced by a compatible **PropertyBag**. +Reading **Contents** serialises the whole bag --- every name/value pair currently in it --- into a self-contained byte array suitable for writing to a file, sending across a network, or storing in another medium. Assigning to **Contents** discards the current state and replaces it with the state encoded in *value*; the byte array must be one previously produced by a compatible **PropertyBag**. ### ReadProperty @@ -78,4 +78,4 @@ Syntax: *object*.**WriteProperty** *Name* **,** *Value* [ **,** *DefaultValue* ] : *required* The value to store. May be any expression assignable to a **Variant**. *DefaultValue* -: *optional* A value that the consumer will treat as the default when reading the property. If *Value* is equal to *DefaultValue*, the bag may skip writing the entry at all — the read side will fall back to the same default — keeping the serialised form small. Pass the same default that the matching call to [**ReadProperty**](#readproperty) will use. +: *optional* A value that the consumer will treat as the default when reading the property. If *Value* is equal to *DefaultValue*, the bag may skip writing the entry at all --- the read side will fall back to the same default --- keeping the serialised form small. Pass the same default that the matching call to [**ReadProperty**](#readproperty) will use. diff --git a/docs/Reference/VBRUN/index.md b/docs/Reference/VBRUN/index.md index 0218bbe5..6c8aba33 100644 --- a/docs/Reference/VBRUN/index.md +++ b/docs/Reference/VBRUN/index.md @@ -19,12 +19,12 @@ The VBRUN built-in package collects twinBASIC's runtime-only types: the ambient, - [DataMembers](DataMembers) -- collection of named data-source members advertised at design time to data-binding consumers - [DataObject](DataObject) -- clipboard / OLE drag-and-drop container that holds one payload in multiple clipboard formats - [ErrorCallstack](ErrorCallstack) -- snapshot of the call stack at the moment a run-time error was raised, exposed as a sequence of [**ErrorStackFrame**](ErrorStackFrame) items -- [ErrorContext](ErrorContext) -- structured error object — number, description, source, help, OS error, state, and call stack -- [ErrorStackFrame](ErrorStackFrame) -- single procedure on an [**ErrorCallstack**](ErrorCallstack) — its project, module, and procedure names +- [ErrorContext](ErrorContext) -- structured error object -- number, description, source, help, OS error, state, and call stack +- [ErrorStackFrame](ErrorStackFrame) -- single procedure on an [**ErrorCallstack**](ErrorCallstack) -- its project, module, and procedure names - [Hyperlink](Hyperlink) -- runtime bridge for browser-style navigation; controls call **UserControl.Hyperlink.NavigateTo** to ask the host to load a target - [ParentControls](ParentControls) -- collection of the **UserControl**'s siblings in its container, optionally wrapped in their host **Extender** -- [PropertyBag](PropertyBag) -- creatable key / value store for persisting an object's state — used by **UserControl** save / load and serialisable as a single byte array +- [PropertyBag](PropertyBag) -- creatable key / value store for persisting an object's state -- used by **UserControl** save / load and serialisable as a single byte array ## Modules -- [Constants](Constants) -- enumerations used by classic VB6 forms, intrinsic controls, and runtime services — colours, mouse pointers, key codes, drag/drop states, OLE container behaviour, printer setup values, … +- [Constants](Constants) -- enumerations used by classic VB6 forms, intrinsic controls, and runtime services -- colours, mouse pointers, key codes, drag/drop states, OLE container behaviour, printer setup values, … diff --git a/docs/Reference/WebView2/Enumerations/index.md b/docs/Reference/WebView2/Enumerations/index.md index 88781133..db5c4947 100644 --- a/docs/Reference/WebView2/Enumerations/index.md +++ b/docs/Reference/WebView2/Enumerations/index.md @@ -7,7 +7,7 @@ has_toc: false # Enumerations -The `wv2…` enumerations used by the **WebView2** control's properties, methods, and event arguments. Their members have the constant value defined by the underlying `COREWEBVIEW2_*` enumeration in the Edge WebView2 runtime — the comment beside each `Enum` in the source records the runtime name. +The `wv2…` enumerations used by the **WebView2** control's properties, methods, and event arguments. Their members have the constant value defined by the underlying `COREWEBVIEW2_*` enumeration in the Edge WebView2 runtime --- the comment beside each `Enum` in the source records the runtime name. | Enumeration | Used by | |-------------|---------| diff --git a/docs/Reference/WebView2/Enumerations/wv2ErrorStatus.md b/docs/Reference/WebView2/Enumerations/wv2ErrorStatus.md index 799bd4d1..2eeb728e 100644 --- a/docs/Reference/WebView2/Enumerations/wv2ErrorStatus.md +++ b/docs/Reference/WebView2/Enumerations/wv2ErrorStatus.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/WebView2/Enumerations/wv2ErrorStatus # wv2ErrorStatus {: .no_toc } -The reason a navigation failed. Carried as the `WebErrorStatus` argument of the [**NavigationComplete**](../WebView2/#navigationcomplete) event — only meaningful when its `IsSuccess` argument is **False**. Mirrors the `COREWEBVIEW2_WEB_ERROR_STATUS` enumeration. +The reason a navigation failed. Passed as the `WebErrorStatus` argument of the [**NavigationComplete**](../WebView2/#navigationcomplete) event --- only meaningful when its `IsSuccess` argument is **False**. Mirrors the `COREWEBVIEW2_WEB_ERROR_STATUS` enumeration. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/WebView2/Enumerations/wv2HostResourceAccessKind.md b/docs/Reference/WebView2/Enumerations/wv2HostResourceAccessKind.md index e6d283b8..fb077bab 100644 --- a/docs/Reference/WebView2/Enumerations/wv2HostResourceAccessKind.md +++ b/docs/Reference/WebView2/Enumerations/wv2HostResourceAccessKind.md @@ -7,10 +7,10 @@ permalink: /tB/Packages/WebView2/Enumerations/wv2HostResourceAccessKind # wv2HostResourceAccessKind {: .no_toc } -How the WebView2 runtime should treat a virtual hostname mapped to a local folder by [**SetVirtualHostNameToFolderMapping**](../WebView2/#setvirtualhostnametofoldermapping) — whether pages on other origins are allowed to fetch from it. Mirrors the `COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND` enumeration. +How the WebView2 runtime should treat a virtual hostname mapped to a local folder by [**SetVirtualHostNameToFolderMapping**](../WebView2/#setvirtualhostnametofoldermapping) --- whether pages on other origins are allowed to fetch from it. Mirrors the `COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND` enumeration. | Constant | Value | Description | |----------|-------|-------------| | **wv2ResourceDeny**{: #wv2ResourceDeny } | 0 | Only pages served from the same virtual hostname may load resources from the mapped folder. | -| **wv2ResourceAllow**{: #wv2ResourceAllow } | 1 | Default — any page may load resources from the mapped folder. | +| **wv2ResourceAllow**{: #wv2ResourceAllow } | 1 | Default --- any page may load resources from the mapped folder. | | **wv2ResourceDenyCors**{: #wv2ResourceDenyCors } | 2 | Same as **wv2ResourceAllow**, but cross-origin requests are subject to the usual CORS checks. | diff --git a/docs/Reference/WebView2/Enumerations/wv2KeyEventKind.md b/docs/Reference/WebView2/Enumerations/wv2KeyEventKind.md index dac90e13..f91b13f3 100644 --- a/docs/Reference/WebView2/Enumerations/wv2KeyEventKind.md +++ b/docs/Reference/WebView2/Enumerations/wv2KeyEventKind.md @@ -13,5 +13,5 @@ The kind of accelerator-key keyboard message that fired the [**AcceleratorKeyPre |----------|-------|-------------| | **wv2EventKeyDown**{: #wv2EventKeyDown } | 0 | Raised from a `WM_KEYDOWN` message. | | **wv2EventKeyUp**{: #wv2EventKeyUp } | 1 | Raised from a `WM_KEYUP` message. | -| **wv2EventSystemKeyDown**{: #wv2EventSystemKeyDown } | 2 | Raised from a `WM_SYSKEYDOWN` message — e.g. **Alt+** *key*. | +| **wv2EventSystemKeyDown**{: #wv2EventSystemKeyDown } | 2 | Raised from a `WM_SYSKEYDOWN` message --- e.g. **Alt+** *key*. | | **wv2EventSystemKeyUp**{: #wv2EventSystemKeyUp } | 3 | Raised from a `WM_SYSKEYUP` message. | diff --git a/docs/Reference/WebView2/Enumerations/wv2PermissionKind.md b/docs/Reference/WebView2/Enumerations/wv2PermissionKind.md index 3681bd14..3048e829 100644 --- a/docs/Reference/WebView2/Enumerations/wv2PermissionKind.md +++ b/docs/Reference/WebView2/Enumerations/wv2PermissionKind.md @@ -7,7 +7,7 @@ permalink: /tB/Packages/WebView2/Enumerations/wv2PermissionKind # wv2PermissionKind {: .no_toc } -Identifies which device or browser capability a web page is asking permission to use. Carried as the `PermissionKind` argument of the [**PermissionRequested**](../WebView2/#permissionrequested) event. Mirrors the `COREWEBVIEW2_PERMISSION_KIND` enumeration in the Edge WebView2 runtime. +Identifies which device or browser capability a web page is asking permission to use. Passed as the `PermissionKind` argument of the [**PermissionRequested**](../WebView2/#permissionrequested) event. Mirrors the `COREWEBVIEW2_PERMISSION_KIND` enumeration in the Edge WebView2 runtime. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/WebView2/Enumerations/wv2PermissionState.md b/docs/Reference/WebView2/Enumerations/wv2PermissionState.md index 595bf24a..722e142a 100644 --- a/docs/Reference/WebView2/Enumerations/wv2PermissionState.md +++ b/docs/Reference/WebView2/Enumerations/wv2PermissionState.md @@ -7,10 +7,10 @@ permalink: /tB/Packages/WebView2/Enumerations/wv2PermissionState # wv2PermissionState {: .no_toc } -The host's decision on a permission request. Carried as the **ByRef** `State` argument of the [**PermissionRequested**](../WebView2/#permissionrequested) event — assign one of these values to control whether the page is granted, denied, or left to the runtime's default behaviour. Mirrors the `COREWEBVIEW2_PERMISSION_STATE` enumeration. +The host's decision on a permission request. Passed as the **ByRef** `State` argument of the [**PermissionRequested**](../WebView2/#permissionrequested) event --- assign one of these values to control whether the page is granted, denied, or left to the runtime's default behaviour. Mirrors the `COREWEBVIEW2_PERMISSION_STATE` enumeration. | Constant | Value | Description | |----------|-------|-------------| -| **wv2StateDefault**{: #wv2StateDefault } | 0 | Let the runtime decide — typically prompts the user. | +| **wv2StateDefault**{: #wv2StateDefault } | 0 | Let the runtime decide --- typically prompts the user. | | **wv2StateAllow**{: #wv2StateAllow } | 1 | Grant the permission silently. | | **wv2StateDeny**{: #wv2StateDeny } | 2 | Deny the permission silently. | diff --git a/docs/Reference/WebView2/Enumerations/wv2PrintOrientation.md b/docs/Reference/WebView2/Enumerations/wv2PrintOrientation.md index 1e9f6f08..3ba7d43c 100644 --- a/docs/Reference/WebView2/Enumerations/wv2PrintOrientation.md +++ b/docs/Reference/WebView2/Enumerations/wv2PrintOrientation.md @@ -11,5 +11,5 @@ Page orientation passed to [**PrintToPdf**](../WebView2/#printtopdf) when writin | Constant | Value | Description | |----------|-------|-------------| -| **wv2PrintPortrait**{: #wv2PrintPortrait } | 0 | Default — pages are laid out with the long side vertical. | +| **wv2PrintPortrait**{: #wv2PrintPortrait } | 0 | Default --- pages are laid out with the long side vertical. | | **wv2PrintLandscape**{: #wv2PrintLandscape } | 1 | Pages are laid out with the long side horizontal. | diff --git a/docs/Reference/WebView2/Enumerations/wv2ProcessFailedKind.md b/docs/Reference/WebView2/Enumerations/wv2ProcessFailedKind.md index 1c4f6a81..47ec6051 100644 --- a/docs/Reference/WebView2/Enumerations/wv2ProcessFailedKind.md +++ b/docs/Reference/WebView2/Enumerations/wv2ProcessFailedKind.md @@ -7,11 +7,11 @@ permalink: /tB/Packages/WebView2/Enumerations/wv2ProcessFailedKind # wv2ProcessFailedKind {: .no_toc } -Identifies which of the external WebView2 processes failed. Carried as the `Kind` argument of the [**ProcessFailed**](../WebView2/#processfailed) event. Mirrors the `COREWEBVIEW2_PROCESS_FAILED_KIND` enumeration. +Identifies which of the external WebView2 processes failed. Passed as the `Kind` argument of the [**ProcessFailed**](../WebView2/#processfailed) event. Mirrors the `COREWEBVIEW2_PROCESS_FAILED_KIND` enumeration. | Constant | Value | Description | |----------|-------|-------------| -| **wv2BrowserProcessExited**{: #wv2BrowserProcessExited } | 0 | The main browser process exited unexpectedly — the control cannot be recovered. | +| **wv2BrowserProcessExited**{: #wv2BrowserProcessExited } | 0 | The main browser process exited unexpectedly --- the control cannot be recovered. | | **wv2RenderProcessExited**{: #wv2RenderProcessExited } | 1 | The renderer process exited unexpectedly. | | **wv2RenderProcessUnresponsive**{: #wv2RenderProcessUnresponsive } | 2 | The renderer process is hung. | | **wv2FrameRenderProcessExited**{: #wv2FrameRenderProcessExited } | 3 | A renderer process for one of the iframes exited. | diff --git a/docs/Reference/WebView2/Enumerations/wv2ScriptDialogKind.md b/docs/Reference/WebView2/Enumerations/wv2ScriptDialogKind.md index b5fac7aa..abce4629 100644 --- a/docs/Reference/WebView2/Enumerations/wv2ScriptDialogKind.md +++ b/docs/Reference/WebView2/Enumerations/wv2ScriptDialogKind.md @@ -7,11 +7,11 @@ permalink: /tB/Packages/WebView2/Enumerations/wv2ScriptDialogKind # wv2ScriptDialogKind {: .no_toc } -Identifies which JavaScript-dialog primitive the page is trying to open. Carried as the `ScriptDialogKind` argument of the [**ScriptDialogOpening**](../WebView2/#scriptdialogopening) event — the event only fires when **AreDefaultScriptDialogsEnabled** is **False**, so the application can implement its own dialogs. Mirrors the `COREWEBVIEW2_SCRIPT_DIALOG_KIND` enumeration. +Identifies which JavaScript-dialog primitive the page is trying to open. Passed as the `ScriptDialogKind` argument of the [**ScriptDialogOpening**](../WebView2/#scriptdialogopening) event --- the event only fires when **AreDefaultScriptDialogsEnabled** is **False**, so the application can implement its own dialogs. Mirrors the `COREWEBVIEW2_SCRIPT_DIALOG_KIND` enumeration. | Constant | Value | Description | |----------|-------|-------------| -| **wv2DialogAlert**{: #wv2DialogAlert } | 0 | `alert()` — a single-message notification with an *OK* button. | -| **wv2DialogConfirm**{: #wv2DialogConfirm } | 1 | `confirm()` — a question with *OK* and *Cancel*. | -| **wv2DialogPrompt**{: #wv2DialogPrompt } | 2 | `prompt()` — a text-input question with *OK* and *Cancel*. | +| **wv2DialogAlert**{: #wv2DialogAlert } | 0 | `alert()` --- a single-message notification with an *OK* button. | +| **wv2DialogConfirm**{: #wv2DialogConfirm } | 1 | `confirm()` --- a question with *OK* and *Cancel*. | +| **wv2DialogPrompt**{: #wv2DialogPrompt } | 2 | `prompt()` --- a text-input question with *OK* and *Cancel*. | | **wv2DialogBeforeUnload**{: #wv2DialogBeforeUnload } | 3 | The browser's *Leave this page?* confirmation raised by `beforeunload`. | diff --git a/docs/Reference/WebView2/Types/COREWEBVIEW2_PHYSICAL_KEY_STATUS.md b/docs/Reference/WebView2/Types/COREWEBVIEW2_PHYSICAL_KEY_STATUS.md index 749ce970..42e12c7d 100644 --- a/docs/Reference/WebView2/Types/COREWEBVIEW2_PHYSICAL_KEY_STATUS.md +++ b/docs/Reference/WebView2/Types/COREWEBVIEW2_PHYSICAL_KEY_STATUS.md @@ -7,12 +7,12 @@ permalink: /tB/Packages/WebView2/Types/COREWEBVIEW2_PHYSICAL_KEY_STATUS # COREWEBVIEW2_PHYSICAL_KEY_STATUS {: .no_toc } -The bit-fields the Win32 `WM_KEYDOWN` / `WM_KEYUP` message family packs into its `lParam`, decoded into a record. The control reads the runtime's `COREWEBVIEW2_PHYSICAL_KEY_STATUS` structure on each accelerator keystroke and splays it across individual arguments of the [**AcceleratorKeyPressed**](../WebView2/#acceleratorkeypressed) event — application code does not normally create instances of this type directly. +The bit-fields the Win32 `WM_KEYDOWN` / `WM_KEYUP` message family packs into its `lParam`, decoded into a record. The control reads the runtime's `COREWEBVIEW2_PHYSICAL_KEY_STATUS` structure on each accelerator keystroke and distributes it across individual arguments of the [**AcceleratorKeyPressed**](../WebView2/#acceleratorkeypressed) event --- application code does not normally create instances of this type directly. ```tb Public Type COREWEBVIEW2_PHYSICAL_KEY_STATUS RepeatCount As Long - ScanCode As Long + ScanCode As Long IsExtendedKey As Long IsMenuKeyDown As Long WasKeyDown As Long @@ -29,13 +29,13 @@ End Type : The hardware scan code of the pressed key. *IsExtendedKey* -: Non-zero when the key is one of the *extended* keys — right-hand **Alt** / **Ctrl**, the arrow / **Home** / **End** / **Page Up** / **Page Down** / **Insert** / **Delete** block, **NumLock**, and the numeric-keypad **Enter** and **/**. +: Non-zero when the key is one of the *extended* keys --- right-hand **Alt** / **Ctrl**, the arrow / **Home** / **End** / **Page Up** / **Page Down** / **Insert** / **Delete** block, **NumLock**, and the numeric-keypad **Enter** and **/**. *IsMenuKeyDown* : Non-zero when **Alt** was held while the message was generated. *WasKeyDown* -: Non-zero when the key was already down before this message — distinguishes the initial keystroke from subsequent auto-repeats. +: Non-zero when the key was already down before this message --- distinguishes the initial keystroke from subsequent auto-repeats. *IsKeyReleased* : Non-zero on the transition message reporting the key going up; zero on key-down messages. diff --git a/docs/Reference/WebView2/WebView2/EnvironmentOptions.md b/docs/Reference/WebView2/WebView2/EnvironmentOptions.md index 1454d036..4ab60c81 100644 --- a/docs/Reference/WebView2/WebView2/EnvironmentOptions.md +++ b/docs/Reference/WebView2/WebView2/EnvironmentOptions.md @@ -9,9 +9,9 @@ has_toc: false # WebView2EnvironmentOptions class {: .no_toc } -Carries the host's pre-creation configuration for the underlying WebView2 environment — folder layout, additional command-line arguments, locale, and a few policy switches. Surfaces on every [**WebView2**](.) control as its **EnvironmentOptions** property; the control instantiates one automatically before raising the [**Create**](.#create) event. +Holds the host's pre-creation configuration for the underlying WebView2 environment --- folder layout, additional command-line arguments, locale, and a few policy switches. Exposed on every [**WebView2**](.) control as its **EnvironmentOptions** property; the control instantiates one automatically before raising the [**Create**](.#create) event. -The fields below take effect only while the WebView2 environment is being constructed — that is, *before or during* the control's [**Create**](.#create) event. Assigning them after that point has no effect on the live environment. +The fields below take effect only while the WebView2 environment is being constructed --- that is, *before or during* the control's [**Create**](.#create) event. Assigning them after that point has no effect on the live environment. ```tb Private Sub WebView21_Create() @@ -21,14 +21,14 @@ Private Sub WebView21_Create() End Sub ``` -The type itself is `Private Class` — you reach instances only through the control's **EnvironmentOptions** property and cannot declare a variable typed as **WebView2EnvironmentOptions** from outside the package. +The type itself is `Private Class` --- instances are reachable only through the control's **EnvironmentOptions** property, and a variable typed as **WebView2EnvironmentOptions** cannot be declared from outside the package. ## Properties ### AdditionalBrowserArguments {: .no_toc } -Extra command-line switches passed straight through to the Edge browser process — same syntax as `msedge.exe`. **String**. Default: empty. +Extra command-line switches passed straight through to the Edge browser process --- same syntax as `msedge.exe`. **String**. Default: empty. ### AllowSingleSignOnUsingOSPrimaryAccount {: .no_toc } @@ -53,17 +53,17 @@ When **True**, the runtime locks the user-data folder so that no other WebView2 ### Language {: .no_toc } -The language and locale Edge should report in `Accept-Language` and use for its UI strings — BCP-47 form, e.g. `"en-GB"`, `"fr-FR"`. **String**. Default: empty (the runtime picks the system default). +The language and locale Edge should report in `Accept-Language` and use for its UI strings --- BCP-47 form, e.g. `"en-GB"`, `"fr-FR"`. **String**. Default: empty (the runtime picks the system default). ### TargetCompatibleBrowserVersion {: .no_toc } -The minimum Edge browser version this application is built against — used by the loader to decide whether a runtime can host it. **String**. Default: `"86.0.616.0"` (the minimum version that supports WebView2). +The minimum Edge browser version this application is built against --- used by the loader to decide whether a runtime can host it. **String**. Default: `"86.0.616.0"` (the minimum version that supports WebView2). ### UserDataFolder {: .no_toc } -Path to the folder Edge uses for the user profile — cache, cookies, history, local storage, password manager, and so on. Leave empty (the default) to let the runtime pick a folder beside the host executable; set it to keep user data outside the install location, e.g. under `%APPDATA%`. **String**. +Path to the folder Edge uses for the user profile --- cache, cookies, history, local storage, password manager, and so on. Leave empty (the default) to let the runtime pick a folder beside the host executable; set it to keep user data outside the install location, e.g. under `%APPDATA%`. **String**. Setting a writable user-data folder is the usual remedy for the *"Error occurred creating the WebView2 controller"* failure on installs that live under `Program Files`. diff --git a/docs/Reference/WebView2/WebView2/index.md b/docs/Reference/WebView2/WebView2/index.md index 63859afa..34dd1be2 100644 --- a/docs/Reference/WebView2/WebView2/index.md +++ b/docs/Reference/WebView2/WebView2/index.md @@ -8,9 +8,9 @@ has_toc: false # WebView2 class {: .no_toc } -A **WebView2** is a twinBASIC control that hosts the Microsoft Edge **WebView2** runtime — drop one onto a [**Form**](../../VB/Form/) and the running Edge engine renders web content inside its rectangle. Application code can navigate to URLs, run JavaScript, intercept HTTP requests, share BASIC objects with the page, post messages back and forth, and print the document to PDF. +A **WebView2** is a twinBASIC control that hosts the Microsoft Edge **WebView2** runtime --- drop one onto a [**Form**](../../VB/Form/) and the running Edge engine renders web content inside its rectangle. Application code can navigate to URLs, run JavaScript, intercept HTTP requests, share BASIC objects with the page, post messages back and forth, and print the document to PDF. -The control wraps the underlying `ICoreWebView2*` COM interfaces and exposes them as ordinary BASIC properties, methods, and events. Most of the work happens asynchronously inside the browser process — the control raises [**Ready**](#ready) once the WebView2 environment and controller have been created, and most members raise *"WebView2 control is not ready"* (run-time error 5) if called before then. +The control wraps the underlying `ICoreWebView2*` COM interfaces and exposes them as ordinary BASIC properties, methods, and events. Most of the work happens asynchronously inside the browser process --- the control raises [**Ready**](#ready) once the WebView2 environment and controller have been created, and most members raise *"WebView2 control is not ready"* (run-time error 5) if called before then. ```tb Private Sub Form_Load() @@ -39,32 +39,32 @@ A WebView2 control passes through three distinct phases between construction and | Event | When | |--------------------------------------|-------------------------------------------------------------------------------------------------------------------| | [**Create**](#create) | After the container window exists, before the WebView2 environment is built. Last chance to set [**EnvironmentOptions**](#environmentoptions). | -| [**Error**](#error) | The environment or controller could not be created — typically because the WebView2 runtime is missing. | +| [**Error**](#error) | The environment or controller could not be created --- typically because the WebView2 runtime is missing. | | [**Ready**](#ready) | The environment, controller, and core view are all live. The control is now fully functional. | -Calling navigation, scripting, or setting accessors before [**Ready**](#ready) raises run-time error 5 with the message *"WebView2 control is not ready"*. Where a setting depends on a newer runtime interface, the same error appears with *"The executing version of WebView2 does not support the requested feature"* instead — query the matching `Supports…Features` property first. +Calling navigation, scripting, or setting accessors before [**Ready**](#ready) raises run-time error 5 with the message *"WebView2 control is not ready"*. Where a setting depends on a newer runtime interface, the same error appears with *"The executing version of WebView2 does not support the requested feature"* instead --- query the matching `Supports…Features` property first. If the [**DocumentURL**](#documenturl) field has a non-empty value when [**Ready**](#ready) fires (the design-time default is `https://www.twinbasic.com`), the control auto-navigates to it. ## Deferred events -Several runtime callbacks — [**PermissionRequested**](#permissionrequested), [**NavigationStarting**](#navigationstarting), [**WebResourceRequested**](#webresourcerequested), [**ScriptDialogOpening**](#scriptdialogopening), [**DownloadStarting**](#downloadstarting), and [**NewWindowRequested**](#newwindowrequested) — are reentrant from the Edge side, meaning they fire on the WebView2 thread while it expects the host to either return synchronously or hold a *deferral* until the decision is made. Calling back into the control from inside a synchronous handler can deadlock the browser process. +Several runtime callbacks --- [**PermissionRequested**](#permissionrequested), [**NavigationStarting**](#navigationstarting), [**WebResourceRequested**](#webresourcerequested), [**ScriptDialogOpening**](#scriptdialogopening), [**DownloadStarting**](#downloadstarting), and [**NewWindowRequested**](#newwindowrequested) --- are reentrant from the Edge side, meaning they fire on the WebView2 thread while it expects the host to either return synchronously or hold a *deferral* until the decision is made. Calling back into the control from inside a synchronous handler can deadlock the browser process. -When [**UseDeferredEvents**](#usedeferredevents) is **True** (the default), the control takes the runtime's deferral on the host's behalf, posts the event onto the BASIC message-loop, and completes the deferral after the handler returns. Application code is therefore safe to call any other **WebView2** method from inside these events. Set [**UseDeferredEvents**](#usedeferredevents) to **False** only if you need synchronous semantics and have arranged your own re-entrancy guard. +When [**UseDeferredEvents**](#usedeferredevents) is **True** (the default), the control takes the runtime's deferral on the host's behalf, posts the event onto the BASIC message-loop, and completes the deferral after the handler returns. Application code is therefore safe to call any other **WebView2** method from inside these events. Set [**UseDeferredEvents**](#usedeferredevents) to **False** only when synchronous semantics are required and the host has arranged its own re-entrancy guard. -[**AcceleratorKeyPressed**](#acceleratorkeypressed) is always synchronous — its runtime arguments do not expose a deferral. +[**AcceleratorKeyPressed**](#acceleratorkeypressed) is always synchronous --- its runtime arguments do not expose a deferral. ## JavaScript interop The control offers three families of BASIC ↔ JavaScript bridges: -- **Host-object sharing** — [**AddObject**](#addobject) publishes a COM object to JavaScript under `chrome.webview.hostObjects.<Name>`. The page can call methods and read / write properties on the BASIC object directly. Requires [**AreHostObjectsAllowed**](#arehostobjectsallowed) (default **True**). Pass `UseDeferredInvoke:=True` if the page may call back during a BASIC operation, then accept that you cannot return values to the page. -- **Posting messages** — [**PostWebMessage**](#postwebmessage) sends a value to the page, where it shows up via `window.chrome.webview.addEventListener('message', …)`. The page replies with `window.chrome.webview.postMessage(…)`, which fires the [**JsMessage**](#jsmessage) event. Requires [**IsWebMessageEnabled**](#iswebmessageenabled) (default **True**). -- **Executing script** — [**JsRun**](#jsrun) calls a named JavaScript function and waits for the result, [**JsRunAsync**](#jsrunasync) calls one and fires [**JsAsyncResult**](#jsasyncresult) when the result arrives, [**JsProp**](#jsprop) evaluates an expression like `document.title`, and [**ExecuteScript**](#executescript) fires-and-forgets. +- **Host-object sharing** --- [**AddObject**](#addobject) publishes a COM object to JavaScript under `chrome.webview.hostObjects.<Name>`. The page can call methods and read / write properties on the BASIC object directly. Requires [**AreHostObjectsAllowed**](#arehostobjectsallowed) (default **True**). Pass `UseDeferredInvoke:=True` when the page may call back during a BASIC operation; with deferred invocation the host cannot return values to the page. +- **Posting messages** --- [**PostWebMessage**](#postwebmessage) sends a value to the page, where it shows up via `window.chrome.webview.addEventListener('message', …)`. The page replies with `window.chrome.webview.postMessage(…)`, which fires the [**JsMessage**](#jsmessage) event. Requires [**IsWebMessageEnabled**](#iswebmessageenabled) (default **True**). +- **Executing script** --- [**JsRun**](#jsrun) calls a named JavaScript function and waits for the result, [**JsRunAsync**](#jsrunasync) calls one and fires [**JsAsyncResult**](#jsasyncresult) when the result arrives, [**JsProp**](#jsprop) evaluates an expression like `document.title`, and [**ExecuteScript**](#executescript) fires-and-forgets. ## Intercepting requests -To rewrite, mock, or simply observe HTTP traffic from the page, register a URL filter with [**AddWebResourceRequestedFilter**](#addwebresourcerequestedfilter) and handle [**WebResourceRequested**](#webresourcerequested). The event arguments expose a [**WebView2Request**](../WebView2Request) (read-only metadata, mutable body) and a [**WebView2Response**](../WebView2Response) — assign **StatusCode**, **ReasonPhrase**, **Headers**, and content to the response object to short-circuit the network fetch; leave it untouched to let the runtime proceed normally. +To rewrite, mock, or simply observe HTTP traffic from the page, register a URL filter with [**AddWebResourceRequestedFilter**](#addwebresourcerequestedfilter) and handle [**WebResourceRequested**](#webresourcerequested). The event arguments expose a [**WebView2Request**](../WebView2Request) (read-only metadata, mutable body) and a [**WebView2Response**](../WebView2Response) --- assign **StatusCode**, **ReasonPhrase**, **Headers**, and content to the response object to short-circuit the network fetch; leave it untouched to let the runtime proceed normally. Properties ---------- @@ -84,17 +84,17 @@ The container-edge anchors that control automatic resizing when the parent **For ### AreBrowserAcceleratorKeysEnabled {: .no_toc } -Whether Edge's built-in accelerator keys are active — **F5** to reload, **Ctrl+P** to print, **Ctrl+F** to find in page, and so on. **Boolean**, default **True**. Requires [**SupportsAcceleratorKeysFeatures**](#supportsacceleratorkeysfeatures). +Whether Edge's built-in accelerator keys are active --- **F5** to reload, **Ctrl+P** to print, **Ctrl+F** to find in page, and so on. **Boolean**, default **True**. Requires [**SupportsAcceleratorKeysFeatures**](#supportsacceleratorkeysfeatures). ### AreDefaultContextMenusEnabled {: .no_toc } -Whether Edge's right-click context menu is shown. **Boolean**, default **True**. Set to **False** and handle [**UserContextMenu**](#usercontextmenu) to draw your own menu. +Whether Edge's right-click context menu is shown. **Boolean**, default **True**. Set to **False** and handle [**UserContextMenu**](#usercontextmenu) to draw a custom menu. ### AreDefaultScriptDialogsEnabled {: .no_toc } -Whether Edge shows its own dialogs for `alert()`, `confirm()`, `prompt()`, and the `beforeunload` confirmation. **Boolean**, default **True**. Set to **False** and handle [**ScriptDialogOpening**](#scriptdialogopening) to provide your own. +Whether Edge shows its own dialogs for `alert()`, `confirm()`, `prompt()`, and the `beforeunload` confirmation. **Boolean**, default **True**. Set to **False** and handle [**ScriptDialogOpening**](#scriptdialogopening) to provide custom dialogs. ### AreDevToolsEnabled {: .no_toc } @@ -144,7 +144,7 @@ Always **vbWebView2** ([**ControlTypeConstants**](../../VBRUN/Constants/ControlT ### DocumentTitle {: .no_toc } -The current document's `<title>` text. **String**. Read-only. Updated each time the page changes its title — the [**DocumentTitleChanged**](#documenttitlechanged) event fires on every update. +The current document's `<title>` text. **String**. Read-only. Updated each time the page changes its title --- the [**DocumentTitleChanged**](#documenttitlechanged) event fires on every update. ### DocumentURL {: .no_toc } @@ -159,7 +159,7 @@ A **StdPicture** used as the mouse cursor during a manual drag from this control ### DragMode {: .no_toc } -How drag-and-drop is initiated. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default — call [**Drag**](#drag) from code) or **vbAutomatic** (1). Inherited. +How drag-and-drop is initiated. A member of [**DragModeConstants**](../../VBRUN/Constants/DragModeConstants): **vbManual** (0, default --- call [**Drag**](#drag) from code) or **vbAutomatic** (1). Inherited. ### Enabled {: .no_toc } @@ -169,7 +169,7 @@ Whether the control accepts user input. **Boolean**, default **True**. Inherited ### EnvironmentOptions {: .no_toc } -The [**WebView2EnvironmentOptions**](EnvironmentOptions) object that configures the WebView2 environment — user-data folder, executable folder, locale, tracking-prevention, single-sign-on, and additional command-line arguments. The control auto-creates one on initialization; assign to its fields before or during the [**Create**](#create) event for them to take effect. +The [**WebView2EnvironmentOptions**](EnvironmentOptions) object that configures the WebView2 environment --- user-data folder, executable folder, locale, tracking-prevention, single-sign-on, and additional command-line arguments. The control auto-creates one on initialization; assign to its fields before or during the [**Create**](#create) event for them to take effect. ### Height {: .no_toc } @@ -179,7 +179,7 @@ The control's height. **Single**. Inherited. ### hWnd {: .no_toc } -The Win32 window handle of the *container* window that hosts the WebView2 surface — not the HWND of the Edge browser tab itself, which lives in a separate process. **LongPtr**. Read-only. Overrides the inherited definition. +The Win32 window handle of the *container* window that hosts the WebView2 surface --- not the HWND of the Edge browser tab itself, which lives in a separate process. **LongPtr**. Read-only. Overrides the inherited definition. ### Index {: .no_toc } @@ -279,62 +279,62 @@ The design-time name. **String**. Read-only at runtime. Inherited. ### SupportsAcceleratorKeysFeatures {: .no_toc } -Whether the loaded WebView2 runtime supports the accelerator-key settings — i.e. exposes `ICoreWebView2Settings3`. **Boolean**. Read-only. +Whether the loaded WebView2 runtime supports the accelerator-key settings --- i.e. exposes `ICoreWebView2Settings3`. **Boolean**. Read-only. ### SupportsAudioFeatures {: .no_toc } -Whether the loaded runtime supports the audio settings — i.e. exposes `ICoreWebView2_8`. **Boolean**. Read-only. +Whether the loaded runtime supports the audio settings --- i.e. exposes `ICoreWebView2_8`. **Boolean**. Read-only. ### SupportsAutoFillFeatures {: .no_toc } -Whether the loaded runtime supports the autofill settings — i.e. exposes `ICoreWebView2Settings4`. **Boolean**. Read-only. +Whether the loaded runtime supports the autofill settings --- i.e. exposes `ICoreWebView2Settings4`. **Boolean**. Read-only. ### SupportsDownloadDialogFeatures {: .no_toc } -Whether the loaded runtime supports controlling the download dialog — i.e. exposes `ICoreWebView2_9`. **Boolean**. Read-only. +Whether the loaded runtime supports controlling the download dialog --- i.e. exposes `ICoreWebView2_9`. **Boolean**. Read-only. ### SupportsFolderMappingFeatures {: .no_toc } -Whether the loaded runtime supports virtual-host-to-folder mapping — i.e. exposes `ICoreWebView2_5`. **Boolean**. Read-only. +Whether the loaded runtime supports virtual-host-to-folder mapping --- i.e. exposes `ICoreWebView2_5`. **Boolean**. Read-only. ### SupportsNavigateCustomFeatures {: .no_toc } -Whether the loaded runtime supports the custom-request navigation feature used by [**NavigateCustom**](#navigatecustom) — i.e. exposes `ICoreWebView2_2`. **Boolean**. Read-only. +Whether the loaded runtime supports the custom-request navigation feature used by [**NavigateCustom**](#navigatecustom) --- i.e. exposes `ICoreWebView2_2`. **Boolean**. Read-only. ### SupportsPdfFeatures {: .no_toc } -Whether the loaded runtime supports [**PrintToPdf**](#printtopdf) — i.e. exposes `ICoreWebView2_7`. **Boolean**. Read-only. +Whether the loaded runtime supports [**PrintToPdf**](#printtopdf) --- i.e. exposes `ICoreWebView2_7`. **Boolean**. Read-only. ### SupportsPinchZoomFeatures {: .no_toc } -Whether the loaded runtime supports the pinch-zoom setting — i.e. exposes `ICoreWebView2Settings5`. **Boolean**. Read-only. +Whether the loaded runtime supports the pinch-zoom setting --- i.e. exposes `ICoreWebView2Settings5`. **Boolean**. Read-only. ### SupportsSuspendResumeFeatures {: .no_toc } -Whether the loaded runtime supports [**Suspend**](#suspend) / [**Resume**](#resume) — i.e. exposes `ICoreWebView2_3`. **Boolean**. Read-only. +Whether the loaded runtime supports [**Suspend**](#suspend) / [**Resume**](#resume) --- i.e. exposes `ICoreWebView2_3`. **Boolean**. Read-only. ### SupportsSwipeNavigationFeatures {: .no_toc } -Whether the loaded runtime supports the swipe-navigation setting — i.e. exposes `ICoreWebView2Settings6`. **Boolean**. Read-only. +Whether the loaded runtime supports the swipe-navigation setting --- i.e. exposes `ICoreWebView2Settings6`. **Boolean**. Read-only. ### SupportsTaskManagerFeatures {: .no_toc } -Whether the loaded runtime supports [**OpenTaskManagerWindow**](#opentaskmanagerwindow) — i.e. exposes `ICoreWebView2_6`. **Boolean**. Read-only. +Whether the loaded runtime supports [**OpenTaskManagerWindow**](#opentaskmanagerwindow) --- i.e. exposes `ICoreWebView2_6`. **Boolean**. Read-only. ### SupportsUserAgentFeatures {: .no_toc } -Whether the loaded runtime supports the [**UserAgent**](#useragent) setting — i.e. exposes `ICoreWebView2Settings2`. **Boolean**. Read-only. +Whether the loaded runtime supports the [**UserAgent**](#useragent) setting --- i.e. exposes `ICoreWebView2Settings2`. **Boolean**. Read-only. ### TabIndex {: .no_toc } @@ -379,7 +379,7 @@ The control's width. **Single**. Inherited. ### ZoomFactor {: .no_toc } -The current zoom factor — `1.0` is 100%, `1.5` is 150%, and so on. **Double**. The design-time default is `0`, which means "do not override Edge's default of 1.0". +The current zoom factor --- `1.0` is 100%, `1.5` is 150%, and so on. **Double**. The design-time default is `0`, which means "do not override Edge's default of 1.0". > [!NOTE] > Because the design-time default is `0`, not `1.0`, arithmetic that multiplies the current value silently starts from zero unless the host clamps it to `1` first: @@ -406,7 +406,7 @@ Syntax: *object*.**AddObject** *ObjName*, *Object* [, *UseDeferredInvoke* ] : *required* An **Object** to publish. *UseDeferredInvoke* -: *optional* A **Boolean**, default **False**. When **True**, calls from the page are deferred onto the BASIC message-loop — safe to re-enter the WebView2 control from within them, but the page cannot read a return value back. Use **False** when the page needs to read return values. +: *optional* A **Boolean**, default **False**. When **True**, calls from the page are deferred onto the BASIC message-loop --- safe to re-enter the WebView2 control from within them, but the page cannot read a return value back. Use **False** when the page needs to read return values. ```tb Private Sub WebView21_Ready() @@ -427,12 +427,12 @@ async function callHostCalculator() { } ``` -Calls into the host object are asynchronous on the JavaScript side and must be `await`-ed inside an `async` function — even when *UseDeferredInvoke* is **False**. See the [Re-entrancy](../../../../Tutorials/WebView2/Re-entrancy) tutorial for when to pass **True**. +Calls into the host object are asynchronous on the JavaScript side and must be `await`-ed inside an `async` function --- even when *UseDeferredInvoke* is **False**. See the [Re-entrancy](../../../../Tutorials/WebView2/Re-entrancy) tutorial for when to pass **True**. ### AddScriptToExecuteOnDocumentCreated {: .no_toc } -Registers a JavaScript snippet to be run automatically at the top of every new document the WebView2 navigates to. Takes effect on the *next* navigation — does not affect the page currently loaded. +Registers a JavaScript snippet to be run automatically at the top of every new document the WebView2 navigates to. Takes effect on the *next* navigation --- does not affect the page currently loaded. Syntax: *object*.**AddScriptToExecuteOnDocumentCreated** *jsCode* @@ -499,7 +499,7 @@ Syntax: *object*.**Drag** [ *Action* ] ### ExecuteScript {: .no_toc } -Evaluates JavaScript in the page without waiting for it to finish and without returning its result. Use [**JsRun**](#jsrun) or [**JsRunAsync**](#jsrunasync) when you need the value. +Evaluates JavaScript in the page without waiting for it to finish and without returning its result. Use [**JsRun**](#jsrun) or [**JsRunAsync**](#jsrunasync) when the value is needed. Syntax: *object*.**ExecuteScript** *jsCode* @@ -523,14 +523,14 @@ Syntax: *object*.**GoForward** ### JsProp {: .no_toc } -Evaluates a JavaScript expression and returns the result synchronously — convenient for property reads like `document.title`. Waits up to [**JsCallTimeOutSeconds**](#jscalltimeoutseconds) for the result. +Evaluates a JavaScript expression and returns the result synchronously --- convenient for property reads like `document.title`. Waits up to [**JsCallTimeOutSeconds**](#jscalltimeoutseconds) for the result. Syntax: *object*.**JsProp** ( *PropName* ) **As Variant** *PropName* : *required* A **String** containing the expression to evaluate. -Returns the result decoded from the JSON the runtime returns — **Boolean**, **Double**, **String**, **Null**, or **Empty** (for `undefined`). Object and array results are not yet supported — accessing them raises run-time error 5. +Returns the result decoded from the JSON the runtime returns --- **Boolean**, **Double**, **String**, **Null**, or **Empty** (for `undefined`). Object and array results are not yet supported --- accessing them raises run-time error 5. ### JsRun {: .no_toc } @@ -540,7 +540,7 @@ Calls a named JavaScript function with the given arguments and returns the resul Syntax: *object*.**JsRun** ( *FuncName*, [ *args* ] ) **As Variant** *FuncName* -: *required* A **String** naming the JavaScript function — e.g. `"document.querySelector"`. +: *required* A **String** naming the JavaScript function --- e.g. `"document.querySelector"`. *args* : *optional* Any number of **Variant** arguments. Each is JSON-encoded before being passed to the function. Strings, numerics, **Boolean**, **Null**, and **Empty** are supported. @@ -589,7 +589,7 @@ Syntax: *object*.**Move** *Left* [, *Top* [, *Width* [, *Height* ] ] ] ### MoveFocus {: .no_toc } -Hands keyboard focus to the underlying WebView2 surface so that subsequent keystrokes are dispatched into the page. Distinct from the inherited [**SetFocus**](#setfocus), which focuses the host control window. +Transfers keyboard focus to the underlying WebView2 surface so that subsequent keystrokes are dispatched into the page. Distinct from the inherited [**SetFocus**](#setfocus), which focuses the host control window. Syntax: *object*.**MoveFocus** @@ -618,7 +618,7 @@ End Sub ### NavigateCustom {: .no_toc } -Navigates with an arbitrary HTTP method, optional headers, and an optional request body — useful for POST navigation or attaching authorization headers up front. Fires [**NavigationStarting**](#navigationstarting) and [**NavigationComplete**](#navigationcomplete). +Navigates with an arbitrary HTTP method, optional headers, and an optional request body --- useful for POST navigation or attaching authorization headers up front. Fires [**NavigationStarting**](#navigationstarting) and [**NavigationComplete**](#navigationcomplete). Syntax: *object*.**NavigateCustom** *uri*, *method* [, *headers* [, *postData* [, *postDataAsUTF8* ] ] ] @@ -626,13 +626,13 @@ Syntax: *object*.**NavigateCustom** *uri*, *method* [, *headers* [, *postData* [ : *required* A **String** URI. As with [**Navigate**](#navigate), a missing protocol prefix is patched to `https://`. *method* -: *required* A **String** HTTP method — `"GET"`, `"POST"`, … +: *required* A **String** HTTP method --- `"GET"`, `"POST"`, … *headers* : *optional* A **String** of `vbCrLf`-delimited `Header: value` lines. *postData* -: *optional* A **Variant** containing the body — a **String** (encoded according to *postDataAsUTF8*) or a **Byte()** array (used verbatim). +: *optional* A **Variant** containing the body --- a **String** (encoded according to *postDataAsUTF8*) or a **Byte()** array (used verbatim). *postDataAsUTF8* : *optional* A **Boolean**, default **True**. When **True** and *postData* is a **String**, the string is UTF-8-encoded before being sent. @@ -642,7 +642,7 @@ Requires [**SupportsNavigateCustomFeatures**](#supportsnavigatecustomfeatures). ### NavigateToString {: .no_toc } -Loads an HTML string directly into the WebView2 as if it were the body of an HTTP response — useful for splash screens, generated reports, or about pages. Fires [**NavigationStarting**](#navigationstarting) and [**NavigationComplete**](#navigationcomplete). +Loads an HTML string directly into the WebView2 as if it were the body of an HTTP response --- useful for splash screens, generated reports, or about pages. Fires [**NavigationStarting**](#navigationstarting) and [**NavigationComplete**](#navigationcomplete). Syntax: *object*.**NavigateToString** *htmlContent* @@ -708,7 +708,7 @@ window.chrome.webview.addEventListener('message', (e) => { ### PostWebMessageJSON {: .no_toc } -Posts a literal JSON string to the page without re-encoding it — useful when the caller already has serialised JSON. +Posts a literal JSON string to the page without re-encoding it --- useful when the caller already has serialised JSON. Syntax: *object*.**PostWebMessageJSON** *jsonString* @@ -720,7 +720,7 @@ Requires [**IsWebMessageEnabled**](#iswebmessageenabled). ### PrintToPdf {: .no_toc } -Saves the current document to a PDF file. The work happens asynchronously — the result arrives through [**PrintToPdfCompleted**](#printtopdfcompleted) or [**PrintToPdfFailed**](#printtopdffailed). Requires [**SupportsPdfFeatures**](#supportspdffeatures). +Saves the current document to a PDF file. The work happens asynchronously --- the result arrives through [**PrintToPdfCompleted**](#printtopdfcompleted) or [**PrintToPdfFailed**](#printtopdffailed). Requires [**SupportsPdfFeatures**](#supportspdffeatures). Syntax: *object*.**PrintToPdf** *outputPath* [, *Orientation* [, *ScaleFactor* [, *PageWidth* [, *PageHeight* [, *MarginTop* [, *MarginBottom* [, *MarginLeft* [, *MarginRight* [, *ShouldPrintBackgrounds* [, *ShouldPrintSelectionOnly* [, *ShouldPrintHeaderAndFooter* [, *HeaderTitle* [, *FooterUri* ] ] ] ] ] ] ] ] ] ] ] ] ] @@ -758,7 +758,7 @@ End Sub ### Reload {: .no_toc } -Reloads the current document — equivalent to pressing **F5**. +Reloads the current document --- equivalent to pressing **F5**. Syntax: *object*.**Reload** @@ -788,7 +788,7 @@ Syntax: *object*.**RemoveWebResourceRequestedFilter** *sFilter*, *FilterContext* ### Resume {: .no_toc } -Resumes a previously suspended WebView2 pipeline. Fires no event — read [**IsSuspended**](#issuspended) afterwards to confirm. +Resumes a previously suspended WebView2 pipeline. Fires no event --- read [**IsSuspended**](#issuspended) afterwards to confirm. Syntax: *object*.**Resume** @@ -804,7 +804,7 @@ Syntax: *object*.**SetFocus** ### SetVirtualHostNameToFolderMapping {: .no_toc } -Maps a virtual hostname to a local folder so that a page can reference local files through HTTPS URLs — e.g. `https://app.local/index.html` resolves to `C:\MyApp\html\index.html`. Useful for hosting local assets without setting up an HTTP server. +Maps a virtual hostname to a local folder so that a page can reference local files through HTTPS URLs --- e.g. `https://app.local/index.html` resolves to `C:\MyApp\html\index.html`. Useful for hosting local assets without setting up an HTTP server. Syntax: *object*.**SetVirtualHostNameToFolderMapping** *hostName*, *folderPath* [, *accessKind* ] @@ -818,7 +818,7 @@ Syntax: *object*.**SetVirtualHostNameToFolderMapping** *hostName*, *folderPath* : *optional* A member of [**wv2HostResourceAccessKind**](../Enumerations/wv2HostResourceAccessKind). Default **wv2ResourceAllow**. > [!NOTE] -> Pick the *hostName* carefully — certain DNS-resolvable hostnames cause a 2-second resolution stall before the local override kicks in. See [WebView2Feedback#2381](https://github.com/MicrosoftEdge/WebView2Feedback/issues/2381). +> Pick the *hostName* carefully --- certain DNS-resolvable hostnames cause a 2-second resolution stall before the local override kicks in. See [WebView2Feedback#2381](https://github.com/MicrosoftEdge/WebView2Feedback/issues/2381). Requires [**SupportsFolderMappingFeatures**](#supportsfoldermappingfeatures). @@ -836,7 +836,7 @@ See the [Hosting local web assets](../../../../Tutorials/WebView2/Hosting-Local- ### Suspend {: .no_toc } -Pauses the WebView2 pipeline so the browser process can free memory — useful for application-style tab management. Read [**IsSuspended**](#issuspended) afterwards to confirm; the runtime hides the control while suspended. +Pauses the WebView2 pipeline so the browser process can free memory --- useful for application-style tab management. Read [**IsSuspended**](#issuspended) afterwards to confirm; the runtime hides the control while suspended. Syntax: *object*.**Suspend** @@ -855,11 +855,11 @@ Events ### AcceleratorKeyPressed {: .no_toc } -Raised when Edge detects an accelerator-style keystroke — e.g. **F1**, **Alt+**, **Ctrl+**. Set *IsHandled* to **True** to consume the keystroke so Edge doesn't act on it. Always synchronous: cannot be deferred. +Raised when Edge detects an accelerator-style keystroke --- e.g. **F1**, **Alt+**, **Ctrl+**. Set *IsHandled* to **True** to consume the keystroke so Edge doesn't act on it. Always synchronous: cannot be deferred. Syntax: *object*\_**AcceleratorKeyPressed**( *KeyState* **As** [**wv2KeyEventKind**](../Enumerations/wv2KeyEventKind), *IsExtendedKey* **As Boolean**, *WasKeyDown* **As Boolean**, *IsKeyReleased* **As Boolean**, *IsMenuKeyDown* **As Boolean**, *RepeatCount* **As Long**, *ScanCode* **As Long**, *IsHandled* **As Boolean** ) -The flags are the contents of the Win32 `WM_KEYDOWN` / `WM_KEYUP` *lParam* — see [**COREWEBVIEW2_PHYSICAL_KEY_STATUS**](../Types/COREWEBVIEW2_PHYSICAL_KEY_STATUS) for the full breakdown. +The flags are the contents of the Win32 `WM_KEYDOWN` / `WM_KEYUP` *lParam* --- see [**COREWEBVIEW2_PHYSICAL_KEY_STATUS**](../Types/COREWEBVIEW2_PHYSICAL_KEY_STATUS) for the full breakdown. ### Create {: .no_toc } @@ -871,40 +871,40 @@ Syntax: *object*\_**Create**( ) ### DevToolsProtocolResponse {: .no_toc } -Raised when a previously sent [**CallDevToolsProtocolMethod**](#calldevtoolsprotocolmethod) call returns. Carries the *CustomEventId* supplied at the call site and the JSON-encoded response. +Raised when a previously sent [**CallDevToolsProtocolMethod**](#calldevtoolsprotocolmethod) call returns. Includes the *CustomEventId* supplied at the call site and the JSON-encoded response. Syntax: *object*\_**DevToolsProtocolResponse**( *CustomEventId* **As Variant**, *JsonResponse* **As String** ) ### DocumentTitleChanged {: .no_toc } -Raised when the document changes its title — typically right after a navigation, but also when client-side JavaScript writes to `document.title`. Read [**DocumentTitle**](#documenttitle) for the new value. +Raised when the document changes its title --- typically right after a navigation, but also when client-side JavaScript writes to `document.title`. Read [**DocumentTitle**](#documenttitle) for the new value. Syntax: *object*\_**DocumentTitleChanged**( ) ### DOMContentLoaded {: .no_toc } -Raised when the page reaches the `DOMContentLoaded` lifecycle event — the DOM tree is built and JavaScript can safely walk it, but external resources may still be loading. +Raised when the page reaches the `DOMContentLoaded` lifecycle event --- the DOM tree is built and JavaScript can safely walk it, but external resources may still be loading. Syntax: *object*\_**DOMContentLoaded**( ) ### DownloadStarting {: .no_toc } -Raised when the user (or the page) starts a file download. Set *Cancel* to **True** to suppress the download; set *Handled* to **True** to suppress the runtime's default download UI when you intend to manage progress yourself. Modify *ResultFilePath* to redirect the download to a different path. Can be deferred — see [Deferred events](#deferred-events). +Raised when the user (or the page) starts a file download. Set *Cancel* to **True** to suppress the download; set *Handled* to **True** to suppress the runtime's default download UI when the application intends to manage progress itself. Modify *ResultFilePath* to redirect the download to a different path. Can be deferred --- see [Deferred events](#deferred-events). Syntax: *object*\_**DownloadStarting**( *ResultFilePath* **As String**, *Cancel* **As Boolean**, *Handled* **As Boolean** ) ### Error {: .no_toc } -Raised when the WebView2 environment or controller fails to initialise — most commonly because the Edge WebView2 runtime isn't installed, the user-data folder isn't writable, or the fixed-version folder is incorrect. +Raised when the WebView2 environment or controller fails to initialise --- most commonly because the Edge WebView2 runtime isn't installed, the user-data folder isn't writable, or the fixed-version folder is incorrect. Syntax: *object*\_**Error**( *code* **As Long**, *msg* **As String** ) > [!NOTE] -> Code `&H80070002` (`ERROR_FILE_NOT_FOUND`) is the canonical signal that the WebView2 Evergreen runtime is missing from the machine — the right cue to prompt the user to install it. +> Code `&H80070002` (`ERROR_FILE_NOT_FOUND`) is the canonical signal that the WebView2 Evergreen runtime is missing from the machine --- the right cue to prompt the user to install it. ```tb Private Sub WebView21_Error(ByVal code As Long, ByVal msg As String) @@ -936,14 +936,14 @@ Syntax: *object*\_**JsMessage**( *Message* **As Variant** ) ### NavigationComplete {: .no_toc } -Raised after a navigation finishes — successfully or otherwise. Inspect *IsSuccess* first; if **False**, *WebErrorStatus* is a member of [**wv2ErrorStatus**](../Enumerations/wv2ErrorStatus). +Raised after a navigation finishes --- successfully or otherwise. Inspect *IsSuccess* first; if **False**, *WebErrorStatus* is a member of [**wv2ErrorStatus**](../Enumerations/wv2ErrorStatus). Syntax: *object*\_**NavigationComplete**( *IsSuccess* **As Boolean**, *WebErrorStatus* **As Long** ) ### NavigationStarting {: .no_toc } -Raised before each navigation begins. Set *Cancel* to **True** to block the navigation; modify *RequestHeaders* to alter the HTTP request the runtime is about to send. Can be deferred — see [Deferred events](#deferred-events). +Raised before each navigation begins. Set *Cancel* to **True** to block the navigation; modify *RequestHeaders* to alter the HTTP request the runtime is about to send. Can be deferred --- see [Deferred events](#deferred-events). Syntax: *object*\_**NavigationStarting**( *Uri* **As String**, *IsUserInitiated* **As Boolean**, *IsRedirected* **As Boolean**, *RequestHeaders* **As** [**WebView2RequestHeaders**](../WebView2RequestHeaders), *Cancel* **As Boolean** ) @@ -964,14 +964,14 @@ End Sub ### NewWindowRequested {: .no_toc } -Raised when the page tries to open a new window — via `window.open(…)`, `target="_blank"`, **Ctrl+** click, and so on. Set *IsHandled* to **True** to suppress the default behaviour (which opens a fresh Edge window) so the application can host the new content itself. The window-features arguments describe what the page asked for. Can be deferred — see [Deferred events](#deferred-events). +Raised when the page tries to open a new window --- via `window.open(…)`, `target="_blank"`, **Ctrl+** click, and so on. Set *IsHandled* to **True** to suppress the default behaviour (which opens a fresh Edge window) so the application can host the new content itself. The window-features arguments describe what the page asked for. Can be deferred --- see [Deferred events](#deferred-events). Syntax: *object*\_**NewWindowRequested**( *IsUserInitiated* **As Boolean**, *IsHandled* **As Boolean**, *Uri* **As String**, *HasPosition* **As Long**, *HasSize* **As Long**, *Left* **As Long**, *Top* **As Long**, *Width* **As Long**, *Height* **As Long**, *ShouldDisplayMenuBar* **As Long**, *ShouldDisplayStatus* **As Long**, *ShouldDisplayToolbar* **As Long**, *ShouldDisplayScrollBars* **As Long** ) ### PermissionRequested {: .no_toc } -Raised when the page asks for permission to use a device or browser capability — camera, microphone, geolocation, notifications, clipboard. Assign *State* to grant ([**wv2StateAllow**](../Enumerations/wv2PermissionState#wv2StateAllow)) or deny ([**wv2StateDeny**](../Enumerations/wv2PermissionState#wv2StateDeny)); leave it at **wv2StateDefault** to let Edge prompt the user. Can be deferred — see [Deferred events](#deferred-events). +Raised when the page asks for permission to use a device or browser capability --- camera, microphone, geolocation, notifications, clipboard. Assign *State* to grant ([**wv2StateAllow**](../Enumerations/wv2PermissionState#wv2StateAllow)) or deny ([**wv2StateDeny**](../Enumerations/wv2PermissionState#wv2StateDeny)); leave it at **wv2StateDefault** to let Edge prompt the user. Can be deferred --- see [Deferred events](#deferred-events). Syntax: *object*\_**PermissionRequested**( *IsUserInitiated* **As Boolean**, *State* **As** [**wv2PermissionState**](../Enumerations/wv2PermissionState), *Uri* **As String**, *PermissionKind* **As** [**wv2PermissionKind**](../Enumerations/wv2PermissionKind) ) @@ -985,14 +985,14 @@ Syntax: *object*\_**PrintToPdfCompleted**( ) ### PrintToPdfFailed {: .no_toc } -Raised when [**PrintToPdf**](#printtopdf) fails — e.g. the output path was not writable. +Raised when [**PrintToPdf**](#printtopdf) fails --- e.g. the output path was not writable. Syntax: *object*\_**PrintToPdfFailed**( ) ### ProcessFailed {: .no_toc } -Raised when one of WebView2's external processes (the browser, renderer, GPU, …) exits unexpectedly. Inspect *Kind* — a [**wv2ProcessFailedKind**](../Enumerations/wv2ProcessFailedKind) — to find out which. +Raised when one of WebView2's external processes (the browser, renderer, GPU, …) exits unexpectedly. Inspect *Kind* --- a [**wv2ProcessFailedKind**](../Enumerations/wv2ProcessFailedKind) --- to find out which. Syntax: *object*\_**ProcessFailed**( *Kind* **As** [**wv2ProcessFailedKind**](../Enumerations/wv2ProcessFailedKind) ) @@ -1006,14 +1006,14 @@ Syntax: *object*\_**Ready**( ) ### ScriptDialogOpening {: .no_toc } -Raised when the page tries to open a script dialog — `alert()`, `confirm()`, `prompt()`, or `beforeunload`. Only fires when [**AreDefaultScriptDialogsEnabled**](#aredefaultscriptdialogsenabled) is **False**. Set *Accept* to **True** to accept the dialog (the JavaScript-side equivalent of clicking *OK*); for prompts, update *ResultText* with the text to return. Can be deferred — see [Deferred events](#deferred-events). +Raised when the page tries to open a script dialog --- `alert()`, `confirm()`, `prompt()`, or `beforeunload`. Only fires when [**AreDefaultScriptDialogsEnabled**](#aredefaultscriptdialogsenabled) is **False**. Set *Accept* to **True** to accept the dialog (the JavaScript-side equivalent of clicking *OK*); for prompts, update *ResultText* with the text to return. Can be deferred --- see [Deferred events](#deferred-events). Syntax: *object*\_**ScriptDialogOpening**( *ScriptDialogKind* **As** [**wv2ScriptDialogKind**](../Enumerations/wv2ScriptDialogKind), *Accept* **As Boolean**, *ResultText* **As String**, *URI* **As String**, *Message* **As String**, *DefaultText* **As String** ) ### SourceChanged {: .no_toc } -Raised when [**DocumentURL**](#documenturl) changes — typically right after a navigation, but also when client-side script calls `history.pushState(…)`. *IsNewDocument* distinguishes a real navigation (**True**) from a same-document URL change (**False**). +Raised when [**DocumentURL**](#documenturl) changes --- typically right after a navigation, but also when client-side script calls `history.pushState(…)`. *IsNewDocument* distinguishes a real navigation (**True**) from a same-document URL change (**False**). Syntax: *object*\_**SourceChanged**( *IsNewDocument* **As Boolean** ) @@ -1027,7 +1027,7 @@ Syntax: *object*\_**SuspendCompleted**( ) ### SuspendFailed {: .no_toc } -Raised when a [**Suspend**](#suspend) request fails — typically because the page is still doing something the runtime cannot suspend. +Raised when a [**Suspend**](#suspend) request fails --- typically because the page is still doing something the runtime cannot suspend. Syntax: *object*\_**SuspendFailed**( ) @@ -1041,7 +1041,7 @@ Syntax: *object*\_**UserContextMenu**( *X* **As Single**, *Y* **As Single** ) ### WebResourceRequested {: .no_toc } -Raised when an in-flight HTTP request matches a filter previously registered with [**AddWebResourceRequestedFilter**](#addwebresourcerequestedfilter). Modify *Response* to mock or override the reply; leave it untouched to let the runtime fetch normally. Can be deferred — see [Deferred events](#deferred-events). +Raised when a pending HTTP request matches a filter previously registered with [**AddWebResourceRequestedFilter**](#addwebresourcerequestedfilter). Modify *Response* to mock or override the reply; leave it untouched to let the runtime fetch normally. Can be deferred --- see [Deferred events](#deferred-events). Syntax: *object*\_**WebResourceRequested**( *Request* **As** [**WebView2Request**](../WebView2Request), *Response* **As** [**WebView2Response**](../WebView2Response) ) diff --git a/docs/Reference/WebView2/WebView2Header.md b/docs/Reference/WebView2/WebView2Header.md index c414689e..bda810f2 100644 --- a/docs/Reference/WebView2/WebView2Header.md +++ b/docs/Reference/WebView2/WebView2Header.md @@ -8,7 +8,7 @@ has_toc: false # WebView2Header class {: .no_toc } -A single HTTP header — a name / value pair. **WebView2Header** is the element type produced by iterating a [**WebView2HeadersCollection**](WebView2HeadersCollection), which in turn comes from a [**WebView2RequestHeaders**](WebView2RequestHeaders) or [**WebView2ResponseHeaders**](WebView2ResponseHeaders) collection. +A single HTTP header --- a name / value pair. **WebView2Header** is the element type produced by iterating a [**WebView2HeadersCollection**](WebView2HeadersCollection), which in turn comes from a [**WebView2RequestHeaders**](WebView2RequestHeaders) or [**WebView2ResponseHeaders**](WebView2ResponseHeaders) collection. ```tb Dim h As WebView2Header @@ -42,7 +42,7 @@ Syntax: *object*.**Value** [ = *string* ] ### New {: .no_toc } -Constructs a header. Application code does not normally create headers manually — instances are produced by the package while iterating a request- or response-header collection — but the constructor is **Public**. +Constructs a header. Application code does not normally create headers manually --- instances are produced by the package while iterating a request- or response-header collection --- but the constructor is **Public**. Syntax: **New WebView2Header** ( *Name*, *Value* ) diff --git a/docs/Reference/WebView2/WebView2Request.md b/docs/Reference/WebView2/WebView2Request.md index 15433243..9db5c587 100644 --- a/docs/Reference/WebView2/WebView2Request.md +++ b/docs/Reference/WebView2/WebView2Request.md @@ -8,7 +8,7 @@ has_toc: false # WebView2Request class {: .no_toc } -The request side of a [**WebResourceRequested**](WebView2/#webresourcerequested) event. Surfaces the HTTP method, target URI, request headers, and request body of an in-flight WebView2 request, and lets the event handler edit the body before the runtime sends it. +The request side of a [**WebResourceRequested**](WebView2/#webresourcerequested) event. Exposes the HTTP method, target URI, request headers, and request body of a pending WebView2 request, and lets the event handler edit the body before the runtime sends it. To be notified, register a URL filter first with [**AddWebResourceRequestedFilter**](WebView2/#addwebresourcerequestedfilter); only requests whose URI matches the filter raise the event. @@ -40,7 +40,7 @@ Syntax: *object*.**ContentBytes** [ = *bytes* ] ### ContentUTF8 {: .no_toc } -The request body as a UTF-8 **String** — a convenience over [**ContentBytes**](#contentbytes) that does the `StrConv` round-trip for you. Read / write. +The request body as a UTF-8 **String** --- a convenience over [**ContentBytes**](#contentbytes) that performs the `StrConv` round-trip automatically. Read / write. Syntax: *object*.**ContentUTF8** [ = *text* ] @@ -50,7 +50,7 @@ Syntax: *object*.**ContentUTF8** [ = *text* ] ### Headers {: .no_toc } -The request's HTTP headers as a [**WebView2RequestHeaders**](WebView2RequestHeaders) collection — read or modify them before the request is sent. Read-only at the property level (the collection itself is mutable). +The request's HTTP headers as a [**WebView2RequestHeaders**](WebView2RequestHeaders) collection --- read or modify them before the request is sent. Read-only at the property level (the collection itself is mutable). ### Method {: .no_toc } diff --git a/docs/Reference/WebView2/WebView2RequestHeaders.md b/docs/Reference/WebView2/WebView2RequestHeaders.md index d4592377..5103e15e 100644 --- a/docs/Reference/WebView2/WebView2RequestHeaders.md +++ b/docs/Reference/WebView2/WebView2RequestHeaders.md @@ -10,7 +10,7 @@ has_toc: false The mutable HTTP-request-header collection for a navigation or a web-resource request. Reached two ways: -- As the **RequestHeaders** argument of the [**NavigationStarting**](WebView2/#navigationstarting) event — the headers that will be sent for the page navigation. Mutations made before the event handler returns are transmitted. +- As the **RequestHeaders** argument of the [**NavigationStarting**](WebView2/#navigationstarting) event --- the headers about to be sent for the page navigation. Mutations made before the event handler returns are transmitted. - Through [**WebView2Request.Headers**](WebView2Request#headers) when handling a [**WebResourceRequested**](WebView2/#webresourcerequested) event. The collection is enumerable: a `For Each` loop yields one [**WebView2Header**](WebView2Header) per entry. @@ -34,7 +34,7 @@ End Sub ### AppendHeader {: .no_toc } -Sets the value of a header — replacing the existing value if present, otherwise adding it. The underlying runtime call is `SetHeader`, so existing values for the named header are overwritten rather than appended; the method's name preserves twinBASIC's wrapping convention. +Sets the value of a header --- replacing the existing value if present, otherwise adding it. The underlying runtime call is `SetHeader`, so existing values for the named header are overwritten rather than appended; the method's name preserves twinBASIC's wrapping convention. Syntax: *object*.**AppendHeader** *name*, *value* @@ -67,7 +67,7 @@ Syntax: *object*.**GetHeader** ( *name* ) **As String** ### GetHeaders {: .no_toc } -Returns a [**WebView2HeadersCollection**](WebView2HeadersCollection) iterator restricted to the headers that match *name* — useful for headers that may have multiple values. +Returns a [**WebView2HeadersCollection**](WebView2HeadersCollection) iterator restricted to the headers that match *name* --- useful for headers that may have multiple values. Syntax: *object*.**GetHeaders** ( *name* ) **As WebView2HeadersCollection** diff --git a/docs/Reference/WebView2/WebView2Response.md b/docs/Reference/WebView2/WebView2Response.md index 19b1e5e9..a1b0656f 100644 --- a/docs/Reference/WebView2/WebView2Response.md +++ b/docs/Reference/WebView2/WebView2Response.md @@ -10,7 +10,7 @@ has_toc: false The response side of a [**WebResourceRequested**](WebView2/#webresourcerequested) event. Fill in any of [**StatusCode**](#statuscode), [**ReasonPhrase**](#reasonphrase), [**Headers**](#headers), or one of the content properties, and the runtime returns that synthesised response to the page instead of going to the network. -If the event handler does not touch the response (no property is written), the runtime falls through to its normal fetch — the in-flight request continues unchanged. +If the event handler does not touch the response (no property is written), the runtime falls through to its normal fetch --- the pending request continues unchanged. ```tb Private Sub Form_Load() @@ -43,7 +43,7 @@ Syntax: *object*.**ContentBytes** [ = *bytes* ] ### ContentUTF8 {: .no_toc } -The response body as a UTF-8 **String** — a convenience over [**ContentBytes**](#contentbytes) that does the `StrConv` round-trip for you. Read / write. +The response body as a UTF-8 **String** --- a convenience over [**ContentBytes**](#contentbytes) that performs the `StrConv` round-trip automatically. Read / write. Syntax: *object*.**ContentUTF8** [ = *text* ] @@ -53,7 +53,7 @@ Syntax: *object*.**ContentUTF8** [ = *text* ] ### Headers {: .no_toc } -The response's HTTP headers as a [**WebView2ResponseHeaders**](WebView2ResponseHeaders) collection — add or inspect headers here. Read-only at the property level (the collection itself is mutable). +The response's HTTP headers as a [**WebView2ResponseHeaders**](WebView2ResponseHeaders) collection --- add or inspect headers here. Read-only at the property level (the collection itself is mutable). ### ReasonPhrase {: .no_toc } diff --git a/docs/Reference/WebView2/WebView2ResponseHeaders.md b/docs/Reference/WebView2/WebView2ResponseHeaders.md index 43d1bbfd..d15d2ca4 100644 --- a/docs/Reference/WebView2/WebView2ResponseHeaders.md +++ b/docs/Reference/WebView2/WebView2ResponseHeaders.md @@ -10,7 +10,7 @@ has_toc: false The HTTP-response-header collection for a web-resource response. Reached through [**WebView2Response.Headers**](WebView2Response#headers) inside a [**WebResourceRequested**](WebView2/#webresourcerequested) event handler. -The collection is enumerable — `For Each` yields one [**WebView2Header**](WebView2Header) per entry. Unlike the request side, **AppendHeader** appends additional values rather than overwriting the existing one, matching HTTP's allowance of repeated response headers (e.g. multiple `Set-Cookie`). +The collection is enumerable --- `For Each` yields one [**WebView2Header**](WebView2Header) per entry. Unlike the request side, **AppendHeader** appends additional values rather than overwriting the existing one, matching HTTP's allowance of repeated response headers (e.g. multiple `Set-Cookie`). ```tb Private Sub WebView21_WebResourceRequested( _ @@ -29,7 +29,7 @@ End Sub ### AppendHeader {: .no_toc } -Appends a header — adds it to the collection even if an entry with the same name already exists. Repeated headers are legal in HTTP responses. +Appends a header --- adds it to the collection even if an entry with the same name already exists. Repeated headers are legal in HTTP responses. Syntax: *object*.**AppendHeader** *name*, *value* @@ -52,7 +52,7 @@ Syntax: *object*.**Contains** ( *name* ) **As Boolean** ### GetHeader {: .no_toc } -Returns the value of the named header — when there are several, the first. +Returns the value of the named header --- when there are several, the first. Syntax: *object*.**GetHeader** ( *name* ) **As String** diff --git a/docs/Reference/WebView2/index.md b/docs/Reference/WebView2/index.md index 536a28d0..a7bacc4b 100644 --- a/docs/Reference/WebView2/index.md +++ b/docs/Reference/WebView2/index.md @@ -9,11 +9,11 @@ has_toc: false # WebView2 Package -The **WebView2Package** wraps the Microsoft Edge WebView2 runtime and exposes it as an ordinary twinBASIC control. Drop a [**WebView2**](WebView2/) onto a form and the running Edge engine renders web content inside it — navigate to URLs, run JavaScript, intercept HTTP requests, post messages between BASIC and JavaScript, and print pages to PDF. +The **WebView2Package** wraps the Microsoft Edge WebView2 runtime and exposes it as an ordinary twinBASIC control. Drop a [**WebView2**](WebView2/) onto a form and the running Edge engine renders web content inside it --- navigate to URLs, run JavaScript, intercept HTTP requests, post messages between BASIC and JavaScript, and print pages to PDF. -The package is a built-in package shipped with twinBASIC. See the [WebView2 tutorials](../../../Tutorials/WebView2/) for how to reference it in your project, and worked samples. +The package is a built-in package shipped with twinBASIC. See the [WebView2 tutorials](../../../Tutorials/WebView2/) for how to reference it in a project, and worked samples. -Beyond the control itself, the package exposes a small set of wrapper objects that appear inside the control's event arguments — the request / response pair on **WebResourceRequested**, the request-header collection on **NavigationStarting**, the environment-options object configured before **Create** — together with the `wv2…` enumerations used to spell out option values. +Beyond the control itself, the package exposes a small set of wrapper objects that appear inside the control's event arguments --- the request / response pair on **WebResourceRequested**, the request-header collection on **NavigationStarting**, the environment-options object configured before **Create** --- together with the `wv2…` enumerations used to spell out option values. ## Classes @@ -21,9 +21,9 @@ Beyond the control itself, the package exposes a small set of wrapper objects th - [WebView2EnvironmentOptions](WebView2/EnvironmentOptions) -- pre-creation configuration for the WebView2 environment (user-data folder, executable folder, locale, tracking-prevention, …); reached via the control's **EnvironmentOptions** property - [WebView2Header](WebView2Header) -- one HTTP header (Name / Value); the element type yielded by header iteration - [WebView2HeadersCollection](WebView2HeadersCollection) -- enumerable wrapper used by `For Each` over request / response headers -- [WebView2Request](WebView2Request) -- the request side of a **WebResourceRequested** event — **Method**, **Uri**, **Headers**, and the request body as bytes or UTF-8 text +- [WebView2Request](WebView2Request) -- the request side of a **WebResourceRequested** event -- **Method**, **Uri**, **Headers**, and the request body as bytes or UTF-8 text - [WebView2RequestHeaders](WebView2RequestHeaders) -- mutable request-header collection passed to **NavigationStarting** and reached via **WebView2Request.Headers** -- [WebView2Response](WebView2Response) -- the response side of a **WebResourceRequested** event — **StatusCode**, **ReasonPhrase**, **Headers**, and the body as bytes or UTF-8 text +- [WebView2Response](WebView2Response) -- the response side of a **WebResourceRequested** event -- **StatusCode**, **ReasonPhrase**, **Headers**, and the body as bytes or UTF-8 text - [WebView2ResponseHeaders](WebView2ResponseHeaders) -- mutable response-header collection reached via **WebView2Response.Headers** ## Enumerations @@ -47,7 +47,7 @@ Beyond the control itself, the package exposes a small set of wrapper objects th - [Getting started](../../../Tutorials/WebView2/Getting-Started) -- adding the package references and dropping a control onto a form - [Customize the UserDataFolder](../../../Tutorials/WebView2/Customize-UserDataFolder) -- relocating the runtime's working folder for hosted scenarios (Office add-ins, kiosk installs) -- [Re-entrancy](../../../Tutorials/WebView2/Re-entrancy) -- what the control's deferred-event machinery does for you, and the **AddObject** synchronous-vs-deferred trade-off +- [Re-entrancy](../../../Tutorials/WebView2/Re-entrancy) -- what the control's deferred-event machinery handles automatically, and the **AddObject** synchronous-vs-deferred trade-off - [Building a browser shell](../../../Tutorials/WebView2/Building-A-Browser-Shell) -- address bar, back / forward / reload, zoom, PDF export - [Hosting local web assets](../../../Tutorials/WebView2/Hosting-Local-Web-Assets) -- serve HTML / JS / CSS from a project resource folder, without an HTTP server - [JavaScript interop](../../../Tutorials/WebView2/JavaScript-Interop) -- the three bridges between BASIC and the page: host objects, messages, and scripted calls diff --git a/docs/Reference/WinEventLogLib/EventLog.md b/docs/Reference/WinEventLogLib/EventLog.md index 37284e73..a588548c 100644 --- a/docs/Reference/WinEventLogLib/EventLog.md +++ b/docs/Reference/WinEventLogLib/EventLog.md @@ -19,7 +19,7 @@ Syntax: **New EventLog(Of** *T1*, *T2* **)** ( *LogName* ) : *required* The enumeration type whose members name the categories events fall into. Passed as the *CategoryId* argument of [**LogSuccess**](#logsuccess) / [**LogFailure**](#logfailure). The number of categories declared in *T2* is what [**Register**](#register) writes as the registry's `CategoryCount`. *LogName* -: *required* A **String** naming the event source. A leaf name like `"MyService"` is registered under the **Application** log (`Application\MyService`); a path like `"System\MyService"` is registered under the named parent log. The trailing segment is the source name — it appears in the Event Viewer's **Source** column. +: *required* A **String** naming the event source. A leaf name like `"MyService"` is registered under the **Application** log (`Application\MyService`); a path like `"System\MyService"` is registered under the named parent log. The trailing segment is the source name --- it appears in the Event Viewer's **Source** column. ```tb Public Enum MyEventIds @@ -35,9 +35,9 @@ End Enum Dim Log As New EventLog(Of MyEventIds, MyCategories)("MyService") ``` -Both type arguments are required at instantiation — twinBASIC does not deduce them from the *LogName* constructor argument. See the [Generics](../../../Features/Language/Generics) page for the general rules. +Both type arguments are required at instantiation --- twinBASIC does not deduce them from the *LogName* constructor argument. See the [Generics](../../../Features/Language/Generics) page for the general rules. -A class that needs to expose [**LogSuccess**](#logsuccess) / [**LogFailure**](#logfailure) / [**Register**](#register) as if those methods were its own can mix the **EventLog** members in through [**Implements ... Via**](../../../Features/Language/Inheritance) composition — see the [composition-delegation idiom](.#composition-delegation-idiom) section on the package overview for the canonical service-class pattern. +A class that needs to expose [**LogSuccess**](#logsuccess) / [**LogFailure**](#logfailure) / [**Register**](#register) as if those methods were its own can mix the **EventLog** members in through [**Implements ... Via**](../../../Features/Language/Inheritance) composition --- see the [composition-delegation idiom](.#composition-delegation-idiom) section on the package overview for the canonical service-class pattern. The package [overview](.) covers the install-then-log lifecycle, the [`[PopulateFrom("json", ...)]` message-resource convention](.#populatefrom-convention), registry layout, and the [composition-delegation idiom](.#composition-delegation-idiom). @@ -63,7 +63,7 @@ Syntax: *object*.**LogFailure** *EventId*, *CategoryId* [, *AdditionalStrings* . : *optional* A **ParamArray** of values inserted into the event's message string at the `%1`, `%2`, … placeholders. Each value is converted to a **String** before being passed to `ReportEventW`. > [!NOTE] -> Despite the name, **LogFailure** writes an **Error** entry — the Windows event type `EVENTLOG_ERROR_TYPE` (= 1). It does *not* write an *Audit Failure* entry. That event type, and *Warning* and *Audit Success*, are not currently reachable through this class. +> Despite the name, **LogFailure** writes an **Error** entry --- the Windows event type `EVENTLOG_ERROR_TYPE` (= 1). It does *not* write an *Audit Failure* entry. That event type, and *Warning* and *Audit Success*, are not currently reachable through this class. The first call after construction lazily resolves the source handle via `RegisterEventSourceW`; if [**Register**](#register) has not been run for this *LogName*, the entry is still written but the Event Viewer cannot resolve the message strings and shows *"The description for Event ID X cannot be found"*. @@ -84,7 +84,7 @@ Syntax: *object*.**LogSuccess** *EventId*, *CategoryId* [, *AdditionalStrings* . : *optional* A **ParamArray** of values inserted into the event's message string at the `%1`, `%2`, … placeholders. > [!NOTE] -> The Windows event type for this call is `EVENTLOG_SUCCESS` (= 0), which is the Win32 SDK's literal name for the **Information** event type — *not* an Audit Success entry. The class spells the method **LogSuccess** to track the SDK constant, but the entries you read back in `eventvwr.msc` are tagged **Information**. +> The Windows event type for this call is `EVENTLOG_SUCCESS` (= 0), which is the Win32 SDK's literal name for the **Information** event type --- *not* an Audit Success entry. The class spells the method **LogSuccess** to track the SDK constant, but the entries that appear in `eventvwr.msc` are tagged **Information**. ### New {: .no_toc } @@ -96,7 +96,7 @@ Syntax: **New EventLog(Of** *T1*, *T2* **)** ( *LogName* ) *LogName* : *required* A **String** naming the source. See the top of this page for the leaf-name vs full-path syntax. -The constructor only stores *LogName*. The first call to [**LogSuccess**](#logsuccess) / [**LogFailure**](#logfailure) lazily acquires the Win32 source handle via `RegisterEventSourceW`. [**Register**](#register) writes the registry entries the Event Viewer reads when rendering messages — it must be run separately, once, with admin rights. +The constructor only stores *LogName*. The first call to [**LogSuccess**](#logsuccess) / [**LogFailure**](#logfailure) lazily acquires the Win32 source handle via `RegisterEventSourceW`. [**Register**](#register) writes the registry entries the Event Viewer reads when rendering messages --- it must be run separately, once, with admin rights. ### Register {: .no_toc } @@ -112,16 +112,16 @@ Creates `HKLM\SYSTEM\CurrentControlSet\Services\EventLog\<LogPath>` (prepending - **CategoryCount** = the largest declared value in *T2*, resolved at compile time via [**GetDeclaredMaxEnumValue**](../../Modules/HiddenModule/GetDeclaredMaxEnumValue)`(Of T2)` > [!IMPORTANT] -> **Register** requires administrator rights — it writes to `HKEY_LOCAL_MACHINE`. The usual pattern is to call it once from an elevated installer, not from the application's normal startup path. +> **Register** requires administrator rights --- it writes to `HKEY_LOCAL_MACHINE`. The usual pattern is to call it once from an elevated installer, not from the application's normal startup path. The Event Viewer renders message strings by loading **EventMessageFile** and looking up the message resource keyed by *EventId*. Because **EventMessageFile** points at `App.ModulePath`, the same EXE that calls **Register** must be the one that later calls [**LogSuccess**](#logsuccess) / [**LogFailure**](#logfailure); otherwise the Event Viewer cannot find the message strings. See [Message resources](.#message-resources) and [The `[PopulateFrom("json", ...)]` convention](.#populatefrom-convention) on the package landing page for the recommended way to populate the resource. If the registry key cannot be opened for write, **Register** raises run-time error 5 *"Failed to register event log source (\<LogName\>)"*. Typical causes are insufficient privileges and a *LogPath* that points at a non-existent parent log. -The lower-level [**EventLogHelperPublic.RegisterEventLogInternal**](EventLogHelperPublic#registereventloginternal) is what **Register** delegates to; use it directly only if you need to register a source without binding it to a generic *T2* (and so without using **GetDeclaredMaxEnumValue** to derive the category count). +The lower-level [**EventLogHelperPublic.RegisterEventLogInternal**](EventLogHelperPublic#registereventloginternal) is what **Register** delegates to; use it directly only when registering a source without binding it to a generic *T2* (and so without using **GetDeclaredMaxEnumValue** to derive the category count). ## See Also -- [WinEventLogLib package](.) -- overview, lifecycle, message-resource generation -- [EventLogHelperPublic module](EventLogHelperPublic) -- the lower-level registration helper -- [Generics feature](../../../Features/Language/Generics) -- syntax rules for generic class instantiation +- [WinEventLogLib](.) package -- overview, lifecycle, message-resource generation +- [EventLogHelperPublic](EventLogHelperPublic) module -- the lower-level registration helper +- [Generics](../../../Features/Language/Generics) feature -- syntax rules for generic class instantiation diff --git a/docs/Reference/WinEventLogLib/EventLogHelperPublic.md b/docs/Reference/WinEventLogLib/EventLogHelperPublic.md index e71f78ab..1a855d02 100644 --- a/docs/Reference/WinEventLogLib/EventLogHelperPublic.md +++ b/docs/Reference/WinEventLogLib/EventLogHelperPublic.md @@ -8,7 +8,7 @@ has_toc: false # EventLogHelperPublic module {: .no_toc } -A single low-level helper that writes the registry entries Windows reads when rendering Event Log messages. Most projects do not call into this module directly — [**EventLog.Register**](EventLog#register) wraps the call and automatically supplies the category count from the *T2* type argument. Use **EventLogHelperPublic** only when registering a source outside the generic [**EventLog**](EventLog) class (for example, when the category count cannot be derived from a declared enum). +A single low-level helper that writes the registry entries Windows reads when rendering Event Log messages. Most projects do not call into this module directly --- [**EventLog.Register**](EventLog#register) wraps the call and automatically supplies the category count from the *T2* type argument. Use **EventLogHelperPublic** only when registering a source outside the generic [**EventLog**](EventLog) class (for example, when the category count cannot be derived from a declared enum). * TOC {:toc} @@ -23,7 +23,7 @@ Syntax: **EventLogHelperPublic.RegisterEventLogInternal** *LogPath*, *CategoryCo : *required* A **String** naming the source. A leaf name like `"MyService"` is registered under the **Application** log (rewritten internally to `"Application\MyService"`); a full path like `"System\MyService"` is registered under the named parent log. The trailing segment is the source name displayed in the Event Viewer's **Source** column. *CategoryCount* -: *required* A **Long** giving the number of categories declared for this source — the largest value in the corresponding category enum. Stored as the registry's `CategoryCount` DWORD; the Event Viewer uses it to bound category-string lookups in the EXE's message-table resource. +: *required* A **Long** giving the number of categories declared for this source --- the largest value in the corresponding category enum. Stored as the registry's `CategoryCount` DWORD; the Event Viewer uses it to bound category-string lookups in the EXE's message-table resource. Creates `HKLM\SYSTEM\CurrentControlSet\Services\EventLog\<LogPath>` and writes: @@ -38,5 +38,5 @@ If the registry key cannot be opened for write, **RegisterEventLogInternal** rai ## See Also -- [WinEventLogLib package](.) -- overview, lifecycle, message-resource generation -- [EventLog class](EventLog) -- the generic class whose [**Register**](EventLog#register) method wraps this helper +- [WinEventLogLib](.) package -- overview, lifecycle, message-resource generation +- [EventLog](EventLog) class -- the generic class whose [**Register**](EventLog#register) method wraps this helper diff --git a/docs/Reference/WinEventLogLib/index.md b/docs/Reference/WinEventLogLib/index.md index 8e7ddc49..f8e98663 100644 --- a/docs/Reference/WinEventLogLib/index.md +++ b/docs/Reference/WinEventLogLib/index.md @@ -10,7 +10,7 @@ has_toc: false # WinEventLogLib Package {: .no_toc } -The **WinEventLogLib** built-in package writes entries to the Windows Event Log from twinBASIC. Define two enumerations — one naming the event IDs your application can report, one naming the categories those events belong to — and the generic [**EventLog**](EventLog) class handles registration, registry setup, and the per-event `ReportEventW` call. +The **WinEventLogLib** built-in package writes entries to the Windows Event Log from twinBASIC. Define two enumerations --- one naming the event IDs the application can report, one naming the categories those events belong to --- and the generic [**EventLog**](EventLog) class handles registration, registry setup, and the per-event `ReportEventW` call. The package is a built-in package shipped with twinBASIC. Add it through Project → References (**Ctrl-T**) → Available Packages. @@ -21,7 +21,7 @@ The package is a built-in package shipped with twinBASIC. Add it through Project A typical use has three stages: -1. **Declare** two enumerations — the event IDs and the categories — anywhere in the project. The values you assign become the numeric **Event ID** and **Category** columns visible in `eventvwr.msc`. +1. **Declare** two enumerations --- the event IDs and the categories --- anywhere in the project. The assigned values become the numeric **Event ID** and **Category** columns visible in `eventvwr.msc`. 2. **Register** once, with administrator rights, at install time. Construct an [**EventLog**](EventLog) instance and call [**Register**](EventLog#register); this writes the source key under `HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\<LogName>` and points the registry's **EventMessageFile** and **CategoryMessageFile** entries at the running EXE. Without this step, the Event Viewer shows *"The description for Event ID X cannot be found"* for every entry. 3. **Log** at runtime, without elevation. Construct the same [**EventLog**](EventLog) with the same *LogName* and call [**LogSuccess**](EventLog#logsuccess) or [**LogFailure**](EventLog#logfailure) whenever the application has something to report. @@ -50,7 +50,7 @@ Sub OnServiceStart() End Sub ``` -The same EXE that calls [**Register**](EventLog#register) must be the one that calls [**LogSuccess**](EventLog#logsuccess) / [**LogFailure**](EventLog#logfailure) — the registered **EventMessageFile** points at `App.ModulePath`, and the Event Viewer reads message strings out of that file when rendering entries. +The same EXE that calls [**Register**](EventLog#register) must be the one that calls [**LogSuccess**](EventLog#logsuccess) / [**LogFailure**](EventLog#logfailure) --- the registered **EventMessageFile** points at `App.ModulePath`, and the Event Viewer reads message strings out of that file when rendering entries. For service / long-running classes that should expose [**LogSuccess**](EventLog#logsuccess) / [**LogFailure**](EventLog#logfailure) / [**Register**](EventLog#register) as if those methods were their own, see the [composition-delegation idiom](#composition-delegation-idiom) below. @@ -71,22 +71,22 @@ Class MyService End Class ``` -The `Implements <Class> Via <field> = <expression>` clause declares a private field, evaluates the constructor expression once on first use, and forwards every public member of [**EventLog**](EventLog) — [**LogSuccess**](EventLog#logsuccess), [**LogFailure**](EventLog#logfailure), and [**Register**](EventLog#register) — through that field. Inside `MyService` the three methods read as if they were declared on the class itself. +The `Implements <Class> Via <field> = <expression>` clause declares a private field, evaluates the constructor expression once on first use, and forwards every public member of [**EventLog**](EventLog) --- [**LogSuccess**](EventLog#logsuccess), [**LogFailure**](EventLog#logfailure), and [**Register**](EventLog#register) --- through that field. Inside `MyService` the three methods read as if they were declared on the class itself. Two things to remember: -- The *T1* / *T2* type arguments must match between the `Implements` declaration and the constructor expression — the compiler enforces this. +- The *T1* / *T2* type arguments must match between the `Implements` declaration and the constructor expression --- the compiler enforces this. - Using `"Application\" & CurrentComponentName` as the *LogName* makes the log path automatically track the class name at compile time; renaming the class renames the source it logs to. This is the canonical mix-in pattern for [**WinServicesLib**](../WinServicesLib/) service classes (every service class in a project that shares one set of event IDs inherits logging methods without per-class boilerplate). The same pattern works for any class that wants the [**EventLog**](EventLog) members available directly. -A class can use `Implements ... Via` on [**EventLog**](EventLog)`(Of T1, T2)` only **once**. When several classes in the same project need to share logging, declare a single module with one event-ID enum and one category enum and `Implements ... Via` against that pair from every class. Multiple unrelated message tables are still possible — they just have to be reached through explicitly-named [**EventLog**](EventLog) fields rather than the `Implements ... Via` shortcut. +A class can use `Implements ... Via` on [**EventLog**](EventLog)`(Of T1, T2)` only **once**. When several classes in the same project need to share logging, declare a single module with one event-ID enum and one category enum and `Implements ... Via` against that pair from every class. Multiple unrelated message tables are still possible --- they just have to be reached through explicitly-named [**EventLog**](EventLog) fields rather than the `Implements ... Via` shortcut. ## Message resources The Windows Event Log stores only numeric **Event ID** and **Category** values; the human-readable strings live in a message-table resource embedded in the EXE pointed to by the registered **EventMessageFile** / **CategoryMessageFile** entries. Without this resource the Event Viewer cannot render entries and instead shows *"The description for Event ID X cannot be found"*. -For the generic [**EventLog**](EventLog)`(Of T1, T2)` class, the *T1* (event IDs) and *T2* (categories) enum declarations are the source of those strings — the class points the registry at the running EXE and the Event Viewer looks for a message-table resource keyed by the enum member values. Authoring the resource directly (a `.mc` file fed to `mc.exe`, embedded as a resource section) is one route; the convention shown below keeps the enums, the message strings, and the resource emission in lockstep from a single JSON file using twinBASIC's [`[PopulateFrom]`](../../Core/Attributes#populatefrom) enum-population attribute. +For the generic [**EventLog**](EventLog)`(Of T1, T2)` class, the *T1* (event IDs) and *T2* (categories) enum declarations are the source of those strings --- the class points the registry at the running EXE and the Event Viewer looks for a message-table resource keyed by the enum member values. Authoring the resource directly (a `.mc` file fed to `mc.exe`, embedded as a resource section) is one route; the convention shown below keeps the enums, the message strings, and the resource emission in lockstep from a single JSON file using twinBASIC's [`[PopulateFrom]`](../../Core/Attributes#populatefrom) enum-population attribute. ### The `[PopulateFrom("json", ...)]` convention {: #populatefrom-convention } @@ -107,7 +107,7 @@ End Module The five [`[PopulateFrom]`](../../Core/Attributes#populatefrom) arguments are: the resource format (`"json"`), the project-relative path to the file, the JSON array to read entries from (`"events"` for the events stub, `"categories"` for the categories stub), the field name supplying each enum member's identifier, and the field name supplying its numeric value. -`Resources/MESSAGETABLE/Strings.json` has one entry per event and one per category. Each entry has three fields — a numeric `id`, an enum-member `name`, and the per-locale message text under an `LCID_XXXX` key: +`Resources/MESSAGETABLE/Strings.json` has one entry per event and one per category. Each entry has three fields --- a numeric `id`, an enum-member `name`, and the per-locale message text under an `LCID_XXXX` key: ```json { @@ -122,7 +122,7 @@ The five [`[PopulateFrom]`](../../Core/Attributes#populatefrom) arguments are: t } ``` -The compiler reads the JSON at build time and populates each enum body — `Enum EVENTS` ends up with `service_started = -1073610751`, `service_startup_failed = -1073610750`, … — while emitting the message-table resource into the produced EXE. The `LCID_0000` strings (locale-neutral) become the message templates; substitute / add `LCID_0409` (US English), `LCID_040C` (French), etc. for localised projects. +The compiler reads the JSON at build time and populates each enum body --- `Enum EVENTS` ends up with `service_started = -1073610751`, `service_startup_failed = -1073610750`, … --- while emitting the message-table resource into the produced EXE. The `LCID_0000` strings (locale-neutral) become the message templates; substitute / add `LCID_0409` (US English), `LCID_040C` (French), etc. for localised projects. Once the JSON, the enum stubs, and the registry entries written by [**Register**](EventLog#register) are in place, a runtime call @@ -131,20 +131,20 @@ Dim Log As New EventLog(Of MESSAGETABLE.EVENTS, MESSAGETABLE.CATEGORIES)("Applic Log.LogSuccess service_started, status_changed, "MyService" ``` -writes an event the Event Viewer renders as *"MyService service started"* — the `%1` placeholder filled from the [**LogSuccess**](EventLog#logsuccess) *AdditionalStrings* `ParamArray`, the `status_changed` category resolved against the message table, both keyed by the numeric values the enums define. +writes an event the Event Viewer renders as *"MyService service started"* --- the `%1` placeholder filled from the [**LogSuccess**](EventLog#logsuccess) *AdditionalStrings* `ParamArray`, the `status_changed` category resolved against the message table, both keyed by the numeric values the enums define. -The negative event-ID values in the JSON (`-1073610751` etc.) follow the Win32 documented event-ID bit layout — the high bits encode severity, facility, and customer-defined flags. See Microsoft's *"Event Identifiers"* reference for the encoding; pick fresh IDs for new events and don't reuse identifiers across products. +The negative event-ID values in the JSON (`-1073610751` etc.) follow the Win32 documented event-ID bit layout --- the high bits encode severity, facility, and customer-defined flags. See Microsoft's *"Event Identifiers"* reference for the encoding; pick fresh IDs for new events and don't reuse identifiers across products. ## Log Type -[**LogSuccess**](EventLog#logsuccess) and [**LogFailure**](EventLog#logfailure) are the only entry points currently exposed; they write **Information**-type and **Error**-type entries respectively. The names follow the Win32 SDK's `EVENTLOG_SUCCESS` (= 0, the *information* event type) and `EVENTLOG_ERROR_TYPE` (= 1) constants verbatim — *not* the Audit Success / Audit Failure event types familiar from the Security log. +[**LogSuccess**](EventLog#logsuccess) and [**LogFailure**](EventLog#logfailure) are the only entry points currently exposed; they write **Information**-type and **Error**-type entries respectively. The names follow the Win32 SDK's `EVENTLOG_SUCCESS` (= 0, the *information* event type) and `EVENTLOG_ERROR_TYPE` (= 1) constants verbatim --- *not* the Audit Success / Audit Failure event types familiar from the Security log. -The three other Windows Event Log entry types — **Warning**, **Audit Success**, and **Audit Failure** — are not yet reachable through the public API. +The three other Windows Event Log entry types --- **Warning**, **Audit Success**, and **Audit Failure** --- are not yet reachable through the public API. ## Classes -- [EventLog](EventLog) -- the generic event-log source — open / register / log entries against one event log, parameterised by an event-ID enum and a category enum +- [EventLog](EventLog) -- the generic event-log source -- open / register / log entries against one event log, parameterised by an event-ID enum and a category enum ## Modules -- [EventLogHelperPublic](EventLogHelperPublic) -- the low-level registry helper underlying [**EventLog.Register**](EventLog#register); call it directly only when you need to supply a category count without using the generic class +- [EventLogHelperPublic](EventLogHelperPublic) -- the low-level registry helper underlying [**EventLog.Register**](EventLog#register); call it directly only when a category count must be supplied without using the generic class diff --git a/docs/Reference/WinNamedPipesLib/NamedPipeClientConnection.md b/docs/Reference/WinNamedPipesLib/NamedPipeClientConnection.md index 4124b766..62864bc8 100644 --- a/docs/Reference/WinNamedPipesLib/NamedPipeClientConnection.md +++ b/docs/Reference/WinNamedPipesLib/NamedPipeClientConnection.md @@ -10,10 +10,10 @@ has_toc: false One client-side connection to a named pipe. Produced by [**NamedPipeClientManager.Connect**](NamedPipeClientManager#connect). Carries the connection-lifecycle events ([**Connected**](#connected), [**Disconnected**](#disconnected)) and the message events ([**MessageReceived**](#messagereceived), [**MessageSent**](#messagesent)), plus the [**AsyncRead**](#asyncread) / [**AsyncWrite**](#asyncwrite) / [**AsyncClose**](#asyncclose) methods that trigger them. -The class is tagged `[COMCreatable(False)]` and its constructor takes a package-private interface — reach instances only through [**NamedPipeClientManager.Connect**](NamedPipeClientManager#connect). +The class is tagged `[COMCreatable(False)]` and its constructor takes a package-private interface --- reach instances only through [**NamedPipeClientManager.Connect**](NamedPipeClientManager#connect). > [!IMPORTANT] -> The package `_README.txt` states: *"you MUST call **AsyncClose** on the client side, otherwise the connection is left alive when the object goes out of scope"*. Either call [**AsyncClose**](#asyncclose) explicitly before dropping the last reference, **or** let the object terminate cleanly through its `Class_Terminate` (which calls [**AsyncClose**](#asyncclose) automatically). Holding the reference forever — in a module-level **Collection**, for example — without calling [**AsyncClose**](#asyncclose) keeps the pipe handle open and the IOCP thread alive. +> The package `_README.txt` states: *"you MUST call **AsyncClose** on the client side, otherwise the connection is left alive when the object goes out of scope"*. Either call [**AsyncClose**](#asyncclose) explicitly before dropping the last reference, **or** let the object terminate cleanly through its `Class_Terminate` (which calls [**AsyncClose**](#asyncclose) automatically). Holding the reference forever --- in a module-level **Collection**, for example --- without calling [**AsyncClose**](#asyncclose) keeps the pipe handle open and the IOCP thread alive. ```tb Private manager As NamedPipeClientManager @@ -47,17 +47,17 @@ See the package [overview](.) for the IOCP / event-marshalling architecture, the ### CustomData {: .no_toc } -A per-connection opaque slot the consumer can attach state to — typically a session object or a pending-replies dictionary tied to this one connection. **Variant**, default **Empty**. The package never reads or writes this field. +A per-connection opaque slot the consumer can attach state to --- typically a session object or a pending-replies dictionary tied to this one connection. **Variant**, default **Empty**. The package never reads or writes this field. ### Handle {: .no_toc } -The underlying Win32 file handle returned by `CreateFileW("\\.\pipe\<PipeName>")`. **LongPtr**. Exposed for low-level / debugging use — most consumers can ignore it. Do not call `CloseHandle` on this value yourself; use [**AsyncClose**](#asyncclose) so the IOCP loop and the parent manager's bookkeeping stay consistent. +The underlying Win32 file handle returned by `CreateFileW("\\.\pipe\<PipeName>")`. **LongPtr**. Exposed for low-level / debugging use --- most consumers can ignore it. Do not call `CloseHandle` on this value directly; use [**AsyncClose**](#asyncclose) so the IOCP loop and the parent manager's bookkeeping stay consistent. ### PipeName {: .no_toc } -The leaf pipe name this connection was opened against — the same value that was passed to [**NamedPipeClientManager.Connect**](NamedPipeClientManager#connect). **String**. Read-only in practice; the package sets it from the constructor argument and never changes it. +The leaf pipe name this connection was opened against --- the same value that was passed to [**NamedPipeClientManager.Connect**](NamedPipeClientManager#connect). **String**. Read-only in practice; the package sets it from the constructor argument and never changes it. ## Events @@ -83,10 +83,10 @@ Fires when a complete message has been read from the pipe. Syntax: *connection*_**MessageReceived**(**ByRef** *Cookie* **As Variant**, **ByRef** *Data*() **As Byte**) *Cookie* -: The opaque correlation value originally passed to the [**AsyncRead**](#asyncread) that produced this read — or **Empty** if the read came from the auto-issued reads triggered by [**NamedPipeClientManager.ContinuouslyReadFromPipe**](NamedPipeClientManager#continuouslyreadfrompipe). +: The opaque correlation value originally passed to the [**AsyncRead**](#asyncread) that produced this read --- or **Empty** if the read came from the auto-issued reads triggered by [**NamedPipeClientManager.ContinuouslyReadFromPipe**](NamedPipeClientManager#continuouslyreadfrompipe). *Data* -: The message payload. See [Working with `Data() As Byte` in events](.#working-with-data-as-byte-in-events) on the package overview for the transient-buffer lifetime caveat — copy the bytes out before the handler returns if you need them. The [recommended capture mechanism](.#propertybag-carrier) is to assign *Data* to a fresh [**PropertyBag**](../VBRUN/PropertyBag/)'s **Contents**, which deep-copies the bytes and gives you typed multi-field access in one step. +: The message payload. See [Working with `Data() As Byte` in events](.#working-with-data-as-byte-in-events) on the package overview for the transient-buffer lifetime caveat --- copy the bytes out before the handler returns if they are needed later. The [recommended capture mechanism](.#propertybag-carrier) is to assign *Data* to a fresh [**PropertyBag**](../VBRUN/PropertyBag/)'s **Contents**, which deep-copies the bytes and provides typed multi-field access in one step. ### MessageSent {: .no_toc } @@ -121,7 +121,7 @@ Syntax: *connection*.**AsyncRead** [ *Cookie* [, *OverlappedStruct* ] ] : *optional* A **Variant** correlation value, passed back as the *Cookie* parameter of the matching [**MessageReceived**](#messagereceived) event. Default **Empty**. *OverlappedStruct* -: *optional* A **LongPtr** to a pre-allocated `OVERLAPPED_CUSTOM` structure. **Internal use only** — the IOCP machinery passes this when re-issuing a read after `ERROR_MORE_DATA`. Consumer code should always omit this parameter. +: *optional* A **LongPtr** to a pre-allocated `OVERLAPPED_CUSTOM` structure. **Internal use only** --- the IOCP machinery passes this when re-issuing a read after `ERROR_MORE_DATA`. Consumer code should always omit this parameter. Only needed when the parent manager's [**ContinuouslyReadFromPipe**](NamedPipeClientManager#continuouslyreadfrompipe) is **False**; otherwise the IOCP loop keeps a read pending automatically and explicit calls are redundant. @@ -133,7 +133,7 @@ Sends a message to the server. Syntax: *connection*.**AsyncWrite** *Data*() [, *Cookie* ] *Data* -: *required* A **Byte()** array containing the bytes to send. An uninitialised or zero-length array is a no-op. For typed multi-field payloads the recommended encoding is [**PropertyBag**](../VBRUN/PropertyBag/) — see [Recommended payload encoding: `PropertyBag`](.#propertybag-carrier) on the package overview. +: *required* A **Byte()** array containing the bytes to send. An uninitialised or zero-length array is a no-op. For typed multi-field payloads the recommended encoding is [**PropertyBag**](../VBRUN/PropertyBag/) --- see [Recommended payload encoding: `PropertyBag`](.#propertybag-carrier) on the package overview. *Cookie* : *optional* A **Variant** correlation value, passed back as the *Cookie* parameter of the matching [**MessageSent**](#messagesent) event. Default **Empty**. diff --git a/docs/Reference/WinNamedPipesLib/NamedPipeClientManager.md b/docs/Reference/WinNamedPipesLib/NamedPipeClientManager.md index c3217a70..16c91545 100644 --- a/docs/Reference/WinNamedPipesLib/NamedPipeClientManager.md +++ b/docs/Reference/WinNamedPipesLib/NamedPipeClientManager.md @@ -8,7 +8,7 @@ has_toc: false # NamedPipeClientManager class {: .no_toc } -The client-side coordinator. Owns a Windows I/O Completion Port and a pool of worker threads shared by every [**NamedPipeClientConnection**](NamedPipeClientConnection) it produces, and returns them through [**Connect**](#connect). One [**NamedPipeClientManager**](.) typically lives for the lifetime of the consuming process and manages many connections — to one or several servers — through that shared IOCP infrastructure. Instantiate with **New**. +The client-side coordinator. Owns a Windows I/O Completion Port and a pool of worker threads shared by every [**NamedPipeClientConnection**](NamedPipeClientConnection) it produces, and returns them through [**Connect**](#connect). One [**NamedPipeClientManager**](.) typically lives for the lifetime of the consuming process and manages many connections --- to one or several servers --- through that shared IOCP infrastructure. Instantiate with **New**. Configure the public fields (all four have reasonable defaults), call [**Connect**](#connect) for each pipe the application wants to dial, and respond to the [**NamedPipeClientConnection**](NamedPipeClientConnection) events. The first [**Connect**](#connect) lazily creates the completion port and starts the worker threads; subsequent calls reuse them. @@ -39,22 +39,22 @@ See the package [overview](.) for the IOCP / event-marshalling architecture, the ## Properties -The four configuration fields are read once on the first [**Connect**](#connect) call and propagated to every [**NamedPipeClientConnection**](NamedPipeClientConnection) created through this manager. Subsequent changes affect connections opened thereafter but **not** connections that already exist — set the fields before the first [**Connect**](#connect). +The four configuration fields are read once on the first [**Connect**](#connect) call and propagated to every [**NamedPipeClientConnection**](NamedPipeClientConnection) created through this manager. Subsequent changes affect connections opened thereafter but **not** connections that already exist --- set the fields before the first [**Connect**](#connect). ### ContinuouslyReadFromPipe {: .no_toc } -When **True** (the default), each [**NamedPipeClientConnection**](NamedPipeClientConnection) keeps a read pending against its pipe at all times — every [**MessageReceived**](NamedPipeClientConnection#messagereceived) is followed by an automatic `AsyncRead` issued from inside the IOCP thread. Set to **False** to handle reads one-at-a-time; each [**MessageReceived**](NamedPipeClientConnection#messagereceived) handler must then call [**NamedPipeClientConnection.AsyncRead**](NamedPipeClientConnection#asyncread) to receive the next message. **Boolean**, default **True**. +When **True** (the default), each [**NamedPipeClientConnection**](NamedPipeClientConnection) keeps a read pending against its pipe at all times --- every [**MessageReceived**](NamedPipeClientConnection#messagereceived) is followed by an automatic `AsyncRead` issued from inside the IOCP thread. Set to **False** to handle reads one-at-a-time; each [**MessageReceived**](NamedPipeClientConnection#messagereceived) handler must then call [**NamedPipeClientConnection.AsyncRead**](NamedPipeClientConnection#asyncread) to receive the next message. **Boolean**, default **True**. ### FreeThreadingEvents {: .no_toc } -Controls where the [**NamedPipeClientConnection**](NamedPipeClientConnection) events are raised. When **False** (the default), the IOCP worker threads marshal each event to the main UI thread through the manager's hidden message-only window, and the consuming process must be pumping a Win32 message loop. When **True**, events fire directly on whichever IOCP worker thread received the completion — no message-loop dependency, but the consumer's event handlers must be thread-safe. **Boolean**, default **False**. +Controls where the [**NamedPipeClientConnection**](NamedPipeClientConnection) events are raised. When **False** (the default), the IOCP worker threads marshal each event to the main UI thread through the manager's hidden message-only window, and the consuming process must be pumping a Win32 message loop. When **True**, events fire directly on whichever IOCP worker thread received the completion --- no message-loop dependency, but the consumer's event handlers must be thread-safe. **Boolean**, default **False**. ### MessageBufferSize {: .no_toc } -The size, in bytes, of the per-completion `ReadFile` buffer initially allocated for each client connection. **Long**, default **131072** (128 KiB). Does not cap the maximum message size — on `ERROR_MORE_DATA` the IOCP loop allocates a larger overflow buffer and re-issues the read — but the initial size affects throughput for sustained large-message traffic. +The size, in bytes, of the per-completion `ReadFile` buffer initially allocated for each client connection. **Long**, default **131072** (128 KiB). Does not cap the maximum message size --- on `ERROR_MORE_DATA` the IOCP loop allocates a larger overflow buffer and re-issues the read --- but the initial size affects throughput for sustained large-message traffic. ### NumThreadsIOCP {: .no_toc } @@ -71,7 +71,7 @@ Opens an asynchronous connection to a named pipe on the local machine. Syntax: *manager*.**Connect**( *PipeName* ) **As NamedPipeClientConnection** *PipeName* -: *required* The leaf name of the pipe to dial — the package prepends `\\.\pipe\` itself. Raises run-time error 5 *"cannot start without specifying a pipe name"* if empty. +: *required* The leaf name of the pipe to dial --- the package prepends `\\.\pipe\` itself. Raises run-time error 5 *"cannot start without specifying a pipe name"* if empty. Lazy on first call: creates the completion port and starts [**NumThreadsIOCP**](#numthreadsiocp) worker threads. Returns immediately with a [**NamedPipeClientConnection**](NamedPipeClientConnection) in the not-yet-connected state. The actual `CreateFileW` runs asynchronously on an IOCP worker and fires [**Connected**](NamedPipeClientConnection#connected) on the returned object once the pipe is open. @@ -85,7 +85,7 @@ Enumerates the named pipes currently published on the local machine. Syntax: *manager*.**FindNamedPipes** ( [ *Pattern* ] ) **As Collection** *Pattern* -: *optional* A wildcard pattern matched against the leaf pipe name (no `\\.\pipe\` prefix; the package adds it). `*` matches any sequence, `?` matches any single character. Default `"*"` — return every pipe. +: *optional* A wildcard pattern matched against the leaf pipe name (no `\\.\pipe\` prefix; the package adds it). `*` matches any sequence, `?` matches any single character. Default `"*"` --- return every pipe. Returns a **Collection** of **String** values, each a leaf pipe name suitable to pass to [**Connect**](#connect). Useful as a discovery step when the consumer doesn't know the exact server name in advance: @@ -97,12 +97,12 @@ For Each name In names Next ``` -The package does not publish an event when pipes appear or disappear, so dynamic UIs that list available servers typically refresh the list from a low-frequency [**Timer**](../VB/Timer/) — see [Discovering pipes](.#discovering-pipes) on the package overview for the polling-loop pattern that preserves the user's current selection across refreshes. +The package does not publish an event when pipes appear or disappear, so dynamic UIs that list available servers typically refresh the list from a low-frequency [**Timer**](../VB/Timer/) --- see [Discovering pipes](.#discovering-pipes) on the package overview for the polling-loop pattern that preserves the user's current selection across refreshes. ### Stop {: .no_toc } -Cancels every outstanding I/O on every connection produced by this manager, posts the IOCP shutdown sentinel to each worker, waits for the threads to exit, closes every pipe handle, and frees the completion port. Idempotent: calling [**Stop**](#stop) on a manager that has not connected anything — or has already been stopped — is a no-op. Automatically invoked from `Class_Terminate`, so a manager going out of scope closes resources implicitly. +Cancels every outstanding I/O on every connection produced by this manager, posts the IOCP shutdown sentinel to each worker, waits for the threads to exit, closes every pipe handle, and frees the completion port. Idempotent: calling [**Stop**](#stop) on a manager that has not connected anything --- or has already been stopped --- is a no-op. Automatically invoked from `Class_Terminate`, so a manager going out of scope closes resources implicitly. Syntax: *manager*.**Stop** diff --git a/docs/Reference/WinNamedPipesLib/NamedPipeServer.md b/docs/Reference/WinNamedPipesLib/NamedPipeServer.md index 10a16227..c43176e1 100644 --- a/docs/Reference/WinNamedPipesLib/NamedPipeServer.md +++ b/docs/Reference/WinNamedPipesLib/NamedPipeServer.md @@ -10,7 +10,7 @@ has_toc: false Hosts one named pipe and accepts an unbounded number of concurrent client connections, each represented by a [**NamedPipeServerConnection**](NamedPipeServerConnection). The class owns a Windows I/O Completion Port and a configurable pool of worker threads that handle every connection's reads, writes, and connect notifications. Instantiate with **New**. -Configure the public fields ([**PipeName**](#pipename) is required, the others have reasonable defaults), call [**Start**](#start), and respond to the lifecycle events as clients arrive and exchange messages. The package opens the underlying pipe as **PIPE_TYPE_MESSAGE** / **PIPE_READMODE_MESSAGE** — messages preserve their boundaries between sender and receiver. +Configure the public fields ([**PipeName**](#pipename) is required, the others have reasonable defaults), call [**Start**](#start), and respond to the lifecycle events as clients arrive and exchange messages. The package opens the underlying pipe as **PIPE_TYPE_MESSAGE** / **PIPE_READMODE_MESSAGE** --- messages preserve their boundaries between sender and receiver. ```tb Private WithEvents server As NamedPipeServer @@ -43,19 +43,19 @@ See the package [overview](.) for the IOCP / event-marshalling architecture, the ### ContinuouslyReadFromPipe {: .no_toc } -When **True** (the default), the server keeps a read pending against every connected client at all times — every [**ClientMessageReceived**](#clientmessagereceived) is followed by an automatic `AsyncRead` issued from inside the IOCP thread. Set to **False** to handle reads one-at-a-time; each [**ClientMessageReceived**](#clientmessagereceived) handler must then call [**NamedPipeServerConnection.AsyncRead**](NamedPipeServerConnection#asyncread) to receive the next message. **Boolean**, default **True**. +When **True** (the default), the server keeps a read pending against every connected client at all times --- every [**ClientMessageReceived**](#clientmessagereceived) is followed by an automatic `AsyncRead` issued from inside the IOCP thread. Set to **False** to handle reads one-at-a-time; each [**ClientMessageReceived**](#clientmessagereceived) handler must then call [**NamedPipeServerConnection.AsyncRead**](NamedPipeServerConnection#asyncread) to receive the next message. **Boolean**, default **True**. ### FreeThreadingEvents {: .no_toc } -Controls where the lifecycle and message events are raised. When **False** (the default), the IOCP worker threads marshal each event to the main UI thread through a hidden message-only window, and the consuming process must be pumping a Win32 message loop. When **True**, events fire directly on whichever IOCP worker thread received the completion — no message-loop dependency, but the consumer's event handlers must be thread-safe. **Boolean**, default **False**. +Controls where the lifecycle and message events are raised. When **False** (the default), the IOCP worker threads marshal each event to the main UI thread through a hidden message-only window, and the consuming process must be pumping a Win32 message loop. When **True**, events fire directly on whichever IOCP worker thread received the completion --- no message-loop dependency, but the consumer's event handlers must be thread-safe. **Boolean**, default **False**. Set this before calling [**Start**](#start); it is read once when the worker threads are created and propagated to every [**NamedPipeServerConnection**](NamedPipeServerConnection). ### MessageBufferSize {: .no_toc } -The size, in bytes, of the per-completion `ReadFile` buffer initially allocated for each connection. **Long**, default **131072** (128 KiB). Does not cap the maximum message size — on `ERROR_MORE_DATA` the IOCP loop allocates a larger overflow buffer and re-issues the read — but the initial size affects how often that overflow path runs, and so affects throughput for sustained large-message traffic. +The size, in bytes, of the per-completion `ReadFile` buffer initially allocated for each connection. **Long**, default **131072** (128 KiB). Does not cap the maximum message size --- on `ERROR_MORE_DATA` the IOCP loop allocates a larger overflow buffer and re-issues the read --- but the initial size affects how often that overflow path runs, and so affects throughput for sustained large-message traffic. ### NumThreadsIOCP {: .no_toc } @@ -65,7 +65,7 @@ The number of IOCP worker threads created by [**Start**](#start). **Long**, defa ### PipeName {: .no_toc } -The name the pipe is published under. **String**, no default. The Win32 pipe namespace path is `\\.\pipe\<PipeName>` — the package prepends `\\.\pipe\` itself; pass just the leaf name. +The name the pipe is published under. **String**, no default. The Win32 pipe namespace path is `\\.\pipe\<PipeName>` --- the package prepends `\\.\pipe\` itself; pass just the leaf name. > [!IMPORTANT] > [**PipeName**](#pipename) must be set to a non-empty value before [**Start**](#start), or [**Start**](#start) raises run-time error 5 (*"cannot start without specifying a pipe name"*). @@ -80,7 +80,7 @@ Fires after a client's `ConnectNamedPipe` has completed and the connection is re Syntax: *server*_**ClientConnected**(*Connection* **As NamedPipeServerConnection**) *Connection* -: The newly-connected client's server-side connection object. Hold the reference if you need per-client state across messages — the same instance is passed to every event for this client. Note that **Cookie** / `Tag`-style storage is available through [**NamedPipeServerConnection.CustomData**](NamedPipeServerConnection#customdata). +: The newly-connected client's server-side connection object. Hold the reference to keep per-client state across messages --- the same instance is passed to every event for this client. **Cookie** / `Tag`-style storage is available through [**NamedPipeServerConnection.CustomData**](NamedPipeServerConnection#customdata). ### ClientDisconnected {: .no_toc } @@ -103,10 +103,10 @@ Syntax: *server*_**ClientMessageReceived**(*Connection* **As NamedPipeServerConn : The connection the message came from. *Cookie* -: The opaque correlation value originally passed to the [**NamedPipeServerConnection.AsyncRead**](NamedPipeServerConnection#asyncread) that produced this read — or **Empty** if the read came from the auto-issued reads triggered by [**ContinuouslyReadFromPipe**](#continuouslyreadfrompipe). +: The opaque correlation value originally passed to the [**NamedPipeServerConnection.AsyncRead**](NamedPipeServerConnection#asyncread) that produced this read --- or **Empty** if the read came from the auto-issued reads triggered by [**ContinuouslyReadFromPipe**](#continuouslyreadfrompipe). *Data* -: The message payload. See [Working with `Data() As Byte` in events](.#working-with-data-as-byte-in-events) on the package overview for the transient-buffer lifetime caveat — copy the bytes out before the handler returns if you need them. The [recommended capture mechanism](.#propertybag-carrier) is to assign *Data* to a fresh [**PropertyBag**](../VBRUN/PropertyBag/)'s **Contents**, which deep-copies the bytes and gives you typed multi-field access in one step. +: The message payload. See [Working with `Data() As Byte` in events](.#working-with-data-as-byte-in-events) on the package overview for the transient-buffer lifetime caveat --- copy the bytes out before the handler returns if they are needed later. The [recommended capture mechanism](.#propertybag-carrier) is to assign *Data* to a fresh [**PropertyBag**](../VBRUN/PropertyBag/)'s **Contents**, which deep-copies the bytes and provides typed multi-field access in one step. ### ClientMessageSent {: .no_toc } @@ -138,7 +138,7 @@ Issues an [**AsyncWrite**](NamedPipeServerConnection#asyncwrite) against every c Syntax: *server*.**AsyncBroadcast** *Data*() [, *Cookie* ] *Data* -: *required* The message bytes to send. twinBASIC will coerce a **String** literal to **Byte()** implicitly, so `server.AsyncBroadcast "shutting down"` works without a separate `StrConv` step — useful for protocol-less server-pushed notifications. +: *required* The message bytes to send. twinBASIC will coerce a **String** literal to **Byte()** implicitly, so `server.AsyncBroadcast "shutting down"` works without a separate `StrConv` step --- useful for protocol-less server-pushed notifications. *Cookie* : *optional* A **Variant** correlation value, attached to *each* per-client [**ClientMessageSent**](#clientmessagesent) event. Default **Empty**. @@ -163,7 +163,7 @@ Posts a `WM_USER_QUITTING` message to the hidden marshalling window, causing the Syntax: *server*.**ManualMessageLoopLeave** -The intended caller is a thread *other* than the one inside [**ManualMessageLoopEnter**](#manualmessageloopenter) — typically the Windows service's dispatcher thread waking the service-entry-point thread out of its blocked loop. See [Hosting inside a Windows service](.#service-host-idiom). +The intended caller is a thread *other* than the one inside [**ManualMessageLoopEnter**](#manualmessageloopenter) --- typically the Windows service's dispatcher thread waking the service-entry-point thread out of its blocked loop. See [Hosting inside a Windows service](.#service-host-idiom). ### Start {: .no_toc } @@ -179,7 +179,7 @@ Idempotent: calling [**Start**](#start) while the server is already running is a ### Stop {: .no_toc } -Cancels every outstanding I/O on every connection, posts the IOCP shutdown sentinel to each worker, waits for the threads to exit, closes every pipe handle, and frees the completion port. Idempotent: calling [**Stop**](#stop) on a server that has not been started — or has already been stopped — is a no-op. Automatically invoked from `Class_Terminate`, so a server going out of scope closes resources implicitly. +Cancels every outstanding I/O on every connection, posts the IOCP shutdown sentinel to each worker, waits for the threads to exit, closes every pipe handle, and frees the completion port. Idempotent: calling [**Stop**](#stop) on a server that has not been started --- or has already been stopped --- is a no-op. Automatically invoked from `Class_Terminate`, so a server going out of scope closes resources implicitly. Syntax: *server*.**Stop** diff --git a/docs/Reference/WinNamedPipesLib/NamedPipeServerConnection.md b/docs/Reference/WinNamedPipesLib/NamedPipeServerConnection.md index c01faefb..5283c6ea 100644 --- a/docs/Reference/WinNamedPipesLib/NamedPipeServerConnection.md +++ b/docs/Reference/WinNamedPipesLib/NamedPipeServerConnection.md @@ -10,7 +10,7 @@ has_toc: false One server-side per-client connection. A [**NamedPipeServer**](NamedPipeServer) creates one of these for every client that connects, and passes it as the *Connection* parameter of every server event. Use it to send messages to that specific client, to manually issue reads when [**NamedPipeServer.ContinuouslyReadFromPipe**](NamedPipeServer#continuouslyreadfrompipe) is **False**, and to close the connection from the server side. -The class is tagged `[COMCreatable(False)]` and its constructor takes a package-private interface — reach instances only through [**NamedPipeServer**](NamedPipeServer) events. Connection-lifecycle and message events come through the parent [**NamedPipeServer**](NamedPipeServer); this class holds the per-connection data and methods only. +The class is tagged `[COMCreatable(False)]` and its constructor takes a package-private interface --- reach instances only through [**NamedPipeServer**](NamedPipeServer) events. Connection-lifecycle and message events come through the parent [**NamedPipeServer**](NamedPipeServer); this class holds the per-connection data and methods only. ```tb Private Sub server_ClientConnected(Connection As NamedPipeServerConnection) @@ -38,12 +38,12 @@ See the package [overview](.) for the IOCP / event-marshalling architecture, the ### CustomData {: .no_toc } -A per-connection opaque slot the consumer can attach state to — typically a session object scoped to that one client. **Variant**, default **Empty**. The package never reads or writes this field; it is provided for convenience so that consumers do not have to maintain a parallel `Dictionary` keyed by [**Handle**](#handle). +A per-connection opaque slot the consumer can attach state to --- typically a session object scoped to that one client. **Variant**, default **Empty**. The package never reads or writes this field; it is provided for convenience so that consumers do not have to maintain a parallel `Dictionary` keyed by [**Handle**](#handle). ### Handle {: .no_toc } -The underlying Win32 named-pipe handle. **LongPtr**. Exposed for low-level / debugging use — most consumers can ignore it. Do not call `CloseHandle` on this value yourself; use [**AsyncClose**](#asyncclose) so the IOCP loop and the parent server's bookkeeping stay consistent. +The underlying Win32 named-pipe handle. **LongPtr**. Exposed for low-level / debugging use --- most consumers can ignore it. Do not call `CloseHandle` on this value directly; use [**AsyncClose**](#asyncclose) so the IOCP loop and the parent server's bookkeeping stay consistent. ### IsConnected {: .no_toc } @@ -75,7 +75,7 @@ Syntax: *connection*.**AsyncRead** [ *Cookie* [, *OverlappedStruct* ] ] : *optional* A **Variant** correlation value, passed back as the *Cookie* parameter of the matching [**ClientMessageReceived**](NamedPipeServer#clientmessagereceived) event. Default **Empty**. *OverlappedStruct* -: *optional* A **LongPtr** to a pre-allocated `OVERLAPPED_CUSTOM` structure. **Internal use only** — the IOCP machinery passes this when re-issuing a read after `ERROR_MORE_DATA`. Consumer code should always omit this parameter. +: *optional* A **LongPtr** to a pre-allocated `OVERLAPPED_CUSTOM` structure. **Internal use only** --- the IOCP machinery passes this when re-issuing a read after `ERROR_MORE_DATA`. Consumer code should always omit this parameter. Only needed when the parent server's [**ContinuouslyReadFromPipe**](NamedPipeServer#continuouslyreadfrompipe) is **False**; otherwise the IOCP loop keeps a read pending automatically and explicit calls are redundant. @@ -87,7 +87,7 @@ Sends a message back to this specific client. Syntax: *connection*.**AsyncWrite** *Data*() [, *Cookie* ] *Data* -: *required* A **Byte()** array containing the bytes to send. An uninitialised or zero-length array is a no-op. For typed multi-field payloads the recommended encoding is [**PropertyBag**](../VBRUN/PropertyBag/) — see [Recommended payload encoding: `PropertyBag`](.#propertybag-carrier) on the package overview. +: *required* A **Byte()** array containing the bytes to send. An uninitialised or zero-length array is a no-op. For typed multi-field payloads the recommended encoding is [**PropertyBag**](../VBRUN/PropertyBag/) --- see [Recommended payload encoding: `PropertyBag`](.#propertybag-carrier) on the package overview. *Cookie* : *optional* A **Variant** correlation value, passed back as the *Cookie* parameter of the matching [**ClientMessageSent**](NamedPipeServer#clientmessagesent) event. Default **Empty**. diff --git a/docs/Reference/WinNamedPipesLib/index.md b/docs/Reference/WinNamedPipesLib/index.md index 5f2d605b..bcccac05 100644 --- a/docs/Reference/WinNamedPipesLib/index.md +++ b/docs/Reference/WinNamedPipesLib/index.md @@ -26,15 +26,15 @@ Two halves, each one user-instantiated coordinator class plus one per-connection | Server | [**NamedPipeServer**](NamedPipeServer) | [**NamedPipeServerConnection**](NamedPipeServerConnection) | | Client | [**NamedPipeClientManager**](NamedPipeClientManager) | [**NamedPipeClientConnection**](NamedPipeClientConnection) | -The server publishes a name (`PipeName = "MyService"` → Win32 path `\\.\pipe\MyService`) and returns a [**NamedPipeServerConnection**](NamedPipeServerConnection) for every client that connects. The client manager dials by the same name (with [**Connect**](NamedPipeClientManager#connect)) and gets back a [**NamedPipeClientConnection**](NamedPipeClientConnection). The two ends are symmetric thereafter — both expose `AsyncRead`, `AsyncWrite`, and `AsyncClose` with the same signatures. +The server publishes a name (`PipeName = "MyService"` → Win32 path `\\.\pipe\MyService`) and returns a [**NamedPipeServerConnection**](NamedPipeServerConnection) for every client that connects. The client manager dials by the same name (with [**Connect**](NamedPipeClientManager#connect)) and returns a [**NamedPipeClientConnection**](NamedPipeClientConnection). The two ends are symmetric thereafter --- both expose `AsyncRead`, `AsyncWrite`, and `AsyncClose` with the same signatures. Reads, writes, and connection completion all run through the same Windows I/O Completion Port (IOCP) infrastructure. Each coordinator class owns its own completion port, a configurable pool of worker threads ([**NumThreadsIOCP**](NamedPipeServer#numthreadsiocp)), and a hidden message-only window used to marshal events back to the UI thread. -## Event delivery — marshalled vs free-threaded +## Event delivery --- marshalled vs free-threaded By default events fire on the main UI thread. The IOCP worker threads receive each completion, package the buffer, and `PostMessage` the result to a hidden `STATIC`-class window owned by the coordinator. The window's subclassed `WndProc` then raises the BASIC event from the message loop. This means the consuming process **must be pumping a Win32 message loop** for events to be delivered. Forms-based hosts already are; console hosts and Windows services are not, and need either [**NamedPipeServer.ManualMessageLoopEnter**](NamedPipeServer#manualmessageloopenter) (and the matching `ManualMessageLoopLeave`) or `FreeThreadingEvents = True`. -Setting [**FreeThreadingEvents**](NamedPipeServer#freethreadingevents) to **True** skips the marshalling round-trip and raises events directly from the IOCP worker thread. Performance is higher and there is no message-loop requirement, but the consumer's event handlers must be thread-safe — multiple `ClientMessageReceived` events from different clients can fire concurrently, and global / class state touched from the handler is **not** protected by the implicit UI-thread serialisation that the default mode gives. +Setting [**FreeThreadingEvents**](NamedPipeServer#freethreadingevents) to **True** skips the marshalling round-trip and raises events directly from the IOCP worker thread. Performance is higher and there is no message-loop requirement, but the consumer's event handlers must be thread-safe --- multiple `ClientMessageReceived` events from different clients can fire concurrently, and global / class state touched from the handler is **not** protected by the implicit UI-thread serialisation that the default mode provides. The flag must be set before [**Start**](NamedPipeServer#start) (server side) or before the first [**Connect**](NamedPipeClientManager#connect) call (client side); it is read once and propagated to every per-connection object. @@ -43,14 +43,14 @@ The flag must be set before [**Start**](NamedPipeServer#start) (server side) or Windows services hosted through the [**WinServicesLib**](../WinServicesLib/) package run into the message-loop dependency described above when they also host a [**NamedPipeServer**](NamedPipeServer): the [**ITbService.EntryPoint**](../WinServicesLib/ITbService#entrypoint) thread is not pumping messages by default, so the marshalled-event delivery has nothing to dispatch through. The package provides [**NamedPipeServer.ManualMessageLoopEnter**](NamedPipeServer#manualmessageloopenter) / [**ManualMessageLoopLeave**](NamedPipeServer#manualmessageloopleave) for exactly this case. -The canonical pattern: [**ITbService.EntryPoint**](../WinServicesLib/ITbService#entrypoint) opens the server, transitions the service to `Running`, blocks inside [**ManualMessageLoopEnter**](NamedPipeServer#manualmessageloopenter), and only leaves the loop when [**ITbService.ChangeState**](../WinServicesLib/ITbService#changestate) — running on the *other* (dispatcher) thread — calls [**ManualMessageLoopLeave**](NamedPipeServer#manualmessageloopleave) on the same server instance. +The canonical pattern: [**ITbService.EntryPoint**](../WinServicesLib/ITbService#entrypoint) opens the server, transitions the service to `Running`, blocks inside [**ManualMessageLoopEnter**](NamedPipeServer#manualmessageloopenter), and only leaves the loop when [**ITbService.ChangeState**](../WinServicesLib/ITbService#changestate) --- running on the *other* (dispatcher) thread --- calls [**ManualMessageLoopLeave**](NamedPipeServer#manualmessageloopleave) on the same server instance. ```tb ' On the service-entry-point thread: Set NamedPipeServer = New NamedPipeServer NamedPipeServer.PipeName = "MyServicePipe" -' (tell the SCM we're running, then block on the message loop) +' (tell the SCM the service is running, then block on the message loop) ServiceManager.ReportStatus vbServiceStatusRunning NamedPipeServer.Start NamedPipeServer.ManualMessageLoopEnter ' blocks until ManualMessageLoopLeave @@ -70,17 +70,17 @@ Three facts worth pulling out: - The service entry-point and the control-code handler run on **different threads**. The shared [**NamedPipeServer**](NamedPipeServer) member field is what they coordinate through; the handler calls [**ManualMessageLoopLeave**](NamedPipeServer#manualmessageloopleave) on it to wake the entry-point. - [**ManualMessageLoopLeave**](NamedPipeServer#manualmessageloopleave) is the only way to exit [**ManualMessageLoopEnter**](NamedPipeServer#manualmessageloopenter) cleanly. There is no timeout and no second blocking primitive. Services that need to react to other wake-up sources (e.g. a *Pause* control code) set a shared `Public` flag *then* call [**ManualMessageLoopLeave**](NamedPipeServer#manualmessageloopleave) to break out, inspect the flag, and re-enter the loop or proceed to shutdown. -- [**FreeThreadingEvents**](NamedPipeServer#freethreadingevents) = **False** (the default) is **required** for this pattern. Setting it to **True** would deliver events directly on the IOCP worker thread and bypass the manual loop entirely — the pipe still works, but `ManualMessageLoopEnter` / `Leave` become irrelevant. Pick one mode and stay with it. +- [**FreeThreadingEvents**](NamedPipeServer#freethreadingevents) = **False** (the default) is **required** for this pattern. Setting it to **True** would deliver events directly on the IOCP worker thread and bypass the manual loop entirely -- the pipe still works, but `ManualMessageLoopEnter` / `Leave` become irrelevant. Pick one mode and stay with it. -The non-service equivalent — hosting the same [**NamedPipeServer**](NamedPipeServer) inside a Form — is simpler: the Form's regular message loop pumps the marshalling window automatically, so the Form calls [**Start**](NamedPipeServer#start) in `Form_Load`, [**Stop**](NamedPipeServer#stop) in `Form_Unload`, and never touches [**ManualMessageLoopEnter**](NamedPipeServer#manualmessageloopenter) / [**ManualMessageLoopLeave**](NamedPipeServer#manualmessageloopleave). Either pattern works; the service-host pattern is the one that needs the manual pump. +The non-service equivalent --- hosting the same [**NamedPipeServer**](NamedPipeServer) inside a Form --- is simpler: the Form's regular message loop pumps the marshalling window automatically, so the Form calls [**Start**](NamedPipeServer#start) in `Form_Load`, [**Stop**](NamedPipeServer#stop) in `Form_Unload`, and never touches [**ManualMessageLoopEnter**](NamedPipeServer#manualmessageloopenter) / [**ManualMessageLoopLeave**](NamedPipeServer#manualmessageloopleave). Either pattern works; the service-host pattern is the one that needs the manual pump. ## Asynchronous reads -When [**ContinuouslyReadFromPipe**](NamedPipeServer#continuouslyreadfrompipe) is **True** (the default), the package keeps a read pending against every connection at all times — every [**ClientMessageReceived**](NamedPipeServer#clientmessagereceived) / [**MessageReceived**](NamedPipeClientConnection#messagereceived) event is followed by another `AsyncRead` issued from inside the IOCP thread. Set the flag to **False** to handle reads one-at-a-time: each event handler must then call [**NamedPipeServerConnection.AsyncRead**](NamedPipeServerConnection#asyncread) / [**NamedPipeClientConnection.AsyncRead**](NamedPipeClientConnection#asyncread) to receive the next message. This is useful for back-pressure when the consumer can't process messages as fast as they arrive. +When [**ContinuouslyReadFromPipe**](NamedPipeServer#continuouslyreadfrompipe) is **True** (the default), the package keeps a read pending against every connection at all times --- every [**ClientMessageReceived**](NamedPipeServer#clientmessagereceived) / [**MessageReceived**](NamedPipeClientConnection#messagereceived) event is followed by another `AsyncRead` issued from inside the IOCP thread. Set the flag to **False** to handle reads one-at-a-time: each event handler must then call [**NamedPipeServerConnection.AsyncRead**](NamedPipeServerConnection#asyncread) / [**NamedPipeClientConnection.AsyncRead**](NamedPipeClientConnection#asyncread) to receive the next message. This is useful for back-pressure when the consumer can't process messages as fast as they arrive. ## The cookie correlation pattern -Every [**AsyncRead**](NamedPipeServerConnection#asyncread) and [**AsyncWrite**](NamedPipeServerConnection#asyncwrite) accepts an optional *Cookie* of type **Variant**. Whatever value the caller passes in is round-tripped through the IOCP completion and re-emitted as the *Cookie* parameter of the matching [**ClientMessageReceived**](NamedPipeServer#clientmessagereceived) / [**ClientMessageSent**](NamedPipeServer#clientmessagesent) (or client-side [**MessageReceived**](NamedPipeClientConnection#messagereceived) / [**MessageSent**](NamedPipeClientConnection#messagesent)) event. Use this to correlate event callbacks with the calls that initiated them — a per-request sequence number, a callback object, a key into a pending-replies dictionary. +Every [**AsyncRead**](NamedPipeServerConnection#asyncread) and [**AsyncWrite**](NamedPipeServerConnection#asyncwrite) accepts an optional *Cookie* of type **Variant**. Whatever value the caller passes in is round-tripped through the IOCP completion and re-emitted as the *Cookie* parameter of the matching [**ClientMessageReceived**](NamedPipeServer#clientmessagereceived) / [**ClientMessageSent**](NamedPipeServer#clientmessagesent) (or client-side [**MessageReceived**](NamedPipeClientConnection#messagereceived) / [**MessageSent**](NamedPipeClientConnection#messagesent)) event. Use this to correlate event callbacks with the calls that initiated them --- a per-request sequence number, a callback object, a key into a pending-replies dictionary. ```tb Private pending As New Collection @@ -103,7 +103,7 @@ End Sub The *Data* parameter on [**ClientMessageReceived**](NamedPipeServer#clientmessagereceived) and [**MessageReceived**](NamedPipeClientConnection#messagereceived) is **not** a normal heap-allocated **Byte** array. The package constructs a custom `SAFEARRAY` whose backing memory points at the IOCP read buffer, then clears the array pointer at the end of the event handler so the buffer can be recycled. The values are valid *only* while the handler is on the stack. > [!IMPORTANT] -> Copy the bytes out before the event handler returns if you need them later. Storing the array reference in a module-level variable, a **Collection**, or a class field leaves a dangling pointer once the IOCP loop reuses the buffer for the next message. +> Copy the bytes out before the event handler returns if they are needed later. Storing the array reference in a module-level variable, a **Collection**, or a class field leaves a dangling pointer once the IOCP loop reuses the buffer for the next message. For a fresh **Byte()** copy: @@ -118,9 +118,9 @@ For a text payload, `StrConv(Data, vbUnicode)` (UTF-8) or `CStr` over a `vbUnico ## Recommended payload encoding: `PropertyBag` {: #propertybag-carrier } -The package transports raw bytes; it is agnostic about what is inside them. For non-trivial protocols the recommended carrier is [**PropertyBag**](../VBRUN/PropertyBag/) — twinBASIC's built-in keyed-property serialiser. Two reasons: +The package transports raw bytes; it is agnostic about what is inside them. For non-trivial protocols the recommended carrier is [**PropertyBag**](../VBRUN/PropertyBag/) --- twinBASIC's built-in keyed-property serialiser. Two reasons: -1. **`PropertyBag.Contents` deep-copies the bytes**, which is the simplest answer to the transient-`Data()` lifetime caveat above. Assigning *Data* to a fresh **PropertyBag**'s **Contents** captures the buffer in one step; the copy is safe to keep past the event handler. +1. **`PropertyBag.Contents` deep-copies the bytes**, which is the simplest answer to the transient-`Data()` lifetime caveat above. Assigning *Data* to a fresh **PropertyBag**'s **Contents** captures the buffer in one step; the copy is safe to retain past the event handler. 2. **`PropertyBag` provides typed multi-field payloads** without the consumer having to design a wire protocol. Both sides agree on property names (e.g. `"CommandID"`, `"ResponseCommandID"`, `"Data"`) and **PropertyBag** handles the byte-level encoding. ```tb @@ -143,20 +143,20 @@ Select Case cmd End Select ``` -Nothing in the package mandates **PropertyBag** — raw `Byte()` works too, and a custom wire format may be the right answer for very high-throughput scenarios. But the everyday case is well served by the **PropertyBag** convention and it solves the transient-`Data()` problem without extra effort. +Nothing in the package mandates **PropertyBag** --- raw `Byte()` works too, and a custom wire format may be the right answer for very high-throughput scenarios. The everyday case is well served by the **PropertyBag** convention, and it solves the transient-`Data()` problem without extra effort. ## Closing a client connection > [!IMPORTANT] > The **`_README.txt`** states: *"you MUST call **AsyncClose** on the client side, otherwise the connection is left alive when the object goes out of scope"*. -Either let the [**NamedPipeClientConnection**](NamedPipeClientConnection) object terminate cleanly through its `Class_Terminate` (which calls [**AsyncClose**](NamedPipeClientConnection#asyncclose) automatically) **or** call [**AsyncClose**](NamedPipeClientConnection#asyncclose) yourself before dropping the last reference. Holding a reference forever — for example in a long-lived module-level **Collection** — without calling [**AsyncClose**](NamedPipeClientConnection#asyncclose) keeps the underlying pipe handle open and the IOCP thread alive. +Either let the [**NamedPipeClientConnection**](NamedPipeClientConnection) object terminate cleanly through its `Class_Terminate` (which calls [**AsyncClose**](NamedPipeClientConnection#asyncclose) automatically) **or** call [**AsyncClose**](NamedPipeClientConnection#asyncclose) explicitly before dropping the last reference. Holding a reference forever --- for example in a long-lived module-level **Collection** --- without calling [**AsyncClose**](NamedPipeClientConnection#asyncclose) keeps the underlying pipe handle open and the IOCP thread alive. ## Discovering pipes -[**NamedPipeClientManager.FindNamedPipes**](NamedPipeClientManager#findnamedpipes) enumerates the named pipes published on the local machine, returning a **Collection** of **String** names that match an optional `*`/`?` wildcard pattern. The implementation is `FindFirstFileW("\\.\pipe\<Pattern>")` — the package strips the leading namespace itself, so pass just the pipe name (`"MyService*"`, not `"\\.\pipe\MyService*"`). +[**NamedPipeClientManager.FindNamedPipes**](NamedPipeClientManager#findnamedpipes) enumerates the named pipes published on the local machine, returning a **Collection** of **String** names that match an optional `*`/`?` wildcard pattern. The implementation is `FindFirstFileW("\\.\pipe\<Pattern>")` --- the package strips the leading namespace itself, so pass just the pipe name (`"MyService*"`, not `"\\.\pipe\MyService*"`). -Named pipes can appear and disappear at any time as their server processes start and stop, and the package does not publish an event for this. The canonical discovery loop is a low-frequency [**Timer**](../VB/Timer/) that repopulates a list and preserves the user's current selection — a few seconds between polls is the typical interval; the underlying `FindFirstFileW` is cheap enough that nothing finer is required: +Named pipes can appear and disappear at any time as their server processes start and stop, and the package does not publish an event for this. The canonical discovery loop is a low-frequency [**Timer**](../VB/Timer/) that repopulates a list and preserves the user's current selection --- a few seconds between polls is the typical interval; the underlying `FindFirstFileW` is cheap enough that nothing finer is required: ```tb Private Sub timerRefreshNamedPipes_Timer() @@ -176,8 +176,8 @@ End Sub ## Known limitations -- **No `Error` event is raised.** None of the four classes raises an `Error` event. Recognised IOCP failures (`ERROR_BROKEN_PIPE`, `ERROR_OPERATION_ABORTED`) drop the connection silently through the normal [**ClientDisconnected**](NamedPipeServer#clientdisconnected) / [**Disconnected**](NamedPipeClientConnection#disconnected) path — the consumer cannot distinguish a deliberate close from a transport failure. Worse, the client-side IOCP loop (`IOCPThreadClient` in `NamedPipeClientManager.twin`) contains a literal **Stop** statement on the branch for *unrecognised* error codes, which halts execution rather than reporting the error to consumer code. -- **Send is hard-capped at** [**MessageBufferSize**](NamedPipeServer#messagebuffersize) **bytes.** The receive path grows its buffer dynamically on `ERROR_MORE_DATA`, so reads of arbitrary size work. The send path does not: [**AsyncWrite**](NamedPipeServerConnection#asyncwrite) (and the client-side [**AsyncWrite**](NamedPipeClientConnection#asyncwrite)) copies the caller's `Byte()` *without a bounds-check* into a per-completion buffer sized at [**MessageBufferSize**](NamedPipeServer#messagebuffersize) (default **131072** bytes); the same goes for [**AsyncBroadcast**](NamedPipeServer#asyncbroadcast). A larger message overruns the buffer — likely a crash or heap corruption rather than a clean error. Raise [**MessageBufferSize**](NamedPipeServer#messagebuffersize) above your largest expected message *before* the first [**Start**](NamedPipeServer#start) (server) or [**Connect**](NamedPipeClientManager#connect) (client); the value is read once at that point and propagated to every per-connection buffer. +- **No `Error` event is raised.** None of the four classes raises an `Error` event. Recognised IOCP failures (`ERROR_BROKEN_PIPE`, `ERROR_OPERATION_ABORTED`) drop the connection silently through the normal [**ClientDisconnected**](NamedPipeServer#clientdisconnected) / [**Disconnected**](NamedPipeClientConnection#disconnected) path --- the consumer cannot distinguish a deliberate close from a transport failure. Worse, the client-side IOCP loop (`IOCPThreadClient` in `NamedPipeClientManager.twin`) contains a literal **Stop** statement on the branch for *unrecognised* error codes, which halts execution rather than reporting the error to consumer code. +- **Send is hard-capped at** [**MessageBufferSize**](NamedPipeServer#messagebuffersize) **bytes.** The receive path grows its buffer dynamically on `ERROR_MORE_DATA`, so reads of arbitrary size work. The send path does not: [**AsyncWrite**](NamedPipeServerConnection#asyncwrite) (and the client-side [**AsyncWrite**](NamedPipeClientConnection#asyncwrite)) copies the caller's `Byte()` *without a bounds-check* into a per-completion buffer sized at [**MessageBufferSize**](NamedPipeServer#messagebuffersize) (default **131072** bytes); the same applies to [**AsyncBroadcast**](NamedPipeServer#asyncbroadcast). A larger message overruns the buffer --- likely a crash or heap corruption rather than a clean error. Raise [**MessageBufferSize**](NamedPipeServer#messagebuffersize) above the largest expected message *before* the first [**Start**](NamedPipeServer#start) (server) or [**Connect**](NamedPipeClientManager#connect) (client); the value is read once at that point and propagated to every per-connection buffer. ## Classes diff --git a/docs/Reference/WinNativeCommonCtls/DTPicker.md b/docs/Reference/WinNativeCommonCtls/DTPicker.md index 76f3a470..8e61af9f 100644 --- a/docs/Reference/WinNativeCommonCtls/DTPicker.md +++ b/docs/Reference/WinNativeCommonCtls/DTPicker.md @@ -23,14 +23,14 @@ Private Sub DTPicker1_Change() End Sub ``` -The control inherits the focusable rect-dockable members from `BaseControlFocusable` — size, position, **Anchors**, **Dock**, **Font**, **BackColor** / **ForeColor**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. +The control inherits the focusable rect-dockable members from `BaseControlFocusable` --- size, position, **Anchors**, **Dock**, **Font**, **BackColor** / **ForeColor**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. * TOC {:toc} ## Format and value -[**Format**](#format) selects one of four display styles — long date, short date, time, or a custom format string supplied through [**CustomFormat**](#customformat). The inline value is always a **Date**, but [**Value**](#value) is typed **Variant** because a [**CheckBox**](#checkbox)-equipped picker may have no date assigned (the user can clear the checkbox), in which case [**Value**](#value) reads as **Null**. +[**Format**](#format) selects one of four display styles --- long date, short date, time, or a custom format string supplied through [**CustomFormat**](#customformat). The inline value is always a **Date**, but [**Value**](#value) is typed **Variant** because a [**CheckBox**](#checkbox)-equipped picker may have no date assigned (the user can clear the checkbox), in which case [**Value**](#value) reads as **Null**. The convenience accessors [**Year**](#year), [**Month**](#month), [**Week**](#week), [**Day**](#day), [**Hour**](#hour), [**Minute**](#minute), and [**Second**](#second) decompose the current value into individual components; assigning to any of them rewrites [**Value**](#value) with the requested component changed. The [**StartOfWeek**](#startofweek) property selects the first-day-of-week used by the calendar dropdown and by [**Week**](#week). @@ -42,7 +42,7 @@ When [**Format**](#format) is set to **dtpCustom**, the [**CustomFormat**](#cust When the dropdown calendar is shown, the [**CalendarBackColor**](#calendarbackcolor), [**CalendarForeColor**](#calendarforecolor), [**CalendarTitleBackColor**](#calendartitlebackcolor), [**CalendarTitleForeColor**](#calendartitleforecolor), and [**CalendarTrailingForeColor**](#calendartrailingforecolor) properties control the calendar's colors via `DTM_SETMCCOLOR`. The [**CalendarShowToday**](#calendarshowtoday), [**CalendarShowTodayCircle**](#calendarshowtodaycircle), [**CalendarShowWeekNumbers**](#calendarshowweeknumbers), and [**CalendarShowTrailingDates**](#calendarshowtrailingdates) booleans toggle the corresponding `MCS_…` style flags on the embedded calendar. -[**hWndCalendar**](#hwndcalendar) returns the Win32 handle of the dropped-down calendar window — useful for advanced customization. It is only valid between the [**DropDown**](#dropdown) and [**CloseUp**](#closeup) events. +[**hWndCalendar**](#hwndcalendar) returns the Win32 handle of the dropped-down calendar window --- useful for advanced customization. It is only valid between the [**DropDown**](#dropdown) and [**CloseUp**](#closeup) events. Properties ---------- @@ -97,7 +97,7 @@ The text color used for trailing days from adjacent months when [**CalendarShowT Whether the picker includes a checkbox next to the date value. **Boolean**. Default: **False**. When **True**, the user can clear the checkbox to leave the picker without a value, in which case [**Value**](#value) returns **Null**. Assigning **Null** to [**Value**](#value) when **CheckBox** is **False** raises run-time error 35787 (*"Can't set Value to NULL when CheckBox property = FALSE"*). -Changing this property at run time recreates the underlying Win32 window — the property cannot be flipped in the GWL_STYLE alone. +Changing this property at run time recreates the underlying Win32 window --- the property cannot be flipped in the GWL_STYLE alone. ### CustomFormat {: .no_toc } @@ -107,7 +107,7 @@ The picture string used when [**Format**](#format) is **dtpCustom**. **String**. ### Day {: .no_toc } -The day-of-month component of [**Value**](#value). **Integer** (1–31). Reading returns the current day; assigning rewrites the date with the new day, raising run-time error 380 if the assigned value is out of range for the current month. See also [**DayCount**](#daycount). +The day-of-month component of [**Value**](#value). **Integer** (1--31). Reading returns the current day; assigning rewrites the date with the new day, raising run-time error 380 if the assigned value is out of range for the current month. See also [**DayCount**](#daycount). ### DayCount {: .no_toc } @@ -127,7 +127,7 @@ The display format. A member of [**DTPickerFormatConstants**](Enumerations/DTPic ### Hour {: .no_toc } -The hour component of [**Value**](#value), in 24-hour form. **Integer** (1–23 — note that `0` is rejected with run-time error 380 by the setter; read returns the live value). Reading is unrestricted. +The hour component of [**Value**](#value), in 24-hour form. **Integer** (1--23 --- note that `0` is rejected with run-time error 380 by the setter; read returns the live value). Reading is unrestricted. ### hWndCalendar {: .no_toc } @@ -147,12 +147,12 @@ The lower bound of the navigable date range. **Date**. Default: `1601-01-01`. As ### Minute {: .no_toc } -The minute component of [**Value**](#value). **Integer** (1–59 on assignment; 0–59 on read). +The minute component of [**Value**](#value). **Integer** (1--59 on assignment; 0--59 on read). ### Month {: .no_toc } -The month-of-year component of [**Value**](#value). **Integer** (1–12). Assigning an out-of-range value raises run-time error 380. +The month-of-year component of [**Value**](#value). **Integer** (1--12). Assigning an out-of-range value raises run-time error 380. ### RightToLeft {: .no_toc } @@ -165,7 +165,7 @@ A **Boolean**. ### Second {: .no_toc } -The seconds component of [**Value**](#value). **Integer** (1–59 on assignment; 0–59 on read). +The seconds component of [**Value**](#value). **Integer** (1--59 on assignment; 0--59 on read). ### StartOfWeek {: .no_toc } @@ -191,7 +191,7 @@ Assigning a numeric (non-**Date**) value implicitly converts via **CDate**. Assi ### Week {: .no_toc } -The ISO-style week-of-year for the current [**Value**](#value). **Integer** (1–53). The setter applies a delta of `DateAdd("ww", …)` so changing **Week** preserves the day-of-week within the week. Assigning out-of-range raises run-time error 380. Honors [**StartOfWeek**](#startofweek) when computing the week boundary. +The ISO-style week-of-year for the current [**Value**](#value). **Integer** (1--53). The setter applies a delta of `DateAdd("ww", …)` so changing **Week** preserves the day-of-week within the week. Assigning out-of-range raises run-time error 380. Honors [**StartOfWeek**](#startofweek) when computing the week boundary. ### Year {: .no_toc } @@ -218,7 +218,7 @@ Syntax: *object*\_**CallbackKeyDown**( **ByVal** *KeyCode* **As Integer**, **ByV : The picture-string token identifying which callback field is focused. *CallbackDate* -: **In / out** — the current value the application can mutate before the event returns. +: **In / out** --- the current value the application can mutate before the event returns. ### Change {: .no_toc } @@ -237,7 +237,7 @@ Syntax: *object*\_**Click**( ) ### CloseUp {: .no_toc } -Raised when the dropdown calendar closes — either by the user picking a date, by clicking outside the calendar, or by pressing **Esc**. +Raised when the dropdown calendar closes --- either by the user picking a date, by clicking outside the calendar, or by pressing **Esc**. Syntax: *object*\_**CloseUp**( ) @@ -276,7 +276,7 @@ Syntax: *object*\_**Format**( **ByVal** *CallbackField* **As String**, *Formatte : The picture-string token identifying which callback field is being rendered. *FormattedString* -: **Out** — the application sets this to the text the picker should display in the field. +: **Out** --- the application sets this to the text the picker should display in the field. ### FormatSize {: .no_toc } @@ -289,7 +289,7 @@ Syntax: *object*\_**FormatSize**( **ByVal** *CallbackField* **As String**, *Size : The picture-string token identifying the callback field. *Size* -: **Out** — the application sets this to the expected character count. +: **Out** --- the application sets this to the expected character count. ### GotFocus {: .no_toc } diff --git a/docs/Reference/WinNativeCommonCtls/Enumerations/DTPickerFormatConstants.md b/docs/Reference/WinNativeCommonCtls/Enumerations/DTPickerFormatConstants.md index a14dbc4b..3398228a 100644 --- a/docs/Reference/WinNativeCommonCtls/Enumerations/DTPickerFormatConstants.md +++ b/docs/Reference/WinNativeCommonCtls/Enumerations/DTPickerFormatConstants.md @@ -8,7 +8,7 @@ permalink: /tB/Packages/WinNativeCommonCtls/Enumerations/DTPickerFormatConstants # DTPickerFormatConstants {: .no_toc } -Selects the display format used by a [**DTPicker**](../DTPicker) control. Carried by the [**DTPicker.Format**](../DTPicker#format) property. +Selects the display format used by a [**DTPicker**](../DTPicker) control. Used by the [**DTPicker.Format**](../DTPicker#format) property. When set to **dtpCustom**, the picker also reads [**DTPicker.CustomFormat**](../DTPicker#customformat) to control the actual display. diff --git a/docs/Reference/WinNativeCommonCtls/Enumerations/ImlDrawConstants.md b/docs/Reference/WinNativeCommonCtls/Enumerations/ImlDrawConstants.md index 96236e1f..32ea8e61 100644 --- a/docs/Reference/WinNativeCommonCtls/Enumerations/ImlDrawConstants.md +++ b/docs/Reference/WinNativeCommonCtls/Enumerations/ImlDrawConstants.md @@ -20,10 +20,10 @@ ImageList1.ListImages("doc").Draw _ | Member | Value | Description | |---------------------------|-------|--------------------------------------------------------------------------| | **ImlDrawNormal**{: #ImlDrawNormal } | 1 | Render in the normal state (no overlays). | -| **ImlDrawTransparent**{: #ImlDrawTransparent } | 2 | Honour the image's mask / alpha — transparent pixels stay transparent. | +| **ImlDrawTransparent**{: #ImlDrawTransparent } | 2 | Honour the image's mask / alpha --- transparent pixels stay transparent. | | **ImlDrawSelected**{: #ImlDrawSelected } | 4 | Render with the selection-color overlay (typically a blue tint). | | **ImlDrawFocus**{: #ImlDrawFocus } | 8 | Render with the focus-rectangle overlay (dotted border). | -| **ImlDrawNoMask**{: #ImlDrawNoMask } | 16 | Bypass the mask — draw the entire bitmap including pixels that would normally be transparent. | +| **ImlDrawNoMask**{: #ImlDrawNoMask } | 16 | Bypass the mask --- draw the entire bitmap including pixels that would normally be transparent. | ## See Also diff --git a/docs/Reference/WinNativeCommonCtls/Enumerations/TreeLabelEditConstants.md b/docs/Reference/WinNativeCommonCtls/Enumerations/TreeLabelEditConstants.md index 62917343..caa00a71 100644 --- a/docs/Reference/WinNativeCommonCtls/Enumerations/TreeLabelEditConstants.md +++ b/docs/Reference/WinNativeCommonCtls/Enumerations/TreeLabelEditConstants.md @@ -8,7 +8,7 @@ permalink: /tB/Packages/WinNativeCommonCtls/Enumerations/TreeLabelEditConstants # TreeLabelEditConstants {: .no_toc } -Controls when inline label editing is triggered on a [**TreeView**](../TreeView/). Carried by [**TreeView.LabelEdit**](../TreeView/#labeledit). +Controls when inline label editing is triggered on a [**TreeView**](../TreeView/). Used by [**TreeView.LabelEdit**](../TreeView/#labeledit). | Member | Value | Description | |----------------------|-------|-----------------------------------------------------------------------------------| diff --git a/docs/Reference/WinNativeCommonCtls/Enumerations/TreeLineStyleConstants.md b/docs/Reference/WinNativeCommonCtls/Enumerations/TreeLineStyleConstants.md index 59831d41..397fadff 100644 --- a/docs/Reference/WinNativeCommonCtls/Enumerations/TreeLineStyleConstants.md +++ b/docs/Reference/WinNativeCommonCtls/Enumerations/TreeLineStyleConstants.md @@ -8,7 +8,7 @@ permalink: /tB/Packages/WinNativeCommonCtls/Enumerations/TreeLineStyleConstants # TreeLineStyleConstants {: .no_toc } -Controls whether the [**TreeView**](../TreeView/) draws tree lines from root nodes or only from child nodes. Carried by [**TreeView.LineStyle**](../TreeView/#linestyle). Only has visible effect when [**Style**](../TreeView/#style) is one of the **tvwTreelines…** variants. +Controls whether the [**TreeView**](../TreeView/) draws tree lines from root nodes or only from child nodes. Used by [**TreeView.LineStyle**](../TreeView/#linestyle). Only has visible effect when [**Style**](../TreeView/#style) is one of the **tvwTreelines…** variants. | Member | Value | Description | |-----------------------|-------|----------------------------------------------------------------------------| diff --git a/docs/Reference/WinNativeCommonCtls/Enumerations/TreeRelationshipConstants.md b/docs/Reference/WinNativeCommonCtls/Enumerations/TreeRelationshipConstants.md index 04536366..9189b868 100644 --- a/docs/Reference/WinNativeCommonCtls/Enumerations/TreeRelationshipConstants.md +++ b/docs/Reference/WinNativeCommonCtls/Enumerations/TreeRelationshipConstants.md @@ -12,8 +12,8 @@ Describes where a new node is inserted relative to an existing node. Passed as t | Member | Value | Description | |----------------------|-------|------------------------------------------------------------------------------------------| -| **tvwFirst**{: #tvwFirst } | 0 | The new node becomes the first sibling of *Relative*'s parent — i.e. the leftmost peer. | -| **tvwLast**{: #tvwLast } | 1 | The new node becomes the last sibling of *Relative*'s parent — i.e. the rightmost peer. | +| **tvwFirst**{: #tvwFirst } | 0 | The new node becomes the first sibling of *Relative*'s parent --- i.e. the leftmost peer. | +| **tvwLast**{: #tvwLast } | 1 | The new node becomes the last sibling of *Relative*'s parent --- i.e. the rightmost peer. | | **tvwNext**{: #tvwNext } | 2 | The new node is inserted immediately after *Relative*, as its next sibling. | | **tvwPrevious**{: #tvwPrevious } | 3 | The new node is inserted immediately before *Relative*, as its previous sibling. | | **tvwChild**{: #tvwChild } | 4 | The new node becomes a child of *Relative*. | diff --git a/docs/Reference/WinNativeCommonCtls/Enumerations/TreeStyleConstants.md b/docs/Reference/WinNativeCommonCtls/Enumerations/TreeStyleConstants.md index be3679ce..d9f331d9 100644 --- a/docs/Reference/WinNativeCommonCtls/Enumerations/TreeStyleConstants.md +++ b/docs/Reference/WinNativeCommonCtls/Enumerations/TreeStyleConstants.md @@ -10,22 +10,22 @@ permalink: /tB/Packages/WinNativeCommonCtls/Enumerations/TreeStyleConstants Composite visual style of a [**TreeView**](../TreeView/), encoding a 3-bit combination of which elements appear: **plus-minus** buttons, **treelines**, and **picture** icons. The labels are always shown. -Carried by [**TreeView.Style**](../TreeView/#style). Default: **tvwTreelinesPlusMinusPictureText**. +Used by [**TreeView.Style**](../TreeView/#style). Default: **tvwTreelinesPlusMinusPictureText**. The composite decoding: | [**Style**](../TreeView/#style) | Buttons | Lines | Icons | Labels | |--------------------------------------------------|---------|-------|-------|--------| -| **tvwTextOnly** | — | — | — | yes | -| **tvwPictureText** | — | — | yes | yes | -| **tvwPlusMinusText** | yes | — | — | yes | -| **tvwPlusMinusPictureText** | yes | — | yes | yes | -| **tvwTreelinesText** | — | yes | — | yes | -| **tvwTreelinesPictureText** | — | yes | yes | yes | -| **tvwTreelinesPlusMinusText** | yes | yes | — | yes | +| **tvwTextOnly** | --- | --- | --- | yes | +| **tvwPictureText** | --- | --- | yes | yes | +| **tvwPlusMinusText** | yes | --- | --- | yes | +| **tvwPlusMinusPictureText** | yes | --- | yes | yes | +| **tvwTreelinesText** | --- | yes | --- | yes | +| **tvwTreelinesPictureText** | --- | yes | yes | yes | +| **tvwTreelinesPlusMinusText** | yes | yes | --- | yes | | **tvwTreelinesPlusMinusPictureText** | yes | yes | yes | yes | -The enum's underlying values are 0–7, matching the order in the table. +The enum's underlying values are 0--7, matching the order in the table. | Member | Value | |----------------------------------------------|-------| diff --git a/docs/Reference/WinNativeCommonCtls/Enumerations/index.md b/docs/Reference/WinNativeCommonCtls/Enumerations/index.md index cec8ed34..72f6d4f8 100644 --- a/docs/Reference/WinNativeCommonCtls/Enumerations/index.md +++ b/docs/Reference/WinNativeCommonCtls/Enumerations/index.md @@ -12,7 +12,7 @@ nav_order: 99 The ten module-level enumerations declared in the package's shared modules and exposed to user code. Each is reachable from any project that references the package. -Per-control nested enumerations (those declared *inside* a `<Name>BaseCtl` class — `ListViewConstants`, `ListArrangeConstants`, `ListLabelEditConstants`, `ListTextBackgroundConstants`, `ListColumnAlignmentConstants`, `PrbOrientation`, `PrbScrolling`, `PrbState`, `TickStyleConstants`, `TextPositionConstants`, `ImageListColorDepth`) are documented on the page of the control that declares them, not under this folder. +Per-control nested enumerations (those declared *inside* a `<Name>BaseCtl` class --- `ListViewConstants`, `ListArrangeConstants`, `ListLabelEditConstants`, `ListTextBackgroundConstants`, `ListColumnAlignmentConstants`, `PrbOrientation`, `PrbScrolling`, `PrbState`, `TickStyleConstants`, `TextPositionConstants`, `ImageListColorDepth`) are documented on the page of the control that declares them, not under this folder. * TOC {:toc} diff --git a/docs/Reference/WinNativeCommonCtls/ImageList/ListImage.md b/docs/Reference/WinNativeCommonCtls/ImageList/ListImage.md index b77e81ee..5be11eba 100644 --- a/docs/Reference/WinNativeCommonCtls/ImageList/ListImage.md +++ b/docs/Reference/WinNativeCommonCtls/ImageList/ListImage.md @@ -11,7 +11,7 @@ has_toc: false A **ListImage** is one picture inside an [**ImageList**](.)'s [**ListImages**](ListImages) collection. Returned from [**ListImages.Add**](ListImages#add) and from [**ListImages.Item**](ListImages#item). -The class is tagged `[COMCreatable(False)]` — user code never instantiates a **ListImage** directly; the [**ListImages**](ListImages) collection creates them as part of its **Add** method. +The class is tagged `[COMCreatable(False)]` --- user code never instantiates a **ListImage** directly; the [**ListImages**](ListImages) collection creates them as part of its **Add** method. ```tb Dim img As ListImage = ImageList1.ListImages.Add(, "open", LoadPicture("open.ico")) diff --git a/docs/Reference/WinNativeCommonCtls/ImageList/ListImages.md b/docs/Reference/WinNativeCommonCtls/ImageList/ListImages.md index 6b15b41c..aee43e66 100644 --- a/docs/Reference/WinNativeCommonCtls/ImageList/ListImages.md +++ b/docs/Reference/WinNativeCommonCtls/ImageList/ListImages.md @@ -9,9 +9,9 @@ has_toc: false # ListImages class {: .no_toc } -The **ListImages** collection is the entry point for managing the pictures inside an [**ImageList**](.). Reached as `<imageList>.ListImages`; supports adding, removing, indexed access, and `For Each` iteration. +The **ListImages** collection is the entry point for managing the pictures inside an [**ImageList**](.). Accessed as `<imageList>.ListImages`; supports adding, removing, indexed access, and `For Each` iteration. -The class is tagged `[COMCreatable(False)]` — user code reaches **ListImages** through the parent [**ImageList**](.) control's [**ListImages**](.#listimages) property, never by direct instantiation. +The class is tagged `[COMCreatable(False)]` --- user code accesses **ListImages** through the parent [**ImageList**](.) control's [**ListImages**](.#listimages) property, never by direct instantiation. ```tb With ImageList1.ListImages @@ -31,7 +31,7 @@ Next ## Modification while bound -If the parent [**ImageList**](.) is bound to a consuming control (a [**ListView**](../ListView/) or [**TreeView**](../TreeView/) has it set as their image-list property), [**Clear**](#clear) and [**Remove**](#remove) raise run-time error 35617 (*"ImageList cannot be modified while another control is bound to it"*). [**Add**](#add) is unaffected — new pictures can always be added. +If the parent [**ImageList**](.) is bound to a consuming control (a [**ListView**](../ListView/) or [**TreeView**](../TreeView/) has it set as their image-list property), [**Clear**](#clear) and [**Remove**](#remove) raise run-time error 35617 (*"ImageList cannot be modified while another control is bound to it"*). [**Add**](#add) is unaffected --- new pictures can always be added. To rebuild a bound image list, first unbind by setting the consuming control's image-list property to **Nothing**. @@ -51,7 +51,7 @@ Returns the [**ListImage**](ListImage) at the given index or with the given key. Syntax: *object*.**Item** ( *Index* ) **As ListImage** *Index* -: A **Variant** that is either a 1-based **Long** position in the collection or a **String** key (case-sensitive — the collection uses `vbBinaryCompare`). +: A **Variant** that is either a 1-based **Long** position in the collection or a **String** key (case-sensitive --- the collection uses `vbBinaryCompare`). Methods ------- @@ -106,7 +106,7 @@ Removes a picture from the collection. The remaining pictures' [**Index**](ListI Syntax: *object*.**Remove** ( *Index* ) *Index* -: A **Variant** — either a 1-based **Long** position or a **String** key. Out-of-range / non-existent values raise run-time error 35601. Non-string non-numeric values raise run-time error 35603. +: A **Variant** --- either a 1-based **Long** position or a **String** key. Out-of-range / non-existent values raise run-time error 35601. Non-string non-numeric values raise run-time error 35603. Raises run-time error 35617 if the parent [**ImageList**](.) is currently bound to a consuming control. diff --git a/docs/Reference/WinNativeCommonCtls/ImageList/index.md b/docs/Reference/WinNativeCommonCtls/ImageList/index.md index a9dff590..38b8b040 100644 --- a/docs/Reference/WinNativeCommonCtls/ImageList/index.md +++ b/docs/Reference/WinNativeCommonCtls/ImageList/index.md @@ -8,7 +8,7 @@ has_toc: false # ImageList class {: .no_toc } -An **ImageList** is an off-screen container for pictures, all of which are scaled to the same [**ImageWidth**](#imagewidth) × [**ImageHeight**](#imageheight) bitmap size. The control has no visible representation at run time — its purpose is to feed icons to other controls that consume them through their [**Icons**](../ListView/#icons), [**SmallIcons**](../ListView/#smallicons), [**ColumnHeaderIcons**](../ListView/#columnheadericons), or [**ImageList**](../TreeView/#imagelist) properties. +An **ImageList** is an off-screen container for pictures, all of which are scaled to the same [**ImageWidth**](#imagewidth) × [**ImageHeight**](#imageheight) bitmap size. The control has no visible representation at run time --- its purpose is to feed icons to other controls that consume them through their [**Icons**](../ListView/#icons), [**SmallIcons**](../ListView/#smallicons), [**ColumnHeaderIcons**](../ListView/#columnheadericons), or [**ImageList**](../TreeView/#imagelist) properties. ```tb Private Sub Form_Load() @@ -26,22 +26,22 @@ Private Sub Form_Load() End Sub ``` -The control inherits the rectangular non-focusable base members from `BaseControlNotFocusable` — size and position (size is irrelevant at run time since the control isn't drawn), **Name**, **Tag**, **hWnd**. It does not expose **Visible**, **Anchors**, or **Dock** in any meaningful way, and never accepts focus. +The control inherits the rectangular non-focusable base members from `BaseControlNotFocusable` --- size and position (size is irrelevant at run time since the control isn't drawn), **Name**, **Tag**, **hWnd**. It does not expose **Visible**, **Anchors**, or **Dock** in any meaningful way, and never accepts focus. * TOC {:toc} ## Image size lock-in -The first picture added to the list fixes its [**ImageWidth**](#imagewidth) and [**ImageHeight**](#imageheight) — every subsequent picture is scaled to match those dimensions. The sizes can also be set explicitly *before* any image is added (typically through the design-time properties), in which case the first **Add** call honors the pre-set values rather than measuring the incoming picture. +The first picture added to the list fixes its [**ImageWidth**](#imagewidth) and [**ImageHeight**](#imageheight) --- every subsequent picture is scaled to match those dimensions. The sizes can also be set explicitly *before* any image is added (typically through the design-time properties), in which case the first **Add** call honors the pre-set values rather than measuring the incoming picture. Once any image is in the list, attempting to assign [**ImageWidth**](#imagewidth) or [**ImageHeight**](#imageheight) raises run-time error 35611 with the message *"Property is read-only if image list contains images"*. To resize an image list, call [**ListImages.Clear**](ListImages#clear) first. ## Mask color and transparency -When [**UseMaskColor**](#usemaskcolor) is **True** (the default), every bitmap added through [**ListImages.Add**](ListImages#add) is masked: pixels matching [**MaskColor**](#maskcolor) become transparent when the image is rendered into a consuming control. The default [**MaskColor**](#maskcolor) is `&H00C0C0C0` (silver), which matches the classic VB6 transparency convention. Icons (passed as `StdPicture` of type `vbPicTypeIcon`) carry their own alpha mask and are unaffected by **MaskColor** / **UseMaskColor**. +When [**UseMaskColor**](#usemaskcolor) is **True** (the default), every bitmap added through [**ListImages.Add**](ListImages#add) is masked: pixels matching [**MaskColor**](#maskcolor) become transparent when the image is rendered into a consuming control. The default [**MaskColor**](#maskcolor) is `&H00C0C0C0` (silver), which matches the classic VB6 transparency convention. Icons (passed as `StdPicture` of type `vbPicTypeIcon`) include their own alpha mask and are unaffected by **MaskColor** / **UseMaskColor**. -Setting [**ColorDepth**](#colordepth) to **ColorDepth32Bit** disables masking entirely — the alpha channel is preserved directly. +Setting [**ColorDepth**](#colordepth) to **ColorDepth32Bit** disables masking entirely --- the alpha channel is preserved directly. ## Binding to consumers @@ -58,7 +58,7 @@ The background color used to render the image list into a target DC via [**ListI ### ColorDepth {: .no_toc } -The pixel depth of the underlying bitmap storage. A member of [**ImageListColorDepth**](#imagelistcolordepth). Default: **ColorDepth32Bit**. Once images have been added, this value is fixed for the life of the list — to change it, call [**ListImages.Clear**](ListImages#clear) first. +The pixel depth of the underlying bitmap storage. A member of [**ImageListColorDepth**](#imagelistcolordepth). Default: **ColorDepth32Bit**. Once images have been added, this value is fixed for the life of the list --- to change it, call [**ListImages.Clear**](ListImages#clear) first. ### hImageList {: .no_toc } @@ -111,7 +111,7 @@ Syntax: *object*.**Overlay** ( *Key1*, *Key2* ) **As StdPicture** *Key2* : The **Index** or **Key** of the top image. -Returns an **StdPicture** of type **vbPicTypeIcon** suitable for direct rendering or for use elsewhere — note this is a one-off snapshot, not a reference into the image list. The returned icon is destroyed when the **StdPicture** goes out of scope. +Returns an **StdPicture** of type **vbPicTypeIcon** suitable for direct rendering or for use elsewhere --- note this is a one-off snapshot, not a reference into the image list. The returned icon is destroyed when the **StdPicture** goes out of scope. ## ImageListColorDepth {: #imagelistcolordepth } diff --git a/docs/Reference/WinNativeCommonCtls/ListView/ColumnHeader.md b/docs/Reference/WinNativeCommonCtls/ListView/ColumnHeader.md index 38ed8a8e..e6fce866 100644 --- a/docs/Reference/WinNativeCommonCtls/ListView/ColumnHeader.md +++ b/docs/Reference/WinNativeCommonCtls/ListView/ColumnHeader.md @@ -11,7 +11,7 @@ has_toc: false A **ColumnHeader** represents a single column in a [**ListView**](.) running in **lvwReport** view. Returned from [**ColumnHeaders.Add**](ColumnHeaders#add) and from [**ColumnHeaders.Item**](ColumnHeaders#item). -The class is tagged `[COMCreatable(False)]` — user code reaches **ColumnHeader** instances through the parent [**ListView**](.)'s [**ColumnHeaders**](ColumnHeaders) collection. +The class is tagged `[COMCreatable(False)]` --- user code accesses **ColumnHeader** instances through the parent [**ListView**](.)'s [**ColumnHeaders**](ColumnHeaders) collection. ```tb With ListView1.ColumnHeaders @@ -38,7 +38,7 @@ The horizontal alignment of the column's text. A member of [**ListColumnAlignmen ### Icon {: .no_toc } -The icon rendered in the header. **Variant** — either a 1-based **Long** index into [**ListView.ColumnHeaderIcons**](.#columnheadericons), or a **String** key. Assignment validates against the bound image list. +The icon rendered in the header. **Variant** --- either a 1-based **Long** index into [**ListView.ColumnHeaderIcons**](.#columnheadericons), or a **String** key. Assignment validates against the bound image list. ### Index {: .no_toc } @@ -58,7 +58,7 @@ The column's horizontal pixel position in the listview, computed as the sum of p ### Position {: .no_toc } -The column's visual position. **Long**, read/write. Distinct from [**Index**](#index) — when [**ListView.AllowColumnReorder**](.#allowcolumnreorder) is **True**, the user can drag columns to reorder them, in which case **Index** stays fixed but **Position** changes. +The column's visual position. **Long**, read/write. Distinct from [**Index**](#index) --- when [**ListView.AllowColumnReorder**](.#allowcolumnreorder) is **True**, the user can drag columns to reorder them, in which case **Index** stays fixed but **Position** changes. Assigning a value outside `1..Count` raises run-time error 380. diff --git a/docs/Reference/WinNativeCommonCtls/ListView/ColumnHeaders.md b/docs/Reference/WinNativeCommonCtls/ListView/ColumnHeaders.md index dc5011d5..2858c24e 100644 --- a/docs/Reference/WinNativeCommonCtls/ListView/ColumnHeaders.md +++ b/docs/Reference/WinNativeCommonCtls/ListView/ColumnHeaders.md @@ -9,9 +9,9 @@ has_toc: false # ColumnHeaders class {: .no_toc } -The **ColumnHeaders** collection is the entry point for managing the columns of a [**ListView**](.) in **lvwReport** view. Reached as `<listView>.ColumnHeaders`; supports adding, removing, indexed access, and `For Each` iteration. +The **ColumnHeaders** collection is the entry point for managing the columns of a [**ListView**](.) in **lvwReport** view. Accessed as `<listView>.ColumnHeaders`; supports adding, removing, indexed access, and `For Each` iteration. -The class is tagged `[COMCreatable(False)]` — user code reaches **ColumnHeaders** through the parent [**ListView**](.) control's [**ColumnHeaders**](.#columnheaders) property. +The class is tagged `[COMCreatable(False)]` --- user code accesses **ColumnHeaders** through the parent [**ListView**](.) control's [**ColumnHeaders**](.#columnheaders) property. ```tb With ListView1.ColumnHeaders @@ -40,7 +40,7 @@ Returns the [**ColumnHeader**](ColumnHeader) at the given index or with the give Syntax: *object*.**Item** ( *Index* ) **As ColumnHeader** *Index* -: A **Variant** — either a 1-based **Long** position or a **String** key. +: A **Variant** --- either a 1-based **Long** position or a **String** key. Methods ------- @@ -68,7 +68,7 @@ Syntax: *object*.**Add** ( [ *Index* ] [, *Key* ] [, *Text* ] [, *Width* ] [, *A : *optional* A member of [**ListColumnAlignmentConstants**](ColumnHeader#listcolumnalignmentconstants). Default: **lvwColumnLeft**. Attempting to add a non-left-aligned column at position `1` raises run-time error 5. *Icon* -: *optional* A **Variant** identifying the header icon — either a 1-based **Long** index into [**ListView.ColumnHeaderIcons**](.#columnheadericons), or a **String** key. +: *optional* A **Variant** identifying the header icon --- either a 1-based **Long** index into [**ListView.ColumnHeaderIcons**](.#columnheadericons), or a **String** key. Returns the newly-created [**ColumnHeader**](ColumnHeader). @@ -87,7 +87,7 @@ Removes a column from the listview. Syntax: *object*.**Remove** ( *Index* ) *Index* -: A **Variant** — either a 1-based **Long** position or a **String** key. +: A **Variant** --- either a 1-based **Long** position or a **String** key. ### _NewEnum {: .no_toc } diff --git a/docs/Reference/WinNativeCommonCtls/ListView/ListItem.md b/docs/Reference/WinNativeCommonCtls/ListView/ListItem.md index 4a1373b0..57af8393 100644 --- a/docs/Reference/WinNativeCommonCtls/ListView/ListItem.md +++ b/docs/Reference/WinNativeCommonCtls/ListView/ListItem.md @@ -11,7 +11,7 @@ has_toc: false A **ListItem** is a single row in a [**ListView**](.). Returned from [**ListItems.Add**](ListItems#add) and from [**ListItems.Item**](ListItems#item). In **lvwReport** view, the first column is the main label ([**Text**](#text)); subsequent columns are exposed through [**SubItems**](#subitemsindex)(*index*). -The class is tagged `[COMCreatable(False)]` — user code reaches **ListItem** instances through the parent [**ListView**](.)'s [**ListItems**](ListItems) collection, never by direct instantiation. +The class is tagged `[COMCreatable(False)]` --- user code accesses **ListItem** instances through the parent [**ListView**](.)'s [**ListItems**](ListItems) collection, never by direct instantiation. ```tb Dim item As ListItem = ListView1.ListItems.Add(, "doc1", "Report.docx", "doc") @@ -30,7 +30,7 @@ Properties ### BackColor {: .no_toc } -The background color used to render this row. **OLE_COLOR**. Default: `-1` (transparent — defer to [**ListView.BackColor**](#backcolor)). +The background color used to render this row. **OLE_COLOR**. Default: `-1` (transparent --- defer to [**ListView.BackColor**](#backcolor)). ### Bold {: .no_toc } @@ -45,7 +45,7 @@ Whether the row's checkbox is checked. **Boolean**. Only meaningful when [**List ### EnsureVisible {: .no_toc } -Scrolls the listview so this row is visible. Available as a method (not a property — listed in the methods section below). +Scrolls the listview so this row is visible. Available as a method (not a property --- listed in the methods section below). ### ForeColor {: .no_toc } @@ -65,7 +65,7 @@ The pixel height of the row's selection rectangle. **Single**, read-only. ### Icon {: .no_toc } -The large icon for the row in [**lvwIcon**](.#listviewconstants) view. **Variant** — either a 1-based **Long** index into [**ListView.Icons**](.#icons), or a **String** key. Assignment validates against the bound image list and raises run-time error 35601 (*"Element not found"*) for an unknown key, 35600 (*"Index out of bounds"*) for an out-of-range index, or 35613 (*"ImageList must be initialized before it can be used"*) if no image list is bound. +The large icon for the row in [**lvwIcon**](.#listviewconstants) view. **Variant** --- either a 1-based **Long** index into [**ListView.Icons**](.#icons), or a **String** key. Assignment validates against the bound image list and raises run-time error 35601 (*"Element not found"*) for an unknown key, 35600 (*"Index out of bounds"*) for an out-of-range index, or 35613 (*"ImageList must be initialized before it can be used"*) if no image list is bound. ### Index {: .no_toc } @@ -90,7 +90,7 @@ Whether the row is selected. **Boolean**, read/write. Setting **Selected = True* ### SmallIcon {: .no_toc } -The small icon for the row in non-icon views. **Variant** — either an index or a key into [**ListView.SmallIcons**](.#smallicons). Same validation as [**Icon**](#icon). +The small icon for the row in non-icon views. **Variant** --- either an index or a key into [**ListView.SmallIcons**](.#smallicons). Same validation as [**Icon**](#icon). ### SubItems(Index) {: #subitemsindex .no_toc } @@ -112,7 +112,7 @@ The row's main label text. **String**, read/write. The default member. Maps to t ### ToolTipText {: .no_toc } -A tooltip string shown when the user hovers over this row. **String**. Surfaced through the listview's `LVS_EX_INFOTIP` extended style. +A tooltip string shown when the user hovers over this row. **String**. Exposed through the listview's `LVS_EX_INFOTIP` extended style. ### Top {: .no_toc } @@ -131,7 +131,7 @@ Methods {: .no_toc } > [!NOTE] -> **CreateDragImage** is tagged `[Unimplemented]` in the current source. Calling it has no useful effect — the body is empty. +> **CreateDragImage** is tagged `[Unimplemented]` in the current source. Calling it has no useful effect --- the body is empty. ### EnsureVisible {: .no_toc } diff --git a/docs/Reference/WinNativeCommonCtls/ListView/ListItems.md b/docs/Reference/WinNativeCommonCtls/ListView/ListItems.md index d2cbc696..be1007a5 100644 --- a/docs/Reference/WinNativeCommonCtls/ListView/ListItems.md +++ b/docs/Reference/WinNativeCommonCtls/ListView/ListItems.md @@ -9,9 +9,9 @@ has_toc: false # ListItems class {: .no_toc } -The **ListItems** collection is the entry point for managing the rows of a [**ListView**](.). Reached as `<listView>.ListItems`; supports adding, removing, indexed access, and `For Each` iteration. +The **ListItems** collection is the entry point for managing the rows of a [**ListView**](.). Accessed as `<listView>.ListItems`; supports adding, removing, indexed access, and `For Each` iteration. -The class is tagged `[COMCreatable(False)]` — user code reaches **ListItems** through the parent [**ListView**](.) control's [**ListItems**](.#listitems) property. +The class is tagged `[COMCreatable(False)]` --- user code accesses **ListItems** through the parent [**ListView**](.) control's [**ListItems**](.#listitems) property. ```tb With ListView1.ListItems @@ -46,7 +46,7 @@ Returns the [**ListItem**](ListItem) at the given index or with the given key. T Syntax: *object*.**Item** ( *Index* ) **As ListItem** *Index* -: A **Variant** — either a 1-based **Long** position or a **String** key. +: A **Variant** --- either a 1-based **Long** position or a **String** key. Methods ------- @@ -68,7 +68,7 @@ Syntax: *object*.**Add** ( [ *Index* ] [, *Key* ] [, *Text* ] [, *Icon* ] [, *Sm : *optional* A **String** giving the row's main label. *Icon* -: *optional* A **Variant** identifying the row's large icon — either a 1-based **Long** index into [**ListView.Icons**](.#icons), or a **String** key. Validated against the bound image list. +: *optional* A **Variant** identifying the row's large icon --- either a 1-based **Long** index into [**ListView.Icons**](.#icons), or a **String** key. Validated against the bound image list. *SmallIcon* : *optional* A **Variant** identifying the row's small icon, against [**ListView.SmallIcons**](.#smallicons). @@ -90,7 +90,7 @@ Removes a row from the listview. The remaining rows' [**Index**](ListItem#index) Syntax: *object*.**Remove** ( *Index* ) *Index* -: A **Variant** — either a 1-based **Long** position or a **String** key. +: A **Variant** --- either a 1-based **Long** position or a **String** key. ### _NewEnum {: .no_toc } diff --git a/docs/Reference/WinNativeCommonCtls/ListView/index.md b/docs/Reference/WinNativeCommonCtls/ListView/index.md index bb40dc7d..066f36b0 100644 --- a/docs/Reference/WinNativeCommonCtls/ListView/index.md +++ b/docs/Reference/WinNativeCommonCtls/ListView/index.md @@ -17,7 +17,7 @@ A **ListView** is a flexible multi-column / icon list with four distinct visual | **lvwList** | A single column of small-icon-plus-label entries, wrapped into multiple columns to fit. | | **lvwReport** | Multi-column table view with header row; columns are defined through [**ColumnHeaders**](ColumnHeaders). | -The two main collections are reached through properties: [**ListItems**](#listitems) for the rows, and [**ColumnHeaders**](#columnheaders) for the **Report**-view column headers. +The two main collections are accessed through properties: [**ListItems**](#listitems) for the rows, and [**ColumnHeaders**](#columnheaders) for the **Report**-view column headers. ```tb Private Sub Form_Load() @@ -42,7 +42,7 @@ Private Sub ListView1_ItemClick(Item As ListItem) End Sub ``` -The control inherits the focusable rect-dockable members from `BaseControlFocusable` — size, position, **Anchors**, **Dock**, **Font**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. +The control inherits the focusable rect-dockable members from `BaseControlFocusable` --- size, position, **Anchors**, **Dock**, **Font**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. * TOC {:toc} @@ -51,9 +51,9 @@ The control inherits the focusable rect-dockable members from `BaseControlFocusa A **ListView** can bind to three independent [**ImageList**](../ImageList/) instances, one per role: -- **[Icons](#icons)** — large icons rendered in **lvwIcon** view. -- **[SmallIcons](#smallicons)** — small icons rendered in **lvwSmallIcon**, **lvwList**, and **lvwReport** views. -- **[ColumnHeaderIcons](#columnheadericons)** — small icons rendered inside the report-view column headers, addressed per-column through [**ColumnHeader.Icon**](ColumnHeader#icon). +- **[Icons](#icons)** --- large icons rendered in **lvwIcon** view. +- **[SmallIcons](#smallicons)** --- small icons rendered in **lvwSmallIcon**, **lvwList**, and **lvwReport** views. +- **[ColumnHeaderIcons](#columnheadericons)** --- small icons rendered inside the report-view column headers, addressed per-column through [**ColumnHeader.Icon**](ColumnHeader#icon). A [**ListItem**](ListItem) selects its icons through its **Icon** and **SmallIcon** properties, which can be either a 1-based **Long** index or a **String** key into the respective image list. @@ -63,9 +63,9 @@ Selection is single-row by default; setting [**MultiSelect**](#multiselect) to * [**LabelEdit**](#labeledit) controls inline label editing: -- **lvwAutomatic** — clicking an already-selected item starts an edit (after a short delay; this is the F2 / single-click-and-pause pattern). -- **lvwManual** — only programmatic [**StartLabelEdit**](#startlabeledit) calls open an editor. -- **lvwDisabled** — labels cannot be edited. +- **lvwAutomatic** --- clicking an already-selected item starts an edit (after a short delay; this is the F2 / single-click-and-pause pattern). +- **lvwManual** --- only programmatic [**StartLabelEdit**](#startlabeledit) calls open an editor. +- **lvwDisabled** --- labels cannot be edited. Edit start fires [**BeforeLabelEdit**](#beforelabeledit) (cancellable), and edit end fires [**AfterLabelEdit**](#afterlabeledit) (cancellable, with the proposed new text). @@ -156,7 +156,7 @@ The Win32 handle of the listview window. **LongPtr**, read-only. ### hWndHeader {: .no_toc } -The Win32 handle of the embedded column-header window (`SysHeader32`). **LongPtr**, read-only. Tagged `[Hidden]` `[NonBrowsable]` — exposed only for advanced Win32 customization (e.g. subclassing the header). +The Win32 handle of the embedded column-header window (`SysHeader32`). **LongPtr**, read-only. Tagged `[Hidden]` `[NonBrowsable]` --- exposed only for advanced Win32 customization (e.g. subclassing the header). ### Icons {: .no_toc } @@ -176,7 +176,7 @@ Whether item labels wrap to multiple lines in **lvwIcon** view. **Boolean**. Def ### ListItems {: .no_toc } -The [**ListItems**](ListItems) collection — the rows of the list. Read-only. +The [**ListItems**](ListItems) collection --- the rows of the list. Read-only. ### MultiSelect {: .no_toc } @@ -186,7 +186,7 @@ Whether the user can select multiple items. **Boolean**. Default: **False**. ### SelectedItem {: .no_toc } -The currently focused [**ListItem**](ListItem), or **Nothing** if no row is focused. Read-only — to change selection, assign to [**ListItem.Selected**](ListItem#selected). +The currently focused [**ListItem**](ListItem), or **Nothing** if no row is focused. Read-only --- to change selection, assign to [**ListItem.Selected**](ListItem#selected). ### SelectedItemIndex {: .no_toc } diff --git a/docs/Reference/WinNativeCommonCtls/MonthView.md b/docs/Reference/WinNativeCommonCtls/MonthView.md index d5c476e1..405527f4 100644 --- a/docs/Reference/WinNativeCommonCtls/MonthView.md +++ b/docs/Reference/WinNativeCommonCtls/MonthView.md @@ -8,7 +8,7 @@ has_toc: false # MonthView class {: .no_toc } -A **MonthView** is a full-month calendar grid: a visible matrix of [**MonthColumns**](#monthcolumns) × [**MonthRows**](#monthrows) month panels, navigable forwards and backwards through the month headers, with optional today indicator, week numbers, and bold-day highlighting through the [**GetDayBold**](#getdaybold) callback event. Unlike [**DTPicker**](DTPicker) — which shows only its inline value field and pops the calendar on demand — a **MonthView** is always visible on the form. +A **MonthView** is a full-month calendar grid: a visible matrix of [**MonthColumns**](#monthcolumns) × [**MonthRows**](#monthrows) month panels, navigable forwards and backwards through the month headers, with optional today indicator, week numbers, and bold-day highlighting through the [**GetDayBold**](#getdaybold) callback event. Unlike [**DTPicker**](DTPicker) --- which shows only its inline value field and pops the calendar on demand --- a **MonthView** is always visible on the form. ```tb Private Sub Form_Load() @@ -33,7 +33,7 @@ Private Sub MonthView1_GetDayBold( _ End Sub ``` -The control inherits the focusable rect-dockable members from `BaseControlFocusable` — size, position, **Anchors**, **Dock**, **Font**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. +The control inherits the focusable rect-dockable members from `BaseControlFocusable` --- size, position, **Anchors**, **Dock**, **Font**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. * TOC {:toc} @@ -42,13 +42,13 @@ The control inherits the focusable rect-dockable members from `BaseControlFocusa A **MonthView** can display more than one calendar panel at once. [**MonthColumns**](#monthcolumns) and [**MonthRows**](#monthrows) set the panel grid (default 1 × 1); when [**ResizeToFit**](#resizetofit) is **True** (the default), the control auto-sizes its **Width** and **Height** to fit the requested grid using the current [**Font**](../VB/CheckBox#font) and the [**ShowToday**](#showtoday) / [**ShowWeekNumbers**](#showweeknumbers) options. Setting **ResizeToFit** to **False** allows the application to size the control freely, with the calendar panels arranged to fit whatever space is available. -[**GetMonthRange**](#getmonthrange) returns the span of dates currently visible across all panels — useful inside [**GetDayBold**](#getdaybold) to know which days to populate. +[**GetMonthRange**](#getmonthrange) returns the span of dates currently visible across all panels --- useful inside [**GetDayBold**](#getdaybold) to know which days to populate. ## Single-day and multi-day selection When [**MultiSelect**](#multiselect) is **False** (the default), the user can select one date at a time and [**Value**](#value), [**SelStart**](#selstart), and [**SelEnd**](#selend) all report the same value. When [**MultiSelect**](#multiselect) is **True**, the user can drag-select a contiguous range up to [**MaxSelCount**](#maxselcount) days wide; [**SelStart**](#selstart) and [**SelEnd**](#selend) bracket the range, and [**Value**](#value) returns [**SelStart**](#selstart). -Changing [**MultiSelect**](#multiselect) at run time recreates the underlying Win32 window — the property cannot be flipped through GWL_STYLE alone. +Changing [**MultiSelect**](#multiselect) at run time recreates the underlying Win32 window --- the property cannot be flipped through GWL_STYLE alone. ## Bold days for highlighting @@ -80,7 +80,7 @@ The number of calendar panels the underlying control is rendering. **Byte**, rea ### Day {: .no_toc } -The day-of-month component of [**Value**](#value). **Integer** (1–31). See [**DayCount**](#daycount). +The day-of-month component of [**Value**](#value). **Integer** (1--31). See [**DayCount**](#daycount). ### DayBold(date) {: #dayboldday .no_toc } @@ -125,7 +125,7 @@ The lower bound of the navigable date range. **Date**. Default: `1753-01-01`. ### Month {: .no_toc } -The month-of-year component of [**Value**](#value). **Integer** (1–12). +The month-of-year component of [**Value**](#value). **Integer** (1--12). ### MonthBackColor {: .no_toc } @@ -163,7 +163,7 @@ A **Boolean**. ### ScrollRate {: .no_toc } -The number of months the navigation arrows scroll the visible range by. **Long**. Default: `0` — meaning "use the calendar's natural width" (typically `MonthColumns`). Pass any positive integer to override. +The number of months the navigation arrows scroll the visible range by. **Long**. Default: `0` --- meaning "use the calendar's natural width" (typically `MonthColumns`). Pass any positive integer to override. ### SelEnd {: .no_toc } @@ -235,7 +235,7 @@ Syntax: *object*.**VisibleDays**( *sIndex* ) ### Week {: .no_toc } -The week-of-year for the current [**Value**](#value). **Integer** (1–53). +The week-of-year for the current [**Value**](#value). **Integer** (1--53). ### Year {: .no_toc } diff --git a/docs/Reference/WinNativeCommonCtls/ProgressBar.md b/docs/Reference/WinNativeCommonCtls/ProgressBar.md index d902c874..159e5a7b 100644 --- a/docs/Reference/WinNativeCommonCtls/ProgressBar.md +++ b/docs/Reference/WinNativeCommonCtls/ProgressBar.md @@ -35,7 +35,7 @@ ProgressBar1.MarqueeSpeed = 30 ' milliseconds per animation step ProgressBar1.MarqueeAnimation = True ' start animating ``` -The control inherits the non-focusable rect-dockable members from `BaseControlNotFocusable2` — size, position, **Anchors**, **Dock**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. +The control inherits the non-focusable rect-dockable members from `BaseControlNotFocusable2` --- size, position, **Anchors**, **Dock**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. * TOC {:toc} @@ -44,9 +44,9 @@ The control inherits the non-focusable rect-dockable members from `BaseControlNo The visual is the cartesian product of three properties: -- **[Scrolling](#scrolling)** — *Standard* (the default, animated segmented bar), *Smooth* (a continuous block — combine with [**SmoothReverse**](#smoothreverse) to allow the bar to decrease), or *Marquee* (an indeterminate animated stripe; control with [**MarqueeAnimation**](#marqueeanimation) + [**MarqueeSpeed**](#marqueespeed)). -- **[State](#state)** — *Normal* (theme-default color, typically green), *Error* (typically red), or *Paused* (typically yellow). The OS chooses the actual colors based on its current theme. -- **[Orientation](#orientation)** — *Horizontal* or *Vertical*. +- **[Scrolling](#scrolling)** --- *Standard* (the default, animated segmented bar), *Smooth* (a continuous block --- combine with [**SmoothReverse**](#smoothreverse) to allow the bar to decrease), or *Marquee* (an indeterminate animated stripe; control with [**MarqueeAnimation**](#marqueeanimation) + [**MarqueeSpeed**](#marqueespeed)). +- **[State](#state)** --- *Normal* (theme-default color, typically green), *Error* (typically red), or *Paused* (typically yellow). The OS chooses the actual colors based on its current theme. +- **[Orientation](#orientation)** --- *Horizontal* or *Vertical*. All three can be changed at run time; the underlying Win32 styles are re-applied without recreating the window. @@ -120,12 +120,12 @@ The visual style of progress. A member of [**PrbScrolling**](#prbscrolling). Def ### SmoothReverse {: .no_toc } -Whether a smooth progress bar can decrease (when [**Value**](#value) is set to a smaller number). **Boolean**. Default: **False**. Without this flag a smooth bar that has reached, say, 80% will not visibly decrease when [**Value**](#value) is reduced — it simply snaps back. Only meaningful when [**Scrolling**](#scrolling) is **PrbScrollingSmooth**. +Whether a smooth progress bar can decrease (when [**Value**](#value) is set to a smaller number). **Boolean**. Default: **False**. Without this flag a smooth bar that has reached, say, 80% will not visibly decrease when [**Value**](#value) is reduced --- it simply snaps back. Only meaningful when [**Scrolling**](#scrolling) is **PrbScrollingSmooth**. ### State {: .no_toc } -The visual state of the bar. A member of [**PrbState**](#prbstate). Default: **PrbStateNormal**. The OS uses the value to tint the bar — **PrbStateError** typically renders red, **PrbStatePaused** typically renders yellow, **PrbStateNormal** uses the theme-default progress color (typically green). +The visual state of the bar. A member of [**PrbState**](#prbstate). Default: **PrbStateNormal**. The OS uses the value to tint the bar --- **PrbStateError** typically renders red, **PrbStatePaused** typically renders yellow, **PrbStateNormal** uses the theme-default progress color (typically green). ### Step {: .no_toc } @@ -153,7 +153,7 @@ Events ### Change {: .no_toc } -Raised when [**Value**](#value) has changed — either through direct assignment, through [**StepIt**](#stepit), or by code adjusting [**Step**](#step) and re-applying. +Raised when [**Value**](#value) has changed --- either through direct assignment, through [**StepIt**](#stepit), or by code adjusting [**Step**](#step) and re-applying. Syntax: *object*\_**Change**( ) @@ -201,7 +201,7 @@ Determines how the progress bar animates as the value changes. Declared on the * |------------------------------|-------|------------------------------------------------------------------------| | **PrbScrollingStandard**{: #PrbScrolling_PrbScrollingStandard } | 0 | Segmented bar with the classic discrete blocks animation. | | **PrbScrollingSmooth**{: #PrbScrolling_PrbScrollingSmooth } | 1 | Continuous block with no inter-segment gaps. Pair with [**SmoothReverse**](#smoothreverse) to allow the value to decrease visibly. | -| **PrbScrollingMarquee**{: #PrbScrolling_PrbScrollingMarquee } | 2 | Indeterminate animated stripe. Drive with [**MarqueeAnimation**](#marqueeanimation) and [**MarqueeSpeed**](#marqueespeed); the actual [**Value**](#value) is irrelevant. | +| **PrbScrollingMarquee**{: #PrbScrolling_PrbScrollingMarquee } | 2 | Indeterminate animated stripe. Control with [**MarqueeAnimation**](#marqueeanimation) and [**MarqueeSpeed**](#marqueespeed); the actual [**Value**](#value) is irrelevant. | ## PrbState {: #prbstate } diff --git a/docs/Reference/WinNativeCommonCtls/Slider.md b/docs/Reference/WinNativeCommonCtls/Slider.md index bb695300..33541199 100644 --- a/docs/Reference/WinNativeCommonCtls/Slider.md +++ b/docs/Reference/WinNativeCommonCtls/Slider.md @@ -8,7 +8,7 @@ has_toc: false # Slider class {: .no_toc } -A **Slider** is a trackbar control — a horizontal or vertical channel with a draggable thumb that lets the user pick a value between [**Min**](#min) and [**Max**](#max). Optional tick marks, a floating value tip, and a highlighted selection range round out the control. +A **Slider** is a trackbar control --- a horizontal or vertical channel with a draggable thumb that lets the user pick a value between [**Min**](#min) and [**Max**](#max). Optional tick marks, a floating value tip, and a highlighted selection range round out the control. ```tb Private Sub Form_Load() @@ -25,7 +25,7 @@ Private Sub Slider1_Change() End Sub ``` -The control inherits the focusable rect-dockable members from `BaseControlFocusableNoFont` — size, position, **Anchors**, **Dock**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. Slider does not have a [**Font**](../VB/CheckBox#font) property (its thumb and tick marks are drawn by the OS theme). +The control inherits the focusable rect-dockable members from `BaseControlFocusableNoFont` --- size, position, **Anchors**, **Dock**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. Slider does not have a [**Font**](../VB/CheckBox#font) property (its thumb and tick marks are drawn by the OS theme). * TOC {:toc} @@ -34,7 +34,7 @@ The control inherits the focusable rect-dockable members from `BaseControlFocusa The slider raises two distinct events as the user interacts with the thumb: -- **[Scroll](#scroll)** fires *during* drag and during keyboard navigation — every time the thumb position is updated, regardless of whether the user has settled. +- **[Scroll](#scroll)** fires *during* drag and during keyboard navigation --- every time the thumb position is updated, regardless of whether the user has settled. - **[Change](#change)** fires *only when the drag completes* (mouse release) or when the user reaches an extremity with the keyboard. Use **Scroll** for live previews ("show the value as the user is dragging") and **Change** for commit-style handlers ("apply the value once the user lets go"). diff --git a/docs/Reference/WinNativeCommonCtls/TreeView/Node.md b/docs/Reference/WinNativeCommonCtls/TreeView/Node.md index cee82ac8..8240af06 100644 --- a/docs/Reference/WinNativeCommonCtls/TreeView/Node.md +++ b/docs/Reference/WinNativeCommonCtls/TreeView/Node.md @@ -11,7 +11,7 @@ has_toc: false A **Node** is a single entry in a [**TreeView**](.)'s [**Nodes**](Nodes) collection. Returned from [**Nodes.Add**](Nodes#add) and from [**Nodes.Item**](Nodes#item). Each node has its own text, icons, sort settings, check state, and sibling / parent / child relationships. -The class is tagged `[COMCreatable(False)]` — user code reaches **Node** instances through the parent [**TreeView**](.)'s [**Nodes**](Nodes) collection or through navigation properties on other nodes. +The class is tagged `[COMCreatable(False)]` --- user code accesses **Node** instances through the parent [**TreeView**](.)'s [**Nodes**](Nodes) collection or through navigation properties on other nodes. ```tb Dim root As Node = TreeView1.Nodes.Add(, , "root", "My Computer") @@ -80,7 +80,7 @@ Example: a node "C: drive" whose parent is "My Computer" returns `"My Computer\C ### Image {: .no_toc } -The icon rendered when the node is not selected. **Variant** — either a 1-based **Long** index into [**TreeView.ImageList**](.#imagelist), or a **String** key. Assignment validates against the bound image list. +The icon rendered when the node is not selected. **Variant** --- either a 1-based **Long** index into [**TreeView.ImageList**](.#imagelist), or a **String** key. Assignment validates against the bound image list. ### Index {: .no_toc } @@ -105,7 +105,7 @@ The next sibling of this node, or **Nothing** if this is the last sibling. **Nod ### Parent {: .no_toc } -The parent **Node**, or **Nothing** if this node is at the root level. **Node**, read/write. Note: assigning **Parent** does not move the node — it merely changes the recorded parent reference. +The parent **Node**, or **Nothing** if this node is at the root level. **Node**, read/write. Note: assigning **Parent** does not move the node --- it merely changes the recorded parent reference. ### Previous {: .no_toc } @@ -125,7 +125,7 @@ Whether this node is the [**TreeView.SelectedItem**](.#selecteditem) of the tree ### SelectedImage {: .no_toc } -The icon rendered when the node is selected. **Variant** — either an index or a key into [**TreeView.ImageList**](.#imagelist). When unset, defaults to the same as [**Image**](#image). +The icon rendered when the node is selected. **Variant** --- either an index or a key into [**TreeView.ImageList**](.#imagelist). When unset, defaults to the same as [**Image**](#image). ### Sorted {: .no_toc } @@ -155,7 +155,7 @@ The node's label text. **String**, read/write. ### Visible {: .no_toc } -Whether the node is currently visible — i.e. not hidden because an ancestor is collapsed and not scrolled out of view. **Boolean**, read-only. +Whether the node is currently visible --- i.e. not hidden because an ancestor is collapsed and not scrolled out of view. **Boolean**, read-only. Methods ------- diff --git a/docs/Reference/WinNativeCommonCtls/TreeView/Nodes.md b/docs/Reference/WinNativeCommonCtls/TreeView/Nodes.md index bfeb9d26..7fac617a 100644 --- a/docs/Reference/WinNativeCommonCtls/TreeView/Nodes.md +++ b/docs/Reference/WinNativeCommonCtls/TreeView/Nodes.md @@ -9,9 +9,9 @@ has_toc: false # Nodes class {: .no_toc } -The **Nodes** collection is the entry point for managing the [**Node**](Node) tree of a [**TreeView**](.). Reached as `<treeView>.Nodes`; supports adding, removing, indexed access, and `For Each` iteration. +The **Nodes** collection is the entry point for managing the [**Node**](Node) tree of a [**TreeView**](.). Accessed as `<treeView>.Nodes`; supports adding, removing, indexed access, and `For Each` iteration. -The class is tagged `[COMCreatable(False)]` — user code reaches **Nodes** through the parent [**TreeView**](.) control's [**Nodes**](.#nodes) property. +The class is tagged `[COMCreatable(False)]` --- user code accesses **Nodes** through the parent [**TreeView**](.) control's [**Nodes**](.#nodes) property. ```tb With TreeView1.Nodes @@ -27,7 +27,7 @@ For Each node In TreeView1.Nodes Next ``` -The `For Each` iteration visits **only the nodes in the order they were added** — not in tree order. For a depth-first or breadth-first traversal that follows the visual hierarchy, traverse the parent-child links manually starting from a root [**Node**](Node) and using [**Node.Child**](Node#child) / [**Node.Next**](Node#next). +The `For Each` iteration visits **only the nodes in the order they were added** --- not in tree order. For a depth-first or breadth-first traversal that follows the visual hierarchy, traverse the parent-child links manually starting from a root [**Node**](Node) and using [**Node.Child**](Node#child) / [**Node.Next**](Node#next). * TOC {:toc} @@ -48,7 +48,7 @@ Returns the [**Node**](Node) at the given index or with the given key. The defau Syntax: *object*.**Item** ( *Index* ) **As Node** *Index* -: A **Variant** — either a 1-based **Long** position or a **String** key. +: A **Variant** --- either a 1-based **Long** position or a **String** key. Methods ------- @@ -61,7 +61,7 @@ Adds a node to the treeview, optionally positioned relative to another node. Syntax: *object*.**Add** ( [ *Relative* ] [, *Relationship* ] [, *Key* ] [, *Text* ] [, *Image* ] [, *SelectedImage* ] ) **As Node** *Relative* -: *optional* A **Variant** identifying the existing node the new node will be positioned against — either a [**Node**](Node) reference, a 1-based **Long** index, or a **String** key. When omitted, the new node is inserted at the root level using *Relationship* = **tvwNext** semantics. +: *optional* A **Variant** identifying the existing node the new node will be positioned against --- either a [**Node**](Node) reference, a 1-based **Long** index, or a **String** key. When omitted, the new node is inserted at the root level using *Relationship* = **tvwNext** semantics. *Relationship* : *optional* A member of [**TreeRelationshipConstants**](../Enumerations/TreeRelationshipConstants) describing where the new node is placed relative to *Relative*. Default: **tvwNext**. @@ -73,7 +73,7 @@ Syntax: *object*.**Add** ( [ *Relative* ] [, *Relationship* ] [, *Key* ] [, *Tex : *optional* A **String** giving the node's label. *Image* -: *optional* A **Variant** identifying the unselected-state icon — either a 1-based **Long** index into [**TreeView.ImageList**](.#imagelist), or a **String** key. +: *optional* A **Variant** identifying the unselected-state icon --- either a 1-based **Long** index into [**TreeView.ImageList**](.#imagelist), or a **String** key. *SelectedImage* : *optional* A **Variant** identifying the selected-state icon. When unset, defaults to the same as *Image*. @@ -95,7 +95,7 @@ Removes a node from the treeview, along with all its descendants. The remaining Syntax: *object*.**Remove** ( *Index* ) *Index* -: A **Variant** — either a 1-based **Long** position or a **String** key. +: A **Variant** --- either a 1-based **Long** position or a **String** key. ### _NewEnum {: .no_toc } diff --git a/docs/Reference/WinNativeCommonCtls/TreeView/index.md b/docs/Reference/WinNativeCommonCtls/TreeView/index.md index 24875b79..633d25a7 100644 --- a/docs/Reference/WinNativeCommonCtls/TreeView/index.md +++ b/docs/Reference/WinNativeCommonCtls/TreeView/index.md @@ -8,7 +8,7 @@ has_toc: false # TreeView class {: .no_toc } -A **TreeView** is a hierarchical display of [**Node**](Node) objects organized into a tree. Each node can be expanded or collapsed, optionally has a checkbox, and references an icon from an associated [**ImageList**](../ImageList/). The collection of nodes is reached through [**Nodes**](#nodes); each [**Node**](Node) has its own siblings, parent, and child navigation properties. +A **TreeView** is a hierarchical display of [**Node**](Node) objects organized into a tree. Each node can be expanded or collapsed, optionally has a checkbox, and references an icon from an associated [**ImageList**](../ImageList/). The collection of nodes is accessed through [**Nodes**](#nodes); each [**Node**](Node) has its own siblings, parent, and child navigation properties. ```tb Private Sub Form_Load() @@ -27,7 +27,7 @@ Private Sub TreeView1_NodeClick(ByVal Node As Node) End Sub ``` -The control inherits the focusable rect-dockable members from `BaseControlFocusable` — size, position, **Anchors**, **Dock**, **Font**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. +The control inherits the focusable rect-dockable members from `BaseControlFocusable` --- size, position, **Anchors**, **Dock**, **Font**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. * TOC {:toc} @@ -38,13 +38,13 @@ The control inherits the focusable rect-dockable members from `BaseControlFocusa | [**Style**](#style) | Buttons | Lines | Icons | |----------------------------------------------------|---------|-------|-------| -| **tvwTextOnly** | — | — | — | -| **tvwPictureText** | — | — | yes | -| **tvwPlusMinusText** | yes | — | — | -| **tvwPlusMinusPictureText** | yes | — | yes | -| **tvwTreelinesText** | — | yes | — | -| **tvwTreelinesPictureText** | — | yes | yes | -| **tvwTreelinesPlusMinusText** | yes | yes | — | +| **tvwTextOnly** | --- | --- | --- | +| **tvwPictureText** | --- | --- | yes | +| **tvwPlusMinusText** | yes | --- | --- | +| **tvwPlusMinusPictureText** | yes | --- | yes | +| **tvwTreelinesText** | --- | yes | --- | +| **tvwTreelinesPictureText** | --- | yes | yes | +| **tvwTreelinesPlusMinusText** | yes | yes | --- | | **tvwTreelinesPlusMinusPictureText** (default) | yes | yes | yes | The values are decoded internally into the Win32 `TVS_HASBUTTONS` / `TVS_HASLINES` style bits. @@ -177,7 +177,7 @@ The string comparison used for sorting at the root level. A member of [**TreeSor ### Style {: .no_toc } -The composite visual style — see [the **Style** table above](#style-a-composite-of-buttons--lines--icons--text). A member of [**TreeStyleConstants**](../Enumerations/TreeStyleConstants). Default: **tvwTreelinesPlusMinusPictureText**. +The composite visual style --- see [the **Style** table above](#style-a-composite-of-buttons--lines--icons--text). A member of [**TreeStyleConstants**](../Enumerations/TreeStyleConstants). Default: **tvwTreelinesPlusMinusPictureText**. ### WheelScrollEvent {: .no_toc } @@ -296,21 +296,21 @@ Inherited mouse events. ### NodeCheck {: .no_toc } -Raised when a node's checkbox is toggled — either by the user clicking it, by **Space** keypress, or by code assigning [**Node.Checked**](Node#checked). +Raised when a node's checkbox is toggled --- either by the user clicking it, by **Space** keypress, or by code assigning [**Node.Checked**](Node#checked). Syntax: *object*\_**NodeCheck**( **ByVal** *Node* **As Node** ) ### NodeClick {: .no_toc } -Raised when a node is clicked. Distinct from [**Click**](#click), which fires on any mouse click in the control regardless of where it lands. +Raised when a node is clicked. Distinct from [**Click**](#click), which fires on any mouse click in the control regardless of where it occurs. Syntax: *object*\_**NodeClick**( **ByVal** *Node* **As Node** ) ### NodeSelect {: .no_toc } -Raised when a node becomes the selected node — either by user click, by keyboard arrow navigation, or by code assigning [**SelectedItem**](#selecteditem). +Raised when a node becomes the selected node --- either by user click, by keyboard arrow navigation, or by code assigning [**SelectedItem**](#selecteditem). Syntax: *object*\_**NodeSelect**( **ByVal** *Node* **As Node** ) diff --git a/docs/Reference/WinNativeCommonCtls/UpDown.md b/docs/Reference/WinNativeCommonCtls/UpDown.md index 246cb48d..2d40bff5 100644 --- a/docs/Reference/WinNativeCommonCtls/UpDown.md +++ b/docs/Reference/WinNativeCommonCtls/UpDown.md @@ -8,7 +8,7 @@ has_toc: false # UpDown class {: .no_toc } -An **UpDown** is a small spin control — a pair of up / down arrow buttons that adjust an internal [**Value**](#value) by [**Increment**](#increment) on each click. Often paired with an external textbox or label to display the current value. +An **UpDown** is a small spin control --- a pair of up / down arrow buttons that adjust an internal [**Value**](#value) by [**Increment**](#increment) on each click. Often paired with an external textbox or label to display the current value. ```tb Private Sub Form_Load() @@ -27,20 +27,20 @@ Private Sub Text1_Change() End Sub ``` -The control inherits the focusable rect-dockable members from `BaseControlFocusableNoFont` — size, position, **Anchors**, **Dock**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. **UpDown** does not have a [**Font**](../VB/CheckBox#font) property (the arrows are drawn by the OS theme). +The control inherits the focusable rect-dockable members from `BaseControlFocusableNoFont` --- size, position, **Anchors**, **Dock**, **Appearance**, **MousePointer** / **MouseIcon**, **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **Refresh**, **SetFocus**, **TabIndex** / **TabStop**, **ZOrder**, **CausesValidation**, **VisualStyles**, **hWnd**, **HelpContextID** / **WhatsThisHelpID**. **UpDown** does not have a [**Font**](../VB/CheckBox#font) property (the arrows are drawn by the OS theme). * TOC {:toc} ## No auto-buddy -Unlike the VB6-era Win32 `msctls_updown32` control, this **UpDown** does not auto-attach to a "buddy" textbox — there is no `UDS_AUTOBUDDY` style exposed. Pair the spin control with another control manually by handling [**Change**](#change), [**UpClick**](#upclick), and [**DownClick**](#downclick). +Unlike the VB6-era Win32 `msctls_updown32` control, this **UpDown** does not auto-attach to a "buddy" textbox --- there is no `UDS_AUTOBUDDY` style exposed. Pair the spin control with another control manually by handling [**Change**](#change), [**UpClick**](#upclick), and [**DownClick**](#downclick). ## Three event flavors Three events let the application observe spin interaction at different granularity: -- **[Change](#change)** fires whenever [**Value**](#value) actually changes — including programmatic assignments. +- **[Change](#change)** fires whenever [**Value**](#value) actually changes --- including programmatic assignments. - **[UpClick](#upclick)** fires when the user clicks the up arrow and [**Value**](#value) increases. - **[DownClick](#downclick)** fires when the user clicks the down arrow and [**Value**](#value) decreases. diff --git a/docs/Reference/WinNativeCommonCtls/index.md b/docs/Reference/WinNativeCommonCtls/index.md index 7a89468c..3b444659 100644 --- a/docs/Reference/WinNativeCommonCtls/index.md +++ b/docs/Reference/WinNativeCommonCtls/index.md @@ -19,7 +19,7 @@ The package is a built-in package shipped with twinBASIC. Add it through Project ## Why this package exists -VB6 projects that depend on `MSCOMCTL.OCX` cannot run unmodified in modern environments — the OCX is unsigned, requires per-machine registration with admin rights, ships with known security advisories, and is not available on non-Windows hosts at all. **WinNativeCommonCtls** removes the dependency: drop a [**ListView**](ListView/), [**TreeView**](TreeView/), [**ProgressBar**](ProgressBar), [**Slider**](Slider), [**ImageList**](ImageList/), [**DTPicker**](DTPicker), [**MonthView**](MonthView), or [**UpDown**](UpDown) onto a [**Form**](../VB/Form/) and twinBASIC creates the underlying Win32 ComCtl32 control directly, with no OCX involved. +VB6 projects that depend on `MSCOMCTL.OCX` cannot run unmodified in modern environments --- the OCX is unsigned, requires per-machine registration with admin rights, ships with known security advisories, and is not available on non-Windows hosts at all. **WinNativeCommonCtls** removes the dependency: drop a [**ListView**](ListView/), [**TreeView**](TreeView/), [**ProgressBar**](ProgressBar), [**Slider**](Slider), [**ImageList**](ImageList/), [**DTPicker**](DTPicker), [**MonthView**](MonthView), or [**UpDown**](UpDown) onto a [**Form**](../VB/Form/) and twinBASIC creates the underlying Win32 ComCtl32 control directly, with no OCX involved. The control names, property names, event signatures, and the `vb…` / `tvw…` / `lvw…` / `sld…` / `Prb…` member-name conventions all match the original `MSCOMCTL.OCX` API, so VB6 code that uses the original controls usually compiles and runs unchanged once the package reference is in place. @@ -36,7 +36,7 @@ Eight controls, each a leaf class that inherits from a `<Name>BaseCtl` where the - [TreeView](TreeView/) -- hierarchical tree of [**Node**](TreeView/Node) objects with sorting, label-edit, checkboxes, image lists, and per-node bold / color overrides - [UpDown](UpDown) -- spin control with up / down arrows: pure [**Min**](UpDown#min) / [**Max**](UpDown#max) / [**Value**](UpDown#value) / [**Increment**](UpDown#increment) (no auto-buddy) -[**ListView**](ListView/), [**TreeView**](TreeView/), and [**ImageList**](ImageList/) include collection sub-objects — see the folder index pages for the full hierarchy. +[**ListView**](ListView/), [**TreeView**](TreeView/), and [**ImageList**](ImageList/) include collection sub-objects --- see the folder index pages for the full hierarchy. ## Enumerations @@ -48,15 +48,15 @@ Module-level enumerations shared across multiple controls live under [**Enumerat Every control inherits the standard VB-package members from `BaseControl` / `BaseControlRect` / `BaseControlRectDockable` / `BaseControlFocusable` (or `BaseControlNotFocusable`, where the control cannot take focus). Inherited members include: -- **Positioning and layout** — **Name**, **Left**, **Top**, **Width**, **Height**, **Anchors**, **Dock**, **Visible**, **Enabled**, **Move**, **Refresh**, **ZOrder**, **Container**, **Parent**, **Index**, **Tag**, **hWnd** -- **Appearance** — **BackColor** / **ForeColor** / **Font** (where focusable), **Appearance**, **VisualStyles**, **MousePointer** / **MouseIcon** -- **Tooltips, drag-and-drop, validation** — **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **CausesValidation**, **Validate** event -- **Focus** (focusable controls only) — **SetFocus**, **TabIndex**, **TabStop**, **GotFocus** / **LostFocus** events -- **Help integration** — **HelpContextID**, **WhatsThisHelpID** -- **OLE drag-and-drop** — **OLEDropMode**, the **OLEDrag** method, and the **OLEStartDrag** / **OLEGiveFeedback** / **OLESetData** / **OLEDragOver** / **OLEDragDrop** / **OLECompleteDrag** events. See [**OLEDropConstants**](../VBRUN/Constants/OLEDropConstants) -- **Transparency** — **Opacity** (`Double`, 0–100, percentage) and **TransparencyKey** (`OLE_COLOR`, `-1` to disable). Both require Windows 8 (target OS 6.2+) for child controls; on older OS versions they are silently no-ops +- **Positioning and layout** --- **Name**, **Left**, **Top**, **Width**, **Height**, **Anchors**, **Dock**, **Visible**, **Enabled**, **Move**, **Refresh**, **ZOrder**, **Container**, **Parent**, **Index**, **Tag**, **hWnd** +- **Appearance** --- **BackColor** / **ForeColor** / **Font** (where focusable), **Appearance**, **VisualStyles**, **MousePointer** / **MouseIcon** +- **Tooltips, drag-and-drop, validation** --- **ToolTipText**, **DragMode** / **DragIcon**, **Drag**, **CausesValidation**, **Validate** event +- **Focus** (focusable controls only) --- **SetFocus**, **TabIndex**, **TabStop**, **GotFocus** / **LostFocus** events +- **Help integration** --- **HelpContextID**, **WhatsThisHelpID** +- **OLE drag-and-drop** --- **OLEDropMode**, the **OLEDrag** method, and the **OLEStartDrag** / **OLEGiveFeedback** / **OLESetData** / **OLEDragOver** / **OLEDragDrop** / **OLECompleteDrag** events. See [**OLEDropConstants**](../VBRUN/Constants/OLEDropConstants) +- **Transparency** --- **Opacity** (`Double`, 0--100, percentage) and **TransparencyKey** (`OLE_COLOR`, `-1` to disable). Both require Windows 8 (target OS 6.2+) for child controls; on older OS versions they are silently no-ops -Each control's reference page lists the control-specific members — own properties, methods, events, and nested enums — without re-enumerating the entire inherited base every time. +Each control's reference page lists the control-specific members --- own properties, methods, events, and nested enums --- without re-enumerating the entire inherited base every time. ## Control type constants diff --git a/docs/Reference/WinServicesLib/Enumerations/ServiceControlCodeConstants.md b/docs/Reference/WinServicesLib/Enumerations/ServiceControlCodeConstants.md index 92187a1c..6bbf2170 100644 --- a/docs/Reference/WinServicesLib/Enumerations/ServiceControlCodeConstants.md +++ b/docs/Reference/WinServicesLib/Enumerations/ServiceControlCodeConstants.md @@ -9,17 +9,17 @@ permalink: /tB/Packages/WinServicesLib/Enumerations/ServiceControlCodeConstants The control codes the SCM can deliver to a running service. Used as the *dwControl* parameter of [**ITbService.ChangeState**](../ITbService#changestate) (where the service reacts to the request) and as the *ControlCode* parameter of [**Services.ControlService**](../Services#controlservice) (where the consumer issues the request to a service running elsewhere). -The values mirror the Win32 `SERVICE_CONTROL_*` constants verbatim — the `vb` prefix is a historical hold-over from VB6's coding conventions and does not affect the numeric values. +The values mirror the Win32 `SERVICE_CONTROL_*` constants verbatim --- the `vb` prefix is a historical hold-over from VB6's coding conventions and does not affect the numeric values. | Constant | Value | Description | |----------|-------|-------------| -| **vbServiceControlStop**{: #vbServiceControlStop } | 0x01 | Request the service stop. The standard shutdown signal — every service should handle this in [**ChangeState**](../ITbService#changestate). | +| **vbServiceControlStop**{: #vbServiceControlStop } | 0x01 | Request the service stop. The standard shutdown signal --- every service should handle this in [**ChangeState**](../ITbService#changestate). | | **vbServiceControlPause**{: #vbServiceControlPause } | 0x02 | Pause the service. Only delivered if [**ServiceManager.SupportsPausing**](../ServiceManager#supportspausing) is **True**. | | **vbServiceControlContinue**{: #vbServiceControlContinue } | 0x03 | Resume a paused service. Paired with [**vbServiceControlPause**](#vbServiceControlPause). | -| **vbServiceControlInterrogate**{: #vbServiceControlInterrogate } | 0x04 | The SCM is asking the service to re-report its current state via [**ReportStatus**](../ServiceManager#reportstatus). A bare-minimum handler can ignore it — the SCM already has the most recent status from the previous call. | +| **vbServiceControlInterrogate**{: #vbServiceControlInterrogate } | 0x04 | The SCM is asking the service to re-report its current state via [**ReportStatus**](../ServiceManager#reportstatus). A bare-minimum handler can ignore it --- the SCM already has the most recent status from the previous call. | | **vbServiceControlShutdown**{: #vbServiceControlShutdown } | 0x05 | The OS is shutting down. Most services treat this identically to [**vbServiceControlStop**](#vbServiceControlStop). | -| **vbServiceControlParamChange**{: #vbServiceControlParamChange } | 0x06 | An admin has changed the service's configuration via `sc.exe config`. Delivered only if the service registered `SERVICE_ACCEPT_PARAMCHANGE` — currently not exposed through the package. | -| **vbServiceControlNetBindAdd**{: #vbServiceControlNetBindAdd } | 0x07 | A new network binding is available. Delivered only if `SERVICE_ACCEPT_NETBINDCHANGE` is accepted — currently not exposed. | +| **vbServiceControlParamChange**{: #vbServiceControlParamChange } | 0x06 | An admin has changed the service's configuration via `sc.exe config`. Delivered only if the service registered `SERVICE_ACCEPT_PARAMCHANGE` --- currently not exposed through the package. | +| **vbServiceControlNetBindAdd**{: #vbServiceControlNetBindAdd } | 0x07 | A new network binding is available. Delivered only if `SERVICE_ACCEPT_NETBINDCHANGE` is accepted --- currently not exposed. | | **vbServiceControlNetBindRemove**{: #vbServiceControlNetBindRemove } | 0x08 | A network binding has been removed. | | **vbServiceControlNetBindEnable**{: #vbServiceControlNetBindEnable } | 0x09 | A previously disabled network binding has been enabled. | | **vbServiceControlNetBindDisable**{: #vbServiceControlNetBindDisable } | 0x0A | A network binding has been disabled. | @@ -27,10 +27,10 @@ The values mirror the Win32 `SERVICE_CONTROL_*` constants verbatim — the `vb` | **vbServiceControlHardwareProfileChange**{: #vbServiceControlHardwareProfileChange } | 0x0C | A hardware-profile change (laptop docking, …). | | **vbServiceControlPowerEvent**{: #vbServiceControlPowerEvent } | 0x0D | A system power event (suspend, resume, battery low, …). The *dwEventType* parameter holds the `PBT_*` sub-code. | | **vbServiceControlSessionChange**{: #vbServiceControlSessionChange } | 0x0E | A session-change event (user logon, RDP connect / disconnect, …). The *dwEventType* parameter holds the `WTS_*` sub-code. | -| **vbServiceControlPreShutdown**{: #vbServiceControlPreShutdown } | 0x0F | The OS is about to shut down — sent before [**vbServiceControlShutdown**](#vbServiceControlShutdown) to services that have registered for the longer pre-shutdown notification window. | +| **vbServiceControlPreShutdown**{: #vbServiceControlPreShutdown } | 0x0F | The OS is about to shut down --- sent before [**vbServiceControlShutdown**](#vbServiceControlShutdown) to services that have registered for the longer pre-shutdown notification window. | | **vbServiceControlTimeChange**{: #vbServiceControlTimeChange } | 0x10 | The system time has changed. | | **vbServiceControlTriggerEvent**{: #vbServiceControlTriggerEvent } | 0x20 | A registered trigger event has fired (typically used by trigger-started services). | | **vbServiceControlLowResources**{: #vbServiceControlLowResources } | 0x60 | The service should reduce its memory / CPU footprint. | | **vbServiceControlSystemLowResources**{: #vbServiceControlSystemLowResources } | 0x61 | The whole system is low on resources. | -Control codes in the range **128–255** are reserved for user-defined codes; pass any value in that range to [**Services.ControlService**](../Services#controlservice) and the package will request the matching `SERVICE_USER_DEFINED_CONTROL` SCM permission. Most services only need to handle [**vbServiceControlStop**](#vbServiceControlStop) and optionally the pause / continue pair. +Control codes in the range **128--255** are reserved for user-defined codes; pass any value in that range to [**Services.ControlService**](../Services#controlservice) and the package will request the matching `SERVICE_USER_DEFINED_CONTROL` SCM permission. Most services only need to handle [**vbServiceControlStop**](#vbServiceControlStop) and optionally the pause / continue pair. diff --git a/docs/Reference/WinServicesLib/Enumerations/ServiceStartConstants.md b/docs/Reference/WinServicesLib/Enumerations/ServiceStartConstants.md index cb89f012..717832b1 100644 --- a/docs/Reference/WinServicesLib/Enumerations/ServiceStartConstants.md +++ b/docs/Reference/WinServicesLib/Enumerations/ServiceStartConstants.md @@ -11,7 +11,7 @@ When and how the SCM starts a service. Assigned to [**ServiceManager.InstallStar | Constant | Value | Description | |----------|-------|-------------| -| **tbServiceStartBoot**{: #tbServiceStartBoot } | 0 | Started by the boot loader at OS boot. **Kernel drivers only** — not applicable to twinBASIC services. | +| **tbServiceStartBoot**{: #tbServiceStartBoot } | 0 | Started by the boot loader at OS boot. **Kernel drivers only** --- not applicable to twinBASIC services. | | **tbServiceStartDriverSystem**{: #tbServiceStartDriverSystem } | 1 | Started by `Ntldr` / `Winload` during system initialisation. **Kernel drivers only.** | | **tbServiceStartAuto**{: #tbServiceStartAuto } | 2 | Automatically started by the SCM at system boot, before any user logs in. The typical setting for a background service that should always be running. | | **tbServiceStartOnDemand**{: #tbServiceStartOnDemand } | 3 | Started by the SCM only when something explicitly requests it (control-panel applet, `sc.exe start`, [**Services.LaunchService**](../Services#launchservice), or a service that lists it in [**DependentServices**](../ServiceManager#dependentservices)). The default for new [**ServiceManager**](../ServiceManager) instances. | diff --git a/docs/Reference/WinServicesLib/Enumerations/ServiceTypeConstants.md b/docs/Reference/WinServicesLib/Enumerations/ServiceTypeConstants.md index 439e5ec8..c9711371 100644 --- a/docs/Reference/WinServicesLib/Enumerations/ServiceTypeConstants.md +++ b/docs/Reference/WinServicesLib/Enumerations/ServiceTypeConstants.md @@ -7,20 +7,20 @@ permalink: /tB/Packages/WinServicesLib/Enumerations/ServiceTypeConstants # ServiceTypeConstants {: .no_toc } -The Win32 service-type values. Read into [**ServiceManager.Type**](../ServiceManager#type) at configuration time and reported back by the SCM through [**ServiceState.Type**](../ServiceState#type) at query time. Determines whether the service runs in its own process, in a shared host process, or is a kernel driver — and, historically, whether it can interact with the desktop. +The Win32 service-type values. Read into [**ServiceManager.Type**](../ServiceManager#type) at configuration time and reported back by the SCM through [**ServiceState.Type**](../ServiceState#type) at query time. Determines whether the service runs in its own process, in a shared host process, or is a kernel driver --- and, historically, whether it can interact with the desktop. | Constant | Value | Description | |----------|-------|-------------| -| **tbServiceTypeKernelDriver**{: #tbServiceTypeKernelDriver } | 1 | A kernel-mode driver. **Not applicable** to twinBASIC services — kernel drivers are written in C and built against the Windows DDK. | +| **tbServiceTypeKernelDriver**{: #tbServiceTypeKernelDriver } | 1 | A kernel-mode driver. **Not applicable** to twinBASIC services --- kernel drivers are written in C and built against the Windows DDK. | | **tbServiceTypeSystemDriver**{: #tbServiceTypeSystemDriver } | 2 | A file-system kernel driver. Same caveat as above. | | **tbServiceTypeAdapter**{: #tbServiceTypeAdapter } | 4 | Legacy adapter service (network-adapter binding). Not used by modern services. | | **tbServiceTypeRecognizerDriver**{: #tbServiceTypeRecognizerDriver } | 8 | A file-system-recognizer driver. Kernel-only. | | **tbServiceTypeOwnProcess**{: #tbServiceTypeOwnProcess } | 16 | The service runs in its own dedicated EXE process. The typical setting for a one-service EXE. | | **tbServiceTypeShareProcess**{: #tbServiceTypeShareProcess } | 32 | The service runs alongside other services in a shared host EXE. Used when one EXE hosts multiple distinct services (`ConfigureNew` called more than once); the SCM keeps a single process alive that serves all of them. | -| **tbServiceTypeOwnProcessInteractive**{: #tbServiceTypeOwnProcessInteractive } | 272 | `tbServiceTypeOwnProcess` with the interactive bit (`SERVICE_INTERACTIVE_PROCESS`) set. **Not supported on Windows Vista and later** — see note below. | +| **tbServiceTypeOwnProcessInteractive**{: #tbServiceTypeOwnProcessInteractive } | 272 | `tbServiceTypeOwnProcess` with the interactive bit (`SERVICE_INTERACTIVE_PROCESS`) set. **Not supported on Windows Vista and later** --- see note below. | | **tbServiceTypeShareProcessInteractive**{: #tbServiceTypeShareProcessInteractive } | 288 | `tbServiceTypeShareProcess` with the interactive bit set. Same caveat as above. | > [!NOTE] -> Windows Vista and later run services in *Session 0*, which has no user desktop and no message-loop interaction with logged-in users — the `SERVICE_INTERACTIVE_PROCESS` flag is **silently ignored**. The `Interactive` constants are kept in the enum for compatibility, but services that need user-interface elements should use a separate UI process (launched via the Services package or via inter-process communication) rather than the interactive-service mechanism. +> Windows Vista and later run services in *Session 0*, which has no user desktop and no message-loop interaction with logged-in users --- the `SERVICE_INTERACTIVE_PROCESS` flag is **silently ignored**. The `Interactive` constants are kept in the enum for compatibility, but services that need user-interface elements should use a separate UI process (launched via the Services package or via inter-process communication) rather than the interactive-service mechanism. For user-mode twinBASIC services, the only two values that matter in practice are [**tbServiceTypeOwnProcess**](#tbServiceTypeOwnProcess) and [**tbServiceTypeShareProcess**](#tbServiceTypeShareProcess). diff --git a/docs/Reference/WinServicesLib/Enumerations/index.md b/docs/Reference/WinServicesLib/Enumerations/index.md index 40c8f9c5..b07f3042 100644 --- a/docs/Reference/WinServicesLib/Enumerations/index.md +++ b/docs/Reference/WinServicesLib/Enumerations/index.md @@ -16,4 +16,4 @@ The four user-facing enumerations the **WinServicesLib** package exposes. All fo | [ServiceControlCodeConstants](ServiceControlCodeConstants) | [**Services.ControlService**](../Services#controlservice), the *dwControl* parameter of [**ITbService.ChangeState**](../ITbService#changestate) | | [ServiceStatusConstants](ServiceStatusConstants) | [**ServiceManager.ReportStatus**](../ServiceManager#reportstatus) | -The member-name prefixes are inherited from the underlying Win32 SDK constants — `tb…` on the *configuration* enums ([**ServiceTypeConstants**](ServiceTypeConstants), [**ServiceStartConstants**](ServiceStartConstants)) and `vb…` on the *runtime* enums ([**ServiceControlCodeConstants**](ServiceControlCodeConstants), [**ServiceStatusConstants**](ServiceStatusConstants)). The split is not deliberate; treat the prefixes as part of the member names and ignore the asymmetry. +The member-name prefixes are inherited from the underlying Win32 SDK constants --- `tb…` on the *configuration* enums ([**ServiceTypeConstants**](ServiceTypeConstants), [**ServiceStartConstants**](ServiceStartConstants)) and `vb…` on the *runtime* enums ([**ServiceControlCodeConstants**](ServiceControlCodeConstants), [**ServiceStatusConstants**](ServiceStatusConstants)). The split is not deliberate; treat the prefixes as part of the member names and ignore the asymmetry. diff --git a/docs/Reference/WinServicesLib/ITbService.md b/docs/Reference/WinServicesLib/ITbService.md index c317af45..902815a0 100644 --- a/docs/Reference/WinServicesLib/ITbService.md +++ b/docs/Reference/WinServicesLib/ITbService.md @@ -10,9 +10,9 @@ has_toc: false The contract every service class in a **WinServicesLib** project implements. Three subs, each invoked at a specific point in the service's lifecycle: -- [**EntryPoint**](#entrypoint) — runs the service's actual work. -- [**StartupFailed**](#startupfailed) — invoked when the SCM handshake fails before [**EntryPoint**](#entrypoint) can run. -- [**ChangeState**](#changestate) — invoked when the SCM delivers a control code (*Stop*, *Pause*, *Continue*, …). +- [**EntryPoint**](#entrypoint) -- runs the service's actual work. +- [**StartupFailed**](#startupfailed) -- invoked when the SCM handshake fails before [**EntryPoint**](#entrypoint) can run. +- [**ChangeState**](#changestate) -- invoked when the SCM delivers a control code (*Stop*, *Pause*, *Continue*, …). The package's [**ServiceCreator**](ServiceCreator)`(Of T)` factory creates one instance per service start; the dispatcher trampoline holds the instance for the lifetime of the service and routes the three lifecycle subs to it. @@ -52,7 +52,7 @@ End Class ``` > [!IMPORTANT] -> [**EntryPoint**](#entrypoint) runs on the **service thread**. [**ChangeState**](#changestate) runs on the **dispatcher thread** (the EXE's main thread). The two methods execute concurrently and must coordinate through shared `Public` flags on the class — see [The two-thread split](.#two-thread-split) on the package overview. +> [**EntryPoint**](#entrypoint) runs on the **service thread**. [**ChangeState**](#changestate) runs on the **dispatcher thread** (the EXE's main thread). The two methods execute concurrently and must coordinate through shared `Public` flags on the class --- see [The two-thread split](.#two-thread-split) on the package overview. * TOC {:toc} @@ -67,10 +67,10 @@ Invoked by the SCM dispatcher thread when a control code is delivered to the ser Syntax: *service*.**ChangeState** *ServiceManager*, *dwControl*, *dwEventType*, *lpEventData* *ServiceManager* -: The [**ServiceManager**](ServiceManager) for this service — the same instance passed to [**EntryPoint**](#entrypoint). Use it to call [**ReportStatus**](ServiceManager#reportstatus) acknowledging the pending transition. +: The [**ServiceManager**](ServiceManager) for this service --- the same instance passed to [**EntryPoint**](#entrypoint). The implementation calls [**ReportStatus**](ServiceManager#reportstatus) on it to acknowledge the pending transition. *dwControl* -: A [**ServiceControlCodeConstants**](Enumerations/ServiceControlCodeConstants) value identifying the control. Standard codes the SCM may deliver include [**vbServiceControlStop**](Enumerations/ServiceControlCodeConstants#vbServiceControlStop), [**vbServiceControlShutdown**](Enumerations/ServiceControlCodeConstants#vbServiceControlShutdown), [**vbServiceControlPause**](Enumerations/ServiceControlCodeConstants#vbServiceControlPause), [**vbServiceControlContinue**](Enumerations/ServiceControlCodeConstants#vbServiceControlContinue), [**vbServiceControlInterrogate**](Enumerations/ServiceControlCodeConstants#vbServiceControlInterrogate), and the event-bearing codes ([**vbServiceControlSessionChange**](Enumerations/ServiceControlCodeConstants#vbServiceControlSessionChange), [**vbServiceControlPowerEvent**](Enumerations/ServiceControlCodeConstants#vbServiceControlPowerEvent), [**vbServiceControlDeviceEvent**](Enumerations/ServiceControlCodeConstants#vbServiceControlDeviceEvent), [**vbServiceControlHardwareProfileChange**](Enumerations/ServiceControlCodeConstants#vbServiceControlHardwareProfileChange)). User-defined codes in the range 128–255 can also be delivered through [**Services.ControlService**](Services#controlservice). +: A [**ServiceControlCodeConstants**](Enumerations/ServiceControlCodeConstants) value identifying the control. Standard codes the SCM may deliver include [**vbServiceControlStop**](Enumerations/ServiceControlCodeConstants#vbServiceControlStop), [**vbServiceControlShutdown**](Enumerations/ServiceControlCodeConstants#vbServiceControlShutdown), [**vbServiceControlPause**](Enumerations/ServiceControlCodeConstants#vbServiceControlPause), [**vbServiceControlContinue**](Enumerations/ServiceControlCodeConstants#vbServiceControlContinue), [**vbServiceControlInterrogate**](Enumerations/ServiceControlCodeConstants#vbServiceControlInterrogate), and the event-bearing codes ([**vbServiceControlSessionChange**](Enumerations/ServiceControlCodeConstants#vbServiceControlSessionChange), [**vbServiceControlPowerEvent**](Enumerations/ServiceControlCodeConstants#vbServiceControlPowerEvent), [**vbServiceControlDeviceEvent**](Enumerations/ServiceControlCodeConstants#vbServiceControlDeviceEvent), [**vbServiceControlHardwareProfileChange**](Enumerations/ServiceControlCodeConstants#vbServiceControlHardwareProfileChange)). User-defined codes in the range 128--255 can also be delivered through [**Services.ControlService**](Services#controlservice). *dwEventType* : A **Long** holding the event-type sub-code for the codes that have one. **0** otherwise. See Microsoft's `HandlerEx` documentation for the per-code interpretation. @@ -88,7 +88,7 @@ Select Case dwControl End Select ``` -[**ChangeState**](#changestate) **does not stop** [**EntryPoint**](#entrypoint) — it only delivers the SCM's request. The user's code is responsible for the actual shutdown logic, typically by setting a shared `Public` flag the service thread polls (`IsStopping`) or by calling a signal method on a blocking primitive that [**EntryPoint**](#entrypoint) owns (`NamedPipeServer.ManualMessageLoopLeave`, `SetEvent` on a Win32 event handle, ...). +[**ChangeState**](#changestate) **does not stop** [**EntryPoint**](#entrypoint) --- it only delivers the SCM's request. The user's code is responsible for the actual shutdown logic, typically by setting a shared `Public` flag the service thread polls (`IsStopping`) or by calling a signal method on a blocking primitive that [**EntryPoint**](#entrypoint) owns (`NamedPipeServer.ManualMessageLoopLeave`, `SetEvent` on a Win32 event handle, ...). The method runs on a different thread than [**EntryPoint**](#entrypoint); see [The two-thread split](.#two-thread-split) for the coordination rules. @@ -100,7 +100,7 @@ The service's main routine. Invoked by the package's dispatcher trampoline on th Syntax: *service*.**EntryPoint** *ServiceManager* *ServiceManager* -: The [**ServiceManager**](ServiceManager) for this service. Carries the configuration that was set during `Sub Main` plus the runtime [**LaunchArgs**](ServiceManager#launchargs) the SCM passed in. Use it to call [**ReportStatus**](ServiceManager#reportstatus) on every state transition. +: The [**ServiceManager**](ServiceManager) for this service. Contains the configuration that was set during `Sub Main` plus the runtime [**LaunchArgs**](ServiceManager#launchargs) the SCM passed in. The implementation calls [**ReportStatus**](ServiceManager#reportstatus) on it for every state transition. The body of **EntryPoint** is the service's actual work. The minimum responsibilities: @@ -112,7 +112,7 @@ The body of **EntryPoint** is the service's actual work. The minimum responsibil After the **EntryPoint** sub returns, the service thread exits and the SCM marks the service as stopped. > [!IMPORTANT] -> **EntryPoint** runs on the **service thread**, not the dispatcher thread. The two threads execute concurrently for the lifetime of the service. Use shared `Public` flags on the implementing class (`IsStopping`, `IsPaused`, …) to coordinate state changes triggered from [**ChangeState**](#changestate). +> **EntryPoint** runs on the **service thread**, not the dispatcher thread. The two threads execute concurrently for the lifetime of the service. Shared `Public` flags on the implementing class (`IsStopping`, `IsPaused`, …) coordinate state changes triggered from [**ChangeState**](#changestate). ### StartupFailed {: .no_toc } @@ -124,7 +124,7 @@ Syntax: *service*.**StartupFailed** *ServiceManager* *ServiceManager* : The [**ServiceManager**](ServiceManager) for this service. -This sub fires when `RegisterServiceCtrlHandlerExW` returns a zero handle — typically because the service was launched outside the SCM context, or the SCM's `RegisterServiceCtrlHandlerExW` rejected the registration. The service has no SCM status handle in this state, so [**ServiceManager.ReportStatus**](ServiceManager#reportstatus) cannot be called from inside **StartupFailed** — calling it raises run-time error 5. +This sub fires when `RegisterServiceCtrlHandlerExW` returns a zero handle --- typically because the service was launched outside the SCM context, or the SCM's `RegisterServiceCtrlHandlerExW` rejected the registration. The service has no SCM status handle in this state, so [**ServiceManager.ReportStatus**](ServiceManager#reportstatus) cannot be called from inside **StartupFailed** --- calling it raises run-time error 5. The typical implementation is a logging-only hook so the failure is recorded somewhere a developer can find it later: @@ -135,7 +135,7 @@ Sub StartupFailed(ByVal ServiceManager As ServiceManager) _ End Sub ``` -If you have no useful failure-reporting hook to add, an empty implementation is fine — the SCM has already given up at this point and no recovery is possible. +If there is no useful failure-reporting hook to add, an empty implementation is fine --- the SCM has already abandoned the start attempt at this point and no recovery is possible. ## See Also diff --git a/docs/Reference/WinServicesLib/ServiceCreator.md b/docs/Reference/WinServicesLib/ServiceCreator.md index 56317ff0..9964af05 100644 --- a/docs/Reference/WinServicesLib/ServiceCreator.md +++ b/docs/Reference/WinServicesLib/ServiceCreator.md @@ -13,7 +13,7 @@ The generic factory the **WinServicesLib** dispatcher uses to instantiate the us Syntax: **New ServiceCreator(Of** *T* **)** *T* -: *required* A user class that implements [**ITbService**](ITbService). The constraint is *practical* rather than syntactic — there is no `Where T : ITbService` clause in the source, but the factory's `CreateInstance` returns `New T As ITbService`, which the compiler only accepts when *T* implements [**ITbService**](ITbService). +: *required* A user class that implements [**ITbService**](ITbService). The constraint is *practical* rather than syntactic --- there is no `Where T : ITbService` clause in the source, but the factory's `CreateInstance` returns `New T As ITbService`, which the compiler only accepts when *T* implements [**ITbService**](ITbService). The class is the value typically assigned to [**ServiceManager.InstanceCreator**](ServiceManager#instancecreator): @@ -40,7 +40,7 @@ Returns a fresh `New T` cast as [**ITbService**](ITbService). Syntax: *creator*.**CreateInstance** **As** [**ITbService**](ITbService) -User code rarely calls **CreateInstance** directly; the package's dispatcher trampoline invokes it once per service start. The returned instance is owned by the dispatcher for the lifetime of the service — it is released when the service stops or the dispatcher exits. +User code rarely calls **CreateInstance** directly; the package's dispatcher trampoline invokes it once per service start. The returned instance is owned by the dispatcher for the lifetime of the service --- it is released when the service stops or the dispatcher exits. The method has no parameters; if the user's service class needs configuration, it should read it from the [**ServiceManager**](ServiceManager) passed to [**EntryPoint**](ITbService#entrypoint) rather than from constructor arguments. @@ -48,7 +48,7 @@ The method has no parameters; if the user's service class needs configuration, i `ServiceCreator(Of T)` exists because the SCM dispatch model needs *deferred* instantiation. The configuration phase runs in `Sub Main` before the SCM has decided which services to start; constructing the service class eagerly there would create an unnecessary instance for services the SCM may never launch (or launch only much later). The factory defers the `New T` call until the service actually starts. -The same indirection lets the dispatcher pair the [**ITbService**](ITbService) instance with the [**ServiceManager**](ServiceManager) one-to-one — the trampoline can pass the service-specific [**ServiceManager**](ServiceManager) into [**EntryPoint**](ITbService#entrypoint) without the service class having to know about the manager at construction time. +The same indirection lets the dispatcher pair the [**ITbService**](ITbService) instance with the [**ServiceManager**](ServiceManager) one-to-one --- the trampoline can pass the service-specific [**ServiceManager**](ServiceManager) into [**EntryPoint**](ITbService#entrypoint) without the service class having to know about the manager at construction time. ## See Also diff --git a/docs/Reference/WinServicesLib/ServiceManager.md b/docs/Reference/WinServicesLib/ServiceManager.md index 78dea9ec..f9f1600a 100644 --- a/docs/Reference/WinServicesLib/ServiceManager.md +++ b/docs/Reference/WinServicesLib/ServiceManager.md @@ -8,10 +8,10 @@ has_toc: false # ServiceManager class {: .no_toc } -The per-service configuration object. One [**ServiceManager**](.) describes one Windows service the EXE knows how to host — its [**Name**](#name), [**Description**](#description), service [**Type**](#type), [**InstallStartMode**](#installstartmode), [**InstanceCreator**](#instancecreator), and the optional fields the SCM cares about — and exposes the methods that act on a single service: [**Install**](#install), [**Uninstall**](#uninstall), and the [**ReportStatus**](#reportstatus) call the service uses to inform the SCM of state transitions while running. +The per-service configuration object. One [**ServiceManager**](.) describes one Windows service the EXE knows how to host --- its [**Name**](#name), [**Description**](#description), service [**Type**](#type), [**InstallStartMode**](#installstartmode), [**InstanceCreator**](#instancecreator), and the optional fields the SCM cares about --- and exposes the methods that act on a single service: [**Install**](#install), [**Uninstall**](#uninstall), and the [**ReportStatus**](#reportstatus) call the service uses to inform the SCM of state transitions while running. > [!NOTE] -> Do not construct **ServiceManager** instances directly. Call [**Services.ConfigureNew**](Services#configurenew) instead — it allocates a fresh manager and registers it in the package's internal collection so the dispatcher can find it. +> Do not construct **ServiceManager** instances directly. Call [**Services.ConfigureNew**](Services#configurenew) instead --- it allocates a fresh manager and registers it in the package's internal collection so the dispatcher can find it. ```tb With Services.ConfigureNew @@ -36,7 +36,7 @@ See the package [overview](.) for the broader lifecycle, the [two-thread split]( The launch-time arguments the SCM forwarded to the service. **String()**. Populated by the package's dispatcher trampoline when the SCM invokes the service-thread entry-point; *not* a configuration field. The service-thread [**ITbService.EntryPoint**](ITbService#entrypoint) reads it to discover the arguments that [**Services.LaunchService**](Services#launchservice) (or the SCM, or `sc.exe`) passed in. -`LaunchArgs(0)` is the *first user-supplied* argument — the SCM-supplied service name that comes through as `argv[0]` is dropped before the array is populated, so the indexing matches the caller's mental model. +`LaunchArgs(0)` is the *first user-supplied* argument --- the SCM-supplied service name that comes through as `argv[0]` is dropped before the array is populated, so the indexing matches the caller's mental model. ```tb Sub EntryPoint(ByVal ServiceManager As ServiceManager) _ @@ -56,14 +56,14 @@ End Sub Whether the dispatcher trampoline calls `CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)` on the service thread before invoking [**ITbService.EntryPoint**](ITbService#entrypoint). **Boolean**, default **True**. -Set to **False** if the service needs a different apartment model — for example, a service that creates an MTA worker pool. The service must then call `CoInitializeEx` itself from its [**EntryPoint**](ITbService#entrypoint) before touching COM-aware objects. +Set to **False** if the service needs a different apartment model --- for example, a service that creates an MTA worker pool. The service must then call `CoInitializeEx` itself from its [**EntryPoint**](ITbService#entrypoint) before touching COM-aware objects. ### Description {: .no_toc } The human-readable description listed in `services.msc` and `sc.exe query`. **String**, no default. -The value is written to the SCM by [**Install**](#install) via `ChangeServiceConfig2W(SERVICE_CONFIG_DESCRIPTION)` and is applied to a fresh service or refreshed on every re-install. Set it before calling [**Install**](#install); changing the field at run-time has no effect until the next install. +The value is written to the SCM by [**Install**](#install) via `ChangeServiceConfig2W(SERVICE_CONFIG_DESCRIPTION)` and is applied to a fresh service or refreshed on every re-install. The field must be assigned before [**Install**](#install) is called; changing it at run-time has no effect until the next install. ### DependentServices {: .no_toc } @@ -81,7 +81,7 @@ Pass an `Array("OtherSvc1", "OtherSvc2")`. When the SCM is asked to start the se The command line the SCM will use when launching the service-host EXE. **String**, default `"""<App.ModulePath>"""` (the running EXE path, quoted). -The default suffices only when the EXE always wants to run as a service. The conventional pattern is to **override the default** to add a discriminator argument so the EXE's `Sub Main` can tell which mode it is in: +The default suffices only when the EXE always runs as a service. The conventional pattern is to **override the default** to add a discriminator argument so the EXE's `Sub Main` can tell which mode it is in: ```tb .InstallCmdLine = """" & App.ModulePath & """ -startService" @@ -98,9 +98,9 @@ The SCM start mode the service is registered with. [**ServiceStartConstants**](E Typical settings: -- [**tbServiceStartOnDemand**](Enumerations/ServiceStartConstants#tbServiceStartOnDemand) — the service is **not** started automatically; user / installer / [**Services.LaunchService**](Services#launchservice) starts it on demand. -- [**tbServiceStartAuto**](Enumerations/ServiceStartConstants#tbServiceStartAuto) — the SCM starts the service at system boot. -- [**tbServiceStartDisabled**](Enumerations/ServiceStartConstants#tbServiceStartDisabled) — the service cannot be started until its start mode is changed. +- [**tbServiceStartOnDemand**](Enumerations/ServiceStartConstants#tbServiceStartOnDemand) -- the service is **not** started automatically; user / installer / [**Services.LaunchService**](Services#launchservice) starts it on demand. +- [**tbServiceStartAuto**](Enumerations/ServiceStartConstants#tbServiceStartAuto) -- the SCM starts the service at system boot. +- [**tbServiceStartDisabled**](Enumerations/ServiceStartConstants#tbServiceStartDisabled) -- the service cannot be started until its start mode is changed. The driver-only modes ([**tbServiceStartBoot**](Enumerations/ServiceStartConstants#tbServiceStartBoot), [**tbServiceStartDriverSystem**](Enumerations/ServiceStartConstants#tbServiceStartDriverSystem)) are not meaningful for user-mode twinBASIC services. @@ -109,41 +109,41 @@ The driver-only modes ([**tbServiceStartBoot**](Enumerations/ServiceStartConstan The factory the dispatcher uses to create the [**ITbService**](ITbService) instance for this service when the SCM launches it. [**IServiceCreator**](ServiceCreator), no default. -Set this to `New ServiceCreator(Of MyServiceClass)` where `MyServiceClass` is the user's [**ITbService**](ITbService) implementation: +Assigned `New ServiceCreator(Of MyServiceClass)` where `MyServiceClass` is the user's [**ITbService**](ITbService) implementation: ```tb .InstanceCreator = New ServiceCreator(Of MyService) ``` -[**RunServiceDispatcher**](Services#runservicedispatcher) calls `InstanceCreator.CreateInstance()` once per service start. **InstanceCreator** is read-write — the underlying private interface accepts both **Let** and **Set** assignment, so either syntax works. +[**RunServiceDispatcher**](Services#runservicedispatcher) calls `InstanceCreator.CreateInstance()` once per service start. **InstanceCreator** is read-write --- the underlying private interface accepts both **Let** and **Set** assignment, so either syntax works. -If only [**Install**](#install) / [**Uninstall**](#uninstall) need to run (e.g. inside a stand-alone installer), **InstanceCreator** can be left **Nothing** — the dispatcher only needs it when the SCM actually starts the service. +If only [**Install**](#install) / [**Uninstall**](#uninstall) need to run (e.g. inside a stand-alone installer), **InstanceCreator** can be left **Nothing** --- the dispatcher only needs it when the SCM actually starts the service. ### Name {: .no_toc } The service's name in the SCM database, used by `services.msc` and `sc.exe`. **String**, no default. -The name is what the SCM stores at `HKLM\SYSTEM\CurrentControlSet\Services\<Name>`; it is also the name [**Services.LaunchService**](Services#launchservice), [**Services.ControlService**](Services#controlservice), and [**Services.QueryStateOfService**](Services#querystateofservice) take as their *ServiceName* parameter. The same value is used for the SCM's *DisplayName* — the package does not currently expose a distinct display name. +The name is what the SCM stores at `HKLM\SYSTEM\CurrentControlSet\Services\<Name>`; it is also the name [**Services.LaunchService**](Services#launchservice), [**Services.ControlService**](Services#controlservice), and [**Services.QueryStateOfService**](Services#querystateofservice) take as their *ServiceName* parameter. The same value is used for the SCM's *DisplayName* --- the package does not currently expose a distinct display name. ### SupportsPausing {: .no_toc } Whether the SCM is told that the service accepts [**SERVICE_CONTROL_PAUSE**](Enumerations/ServiceControlCodeConstants#vbServiceControlPause) / [**SERVICE_CONTROL_CONTINUE**](Enumerations/ServiceControlCodeConstants#vbServiceControlContinue) notifications. **Boolean**, default **False**. -Setting this property immediately resyncs the cached `SERVICE_STATUS` to the SCM via `SetServiceStatus`, so toggling it from inside [**EntryPoint**](ITbService#entrypoint) — once the service is past the `StartPending` phase — takes effect on the next SCM query. Most services that support pausing set the property to **True** at the top of [**EntryPoint**](ITbService#entrypoint) and handle [**vbServiceControlPause**](Enumerations/ServiceControlCodeConstants#vbServiceControlPause) / [**vbServiceControlContinue**](Enumerations/ServiceControlCodeConstants#vbServiceControlContinue) in [**ChangeState**](ITbService#changestate). +Setting this property immediately resyncs the cached `SERVICE_STATUS` to the SCM via `SetServiceStatus`, so toggling it from inside [**EntryPoint**](ITbService#entrypoint) --- once the service is past the `StartPending` phase --- takes effect on the next SCM query. Most services that support pausing set the property to **True** at the top of [**EntryPoint**](ITbService#entrypoint) and handle [**vbServiceControlPause**](Enumerations/ServiceControlCodeConstants#vbServiceControlPause) / [**vbServiceControlContinue**](Enumerations/ServiceControlCodeConstants#vbServiceControlContinue) in [**ChangeState**](ITbService#changestate). If the service has not yet reached the started state when **SupportsPausing** is set, the resync raises run-time error 5 *"Can't update the service state until the service has started"*. Wait until after the first [**ReportStatus**](#reportstatus)`(vbServiceStatusRunning)` call before toggling the property. ### Type {: .no_toc } -The Win32 service type — controls whether the service runs in its own process, in a shared process, or is a kernel driver. [**ServiceTypeConstants**](Enumerations/ServiceTypeConstants), default [**tbServiceTypeOwnProcess**](Enumerations/ServiceTypeConstants#tbServiceTypeOwnProcess). +The Win32 service type --- controls whether the service runs in its own process, in a shared process, or is a kernel driver. [**ServiceTypeConstants**](Enumerations/ServiceTypeConstants), default [**tbServiceTypeOwnProcess**](Enumerations/ServiceTypeConstants#tbServiceTypeOwnProcess). Typical settings: -- [**tbServiceTypeOwnProcess**](Enumerations/ServiceTypeConstants#tbServiceTypeOwnProcess) — one service per EXE. -- [**tbServiceTypeShareProcess**](Enumerations/ServiceTypeConstants#tbServiceTypeShareProcess) — multiple services hosted in a single EXE; the SCM keeps one process alive that serves all of them. Each [**ServiceManager**](.) still needs its own configuration and [**InstanceCreator**](#instancecreator). +- [**tbServiceTypeOwnProcess**](Enumerations/ServiceTypeConstants#tbServiceTypeOwnProcess) -- one service per EXE. +- [**tbServiceTypeShareProcess**](Enumerations/ServiceTypeConstants#tbServiceTypeShareProcess) -- multiple services hosted in a single EXE; the SCM keeps one process alive that serves all of them. Each [**ServiceManager**](.) still needs its own configuration and [**InstanceCreator**](#instancecreator). The driver-only modes ([**tbServiceTypeSystemDriver**](Enumerations/ServiceTypeConstants#tbServiceTypeSystemDriver), [**tbServiceTypeKernelDriver**](Enumerations/ServiceTypeConstants#tbServiceTypeKernelDriver), …) are not meaningful for user-mode twinBASIC services. @@ -156,10 +156,10 @@ Registers this service in the SCM database. Syntax: *manager*.**Install** -Opens the SCM with `SC_MANAGER_CONNECT Or SC_MANAGER_CREATE_SERVICE`, calls `CreateServiceW` with the configured fields. If a service with the same [**Name**](#name) already exists, the method deletes it first (via `OpenServiceW(SERVICE_DELETE)` + `DeleteService`) and retries — so calling [**Install**](#install) on a service that already exists overwrites the existing registration rather than failing. On a successful create the [**Description**](#description) is written via `ChangeServiceConfig2W(SERVICE_CONFIG_DESCRIPTION)`. +Opens the SCM with `SC_MANAGER_CONNECT Or SC_MANAGER_CREATE_SERVICE`, calls `CreateServiceW` with the configured fields. If a service with the same [**Name**](#name) already exists, the method deletes it first (via `OpenServiceW(SERVICE_DELETE)` + `DeleteService`) and retries --- so calling [**Install**](#install) on a service that already exists overwrites the existing registration rather than failing. On a successful create the [**Description**](#description) is written via `ChangeServiceConfig2W(SERVICE_CONFIG_DESCRIPTION)`. > [!IMPORTANT] -> [**Install**](#install) writes to the SCM database, which requires administrator rights. The usual pattern is to call it once from an elevated installer, not from the application's normal startup path. Running from within the twinBASIC IDE typically fails — the IDE is rarely elevated. +> [**Install**](#install) writes to the SCM database, which requires administrator rights. The usual pattern is to call it once from an elevated installer, not from the application's normal startup path. Running from within the twinBASIC IDE typically fails --- the IDE is rarely elevated. Raises run-time error 5 with a descriptive message on permission failure (*"Unable to open the Service manager..."*) or unrecoverable create failure (*"CreateServiceW() failed with error code <N>"*). @@ -171,17 +171,17 @@ Informs the SCM of the service's current state. Called by the service from insid Syntax: *manager*.**ReportStatus** *CurrentState* [, *Win32ExitCode* [, *WaitHint* ] ] *CurrentState* -: *required* A [**ServiceStatusConstants**](Enumerations/ServiceStatusConstants) value — typically [**vbServiceStatusRunning**](Enumerations/ServiceStatusConstants#vbServiceStatusRunning), [**vbServiceStatusStopPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStopPending), or [**vbServiceStatusStopped**](Enumerations/ServiceStatusConstants#vbServiceStatusStopped). +: *required* A [**ServiceStatusConstants**](Enumerations/ServiceStatusConstants) value --- typically [**vbServiceStatusRunning**](Enumerations/ServiceStatusConstants#vbServiceStatusRunning), [**vbServiceStatusStopPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStopPending), or [**vbServiceStatusStopped**](Enumerations/ServiceStatusConstants#vbServiceStatusStopped). *Win32ExitCode* -: *optional* A **Long** exit code. Default **0** (`NO_ERROR`). When reporting [**vbServiceStatusStopped**](Enumerations/ServiceStatusConstants#vbServiceStatusStopped) after an error, pass either a Win32 error code or, for service-specific codes, the magic value `ERROR_SERVICE_SPECIFIC_ERROR` (1066) along with placing the real code in the service-specific field — but the package's API exposes only the *Win32ExitCode* parameter directly. Most services pass **0** for a clean stop and a small custom code for an error stop. +: *optional* A **Long** exit code. Default **0** (`NO_ERROR`). When reporting [**vbServiceStatusStopped**](Enumerations/ServiceStatusConstants#vbServiceStatusStopped) after an error, pass either a Win32 error code or, for service-specific codes, the magic value `ERROR_SERVICE_SPECIFIC_ERROR` (1066) along with placing the real code in the service-specific field --- but the package's API exposes only the *Win32ExitCode* parameter directly. Most services pass **0** for a clean stop and a small custom code for an error stop. *WaitHint* -: *optional* A **Long** giving the SCM an upper-bound milliseconds estimate of how long the current pending transition will take. Default **0**. Only meaningful for pending states ([**vbServiceStatusStartPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStartPending), [**vbServiceStatusStopPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStopPending), [**vbServiceStatusPausePending**](Enumerations/ServiceStatusConstants#vbServiceStatusPausePending), [**vbServiceStatusContinuePending**](Enumerations/ServiceStatusConstants#vbServiceStatusContinuePending)) — the SCM uses it together with the auto-incremented `dwCheckPoint` field to detect a stuck service. +: *optional* A **Long** giving the SCM an upper-bound milliseconds estimate of how long the current pending transition will take. Default **0**. Only meaningful for pending states ([**vbServiceStatusStartPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStartPending), [**vbServiceStatusStopPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStopPending), [**vbServiceStatusPausePending**](Enumerations/ServiceStatusConstants#vbServiceStatusPausePending), [**vbServiceStatusContinuePending**](Enumerations/ServiceStatusConstants#vbServiceStatusContinuePending)) --- the SCM uses it together with the auto-incremented `dwCheckPoint` field to detect a stuck service. -**ReportStatus** fills the `dwControlsAccepted` field of `SERVICE_STATUS` automatically — *Stop* is always accepted except during [**vbServiceStatusStartPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStartPending), and *Pause* / *Continue* are accepted when [**SupportsPausing**](#supportspausing) is **True**. The `dwCheckPoint` field auto-increments while the service is in a pending state and resets to **0** on [**vbServiceStatusRunning**](Enumerations/ServiceStatusConstants#vbServiceStatusRunning) / [**vbServiceStatusStopped**](Enumerations/ServiceStatusConstants#vbServiceStatusStopped). +**ReportStatus** fills the `dwControlsAccepted` field of `SERVICE_STATUS` automatically --- *Stop* is always accepted except during [**vbServiceStatusStartPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStartPending), and *Pause* / *Continue* are accepted when [**SupportsPausing**](#supportspausing) is **True**. The `dwCheckPoint` field auto-increments while the service is in a pending state and resets to **0** on [**vbServiceStatusRunning**](Enumerations/ServiceStatusConstants#vbServiceStatusRunning) / [**vbServiceStatusStopped**](Enumerations/ServiceStatusConstants#vbServiceStatusStopped). -The package's dispatcher trampoline reports [**vbServiceStatusStartPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStartPending) for you immediately before calling [**EntryPoint**](ITbService#entrypoint); the user's [**EntryPoint**](ITbService#entrypoint) is responsible for the subsequent [**vbServiceStatusRunning**](Enumerations/ServiceStatusConstants#vbServiceStatusRunning) and [**vbServiceStatusStopped**](Enumerations/ServiceStatusConstants#vbServiceStatusStopped) transitions. +The package's dispatcher trampoline reports [**vbServiceStatusStartPending**](Enumerations/ServiceStatusConstants#vbServiceStatusStartPending) immediately before calling [**EntryPoint**](ITbService#entrypoint); the user's [**EntryPoint**](ITbService#entrypoint) is responsible for the subsequent [**vbServiceStatusRunning**](Enumerations/ServiceStatusConstants#vbServiceStatusRunning) and [**vbServiceStatusStopped**](Enumerations/ServiceStatusConstants#vbServiceStatusStopped) transitions. ### ResyncStatus {: .no_toc } @@ -190,7 +190,7 @@ Re-applies the cached `SERVICE_STATUS` to the SCM via `SetServiceStatus`. Called Syntax: *manager*.**ResyncStatus** -Raises run-time error 5 *"Can't update the service state until the service has started"* if called before the service has acquired its SCM status handle (i.e. before the dispatcher trampoline has called `RegisterServiceCtrlHandlerExW`). Use [**ReportStatus**](#reportstatus) from inside [**EntryPoint**](ITbService#entrypoint) instead of **ResyncStatus** directly. +Raises run-time error 5 *"Can't update the service state until the service has started"* if called before the service has acquired its SCM status handle (i.e. before the dispatcher trampoline has called `RegisterServiceCtrlHandlerExW`). From inside [**EntryPoint**](ITbService#entrypoint), [**ReportStatus**](#reportstatus) is the right call rather than **ResyncStatus** directly. ### Uninstall {: .no_toc } @@ -199,7 +199,7 @@ Removes this service from the SCM database. Syntax: *manager*.**Uninstall** -Opens the SCM, opens the service with `SERVICE_DELETE`, calls `DeleteService`. The actual deletion is queued by the SCM and completes once every open handle to the service is closed — `services.msc` may show the service as *"Marked for deletion"* until the host process exits. +Opens the SCM, opens the service with `SERVICE_DELETE`, calls `DeleteService`. The actual deletion is queued by the SCM and completes once every open handle to the service is closed --- `services.msc` may show the service as *"Marked for deletion"* until the host process exits. > [!IMPORTANT] > [**Uninstall**](#uninstall) requires administrator rights. Raises run-time error 5 with a descriptive message if the SCM cannot be opened, the service is not installed, or `DeleteService` fails. diff --git a/docs/Reference/WinServicesLib/ServiceState.md b/docs/Reference/WinServicesLib/ServiceState.md index edefa99c..83c4b321 100644 --- a/docs/Reference/WinServicesLib/ServiceState.md +++ b/docs/Reference/WinServicesLib/ServiceState.md @@ -17,9 +17,9 @@ Set state = Services.QueryStateOfService("MyService") Debug.Print state.CurrentStateText, "PID " & state.ProcessId ``` -The snapshot is taken **once at construction time** and never refreshed. To monitor a service over time, call [**Services.QueryStateOfService**](Services#querystateofservice) again at each sampling interval — typically from a low-frequency Timer. +The snapshot is taken **once at construction time** and never refreshed. To monitor a service over time, call [**Services.QueryStateOfService**](Services#querystateofservice) again at each sampling interval --- typically from a low-frequency Timer. -The constructor opens the SCM with `SC_MANAGER_CONNECT`, opens the service with `SERVICE_QUERY_STATUS`, calls `QueryServiceStatusEx(SC_STATUS_PROCESS_INFO, ...)`, and copies the result into a private buffer. The three failure modes — SCM open failed, service not installed, status query failed — all raise run-time error 5 with a descriptive message. Wrap the call in `On Error Resume Next` if your UI needs to distinguish "service exists and is running" from "service is not installed": +The constructor opens the SCM with `SC_MANAGER_CONNECT`, opens the service with `SERVICE_QUERY_STATUS`, calls `QueryServiceStatusEx(SC_STATUS_PROCESS_INFO, ...)`, and copies the result into a private buffer. The three failure modes --- SCM open failed, service not installed, status query failed --- all raise run-time error 5 with a descriptive message. Wrap the call in `On Error Resume Next` if the UI needs to distinguish "service exists and is running" from "service is not installed": ```tb Private Function GetStateText(ByVal serviceName As String) As String @@ -52,7 +52,7 @@ Services in a *Pending* state ([**StartPending**](Enumerations/ServiceStatusCons A bitmask of `SERVICE_ACCEPT_*` flags indicating which control codes the service has told the SCM it accepts. **Long**. > [!NOTE] -> Although the underlying SCM field is a flag bitmask, the property is typed plain **Long** in this release rather than as a typed enum. The bit values follow the Win32 documented constants — `SERVICE_ACCEPT_STOP` (1), `SERVICE_ACCEPT_PAUSE_CONTINUE` (2), `SERVICE_ACCEPT_SHUTDOWN` (4), `SERVICE_ACCEPT_PARAMCHANGE` (8), `SERVICE_ACCEPT_NETBINDCHANGE` (16), `SERVICE_ACCEPT_HARDWAREPROFILECHANGE` (32), `SERVICE_ACCEPT_POWEREVENT` (64), `SERVICE_ACCEPT_SESSIONCHANGE` (128), `SERVICE_ACCEPT_PRESHUTDOWN` (256), and so on. +> Although the underlying SCM field is a flag bitmask, the property is typed plain **Long** in this release rather than as a typed enum. The bit values follow the Win32 documented constants --- `SERVICE_ACCEPT_STOP` (1), `SERVICE_ACCEPT_PAUSE_CONTINUE` (2), `SERVICE_ACCEPT_SHUTDOWN` (4), `SERVICE_ACCEPT_PARAMCHANGE` (8), `SERVICE_ACCEPT_NETBINDCHANGE` (16), `SERVICE_ACCEPT_HARDWAREPROFILECHANGE` (32), `SERVICE_ACCEPT_POWEREVENT` (64), `SERVICE_ACCEPT_SESSIONCHANGE` (128), `SERVICE_ACCEPT_PRESHUTDOWN` (256), and so on. ### CurrentState {: .no_toc } @@ -86,14 +86,14 @@ Any unrecognised state value is rendered as `UNKNOWN STATE (<n>)`. The SCM-reported `dwWin32ExitCode` value. **Long**. -For a normally-stopped service this is **0** (`NO_ERROR`); for a service that stopped due to an error, this is either a Win32 error code or the sentinel `ERROR_SERVICE_SPECIFIC_ERROR` (1066) — in which case the real code is in [**ServiceSpecificExitCode**](#servicespecificexitcode). +For a normally-stopped service this is **0** (`NO_ERROR`); for a service that stopped due to an error, this is either a Win32 error code or the sentinel `ERROR_SERVICE_SPECIFIC_ERROR` (1066) --- in which case the real code is in [**ServiceSpecificExitCode**](#servicespecificexitcode). ### Flags {: .no_toc } The SCM-reported `dwServiceFlags` value. **Long**. -Only one bit is currently documented — `SERVICE_RUNS_IN_SYSTEM_PROCESS` (1), set when the service is hosted inside the system process (`services.exe`). +Only one bit is currently documented --- `SERVICE_RUNS_IN_SYSTEM_PROCESS` (1), set when the service is hosted inside the system process (`services.exe`). ### ProcessId {: .no_toc } @@ -121,7 +121,7 @@ The value the SCM has on file for the service, typically [**tbServiceTypeOwnProc The SCM-reported `dwWaitHint` value in milliseconds. **Long**. -Only meaningful while the service is in a *Pending* state — it is the upper-bound estimate the service has told the SCM the pending transition will take. The SCM uses [**CheckPoint**](#checkpoint) and **WaitHint** together to decide whether a pending service is making progress. +Only meaningful while the service is in a *Pending* state --- it is the upper-bound estimate the service has told the SCM the pending transition will take. The SCM uses [**CheckPoint**](#checkpoint) and **WaitHint** together to determine whether a pending service is making progress. ## See Also diff --git a/docs/Reference/WinServicesLib/Services.md b/docs/Reference/WinServicesLib/Services.md index 0abfc338..273a1d9d 100644 --- a/docs/Reference/WinServicesLib/Services.md +++ b/docs/Reference/WinServicesLib/Services.md @@ -63,7 +63,7 @@ Syntax: **Services.ControlService** *ServiceName*, *ControlCode* : *required* A **String** naming an installed service. *ControlCode* -: *required* A [**ServiceControlCodeConstants**](Enumerations/ServiceControlCodeConstants) value — typically [**vbServiceControlStop**](Enumerations/ServiceControlCodeConstants#vbServiceControlStop), [**vbServiceControlPause**](Enumerations/ServiceControlCodeConstants#vbServiceControlPause), [**vbServiceControlContinue**](Enumerations/ServiceControlCodeConstants#vbServiceControlContinue), or [**vbServiceControlInterrogate**](Enumerations/ServiceControlCodeConstants#vbServiceControlInterrogate). User-defined codes in the range 128–255 are also accepted. +: *required* A [**ServiceControlCodeConstants**](Enumerations/ServiceControlCodeConstants) value --- typically [**vbServiceControlStop**](Enumerations/ServiceControlCodeConstants#vbServiceControlStop), [**vbServiceControlPause**](Enumerations/ServiceControlCodeConstants#vbServiceControlPause), [**vbServiceControlContinue**](Enumerations/ServiceControlCodeConstants#vbServiceControlContinue), or [**vbServiceControlInterrogate**](Enumerations/ServiceControlCodeConstants#vbServiceControlInterrogate). User-defined codes in the range 128--255 are also accepted. The method opens the SCM, requests the minimum required permission for the chosen control code (`SERVICE_STOP`, `SERVICE_PAUSE_CONTINUE`, `SERVICE_INTERROGATE`, or `SERVICE_USER_DEFINED_CONTROL`), opens the service, calls `ControlServiceExW`, and closes the handles. For [**vbServiceControlStop**](Enumerations/ServiceControlCodeConstants#vbServiceControlStop) the reason code is filled with `SERVICE_STOP_REASON_FLAG_PLANNED | SERVICE_STOP_REASON_MAJOR_NONE | SERVICE_STOP_REASON_MINOR_NONE` ("planned stop, no specific reason"). Customising the reason code is not currently exposed. @@ -88,7 +88,7 @@ Private Sub btnInstallA_Click() End Sub ``` -Despite the `Property Get` syntax, the lookup is parameterised by name — it reads as a property in source code, but behaves like a function. +Despite the `Property Get` syntax, the lookup is parameterised by name --- it reads as a property in source code, but behaves like a function. ### InstallAll {: .no_toc } @@ -100,7 +100,7 @@ Syntax: **Services.InstallAll** > [!IMPORTANT] > **InstallAll** writes registry entries under `HKEY_LOCAL_MACHINE` and requires administrator rights. The usual pattern is to call it once from an elevated installer. -Per-service errors raised inside [**ServiceManager.Install**](ServiceManager#install) propagate out of **InstallAll** and abort the bulk operation — there is no per-service `On Error Resume Next` wrapping. Services already installed before the failure remain installed. +Per-service errors raised inside [**ServiceManager.Install**](ServiceManager#install) propagate out of **InstallAll** and abort the bulk operation --- there is no per-service `On Error Resume Next` wrapping. Services already installed before the failure remain installed. ### LaunchService {: .no_toc } @@ -171,7 +171,7 @@ Syntax: **Services.RunServiceDispatcher** Internally builds a `SERVICE_TABLE_ENTRYW` array from every configured [**ServiceManager**](ServiceManager) and calls `StartServiceCtrlDispatcherW`. The SCM spawns a fresh thread for each service the user (or the *Start* configuration) wants to start, and invokes the package's dispatcher trampoline on that thread; the trampoline reports `StartPending`, optionally initialises COM in STA mode (controlled by [**ServiceManager.AutoInitializeCOM**](ServiceManager#autoinitializecom)), then calls the user's [**ITbService.EntryPoint**](ITbService#entrypoint). -Raises run-time error 5 *"Unable to start the service dispatcher"* if `StartServiceCtrlDispatcherW` returns zero. The usual cause is that the EXE was launched normally rather than by the SCM — the dispatcher only works when the process is a service host. The conventional `If InStr(Command, "-startService") > 0 Then` gate in `Sub Main` avoids this error. +Raises run-time error 5 *"Unable to start the service dispatcher"* if `StartServiceCtrlDispatcherW` returns zero. The usual cause is that the EXE was launched normally rather than by the SCM --- the dispatcher only works when the process is a service host. The conventional `If InStr(Command, "-startService") > 0 Then` gate in `Sub Main` avoids this error. ### UninstallAll {: .no_toc } @@ -199,7 +199,7 @@ For Each manager In Services Next ``` -The enumeration order is insertion order — services appear in the order they were created with [**ConfigureNew**](#configurenew). +The enumeration order is insertion order --- services appear in the order they were created with [**ConfigureNew**](#configurenew). ## See Also diff --git a/docs/Reference/WinServicesLib/index.md b/docs/Reference/WinServicesLib/index.md index ebf2e320..b7686ecc 100644 --- a/docs/Reference/WinServicesLib/index.md +++ b/docs/Reference/WinServicesLib/index.md @@ -19,18 +19,18 @@ The package is a built-in package shipped with twinBASIC. Add it through Project ## What a Windows service is -A *Windows service* is a long-running background process supervised by the **Service Control Manager (SCM)**. Services can start before any user logs in, run under dedicated accounts (`LocalSystem`, `LocalService`, `NetworkService`, or any explicit user), and respond to lifecycle commands — *Start*, *Stop*, *Pause*, *Continue* — issued from the Services control-panel applet (`services.msc`), the `sc.exe` command-line tool, or programmatic equivalents. +A *Windows service* is a long-running background process supervised by the **Service Control Manager (SCM)**. Services can start before any user logs in, run under dedicated accounts (`LocalSystem`, `LocalService`, `NetworkService`, or any explicit user), and respond to lifecycle commands --- *Start*, *Stop*, *Pause*, *Continue* --- issued from the Services control-panel applet (`services.msc`), the `sc.exe` command-line tool, or programmatic equivalents. -A service-hosting EXE communicates with the SCM through a small set of Win32 entry points: `StartServiceCtrlDispatcherW` to hand the process over to the SCM, `RegisterServiceCtrlHandlerExW` to hook a control-code callback, `SetServiceStatus` to report state transitions, and `CreateServiceW` / `DeleteService` to register / unregister the service in the system database. **WinServicesLib** wraps all of these — the consumer writes one class per service, declares it through the package's coordinator, and the package handles every Win32 detail. +A service-hosting EXE communicates with the SCM through a small set of Win32 entry points: `StartServiceCtrlDispatcherW` to hand the process over to the SCM, `RegisterServiceCtrlHandlerExW` to hook a control-code callback, `SetServiceStatus` to report state transitions, and `CreateServiceW` / `DeleteService` to register / unregister the service in the system database. **WinServicesLib** wraps all of these --- the consumer writes one class per service, declares it through the package's coordinator, and the package handles every Win32 detail. ## Lifecycle A service-hosting EXE goes through four phases: -1. **Configure** — at startup, declare every service the EXE knows how to host by calling [**Services.ConfigureNew**](Services#configurenew) and filling the returned [**ServiceManager**](ServiceManager). Configuration is purely in-memory and does not touch the SCM; it builds the map the dispatcher will use *if* the EXE is launched as a service host. -2. **Install** (one-time, elevated) — register the configured services in the system database via [**ServiceManager.Install**](ServiceManager#install) or [**Services.InstallAll**](Services#installall). This writes registry entries under `HKLM\SYSTEM\CurrentControlSet\Services\<Name>` pointing at the EXE and requires administrator rights. Usually run from an installer. -3. **Run as a service** (when the SCM launches the EXE) — the EXE's `Sub Main` detects it was launched as a service host (typically by inspecting `Command` for a known argument like `"-startService"`) and calls [**Services.RunServiceDispatcher**](Services#runservicedispatcher). This blocks the main thread inside `StartServiceCtrlDispatcherW` until the SCM signals shutdown. The SCM spawns a separate service thread per service and calls into the package's dispatcher trampoline; the trampoline reports `StartPending`, then invokes the user's [**ITbService.EntryPoint**](ITbService#entrypoint) on the service thread. -4. **Run normally** (when a user launches the EXE) — the EXE's `Sub Main` does *not* see the service-host argument and proceeds to whatever UI / CLI logic the EXE provides for installation, status display, or interactive testing. The same configured [**ServiceManager**](ServiceManager) instances are still reachable through [**Services.GetConfiguredService**](Services#getconfiguredservice) and the [**For Each**](Services#_newenum) enumerator, which is what enables a single-EXE install-and-host design. +1. **Configure** --- at startup, declare every service the EXE knows how to host by calling [**Services.ConfigureNew**](Services#configurenew) and filling the returned [**ServiceManager**](ServiceManager). Configuration is purely in-memory and does not touch the SCM; it builds the map the dispatcher will use *if* the EXE is launched as a service host. +2. **Install** (one-time, elevated) --- register the configured services in the system database via [**ServiceManager.Install**](ServiceManager#install) or [**Services.InstallAll**](Services#installall). This writes registry entries under `HKLM\SYSTEM\CurrentControlSet\Services\<Name>` pointing at the EXE and requires administrator rights. Usually run from an installer. +3. **Run as a service** (when the SCM launches the EXE) --- the EXE's `Sub Main` detects it was launched as a service host (typically by inspecting `Command` for a known argument like `"-startService"`) and calls [**Services.RunServiceDispatcher**](Services#runservicedispatcher). This blocks the main thread inside `StartServiceCtrlDispatcherW` until the SCM signals shutdown. The SCM spawns a separate service thread per service and calls into the package's dispatcher trampoline; the trampoline reports `StartPending`, then invokes the user's [**ITbService.EntryPoint**](ITbService#entrypoint) on the service thread. +4. **Run normally** (when a user launches the EXE) --- the EXE's `Sub Main` does *not* see the service-host argument and proceeds to whatever UI / CLI logic the EXE provides for installation, status display, or interactive testing. The same configured [**ServiceManager**](ServiceManager) instances are still reachable through [**Services.GetConfiguredService**](Services#getconfiguredservice) and the [**For Each**](Services#_newenum) enumerator, which is what enables a single-EXE install-and-host design. The canonical `Sub Main` skeleton: @@ -60,12 +60,12 @@ The `-startService` discriminator is the conventional way for the EXE to know wh ## The two-thread split {: #two-thread-split } -When the SCM launches the EXE as a service host, twinBASIC's runtime ends up running **two threads** for each service: +When the SCM launches the EXE as a service host, twinBASIC's runtime runs **two threads** for each service: -- The **service thread** — the SCM-spawned thread that runs the user's [**ITbService.EntryPoint**](ITbService#entrypoint). This is where the service does its actual work. The thread is created by `StartServiceCtrlDispatcherW`'s machinery; it is *not* the main thread of the EXE. -- The **dispatcher thread** — the EXE's main thread, which is what the SCM invokes when it has a control code to deliver (*Stop*, *Pause*, *Continue*, …). The package routes the control through `RegisterServiceCtrlHandlerExW` to a trampoline that calls the user's [**ITbService.ChangeState**](ITbService#changestate). +- The **service thread** --- the SCM-spawned thread that runs the user's [**ITbService.EntryPoint**](ITbService#entrypoint). This is where the service does its actual work. The thread is created by `StartServiceCtrlDispatcherW`'s machinery; it is *not* the main thread of the EXE. +- The **dispatcher thread** --- the EXE's main thread, which is what the SCM invokes when it has a control code to deliver (*Stop*, *Pause*, *Continue*, …). The package routes the control through `RegisterServiceCtrlHandlerExW` to a trampoline that calls the user's [**ITbService.ChangeState**](ITbService#changestate). -The two methods therefore run *concurrently*: while [**EntryPoint**](ITbService#entrypoint) is doing the service's work on the service thread, [**ChangeState**](ITbService#changestate) is sitting idle on the dispatcher thread, and the SCM wakes it on demand to deliver a control code. The two methods must coordinate through shared `Public` flags on the service class — `IsStopping`, `IsPaused`, and friends — because the package cannot tell the service thread to stop except through the user's own code path. +The two methods therefore run *concurrently*: while [**EntryPoint**](ITbService#entrypoint) is doing the service's work on the service thread, [**ChangeState**](ITbService#changestate) waits idle on the dispatcher thread, and the SCM wakes it on demand to deliver a control code. The two methods must coordinate through shared `Public` flags on the service class --- `IsStopping`, `IsPaused`, and similar --- because the package cannot stop the service thread except through the user's own code path. ```tb Class MyService @@ -101,14 +101,14 @@ Class MyService End Class ``` -The shared-flag pattern is the documented coordination mechanism — there is no built-in cancellation primitive. For services that host an inherently message-loop-driven object (a [**NamedPipeServer**](../WinNamedPipesLib/NamedPipeServer), a window-message handler, …) that object's own *Stop*-signal method is usually called from [**ChangeState**](ITbService#changestate); see [the WinNamedPipesLib service-host idiom](../WinNamedPipesLib/#service-host-idiom) for a worked example. +The shared-flag pattern is the documented coordination mechanism --- there is no built-in cancellation primitive. For services that host an inherently message-loop-driven object (a [**NamedPipeServer**](../WinNamedPipesLib/NamedPipeServer), a window-message handler, …) that object's own *Stop*-signal method is usually called from [**ChangeState**](ITbService#changestate); see [the WinNamedPipesLib service-host idiom](../WinNamedPipesLib/#service-host-idiom) for a worked example. ## Integration with the sister "winlibs" packages -`WinServicesLib` is most often used together with [**WinEventLogLib**](../WinEventLogLib/) and [**WinNamedPipesLib**](../WinNamedPipesLib/) — Windows services typically need a place to write diagnostic events (the Windows Event Log) and a way to communicate with non-service processes (named pipes). The three packages integrate well: +`WinServicesLib` is most often used together with [**WinEventLogLib**](../WinEventLogLib/) and [**WinNamedPipesLib**](../WinNamedPipesLib/) --- Windows services typically need a place to write diagnostic events (the Windows Event Log) and a way to communicate with non-service processes (named pipes). The three packages integrate well: -- **Logging** — every service class can mix in the [**EventLog**](../WinEventLogLib/EventLog) members through the [composition-delegation idiom](../WinEventLogLib/#composition-delegation-idiom) (`Implements EventLog(Of EVENTS, CATEGORIES) Via EventLog = New EventLog(...)`), so [**LogSuccess**](../WinEventLogLib/EventLog#logsuccess) / [**LogFailure**](../WinEventLogLib/EventLog#logfailure) read as plain method calls inside `EntryPoint` and `ChangeState`. The events fire under the service account (typically `LocalSystem`), which the Event Viewer renders against the message-table resource embedded in the EXE. -- **IPC** — a [**NamedPipeServer**](../WinNamedPipesLib/NamedPipeServer) hosted inside the service uses [**ManualMessageLoopEnter**](../WinNamedPipesLib/NamedPipeServer#manualmessageloopenter) as the [**EntryPoint**](ITbService#entrypoint)'s blocking primitive, and [**ManualMessageLoopLeave**](../WinNamedPipesLib/NamedPipeServer#manualmessageloopleave) from [**ChangeState**](ITbService#changestate) becomes the *Stop*-signal mechanism. See [Hosting inside a Windows service](../WinNamedPipesLib/#service-host-idiom) for the complete pattern, including pause / continue and the dispatcher-thread / service-thread interaction. +- **Logging** --- every service class can mix in the [**EventLog**](../WinEventLogLib/EventLog) members through the [composition-delegation idiom](../WinEventLogLib/#composition-delegation-idiom) (`Implements EventLog(Of EVENTS, CATEGORIES) Via EventLog = New EventLog(...)`), so [**LogSuccess**](../WinEventLogLib/EventLog#logsuccess) / [**LogFailure**](../WinEventLogLib/EventLog#logfailure) read as plain method calls inside `EntryPoint` and `ChangeState`. The events fire under the service account (typically `LocalSystem`), which the Event Viewer renders against the message-table resource embedded in the EXE. +- **IPC** --- a [**NamedPipeServer**](../WinNamedPipesLib/NamedPipeServer) hosted inside the service uses [**ManualMessageLoopEnter**](../WinNamedPipesLib/NamedPipeServer#manualmessageloopenter) as the [**EntryPoint**](ITbService#entrypoint)'s blocking primitive, and [**ManualMessageLoopLeave**](../WinNamedPipesLib/NamedPipeServer#manualmessageloopleave) from [**ChangeState**](ITbService#changestate) becomes the *Stop*-signal mechanism. See [Hosting inside a Windows service](../WinNamedPipesLib/#service-host-idiom) for the complete pattern, including pause / continue and the dispatcher-thread / service-thread interaction. ## Installation and elevation @@ -116,9 +116,9 @@ The shared-flag pattern is the documented coordination mechanism — there is no - A standalone installer EXE (or installer mode inside the same EXE, gated by a `-install` command-line argument) runs elevated and calls [**Install**](ServiceManager#install) / [**Uninstall**](ServiceManager#uninstall) plus a one-time call to [**EventLog.Register**](../WinEventLogLib/EventLog#register). - The service-host EXE itself does not need elevation at run-time (the SCM launches it under whatever account the service is configured for). -- The control-panel / interactive UI does not need elevation either — it can use [**Services.LaunchService**](Services#launchservice) and [**Services.ControlService**](Services#controlservice) freely, as long as the user has the standard *Start* / *Stop* permissions on the relevant service (the default ACL grants this to **LocalSystem**, **Administrators**, and the running interactive user for *interactive* services). +- The control-panel / interactive UI does not need elevation either --- it can use [**Services.LaunchService**](Services#launchservice) and [**Services.ControlService**](Services#controlservice) freely, as long as the user has the standard *Start* / *Stop* permissions on the relevant service (the default ACL grants this to **LocalSystem**, **Administrators**, and the running interactive user for *interactive* services). -Calling [**Install**](ServiceManager#install) while running inside the twinBASIC IDE will fail with an SCM-access error — the IDE is rarely elevated. Either run the compiled EXE as administrator, or wrap the call in an `If App.IsInIDE() Then Err.Raise 5, , "Run the compiled EXE as administrator."` guard. +Calling [**Install**](ServiceManager#install) while running inside the twinBASIC IDE will fail with an SCM-access error --- the IDE is rarely elevated. Either run the compiled EXE as administrator, or wrap the call in an `If App.IsInIDE() Then Err.Raise 5, , "Run the compiled EXE as administrator."` guard. ## Classes and interface diff --git a/docs/Reference/tbIDE/AddIn.md b/docs/Reference/tbIDE/AddIn.md index ea7b7833..8a2ee975 100644 --- a/docs/Reference/tbIDE/AddIn.md +++ b/docs/Reference/tbIDE/AddIn.md @@ -8,7 +8,7 @@ has_toc: false # AddIn class {: .no_toc } -The contract every addin's main class must implement. One read-only property — [**Name**](#name) — that the IDE reads to label the addin in error messages, log lines, and (eventually) any addin-management UI. The IDE never creates an **AddIn** itself; the addin DLL constructs the object inside [`tbCreateCompilerAddin`](.#building-and-loading-an-addin) and returns it. +The contract every addin's main class must implement. One read-only property --- [**Name**](#name) --- that the IDE reads to label the addin in error messages, log lines, and any addin-management UI added later. The IDE never creates an **AddIn** itself; the addin DLL constructs the object inside [`tbCreateCompilerAddin`](.#building-and-loading-an-addin) and returns it. ```tb Private Class MyAddIn @@ -26,7 +26,7 @@ Private Class MyAddIn End Class ``` -The class implementing **AddIn** is also the natural place to hold every other `WithEvents` reference the addin uses ([**Host**](Host), each [**Button**](Button), each [**ToolWindow**](ToolWindow), an optional [**AddinTimer**](AddinTimer), …) — its lifetime is tied to the addin's loaded state. +The class implementing **AddIn** is also the natural place to hold every other `WithEvents` reference the addin uses ([**Host**](Host), each [**Button**](Button), each [**ToolWindow**](ToolWindow), an optional [**AddinTimer**](AddinTimer), …) --- its lifetime is tied to the addin's loaded state. ## Properties diff --git a/docs/Reference/tbIDE/AddinTimer.md b/docs/Reference/tbIDE/AddinTimer.md index 0656baf6..09dc793b 100644 --- a/docs/Reference/tbIDE/AddinTimer.md +++ b/docs/Reference/tbIDE/AddinTimer.md @@ -8,7 +8,7 @@ has_toc: false # AddinTimer class {: .no_toc } -A simple periodic-callback helper. **AddinTimer** is the **only user-instantiable class** in the package — every other CoClass is handed to the addin by the IDE; this one the addin creates with `New`. Internally it wraps the Win32 `SetTimer` / `KillTimer` pair against `hwnd = 0` and fires its [**Timer**](#timer) event from the IDE's UI thread. +A simple periodic-callback helper. **AddinTimer** is the **only user-instantiable class** in the package --- every other CoClass is supplied to the addin by the IDE; this one the addin creates with `New`. Internally it wraps the Win32 `SetTimer` / `KillTimer` pair against `hwnd = 0` and fires its [**Timer**](#timer) event from the IDE's UI thread. ```tb Private WithEvents Timer As AddinTimer @@ -24,9 +24,9 @@ Private Sub Timer_Timer() End Sub ``` -Stop the timer by setting [**Enabled**](#enabled) = **False**, or simply by dropping the last reference — `Class_Terminate` cancels the underlying Win32 timer automatically. Both [**Enabled**](#enabled) and [**Interval**](#interval) are live: assigning to either re-arms the underlying Win32 timer using the new values, so changing the interval while the timer is running takes effect immediately. +Stop the timer by setting [**Enabled**](#enabled) = **False**, or simply by dropping the last reference --- `Class_Terminate` cancels the underlying Win32 timer automatically. Both [**Enabled**](#enabled) and [**Interval**](#interval) are live: assigning to either re-arms the underlying Win32 timer using the new values, so changing the interval while the timer is running takes effect immediately. -Nothing in the package *requires* this helper — a direct `SetTimer` / `KillTimer` pair (or any other periodic mechanism) works just as well; sample 15's dwell-time pattern uses raw Win32 calls. Use **AddinTimer** when the convenience of an event-bound class is preferable to managing the Win32 plumbing yourself. +Nothing in the package *requires* this helper --- a direct `SetTimer` / `KillTimer` pair (or any other periodic mechanism) works just as well; sample 15's dwell-time pattern uses raw Win32 calls. **AddinTimer** is the right choice when the convenience of an event-bound class is preferable to managing the Win32 plumbing directly. * TOC {:toc} @@ -56,4 +56,4 @@ Fires every [**Interval**](#interval) milliseconds while [**Enabled**](#enabled) Syntax: *timer*_**Timer**() -Long-running work inside the handler will block the UI thread until it returns — keep the handler short and offload heavy work to a background mechanism if needed. +Long-running work inside the handler will block the UI thread until it returns --- keep the handler short and offload heavy work to a background mechanism when needed. diff --git a/docs/Reference/tbIDE/Button.md b/docs/Reference/tbIDE/Button.md index 311ae4a0..457ba445 100644 --- a/docs/Reference/tbIDE/Button.md +++ b/docs/Reference/tbIDE/Button.md @@ -8,7 +8,7 @@ has_toc: false # Button class {: .no_toc } -An addin-created toolbar button. Returned by [**Toolbar.AddButton**](Toolbar#addbutton); hold it via `WithEvents` to receive [**OnClick**](#onclick) notifications. The button's [**Caption**](#caption) and [**IconData**](#icondata) are mutable at run time — change the caption to reflect a state, or swap the icon to reflect a toggle. +An addin-created toolbar button. Returned by [**Toolbar.AddButton**](Toolbar#addbutton); held via `WithEvents` to receive [**OnClick**](#onclick) notifications. The button's [**Caption**](#caption) and [**IconData**](#icondata) are mutable at run time --- the caption can reflect a state, or the icon can reflect a toggle. ```tb Private WithEvents RefreshButton As Button @@ -38,7 +38,7 @@ Syntax: *button*.**Caption** [ = *value* ] ### IconData {: .no_toc } -The icon graphic as a **Byte()** array — typically the bytes of an embedded PNG / ICO resource. Pass **Empty** to remove the icon and fall back to showing the [**Caption**](#caption) inline. Read / write. +The icon graphic as a **Byte()** array --- typically the bytes of an embedded PNG / ICO resource. Pass **Empty** to remove the icon and fall back to showing the [**Caption**](#caption) inline. Read / write. Syntax: *button*.**IconData** [ = *bytes* ] diff --git a/docs/Reference/tbIDE/CodeEditor.md b/docs/Reference/tbIDE/CodeEditor.md index 68ee7b07..1a0aaffb 100644 --- a/docs/Reference/tbIDE/CodeEditor.md +++ b/docs/Reference/tbIDE/CodeEditor.md @@ -8,9 +8,9 @@ has_toc: false # CodeEditor class {: .no_toc } -A code-pane editor — the specific [**Editor**](Editor) kind the IDE returns when the active editor is a source-code pane. Adds selection / text / scrolling control, an inline-widget API, and a raw passthrough into the underlying Monaco editor that powers code panes. +A code-pane editor --- the specific [**Editor**](Editor) kind the IDE returns when the active editor is a source-code pane. Adds selection / text / scrolling control, an inline-widget API, and a raw passthrough into the underlying Monaco editor that powers code panes. -Reach a **CodeEditor** by casting an [**Editor**](Editor) — `Host.ActiveEditors(0)` returns an [**Editor**](Editor) that, for a code pane, is also a **CodeEditor**: +A **CodeEditor** is reached by casting an [**Editor**](Editor) --- `Host.ActiveEditors(0)` returns an [**Editor**](Editor) that, for a code pane, is also a **CodeEditor**: ```tb If TypeOf Host.ActiveEditors(0) Is CodeEditor Then @@ -40,14 +40,14 @@ The full text of the code pane. Reading returns the entire document; assigning r Syntax: *codeEditor*.**Text** [ = *value* ] -Replacing the entire text is heavyweight — both for the editor (it has to rebuild every Monaco data structure) and for the user (the undo stack collapses to a single step). For surgical edits, prefer [**SelectedText**](#selectedtext) over [**Text**](#text). +Replacing the entire text is heavy --- both for the editor (it has to rebuild every Monaco data structure) and for the user (the undo stack collapses to a single step). For targeted edits, prefer [**SelectedText**](#selectedtext) over [**Text**](#text). ## Methods ### AddMonacoWidget {: .no_toc } -Attaches an inline HTML overlay to a specific position in the editor — Monaco's *content widget* mechanism, exposed as a familiar [**HtmlElement**](HtmlElement). +Attaches an inline HTML overlay to a specific position in the editor --- Monaco's *content widget* mechanism, exposed as a familiar [**HtmlElement**](HtmlElement). Syntax: *codeEditor*.**AddMonacoWidget**( *LineNumber*, *ColumnNumber*, *Html* [, *Css* ] ) **As** [**HtmlElement**](HtmlElement) @@ -63,12 +63,12 @@ Syntax: *codeEditor*.**AddMonacoWidget**( *LineNumber*, *ColumnNumber*, *Html* [ *Css* : *optional* Per-widget CSS as a **String**. Use this for widget-local styles that should not bleed into the rest of the code pane. -The returned [**HtmlElement**](HtmlElement) has the same dynamic-DOM properties as elements inside a tool window — see [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview. Use [**HtmlElement.Remove**](HtmlElement#remove) on the returned object to take the widget down. +The returned [**HtmlElement**](HtmlElement) has the same dynamic-DOM properties as elements inside a tool window --- see [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview. Call [**HtmlElement.Remove**](HtmlElement#remove) on the returned object to remove the widget. ### ExecuteMonacoCommand {: .no_toc } -Sends a direct command to the underlying Monaco editor instance. Useful for triggering Monaco's built-in commands (Find, Go-to-Line, Format, Toggle Comment, …) without writing equivalent twinBASIC code. +Sends a direct command to the underlying Monaco editor instance. Useful for triggering Monaco's built-in commands (Find, Go-to-Line, Format, Toggle Comment, …) without writing the equivalent twinBASIC code. Syntax: *codeEditor*.**ExecuteMonacoCommand** *Command* [, *Arg1*, *Arg2*, … ] @@ -78,7 +78,7 @@ Syntax: *codeEditor*.**ExecuteMonacoCommand** *Command* [, *Arg1*, *Arg2*, … ] *Args* : *optional* A **ParamArray** of command-specific arguments. **Variant**. Forwarded verbatim to Monaco. -The reference does not enumerate Monaco's command set — refer to Monaco's documentation for the full list and their per-command argument shapes. +The reference does not enumerate Monaco's command set --- refer to Monaco's documentation for the full list and their per-command argument shapes. ```tb codeEditor.ExecuteMonacoCommand "actions.find" ' open Find widget @@ -88,12 +88,12 @@ codeEditor.ExecuteMonacoCommand "closeFindWidget" ' close it ### GetSelectionInfo {: .no_toc } -Reports the start and end positions of the current selection. All four output arguments are filled even when nothing is selected — start and end positions then coincide on the caret's current position. +Reports the start and end positions of the current selection. All four output arguments are filled even when nothing is selected --- start and end positions then coincide on the caret's current position. Syntax: *codeEditor*.**GetSelectionInfo** *StartLine*, *StartColumn*, *EndLine*, *EndColumn* *StartLine*, *StartColumn*, *EndLine*, *EndColumn* -: **ByRef Long** — output parameters, all one-based. +: **ByRef Long** --- output parameters, all one-based. ### RevealRange {: .no_toc } @@ -106,7 +106,7 @@ Syntax: *codeEditor*.**RevealRange** *StartLine*, *StartColumn*, *EndLine*, *End : *required* The range to reveal. **Long**, one-based. *SmoothScroll* -: *optional* **Boolean** — animate the scroll. Default **True**. +: *optional* **Boolean** --- animate the scroll. Default **True**. *Area* : *optional* A [**RevealArea**](#revealarea) value controlling where in the viewport the range lands. Default [**Any**](#RevealArea_Any). @@ -131,6 +131,6 @@ Controls where in the viewport [**RevealRange**](#revealrange) places the reques | **Any**{: #RevealArea_Any } | 0 | Scroll vertically or horizontally only as much as necessary to make the range visible. Cheapest scroll. | | **Top**{: #RevealArea_Top } | 1 | Scroll so the range sits at the top of the viewport. | | **Center**{: #RevealArea_Center } | 2 | Scroll so the range is vertically centred in the viewport. | -| **CenterIfNotVisible**{: #RevealArea_CenterIfNotVisible } | 3 | Centre vertically, but only if the range currently lies outside the viewport — otherwise do nothing. | -| **NearTop**{: #RevealArea_NearTop } | 4 | Scroll so the range sits close to the top, with some context above — Monaco's "view a code definition" preset. | +| **CenterIfNotVisible**{: #RevealArea_CenterIfNotVisible } | 3 | Centre vertically, but only if the range currently lies outside the viewport --- otherwise do nothing. | +| **NearTop**{: #RevealArea_NearTop } | 4 | Scroll so the range sits close to the top, with some context above --- Monaco's "view a code definition" preset. | | **NearTopIfNotVisible**{: #RevealArea_NearTopIfNotVisible } | 5 | Same as [**NearTop**](#RevealArea_NearTop), but only if the range is currently outside the viewport. | diff --git a/docs/Reference/tbIDE/DebugConsole.md b/docs/Reference/tbIDE/DebugConsole.md index 92ce9553..1089c791 100644 --- a/docs/Reference/tbIDE/DebugConsole.md +++ b/docs/Reference/tbIDE/DebugConsole.md @@ -8,7 +8,7 @@ has_toc: false # DebugConsole class {: .no_toc } -The IDE's DEBUG CONSOLE pane — reached through [**Host.DebugConsole**](Host#debugconsole). The canonical place for an addin to write diagnostic and log output. +The IDE's DEBUG CONSOLE pane --- reached through [**Host.DebugConsole**](Host#debugconsole). The canonical place for an addin to write diagnostic and log output. ```tb With Host.DebugConsole @@ -18,7 +18,7 @@ With Host.DebugConsole End With ``` -The pane is shared across the IDE's own output and every addin's output — prefix log lines with an addin tag (e.g. `"[MyAddIn] "`) so users can tell sources apart. +The pane is shared across the IDE's own output and every addin's output --- prefix log lines with an addin tag (e.g. `"[MyAddIn] "`) so users can distinguish the sources. * TOC {:toc} @@ -43,7 +43,7 @@ Syntax: *debugConsole*.**PrintText** *Prompt* [, *ColorRGB* ] : *required* The text to print. **String**. *ColorRGB* -: *optional* The text colour as an RGB **Long** (use the `RGB(r, g, b)` function to construct one). Default 0 — the IDE's default DEBUG CONSOLE foreground colour. +: *optional* The text colour as an RGB **Long** (use the `RGB(r, g, b)` function to construct one). Default 0 --- the IDE's default DEBUG CONSOLE foreground colour. ```tb Host.DebugConsole.PrintText "Operation completed" ' default colour @@ -53,6 +53,6 @@ Host.DebugConsole.PrintText "Warning: something looks off", RGB(255, 128, 0) ' o ### SetFocus {: .no_toc } -Gives keyboard focus to the DEBUG CONSOLE's text-entry point — equivalent to the user clicking into the console. +Gives keyboard focus to the DEBUG CONSOLE's text-entry point --- equivalent to the user clicking into the console. Syntax: *debugConsole*.**SetFocus** diff --git a/docs/Reference/tbIDE/Editor.md b/docs/Reference/tbIDE/Editor.md index 25de8d2b..1a7b51f1 100644 --- a/docs/Reference/tbIDE/Editor.md +++ b/docs/Reference/tbIDE/Editor.md @@ -8,13 +8,12 @@ has_toc: false # Editor class {: .no_toc } -The base interface every IDE editor presents. **Editor** itself exposes only the universal members — [**Path**](#path), [**Type**](#type), [**SetFocus**](#setfocus), [**Close**](#close), [**Save**](#save), [**IsDirty**](#isdirty) — and an instance returned from [**Editors.Item**](Editors#item) or the [**Host.OnChangedActiveEditor**](Host#onchangedactiveeditor) event is normally a *specific* editor kind (e.g. [**CodeEditor**](CodeEditor) for code panes), reachable by casting. +The base interface every IDE editor presents. **Editor** itself exposes only the universal members --- [**Path**](#path), [**Type**](#type), [**SetFocus**](#setfocus), [**Close**](#close), [**Save**](#save), [**IsDirty**](#isdirty) --- and an instance returned from [**Editors.Item**](Editors#item) or the [**Host.OnChangedActiveEditor**](Host#onchangedactiveeditor) event is normally a *specific* editor kind (e.g. [**CodeEditor**](CodeEditor) for code panes), reachable by casting. ## Castability {: #castability } -> [!NOTE] -> An **Editor** returned by the IDE is castable to the specific editor kind for the underlying pane. For a code pane the cast target is [**CodeEditor**](CodeEditor); other editor kinds may be added in future IDE versions and will follow the same pattern. +An **Editor** returned by the IDE is castable to the specific editor kind for the underlying pane. For a code pane the cast target is [**CodeEditor**](CodeEditor); other editor kinds may be added in future IDE versions and will follow the same pattern. Use `TypeOf` to test before casting: @@ -27,7 +26,7 @@ If Host.ActiveEditors.Count > 0 Then End If ``` -Cast unconditionally only when the source — e.g. an [**OnChangedActiveEditor**](Host#onchangedactiveeditor) handler for a known editor kind — guarantees the underlying type. +Cast unconditionally only when the source --- e.g. an [**OnChangedActiveEditor**](Host#onchangedactiveeditor) handler for a known editor kind --- guarantees the underlying type. * TOC {:toc} @@ -42,12 +41,12 @@ Cast unconditionally only when the source — e.g. an [**OnChangedActiveEditor** ### Path {: .no_toc } -The internal virtual-FS path of the file the editor is displaying — e.g. `"twinbasic:/Sources/MainModule.twin"`. **String**, read-only. Resolves through [**FileSystem.ResolvePath**](FileSystem#resolvepath). +The internal virtual-FS path of the file the editor is displaying --- e.g. `"twinbasic:/Sources/MainModule.twin"`. **String**, read-only. Resolves through [**FileSystem.ResolvePath**](FileSystem#resolvepath). ### Type {: .no_toc } -A short string identifying the editor kind — e.g. `"CodeEditor"` for a code pane. **String**, read-only. Useful for diagnostic log lines; for capability dispatch prefer `TypeOf` over comparing this string. +A short string identifying the editor kind --- e.g. `"CodeEditor"` for a code pane. **String**, read-only. Useful for diagnostic log lines; for capability dispatch prefer `TypeOf` over comparing this string. ## Methods diff --git a/docs/Reference/tbIDE/Editors.md b/docs/Reference/tbIDE/Editors.md index 07e4b1f4..f799c63b 100644 --- a/docs/Reference/tbIDE/Editors.md +++ b/docs/Reference/tbIDE/Editors.md @@ -8,7 +8,7 @@ has_toc: false # Editors class {: .no_toc } -The collection of editors active in the IDE — accessible through [**Host.ActiveEditors**](Host#activeeditors). The IDE currently exposes exactly one active editor at a time, but the collection interface allows future versions to expose more. The most common operations are `Host.ActiveEditors(0)` (the active editor) and [**Open**](#open) (jump to a file at a given line / column). +The collection of editors active in the IDE --- accessible through [**Host.ActiveEditors**](Host#activeeditors). The IDE currently exposes exactly one active editor at a time, but the collection interface allows future versions to expose more. The most common operations are `Host.ActiveEditors(0)` (the active editor) and [**Open**](#open) (jump to a file at a given line / column). ```tb ' Read the selection out of the currently-focused code pane: @@ -37,14 +37,14 @@ Number of editors currently active. **Long**, read-only. Currently always **0** ### Item {: .no_toc } -Indexed access to the editor collection. **DefaultMember** — so `Host.ActiveEditors(0)` is equivalent to `Host.ActiveEditors.Item(0)`. +Indexed access to the editor collection. **DefaultMember** --- so `Host.ActiveEditors(0)` is equivalent to `Host.ActiveEditors.Item(0)`. Syntax: *editors*( *Index* ) **As** [**Editor**](Editor) *Index* : A zero-based **Variant** index. Currently `0` is the only valid value when an editor is open. -The returned object is an [**Editor**](Editor) but is usually castable to a more specific kind (e.g. [**CodeEditor**](CodeEditor) for a code pane) — see [Editor castability](Editor#castability). +The returned object is an [**Editor**](Editor) but is usually castable to a more specific kind (e.g. [**CodeEditor**](CodeEditor) for a code pane) --- see [Editor castability](Editor#castability). ## Methods @@ -59,7 +59,7 @@ Syntax: *editors*.**Open** *Path* [, *LineNumber* ] [, *ColumnNumber* ] [, *Opti : *required* The virtual-FS path of the file to open. **String**. Typically starts with `"twinbasic:/"`; the value returned by [**FileSystemItem.Path**](FileSystemItem#path) or [**Editor.Path**](Editor#path) is always a valid argument. *LineNumber* -: *optional* One-based line number to navigate to. **Long**. Default **0** (no navigation — open the file at its remembered cursor position). +: *optional* One-based line number to navigate to. **Long**. Default **0** (no navigation --- open the file at its remembered cursor position). *ColumnNumber* : *optional* One-based column number on the requested line. **Long**. Default **0** (column 1). @@ -77,7 +77,7 @@ Host.ActiveEditors.Item(0).SetFocus ## EditorOpenOptions {: #editoropenoptions } -A flags enum declared inline on the **Editors** interface; consumed by [**Open**](#open). Currently a single-value placeholder — additional flags may appear in later IDE versions. +A flags enum declared inline on the **Editors** interface; consumed by [**Open**](#open). Currently a single-value placeholder --- additional flags may appear in later IDE versions. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/tbIDE/File.md b/docs/Reference/tbIDE/File.md index 084da422..5b100edc 100644 --- a/docs/Reference/tbIDE/File.md +++ b/docs/Reference/tbIDE/File.md @@ -8,9 +8,9 @@ has_toc: false # File class {: .no_toc } -A file inside the IDE's virtual file system. Extends [**FileSystemItem**](FileSystemItem) with content accessors — raw bytes via [**Data**](#data) / [**DataLen**](#datalen), a decoded text view via [**Text**](#text), a text-with-options accessor via [**ReadText**](#readtext), plus an [**IsDirty**](#isdirty) flag indicating unsaved changes. +A file inside the IDE's virtual file system. Extends [**FileSystemItem**](FileSystemItem) with content accessors --- raw bytes via [**Data**](#data) / [**DataLen**](#datalen), a decoded text view via [**Text**](#text), a text-with-options accessor via [**ReadText**](#readtext), plus an [**IsDirty**](#isdirty) flag indicating unsaved changes. -A **File** also inherits the universal [**FileSystemItem**](FileSystemItem) members — [**Name**](FileSystemItem#name), [**Path**](FileSystemItem#path), [**Type**](FileSystemItem#type), [**Parent**](FileSystemItem#parent). The [**Type**](FileSystemItem#type) value tells the addin what encoding the file is in and whether the text accessors are applicable; see [**FileSystemItemType**](FileSystemItem#filesystemitemtype) for the list. +A **File** also inherits the universal [**FileSystemItem**](FileSystemItem) members --- [**Name**](FileSystemItem#name), [**Path**](FileSystemItem#path), [**Type**](FileSystemItem#type), [**Parent**](FileSystemItem#parent). The [**Type**](FileSystemItem#type) value tells the addin what encoding the file is in and whether the text accessors are applicable; see [**FileSystemItemType**](FileSystemItem#filesystemitemtype) for the list. ```tb ' Read every source file's text: @@ -40,14 +40,14 @@ End Sub ### Data {: .no_toc } -The raw on-disk bytes of the file. Read returns a **Byte()** of the current content. The `Property Let` form is declared but marked `[Unimplemented]` — writes are not currently supported. +The raw on-disk bytes of the file. Read returns a **Byte()** of the current content. The `Property Let` form is declared but marked `[Unimplemented]` --- writes are not currently supported. Syntax: *file*.**Data** **As Byte()** ### DataLen {: .no_toc } -The length in bytes of the current content — equivalent to `UBound(file.Data) + 1` but without copying the array. **LongLong**, read-only. Useful for size displays and quick file-size comparisons. +The length in bytes of the current content --- equivalent to `UBound(file.Data) + 1` but without copying the array. **LongLong**, read-only. Useful for size displays and quick file-size comparisons. ### IsDirty {: .no_toc } @@ -59,7 +59,7 @@ The length in bytes of the current content — equivalent to `UBound(file.Data) The file's content decoded as a **String**, with the appropriate UTF-16 conversion for the underlying encoding ([**FileTWIN**](FileSystemItem#FileSystemItemType_FileTWIN) → UTF-8 → UTF-16; [**FileBAS**](FileSystemItem#FileSystemItemType_FileBAS) / [**FileCLS**](FileSystemItem#FileSystemItemType_FileCLS) → System-ANSI → UTF-16; [**FileVIRTUALDOC**](FileSystemItem#FileSystemItemType_FileVIRTUALDOC) / [**FileUIDESIGNER**](FileSystemItem#FileSystemItemType_FileUIDESIGNER) / [**FileJSON**](FileSystemItem#FileSystemItemType_FileJSON) → UTF-8 → UTF-16). Calling on a [**FileOTHER**](FileSystemItem#FileSystemItemType_FileOTHER) is not supported. -Read returns the decoded text. The `Property Let` form is declared but marked `[Unimplemented]` — writes are not currently supported. +Read returns the decoded text. The `Property Let` form is declared but marked `[Unimplemented]` --- writes are not currently supported. Syntax: *file*.**Text** **As String** @@ -68,7 +68,7 @@ Syntax: *file*.**Text** **As String** ### ReadText {: .no_toc } -A text-with-options accessor — the [**Text**](#text) view, but with optional transforms applied. Currently the only option strips comments and replaces them with whitespace; future versions may add more. +A text-with-options accessor --- the [**Text**](#text) view, but with optional transforms applied. Currently the only option strips comments and replaces them with whitespace; future versions may add more. Syntax: *file*.**ReadText**( *Options* ) **As String** @@ -77,12 +77,12 @@ Syntax: *file*.**ReadText**( *Options* ) **As String** Valid on every text file kind ([**FileTWIN**](FileSystemItem#FileSystemItemType_FileTWIN), [**FileBAS**](FileSystemItem#FileSystemItemType_FileBAS), [**FileCLS**](FileSystemItem#FileSystemItemType_FileCLS), [**FileVIRTUALDOC**](FileSystemItem#FileSystemItemType_FileVIRTUALDOC), [**FileUIDESIGNER**](FileSystemItem#FileSystemItemType_FileUIDESIGNER), [**FileJSON**](FileSystemItem#FileSystemItemType_FileJSON)); calling on a [**FileOTHER**](FileSystemItem#FileSystemItemType_FileOTHER) is not supported. -The line and column structure of the returned text matches the original file — `CommentsToWhitespace` only blanks the comment characters, never moves the surrounding code. That makes the option suitable for indexers / search tools that need both "find non-comment occurrences" and "report the position in the original file". +The line and column structure of the returned text matches the original file --- `CommentsToWhitespace` only blanks the comment characters, never moves the surrounding code. The option is therefore suitable for indexers / search tools that need both "find non-comment occurrences" and "report the position in the original file". ## ReadTextFlags {: #readtextflags } -The option flags consumed by [**ReadText**](#readtext). A `[Flags]`-tagged enum — values can be `Or`'ed in future versions. +The option flags consumed by [**ReadText**](#readtext). A `[Flags]`-tagged enum --- values can be `Or`'ed in future versions. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/tbIDE/FileSystem.md b/docs/Reference/tbIDE/FileSystem.md index 6a7c8164..41c44e88 100644 --- a/docs/Reference/tbIDE/FileSystem.md +++ b/docs/Reference/tbIDE/FileSystem.md @@ -8,7 +8,7 @@ has_toc: false # FileSystem class {: .no_toc } -A handle into the IDE's virtual file system — the abstraction that lets an addin walk and read source files without touching the on-disk paths. Reach the **FileSystem** through [**Host.FileSystem**](Host#filesystem). For the more common per-project case, [**Host.CurrentProject.RootFolder**](Project#rootfolder) is also a [**Folder**](Folder) and is usually the right entry point — the global **FileSystem** matters when an addin needs to address files outside the project's own root. +A handle into the IDE's virtual file system --- the abstraction that lets an addin traverse and read source files without touching the on-disk paths. The **FileSystem** is reached through [**Host.FileSystem**](Host#filesystem). For the more common per-project case, [**Host.CurrentProject.RootFolder**](Project#rootfolder) is also a [**Folder**](Folder) and is usually the right entry point --- the global **FileSystem** matters when an addin needs to address files outside the project's own root. ```tb Dim item As FileSystemItem = Host.FileSystem.ResolvePath("twinbasic:/Sources/MainModule.twin") @@ -26,11 +26,11 @@ The root of the virtual file system. **As** [**Folder**](Folder). Read-only. ### ResolvePath {: .no_toc } -Looks up the [**FileSystemItem**](FileSystemItem) at a given path. The path uses the IDE's `twinbasic:/` URI scheme — the same scheme that [**FileSystemItem.Path**](FileSystemItem#path) and [**Editor.Path**](Editor#path) return. +Looks up the [**FileSystemItem**](FileSystemItem) at a given path. The path uses the IDE's `twinbasic:/` URI scheme --- the same scheme that [**FileSystemItem.Path**](FileSystemItem#path) and [**Editor.Path**](Editor#path) return. Syntax: *fileSystem*.**ResolvePath**( *Path* ) **As** [**FileSystemItem**](FileSystemItem) *Path* : *required* A virtual-FS path. **String**. Must include the `twinbasic:/` prefix. -The returned object is a [**FileSystemItem**](FileSystemItem) but is usually castable to its specific kind — a [**File**](File) for regular files, a [**Folder**](Folder) for folders. Test with `TypeOf … Is Folder` before casting if the path's kind is not known statically. +The returned object is a [**FileSystemItem**](FileSystemItem) but is usually castable to its specific kind --- a [**File**](File) for regular files, a [**Folder**](Folder) for folders. Test with `TypeOf … Is Folder` before casting when the path's kind is not known statically. diff --git a/docs/Reference/tbIDE/FileSystemItem.md b/docs/Reference/tbIDE/FileSystemItem.md index 329b33ee..657a72ab 100644 --- a/docs/Reference/tbIDE/FileSystemItem.md +++ b/docs/Reference/tbIDE/FileSystemItem.md @@ -8,7 +8,7 @@ has_toc: false # FileSystemItem class {: .no_toc } -The base interface for everything inside the IDE's virtual file system. Both [**File**](File) and [**Folder**](Folder) extend **FileSystemItem** and inherit its four universal members ([**Name**](#name), [**Path**](#path), [**Type**](#type), [**Parent**](#parent)). An item returned from a [**Folder**](Folder) enumeration or from [**FileSystem.ResolvePath**](FileSystem#resolvepath) is normally castable to its specific kind — use the [**Type**](#type) property or `TypeOf` to discriminate. +The base interface for everything inside the IDE's virtual file system. Both [**File**](File) and [**Folder**](Folder) extend **FileSystemItem** and inherit its four universal members ([**Name**](#name), [**Path**](#path), [**Type**](#type), [**Parent**](#parent)). An item returned from a [**Folder**](Folder) enumeration or from [**FileSystem.ResolvePath**](FileSystem#resolvepath) is normally castable to its specific kind --- the [**Type**](#type) property or `TypeOf` discriminates between them. ```tb Dim item As FileSystemItem @@ -40,7 +40,7 @@ The folder that contains this item. **As** [**Folder**](Folder). Read-only. The ### Path {: .no_toc } -The item's full virtual-FS path — e.g. `"twinbasic:/Sources/MainModule.twin"`. **String**, read-only. Suitable as the *Path* argument to [**Editors.Open**](Editors#open) and [**FileSystem.ResolvePath**](FileSystem#resolvepath). +The item's full virtual-FS path --- e.g. `"twinbasic:/Sources/MainModule.twin"`. **String**, read-only. Suitable as the *Path* argument to [**Editors.Open**](Editors#open) and [**FileSystem.ResolvePath**](FileSystem#resolvepath). ### Type {: .no_toc } @@ -55,10 +55,10 @@ A type discriminator returned by [**Type**](#type). | Constant | Value | Description | |----------|-------|-------------| | **Folder**{: #FileSystemItemType_Folder } | 0 | A folder. | -| **FileVIRTUALDOC**{: #FileSystemItemType_FileVIRTUALDOC } | 1 | A read-only virtual document — the placeholder content the IDE renders for unrecognised file types. Unicode (UTF-16). | +| **FileVIRTUALDOC**{: #FileSystemItemType_FileVIRTUALDOC } | 1 | A read-only virtual document --- the placeholder content the IDE renders for unrecognised file types. Unicode (UTF-16). | | **FileOTHER**{: #FileSystemItemType_FileOTHER } | 2 | A file the IDE recognises as binary or whose encoding it cannot determine. [**File.ReadText**](File#readtext) is not supported on this kind. | | **FileTWIN**{: #FileSystemItemType_FileTWIN } | 3 | A twinBASIC source file (`.twin`). UTF-8 encoded on disk. | | **FileBAS**{: #FileSystemItemType_FileBAS } | 4 | A VB6-compatible standard module file (`.bas`). System ANSI encoded on disk. | | **FileCLS**{: #FileSystemItemType_FileCLS } | 5 | A VB6-compatible class module file (`.cls`). System ANSI encoded on disk. | | **FileUIDESIGNER**{: #FileSystemItemType_FileUIDESIGNER } | 6 | A UI-designer surface for a Form, expressed as JSON. UTF-8 encoded. | -| **FileJSON**{: #FileSystemItemType_FileJSON } | 7 | A JSON file — typically the project's `Settings` or other JSON project data. UTF-8 encoded. | +| **FileJSON**{: #FileSystemItemType_FileJSON } | 7 | A JSON file --- typically the project's `Settings` or other JSON project data. UTF-8 encoded. | diff --git a/docs/Reference/tbIDE/Folder.md b/docs/Reference/tbIDE/Folder.md index ff582761..e6be368c 100644 --- a/docs/Reference/tbIDE/Folder.md +++ b/docs/Reference/tbIDE/Folder.md @@ -8,9 +8,9 @@ has_toc: false # Folder class {: .no_toc } -A folder inside the IDE's virtual file system. Extends [**FileSystemItem**](FileSystemItem) with child-enumeration capability — [**Count**](#count), [**Item**](#item), and standard **For Each** iteration that yields each child as a [**FileSystemItem**](FileSystemItem) (use `TypeOf` to discriminate folders from files). +A folder inside the IDE's virtual file system. Extends [**FileSystemItem**](FileSystemItem) with child-enumeration capability --- [**Count**](#count), [**Item**](#item), and standard **For Each** iteration that yields each child as a [**FileSystemItem**](FileSystemItem) (use `TypeOf` to discriminate folders from files). -A **Folder** also inherits the universal [**FileSystemItem**](FileSystemItem) members — [**Name**](FileSystemItem#name), [**Path**](FileSystemItem#path), [**Type**](FileSystemItem#type), [**Parent**](FileSystemItem#parent). The most common entry point is [**Host.CurrentProject.RootFolder**](Project#rootfolder), and the most common operation is a **For Each** recursive walk. +A **Folder** also inherits the universal [**FileSystemItem**](FileSystemItem) members --- [**Name**](FileSystemItem#name), [**Path**](FileSystemItem#path), [**Type**](FileSystemItem#type), [**Parent**](FileSystemItem#parent). The most common entry point is [**Host.CurrentProject.RootFolder**](Project#rootfolder), and the most common operation is a **For Each** recursive traversal. ```tb Private Sub WalkAllFiles(ByVal folder As Folder) @@ -27,7 +27,7 @@ End Sub ``` > [!IMPORTANT] -> The twinBASIC IDE is multi-threaded. The same folder can change while an addin holds a reference to it — files arrive, files disappear, indices renumber. The supported way to walk a folder is **For Each**; index-based access through [**Count**](#count) / [**Item**](#item) races against the IDE's own threads and will sometimes miss or duplicate entries. Always prefer **For Each** for traversal. +> The twinBASIC IDE is multi-threaded. The same folder can change while an addin holds a reference to it --- files arrive, files disappear, indices renumber. The supported way to traverse a folder is **For Each**; index-based access through [**Count**](#count) / [**Item**](#item) races against the IDE's own threads and will sometimes miss or duplicate entries. Always prefer **For Each** for traversal. * TOC {:toc} @@ -40,14 +40,14 @@ End Sub Number of items currently in the folder. **Long**, read-only. > [!IMPORTANT] -> The value can change between two reads — the IDE is multi-threaded. **Do not** use this as a `For i = 0 To Count - 1` loop bound; use **For Each** instead. +> The value can change between two reads --- the IDE is multi-threaded. **Do not** use this as a `For i = 0 To Count - 1` loop bound; use **For Each** instead. ### IsPackagesFolder {: .no_toc } **True** if this folder is the project's special `Packages` folder (the one that contains every referenced package's source tree). **Boolean**, read-only. -Useful when walking the project for source-search purposes — an addin that searches user code will usually want to *skip* the package sources: +Useful when traversing the project for source-search purposes --- an addin that searches user code will usually want to *skip* the package sources: ```tb If folder.IsPackagesFolder And Not searchInsidePackages Then Exit Sub @@ -56,12 +56,12 @@ If folder.IsPackagesFolder And Not searchInsidePackages Then Exit Sub ### Item {: .no_toc } -Indexed or named access to a child item. **DefaultMember** — so `folder(0)` is equivalent to `folder.Item(0)`, and `folder("MainModule.twin")` is equivalent to `folder.Item("MainModule.twin")`. +Indexed or named access to a child item. **DefaultMember** --- so `folder(0)` is equivalent to `folder.Item(0)`, and `folder("MainModule.twin")` is equivalent to `folder.Item("MainModule.twin")`. Syntax: *folder*( *IndexOrName* ) **As** [**FileSystemItem**](FileSystemItem) *IndexOrName* -: A **Variant** — either a zero-based **Long** index or a **String** child name. +: A **Variant** --- either a zero-based **Long** index or a **String** child name. > [!IMPORTANT] -> Numeric indices race against the IDE's own threads — the item at index `n` may have changed identity by the time the call returns. Named lookup is safer; **For Each** traversal is safer still. +> Numeric indices race against the IDE's own threads --- the item at index `n` may have changed identity by the time the call returns. Named lookup is safer; **For Each** traversal is safer still. diff --git a/docs/Reference/tbIDE/Host.md b/docs/Reference/tbIDE/Host.md index 9469f4a7..6dbde7d6 100644 --- a/docs/Reference/tbIDE/Host.md +++ b/docs/Reference/tbIDE/Host.md @@ -8,7 +8,7 @@ has_toc: false # Host class {: .no_toc } -The root API the IDE passes to every addin. The DLL receives a **Host** as the argument to its [`tbCreateCompilerAddin`](.#building-and-loading-an-addin) factory; the addin holds onto that reference for its lifetime and reaches every other capability through it — the currently-loaded [**CurrentProject**](#currentproject), the [**ActiveEditors**](#activeeditors), the [**Toolbars**](#toolbars) for adding buttons, the [**ToolWindows**](#toolwindows) for adding HTML-rendered panels, the [**DebugConsole**](#debugconsole) for log output, the virtual [**FileSystem**](#filesystem), the [**KeyboardShortcuts**](#keyboardshortcuts) registry, the [**Themes**](#themes) state, plus the dialog helpers [**ShowMessageBox**](#showmessagebox) / [**ShowNotification**](#shownotification). +The root API the IDE passes to every addin. The DLL receives a **Host** as the argument to its [`tbCreateCompilerAddin`](.#building-and-loading-an-addin) factory; the addin retains that reference for its lifetime and reaches every other capability through it --- the currently-loaded [**CurrentProject**](#currentproject), the [**ActiveEditors**](#activeeditors), the [**Toolbars**](#toolbars) for adding buttons, the [**ToolWindows**](#toolwindows) for adding HTML-rendered panels, the [**DebugConsole**](#debugconsole) for log output, the virtual [**FileSystem**](#filesystem), the [**KeyboardShortcuts**](#keyboardshortcuts) registry, the [**Themes**](#themes) state, plus the dialog helpers [**ShowMessageBox**](#showmessagebox) / [**ShowNotification**](#shownotification). Typically held via `WithEvents` so the addin can subscribe to lifecycle events: @@ -27,7 +27,7 @@ Private Sub Host_OnProjectLoaded() End Sub ``` -Almost every meaningful addin builds its toolbar buttons and tool windows inside the [**OnProjectLoaded**](#onprojectloaded) handler — that is the first moment the IDE is fully ready to accept extensibility commands. +Almost every meaningful addin builds its toolbar buttons and tool windows inside the [**OnProjectLoaded**](#onprojectloaded) handler --- that is the first moment the IDE is fully ready to accept extensibility commands. * TOC {:toc} @@ -37,7 +37,7 @@ Almost every meaningful addin builds its toolbar buttons and tool windows inside ### ActiveEditors {: .no_toc } -The collection of editors currently open in the IDE. Use `Host.ActiveEditors(0)` for the active one — at present the IDE exposes exactly one active editor at a time and `Host.ActiveEditors.Count` is **1** when an editor is open, **0** when none is. **As** [**Editors**](Editors). Read-only. +The collection of editors currently open in the IDE. `Host.ActiveEditors(0)` returns the active one --- at present the IDE exposes exactly one active editor at a time and `Host.ActiveEditors.Count` is **1** when an editor is open, **0** when none is. **As** [**Editors**](Editors). Read-only. ### CompilerVersion {: .no_toc } @@ -57,12 +57,12 @@ The IDE's DEBUG CONSOLE pane. Print, clear, or set focus. **As** [**DebugConsole ### FileSystem {: .no_toc } -The IDE's virtual file system — the abstraction that lets the addin walk and read source files without touching the on-disk paths. **As** [**FileSystem**](FileSystem). Read-only. +The IDE's virtual file system --- the abstraction that lets the addin traverse and read source files without touching the on-disk paths. **As** [**FileSystem**](FileSystem). Read-only. ### IDEProcessID {: .no_toc } -The OS process ID of the running IDE process. **Long**, read-only. Useful for inter-process scenarios — e.g. an external helper EXE that needs to know which IDE invoked it. +The OS process ID of the running IDE process. **Long**, read-only. Useful for inter-process scenarios --- e.g. an external helper EXE that needs to know which IDE invoked it. ### IDEWindowHandle {: .no_toc } @@ -72,7 +72,7 @@ The Win32 `HWND` of the IDE's main window. **LongPtr**, read-only. Pass to Win32 ### KeyboardShortcuts {: .no_toc } -The keyboard-shortcut registry. Use [**KeyboardShortcuts.Add**](KeyboardShortcuts#add) to bind a key combination to a callback. **As** [**KeyboardShortcuts**](KeyboardShortcuts). Read-only. +The keyboard-shortcut registry. Call [**KeyboardShortcuts.Add**](KeyboardShortcuts#add) to bind a key combination to a callback. **As** [**KeyboardShortcuts**](KeyboardShortcuts). Read-only. ### Themes {: .no_toc } @@ -82,12 +82,12 @@ The IDE's theme state. Exposes the active theme name and group; pair with the [* ### Toolbars {: .no_toc } -The collection of IDE toolbars. Currently a one-element collection — `Host.Toolbars(0)` is the only available toolbar. **As** [**Toolbars**](Toolbars). Read-only. +The collection of IDE toolbars. Currently a one-element collection --- `Host.Toolbars(0)` is the only available toolbar. **As** [**Toolbars**](Toolbars). Read-only. ### ToolWindows {: .no_toc } -Factory for HTML-rendered tool windows. Use [**ToolWindows.Add**](ToolWindows#add) to create one. **As** [**ToolWindows**](ToolWindows). Read-only. +Factory for HTML-rendered tool windows. Call [**ToolWindows.Add**](ToolWindows#add) to create one. **As** [**ToolWindows**](ToolWindows). Read-only. ## Methods @@ -119,18 +119,18 @@ End Select ### ShowNotification {: .no_toc } -Displays a non-modal, discreet notification pop-up in the IDE — a toast-style transient message that does not require the user to react. +Displays a non-modal, discreet notification pop-up in the IDE --- a toast-style transient message that does not require the user to react. Syntax: *host*.**ShowNotification** *Prompt* *Prompt* : *required* The notification text. **String**. -Use [**ShowMessageBox**](#showmessagebox) when the user has to answer something; **ShowNotification** is for "the user should know but doesn't have to react". +[**ShowMessageBox**](#showmessagebox) is for when the user has to answer something; **ShowNotification** is for "the user should know but doesn't have to react". ## Events -The **Host** CoClass exposes three events. The third (and any future addition) is tagged with the compile-time `[AllowUnpopulatedVtableEntry]` attribute, which lets a newer addin compile against the newer events interface and still load against an older IDE that does not yet fire the newer event — older IDEs simply leave the slot empty and the addin never receives that particular event. +The **Host** CoClass exposes three events. The third (and any future addition) is tagged with the compile-time `[AllowUnpopulatedVtableEntry]` attribute, which lets a newer addin compile against the newer events interface and still load against an older IDE that does not yet fire the newer event --- older IDEs leave the slot empty and the addin never receives that particular event. ### OnProjectLoaded {: .no_toc } @@ -151,7 +151,7 @@ End Sub ### OnChangedActiveEditor {: .no_toc } -Fires when the user switches the focused editor. Use this to refresh any addin UI that depends on the current editor (e.g. a context-aware tool window). Available since IDE BETA 504+; older IDEs simply do not fire it. +Fires when the user switches the focused editor. The event is the right hook for refreshing any addin UI that depends on the current editor (e.g. a context-aware tool window). Available since IDE BETA 504+; older IDEs do not fire it. Syntax: *host*_**OnChangedActiveEditor**(*EditorIdx* **As Long**, *Editor* **As** [**Editor**](Editor)) @@ -159,7 +159,7 @@ Syntax: *host*_**OnChangedActiveEditor**(*EditorIdx* **As Long**, *Editor* **As* : The zero-based index of the newly active editor in the [**ActiveEditors**](#activeeditors) collection. *Editor* -: The newly active editor object. Castable to [**CodeEditor**](CodeEditor) for code panes — see [Editor castability](Editor#castability). +: The newly active editor object. Castable to [**CodeEditor**](CodeEditor) for code panes --- see [Editor castability](Editor#castability). ### OnChangedTheme {: .no_toc } @@ -169,12 +169,12 @@ Fires when the user changes the IDE theme. Pair with [**Themes.ActiveThemeName** Syntax: *host*_**OnChangedTheme**(*ThemeName* **As String**) *ThemeName* -: The new theme's name — same value the user now sees in [**Themes.ActiveThemeName**](Themes#activethemename) (e.g. `"Classic"`, `"Dark"`, `"Light"`). +: The new theme's name --- same value the user now sees in [**Themes.ActiveThemeName**](Themes#activethemename) (e.g. `"Classic"`, `"Dark"`, `"Light"`). ## DebuggerEvaluateOptions {: #debuggerevaluateoptions } -A flags enum declared inline on the **Host** interface; consumed by [**Project.Evaluate**](Project#evaluate) (and any future debugger-evaluation API). Currently a single-value placeholder — additional flags may appear in later IDE versions. +A flags enum declared inline on the **Host** interface; consumed by [**Project.Evaluate**](Project#evaluate) (and any future debugger-evaluation API). Currently a single-value placeholder --- additional flags may appear in later IDE versions. | Constant | Value | Description | |----------|-------|-------------| diff --git a/docs/Reference/tbIDE/HtmlElement.md b/docs/Reference/tbIDE/HtmlElement.md index 74fe1a73..4f5576e0 100644 --- a/docs/Reference/tbIDE/HtmlElement.md +++ b/docs/Reference/tbIDE/HtmlElement.md @@ -8,7 +8,7 @@ has_toc: false # HtmlElement class {: .no_toc } -One DOM element inside a tool window — every node in the rendered HTML tree is reachable as an **HtmlElement**, starting from [**ToolWindow.RootDomElement**](ToolWindow#rootdomelement) and walking down through [**ChildDomElements**](#childdomelements). Inline overlays inside a code pane (created with [**CodeEditor.AddMonacoWidget**](CodeEditor#addmonacowidget)) also appear as **HtmlElement** instances and behave identically. +One DOM element inside a tool window --- every node in the rendered HTML tree is reachable as an **HtmlElement**, starting from [**ToolWindow.RootDomElement**](ToolWindow#rootdomelement) and traversing down through [**ChildDomElements**](#childdomelements). Inline overlays inside a code pane (created with [**CodeEditor.AddMonacoWidget**](CodeEditor#addmonacowidget)) also appear as **HtmlElement** instances and behave identically. ```tb With myToolWindow.RootDomElement.ChildDomElements.Add("greeting", "h1") @@ -20,7 +20,7 @@ With myToolWindow.RootDomElement.ChildDomElements.Add("greeting", "h1") End With ``` -The element's *properties* — every CSS-style property, every DOM attribute, every custom-widget extension — live inside the [**Properties**](#properties) bag, accessed through a dynamic resolution mechanism. See [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview for the underlying mechanism that makes `.style.textAlign = "center"` work without a statically-declared `style` member. +The element's *properties* --- every CSS-style property, every DOM attribute, every custom-widget extension --- live inside the [**Properties**](#properties) bag, accessed through a dynamic resolution mechanism. See [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview for the underlying mechanism that makes `.style.textAlign = "center"` work without a statically-declared `style` member. * TOC {:toc} @@ -30,7 +30,7 @@ The element's *properties* — every CSS-style property, every DOM attribute, ev ### ChildDomElements {: .no_toc } -The element's child-element collection. Use [**HtmlElements.Add**](HtmlElements#add) to add new children, [**Item**](HtmlElements#item) to look one up by ID. **As** [**HtmlElements**](HtmlElements). Read-only. +The element's child-element collection. Call [**HtmlElements.Add**](HtmlElements#add) to add new children, [**Item**](HtmlElements#item) to look one up by ID. **As** [**HtmlElements**](HtmlElements). Read-only. ### Name {: .no_toc } @@ -40,9 +40,9 @@ The unique ID assigned to the element when it was created via [**HtmlElements.Ad ### Properties {: .no_toc } -The element's dynamic property bag — every DOM property, every CSS-style property, every custom-widget extension lives here. **As** [**HtmlElementProperties**](HtmlElementProperties). **DefaultMember** — so `element.<name>` is equivalent to `element.Properties.<name>`. +The element's dynamic property bag --- every DOM property, every CSS-style property, every custom-widget extension lives here. **As** [**HtmlElementProperties**](HtmlElementProperties). **DefaultMember** --- so `element.<name>` is equivalent to `element.Properties.<name>`. -The bag is [`[COMExtensible(True)]`](.#dynamic-dom-property-resolution): property names are resolved against the DOM element at run time, so the accepted set is everything the underlying tag supports — refer to MDN for standard DOM properties, and to the custom-widget documentation (Chart.js, Monaco, …) for the widget-specific properties. +The bag is [`[COMExtensible(True)]`](.#dynamic-dom-property-resolution): property names are resolved against the DOM element at run time, so the accepted set is everything the underlying tag supports --- refer to MDN for standard DOM properties, and to the custom-widget documentation (Chart.js, Monaco, …) for the widget-specific properties. ## Methods @@ -78,10 +78,10 @@ End Sub > For the four custom-widget tags (`"chartjs"`, `"monaco"`, `"listview"`, `"virtuallistview"`), the widget-specific events (e.g. Monaco's `onDidChangeModelContent`, the listview's `onClickItem`) are registered on the **widget object**, not on the DOM element. So: > > ```tb -> ' WRONG — listener is never reached: +> ' WRONG --- listener is never reached: > monacoDivElement.AddEventListener("onDidChangeModelContent", AddressOf Handler) > -> ' CORRECT — register on .editor (or .listview / .chart for the other widgets): +> ' CORRECT --- register on .editor (or .listview / .chart for the other widgets): > monacoDivElement.Properties.editor.AddEventListener("onDidChangeModelContent", AddressOf Handler) > ``` > @@ -96,7 +96,7 @@ Inline HTML rendered inside a tool window can raise arbitrary event names back t raiseEvent(eventName, event, stopPropagation, ...customData) ``` -— pass an event name (any string), the DOM `event` object, a boolean controlling propagation, and any number of trailing custom-data values. The addin then registers a listener with the same event name through **AddEventListener**, and the custom-data values arrive on the [**HtmlEventProperties**](HtmlEventProperties) as `eventInfo.customData0`, `eventInfo.customData1`, … (numerically indexed from zero). This pattern is used heavily in sample 13 (listview) and sample 15 (Global Search) to attach handlers to per-item buttons rendered inside a listview's HTML. +--- pass an event name (any string), the DOM `event` object, a boolean controlling propagation, and any number of trailing custom-data values. The addin then registers a listener with the same event name through **AddEventListener**, and the custom-data values arrive on the [**HtmlEventProperties**](HtmlEventProperties) as `eventInfo.customData0`, `eventInfo.customData1`, … (numerically indexed from zero). This pattern is used heavily in sample 13 (listview) and sample 15 (Global Search) to attach handlers to per-item buttons rendered inside a listview's HTML. ### Remove {: .no_toc } diff --git a/docs/Reference/tbIDE/HtmlElementProperties.md b/docs/Reference/tbIDE/HtmlElementProperties.md index 833dc155..5466fe7f 100644 --- a/docs/Reference/tbIDE/HtmlElementProperties.md +++ b/docs/Reference/tbIDE/HtmlElementProperties.md @@ -8,7 +8,7 @@ has_toc: false # HtmlElementProperties class {: .no_toc } -The dynamic property bag on an [**HtmlElement**](HtmlElement). Reached through [**HtmlElement.Properties**](HtmlElement#properties). Every CSS property, every DOM attribute, every custom-widget extension is accessed through this bag — and almost always written in shorthand because [**Properties**](HtmlElement#properties) is the **DefaultMember** of [**HtmlElement**](HtmlElement): +The dynamic property bag on an [**HtmlElement**](HtmlElement). Reached through [**HtmlElement.Properties**](HtmlElement#properties). Every CSS property, every DOM attribute, every custom-widget extension is accessed through this bag --- and almost always written in shorthand because [**Properties**](HtmlElement#properties) is the **DefaultMember** of [**HtmlElement**](HtmlElement): ```tb With element ' element.Properties is the default member @@ -19,14 +19,14 @@ With element ' element.Properties is the default member End With ``` -The shorthand reads at run time as a chain of `Item("name")` lookups against the underlying DOM element — see [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview. +The shorthand reads at run time as a chain of `Item("name")` lookups against the underlying DOM element --- see [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview. > [!IMPORTANT] -> This interface is **`[COMExtensible(True)]`**. Property names are resolved against the live DOM element at run time, not declared statically on the interface. The compiler does not validate names — a typo (`.innerTxt = "..."` instead of `.innerText = "..."`) fails silently or throws at run time. The accepted set is **every DOM property of the underlying tag**, plus any custom-widget extensions; the reference does not enumerate it. +> This interface is **`[COMExtensible(True)]`**. Property names are resolved against the live DOM element at run time, not declared statically on the interface. The compiler does not validate names --- a typo (`.innerTxt = "..."` instead of `.innerText = "..."`) fails silently or throws at run time. The accepted set is **every DOM property of the underlying tag**, plus any custom-widget extensions; the reference does not enumerate it. ## Default member -The interface's **DefaultMember** is [**Item**](#item) — so `properties("style")` is equivalent to `properties.Item("style")`. Chains of `.style.color = "red"` thus desugar to `properties.Item("style").Item("color").Value = "red"`. +The interface's **DefaultMember** is [**Item**](#item) --- so `properties("style")` is equivalent to `properties.Item("style")`. Chains of `.style.color = "red"` thus desugar to `properties.Item("style").Item("color").Value = "red"`. ## Properties @@ -38,4 +38,4 @@ Looks up a property by name. Returns an [**HtmlElementProperty**](HtmlElementPro Syntax: *properties*( *DomPropertyName* ) **As** [**HtmlElementProperty**](HtmlElementProperty) *DomPropertyName* -: *required* The property name. **String**. Standard DOM property names, CSS-style property names (when looked up under `style`), or custom-widget property names — all forwarded to the IDE's tool-window renderer. +: *required* The property name. **String**. Standard DOM property names, CSS-style property names (when looked up under `style`), or custom-widget property names --- all forwarded to the IDE's tool-window renderer. diff --git a/docs/Reference/tbIDE/HtmlElementProperty.md b/docs/Reference/tbIDE/HtmlElementProperty.md index dc5a6be3..9b7d6a3e 100644 --- a/docs/Reference/tbIDE/HtmlElementProperty.md +++ b/docs/Reference/tbIDE/HtmlElementProperty.md @@ -8,9 +8,9 @@ has_toc: false # HtmlElementProperty class {: .no_toc } -One settable property on an [**HtmlElement**](HtmlElement) — returned by [**HtmlElementProperties.Item**](HtmlElementProperties#item). Carries the property's [**Value**](#value) plus a [**Properties**](#properties) accessor that lets the addin drill into nested DOM property structures (`.style.color`, `.chart.data.datasets(0).borderWidth`, …). +One settable property on an [**HtmlElement**](HtmlElement) --- returned by [**HtmlElementProperties.Item**](HtmlElementProperties#item). Carries the property's [**Value**](#value) plus a [**Properties**](#properties) accessor that lets the addin drill into nested DOM property structures (`.style.color`, `.chart.data.datasets(0).borderWidth`, …). -Almost always written in shorthand — neither **HtmlElementProperty** nor its parent [**HtmlElementProperties**](HtmlElementProperties) is typically named in addin code; the compiler resolves chains like `.style.color = "red"` through their default-members: +Almost always written in shorthand --- neither **HtmlElementProperty** nor its parent [**HtmlElementProperties**](HtmlElementProperties) is typically named in addin code; the compiler resolves chains like `.style.color = "red"` through their default-members: ```tb element.style.color = "red" @@ -36,8 +36,8 @@ Syntax: *property*.**Properties** **As** [**HtmlElementProperties**](HtmlElement ### Value {: .no_toc } -The property's value. Read returns the current value as a **Variant**; assigning writes the new value back. **DefaultMember** — so `propertyObj = "red"` is equivalent to `propertyObj.Value = "red"`. +The property's value. Read returns the current value as a **Variant**; assigning writes the new value back. **DefaultMember** --- so `propertyObj = "red"` is equivalent to `propertyObj.Value = "red"`. Syntax: *property* [ = *value* ] -The interface is **`[COMExtensible(True)]`** — see [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview. Property names that route through [**Properties**](#properties) are resolved against the live DOM at run time, not declared statically. +The interface is **`[COMExtensible(True)]`** --- see [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview. Property names that route through [**Properties**](#properties) are resolved against the live DOM at run time, not declared statically. diff --git a/docs/Reference/tbIDE/HtmlElements.md b/docs/Reference/tbIDE/HtmlElements.md index 6beae1a0..8814f52d 100644 --- a/docs/Reference/tbIDE/HtmlElements.md +++ b/docs/Reference/tbIDE/HtmlElements.md @@ -37,7 +37,7 @@ Creates a new child element under the parent [**HtmlElement**](HtmlElement) and Syntax: *htmlElements*.**Add**( *ElementID*, *TagName* ) **As** [**HtmlElement**](HtmlElement) *ElementID* -: *required* A DOM `id` for the new element. **String**. Pick distinct IDs across the tool window — they double as the key for [**Item**](#item) lookups. +: *required* A DOM `id` for the new element. **String**. Pick distinct IDs across the tool window --- they double as the key for [**Item**](#item) lookups. *TagName* : *required* The HTML tag name. **String**. Standard tags (`"div"`, `"span"`, `"input"`, `"h1"`, `"label"`, `"img"`, …) work as expected; the IDE additionally accepts four custom-widget tags described in [Tool-window DOM tags](.#tool-window-dom-tags) on the package overview: `"chartjs"`, `"monaco"`, `"listview"`, `"virtuallistview"`. @@ -59,9 +59,9 @@ Set virtList = .ChildDomElements.Add("bigList", "virtuallistview") ### Item {: .no_toc } -Looks up an existing child element by its ID. **DefaultMember** — so `elements("greeting")` is equivalent to `elements.Item("greeting")`. +Looks up an existing child element by its ID. **DefaultMember** --- so `elements("greeting")` is equivalent to `elements.Item("greeting")`. Syntax: *htmlElements*( *ID* ) **As** [**HtmlElement**](HtmlElement) *ID* -: A **Variant** — typically the **String** ID assigned at [**Add**](#add) time. +: A **Variant** --- typically the **String** ID assigned at [**Add**](#add) time. diff --git a/docs/Reference/tbIDE/HtmlEventProperties.md b/docs/Reference/tbIDE/HtmlEventProperties.md index a4453e8b..c02e65f8 100644 --- a/docs/Reference/tbIDE/HtmlEventProperties.md +++ b/docs/Reference/tbIDE/HtmlEventProperties.md @@ -8,7 +8,7 @@ has_toc: false # HtmlEventProperties class {: .no_toc } -The dynamic event-payload bag passed to every [**HtmlElement.AddEventListener**](HtmlElement#addeventlistener) callback. Conceptually the IDE-side equivalent of the JavaScript `Event` object — fields like `.key`, `.target.id`, `.target.value`, `.index` are accessed dynamically through the bag's `[COMExtensible(True)]` resolution. +The dynamic event-payload bag passed to every [**HtmlElement.AddEventListener**](HtmlElement#addeventlistener) callback. Conceptually the IDE-side equivalent of the JavaScript `Event` object --- fields like `.key`, `.target.id`, `.target.value`, `.index` are accessed dynamically through the bag's `[COMExtensible(True)]` resolution. ```tb Private Sub MyButtonClicked(ByVal eventInfo As HtmlEventProperties) @@ -44,7 +44,7 @@ End Sub ## Asynchronous events (`setAsyncResult`) -Some events — notably the virtual listview's `onAsyncGetItemHTML` — are *asynchronous*: the IDE asks the addin to produce content for a specific argument and expects the answer back through the event object itself. The argument arrives on the event as `eventInfo.asyncArgument`, and the listener responds by calling `eventInfo.setAsyncResult(answer)`: +Some events --- notably the virtual listview's `onAsyncGetItemHTML` --- are *asynchronous*: the IDE asks the addin to produce content for a specific argument and expects the answer back through the event object itself. The argument arrives on the event as `eventInfo.asyncArgument`, and the listener responds by calling `eventInfo.setAsyncResult(answer)`: ```tb Private Sub OnAsyncGetItemHTML(ByVal eventInfo As HtmlEventProperties) @@ -53,11 +53,11 @@ Private Sub OnAsyncGetItemHTML(ByVal eventInfo As HtmlEventProperties) End Sub ``` -This is the standard `[COMExtensible(True)]` resolution at work — `setAsyncResult` is not declared on the interface, it is dispatched through the dynamic mechanism just like `.key` or `.target` would be. See sample 14 (`WaynesVirtualListViewAddIn`) for the full pattern, including the cache-invalidation companion call `listview.notifyChangedItem(idx)`. +This is the standard `[COMExtensible(True)]` resolution at work --- `setAsyncResult` is not declared on the interface, it is dispatched through the dynamic mechanism just like `.key` or `.target` would be. See sample 14 (`WaynesVirtualListViewAddIn`) for the full pattern, including the cache-invalidation companion call `listview.notifyChangedItem(idx)`. ## Default member -The interface's **DefaultMember** is [**Item**](#item) — so `eventInfo("target")` is equivalent to `eventInfo.Item("target")`. The `.target.id` shorthand desugars accordingly. +The interface's **DefaultMember** is [**Item**](#item) --- so `eventInfo("target")` is equivalent to `eventInfo.Item("target")`. The `.target.id` shorthand desugars accordingly. ## Properties diff --git a/docs/Reference/tbIDE/HtmlEventProperty.md b/docs/Reference/tbIDE/HtmlEventProperty.md index e438e47c..36376607 100644 --- a/docs/Reference/tbIDE/HtmlEventProperty.md +++ b/docs/Reference/tbIDE/HtmlEventProperty.md @@ -8,9 +8,9 @@ has_toc: false # HtmlEventProperty class {: .no_toc } -One value inside an [**HtmlEventProperties**](HtmlEventProperties) event bag — returned by [**HtmlEventProperties.Item**](HtmlEventProperties#item). Carries the field's [**Value**](#value) plus a [**Properties**](#properties) accessor for nested drill-down (e.g. `eventInfo.target.id`). +One value inside an [**HtmlEventProperties**](HtmlEventProperties) event bag --- returned by [**HtmlEventProperties.Item**](HtmlEventProperties#item). Carries the field's [**Value**](#value) plus a [**Properties**](#properties) accessor for nested drill-down (e.g. `eventInfo.target.id`). -Almost always written in shorthand — neither **HtmlEventProperty** nor its parent [**HtmlEventProperties**](HtmlEventProperties) is typically named in addin code; the compiler resolves chains like `eventInfo.target.id` through their default-members. Unlike [**HtmlElementProperty**](HtmlElementProperty), [**Value**](#value) is **read-only** — event payloads are an inbound signal from the DOM, not an outbound property setter. +Almost always written in shorthand --- neither **HtmlEventProperty** nor its parent [**HtmlEventProperties**](HtmlEventProperties) is typically named in addin code; the compiler resolves chains like `eventInfo.target.id` through their default-members. Unlike [**HtmlElementProperty**](HtmlElementProperty), [**Value**](#value) is **read-only** --- event payloads are an inbound signal from the DOM, not an outbound property setter. ```tb Private Sub MyButtonKeyUp(ByVal eventInfo As HtmlEventProperties) @@ -29,15 +29,15 @@ End Sub ### Properties {: .no_toc } -A nested [**HtmlEventProperties**](HtmlEventProperties) for fields that themselves have sub-fields (the canonical example is `.target`, whose sub-fields are the target element's own properties — `id`, `value`, `name`, `tagName`, …). Read-only at the accessor level. +A nested [**HtmlEventProperties**](HtmlEventProperties) for fields that themselves have sub-fields (the canonical example is `.target`, whose sub-fields are the target element's own properties --- `id`, `value`, `name`, `tagName`, …). Read-only at the accessor level. Syntax: *property*.**Properties** **As** [**HtmlEventProperties**](HtmlEventProperties) ### Value {: .no_toc } -The field's value, as a **Variant**. **DefaultMember** — so `eventInfo.key` desugars to `eventInfo.Item("key").Value`. Read-only — event payloads cannot be modified. +The field's value, as a **Variant**. **DefaultMember** --- so `eventInfo.key` desugars to `eventInfo.Item("key").Value`. Read-only --- event payloads cannot be modified. Syntax: *property* **As Variant** -The interface is **`[COMExtensible(True)]`** — see [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview. Field names that route through [**Properties**](#properties) are resolved against the live event object at run time, not declared statically. +The interface is **`[COMExtensible(True)]`** --- see [Dynamic DOM property resolution](.#dynamic-dom-property-resolution) on the package overview. Field names that route through [**Properties**](#properties) are resolved against the live event object at run time, not declared statically. diff --git a/docs/Reference/tbIDE/KeyboardShortcuts.md b/docs/Reference/tbIDE/KeyboardShortcuts.md index c1480514..cdd5815b 100644 --- a/docs/Reference/tbIDE/KeyboardShortcuts.md +++ b/docs/Reference/tbIDE/KeyboardShortcuts.md @@ -8,7 +8,7 @@ has_toc: false # KeyboardShortcuts class {: .no_toc } -The IDE's keyboard-shortcut registry — reached through [**Host.KeyboardShortcuts**](Host#keyboardshortcuts). Use [**Add**](#add) to bind a key combination to a callback. There is no removal API; the registration is released when the addin is unloaded. +The IDE's keyboard-shortcut registry --- reached through [**Host.KeyboardShortcuts**](Host#keyboardshortcuts). Call [**Add**](#add) to bind a key combination to a callback. There is no removal API; the registration is released when the addin is unloaded. ```tb Private Sub Host_OnProjectLoaded() @@ -45,4 +45,4 @@ Syntax: *keyboardShortcuts*.**Add** *keyString*, *Callback* *Callback* : *required* The callback. Pass `AddressOf` a sub of signature `Sub()` (no arguments). **LongPtr**. -The callback runs on the IDE's UI thread. Long-running work inside the callback will block the IDE until it returns — keep the callback short and offload heavy work to a background mechanism if needed. +The callback runs on the IDE's UI thread. Long-running work inside the callback will block the IDE until it returns --- keep the callback short and offload heavy work to a background mechanism when needed. diff --git a/docs/Reference/tbIDE/Project.md b/docs/Reference/tbIDE/Project.md index ddcf57bc..998221dd 100644 --- a/docs/Reference/tbIDE/Project.md +++ b/docs/Reference/tbIDE/Project.md @@ -12,10 +12,10 @@ The currently-loaded project. Reached through [**Host.CurrentProject**](Host#cur The class groups four kinds of capability: -- **Identification** — [**Name**](#name), [**Path**](#path), [**BaseFolderPath**](#basefolderpath), [**ProjectID**](#projectid), version + architecture + build-output info. -- **Lifecycle commands** — [**Save**](#save), [**Close**](#close), [**Build**](#build), [**Clean**](#clean) (the same actions the IDE's File menu exposes). -- **Programmatic access** — [**Evaluate**](#evaluate) runs an arbitrary expression against the running project context (the same engine as the DEBUG CONSOLE); [**RootFolder**](#rootfolder) is the entry into the virtual file system. -- **Persistent storage** — [**LoadMetaData**](#loadmetadata) / [**SaveMetaData**](#savemetadata) store per-addin key/value pairs inside the `.twinproj` file. +- **Identification** --- [**Name**](#name), [**Path**](#path), [**BaseFolderPath**](#basefolderpath), [**ProjectID**](#projectid), version + architecture + build-output info. +- **Lifecycle commands** --- [**Save**](#save), [**Close**](#close), [**Build**](#build), [**Clean**](#clean) (the same actions the IDE's File menu exposes). +- **Programmatic access** --- [**Evaluate**](#evaluate) runs an arbitrary expression against the running project context (the same engine as the DEBUG CONSOLE); [**RootFolder**](#rootfolder) is the entry into the virtual file system. +- **Persistent storage** --- [**LoadMetaData**](#loadmetadata) / [**SaveMetaData**](#savemetadata) store per-addin key/value pairs inside the `.twinproj` file. ```tb With Host.CurrentProject @@ -39,7 +39,7 @@ The project's target processor architecture. **As** [**VbArchitecture**](../../M ### BaseFolderPath {: .no_toc } -The folder containing the project's `.twinproj` file — i.e. the directory part of [**Path**](#path). **String**, read-only. +The folder containing the project's `.twinproj` file --- i.e. the directory part of [**Path**](#path). **String**, read-only. ### BuildFileExtension {: .no_toc } @@ -49,7 +49,7 @@ The file extension of the build output (`"exe"`, `"dll"`, `"ocx"`, `"twinpack"`) ### BuildOutputPath {: .no_toc } -The full path of the project's build output, including filename and extension — the file that [**Build**](#build) writes (or would write) to. **String**, read-only. +The full path of the project's build output, including filename and extension --- the file that [**Build**](#build) writes (or would write) to. **String**, read-only. ### BuildType {: .no_toc } @@ -69,12 +69,12 @@ The full path to the project's `.twinproj` file. **String**, read-only. ### ProjectID {: .no_toc } -The project's GUID as a string — e.g. `"{99DEC38C-75F6-4488-8EE7-2D52D83881D2}"`. **String**, read-only. Stable across renames; useful as a key in addin-side per-project state. +The project's GUID as a string --- e.g. `"{99DEC38C-75F6-4488-8EE7-2D52D83881D2}"`. **String**, read-only. Stable across renames; useful as a key in addin-side per-project state. ### RootFolder {: .no_toc } -The root of the project's virtual file system — the entry point for walking sources, resources, packages, and other project contents. **As** [**Folder**](Folder). Read-only. +The root of the project's virtual file system --- the entry point for traversing sources, resources, packages, and other project contents. **As** [**Folder**](Folder). Read-only. ### VersionBuild, VersionMajor, VersionMinor, VersionRevision {: .no_toc } @@ -93,7 +93,7 @@ Syntax: *project*.**Build** ### Clean {: .no_toc } -Deregisters and deletes any built executables relating to the project — the inverse of a previous [**Build**](#build). +Deregisters and deletes any built executables relating to the project --- the inverse of a previous [**Build**](#build). Syntax: *project*.**Clean** @@ -112,7 +112,7 @@ Evaluates an expression in the context of the currently-loaded project, as if th Syntax: *project*.**Evaluate**( *EvalString* [, *Options* ] ) **As Variant** *EvalString* -: *required* The expression to evaluate. **String**. Any expression valid in the DEBUG CONSOLE works — arithmetic (`10.5 * 4`), property reads (`MyForm.Caption`), function calls (`MyModule.MyFunc(42)`), and so on. +: *required* The expression to evaluate. **String**. Any expression valid in the DEBUG CONSOLE works --- arithmetic (`10.5 * 4`), property reads (`MyForm.Caption`), function calls (`MyModule.MyFunc(42)`), and so on. *Options* : *optional* A [**DebuggerEvaluateOptions**](Host#debuggerevaluateoptions) value. Default [**NONE**](Host#DebuggerEvaluateOptions_NONE). @@ -127,7 +127,7 @@ Else End If ``` -Same engine the DEBUG CONSOLE uses, so the same set of identifiers, the same accessibility rules, and the same error semantics apply — including the run-time errors that arise from inside the evaluated expression. Wrap in `On Error Resume Next` if the expression may raise. +Same engine the DEBUG CONSOLE uses, so the same set of identifiers, the same accessibility rules, and the same error semantics apply --- including the run-time errors that arise from inside the evaluated expression. Wrap in `On Error Resume Next` when the expression may raise. ### LoadMetaData {: .no_toc } @@ -139,7 +139,7 @@ Syntax: *project*.**LoadMetaData**( *Key* ) **As String** *Key* : *required* The meta-data key. **String**. Returns `""` if no value has been stored under *Key*. -The meta-data is associated with the loaded project, not with the addin globally. Closing the project closes the storage too; opening a different project gives a different store. For addin-wide persistence (e.g. addin-level options that should follow the user across projects), use `GetSetting` / `SaveSetting` against the registry — sample 15 demonstrates that pattern. +The meta-data is associated with the loaded project, not with the addin globally. Closing the project closes the storage too; opening a different project gives a different store. For addin-wide persistence (e.g. addin-level options that should follow the user across projects), use `GetSetting` / `SaveSetting` against the registry --- sample 15 demonstrates that pattern. ### Save {: .no_toc } @@ -183,5 +183,5 @@ The artefact-kind enum returned by [**BuildType**](#buildtype). Declared inline | **StandardEXE**{: #VbBuildType_StandardEXE } | 0 | A standard Win32 executable. | | **StandardDLL**{: #VbBuildType_StandardDLL } | 1 | A standard Win32 DLL. Addins themselves are Standard DLL projects. | | **ActiveXDLL**{: #VbBuildType_ActiveXDLL } | 2 | A COM (ActiveX) DLL. | -| **ActiveXControl**{: #VbBuildType_ActiveXControl } | 3 | A COM (ActiveX) control — `.ocx`. | +| **ActiveXControl**{: #VbBuildType_ActiveXControl } | 3 | A COM (ActiveX) control --- `.ocx`. | | **PackageTWINPACK**{: #VbBuildType_PackageTWINPACK } | 4 | A twinBASIC package (`.twinpack`). | diff --git a/docs/Reference/tbIDE/Themes.md b/docs/Reference/tbIDE/Themes.md index 3fdeb4a2..b4ba82b4 100644 --- a/docs/Reference/tbIDE/Themes.md +++ b/docs/Reference/tbIDE/Themes.md @@ -8,7 +8,7 @@ has_toc: false # Themes class {: .no_toc } -The IDE's active-theme state — reached through [**Host.Themes**](Host#themes). Pair with the [**Host.OnChangedTheme**](Host#onchangedtheme) event to refresh any colour-sensitive elements the addin draws inside its tool windows. +The IDE's active-theme state --- reached through [**Host.Themes**](Host#themes). Pair with the [**Host.OnChangedTheme**](Host#onchangedtheme) event to refresh any colour-sensitive elements the addin draws inside its tool windows. ```tb Private Sub Host_OnProjectLoaded() @@ -35,13 +35,13 @@ End Sub ### ActiveThemeName {: .no_toc } -The name of the current IDE theme — e.g. `"Classic"`, `"Dark"`, `"Light"`. **String**, read-only. +The name of the current IDE theme --- e.g. `"Classic"`, `"Dark"`, `"Light"`. **String**, read-only. -Note that the set of available themes is determined by the IDE and may grow in future versions; do not switch on this value with an exhaustive `Select Case`. For binary light-vs-dark colour decisions, use [**ActiveThemeNameGroup**](#activethemenamegroup) instead. +The set of available themes is determined by the IDE and may grow in future versions; do not switch on this value with an exhaustive `Select Case`. For binary light-vs-dark colour decisions, use [**ActiveThemeNameGroup**](#activethemenamegroup) instead. ### ActiveThemeNameGroup {: .no_toc } -The high-level "family" the current theme belongs to. **String**, read-only — exactly `"dark"` or `"light"`. +The high-level "family" the current theme belongs to. **String**, read-only --- exactly `"dark"` or `"light"`. Useful for an addin that wants to flip its own colours between dark-on-light and light-on-dark without parsing [**ActiveThemeName**](#activethemename). diff --git a/docs/Reference/tbIDE/ToolWindow.md b/docs/Reference/tbIDE/ToolWindow.md index 894814d7..4def17d0 100644 --- a/docs/Reference/tbIDE/ToolWindow.md +++ b/docs/Reference/tbIDE/ToolWindow.md @@ -8,7 +8,7 @@ has_toc: false # ToolWindow class {: .no_toc } -A dockable / floating IDE pane whose contents are rendered as HTML. Created by [**ToolWindows.Add**](ToolWindows#add); the addin populates its DOM through the [**RootDomElement**](#rootdomelement) — an [**HtmlElement**](HtmlElement) at the root of the pane — and shows the pane by setting [**Visible**](#visible) = **True** (tool windows start out invisible). +A dockable / floating IDE pane whose contents are rendered as HTML. Created by [**ToolWindows.Add**](ToolWindows#add); the addin populates its DOM through the [**RootDomElement**](#rootdomelement) --- an [**HtmlElement**](HtmlElement) at the root of the pane --- and shows the pane by setting [**Visible**](#visible) = **True** (tool windows start out invisible). ```tb Private WithEvents myWindow As ToolWindow @@ -29,32 +29,29 @@ Private Sub Button1_OnClick() End Sub ``` -Use the `WithEvents` reference to receive [**OnClose**](#onclose) when the user dismisses the pane — typically the addin uses that event to release any per-window state (timers, references to DOM elements …). +A `WithEvents` reference receives [**OnClose**](#onclose) when the user dismisses the pane --- typically the addin uses that event to release any per-window state (timers, references to DOM elements …). * TOC {:toc} -## Tool-window default member — jQuery-style child lookup +## Tool-window default member --- jQuery-style child lookup -[**RootDomElement**](#rootdomelement) is the **DefaultMember** of the **ToolWindow** interface — so `myToolWindow.(...)` is equivalent to `myToolWindow.RootDomElement.Properties.(...)`. Because [**HtmlElementProperties**](HtmlElementProperties) is `[COMExtensible(True)]`, a string passed in parenthesis-syntax is resolved against the DOM at run time. The IDE treats CSS-style selectors specially, so: +[**RootDomElement**](#rootdomelement) is the **DefaultMember** of the **ToolWindow** interface --- so `myToolWindow.(...)` is equivalent to `myToolWindow.RootDomElement.Properties.(...)`. Because [**HtmlElementProperties**](HtmlElementProperties) is `[COMExtensible(True)]`, a string passed in parenthesis-syntax is resolved against the DOM at run time. The IDE treats CSS-style selectors specially, so: ```tb ' Find the descendant element whose id is "dataEntry" and read its .Value: Dim entered As String = myToolWindow("#dataEntry").Value ``` -Useful for grabbing a single child element by ID without holding a separate `As HtmlElement` reference for it. +Useful for accessing a single child element by ID without holding a separate `As HtmlElement` reference for it. ## Suggested initial size -[**RootDomElement**](#rootdomelement) accepts `.Properties.suggestedWidth` and `.Properties.suggestedHeight` (CSS-length strings like `"400px"`). These are *one-shot* hints — used the **first time** the tool window opens as a floating pane; once the user resizes (or after position persistence kicks in through [**ToolWindows.Add**](ToolWindows#add)'s persistence ID), the IDE remembers the user's chosen size and the suggested values are ignored. +[**RootDomElement**](#rootdomelement) accepts `.Properties.suggestedWidth` and `.Properties.suggestedHeight` (CSS-length strings like `"400px"`). These are *one-shot* hints --- used the **first time** the tool window opens as a floating pane; once the user resizes (or after position persistence kicks in through [**ToolWindows.Add**](ToolWindows#add)'s persistence ID), the IDE remembers the user's chosen size and the suggested values are ignored. > [!NOTE] > Set `suggestedWidth` / `suggestedHeight` before the first time the pane becomes visible. If the pane has previously been opened by this user (and a persistence ID was supplied to [**ToolWindows.Add**](ToolWindows#add)), the IDE-remembered size wins. -* TOC -{:toc} - ## Properties ### Name @@ -72,7 +69,7 @@ Syntax: *toolWindow*.**Resizable** [ = *value* ] ### RootDomElement {: .no_toc } -The root [**HtmlElement**](HtmlElement) of the pane's DOM. **DefaultMember** — see [Tool-window default member](#tool-window-default-member--jquery-style-child-lookup) above. +The root [**HtmlElement**](HtmlElement) of the pane's DOM. **DefaultMember** --- see [Tool-window default member](#tool-window-default-member--jquery-style-child-lookup) above. Syntax: *toolWindow*.**RootDomElement** **As** [**HtmlElement**](HtmlElement) @@ -86,7 +83,7 @@ Syntax: *toolWindow*.**Title** [ = *value* ] ### Visible {: .no_toc } -Whether the pane is shown. **Boolean**, read / write. Default **False** — newly-created tool windows are invisible until the addin sets this to **True**. +Whether the pane is shown. **Boolean**, read / write. Default **False** --- newly-created tool windows are invisible until the addin sets this to **True**. Syntax: *toolWindow*.**Visible** [ = *value* ] @@ -95,7 +92,7 @@ Syntax: *toolWindow*.**Visible** [ = *value* ] ### ApplyCss {: .no_toc } -Injects a `<style>` block into the pane's DOM that applies to every element inside the pane. Useful for global CSS — class selectors, custom-element styling, hover effects — that would be awkward to set element-by-element through [**HtmlElementProperties**](HtmlElementProperties). +Injects a `<style>` block into the pane's DOM that applies to every element inside the pane. Useful for global CSS --- class selectors, custom-element styling, hover effects --- that would be awkward to set element by element through [**HtmlElementProperties**](HtmlElementProperties). Syntax: *toolWindow*.**ApplyCss** *styles* @@ -120,6 +117,6 @@ Syntax: *toolWindow*.**Close** ### OnClose {: .no_toc } -Fires when the pane is closed — either by the user dismissing it or by the addin calling [**Close**](#close). Use this to release any per-window state (timers, references to DOM elements, …). +Fires when the pane is closed --- either by the user dismissing it or by the addin calling [**Close**](#close). Use this to release any per-window state (timers, references to DOM elements, …). Syntax: *toolWindow*_**OnClose**() diff --git a/docs/Reference/tbIDE/ToolWindows.md b/docs/Reference/tbIDE/ToolWindows.md index 03d7611a..6ad97c4a 100644 --- a/docs/Reference/tbIDE/ToolWindows.md +++ b/docs/Reference/tbIDE/ToolWindows.md @@ -8,7 +8,7 @@ has_toc: false # ToolWindows class {: .no_toc } -The IDE's tool-window factory — reached through [**Host.ToolWindows**](Host#toolwindows). Use [**Add**](#add) to create a new HTML-rendered pane; populate its DOM through the returned [**ToolWindow**](ToolWindow)'s [**RootDomElement**](ToolWindow#rootdomelement); show the pane by setting [**Visible**](ToolWindow#visible) = **True**. +The IDE's tool-window factory --- reached through [**Host.ToolWindows**](Host#toolwindows). Call [**Add**](#add) to create a new HTML-rendered pane; populate its DOM through the returned [**ToolWindow**](ToolWindow)'s [**RootDomElement**](ToolWindow#rootdomelement); show the pane by setting [**Visible**](ToolWindow#visible) = **True**. ```tb Set myWindow = Host.ToolWindows.Add("MyAddIn.MyWindow", "MyAddIn.MyWindowPosition") @@ -27,7 +27,7 @@ Syntax: *toolWindows*.**Add**( *Name* [, *UniqueIdForPositionPersistance* ] ) ** : *required* An internal name for the tool window. **String**. Pick an addin-prefixed value so multiple addins do not collide on names. *UniqueIdForPositionPersistance* -: *optional* A stable identifier the IDE uses to remember the pane's size, position, and dock state across IDE restarts. **String**. Omit to make the pane non-persistent — every open is sized from `suggestedWidth` / `suggestedHeight` (see [**ToolWindow**](ToolWindow#suggested-initial-size)) and positioned by the IDE's default placement logic. +: *optional* A stable identifier the IDE uses to remember the pane's size, position, and dock state across IDE restarts. **String**. Omit to make the pane non-persistent --- every open is sized from `suggestedWidth` / `suggestedHeight` (see [**ToolWindow**](ToolWindow#suggested-initial-size)) and positioned by the IDE's default placement logic. ```tb ' Persisted (preferred for user-visible panes): diff --git a/docs/Reference/tbIDE/Toolbar.md b/docs/Reference/tbIDE/Toolbar.md index 840c62a9..e3431c0b 100644 --- a/docs/Reference/tbIDE/Toolbar.md +++ b/docs/Reference/tbIDE/Toolbar.md @@ -8,7 +8,7 @@ has_toc: false # Toolbar class {: .no_toc } -One IDE toolbar — the strip of buttons that runs along the top of the IDE window. Addins add their own buttons and splitters to it during start-up. Reached through `Host.Toolbars(0)` (currently the only toolbar). +One IDE toolbar --- the strip of buttons that runs along the top of the IDE window. Addins add their own buttons and separators to it during start-up. Reached through `Host.Toolbars(0)` (currently the only toolbar). ```tb Private Sub Host_OnProjectLoaded() @@ -20,7 +20,7 @@ Private Sub Host_OnProjectLoaded() End Sub ``` -The toolbar is shared with the IDE's own commands and with every other loaded addin — pick button IDs that uniquely identify the addin so multiple addins do not collide. +The toolbar is shared with the IDE's own commands and with every other loaded addin --- pick button IDs that uniquely identify the addin so multiple addins do not collide. * TOC {:toc} @@ -30,7 +30,7 @@ The toolbar is shared with the IDE's own commands and with every other loaded ad ### AddButton {: .no_toc } -Adds a new button to the right-hand end of the toolbar and returns the [**Button**](Button) object for the addin to wire `WithEvents` against. +Adds a new button to the right-hand end of the toolbar and returns the [**Button**](Button) object for the addin to attach `WithEvents` against. Syntax: *toolbar*.**AddButton**( *Id*, *Caption* [, *IconData* ] ) **As** [**Button**](Button) @@ -41,7 +41,7 @@ Syntax: *toolbar*.**AddButton**( *Id*, *Caption* [, *IconData* ] ) **As** [**But : *required* The button's label. **String**. When *IconData* is supplied, the caption appears as a tooltip only; when *IconData* is omitted, the caption is displayed inline as the button's text. *IconData* -: *optional* The button's icon as a **Byte()** array — typically the bytes of an embedded PNG / ICO resource loaded with `LoadResData`. **Variant**. Pass an empty / **Empty** value to omit the icon and show the caption inline. +: *optional* The button's icon as a **Byte()** array --- typically the bytes of an embedded PNG / ICO resource loaded with `LoadResData`. **Variant**. Pass an empty / **Empty** value to omit the icon and show the caption inline. ```tb Dim icon() As Byte @@ -52,7 +52,7 @@ Set Button1 = Host.Toolbars(0).AddButton("MyAddIn.Button1", "Refresh Project", i ### AddSplitter {: .no_toc } -Adds a vertical separator bar to the toolbar — a visual divider between groups of buttons. +Adds a vertical separator bar to the toolbar --- a visual divider between groups of buttons. Syntax: *toolbar*.**AddSplitter** diff --git a/docs/Reference/tbIDE/Toolbars.md b/docs/Reference/tbIDE/Toolbars.md index 93b03c0f..2a52d7fc 100644 --- a/docs/Reference/tbIDE/Toolbars.md +++ b/docs/Reference/tbIDE/Toolbars.md @@ -8,7 +8,7 @@ has_toc: false # Toolbars class {: .no_toc } -The collection of IDE toolbars. Reached through [**Host.Toolbars**](Host#toolbars). Currently there is only one toolbar — `Host.Toolbars(0)` — but the collection interface allows future IDE versions to add more. +The collection of IDE toolbars. Reached through [**Host.Toolbars**](Host#toolbars). Currently a single toolbar --- `Host.Toolbars(0)` --- but the collection interface allows future IDE versions to add more. ```tb With Host.Toolbars(0) @@ -27,7 +27,7 @@ The number of toolbars. **Long**, read-only. Currently always **1**. ### Item {: .no_toc } -Indexed access to a toolbar. **DefaultMember** — so `Toolbars(0)` is equivalent to `Toolbars.Item(0)`. +Indexed access to a toolbar. **DefaultMember** --- so `Toolbars(0)` is equivalent to `Toolbars.Item(0)`. Syntax: *toolbars*( *Index* ) **As** [**Toolbar**](Toolbar) diff --git a/docs/Reference/tbIDE/index.md b/docs/Reference/tbIDE/index.md index ec8ad7fa..5109eb15 100644 --- a/docs/Reference/tbIDE/index.md +++ b/docs/Reference/tbIDE/index.md @@ -10,9 +10,9 @@ has_toc: false # tbIDE Package {: .no_toc } -The **tbIDE** package is the **addin SDK** for the twinBASIC IDE. An addin is a Standard DLL that the IDE loads at start-up; the DLL exports one factory function, returns one object implementing the [**AddIn**](AddIn) contract, and from there everything happens through the [**Host**](Host) object the IDE passes in. The package itself is **type-only** — every public symbol is an interface or a CoClass; the actual implementations live in the twinBASIC IDE binary, and the addin DLL binds against the type declarations and lets the IDE marshal calls into its implementations at run time. +The **tbIDE** package is the **addin SDK** for the twinBASIC IDE. An addin is a Standard DLL that the IDE loads at start-up; the DLL exports one factory function, returns one object implementing the [**AddIn**](AddIn) contract, and from there everything happens through the [**Host**](Host) object the IDE passes in. The package itself is **type-only** --- every public symbol is an interface or a CoClass; the actual implementations live in the twinBASIC IDE binary, and the addin DLL binds against the type declarations and lets the IDE marshal calls into its implementations at run time. -The package is a built-in *compiler* package shipped with twinBASIC. It is added to addin projects automatically; you do not need to add it manually through Project → References. +The package is a built-in *compiler* package shipped with twinBASIC. It is added to addin projects automatically; there is no need to add it manually through Project → References. * TOC {:toc} @@ -25,7 +25,7 @@ An addin project has three distinguishing settings: - **Build path:** `${IdePath}\addins\${Architecture}\${ProjectName}.${FileExtension}`. The output drops directly into the IDE's `addins\Win32\` or `addins\Win64\` folder, where the IDE scans for addins on start-up. - **Compiler-package reference** to **tbIDE** (added to the project's references with `isCompilerPackage: true`, `publisher: TWINBASIC-COMPILER`, `symbolId: tbIDE`). This is the binding between the DLL's compile-time types and the IDE's run-time implementations. -The DLL must export one function — the entry point the IDE calls when it discovers and loads the addin: +The DLL must export one function --- the entry point the IDE calls when it discovers and loads the addin: ```tb Module MainModule @@ -60,57 +60,57 @@ Private Class MyAddIn End Class ``` -The `WithEvents Host As Host` pattern is how the addin subscribes to IDE lifecycle events ([**OnProjectLoaded**](Host#onprojectloaded), [**OnChangedActiveEditor**](Host#onchangedactiveeditor), [**OnChangedTheme**](Host#onchangedtheme)). Almost every meaningful addin sets up its toolbar buttons and tool windows inside the [**OnProjectLoaded**](Host#onprojectloaded) handler — that is the first moment the IDE is fully ready to accept extensibility commands. +The `WithEvents Host As Host` pattern is how the addin subscribes to IDE lifecycle events ([**OnProjectLoaded**](Host#onprojectloaded), [**OnChangedActiveEditor**](Host#onchangedactiveeditor), [**OnChangedTheme**](Host#onchangedtheme)). Almost every meaningful addin sets up its toolbar buttons and tool windows inside the [**OnProjectLoaded**](Host#onprojectloaded) handler --- that is the first moment the IDE is fully ready to accept extensibility commands. ## The class catalogue -The package's twenty-four `.twin` files declare one interface-and-CoClass pair each (plus one concrete `Class`), grouped here by role for orientation. Every CoClass except [**AddinTimer**](AddinTimer) is **handed to the addin by the IDE** — never instantiated with `New`. +The package's twenty-four `.twin` files declare one interface-and-CoClass pair each (plus one concrete `Class`), grouped here by role for orientation. Every CoClass except [**AddinTimer**](AddinTimer) is **supplied to the addin by the IDE** --- never instantiated with `New`. ### Entry point and root API -- [**AddIn**](AddIn) — the contract every addin's main class implements. One read-only [**Name**](AddIn#name) property. -- [**Host**](Host) — the root API object passed to `tbCreateCompilerAddin`. Exposes the [**CurrentProject**](Host#currentproject), the [**ActiveEditors**](Host#activeeditors), the [**Toolbars**](Host#toolbars), the [**ToolWindows**](Host#toolwindows), the [**DebugConsole**](Host#debugconsole), the [**FileSystem**](Host#filesystem), the [**KeyboardShortcuts**](Host#keyboardshortcuts), the [**Themes**](Host#themes), and a small set of dialog helpers ([**ShowMessageBox**](Host#showmessagebox), [**ShowNotification**](Host#shownotification)). -- [**AddinTimer**](AddinTimer) — the package's only user-instantiable class. `New AddinTimer`; set [**Interval**](AddinTimer#interval) and [**Enabled**](AddinTimer#enabled); receive a [**Timer**](AddinTimer#timer) event. +- [**AddIn**](AddIn) -- the contract every addin's main class implements. One read-only [**Name**](AddIn#name) property. +- [**Host**](Host) -- the root API object passed to `tbCreateCompilerAddin`. Exposes the [**CurrentProject**](Host#currentproject), the [**ActiveEditors**](Host#activeeditors), the [**Toolbars**](Host#toolbars), the [**ToolWindows**](Host#toolwindows), the [**DebugConsole**](Host#debugconsole), the [**FileSystem**](Host#filesystem), the [**KeyboardShortcuts**](Host#keyboardshortcuts), the [**Themes**](Host#themes), and a small set of dialog helpers ([**ShowMessageBox**](Host#showmessagebox), [**ShowNotification**](Host#shownotification)). +- [**AddinTimer**](AddinTimer) -- the package's only user-instantiable class. `New AddinTimer`; set [**Interval**](AddinTimer#interval) and [**Enabled**](AddinTimer#enabled); receives a [**Timer**](AddinTimer#timer) event. ### Project, editors, and the virtual file system -- [**Project**](Project) — the currently-loaded project. Lifecycle ([**Save**](Project#save), [**Close**](Project#close), [**Build**](Project#build), [**Clean**](Project#clean)), introspection ([**Name**](Project#name), [**Path**](Project#path), [**ProjectID**](Project#projectid), version + architecture + build-output info), the [**Evaluate**](Project#evaluate) hook into the debug-console expression engine, the [**RootFolder**](Project#rootfolder) entry into the virtual file system, and the [**LoadMetaData**](Project#loadmetadata) / [**SaveMetaData**](Project#savemetadata) pair for persistent per-addin key/value storage inside the `.twinproj` file. -- [**Editor**](Editor) — the base editor interface (Path, Type, SetFocus, Close, Save, IsDirty). Castable to [**CodeEditor**](CodeEditor). -- [**CodeEditor**](CodeEditor) — a code-pane editor: selection, full text, Monaco passthrough ([**ExecuteMonacoCommand**](CodeEditor#executemonacocommand)), inline overlay HTML ([**AddMonacoWidget**](CodeEditor#addmonacowidget)). -- [**Editors**](Editors) — the collection of active editors. `Editors(0)` is the current editor; [**Open**](Editors#open) jumps to a file (and optional line/column). -- [**FileSystem**](FileSystem) — the virtual file system. [**RootFolder**](FileSystem#rootfolder), [**ResolvePath**](FileSystem#resolvepath). -- [**FileSystemItem**](FileSystemItem) — the base for [**File**](File) and [**Folder**](Folder). `Name`, `Path`, `Type`, `Parent`. -- [**Folder**](Folder) — children enumeration (use **For Each** — see the warning on [**Count**](Folder#count) / [**Item**](Folder#item) — the IDE is multi-threaded and index-based iteration races), [**IsPackagesFolder**](Folder#ispackagesfolder). -- [**File**](File) — virtual-FS file accessors: [**Data**](File#data) (raw bytes), [**Text**](File#text) (decoded text), [**ReadText**](File#readtext) (text with options like comment-stripping), [**IsDirty**](File#isdirty). +- [**Project**](Project) -- the currently-loaded project. Lifecycle ([**Save**](Project#save), [**Close**](Project#close), [**Build**](Project#build), [**Clean**](Project#clean)), introspection ([**Name**](Project#name), [**Path**](Project#path), [**ProjectID**](Project#projectid), version + architecture + build-output info), the [**Evaluate**](Project#evaluate) hook into the debug-console expression engine, the [**RootFolder**](Project#rootfolder) entry into the virtual file system, and the [**LoadMetaData**](Project#loadmetadata) / [**SaveMetaData**](Project#savemetadata) pair for persistent per-addin key/value storage inside the `.twinproj` file. +- [**Editor**](Editor) -- the base editor interface (Path, Type, SetFocus, Close, Save, IsDirty). Castable to [**CodeEditor**](CodeEditor). +- [**CodeEditor**](CodeEditor) -- a code-pane editor: selection, full text, Monaco passthrough ([**ExecuteMonacoCommand**](CodeEditor#executemonacocommand)), inline overlay HTML ([**AddMonacoWidget**](CodeEditor#addmonacowidget)). +- [**Editors**](Editors) -- the collection of active editors. `Editors(0)` is the current editor; [**Open**](Editors#open) jumps to a file (and optional line/column). +- [**FileSystem**](FileSystem) -- the virtual file system. [**RootFolder**](FileSystem#rootfolder), [**ResolvePath**](FileSystem#resolvepath). +- [**FileSystemItem**](FileSystemItem) -- the base for [**File**](File) and [**Folder**](Folder). `Name`, `Path`, `Type`, `Parent`. +- [**Folder**](Folder) -- children enumeration (prefer **For Each** --- see the warning on [**Count**](Folder#count) / [**Item**](Folder#item) --- the IDE is multi-threaded and index-based iteration races), [**IsPackagesFolder**](Folder#ispackagesfolder). +- [**File**](File) -- virtual-FS file accessors: [**Data**](File#data) (raw bytes), [**Text**](File#text) (decoded text), [**ReadText**](File#readtext) (text with options like comment-stripping), [**IsDirty**](File#isdirty). ### IDE UI -- [**Toolbar**](Toolbar) — the IDE toolbar. [**AddSplitter**](Toolbar#addsplitter), [**AddButton**](Toolbar#addbutton). -- [**Toolbars**](Toolbars) — the toolbar collection. Currently there is only one toolbar, addressable as `Toolbars(0)`. -- [**Button**](Button) — a toolbar button created by [**AddButton**](Toolbar#addbutton). Exposes [**OnClick**](Button#onclick). -- [**ToolWindow**](ToolWindow) — a dockable / floating HTML-rendered tool window. [**Title**](ToolWindow#title), [**Visible**](ToolWindow#visible), [**Resizable**](ToolWindow#resizable), [**RootDomElement**](ToolWindow#rootdomelement), [**ApplyCss**](ToolWindow#applycss), [**OnClose**](ToolWindow#onclose). -- [**ToolWindows**](ToolWindows) — the tool-window factory: [**Add**](ToolWindows#add) creates a new one. +- [**Toolbar**](Toolbar) -- the IDE toolbar. [**AddSplitter**](Toolbar#addsplitter), [**AddButton**](Toolbar#addbutton). +- [**Toolbars**](Toolbars) -- the toolbar collection. Currently a single toolbar, addressable as `Toolbars(0)`. +- [**Button**](Button) -- a toolbar button created by [**AddButton**](Toolbar#addbutton). Exposes [**OnClick**](Button#onclick). +- [**ToolWindow**](ToolWindow) -- a dockable / floating HTML-rendered tool window. [**Title**](ToolWindow#title), [**Visible**](ToolWindow#visible), [**Resizable**](ToolWindow#resizable), [**RootDomElement**](ToolWindow#rootdomelement), [**ApplyCss**](ToolWindow#applycss), [**OnClose**](ToolWindow#onclose). +- [**ToolWindows**](ToolWindows) -- the tool-window factory: [**Add**](ToolWindows#add) creates a new one. ### Tool-window DOM and events -The four `Html*` classes are the addin's keyhole into the DOM inside a tool window. All four are declared with `[COMExtensible(True)]` — see [Dynamic DOM property resolution](#dynamic-dom-property-resolution). +The four `Html*` classes are the addin's view into the DOM inside a tool window. All four are declared with `[COMExtensible(True)]` --- see [Dynamic DOM property resolution](#dynamic-dom-property-resolution). -- [**HtmlElement**](HtmlElement) — one DOM element. [**Properties**](HtmlElement#properties), [**ChildDomElements**](HtmlElement#childdomelements), [**Remove**](HtmlElement#remove), [**AddEventListener**](HtmlElement#addeventlistener). -- [**HtmlElements**](HtmlElements) — the child-element collection. [**Item**](HtmlElements#item) and [**Add**](HtmlElements#add) — the latter accepts standard HTML tags **and** the IDE's custom-widget tags `"chartjs"`, `"monaco"`, `"listview"`, `"virtuallistview"`. -- [**HtmlElementProperty**](HtmlElementProperty) — one settable property in the bag. -- [**HtmlElementProperties**](HtmlElementProperties) — the dynamic property bag on a DOM element. -- [**HtmlEventProperty**](HtmlEventProperty) — one read-only value in an event payload. -- [**HtmlEventProperties**](HtmlEventProperties) — the dynamic event-payload bag passed to every [**AddEventListener**](HtmlElement#addeventlistener) callback. +- [**HtmlElement**](HtmlElement) -- one DOM element. [**Properties**](HtmlElement#properties), [**ChildDomElements**](HtmlElement#childdomelements), [**Remove**](HtmlElement#remove), [**AddEventListener**](HtmlElement#addeventlistener). +- [**HtmlElements**](HtmlElements) -- the child-element collection. [**Item**](HtmlElements#item) and [**Add**](HtmlElements#add) --- the latter accepts standard HTML tags **and** the IDE's custom-widget tags `"chartjs"`, `"monaco"`, `"listview"`, `"virtuallistview"`. +- [**HtmlElementProperty**](HtmlElementProperty) -- one settable property in the bag. +- [**HtmlElementProperties**](HtmlElementProperties) -- the dynamic property bag on a DOM element. +- [**HtmlEventProperty**](HtmlEventProperty) -- one read-only value in an event payload. +- [**HtmlEventProperties**](HtmlEventProperties) -- the dynamic event-payload bag passed to every [**AddEventListener**](HtmlElement#addeventlistener) callback. ### Singletons -- [**DebugConsole**](DebugConsole) — the DEBUG CONSOLE pane. [**PrintText**](DebugConsole#printtext), [**Clear**](DebugConsole#clear), [**SetFocus**](DebugConsole#setfocus). -- [**KeyboardShortcuts**](KeyboardShortcuts) — global IDE keyboard shortcuts. [**Add**](KeyboardShortcuts#add). -- [**Themes**](Themes) — the IDE's active theme. [**ActiveThemeName**](Themes#activethemename), [**ActiveThemeNameGroup**](Themes#activethemenamegroup). +- [**DebugConsole**](DebugConsole) -- the DEBUG CONSOLE pane. [**PrintText**](DebugConsole#printtext), [**Clear**](DebugConsole#clear), [**SetFocus**](DebugConsole#setfocus). +- [**KeyboardShortcuts**](KeyboardShortcuts) -- IDE-wide keyboard shortcuts. [**Add**](KeyboardShortcuts#add). +- [**Themes**](Themes) -- the IDE's active theme. [**ActiveThemeName**](Themes#activethemename), [**ActiveThemeNameGroup**](Themes#activethemenamegroup). ## Dynamic DOM property resolution -The four `Html*` classes that have the `[COMExtensible(True)]` attribute — [**HtmlElementProperties**](HtmlElementProperties), [**HtmlElementProperty**](HtmlElementProperty), [**HtmlEventProperties**](HtmlEventProperties), [**HtmlEventProperty**](HtmlEventProperty) — accept **arbitrary property names** that are resolved against the underlying DOM element (or event object) at run time. None of `style`, `innerText`, `chart`, `editor`, `listview`, `value`, `target`, `key`, `index`, …, are declared statically on the interfaces — they are all resolved dynamically through the COM-extensible `Item(name)` default member. +The four `Html*` classes that have the `[COMExtensible(True)]` attribute --- [**HtmlElementProperties**](HtmlElementProperties), [**HtmlElementProperty**](HtmlElementProperty), [**HtmlEventProperties**](HtmlEventProperties), [**HtmlEventProperty**](HtmlEventProperty) --- accept **arbitrary property names** that are resolved against the underlying DOM element (or event object) at run time. None of `style`, `innerText`, `chart`, `editor`, `listview`, `value`, `target`, `key`, `index`, …, are declared statically on the interfaces --- they are all resolved dynamically through the COM-extensible `Item(name)` default member. So: @@ -130,16 +130,16 @@ reads at run time as: .Item("innerText").Value = "Section heading" ``` -The compiler does not validate the property names; they are forwarded as strings to the IDE's tool-window renderer. The accepted set is **every DOM property of the underlying tag** — standard HTML attributes, every CSS-style property under `.style.…`, plus any custom-widget-specific properties like `.chart.data.datasets(0).borderWidth` on a `"chartjs"` element or `.editor.setOption(...)` on a `"monaco"` element. The reference does not enumerate them — defer to MDN for standard DOM property names, to Chart.js for `chartjs` widgets, to Monaco's documentation for `monaco` widgets, and to the matching samples below for the IDE-specific `listview` / `virtuallistview` properties. +The compiler does not validate the property names; they are forwarded as strings to the IDE's tool-window renderer. The accepted set is **every DOM property of the underlying tag** --- standard HTML attributes, every CSS-style property under `.style.…`, plus any custom-widget-specific properties like `.chart.data.datasets(0).borderWidth` on a `"chartjs"` element or `.editor.setOption(...)` on a `"monaco"` element. The reference does not enumerate them --- defer to MDN for standard DOM property names, to Chart.js for `chartjs` widgets, to Monaco's documentation for `monaco` widgets, and to the matching samples below for the IDE-specific `listview` / `virtuallistview` properties. ## Tool-window DOM tags [**HtmlElements.Add**](HtmlElements#add) takes a *TagName* string. Standard HTML tags (`"div"`, `"span"`, `"input"`, `"h1"`, `"label"`, `"img"`, …) work as expected; in addition, the IDE provides four custom-widget tags: -- **`"chartjs"`** — wraps **Chart.js**. The element exposes a `.chart` property whose sub-properties mirror Chart.js's `data` / `options` / `config` namespaces. See sample 11. -- **`"monaco"`** — embeds an instance of the **Monaco editor** (the same editor the IDE itself uses for code panes). The element exposes an `.editor` property with `setOption`, `setValue`, `getValue`, and `AddEventListener` (note: event listeners attach to `.editor`, not to the DOM element). See sample 12. -- **`"listview"`** — the IDE's built-in listview widget. The element exposes a `.listview` property with `addItem`, `removeItem`, `getItem`, `setShowScrollbarV` / `setShowScrollbarH`, and the events `onClickItem` / `onDblClickItem`. See sample 13. -- **`"virtuallistview"`** — a virtual variant of the listview suitable for huge data sets (millions of rows). The element exposes the same `.listview` property plus `setItemCount` and the asynchronous `onAsyncGetItemHTML` event (the listener responds via `eventInfo.setAsyncResult("<html>")`); call `.listview.notifyChangedItem(idx)` to invalidate the internal cache for one row when its underlying data changes. See sample 14. +- **`"chartjs"`** --- wraps **Chart.js**. The element exposes a `.chart` property whose sub-properties mirror Chart.js's `data` / `options` / `config` namespaces. See sample 11. +- **`"monaco"`** --- embeds an instance of the **Monaco editor** (the same editor the IDE itself uses for code panes). The element exposes an `.editor` property with `setOption`, `setValue`, `getValue`, and `AddEventListener` (note: event listeners attach to `.editor`, not to the DOM element). See sample 12. +- **`"listview"`** --- the IDE's built-in listview widget. The element exposes a `.listview` property with `addItem`, `removeItem`, `getItem`, `setShowScrollbarV` / `setShowScrollbarH`, and the events `onClickItem` / `onDblClickItem`. See sample 13. +- **`"virtuallistview"`** --- a virtual variant of the listview suitable for huge data sets (millions of rows). The element exposes the same `.listview` property plus `setItemCount` and the asynchronous `onAsyncGetItemHTML` event (the listener responds via `eventInfo.setAsyncResult("<html>")`); call `.listview.notifyChangedItem(idx)` to invalidate the internal cache for one row when its underlying data changes. See sample 14. The full per-widget properties and methods are documented by each widget's home project; this package wraps them through the same `[COMExtensible(True)]` mechanism described above. @@ -149,7 +149,7 @@ Six worked addins ship in the twinBASIC samples folder. They are the canonical r | Sample | Project | What it teaches | |--------|---------|-----------------| -| 10 | `WaynesWorldAddInTest1` | The kitchen-sink walkthrough — toolbar setup, a single big tool window populated with 22 styled `div`-buttons that each exercise a different `Host.*` capability. Start here. | +| 10 | `WaynesWorldAddInTest1` | The kitchen-sink tour --- toolbar setup, a single big tool window populated with 22 styled `div`-buttons that each exercise a different `Host.*` capability. Start here. | | 11 | `WaynesWorldCPUMonitorTest1` | [**AddinTimer**](AddinTimer) + a `"chartjs"` custom-widget tool window powering a live line chart. | | 12 | `WaynesWorldMonacoEditorTest1` | A `"monaco"` custom-widget tool window: an in-window Monaco editor with `setValue` / `getValue` and a content-change listener. | | 13 | `WaynesListViewAddIn` | A `"listview"` custom-widget tool window with `ApplyCss`, double-click-to-remove behaviour, and inline-HTML `raiseEvent()` for custom event names. | diff --git a/docs/Tutorials/CEF/Building a browser shell.md b/docs/Tutorials/CEF/Building a browser shell.md index a1d6a1f0..276afb5a 100644 --- a/docs/Tutorials/CEF/Building a browser shell.md +++ b/docs/Tutorials/CEF/Building a browser shell.md @@ -10,15 +10,15 @@ permalink: /Tutorials/CEF/Building-A-Browser-Shell A short worked tutorial: turn a [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control into a working browser with an address bar, back / forward / reload buttons, zoom, and a few helpers (DevTools, PDF export). -The complete project ships as *Sample 1b — Chromium Embedded Framework Examples* in the New-Project dialog (form *Example 1*). This tutorial describes its key pieces. +The complete project ships as *Sample 1b --- Chromium Embedded Framework Examples* in the New-Project dialog (form *Example 1*). This tutorial describes its key pieces. ## The form -Drop a [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control onto a Form and rename it `WebView`. Around it, add a `TextBox` named `AddressBar` plus six `CommandButton`s — `btnBack`, `btnForward`, `btnRefresh`, `btnZoomIn`, `btnZoomOut`, `btnPDF`, `btnDevTools`. +Drop a [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control onto a Form and rename it `WebView`. Around it, add a `TextBox` named `AddressBar` plus six `CommandButton`s --- `btnBack`, `btnForward`, `btnRefresh`, `btnZoomIn`, `btnZoomOut`, `btnPDF`, `btnDevTools`. ## Navigating -The bare-bones navigation methods — [**Navigate**](../../tB/Packages/CEF/CefBrowser/#navigate), [**GoBack**](../../tB/Packages/CEF/CefBrowser/#goback), [**GoForward**](../../tB/Packages/CEF/CefBrowser/#goforward), [**Reload**](../../tB/Packages/CEF/CefBrowser/#reload) — are one-liners: +The bare-bones navigation methods --- [**Navigate**](../../tB/Packages/CEF/CefBrowser/#navigate), [**GoBack**](../../tB/Packages/CEF/CefBrowser/#goback), [**GoForward**](../../tB/Packages/CEF/CefBrowser/#goforward), [**Reload**](../../tB/Packages/CEF/CefBrowser/#reload) --- are one-liners: ```tb Private Sub btnBack_Click() Handles btnBack.Click @@ -46,11 +46,11 @@ End Sub ``` > [!NOTE] -> *IsSuccess* and *WebErrorStatus* are part of the event signature but currently return placeholder values (`True` and `0`) — use [**DocumentURL**](../../tB/Packages/CEF/CefBrowser/#documenturl) to confirm where the browser actually landed. +> *IsSuccess* and *WebErrorStatus* are part of the event signature but currently return placeholder values (`True` and `0`) --- use [**DocumentURL**](../../tB/Packages/CEF/CefBrowser/#documenturl) to confirm where the browser actually landed. ## The address bar -Pressing **Enter** in the address bar triggers a navigation. The reverse direction — keeping the visible URL in sync with the page — is the [**SourceChanged**](../../tB/Packages/CEF/CefBrowser/#sourcechanged) event, which fires whenever [**DocumentURL**](../../tB/Packages/CEF/CefBrowser/#documenturl) changes (including same-document `history.pushState` updates): +Pressing **Enter** in the address bar triggers a navigation. The reverse direction --- keeping the visible URL in sync with the page --- is the [**SourceChanged**](../../tB/Packages/CEF/CefBrowser/#sourcechanged) event, which fires whenever [**DocumentURL**](../../tB/Packages/CEF/CefBrowser/#documenturl) changes (including same-document `history.pushState` updates): ```tb Private Sub AddressBar_KeyDown(KeyCode As Integer, Shift As Integer) _ @@ -64,11 +64,11 @@ Private Sub WebView_SourceChanged(ByVal IsNewDocument As Boolean) _ End Sub ``` -[**Navigate**](../../tB/Packages/CEF/CefBrowser/#navigate) requires a full URI with scheme — `http://`, `https://`, `file://`, … Unlike [**WebView2**](../../tB/Packages/WebView2/WebView2/#navigate), no automatic `https://` prefix is added when the scheme is missing. +[**Navigate**](../../tB/Packages/CEF/CefBrowser/#navigate) requires a full URI with scheme --- `http://`, `https://`, `file://`, … Unlike [**WebView2**](../../tB/Packages/WebView2/WebView2/#navigate), no automatic `https://` prefix is added when the scheme is missing. ## Zoom -[**ZoomFactor**](../../tB/Packages/CEF/CefBrowser/#zoomfactor) is a **Double** — `1.0` is 100%, `1.5` is 150%. The value reads as `0` until the browser has reached [**Ready**](../../tB/Packages/CEF/CefBrowser/#ready), so arithmetic that multiplies the current value silently starts from zero unless you clamp first: +[**ZoomFactor**](../../tB/Packages/CEF/CefBrowser/#zoomfactor) is a **Double** --- `1.0` is 100%, `1.5` is 150%. The value reads as `0` until the browser has reached [**Ready**](../../tB/Packages/CEF/CefBrowser/#ready), so arithmetic that multiplies the current value silently starts from zero unless you clamp first: ```tb Private Sub btnZoomIn_Click() Handles btnZoomIn.Click @@ -88,7 +88,7 @@ The `On Error Resume Next` catches the "control not ready" error that fires when ## PDF export -[**PrintToPdf**](../../tB/Packages/CEF/CefBrowser/#printtopdf) saves the current document to disk asynchronously — the result arrives as [**PrintToPdfCompleted**](../../tB/Packages/CEF/CefBrowser/#printtopdfcompleted) or [**PrintToPdfFailed**](../../tB/Packages/CEF/CefBrowser/#printtopdffailed): +[**PrintToPdf**](../../tB/Packages/CEF/CefBrowser/#printtopdf) saves the current document to disk asynchronously --- the result arrives as [**PrintToPdfCompleted**](../../tB/Packages/CEF/CefBrowser/#printtopdfcompleted) or [**PrintToPdfFailed**](../../tB/Packages/CEF/CefBrowser/#printtopdffailed): ```tb Private Sub btnPDF_Click() Handles btnPDF.Click @@ -102,7 +102,7 @@ Private Sub WebView_PrintToPdfCompleted() Handles WebView.PrintToPdfCompleted End Sub ``` -The optional parameters that follow *outputPath* — [**cefPrintOrientation**](../../tB/Packages/CEF/Enumerations/cefPrintOrientation), page size in microns, margins, header/footer toggles — let the host override Chromium's defaults. See the [**PrintToPdf** reference](../../tB/Packages/CEF/CefBrowser/#printtopdf) for the full signature. +The optional parameters that follow *outputPath* --- [**cefPrintOrientation**](../../tB/Packages/CEF/Enumerations/cefPrintOrientation), page size in microns, margins, header/footer toggles --- let the host override Chromium's defaults. See the [**PrintToPdf** reference](../../tB/Packages/CEF/CefBrowser/#printtopdf) for the full signature. ## DevTools @@ -114,7 +114,7 @@ Private Sub btnDevTools_Click() Handles btnDevTools.Click End Sub ``` -The CEF package does not currently expose **WebView2**'s **OpenTaskManagerWindow** equivalent — see the [WebView2 parity](../../tB/Packages/CEF/#webview2-parity) section of the reference for the current gap list. +The CEF package does not currently expose **WebView2**'s **OpenTaskManagerWindow** equivalent --- see the [WebView2 parity](../../tB/Packages/CEF/#webview2-parity) section of the reference for the current gap list. ## Form-title sync @@ -128,7 +128,7 @@ End Sub ## Where next -- [Hosting local web assets](Hosting-Local-Web-Assets) — serve HTML / JS / CSS from a folder without an HTTP server. -- [JavaScript interop](JavaScript-Interop) — pass values and method calls between BASIC and the page. -- [Re-entrancy](Re-entrancy) — the one thing to know about [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) before you use it. -- [CefBrowser reference](../../tB/Packages/CEF/CefBrowser/) — every property, method, and event. +- [Hosting local web assets](Hosting-Local-Web-Assets) -- serve HTML / JS / CSS from a folder without an HTTP server. +- [JavaScript interop](JavaScript-Interop) -- pass values and method calls between BASIC and the page. +- [Re-entrancy](Re-entrancy) -- the one thing to know about [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) before you use it. +- [CefBrowser reference](../../tB/Packages/CEF/CefBrowser/) -- every property, method, and event. diff --git a/docs/Tutorials/CEF/Customize the UserDataFolder.md b/docs/Tutorials/CEF/Customize the UserDataFolder.md index aceb10c8..6db22eb4 100644 --- a/docs/Tutorials/CEF/Customize the UserDataFolder.md +++ b/docs/Tutorials/CEF/Customize the UserDataFolder.md @@ -8,11 +8,11 @@ permalink: /Tutorials/CEF/Customize-UserDataFolder # Customize the UserDataFolder -At runtime, CEF needs a working folder for the user profile — cache, cookies, history, local storage, password manager, and the per-instance lock file that prevents two browser processes from sharing the same profile. By default the runtime picks a folder under `%LocalAppData%\twinBASIC_CEF\<ProjectName>\instance-<N>\`, but that default is not always appropriate. +At runtime, CEF needs a working folder for the user profile --- cache, cookies, history, local storage, password manager, and the per-instance lock file that prevents two browser processes from sharing the same profile. By default the runtime picks a folder under `%LocalAppData%\twinBASIC_CEF\<ProjectName>\instance-<N>\`, but that default is not always appropriate. A few situations where the default goes wrong: -- **Office add-ins**, where the host process is `MSACCESS.EXE` or `EXCEL.EXE` — the default per-process layout interferes with the host's own profile. +- **Office add-ins**, where the host process is `MSACCESS.EXE` or `EXCEL.EXE` --- the default per-process layout interferes with the host's own profile. - **Kiosk installations**, where the application runs under a low-privilege account that can't write under `%LocalAppData%`. - **Portable deployments**, where all state must live next to the executable on a USB stick or network share. - **Multi-user / hosted scenarios**, where each end-user needs an isolated profile. @@ -26,7 +26,7 @@ Private Sub CefBrowser1_Create() End Sub ``` -The folder is created automatically if it doesn't exist. The path must be writable by the current user — a read-only path raises the [**Error**](../../tB/Packages/CEF/CefBrowser/#error) event when the helper browser process tries to launch. +The folder is created automatically if it doesn't exist. The path must be writable by the current user --- a read-only path raises the [**Error**](../../tB/Packages/CEF/CefBrowser/#error) event when the helper browser process tries to launch. ## Why the Create event @@ -34,9 +34,9 @@ CEF reads the environment options *once*, when the helper browser process is lau ## Sharing a folder across instances -A single user-data folder cannot be opened by two CEF processes at once — the runtime takes an exclusive lock on it for the lifetime of the browser process. Two **CefBrowser** controls in the *same* application share the helper process and therefore the same lock, so they cooperate fine; two *separate* applications pointing at the same folder collide. +A single user-data folder cannot be opened by two CEF processes at once --- the runtime takes an exclusive lock on it for the lifetime of the browser process. Two **CefBrowser** controls in the *same* application share the helper process and therefore the same lock, so they cooperate fine; two *separate* applications pointing at the same folder collide. -When a collision is detected and [**UserDataFolder**](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions#userdatafolder) is left at its default, the control automatically retries with the next `instance-N` sub-folder. When the host has explicitly set a path, the lock failure instead appears as a CEF initialisation error (*"CEF cache path already locked by another process"*) — handle it in the [**Error**](../../tB/Packages/CEF/CefBrowser/#error) event: +When a collision is detected and [**UserDataFolder**](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions#userdatafolder) is left at its default, the control automatically retries with the next `instance-N` sub-folder. When the host has explicitly set a path, the lock failure instead appears as a CEF initialisation error (*"CEF cache path already locked by another process"*) --- handle it in the [**Error**](../../tB/Packages/CEF/CefBrowser/#error) event: ```tb Private Sub CefBrowser1_Error(ByVal code As Long, ByVal msg As String) @@ -62,9 +62,9 @@ Private Sub CefBrowser1_Create() End Sub ``` -[**LogFilePath**](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions#logfilepath) is appended to across runs — rotate or delete it from your own code if it needs to be capped. [**LogSeverity**](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions#logseverity) controls the threshold; **CefLogDisable** (the default) writes nothing regardless of the path. +[**LogFilePath**](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions#logfilepath) is appended to across runs --- rotate or delete it from your own code if it needs to be capped. [**LogSeverity**](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions#logseverity) controls the threshold; **CefLogDisable** (the default) writes nothing regardless of the path. ## See also -- [CefEnvironmentOptions](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions) — full reference for the pre-creation options. -- [Customize the UserDataFolder (WebView2)](../WebView2/Customize-UserDataFolder) — the same idea applied to the [**WebView2**](../../tB/Packages/WebView2/WebView2/) control. +- [CefEnvironmentOptions](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions) -- full reference for the pre-creation options. +- [Customize the UserDataFolder (WebView2)](../WebView2/Customize-UserDataFolder) -- the same idea applied to the [**WebView2**](../../tB/Packages/WebView2/WebView2/) control. diff --git a/docs/Tutorials/CEF/Driving Monaco.md b/docs/Tutorials/CEF/Driving Monaco.md index 56b1e0b7..1b57ae7e 100644 --- a/docs/Tutorials/CEF/Driving Monaco.md +++ b/docs/Tutorials/CEF/Driving Monaco.md @@ -8,9 +8,9 @@ permalink: /Tutorials/CEF/Driving-Monaco # Driving Monaco from twinBASIC -A case study combining everything from the previous tutorials: a form with **two** [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) controls — the Microsoft Monaco editor on the left, a live HTML preview on the right. As the user types, Monaco posts the edited source to twinBASIC, which mirrors it into the preview pane. +A case study combining everything from the previous tutorials: a form with **two** [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) controls --- the Microsoft Monaco editor on the left, a live HTML preview on the right. As the user types, Monaco posts the edited source to twinBASIC, which mirrors it into the preview pane. -The complete project ships as *Sample 1b — Chromium Embedded Framework Examples* in the New-Project dialog (form *Example 3*). +The complete project ships as *Sample 1b --- Chromium Embedded Framework Examples* in the New-Project dialog (form *Example 3*). ## Architecture @@ -28,11 +28,11 @@ If WebView.CefMajorVersion < 109 Then End If ``` -In practice this means **v109** or **v145** for this tutorial — **v49** lacks the JavaScript API Monaco depends on. See [Getting started](Getting-Started) for picking the right package reference. +In practice this means **v109** or **v145** for this tutorial --- **v49** lacks the JavaScript API Monaco depends on. See [Getting started](Getting-Started) for picking the right package reference. ## Setting up the editor's assets -The Monaco editor ships as a ~2 MB collection of JavaScript, CSS, and font files. Drop them into a `Resources` sub-folder of your project — call it `MONACO_DEMO` — alongside an `index.html` and a small bootstrap `script.js`. The [Hosting local web assets](Hosting-Local-Web-Assets) tutorial describes the layout. +The Monaco editor ships as a ~2 MB collection of JavaScript, CSS, and font files. Drop them into a `Resources` sub-folder of your project --- call it `MONACO_DEMO` --- alongside an `index.html` and a small bootstrap `script.js`. The [Hosting local web assets](Hosting-Local-Web-Assets) tutorial describes the layout. The page itself is a single `<div id='container'>` plus the bootstrap script that listens for an *initial-content* message from the host: @@ -73,7 +73,7 @@ window.chrome.webview.addEventListener('message', (event) => { ## The BASIC side -Drop two `CefBrowser` controls on a form — `WebView` (the editor) and `WebViewPreview` (the renderer). The `Ready` handler deploys the assets, registers the virtual host, and navigates: +Drop two `CefBrowser` controls on a form --- `WebView` (the editor) and `WebViewPreview` (the renderer). The `Ready` handler deploys the assets, registers the virtual host, and navigates: ```tb Private localPath As String @@ -90,7 +90,7 @@ End Sub (`CopyResourcesFolderContentsToLocalPath` is the helper from [Hosting local web assets](Hosting-Local-Web-Assets).) -The two controls share a single helper browser process — the first **CefBrowser** to reach [**Ready**](../../tB/Packages/CEF/CefBrowser/#ready) launches it, the second one attaches to the existing process. That sharing is what makes the two-pane pattern cheap. +The two controls share a single helper browser process --- the first **CefBrowser** to reach [**Ready**](../../tB/Packages/CEF/CefBrowser/#ready) launches it, the second one attaches to the existing process. That sharing is what makes the two-pane pattern cheap. ## Pushing the initial content @@ -113,11 +113,11 @@ End Sub [**LoadResData**](../../tB/Packages/VB/Global/#loadresdata) returns the resource bytes; `StrConv(..., vbFromUTF8)` decodes them. [**PostWebMessage**](../../tB/Packages/CEF/CefBrowser/#postwebmessage) hands the string to Monaco's `message` listener; [**NavigateToString**](../../tB/Packages/CEF/CefBrowser/#navigatetostring) seeds the preview pane with the same text rendered as HTML. -The `If` guard at the top is important — [**NavigationComplete**](../../tB/Packages/CEF/CefBrowser/#navigationcomplete) fires for *every* navigation, including internal Monaco asset loads. Only seed the editor on the navigation to `index.html`. +The `If` guard at the top is important --- [**NavigationComplete**](../../tB/Packages/CEF/CefBrowser/#navigationcomplete) fires for *every* navigation, including internal Monaco asset loads. Only seed the editor on the navigation to `index.html`. ## Live preview -Every keystroke in Monaco fires its `onDidChangeModelContent` callback, which `postMessage`s the new content back to BASIC. That arrives as the [**JsMessage**](../../tB/Packages/CEF/CefBrowser/#jsmessage) event — feed it straight into the preview: +Every keystroke in Monaco fires its `onDidChangeModelContent` callback, which `postMessage`s the new content back to BASIC. That arrives as the [**JsMessage**](../../tB/Packages/CEF/CefBrowser/#jsmessage) event --- feed it straight into the preview: ```tb Private Sub WebView_JsMessage(ByVal Message As Variant) Handles WebView.JsMessage @@ -125,7 +125,7 @@ Private Sub WebView_JsMessage(ByVal Message As Variant) Handles WebView.JsMessag End Sub ``` -That's it — the preview pane re-renders on every edit. +That's it --- the preview pane re-renders on every edit. ## Detecting a missing runtime @@ -144,8 +144,8 @@ The fix is to install the matching runtime ZIP from [github.com/twinbasic/cef-ru ## Where next -- [Hosting local web assets](Hosting-Local-Web-Assets) — the `CopyResourcesFolderContentsToLocalPath` helper and virtual-host pattern this tutorial builds on. -- [JavaScript interop](JavaScript-Interop) — the two bridges between BASIC and JavaScript. -- [Re-entrancy](Re-entrancy) — why the live-preview pattern is safe even though it's mostly synchronous-looking. -- [CefBrowser reference](../../tB/Packages/CEF/CefBrowser/) — every property, method, and event. -- [Driving Monaco (WebView2)](../WebView2/Driving-Monaco) — the parallel implementation using the [**WebView2**](../../tB/Packages/WebView2/WebView2/) control. +- [Hosting local web assets](Hosting-Local-Web-Assets) -- the `CopyResourcesFolderContentsToLocalPath` helper and virtual-host pattern this tutorial builds on. +- [JavaScript interop](JavaScript-Interop) -- the two bridges between BASIC and JavaScript. +- [Re-entrancy](Re-entrancy) -- why the live-preview pattern is safe even though it's mostly synchronous-looking. +- [CefBrowser reference](../../tB/Packages/CEF/CefBrowser/) -- every property, method, and event. +- [Driving Monaco (WebView2)](../WebView2/Driving-Monaco) -- the parallel implementation using the [**WebView2**](../../tB/Packages/WebView2/WebView2/) control. diff --git a/docs/Tutorials/CEF/Getting started.md b/docs/Tutorials/CEF/Getting started.md index 290a6ae7..52b51bc6 100644 --- a/docs/Tutorials/CEF/Getting started.md +++ b/docs/Tutorials/CEF/Getting started.md @@ -10,7 +10,7 @@ permalink: /Tutorials/CEF/Getting-Started ## Package requirements -To create a project that uses the CEF package, add the right compiler-package reference to your project. The package ships in three flavours — one per supported Chromium version — and you pick exactly one: +To create a project that uses the CEF package, add the right compiler-package reference to your project. The package ships in three flavours --- one per supported Chromium version --- and you pick exactly one: | Reference | Chromium baseline | Supported OS | |-----------------------------------------------------------------|-------------------|---------------| @@ -18,16 +18,16 @@ To create a project that uses the CEF package, add the right compiler-package re | **twinBASIC - Chromium Embedded Framework Package v109** | Chromium 109 | Windows 7+ | | **twinBASIC - Chromium Embedded Framework Package v145** | Chromium 145 | Windows 10+ | -Use **v145** unless you specifically need to support older operating systems. The package source compiles against all three — picking the reference sets the `CEF_VERSION` compiler constant, which selects the matching API. +Use **v145** unless you specifically need to support older operating systems. The package source compiles against all three --- picking the reference sets the `CEF_VERSION` compiler constant, which selects the matching API. Add the reference through **Project** → **References** (Ctrl-T) → **TWINPACK PACKAGES**. Tick the desired CEF package, close the dialog, and restart the compiler. Once added, **CefBrowser** appears in the form-designer toolbox. > [!WARNING] -> Older Chromium versions should not be used for browsing untrusted content from the public Internet — they carry unpatched security vulnerabilities. v49 and v109 remain appropriate for tightly controlled environments where the browser loads only trusted local or internal content; for general web browsing, use v145. +> Older Chromium versions should not be used for browsing untrusted content from the public Internet --- they carry unpatched security vulnerabilities. v49 and v109 remain appropriate for tightly controlled environments where the browser loads only trusted local or internal content; for general web browsing, use v145. ## Downloading the runtime -Unlike [**WebView2**](../../tB/Packages/WebView2/WebView2/), CEF does not rely on a system-installed runtime. The Chromium binaries (`libcef.dll` and friends) ship as a separate download and must be installed alongside the application — both during development and at deploy time. +Unlike [**WebView2**](../../tB/Packages/WebView2/WebView2/), CEF does not rely on a system-installed runtime. The Chromium binaries (`libcef.dll` and friends) ship as a separate download and must be installed alongside the application --- both during development and at deploy time. Download the runtime ZIP that matches both the CEF version and the application bitness: @@ -39,7 +39,7 @@ Download the runtime ZIP that matches both the CEF version and the application b See [CEF Runtime Releases](https://github.com/twinbasic/cef-runtimes/releases/) for the full version list and release notes. -Extract the ZIP into `%LocalAppData%\twinBASIC_CEF_Runtime\`. The version-stamped folder inside the ZIP — for example `145_0_7632_160_Win64` — must be placed directly under that path, containing `libcef.dll` and its sibling files: +Extract the ZIP into `%LocalAppData%\twinBASIC_CEF_Runtime\`. The version-stamped folder inside the ZIP --- for example `145_0_7632_160_Win64` --- must be placed directly under that path, containing `libcef.dll` and its sibling files: ```text %LocalAppData%\twinBASIC_CEF_Runtime\145_0_7632_160_Win64\libcef.dll @@ -49,7 +49,7 @@ Extract the ZIP into `%LocalAppData%\twinBASIC_CEF_Runtime\`. The version-stampe At startup, [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) searches this default location automatically. If `libcef.dll` cannot be found, the [**Error**](../../tB/Packages/CEF/CefBrowser/#error) event fires with the exact path that was searched. -To point at a different folder — for example a portable side-by-side deployment shipped with your installer — assign [**EnvironmentOptions.BrowserExecutableFolder**](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions#browserexecutablefolder) during the [**Create**](../../tB/Packages/CEF/CefBrowser/#create) event: +To point at a different folder --- for example a portable side-by-side deployment shipped with your installer --- assign [**EnvironmentOptions.BrowserExecutableFolder**](../../tB/Packages/CEF/CefBrowser/EnvironmentOptions#browserexecutablefolder) during the [**Create**](../../tB/Packages/CEF/CefBrowser/#create) event: ```tb Private Sub CefBrowser1_Create() @@ -60,7 +60,7 @@ End Sub ## Bitness must match -The runtime bitness must match the application bitness — a 32-bit twinBASIC build needs the Win32 runtime, a 64-bit build needs the Win64 runtime. Mixing them produces a `libcef.dll` load failure reported through the [**Error**](../../tB/Packages/CEF/CefBrowser/#error) event. +The runtime bitness must match the application bitness --- a 32-bit twinBASIC build needs the Win32 runtime, a 64-bit build needs the Win64 runtime. Mixing them produces a `libcef.dll` load failure reported through the [**Error**](../../tB/Packages/CEF/CefBrowser/#error) event. ## Create a CefBrowser control on a form @@ -72,7 +72,7 @@ Private Sub Form_Load() End Sub ``` -The control starts up asynchronously — the first user-visible event is [**Ready**](../../tB/Packages/CEF/CefBrowser/#ready), which fires once the helper browser process has launched and IPC has connected. Navigation, scripting, and most property accessors raise *"CefBrowser control is not ready"* (run-time error 5) before then. +The control starts up asynchronously --- the first user-visible event is [**Ready**](../../tB/Packages/CEF/CefBrowser/#ready), which fires once the helper browser process has launched and IPC has connected. Navigation, scripting, and most property accessors raise *"CefBrowser control is not ready"* (run-time error 5) before then. ## CefBrowser control properties @@ -82,10 +82,10 @@ For the full reference, see the [**CefBrowser** class reference](../../tB/Packag ## Samples -If you prefer to start with a sample, **Sample 1b — Chromium Embedded Framework Examples** is available in the new-project dialog. It mirrors **Sample 1a — WebView2 Examples** almost feature-for-feature, with the differences called out where the CEF package doesn't yet expose a WebView2 equivalent. +If you prefer to start with a sample, **Sample 1b --- Chromium Embedded Framework Examples** is available in the new-project dialog. It mirrors **Sample 1a --- WebView2 Examples** almost feature-for-feature, with the differences called out where the CEF package doesn't yet expose a WebView2 equivalent. ## Where next -- [Customize the UserDataFolder](Customize-UserDataFolder) — relocate the user-profile folder for Office add-ins, kiosks, or portable installs. -- [Building a browser shell](Building-A-Browser-Shell) — back / forward / reload / zoom / PDF. -- [Re-entrancy](Re-entrancy) — what the package protects you from and the one place you still have to think about. +- [Customize the UserDataFolder](Customize-UserDataFolder) -- relocate the user-profile folder for Office add-ins, kiosks, or portable installs. +- [Building a browser shell](Building-A-Browser-Shell) -- back / forward / reload / zoom / PDF. +- [Re-entrancy](Re-entrancy) -- what the package protects you from and the one place you still have to think about. diff --git a/docs/Tutorials/CEF/Hosting local web assets.md b/docs/Tutorials/CEF/Hosting local web assets.md index 2d91410f..a1b06456 100644 --- a/docs/Tutorials/CEF/Hosting local web assets.md +++ b/docs/Tutorials/CEF/Hosting local web assets.md @@ -8,13 +8,13 @@ permalink: /Tutorials/CEF/Hosting-Local-Web-Assets # Hosting local web assets -A [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control can serve HTML, JavaScript, CSS, and any other assets straight from a folder on disk — no embedded HTTP server required. Chromium's [**SetVirtualHostNameToFolderMapping**](../../tB/Packages/CEF/CefBrowser/#setvirtualhostnametofoldermapping) routes a virtual `https://` hostname to a local folder so that resources behave as if they came from a real origin: same-origin `fetch`, Content Security Policy, service workers, and so on all work as expected. +A [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control can serve HTML, JavaScript, CSS, and any other assets straight from a folder on disk --- no embedded HTTP server required. Chromium's [**SetVirtualHostNameToFolderMapping**](../../tB/Packages/CEF/CefBrowser/#setvirtualhostnametofoldermapping) routes a virtual `https://` hostname to a local folder so that resources behave as if they came from a real origin: same-origin `fetch`, Content Security Policy, service workers, and so on all work as expected. -This tutorial demonstrates the pattern used by *Sample 1b — Chromium Embedded Framework Examples* (forms *Example 2*, *Example 3*, *Example 4*). +This tutorial demonstrates the pattern used by *Sample 1b --- Chromium Embedded Framework Examples* (forms *Example 2*, *Example 3*, *Example 4*). ## The three-step pattern -1. **Choose a folder.** It must exist on disk and contain `index.html` (plus whatever assets the page wants — scripts, styles, images). +1. **Choose a folder.** It must exist on disk and contain `index.html` (plus whatever assets the page wants --- scripts, styles, images). 2. **Register a virtual host** mapping to that folder. 3. **Navigate** to a URL under the virtual hostname. @@ -32,7 +32,7 @@ End Sub Once mapped, every request to `https://myapp.example/<path>` is served from `folderPath\<path>`. A `<script src="/script.js">` on the page resolves to `folderPath\script.js` exactly as if a real web server were sitting on `myapp.example`. -The trailing backslash on the folder path is required — the runtime concatenates the incoming URL path onto the folder string verbatim, so a missing separator turns `folderPath` + `/index.html` into a nonsense path. +The trailing backslash on the folder path is required --- the runtime concatenates the incoming URL path onto the folder string verbatim, so a missing separator turns `folderPath` + `/index.html` into a nonsense path. ## Picking a hostname @@ -51,7 +51,7 @@ The `.example`, `.invalid`, and `.test` TLDs are formally reserved by IANA and w Most applications want to ship their HTML / JS / CSS *inside* the executable and drop them onto disk on first run. twinBASIC's `Resources` folder is the right place to keep them. 1. In the IDE's Project explorer, expand **Resources** and add a sub-folder (right-click → *Add new subfolder*). Name it something memorable like `WEB_APP`. -2. Drop the assets in — `index.html`, `script.js`, `styles.css`, plus any sub-directories you need. +2. Drop the assets in --- `index.html`, `script.js`, `styles.css`, plus any sub-directories you need. At runtime, the helper below copies the contents of a `Resources` sub-folder out to a local path. Drop it into a `.twin` module in your project: @@ -101,7 +101,7 @@ Module Files End Module ``` -[**LoadResIdList**](../../tB/Packages/VB/Global/#loadresidlist) returns every resource ID under the named sub-folder; [**LoadResData**](../../tB/Packages/VB/Global/#loadresdata) returns the bytes. The helper splits each resource name on `~` to reconstruct the original sub-directory tree on disk — the twinBASIC IDE flattens nested folders by joining their names with `~` when the resources are compiled in. +[**LoadResIdList**](../../tB/Packages/VB/Global/#loadresidlist) returns every resource ID under the named sub-folder; [**LoadResData**](../../tB/Packages/VB/Global/#loadresdata) returns the bytes. The helper splits each resource name on `~` to reconstruct the original sub-directory tree on disk --- the twinBASIC IDE flattens nested folders by joining their names with `~` when the resources are compiled in. ## Putting it together @@ -121,7 +121,7 @@ Private Sub WebView_Ready() Handles WebView.Ready End Sub ``` -Once deployed, the application can launch DevTools ([**OpenDevToolsWindow**](../../tB/Packages/CEF/CefBrowser/#opendevtoolswindow)) to inspect the loaded files, and users can edit `index.html` directly on disk and hit **Refresh** — useful for rapid iteration during development. +Once deployed, the application can launch DevTools ([**OpenDevToolsWindow**](../../tB/Packages/CEF/CefBrowser/#opendevtoolswindow)) to inspect the loaded files, and users can edit `index.html` directly on disk and hit **Refresh** --- useful for rapid iteration during development. ## Removing a mapping @@ -135,6 +135,6 @@ The browser keeps cached assets until a hard reload, so a navigation that hits t ## Where next -- [JavaScript interop](JavaScript-Interop) — how a hosted page exchanges values and method calls with the BASIC application. -- [Driving Monaco from twinBASIC](Driving-Monaco) — a full case study built on top of this pattern. -- [SetVirtualHostNameToFolderMapping](../../tB/Packages/CEF/CefBrowser/#setvirtualhostnametofoldermapping) — full reference. +- [JavaScript interop](JavaScript-Interop) -- how a hosted page exchanges values and method calls with the BASIC application. +- [Driving Monaco from twinBASIC](Driving-Monaco) -- a full case study built on top of this pattern. +- [SetVirtualHostNameToFolderMapping](../../tB/Packages/CEF/CefBrowser/#setvirtualhostnametofoldermapping) -- full reference. diff --git a/docs/Tutorials/CEF/JavaScript interop.md b/docs/Tutorials/CEF/JavaScript interop.md index 84d05117..851b9846 100644 --- a/docs/Tutorials/CEF/JavaScript interop.md +++ b/docs/Tutorials/CEF/JavaScript interop.md @@ -10,15 +10,15 @@ permalink: /Tutorials/CEF/JavaScript-Interop The [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control offers two complementary bridges between twinBASIC and the JavaScript running in the page: -1. **Messages** — push a value (string, number, …) in either direction and listen for it on the other side. -2. **Scripted calls** — call a named JavaScript function from BASIC and (optionally) wait for its return value. +1. **Messages** --- push a value (string, number, …) in either direction and listen for it on the other side. +2. **Scripted calls** --- call a named JavaScript function from BASIC and (optionally) wait for its return value. > [!NOTE] -> [**WebView2**](../../tB/Packages/WebView2/WebView2/) also exposes a third bridge — *host objects*, where a BASIC class is published under `chrome.webview.hostObjects.<Name>` for the page to call into. The CEF package does not yet expose an equivalent — see the [WebView2 parity](../../tB/Packages/CEF/#webview2-parity) section of the reference. +> [**WebView2**](../../tB/Packages/WebView2/WebView2/) also exposes a third bridge --- *host objects*, where a BASIC class is published under `chrome.webview.hostObjects.<Name>` for the page to call into. The CEF package does not yet expose an equivalent --- see the [WebView2 parity](../../tB/Packages/CEF/#webview2-parity) section of the reference. -This tutorial covers both bridges, with the matching JavaScript side shown next to each BASIC side. The worked code comes from *Sample 1b — Chromium Embedded Framework Examples* (form *Example 2*). +This tutorial covers both bridges, with the matching JavaScript side shown next to each BASIC side. The worked code comes from *Sample 1b --- Chromium Embedded Framework Examples* (form *Example 2*). -## Bridge 1 — Messages +## Bridge 1 --- Messages Messages are values that travel in either direction. Use them for notifications and ad-hoc payloads where you don't want to define a method signature ahead of time. @@ -38,7 +38,7 @@ window.chrome.webview.addEventListener('message', (e) => { Strings arrive as JavaScript strings; numerics, **Boolean**, **Null**, and **Empty** are JSON-encoded for the page. Objects and arrays are not currently supported. -If [**PostWebMessage**](../../tB/Packages/CEF/CefBrowser/#postwebmessage) is called before the renderer IPC has connected, the call is queued and dispatched once the connection comes up — there's no need to wait for [**Ready**](../../tB/Packages/CEF/CefBrowser/#ready) explicitly. +If [**PostWebMessage**](../../tB/Packages/CEF/CefBrowser/#postwebmessage) is called before the renderer IPC has connected, the call is queued and dispatched once the connection comes up --- there's no need to wait for [**Ready**](../../tB/Packages/CEF/CefBrowser/#ready) explicitly. ### Page → BASIC @@ -57,7 +57,7 @@ Private Sub WebView_JsMessage(ByVal Message As Variant) _ End Sub ``` -The two halves form a request / reply exchange — the page posts a query string, BASIC processes it and posts a result back: +The two halves form a request / reply exchange --- the page posts a query string, BASIC processes it and posts a result back: ```tb Private Sub WebView_JsMessage(ByVal Message As Variant) _ @@ -68,7 +68,7 @@ Private Sub WebView_JsMessage(ByVal Message As Variant) _ End Sub ``` -## Bridge 2 — Scripted calls +## Bridge 2 --- Scripted calls When the page exposes named JS functions, BASIC can call them directly. There are three variants: @@ -76,7 +76,7 @@ When the page exposes named JS functions, BASIC can call them directly. There ar |-----------------------------------------------------------------------------------|--------------------------------------------------|-------------------------------------------------------------------| | [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) | **Variant**, synchronously | You need the result inline and the JS is **pure** (no callbacks). | | [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync) | nothing; result via `JsAsyncResult` | The JS may take a while and you don't want to block the UI. | -| [**ExecuteScript**](../../tB/Packages/CEF/CefBrowser/#executescript) | nothing (fire-and-forget) | You just want to trigger something — no return value needed. | +| [**ExecuteScript**](../../tB/Packages/CEF/CefBrowser/#executescript) | nothing (fire-and-forget) | You just want to trigger something --- no return value needed. | ### JsRun (synchronous) @@ -98,7 +98,7 @@ Debug.Print product ' 30 The call blocks the BASIC thread until the renderer process replies. > [!WARNING] -> If the JavaScript function calls back into BASIC during the call — via `window.chrome.webview.postMessage(...)`, for instance — the result is a deadlock. Use [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) only for pure functions; reach for [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync) the moment that's not true. See the [Re-entrancy tutorial](Re-entrancy) for the full discussion. +> If the JavaScript function calls back into BASIC during the call --- via `window.chrome.webview.postMessage(...)`, for instance --- the result is a deadlock. Use [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) only for pure functions; reach for [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync) the moment that's not true. See the [Re-entrancy tutorial](Re-entrancy) for the full discussion. ### JsRunAsync (asynchronous) @@ -132,7 +132,7 @@ No return value, no event. The simplest way to nudge the page into doing somethi ## Re-entrancy -The discussion of when calling synchronous JavaScript from BASIC is safe — and what to do when it isn't — lives in its own tutorial. The short summary: +The discussion of when calling synchronous JavaScript from BASIC is safe --- and what to do when it isn't --- lives in its own tutorial. The short summary: - **Pure JS** (input → output, no side effects that touch the host): [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) is fine. - **JS that might post back, await a host object, or otherwise re-enter BASIC**: use [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync). @@ -141,7 +141,7 @@ See the [Re-entrancy tutorial](Re-entrancy) for the full picture. ## Where next -- [Hosting local web assets](Hosting-Local-Web-Assets) — bundle and serve the JavaScript that talks to the host. -- [Driving Monaco from twinBASIC](Driving-Monaco) — a full case study using both bridges. -- [Re-entrancy](Re-entrancy) — the deeper story behind synchronous vs. asynchronous calls. -- [CefBrowser reference](../../tB/Packages/CEF/CefBrowser/) — every property, method, and event. +- [Hosting local web assets](Hosting-Local-Web-Assets) -- bundle and serve the JavaScript that talks to the host. +- [Driving Monaco from twinBASIC](Driving-Monaco) -- a full case study using both bridges. +- [Re-entrancy](Re-entrancy) -- the deeper story behind synchronous vs. asynchronous calls. +- [CefBrowser reference](../../tB/Packages/CEF/CefBrowser/) -- every property, method, and event. diff --git a/docs/Tutorials/CEF/Re-entrancy.md b/docs/Tutorials/CEF/Re-entrancy.md index 047ea8df..9a56ab7d 100644 --- a/docs/Tutorials/CEF/Re-entrancy.md +++ b/docs/Tutorials/CEF/Re-entrancy.md @@ -8,9 +8,9 @@ permalink: /Tutorials/CEF/Re-entrancy # Re-entrancy -The Chromium Embedded Framework runs the browser and renderer in *separate processes*, with cross-process IPC sitting between BASIC and the page. That model is fundamentally different from an in-process API, and it forces a particular discipline on host code: while a CEF callback is executing on the BASIC thread, the browser / renderer process is waiting for it to return — and calling *back* into the [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control during that wait can deadlock. +The Chromium Embedded Framework runs the browser and renderer in *separate processes*, with cross-process IPC sitting between BASIC and the page. That model is fundamentally different from an in-process API, and it forces a particular discipline on host code: while a CEF callback is executing on the BASIC thread, the browser / renderer process is waiting for it to return --- and calling *back* into the [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control during that wait can deadlock. -For the most part you don't have to think about any of this. The control raises every event onto the BASIC message loop via a posted message, so a handler that runs in response to a CEF callback has already returned control to the browser process by the time your code runs. The one place the rule still applies is [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) — the *synchronous* JavaScript bridge. +For the most part you don't have to think about any of this. The control raises every event onto the BASIC message loop via a posted message, so a handler that runs in response to a CEF callback has already returned control to the browser process by the time your code runs. The one place the rule still applies is [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) --- the *synchronous* JavaScript bridge. ## How the control protects you @@ -18,10 +18,10 @@ When the browser or renderer process raises a CEF callback that needs to appear 1. Captures the callback's arguments into a `Type` instance. 2. Calls `PostMessageW` to push a custom message onto the main thread's message queue. -3. Returns immediately — the browser process is unblocked. +3. Returns immediately --- the browser process is unblocked. 4. Later, when the form's message loop receives the posted message, the control raises the event on the BASIC side. -The handler runs *outside* the original CEF callback. By the time it executes, the browser process has moved on; the handler is free to call any [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) method or property — [**Navigate**](../../tB/Packages/CEF/CefBrowser/#navigate), [**ExecuteScript**](../../tB/Packages/CEF/CefBrowser/#executescript), [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync), even another [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) — without any re-entrancy concern. +The handler runs *outside* the original CEF callback. By the time it executes, the browser process has moved on; the handler is free to call any [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) method or property --- [**Navigate**](../../tB/Packages/CEF/CefBrowser/#navigate), [**ExecuteScript**](../../tB/Packages/CEF/CefBrowser/#executescript), [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync), even another [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) --- without any re-entrancy concern. This covers every event the control raises today: @@ -32,13 +32,13 @@ This covers every event the control raises today: ## The NavigationStarting exception -[**NavigationStarting**](../../tB/Packages/CEF/CefBrowser/#navigationstarting) is the one event that *cannot* be fully deferred — its `Cancel` parameter is **ByRef**, so the BASIC handler has to set it *before* the browser process can decide whether to proceed with the navigation. The control still uses `SendMessageW` (synchronous) rather than `PostMessageW` to deliver this event, which means the handler runs while the browser process is blocked waiting for the answer. +[**NavigationStarting**](../../tB/Packages/CEF/CefBrowser/#navigationstarting) is the one event that *cannot* be fully deferred --- its `Cancel` parameter is **ByRef**, so the BASIC handler has to set it *before* the browser process can decide whether to proceed with the navigation. The control still uses `SendMessageW` (synchronous) rather than `PostMessageW` to deliver this event, which means the handler runs while the browser process is blocked waiting for the answer. -The control adds an extra safety net for one specific case: if the renderer-IPC channel happens to be busy connecting at the same moment **NavigationStarting** fires (which can happen in older CEF versions during early page loads), a straight `SendMessageW` would deadlock — BASIC is waiting on the renderer; the renderer is waiting on BASIC. The control detects the situation and uses an interrupt-style mechanism to dispatch *just* the **NavigationStarting** handler on the UI thread without waiting for the renderer IPC. +The control adds an extra safety net for one specific case: if the renderer-IPC channel happens to be busy connecting at the same moment **NavigationStarting** fires (which can happen in older CEF versions during early page loads), a straight `SendMessageW` would deadlock --- BASIC is waiting on the renderer; the renderer is waiting on BASIC. The control detects the situation and uses an interrupt-style mechanism to dispatch *just* the **NavigationStarting** handler on the UI thread without waiting for the renderer IPC. -The practical consequence: **NavigationStarting** handlers should keep their work small — read [**Uri**](../../tB/Packages/CEF/CefBrowser/#navigationstarting), make a decision, set or leave [**Cancel**](../../tB/Packages/CEF/CefBrowser/#navigationstarting), return. Avoid synchronous round-trips of any kind from inside the handler — including [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun), [**MsgBox**](../../tB/Modules/Interaction/MsgBox), and file dialogs. +The practical consequence: **NavigationStarting** handlers should keep their work small --- read [**Uri**](../../tB/Packages/CEF/CefBrowser/#navigationstarting), make a decision, set or leave [**Cancel**](../../tB/Packages/CEF/CefBrowser/#navigationstarting), return. Avoid synchronous round-trips of any kind from inside the handler --- including [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun), [**MsgBox**](../../tB/Modules/Interaction/MsgBox), and file dialogs. -## JsRun — the explicit warning +## JsRun --- the explicit warning [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) is the synchronous JavaScript bridge: @@ -46,7 +46,7 @@ The practical consequence: **NavigationStarting** handlers should keep their wor Dim product As Long = CefBrowser1.JsRun("multiplyTheseNumbers", 5, 6) ``` -The call blocks the BASIC thread until the renderer process replies with the result. During that block, the renderer is running JavaScript; if that JavaScript calls back into BASIC — via `window.chrome.webview.postMessage(...)`, or via any host-object call that arrives on the BASIC thread — there is no thread available to *receive* the call. The renderer waits on BASIC; BASIC waits on the renderer. Deadlock. +The call blocks the BASIC thread until the renderer process replies with the result. During that block, the renderer is running JavaScript; if that JavaScript calls back into BASIC --- via `window.chrome.webview.postMessage(...)`, or via any host-object call that arrives on the BASIC thread --- there is no thread available to *receive* the call. The renderer waits on BASIC; BASIC waits on the renderer. Deadlock. The control's source includes this warning directly on the method: @@ -54,8 +54,8 @@ The control's source includes this warning directly on the method: The safe rule of thumb: -- Use [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) for **pure** JavaScript functions — ones that take inputs, compute, and return a value. No `postMessage`, no host-object calls, no `await` of anything that touches the host. -- Use [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync) for anything else — anywhere the JavaScript side might end up wanting to talk to BASIC during the call. +- Use [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun) for **pure** JavaScript functions --- ones that take inputs, compute, and return a value. No `postMessage`, no host-object calls, no `await` of anything that touches the host. +- Use [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync) for anything else --- anywhere the JavaScript side might end up wanting to talk to BASIC during the call. ```tb ' Safe — pure JavaScript: takes two numbers, returns one number. @@ -68,12 +68,12 @@ CefBrowser1.JsRunAsync "uploadAndReturnUrl", filePath ## Why the model is simpler than WebView2's -[**WebView2**](../../tB/Packages/WebView2/WebView2/) supports `AddObject` — publishing a BASIC COM object that JavaScript can call directly. That feature has its own re-entrancy story ([**UseDeferredInvoke**](../../tB/Packages/WebView2/WebView2/#addobject)) because page-initiated host-object calls must end up somewhere. +[**WebView2**](../../tB/Packages/WebView2/WebView2/) supports `AddObject` --- publishing a BASIC COM object that JavaScript can call directly. That feature has its own re-entrancy story ([**UseDeferredInvoke**](../../tB/Packages/WebView2/WebView2/#addobject)) because page-initiated host-object calls must end up somewhere. -CEF's host-object equivalent isn't exposed yet — see the [WebView2 parity](../../tB/Packages/CEF/#webview2-parity) section of the reference. The only synchronous BASIC ↔ JavaScript boundary CEF currently offers is **JsRun**, so the entire re-entrancy story reduces to *"don't post messages back to BASIC from inside a **JsRun** target"*. +CEF's host-object equivalent isn't exposed yet --- see the [WebView2 parity](../../tB/Packages/CEF/#webview2-parity) section of the reference. The only synchronous BASIC ↔ JavaScript boundary CEF currently offers is **JsRun**, so the entire re-entrancy story reduces to *"don't post messages back to BASIC from inside a **JsRun** target"*. ## See also -- [JavaScript interop](JavaScript-Interop) — practical patterns for choosing between [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun), [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync), and the message bridge. -- [CefBrowser reference](../../tB/Packages/CEF/CefBrowser/) — every property, method, and event. -- [WebView2 Re-entrancy tutorial](../WebView2/Re-entrancy) — the parallel story for the [**WebView2**](../../tB/Packages/WebView2/WebView2/) control, including the **AddObject** trade-off CEF doesn't yet have. +- [JavaScript interop](JavaScript-Interop) -- practical patterns for choosing between [**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun), [**JsRunAsync**](../../tB/Packages/CEF/CefBrowser/#jsrunasync), and the message bridge. +- [CefBrowser reference](../../tB/Packages/CEF/CefBrowser/) -- every property, method, and event. +- [WebView2 Re-entrancy tutorial](../WebView2/Re-entrancy) -- the parallel story for the [**WebView2**](../../tB/Packages/WebView2/WebView2/) control, including the **AddObject** trade-off CEF doesn't yet have. diff --git a/docs/Tutorials/CEF/index.md b/docs/Tutorials/CEF/index.md index 8acbd885..05bf2a8f 100644 --- a/docs/Tutorials/CEF/index.md +++ b/docs/Tutorials/CEF/index.md @@ -6,21 +6,21 @@ permalink: /Tutorials/CEF/ # CEF -The [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control hosts a Chromium browser inside a twinBASIC form — navigate to web pages, run local web apps, exchange messages and method calls with JavaScript, and print pages to PDF. Unlike [**WebView2**](../WebView2/), the Chromium runtime ships *alongside* the application rather than being a system component, so the browser version is under the developer's control and the same package works on machines without Edge installed. +The [**CefBrowser**](../../tB/Packages/CEF/CefBrowser/) control hosts a Chromium browser inside a twinBASIC form --- navigate to web pages, run local web apps, exchange messages and method calls with JavaScript, and print pages to PDF. Unlike [**WebView2**](../WebView2/), the Chromium runtime ships *alongside* the application rather than being a system component, so the browser version is under the developer's control and the same package works on machines without Edge installed. These tutorials demonstrate the most common patterns: -- [Getting started](Getting-Started) — adding the package reference, downloading the matching CEF runtime, and dropping a control onto a form. -- [Customize the UserDataFolder](Customize-UserDataFolder) — relocating the runtime's working folder for hosted scenarios (Office add-ins, kiosk installs, portable deployments). -- [Re-entrancy](Re-entrancy) — what the control's deferred-event machinery does for you, and the one place ([**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun)) where you still have to think about it. -- [Building a browser shell](Building-A-Browser-Shell) — address bar, back / forward / reload, zoom, PDF export — turning the control into a working browser. -- [Hosting local web assets](Hosting-Local-Web-Assets) — serve HTML / JS / CSS from a project resource folder, without an HTTP server. -- [JavaScript interop](JavaScript-Interop) — the two bridges between BASIC and the page: messages and scripted calls. -- [Driving Monaco from twinBASIC](Driving-Monaco) — a case study combining everything above: embed Microsoft's Monaco editor next to a live HTML preview pane. +- [Getting started](Getting-Started) -- adding the package reference, downloading the matching CEF runtime, and dropping a control onto a form. +- [Customize the UserDataFolder](Customize-UserDataFolder) -- relocating the runtime's working folder for hosted scenarios (Office add-ins, kiosk installs, portable deployments). +- [Re-entrancy](Re-entrancy) -- what the control's deferred-event machinery does for you, and the one place ([**JsRun**](../../tB/Packages/CEF/CefBrowser/#jsrun)) where you still have to think about it. +- [Building a browser shell](Building-A-Browser-Shell) -- address bar, back / forward / reload, zoom, PDF export --- turning the control into a working browser. +- [Hosting local web assets](Hosting-Local-Web-Assets) -- serve HTML / JS / CSS from a project resource folder, without an HTTP server. +- [JavaScript interop](JavaScript-Interop) -- the two bridges between BASIC and the page: messages and scripted calls. +- [Driving Monaco from twinBASIC](Driving-Monaco) -- a case study combining everything above: embed Microsoft's Monaco editor next to a live HTML preview pane. -The complete sample code for the last four tutorials ships as *Sample 1b — Chromium Embedded Framework Examples* in the New-Project dialog, mirroring *Sample 1a — WebView2 Examples* almost feature-for-feature. +The complete sample code for the last four tutorials ships as *Sample 1b --- Chromium Embedded Framework Examples* in the New-Project dialog, mirroring *Sample 1a --- WebView2 Examples* almost feature-for-feature. > [!IMPORTANT] -> The CEF package is currently in **BETA**. Several features available on [**WebView2**](../../tB/Packages/WebView2/WebView2/) are not yet exposed — see the [WebView2 parity](../../tB/Packages/CEF/#webview2-parity) section of the reference for the current gap list. +> The CEF package is currently in **BETA**. Several features available on [**WebView2**](../../tB/Packages/WebView2/WebView2/) are not yet exposed --- see the [WebView2 parity](../../tB/Packages/CEF/#webview2-parity) section of the reference for the current gap list. For the full set of members on the control itself, see the [**CefBrowser** class reference](../../tB/Packages/CEF/CefBrowser/). diff --git a/docs/Tutorials/CustomControls/Defining a CustomControl.md b/docs/Tutorials/CustomControls/Defining a CustomControl.md index 03be45d1..024ecac1 100644 --- a/docs/Tutorials/CustomControls/Defining a CustomControl.md +++ b/docs/Tutorials/CustomControls/Defining a CustomControl.md @@ -98,4 +98,4 @@ The passed in Serializer object offers a `Deserialize()` method that you call to *** ## See also -- [CustomControls package reference](../../tB/Packages/CustomControls/) — the full reference for the framework half (interfaces, callback objects, the [`Canvas`](../../tB/Packages/CustomControls/Framework/Canvas) drawing surface, the [`SerializeInfo`](../../tB/Packages/CustomControls/Framework/SerializeInfo) serializer) and the built-in `Waynes…` controls built on it. \ No newline at end of file +- [CustomControls package reference](../../tB/Packages/CustomControls/) -- the full reference for the framework half (interfaces, callback objects, the [`Canvas`](../../tB/Packages/CustomControls/Framework/Canvas) drawing surface, the [`SerializeInfo`](../../tB/Packages/CustomControls/Framework/SerializeInfo) serializer) and the built-in `Waynes…` controls built on it. \ No newline at end of file diff --git a/docs/Tutorials/CustomControls/Notes about the form designer.md b/docs/Tutorials/CustomControls/Notes about the form designer.md index bca399df..a7baae0d 100644 --- a/docs/Tutorials/CustomControls/Notes about the form designer.md +++ b/docs/Tutorials/CustomControls/Notes about the form designer.md @@ -9,8 +9,8 @@ redirect_from: # Notes About the Form Designer -For the painting of controls in the form designer, CustomControl instances are instantiated and then release immediately after painting has finished. The design-mode flag is exposed on the framework's [`SerializeInfo.RuntimeUISrzIsDesignMode`](../../tB/Packages/CustomControls/Framework/SerializeInfo#runtimeuisrzisdesignmode) — controls that want to render a placeholder only inside the designer (the way [`WaynesTimer`](../../tB/Packages/CustomControls/WaynesTimer) draws its 🕑 glyph) check this flag during [`Initialize`](../../tB/Packages/CustomControls/Framework/ICustomControl#initialize). +For the painting of controls in the form designer, CustomControl instances are instantiated and then release immediately after painting has finished. The design-mode flag is exposed on the framework's [`SerializeInfo.RuntimeUISrzIsDesignMode`](../../tB/Packages/CustomControls/Framework/SerializeInfo#runtimeuisrzisdesignmode) --- controls that want to render a placeholder only inside the designer (the way [`WaynesTimer`](../../tB/Packages/CustomControls/WaynesTimer) draws its 🕑 glyph) check this flag during [`Initialize`](../../tB/Packages/CustomControls/Framework/ICustomControl#initialize). ## See also -- [CustomControls package reference](../../tB/Packages/CustomControls/) — overview of the framework and the built-in `Waynes…` controls \ No newline at end of file +- [CustomControls package reference](../../tB/Packages/CustomControls/) -- overview of the framework and the built-in `Waynes…` controls \ No newline at end of file diff --git a/docs/Tutorials/CustomControls/Painting-drawing to your control.md b/docs/Tutorials/CustomControls/Painting-drawing to your control.md index 2efd7f5c..deed44f2 100644 --- a/docs/Tutorials/CustomControls/Painting-drawing to your control.md +++ b/docs/Tutorials/CustomControls/Painting-drawing to your control.md @@ -106,7 +106,7 @@ EventInfo (MouseEvent) provides mouse information such as the relative X/Y posit *** ## See also -- [`ICustomControl`](../../tB/Packages/CustomControls/Framework/ICustomControl) — the interface every custom control implements -- [`Canvas`](../../tB/Packages/CustomControls/Framework/Canvas) — the drawing surface passed to **Paint** +- [`ICustomControl`](../../tB/Packages/CustomControls/Framework/ICustomControl) -- the interface every custom control implements +- [`Canvas`](../../tB/Packages/CustomControls/Framework/Canvas) -- the drawing surface passed to **Paint** - Style helpers used by the `BackgroundFill` / `Borders` / `Corners` / `TextRenderingOptions` fields of an `ElementDescriptor`: [`Fill`](../../tB/Packages/CustomControls/Styles/Fill), [`Borders`](../../tB/Packages/CustomControls/Styles/Borders), [`Corners`](../../tB/Packages/CustomControls/Styles/Corners), [`TextRendering`](../../tB/Packages/CustomControls/Styles/TextRendering) -- [CustomControls package reference](../../tB/Packages/CustomControls/) — overview of the framework and the built-in `Waynes…` controls (a number of which — `WaynesGrid`, `WaynesButton`, … — are exactly the worked examples mentioned above) \ No newline at end of file +- [CustomControls package reference](../../tB/Packages/CustomControls/) -- overview of the framework and the built-in `Waynes…` controls (a number of which --- `WaynesGrid`, `WaynesButton`, … --- are exactly the worked examples mentioned above) \ No newline at end of file diff --git a/docs/Tutorials/CustomControls/Property sheet and object serialization.md b/docs/Tutorials/CustomControls/Property sheet and object serialization.md index 60eb7c16..566a2566 100644 --- a/docs/Tutorials/CustomControls/Property sheet and object serialization.md +++ b/docs/Tutorials/CustomControls/Property sheet and object serialization.md @@ -88,5 +88,5 @@ At the moment, the form-designer doesn't yet support code-behind-forms, so this *** ## See also -- [`SerializeInfo`](../../tB/Packages/CustomControls/Framework/SerializeInfo) — the reference for the current serializer type (the `SerializationInfo` name in the snippets above is the older draft name; the current type is `SerializeInfo` and `Deserialize()` is exposed as `RuntimeUISrzDeserialize()`) -- [CustomControls package reference](../../tB/Packages/CustomControls/) — overview of the framework and the built-in `Waynes…` controls \ No newline at end of file +- [`SerializeInfo`](../../tB/Packages/CustomControls/Framework/SerializeInfo) -- the reference for the current serializer type (the `SerializationInfo` name in the snippets above is the older draft name; the current type is `SerializeInfo` and `Deserialize()` is exposed as `RuntimeUISrzDeserialize()`) +- [CustomControls package reference](../../tB/Packages/CustomControls/) -- overview of the framework and the built-in `Waynes…` controls \ No newline at end of file diff --git a/docs/Tutorials/CustomControls/index.md b/docs/Tutorials/CustomControls/index.md index 8e2b37e2..822b2fc6 100644 --- a/docs/Tutorials/CustomControls/index.md +++ b/docs/Tutorials/CustomControls/index.md @@ -24,4 +24,4 @@ A few highlights; ## See also -- [CustomControls package reference](../tB/Packages/CustomControls/) — the full reference for the built-in `Waynes…` controls and the framework they are built on, including [`ICustomControl`](../tB/Packages/CustomControls/Framework/ICustomControl), [`Canvas`](../tB/Packages/CustomControls/Framework/Canvas), and the style helpers ([`Fill`](../tB/Packages/CustomControls/Styles/Fill), [`Corners`](../tB/Packages/CustomControls/Styles/Corners), [`Borders`](../tB/Packages/CustomControls/Styles/Borders), [`TextRendering`](../tB/Packages/CustomControls/Styles/TextRendering), …) \ No newline at end of file +- [CustomControls package reference](../tB/Packages/CustomControls/) -- the full reference for the built-in `Waynes…` controls and the framework they are built on, including [`ICustomControl`](../tB/Packages/CustomControls/Framework/ICustomControl), [`Canvas`](../tB/Packages/CustomControls/Framework/Canvas), and the style helpers ([`Fill`](../tB/Packages/CustomControls/Styles/Fill), [`Corners`](../tB/Packages/CustomControls/Styles/Corners), [`Borders`](../tB/Packages/CustomControls/Styles/Borders), [`TextRendering`](../tB/Packages/CustomControls/Styles/TextRendering), …) \ No newline at end of file diff --git a/docs/Tutorials/WebView2/Building a browser shell.md b/docs/Tutorials/WebView2/Building a browser shell.md index ccc1abcc..f17fbd47 100644 --- a/docs/Tutorials/WebView2/Building a browser shell.md +++ b/docs/Tutorials/WebView2/Building a browser shell.md @@ -10,15 +10,15 @@ permalink: /Tutorials/WebView2/Building-A-Browser-Shell A short worked tutorial: turn a [**WebView2**](../../tB/Packages/WebView2/WebView2/) control into a working browser with an address bar, back / forward / reload buttons, zoom, and a few helpers (DevTools, Task Manager, PDF export). -The complete project ships as *Sample 0 — WebView2 Examples* in the New-Project dialog (form *Example 1*). This tutorial describes its key pieces. +The complete project ships as *Sample 0 --- WebView2 Examples* in the New-Project dialog (form *Example 1*). This tutorial describes its key pieces. ## The form -Drop a [**WebView2**](../../tB/Packages/WebView2/WebView2/) control onto a Form and rename it `WebView`. Around it, add a `TextBox` named `AddressBar` plus seven `CommandButton`s — `btnBack`, `btnForward`, `btnRefresh`, `btnZoomIn`, `btnZoomOut`, `btnPDF`, `btnDevTools`, `btnTaskMgr`. +Drop a [**WebView2**](../../tB/Packages/WebView2/WebView2/) control onto a Form and rename it `WebView`. Around it, add a `TextBox` named `AddressBar` plus seven `CommandButton`s --- `btnBack`, `btnForward`, `btnRefresh`, `btnZoomIn`, `btnZoomOut`, `btnPDF`, `btnDevTools`, `btnTaskMgr`. ## Navigating -The bare-bones navigation methods — [**Navigate**](../../tB/Packages/WebView2/WebView2/#navigate), [**GoBack**](../../tB/Packages/WebView2/WebView2/#goback), [**GoForward**](../../tB/Packages/WebView2/WebView2/#goforward), [**Reload**](../../tB/Packages/WebView2/WebView2/#reload) — are one-liners: +The bare-bones navigation methods --- [**Navigate**](../../tB/Packages/WebView2/WebView2/#navigate), [**GoBack**](../../tB/Packages/WebView2/WebView2/#goback), [**GoForward**](../../tB/Packages/WebView2/WebView2/#goforward), [**Reload**](../../tB/Packages/WebView2/WebView2/#reload) --- are one-liners: ```tb Private Sub btnBack_Click() Handles btnBack.Click @@ -47,7 +47,7 @@ End Sub ## The address bar -Pressing **Enter** in the address bar triggers a navigation. The reverse direction — keeping the visible URL in sync with the page — is the [**SourceChanged**](../../tB/Packages/WebView2/WebView2/#sourcechanged) event, which fires whenever [**DocumentURL**](../../tB/Packages/WebView2/WebView2/#documenturl) changes (including same-document `history.pushState` updates): +Pressing **Enter** in the address bar triggers a navigation. The reverse direction --- keeping the visible URL in sync with the page --- is the [**SourceChanged**](../../tB/Packages/WebView2/WebView2/#sourcechanged) event, which fires whenever [**DocumentURL**](../../tB/Packages/WebView2/WebView2/#documenturl) changes (including same-document `history.pushState` updates): ```tb Private Sub AddressBar_KeyDown(KeyCode As Integer, Shift As Integer) _ @@ -65,7 +65,7 @@ End Sub ## Zoom -[**ZoomFactor**](../../tB/Packages/WebView2/WebView2/#zoomfactor) is a **Double** — `1.0` is 100%, `1.5` is 150%. The design-time default is `0`, meaning *"don't override Edge's default of 1.0"* — so multiplying by `1.1` from cold gives `0`, not `1.1`. Clamp to `1` before scaling: +[**ZoomFactor**](../../tB/Packages/WebView2/WebView2/#zoomfactor) is a **Double** --- `1.0` is 100%, `1.5` is 150%. The design-time default is `0`, meaning *"don't override Edge's default of 1.0"* --- so multiplying by `1.1` from cold gives `0`, not `1.1`. Clamp to `1` before scaling: ```tb Private Sub btnZoomIn_Click() Handles btnZoomIn.Click @@ -81,7 +81,7 @@ End Sub ## PDF export -[**PrintToPdf**](../../tB/Packages/WebView2/WebView2/#printtopdf) saves the current document to disk asynchronously — the result arrives as [**PrintToPdfCompleted**](../../tB/Packages/WebView2/WebView2/#printtopdfcompleted) or [**PrintToPdfFailed**](../../tB/Packages/WebView2/WebView2/#printtopdffailed): +[**PrintToPdf**](../../tB/Packages/WebView2/WebView2/#printtopdf) saves the current document to disk asynchronously --- the result arrives as [**PrintToPdfCompleted**](../../tB/Packages/WebView2/WebView2/#printtopdfcompleted) or [**PrintToPdfFailed**](../../tB/Packages/WebView2/WebView2/#printtopdffailed): ```tb Private Sub btnPDF_Click() Handles btnPDF.Click @@ -97,7 +97,7 @@ End Sub ## DevTools and Task Manager -Both windows are one-shot — call the matching method and Edge opens the window in its own process: +Both windows are one-shot --- call the matching method and Edge opens the window in its own process: ```tb Private Sub btnDevTools_Click() Handles btnDevTools.Click @@ -109,7 +109,7 @@ Private Sub btnTaskMgr_Click() Handles btnTaskMgr.Click End Sub ``` -[**OpenDevToolsWindow**](../../tB/Packages/WebView2/WebView2/#opendevtoolswindow) works even when [**AreDevToolsEnabled**](../../tB/Packages/WebView2/WebView2/#aredevtoolsenabled) is **False** (that setting only disables the user-initiated path — keyboard shortcut and context menu). +[**OpenDevToolsWindow**](../../tB/Packages/WebView2/WebView2/#opendevtoolswindow) works even when [**AreDevToolsEnabled**](../../tB/Packages/WebView2/WebView2/#aredevtoolsenabled) is **False** (that setting only disables the user-initiated path --- keyboard shortcut and context menu). ## Form-title sync @@ -123,6 +123,6 @@ End Sub ## Where next -- [Hosting local web assets](Hosting-Local-Web-Assets) — serve HTML / JS / CSS from a folder without an HTTP server. -- [JavaScript interop](JavaScript-Interop) — pass values and method calls between BASIC and the page. -- [WebView2 reference](../../tB/Packages/WebView2/WebView2/) — every property, method, and event. +- [Hosting local web assets](Hosting-Local-Web-Assets) -- serve HTML / JS / CSS from a folder without an HTTP server. +- [JavaScript interop](JavaScript-Interop) -- pass values and method calls between BASIC and the page. +- [WebView2 reference](../../tB/Packages/WebView2/WebView2/) -- every property, method, and event. diff --git a/docs/Tutorials/WebView2/Driving Monaco.md b/docs/Tutorials/WebView2/Driving Monaco.md index 93b04535..cbeba18f 100644 --- a/docs/Tutorials/WebView2/Driving Monaco.md +++ b/docs/Tutorials/WebView2/Driving Monaco.md @@ -8,9 +8,9 @@ permalink: /Tutorials/WebView2/Driving-Monaco # Driving Monaco from twinBASIC -A case study combining everything from the previous tutorials: a form with **two** [**WebView2**](../../tB/Packages/WebView2/WebView2/) controls — the Microsoft Monaco editor on the left, a live HTML preview on the right. As the user types, Monaco posts the edited source to twinBASIC, which mirrors it into the preview pane. +A case study combining everything from the previous tutorials: a form with **two** [**WebView2**](../../tB/Packages/WebView2/WebView2/) controls --- the Microsoft Monaco editor on the left, a live HTML preview on the right. As the user types, Monaco posts the edited source to twinBASIC, which mirrors it into the preview pane. -The complete project ships as *Sample 0 — WebView2 Examples* in the New-Project dialog (form *Example 3*). +The complete project ships as *Sample 0 --- WebView2 Examples* in the New-Project dialog (form *Example 3*). ## Architecture @@ -20,7 +20,7 @@ The editor runs as a local web app under a virtual hostname; the preview pane is ## Setting up the editor's assets -The Monaco editor ships as a ~2 MB collection of JavaScript, CSS, and font files. Drop them into a `Resources` sub-folder of your project — call it `MONACO_DEMO` — alongside an `index.html` and a small bootstrap `script.js`. The [Hosting local web assets](Hosting-Local-Web-Assets) tutorial describes the layout. +The Monaco editor ships as a ~2 MB collection of JavaScript, CSS, and font files. Drop them into a `Resources` sub-folder of your project --- call it `MONACO_DEMO` --- alongside an `index.html` and a small bootstrap `script.js`. The [Hosting local web assets](Hosting-Local-Web-Assets) tutorial describes the layout. The page itself is a single `<div id='container'>` plus the bootstrap script that listens for an *initial-content* message from the host: @@ -61,7 +61,7 @@ window.chrome.webview.addEventListener('message', (event) => { ## The BASIC side -Drop two `WebView2` controls on a form — `WebView` (the editor) and `WebViewPreview` (the renderer). The `Ready` handler deploys the assets, registers the virtual host, and navigates: +Drop two `WebView2` controls on a form --- `WebView` (the editor) and `WebViewPreview` (the renderer). The `Ready` handler deploys the assets, registers the virtual host, and navigates: ```tb Private localPath As String @@ -99,7 +99,7 @@ End Sub ## Live preview -Every keystroke in Monaco fires its `onDidChangeModelContent` callback, which `postMessage`s the new content back to BASIC. That arrives as the [**JsMessage**](../../tB/Packages/WebView2/WebView2/#jsmessage) event — feed it straight into the preview: +Every keystroke in Monaco fires its `onDidChangeModelContent` callback, which `postMessage`s the new content back to BASIC. That arrives as the [**JsMessage**](../../tB/Packages/WebView2/WebView2/#jsmessage) event --- feed it straight into the preview: ```tb Private Sub WebView_JsMessage(ByVal Message As Variant) Handles WebView.JsMessage @@ -107,7 +107,7 @@ Private Sub WebView_JsMessage(ByVal Message As Variant) Handles WebView.JsMessag End Sub ``` -That's it — the preview pane re-renders on every edit. +That's it --- the preview pane re-renders on every edit. ## Detecting a missing Edge runtime @@ -128,10 +128,10 @@ Private Sub WebView_Error(ByVal code As Long, ByVal msg As String) _ End Sub ``` -It is worth handling this even in single-WebView applications — the message you show here is the difference between *"nothing happens"* and *"oh, I need to install something"*. +It is worth handling this even in single-WebView applications --- the message you show here is the difference between *"nothing happens"* and *"oh, I need to install something"*. ## Where next -- [Hosting local web assets](Hosting-Local-Web-Assets) — the `CopyResourcesFolderContentsToLocalPath` helper and virtual-host pattern this tutorial builds on. -- [JavaScript interop](JavaScript-Interop) — the three bridges between BASIC and JavaScript. -- [WebView2 reference](../../tB/Packages/WebView2/WebView2/) — every property, method, and event. +- [Hosting local web assets](Hosting-Local-Web-Assets) -- the `CopyResourcesFolderContentsToLocalPath` helper and virtual-host pattern this tutorial builds on. +- [JavaScript interop](JavaScript-Interop) -- the three bridges between BASIC and JavaScript. +- [WebView2 reference](../../tB/Packages/WebView2/WebView2/) -- every property, method, and event. diff --git a/docs/Tutorials/WebView2/Hosting local web assets.md b/docs/Tutorials/WebView2/Hosting local web assets.md index 67c72c0c..321d6f79 100644 --- a/docs/Tutorials/WebView2/Hosting local web assets.md +++ b/docs/Tutorials/WebView2/Hosting local web assets.md @@ -8,13 +8,13 @@ permalink: /Tutorials/WebView2/Hosting-Local-Web-Assets # Hosting local web assets -A [**WebView2**](../../tB/Packages/WebView2/WebView2/) control can serve HTML, JavaScript, CSS, and any other assets straight from a folder on disk — no embedded HTTP server required. Edge's [**SetVirtualHostNameToFolderMapping**](../../tB/Packages/WebView2/WebView2/#setvirtualhostnametofoldermapping) routes a virtual `https://` hostname to a local folder so that resources behave as if they came from a real origin: same-origin `fetch`, Content Security Policy, service workers, and so on all work as expected. +A [**WebView2**](../../tB/Packages/WebView2/WebView2/) control can serve HTML, JavaScript, CSS, and any other assets straight from a folder on disk --- no embedded HTTP server required. Edge's [**SetVirtualHostNameToFolderMapping**](../../tB/Packages/WebView2/WebView2/#setvirtualhostnametofoldermapping) routes a virtual `https://` hostname to a local folder so that resources behave as if they came from a real origin: same-origin `fetch`, Content Security Policy, service workers, and so on all work as expected. -This tutorial demonstrates the pattern used by *Sample 0 — WebView2 Examples* (forms *Example 2*, *Example 3*, *Example 4*). +This tutorial demonstrates the pattern used by *Sample 0 --- WebView2 Examples* (forms *Example 2*, *Example 3*, *Example 4*). ## The three-step pattern -1. **Choose a folder.** It must exist on disk and contain `index.html` (plus whatever assets the page wants — scripts, styles, images). +1. **Choose a folder.** It must exist on disk and contain `index.html` (plus whatever assets the page wants --- scripts, styles, images). 2. **Register a virtual host** mapping to that folder. 3. **Navigate** to a URL under the virtual hostname. @@ -34,7 +34,7 @@ Once mapped, every request to `https://myapp.example/<path>` is served from `fol ## Picking a hostname -The Edge runtime resolves the virtual hostname through DNS *before* applying the local override. Hostnames that happen to be resolvable on the public Internet introduce a small (≈2 s) stall on every request — see [WebView2Feedback#2381](https://github.com/MicrosoftEdge/WebView2Feedback/issues/2381). +The Edge runtime resolves the virtual hostname through DNS *before* applying the local override. Hostnames that happen to be resolvable on the public Internet introduce a small (≈2 s) stall on every request --- see [WebView2Feedback#2381](https://github.com/MicrosoftEdge/WebView2Feedback/issues/2381). The safe convention is to pick a name under a TLD that will never resolve, like `.example`, `.invalid`, or `.test`: @@ -49,7 +49,7 @@ The safe convention is to pick a name under a TLD that will never resolve, like Most applications want to ship their HTML / JS / CSS *inside* the executable and drop them onto disk on first run. twinBASIC's `Resources` folder is the right place to keep them. 1. In the IDE's Project explorer, expand **Resources** and add a sub-folder (right-click → *Add new subfolder*). Name it something memorable like `WEB_APP`. -2. Drop the assets in — `index.html`, `script.js`, `styles.css`, plus any sub-directories you need. +2. Drop the assets in --- `index.html`, `script.js`, `styles.css`, plus any sub-directories you need. At runtime, the helper below copies the contents of a `Resources` sub-folder out to a local path. Drop it into a `.twin` module in your project: @@ -99,7 +99,7 @@ Module Files End Module ``` -[**LoadResIdList**](../../tB/Packages/VB/Global/#loadresidlist) returns every resource ID under the named sub-folder; [**LoadResData**](../../tB/Packages/VB/Global/#loadresdata) returns the bytes. The helper splits each resource name on `~` to reconstruct the original sub-directory tree on disk — the twinBASIC IDE flattens nested folders by joining their names with `~` when the resources are compiled in. +[**LoadResIdList**](../../tB/Packages/VB/Global/#loadresidlist) returns every resource ID under the named sub-folder; [**LoadResData**](../../tB/Packages/VB/Global/#loadresdata) returns the bytes. The helper splits each resource name on `~` to reconstruct the original sub-directory tree on disk --- the twinBASIC IDE flattens nested folders by joining their names with `~` when the resources are compiled in. ## Putting it together @@ -119,10 +119,10 @@ Private Sub WebView_Ready() Handles WebView.Ready End Sub ``` -Once deployed, the application can launch DevTools ([**OpenDevToolsWindow**](../../tB/Packages/WebView2/WebView2/#opendevtoolswindow)) to inspect the loaded files, and users can edit `index.html` directly on disk and hit **Refresh** — useful for rapid iteration during development. +Once deployed, the application can launch DevTools ([**OpenDevToolsWindow**](../../tB/Packages/WebView2/WebView2/#opendevtoolswindow)) to inspect the loaded files, and users can edit `index.html` directly on disk and hit **Refresh** --- useful for rapid iteration during development. ## Where next -- [JavaScript interop](JavaScript-Interop) — how a hosted page exchanges values and method calls with the BASIC application. -- [Driving Monaco from twinBASIC](Driving-Monaco) — a full case study built on top of this pattern. -- [SetVirtualHostNameToFolderMapping](../../tB/Packages/WebView2/WebView2/#setvirtualhostnametofoldermapping) — full reference. +- [JavaScript interop](JavaScript-Interop) -- how a hosted page exchanges values and method calls with the BASIC application. +- [Driving Monaco from twinBASIC](Driving-Monaco) -- a full case study built on top of this pattern. +- [SetVirtualHostNameToFolderMapping](../../tB/Packages/WebView2/WebView2/#setvirtualhostnametofoldermapping) -- full reference. diff --git a/docs/Tutorials/WebView2/JavaScript interop.md b/docs/Tutorials/WebView2/JavaScript interop.md index e225ae02..370b74ba 100644 --- a/docs/Tutorials/WebView2/JavaScript interop.md +++ b/docs/Tutorials/WebView2/JavaScript interop.md @@ -10,13 +10,13 @@ permalink: /Tutorials/WebView2/JavaScript-Interop The [**WebView2**](../../tB/Packages/WebView2/WebView2/) control offers three complementary bridges between twinBASIC and the JavaScript running in the page: -1. **Host objects** — publish a BASIC COM object to the page so JavaScript can call its methods and read its properties as if it were any other JS object. -2. **Messages** — push a value (string, number, array, …) in either direction and listen for it on the other side. -3. **Scripted calls** — call a named JavaScript function from BASIC and (optionally) wait for its return value. +1. **Host objects** --- publish a BASIC COM object to the page so JavaScript can call its methods and read its properties as if it were any other JS object. +2. **Messages** --- push a value (string, number, array, …) in either direction and listen for it on the other side. +3. **Scripted calls** --- call a named JavaScript function from BASIC and (optionally) wait for its return value. -This tutorial covers all three, with the matching JavaScript side shown next to each BASIC side. The worked code comes from *Sample 0 — WebView2 Examples* (form *Example 2*). +This tutorial covers all three, with the matching JavaScript side shown next to each BASIC side. The worked code comes from *Sample 0 --- WebView2 Examples* (form *Example 2*). -## Bridge 1 — Host objects +## Bridge 1 --- Host objects [**AddObject**](../../tB/Packages/WebView2/WebView2/#addobject) publishes a BASIC class instance under `chrome.webview.hostObjects.<Name>`. Define a small class with public methods or properties: @@ -36,7 +36,7 @@ Private Sub WebView_Ready() Handles WebView.Ready End Sub ``` -JavaScript can now call into it — but the proxy is asynchronous, so the call must be `await`ed inside an `async` function: +JavaScript can now call into it --- but the proxy is asynchronous, so the call must be `await`ed inside an `async` function: ```js async function testHostCalculator() { @@ -56,7 +56,7 @@ End Sub Requires [**AreHostObjectsAllowed**](../../tB/Packages/WebView2/WebView2/#arehostobjectsallowed) (default **True**). See [Re-entrancy](Re-entrancy) for the trade-off between synchronous calls (default) and the **UseDeferredInvoke:=True** variant. -## Bridge 2 — Messages +## Bridge 2 --- Messages Messages are values that travel in either direction. Use them for notifications and ad-hoc payloads where you don't want to define a method signature ahead of time. @@ -95,7 +95,7 @@ End Sub Both directions require [**IsWebMessageEnabled**](../../tB/Packages/WebView2/WebView2/#iswebmessageenabled) (default **True**). -## Bridge 3 — Scripted calls +## Bridge 3 --- Scripted calls When the page exposes named JS functions, BASIC can call them directly. There are three variants: @@ -103,7 +103,7 @@ When the page exposes named JS functions, BASIC can call them directly. There ar |-----------------------------------------------------------------------------------|--------------------------------------------------|-------------------------------------------------------------------| | [**JsRun**](../../tB/Packages/WebView2/WebView2/#jsrun) | **Variant**, synchronously | You need the result inline and the JS is quick. | | [**JsRunAsync**](../../tB/Packages/WebView2/WebView2/#jsrunasync) | **LongLong** token; result via `JsAsyncResult` | The JS may take a while and you don't want to block the UI. | -| [**ExecuteScript**](../../tB/Packages/WebView2/WebView2/#executescript) | nothing (fire-and-forget) | You just want to trigger something — no return value needed. | +| [**ExecuteScript**](../../tB/Packages/WebView2/WebView2/#executescript) | nothing (fire-and-forget) | You just want to trigger something --- no return value needed. | ### JsRun (synchronous) @@ -122,7 +122,7 @@ Dim product As Long = WebView.JsRun("multiplyTheseNumbers", 5, 6) Debug.Print product ' 30 ``` -The call blocks for up to [**JsCallTimeOutSeconds**](../../tB/Packages/WebView2/WebView2/#jscalltimeoutseconds) (default 0 — wait forever). +The call blocks for up to [**JsCallTimeOutSeconds**](../../tB/Packages/WebView2/WebView2/#jscalltimeoutseconds) (default 0 --- wait forever). ### JsRunAsync (asynchronous) @@ -154,16 +154,16 @@ No return value, no event. The simplest way to nudge the page into doing somethi ## Re-entrancy -The Edge runtime forbids host code from calling back into the WebView2 object model while a host-object method is still executing — re-entry deadlocks the browser process. The control protects most events by deferring them through the BASIC message loop ([**UseDeferredEvents**](../../tB/Packages/WebView2/WebView2/#usedeferredevents)), but host-object method calls are synchronous by default. +The Edge runtime forbids host code from calling back into the WebView2 object model while a host-object method is still executing --- re-entry deadlocks the browser process. The control protects most events by deferring them through the BASIC message loop ([**UseDeferredEvents**](../../tB/Packages/WebView2/WebView2/#usedeferredevents)), but host-object method calls are synchronous by default. The full discussion lives in the [Re-entrancy tutorial](Re-entrancy); the short summary is: -- **`AddObject(name, obj)`** — synchronous calls; the page can read return values but the BASIC method **must not** call back into the WebView2 control. -- **`AddObject(name, obj, UseDeferredInvoke:=True)`** — asynchronous calls; the BASIC method is free to call any WebView2 member but the page cannot read a return value. +- **`AddObject(name, obj)`** --- synchronous calls; the page can read return values but the BASIC method **must not** call back into the WebView2 control. +- **`AddObject(name, obj, UseDeferredInvoke:=True)`** --- asynchronous calls; the BASIC method is free to call any WebView2 member but the page cannot read a return value. ## Where next -- [Hosting local web assets](Hosting-Local-Web-Assets) — bundle and serve the JavaScript that talks to the host. -- [Driving Monaco from twinBASIC](Driving-Monaco) — a full case study using all three bridges. -- [Re-entrancy](Re-entrancy) — the deeper story behind **UseDeferredInvoke**. -- [WebView2 reference](../../tB/Packages/WebView2/WebView2/) — every property, method, and event. +- [Hosting local web assets](Hosting-Local-Web-Assets) -- bundle and serve the JavaScript that talks to the host. +- [Driving Monaco from twinBASIC](Driving-Monaco) -- a full case study using all three bridges. +- [Re-entrancy](Re-entrancy) -- the deeper story behind **UseDeferredInvoke**. +- [WebView2 reference](../../tB/Packages/WebView2/WebView2/) -- every property, method, and event. diff --git a/docs/Tutorials/WebView2/index.md b/docs/Tutorials/WebView2/index.md index e727b93e..06d120a7 100644 --- a/docs/Tutorials/WebView2/index.md +++ b/docs/Tutorials/WebView2/index.md @@ -8,18 +8,18 @@ redirect_from: # WebView2 -The [**WebView2**](../../tB/Packages/WebView2/WebView2/) control hosts the Microsoft Edge browser engine inside a twinBASIC form — navigate to web pages, run local web apps, exchange messages and method calls with JavaScript, intercept HTTP traffic, and print pages to PDF. +The [**WebView2**](../../tB/Packages/WebView2/WebView2/) control hosts the Microsoft Edge browser engine inside a twinBASIC form --- navigate to web pages, run local web apps, exchange messages and method calls with JavaScript, intercept HTTP traffic, and print pages to PDF. These tutorials demonstrate the most common patterns: -- [Getting started](Getting-Started) — adding the package references and dropping a control onto a form. -- [Customize the UserDataFolder](Customize-UserDataFolder) — relocating the runtime's working folder for hosted scenarios (Office add-ins, kiosk installs). -- [Re-entrancy](Re-entrancy) — what the control's deferred-event machinery does for you, and the one place you still have to think about it. -- [Building a browser shell](Building-A-Browser-Shell) — address bar, back / forward / reload, zoom, PDF export — turning the control into a working browser. -- [Hosting local web assets](Hosting-Local-Web-Assets) — serve HTML / JS / CSS from a project resource folder, without an HTTP server. -- [JavaScript interop](JavaScript-Interop) — the three bridges between BASIC and the page: host objects, messages, and scripted calls. -- [Driving Monaco from twinBASIC](Driving-Monaco) — a case study combining everything above: embed Microsoft's Monaco editor next to a live HTML preview pane. +- [Getting started](Getting-Started) -- adding the package references and dropping a control onto a form. +- [Customize the UserDataFolder](Customize-UserDataFolder) -- relocating the runtime's working folder for hosted scenarios (Office add-ins, kiosk installs). +- [Re-entrancy](Re-entrancy) -- what the control's deferred-event machinery does for you, and the one place you still have to think about it. +- [Building a browser shell](Building-A-Browser-Shell) -- address bar, back / forward / reload, zoom, PDF export --- turning the control into a working browser. +- [Hosting local web assets](Hosting-Local-Web-Assets) -- serve HTML / JS / CSS from a project resource folder, without an HTTP server. +- [JavaScript interop](JavaScript-Interop) -- the three bridges between BASIC and the page: host objects, messages, and scripted calls. +- [Driving Monaco from twinBASIC](Driving-Monaco) -- a case study combining everything above: embed Microsoft's Monaco editor next to a live HTML preview pane. -The complete sample code for the last four tutorials ships as *Sample 0 — WebView2 Examples* in the New-Project dialog. +The complete sample code for the last four tutorials ships as *Sample 0 --- WebView2 Examples* in the New-Project dialog. For the full set of members on the control itself, see the [**WebView2** class reference](../../tB/Packages/WebView2/WebView2/). diff --git a/docs/Videos/twinBASIC.md b/docs/Videos/twinBASIC.md index 4935c819..198d9361 100644 --- a/docs/Videos/twinBASIC.md +++ b/docs/Videos/twinBASIC.md @@ -16,7 +16,7 @@ permalink: /Videos/tB referrerpolicy="strict-origin-when-cross-origin" allowfullscreen> </iframe> -Introducing "twinBASIC for applications" – the game-changing drop-in replacement for VBA (and VBA SDK). See our proof of concept inside MS ACCESS in action! 🚀👨‍💻👩‍💻 +Introducing "twinBASIC for applications" -- the game-changing drop-in replacement for VBA (and VBA SDK). See our proof of concept inside MS ACCESS in action! 🚀👨‍💻👩‍💻 We posted this video on X last month but forgot to post it also on YT, so here you go :) diff --git a/scripts/convert_em_dash_separators.py b/scripts/convert_em_dash_separators.py new file mode 100644 index 00000000..343277c2 --- /dev/null +++ b/scripts/convert_em_dash_separators.py @@ -0,0 +1,122 @@ +""" +Normalise literal en-/em-dashes in markdown source to kramdown smart_quotes form. + +Kramdown's smart_quotes feature (enabled by default) renders: + source `--` -> en-dash (`-`) + source `---` -> em-dash (`-`) + +Literal `-` and `-` characters in source are therefore redundant. This script +converts them to the equivalent source form, preserving the rendered output: + + * Bullet-list separator em-dash (the first `-` on a `- [link](url) ...` line): + converted to `--` to match the established See Also separator convention + (which renders as en-dash). + * All other em-dashes (prose parentheticals, etc.): + converted to `---` (renders as em-dash, unchanged). + * All en-dashes: + converted to `--` (renders as en-dash, unchanged). + +Code is skipped: + * Fenced code blocks (``` ... ```) are left intact. + * Inline code spans (`...`) on a line are left intact. + +Run from the repository root: + python scripts/convert_em_dash_separators.py +""" + +import re +from pathlib import Path + +ROOT = Path("docs") + +EM_DASH = "—" +EN_DASH = "–" + +# First em-dash after a `[link](url)` on a bullet line. Stops at backticks +# so we don't reach into an inline-code span. +SEPARATOR_PATTERN = re.compile( + r"^(- \[.*?\]\(.*?\)[^" + EM_DASH + r"\n`]*)" + EM_DASH +) + +# A fenced-code-block opener / closer. +FENCE_PATTERN = re.compile(r"^```") + +# Split a line into alternating prose / inline-code segments. +INLINE_CODE_SPLIT = re.compile(r"(`[^`\n]*`)") + + +def process_line(line: str) -> tuple[str, int, int, int]: + n_sep = 0 + n_em = 0 + n_en = 0 + + # Step 1: bullet-list separator em-dash -> `--` (one substitution). + line, n = SEPARATOR_PATTERN.subn(r"\1--", line, count=1) + n_sep = n + + # Step 2: remaining em-dash -> `---`, en-dash -> `--`, but only outside + # inline-code spans. + parts = INLINE_CODE_SPLIT.split(line) + new_parts = [] + for part in parts: + if len(part) >= 2 and part.startswith("`") and part.endswith("`"): + new_parts.append(part) + continue + n_em += part.count(EM_DASH) + n_en += part.count(EN_DASH) + part = part.replace(EM_DASH, "---").replace(EN_DASH, "--") + new_parts.append(part) + line = "".join(new_parts) + + return line, n_sep, n_em, n_en + + +def main() -> None: + total_files = 0 + total_sep = 0 + total_em = 0 + total_en = 0 + + for md in sorted(ROOT.rglob("*.md")): + lines = md.read_text(encoding="utf-8").splitlines(keepends=True) + new_lines = [] + in_fence = False + file_sep = 0 + file_em = 0 + file_en = 0 + + for line in lines: + if FENCE_PATTERN.match(line): + in_fence = not in_fence + new_lines.append(line) + continue + if in_fence: + new_lines.append(line) + continue + + new_line, n_sep, n_em, n_en = process_line(line) + file_sep += n_sep + file_em += n_em + file_en += n_en + new_lines.append(new_line) + + if file_sep + file_em + file_en > 0: + md.write_text("".join(new_lines), encoding="utf-8") + total_files += 1 + total_sep += file_sep + total_em += file_em + total_en += file_en + print( + f" {md}: sep={file_sep}, prose-em={file_em}, en={file_en}" + ) + + print() + print(f"Files changed: {total_files}") + print(f"Separator em-dash -> --: {total_sep}") + print(f"Prose em-dash -> ---: {total_em}") + print(f"En-dash -> --: {total_en}") + print(f"Total replacements: {total_sep + total_em + total_en}") + + +if __name__ == "__main__": + main()