McBasic™Get McBasic™ ↗
Build 881
Hands-on tutorial · Layout & Forms

Manage independent Form instances

Create, show, hide and unload windows deliberately.

2 Form / control designs2 complete BASIC filesGuided sample project

New creates a distinct instance. Show presents it; Hide removes it from view without necessarily discarding its state; Unload ends the Form lifecycle. QueryUnload can cancel closure. Use the sample’s lifecycle feedback to observe the order instead of assuming every Show creates a new window.

Step 1Prepare a safe practice project#

Extract the archive into a new writable folder, separate from your own application. Open MultiForms.mcproj in McBasic™. Keep every declared source, layout, resource and migration file together.

To reconstruct it yourself, create a DesktopApp project and add the files declared below. In the complete project, follow these steps as a guided rebuild: replace each named source file once and Check after all its procedures are present.

Exact project configuration
MultiForms.mcproj
{
  "schemaVersion": 1,
  "projectId": "357c7963-827f-484a-b5a8-3714b1d6ea04",
  "name": "MultiForms",
  "kind": "DesktopApp",
  "language": {
    "dialect": "McBasic1",
    "requireExplicit": true,
    "compare": "Binary",
    "defaultArrayBase": 0
  },
  "application": {
    "bundleIdentifier": "com.mcbasic.samples.multiforms",
    "version": "0.1.0",
    "buildNumber": "1",
    "startupFormId": "form-main",
    "shutdownMode": "OnStartupFormClosed"
  },
  "forms": [
    {
      "id": "form-main",
      "typeName": "frmMain",
      "layout": "Forms/frmMain.form.json",
      "code": "Forms/frmMain.bas"
    },
    {
      "id": "form-details",
      "typeName": "frmDetails",
      "layout": "Forms/frmDetails.form.json",
      "code": "Forms/frmDetails.bas"
    }
  ],
  "modules": [],
  "classes": [],
  "tests": [],
  "references": [],
  "resources": [],
  "targets": [
    "osx-arm64"
  ],
  "capabilities": []
}

Step 2Build the Form and set its properties#

frmMain

Select the Form first and set its properties. Add containers before their children. These are initial Designer values, not statements to paste into a procedure.

Form propertyValue
Caption"MultiForms — independent windows"
Width560
Height320
MinWidth520
MinHeight280
TypeNameParent
LabellblIntroForm
CommandButtoncmdAlphaForm
CommandButtoncmdBetaForm
LabellblStatusForm
CommandButtoncmdCloseForm
lblIntro · exact Inspector values
PropertyValue
Left24
Top24
Width500
Height44
Caption"Open two independent Forms. Each window has its own lifecycle."
Anchor edgesLeft, Top
cmdAlpha · exact Inspector values
PropertyValue
Left24
Top92
Width160
Height38
Caption"Open Alpha"
TabIndex0
Anchor edgesLeft, Top
cmdBeta · exact Inspector values
PropertyValue
Left200
Top92
Width160
Height38
Caption"Open Beta"
TabIndex1
Anchor edgesLeft, Top
lblStatus · exact Inspector values
PropertyValue
Left24
Top158
Width500
Height52
Caption"Ready. No secondary Forms are open."
Anchor edgesLeft, Top
cmdClose · exact Inspector values
PropertyValue
Left24
Top236
Width160
Height38
Caption"Close main Form"
TabIndex2
Anchor edgesLeft, Top

frmDetails

Select the Form first and set its properties. Add containers before their children. These are initial Designer values, not statements to paste into a procedure.

Form propertyValue
Caption"Details window"
Width360
Height220
MinWidth320
MinHeight190
TypeNameParent
LabellblNameForm
CommandButtoncmdHideForm
CommandButtoncmdUnloadForm
lblName · exact Inspector values
PropertyValue
Left24
Top24
Width300
Height44
Caption"Details window"
Anchor edgesLeft, Top
cmdHide · exact Inspector values
PropertyValue
Left24
Top96
Width140
Height36
Caption"Hide window"
TabIndex0
Anchor edgesLeft, Top
cmdUnload · exact Inspector values
PropertyValue
Left176
Top96
Width140
Height36
Caption"Unload window"
TabIndex1
Anchor edgesLeft, Top

Step 3Connect the events explicitly#

frmMain

ObjectEventProcedureParameters
cmdAlphaClickcmdAlpha_ClickClick()
cmdBetaClickcmdBeta_ClickClick()
cmdCloseClickcmdClose_ClickClick()
FormShownForm_Shown()

frmDetails

ObjectEventProcedureParameters
cmdHideClickcmdHide_ClickClick()
cmdUnloadClickcmdUnload_ClickClick()
FormInitializeForm_Initialize()
FormLoadForm_Load()
FormShownForm_Shown()
FormQueryUnloadForm_QueryUnload(ByRef Cancel As Integer, ByVal UnloadMode As Integer)
FormUnloadForm_Unload()

Step 4Enter the complete behavior#

Open the named source file. Enter declarations first, then every procedure. Expand a procedure for its full body, or copy the complete file. Helpers are required: do not stop after entering the first Click handler.

Forms/frmMain.bas

Enter these declarations at file scope, before the procedures.

Forms/frmMain.bas · declarations
Option Explicit
Private Sub Form_Shown()

Initialize state before enabling dependent actions. Keep the shared declarations and startup dependencies with this procedure.

Forms/frmMain.bas · Form_Shown
Private Sub Form_Shown()
    Dim alpha As frmDetails
    Dim beta As frmDetails
    Set alpha = New frmDetails
    Set beta = New frmDetails
    alpha.DisplayName = "Alpha"
    beta.DisplayName = "Beta"
    alpha.Show
    beta.Show
    lblStatus.Caption = "Alpha and Beta are independent windows."
End Sub
Private Sub cmdAlpha_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmMain.bas · cmdAlpha_Click
Private Sub cmdAlpha_Click()
    Dim alpha As frmDetails
    Set alpha = New frmDetails
    alpha.DisplayName = "Alpha"
    alpha.Show
    lblStatus.Caption = "Alpha is an independent window."
End Sub
Private Sub cmdBeta_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmMain.bas · cmdBeta_Click
Private Sub cmdBeta_Click()
    Dim beta As frmDetails
    Set beta = New frmDetails
    beta.DisplayName = "Beta"
    beta.Show
    lblStatus.Caption = "Beta is an independent window."
End Sub
Private Sub cmdClose_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmMain.bas · cmdClose_Click
Private Sub cmdClose_Click()
    Unload Me
End Sub
Copy the complete Forms/frmMain.bas file

Replace the file once; do not append duplicate procedures.

Forms/frmMain.bas
Option Explicit

Private Sub Form_Shown()
    Dim alpha As frmDetails
    Dim beta As frmDetails
    Set alpha = New frmDetails
    Set beta = New frmDetails
    alpha.DisplayName = "Alpha"
    beta.DisplayName = "Beta"
    alpha.Show
    beta.Show
    lblStatus.Caption = "Alpha and Beta are independent windows."
End Sub

Private Sub cmdAlpha_Click()
    Dim alpha As frmDetails
    Set alpha = New frmDetails
    alpha.DisplayName = "Alpha"
    alpha.Show
    lblStatus.Caption = "Alpha is an independent window."
End Sub

Private Sub cmdBeta_Click()
    Dim beta As frmDetails
    Set beta = New frmDetails
    beta.DisplayName = "Beta"
    beta.Show
    lblStatus.Caption = "Beta is an independent window."
End Sub

Private Sub cmdClose_Click()
    Unload Me
End Sub

Forms/frmDetails.bas

Enter these declarations at file scope, before the procedures.

Forms/frmDetails.bas · declarations
Option Explicit

Public DisplayName As String
Private Sub Form_Initialize()

Initialize state before enabling dependent actions. Keep the shared declarations and startup dependencies with this procedure.

Forms/frmDetails.bas · Form_Initialize
Private Sub Form_Initialize()
    Debug.Print "initialize:" & DisplayName
End Sub
Private Sub Form_Load()

Initialize state before enabling dependent actions. Keep the shared declarations and startup dependencies with this procedure.

Forms/frmDetails.bas · Form_Load
Private Sub Form_Load()
    Debug.Print "load:" & DisplayName
End Sub
Private Sub Form_Shown()

Initialize state before enabling dependent actions. Keep the shared declarations and startup dependencies with this procedure.

Forms/frmDetails.bas · Form_Shown
Private Sub Form_Shown()
    lblName.Caption = "Details window: " & DisplayName
    Debug.Print "shown:" & DisplayName
End Sub
Private Sub cmdHide_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmDetails.bas · cmdHide_Click
Private Sub cmdHide_Click()
    Me.Hide
    Debug.Print "hidden:" & DisplayName
End Sub
Private Sub cmdUnload_Click()

Enter the complete action, including its input checks and calls to helper procedures.

Forms/frmDetails.bas · cmdUnload_Click
Private Sub cmdUnload_Click()
    Unload Me
End Sub
Private Sub Form_QueryUnload(ByRef Cancel As Integer, ByVal UnloadMode As Integer)

This is the lifetime boundary. Preserve the cancellation signature where present and release resources owned by this Form.

Forms/frmDetails.bas · Form_QueryUnload
Private Sub Form_QueryUnload(ByRef Cancel As Integer, ByVal UnloadMode As Integer)
    Debug.Print "query:" & DisplayName & ":" & UnloadMode
End Sub
Private Sub Form_Unload()

This is the lifetime boundary. Preserve the cancellation signature where present and release resources owned by this Form.

Forms/frmDetails.bas · Form_Unload
Private Sub Form_Unload()
    Debug.Print "unload:" & DisplayName
End Sub
Copy the complete Forms/frmDetails.bas file

Replace the file once; do not append duplicate procedures.

Forms/frmDetails.bas
Option Explicit

Public DisplayName As String

Private Sub Form_Initialize()
    Debug.Print "initialize:" & DisplayName
End Sub

Private Sub Form_Load()
    Debug.Print "load:" & DisplayName
End Sub

Private Sub Form_Shown()
    lblName.Caption = "Details window: " & DisplayName
    Debug.Print "shown:" & DisplayName
End Sub

Private Sub cmdHide_Click()
    Me.Hide
    Debug.Print "hidden:" & DisplayName
End Sub

Private Sub cmdUnload_Click()
    Unload Me
End Sub

Private Sub Form_QueryUnload(ByRef Cancel As Integer, ByVal UnloadMode As Integer)
    Debug.Print "query:" & DisplayName & ":" & UnloadMode
End Sub

Private Sub Form_Unload()
    Debug.Print "unload:" & DisplayName
End Sub

Step 5Keep resources and storage reproducible#

No external resource or migration files are declared. Any inline migration, seed data or local JSON is present in the code above. Runtime application data and private preferences are not included in the archive.

Step 6Check, run and test the result#

Save all files and run Check. Resolve diagnostics before Run. Developer CLI users can work from the extracted folder:

Developer CLI
mcbasic check MultiForms.mcproj
mcbasic run MultiForms.mcproj

Acceptance checklist

  • Open Alpha and Beta and compare their state.
  • Hide an instance and show it again.
  • Unload an instance and reopen it.
  • Exercise the close veto and inspect lifecycle messages.

Step 7Make one change and repeat the tests#

Pass a public property to each new Form before showing it.

Save a working Git checkpoint first. Change one behavior, Check again and repeat the acceptance checklist. Compare with the downloaded solution if a regression appears.

Source baseline 20f4bfed6b · Build manifest