Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/Miscellaneous/Documentation Development.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ These are modules within VBA and VBRUN:
- [Math](../tB/Modules/Math)
- [Strings](../tB/Modules/Strings)
- [TextEncodingConstants](../tB/Modules/TextEncodingConstants)
- Internal [_HiddenModule](../tB/Modules/_HiddenModule)
- Internal [_HiddenModule](../tB/Modules/HiddenModule)
- VBRUN
- [AmbientProperties](../tB/Modules/AmbientProperties)
- [AsyncProperty](../tB/Modules/AsyncProperty)
Expand Down
74 changes: 72 additions & 2 deletions docs/Reference/Categories.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Procedures:
* [Erl](../tB/Modules/Information/Erl) - returns the line number where the most recent run-time error occurred
* [Error$, Error](../tB/Modules/Conversion/Error) function - returns the error message that corresponds to a given error number
* [CVErr](../tB/Modules/Conversion/CVErr) - wraps a numeric expression in a **Variant** of subtype **Error**
* [SetThreadGlobalErrorTrap](../tB/Modules/HiddenModule/SetThreadGlobalErrorTrap) - register a callback that fires when an unhandled run-time error escapes the active error handler chain on the calling thread

## Variable Declaration

Expand Down Expand Up @@ -108,7 +109,8 @@ Procedures:
See also:

* [Dim](../tB/Core/Dim) - allocate a scalar or array variable
* [Array](../tB/Modules/VBA/Array), [Filter](../tB/Modules/Strings/Filter), [Join](../tB/Modules/Strings/Join), [Split](../tB/Modules/Strings/Split) - array helpers in the **VBA** and **Strings** modules
* [Array](../tB/Modules/HiddenModule/Array), [Filter](../tB/Modules/Strings/Filter), [Join](../tB/Modules/Strings/Join), [Split](../tB/Modules/Strings/Split) - array helpers
* [vbaAryMove](../tB/Modules/HiddenModule/vbaAryMove), [vbaRefVarAry](../tB/Modules/HiddenModule/vbaRefVarAry) - low-level **Variant**-array helpers (see [Memory and Pointers](#memory-and-pointers))

## File I/O

Expand All @@ -124,7 +126,9 @@ Statements:
Procedures:

* [Reset](../tB/Core/Reset) - close all open disk files
* [Width](../tB/Core/Width) - set the limit for line lengths when printing
* [Width](../tB/Modules/HiddenModule/Width) - set the limit for line lengths when printing
* [Input, Input$](../tB/Modules/HiddenModule/Input) - read a fixed number of characters from a sequential file
* [InputB, InputB$](../tB/Modules/HiddenModule/InputB) - read a fixed number of bytes from a sequential file
* [ChDir](../tB/Core/ChDir), [ChDrive](../tB/Core/ChDrive) - change the current working directory and disk drive
* [MkDir](../tB/Core/MkDir), [RmDir](../tB/Core/RmDir) - create/remove a directory on disk
* [Name](../tB/Core/Name) - rename a file or directory on disk
Expand Down Expand Up @@ -153,10 +157,12 @@ Procedures:

* [RaiseEventByName](../tB/Modules/Interaction/RaiseEventByName) - raise an event by name on an object, taking arguments as a **Variant** array
* [RaiseEventByName2](../tB/Modules/Interaction/RaiseEventByName2) - raise an event by name on an object, taking a variable-length argument list
* [RuntimeCreateGetMessageHook](../tB/Modules/HiddenModule/RuntimeCreateGetMessageHook) - create an **IGetMessageHook** for filtering Windows messages destined for a window and (optionally) its descendants

See also

* [Event](../tB/Core/Event) - declare an event
* [IGetMessageHook interface](../tB/Modules/HiddenModule/#igetmessagehook-interface) - subscribe a callback to a Windows message type, then start/stop delivery

## User Dialogs

Expand All @@ -183,6 +189,14 @@ Procedures:
* [GetObject](../tB/Modules/Interaction/GetObject) - obtain a reference to an Automation object loaded from a file or already running
* [CallByName](../tB/Modules/Interaction/CallByName) - invoke a method or property on an object dynamically by name
* [CallByDispId](../tB/Modules/Interaction/CallByDispId) - invoke a method or property on an object dynamically by IDispatch dispatch ID (twinBASIC addition)
* [CreateGUID](../tB/Modules/HiddenModule/CreateGUID) - generate a fresh GUID and return it as a registry-formatted string
* [vbaCastObj](../tB/Modules/HiddenModule/vbaCastObj) - reinterpret an object as another COM interface (a typed `QueryInterface`)
* [vbaObjSet](../tB/Modules/HiddenModule/vbaObjSet), [vbaObjSetAddref](../tB/Modules/HiddenModule/vbaObjSetAddref) - assign a raw object pointer to an **Object** variable, with or without addref
* [vbaObjAddref](../tB/Modules/HiddenModule/vbaObjAddref) - increment the COM reference count of the object at a given address

See also:

* [ObjPtr](../tB/Modules/HiddenModule/ObjPtr) - return the COM-identity address of an object (see [Memory and Pointers](#memory-and-pointers))

## Command Line and Environment

Expand Down Expand Up @@ -351,11 +365,67 @@ Procedures:
* [CurrentSourceFile](../tB/Modules/Compilation/CurrentSourceFile) - returns the full path of the current source file
* [ProcessorArchitecture](../tB/Modules/Compilation/ProcessorArchitecture) - returns the processor architecture of the running application
* [CompilerVersion](../tB/Modules/Compilation/CompilerVersion) - returns the twinBASIC compiler version number
* [GetDeclaredTypeProgId](../tB/Modules/HiddenModule/GetDeclaredTypeProgId), [GetDeclaredTypeClsid](../tB/Modules/HiddenModule/GetDeclaredTypeClsid), [GetDeclaredTypeIid](../tB/Modules/HiddenModule/GetDeclaredTypeIid), [GetDeclaredTypeEventIid](../tB/Modules/HiddenModule/GetDeclaredTypeEventIid) - return the COM ProgID/CLSID/IID/event IID of a declared type, resolved at compile time
* [GetDeclaredMinEnumValue](../tB/Modules/HiddenModule/GetDeclaredMinEnumValue), [GetDeclaredMaxEnumValue](../tB/Modules/HiddenModule/GetDeclaredMaxEnumValue) - return the smallest/largest value of a declared enumeration, resolved at compile time

See also:

* [IMEStatus](../tB/Modules/Information/IMEStatus) - the current Input Method Editor mode (East Asian Windows only)

## Memory and Pointers

Procedures:

* [ObjPtr](../tB/Modules/HiddenModule/ObjPtr) - return the COM-identity address of an object
* [StrPtr](../tB/Modules/HiddenModule/StrPtr) - return the address of the underlying buffer of a **String**
* [VarPtr](../tB/Modules/HiddenModule/VarPtr) - return the address of a variable
* [AllocMem](../tB/Modules/HiddenModule/AllocMem), [FreeMem](../tB/Modules/HiddenModule/FreeMem) - allocate/release native memory blocks
* [GetMem1](../tB/Modules/HiddenModule/GetMem1), [GetMem2](../tB/Modules/HiddenModule/GetMem2), [GetMem4](../tB/Modules/HiddenModule/GetMem4), [GetMem8](../tB/Modules/HiddenModule/GetMem8), [GetMemPtr](../tB/Modules/HiddenModule/GetMemPtr) - read N bytes from a memory address into a typed variable
* [PutMem1](../tB/Modules/HiddenModule/PutMem1), [PutMem2](../tB/Modules/HiddenModule/PutMem2), [PutMem4](../tB/Modules/HiddenModule/PutMem4), [PutMem8](../tB/Modules/HiddenModule/PutMem8), [PutMemPtr](../tB/Modules/HiddenModule/PutMemPtr) - write a typed value of N bytes to a memory address
* [vbaCopyBytes](../tB/Modules/HiddenModule/vbaCopyBytes), [vbaCopyBytesZero](../tB/Modules/HiddenModule/vbaCopyBytesZero) - copy a block of bytes; the *Zero* form clears the source after the copy

See also:

* [vbaAryMove](../tB/Modules/HiddenModule/vbaAryMove), [vbaRefVarAry](../tB/Modules/HiddenModule/vbaRefVarAry) - low-level **Variant**-array helpers (see [Arrays](#arrays))
* [vbaObjSet](../tB/Modules/HiddenModule/vbaObjSet), [vbaObjSetAddref](../tB/Modules/HiddenModule/vbaObjSetAddref), [vbaObjAddref](../tB/Modules/HiddenModule/vbaObjAddref) - object-pointer assignment and refcounting (see [COM and Automation](#com-and-automation))

## Threading and Atomics

Procedures:

* [InterlockedExchangePointer](../tB/Modules/HiddenModule/InterlockedExchangePointer) - atomically exchange a pointer-sized value
* [InterlockedCompareExchangePointer](../tB/Modules/HiddenModule/InterlockedCompareExchangePointer) - atomically compare-and-swap a pointer-sized value
* [InterlockedCompareExchange32](../tB/Modules/HiddenModule/InterlockedCompareExchange32), [InterlockedCompareExchange64](../tB/Modules/HiddenModule/InterlockedCompareExchange64) - atomic 32-bit / 64-bit compare-and-swap
* [InterlockedIncrement32](../tB/Modules/HiddenModule/InterlockedIncrement32), [InterlockedDecrement32](../tB/Modules/HiddenModule/InterlockedDecrement32) - atomic 32-bit increment / decrement

See also:

* [SetThreadGlobalErrorTrap](../tB/Modules/HiddenModule/SetThreadGlobalErrorTrap) - per-thread error trap (see [Error Handling](#error-handling))

## Inline Assembly and Codegen

Procedures:

* [Emit](../tB/Modules/HiddenModule/Emit) - inject custom **Byte** values into the codegen of the enclosing procedure
* [EmitAny](../tB/Modules/HiddenModule/EmitAny) - inject custom typed values into the codegen of the enclosing procedure (size inferred from each value's data type)
* [StackOffset](../tB/Modules/HiddenModule/StackOffset) - return the stack-frame offset of a variable, resolved at compile time
* [StackArgsSize](../tB/Modules/HiddenModule/StackArgsSize) - return the total size of stack-passed arguments to the enclosing procedure
* [UnprotectedAccess](../tB/Modules/HiddenModule/UnprotectedAccess) - return an object reference that bypasses access checks on private members

See also:

* [Direct Assembly Insertion](../Features/Advanced/Assembly) - the `Naked` modifier and worked examples

## Expression Evaluation

Procedures:

* [Eval](../tB/Modules/HiddenModule/Eval) - compile and evaluate a twinBASIC expression supplied as a string

See also:

* [ExpressionService module](../tB/Modules/ExpressionService/) - the underlying engine, when more control over binders or compiled-expression reuse is needed

## Financial

Procedures:
Expand Down
1 change: 0 additions & 1 deletion docs/Reference/Core/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ redirect_from:
- /tB/Core/Unload
- /tB/Core/Unlock
- /tB/Core/While-Wend
- /tB/Core/Width
- /tB/Core/With
- /tB/Core/Write
---
Expand Down
32 changes: 32 additions & 0 deletions docs/Reference/Modules/HiddenModule/AllocMem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: AllocMem
parent: (Default) Module
permalink: /tB/Modules/HiddenModule/AllocMem
---
# AllocMem
{: .no_toc }

Allocates a block of native memory and returns its address.

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.

If the allocation fails, **AllocMem** raises a run-time error.

### Example

```tb
Dim Buffer As LongPtr = AllocMem(1024)
PutMem4 Buffer, &HDEADBEEF
'... use Buffer ...
FreeMem Buffer
```

### See Also

- [FreeMem](FreeMem) procedure
- [vbaCopyBytes](vbaCopyBytes) function
65 changes: 65 additions & 0 deletions docs/Reference/Modules/HiddenModule/Array.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: Array
parent: (Default) Module
permalink: /tB/Modules/HiddenModule/Array
---
# 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.

Syntax:
- *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.

*Var1*, *Var2*, ...
: *required* (destructuring form) The variables to receive successive elements of *RhsArray*. Pass `_` to skip an element.

*RhsArray*
: *required* (destructuring form) An array; non-array values raise an error.

The lower bound of an array created with **Array** is determined by the **Option Base** statement at the component scope, defaulting to `0`.

```tb
Option Base 1
Dim a As Variant
a = Array(10, 20, 30)
Debug.Print a(1) ' 10
```

The destructuring form unpacks an array into the named variables in order, starting from the array's lower bound. The argument list can mix variables and the `_` placeholder to skip elements:

```tb
Dim x As Variant, y As Variant, z As Variant
Array(x, y, z) = Array("one", "two", "three")
' x = "one", y = "two", z = "three"

Dim a As Variant, b As Variant
Array(a, _, b) = Array(1, 2, 3)
' a = 1, b = 3 — the second element is discarded
```

> [!NOTE]
> A **Variant** that is not declared as an array can still contain an array, and a **Variant** array can hold values of any type except fixed-length strings and user-defined types. Although a **Variant** containing an array is conceptually different from an array of **Variant** elements, indexing works the same way for both.

### Example

This example uses the **Array** function to return a **Variant** containing an array.

```tb
Dim MyWeek As Variant
Dim MyDay As Variant
MyWeek = Array("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
MyDay = MyWeek(2) ' MyDay contains "Wed" with default Option Base 0,
' or "Tue" under Option Base 1.
```

### See Also

- [Option](../../Core/Option) statement
- [LBound](../Information/LBound), [UBound](../Information/UBound) functions

{% include VBA-Attribution.md %}
32 changes: 32 additions & 0 deletions docs/Reference/Modules/HiddenModule/ConvertIconToBitmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: ConvertIconToBitmap
parent: (Default) Module
permalink: /tB/Modules/HiddenModule/ConvertIconToBitmap
---
# ConvertIconToBitmap
{: .no_toc }

Converts an icon picture into a bitmap picture.

Syntax: **ConvertIconToBitmap(** *IconPicture* [ **,** *BackColor* ] **)** **As Object**

*IconPicture*
: *required* **Object**. An **stdole.StdPicture** holding an icon (`vbPicTypeIcon`) or cursor (`vbPicTypeIcon`).

*BackColor*
: *optional* **Variant**. The background colour to flatten transparent pixels onto, given as an OLE colour value. If omitted, the system **Window** colour is used.

The returned picture is a fresh bitmap-typed **stdole.StdPicture** with the icon rasterised on top of the chosen background. The original icon picture is unchanged.

### Example

```tb
Dim Bmp As StdPicture
Set Bmp = ConvertIconToBitmap(MyIconPicture, RGB(255, 255, 255))
Set Picture1.Picture = Bmp
```

### See Also

- [CreateStdPictureFromHandle](CreateStdPictureFromHandle) function
- [PictureToByteArray](PictureToByteArray) function
26 changes: 26 additions & 0 deletions docs/Reference/Modules/HiddenModule/CreateGUID.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: CreateGUID
parent: (Default) Module
permalink: /tB/Modules/HiddenModule/CreateGUID
---
# CreateGUID
{: .no_toc }

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.

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

```tb
Debug.Print CreateGUID()
' {2A1B6F2C-4D9F-4D5E-9C8A-EE9C8B5F3DCE}
```

### See Also

- [vbaCastObj](vbaCastObj) function
27 changes: 27 additions & 0 deletions docs/Reference/Modules/HiddenModule/CreateStdPictureFromHandle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: CreateStdPictureFromHandle
parent: (Default) Module
permalink: /tB/Modules/HiddenModule/CreateStdPictureFromHandle
---
# CreateStdPictureFromHandle
{: .no_toc }

Wraps a GDI handle in an **stdole.StdPicture** so it can be assigned to a control's **Picture** property or passed to any other **IPicture** consumer.

Syntax: **CreateStdPictureFromHandle(** *Handle* **,** *Type* **,** *TakeOwnership* **)** **As Object**

*Handle*
: *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.

*TakeOwnership*
: *required* **Boolean**. If **True**, the returned picture takes ownership of *Handle* and frees it when released. If **False**, the caller remains responsible for the handle's lifetime.

The result is a regular **stdole.StdPicture** equivalent to one returned by **LoadPicture**, suitable for assignment to a **Picture** property.

### See Also

- [PictureToByteArray](PictureToByteArray) function
- [ConvertIconToBitmap](ConvertIconToBitmap) function
43 changes: 43 additions & 0 deletions docs/Reference/Modules/HiddenModule/Emit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: Emit
parent: (Default) Module
permalink: /tB/Modules/HiddenModule/Emit
---
# Emit
{: .no_toc }

Splices raw bytes into the codegen output of the enclosing procedure.

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.

### Example

A naked **InterlockedIncrement** that adds one to *Addend* atomically.

```tb
Public Function InlineInterlockedIncrement CDecl Naked(Addend As Long) As Long
#If Win64 Then
Emit(&Hb8, &H01, &H00, &H00, &H00) ' mov eax,0x1
Emit(&Hf0, &H0f, &Hc1, &H41, &H00) ' lock xadd DWORD PTR [rcx+0x4],eax
Emit(&Hff, &Hc0) ' inc eax
Emit(&Hc3) ' ret
#Else
Emit(&H8b, &H4c, &H24, &H04) ' mov ecx, DWORD PTR _Addend$[esp-4]
Emit(&Hb8, &H01, &H00, &H00, &H00) ' mov eax, 1
Emit(&Hf0, &H0f, &Hc1, &H01) ' lock xadd DWORD PTR [ecx], eax
Emit(&H40) ' inc eax
Emit(&Hc3) ' ret 0
#End If
End Function
```

### See Also

- [EmitAny](EmitAny) procedure
- [Direct Assembly Insertion](../../../Features/Advanced/Assembly)
- [StackOffset](StackOffset) function
Loading
Loading