Use records, startup code and Form references
Understand value-copy records, class initialization, Sub Main and the newer desktop object APIs.
Choose a Type for values, a Class for identity#
Type … End Type declares a record. Put a Public Type in a standard module when Forms/classes need it; Private Types stay local to their declaring module. Assigning a Type copies its value, including nested record/array data. Do not use Set or New for a Type. Compare individual fields rather than comparing whole records.
Public Type Reading
Name As String
Value As Long
End Type
Public Function CopyProof() As Long
Dim original As Reading
Dim edited As Reading
original.Value = 7
edited = original
edited.Value = 9
CopyProof = original.Value * 10 + edited.Value
End FunctionType variables, typed parameters/results and arrays are supported. With can target a record or array element. Types are not scalar Variants or Collection items; Len is not a binary record-size operation. For an array of records, use indexed iteration from LBound to UBound rather than For Each. See the downloadable example and unit tests.
Initialize instances; do not depend on prompt finalization#
A parameterless Class_Initialize Sub runs for a new class instance. Class_Terminate runs when the runtime reclaims an instance or drains surviving instances during normal shutdown, not necessarily when the last BASIC reference disappears. Keep critical cleanup explicit. The End statement terminates immediately and skips orderly Form/class cleanup; use normal close/quit paths when cleanup matters.
Start a DesktopApp from code#
Choose Sub Main in Project → Startup Object. Declare exactly one public parameterless Sub Main in a standard module; Public Async Sub Main is also supported for this startup choice. Show the initial Form yourself. The project uses startupObject SubMain and shutdownMode OnLastFormClosed, with no startupFormId.
Public Sub Main()
frmMain.Show
End SubA module named Main is not by itself the startup setting. With a startup Form selected, an ordinary module Sub Main is just another procedure. An MDI child cannot be the startup window without its MDI parent. UI tests that expect an automatic startup Form require that startup mode; use unit tests for the pure functions in this lesson.
Access the right Form and member#
As Form holds the common Form surface. A reference of a specific Form type is needed for its authored members. Cross-form access supports its exposed controls, nonvisual components and indexed members; this is different from using New to create a control. Load a Form to initialize it without showing it, Show to display it, and Unload for its normal lifetime boundary.
Screen exposes desktop/window facts and the global pointer choice; an active Form may be absent, so check Nothing before dereferencing. Object references still cannot be stored in scalar Collection/Dictionary/Variant slots. Use explicit typed references or supported typed arrays.
Read identity without treating it as writable state#
App adds Title, EXEName, PrevInstance, Major, Minor, Revision, ProductName, CompanyName, FileDescription and LegalCopyright. Title is read/write; the others are read-only. PrevInstance currently returns False and FileDescription is empty. App.Path is not a portable writable data directory; use App.DataPath/AppPaths.DataFile for application-owned data. Timer Interval 0 is a disabled schedule, not the fastest possible timer. Bare Rnd is supported alongside the function form; neither is a source of cryptographic secrets.
20f4bfed6b · Build manifestSources & maintenance
Original web explanation, reviewed against these repository sources. API tables and example files follow the implementation.
tests/McBasic.Compiler.Tests/UserTypeChecks.cstests/McBasic.Compiler.Tests/Vb6ScreenClassChecks.cstests/McBasic.Compiler.Tests/SubMainChecks.cstests/McBasic.Compiler.Tests/ApplicationObjectChecks.cssrc/McBasic.Runtime/McApp.cssrc/McBasic.Compiler/Binder.cs