McBasic™Get McBasic™ ↗
Build 881
Hands-on tutorial · Input & events

Keep option groups independent

Build mutually exclusive choices without coupling unrelated decisions.

1 Form / control designs1 complete BASIC filesGuided sample project

Group identity matters more than distance on the canvas. Delivery, payment and customer type are independent decisions in this sample. Update the summary from the selected states, and inspect the difference between clicking the already-selected option and changing a value.

Step 1Prepare a safe practice project#

Extract the archive into a new writable folder, separate from your own application. Open OptionGroups.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
OptionGroups.mcproj
{
  "schemaVersion": 1,
  "projectId": "99578971-5863-4082-a627-ec424196595e",
  "name": "OptionGroups",
  "kind": "DesktopApp",
  "language": {
    "dialect": "McBasic1",
    "requireExplicit": true,
    "compare": "Binary",
    "defaultArrayBase": 0
  },
  "application": {
    "bundleIdentifier": "com.mcbasic.optiongroups",
    "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"
    }
  ],
  "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"Option groups"
Width620
Height460
TypeNameParent
PanelpnlDeliveryForm
PanelpnlPaymentForm
OptionButtonoptStandardpnlDelivery
OptionButtonoptExpresspnlDelivery
OptionButtonoptCardpnlPayment
OptionButtonoptCashpnlPayment
OptionButtonoptPersonalForm
OptionButtonoptBusinessForm
LabellblStateForm
LabellblClickForm
CommandButtoncmdExpressForm
pnlDelivery · exact Inspector values
PropertyValue
Left24
Top44
Width240
Height150
EnabledTrue
VisibleTrue
TabIndex0
Anchor edgesLeft, Top
pnlPayment · exact Inspector values
PropertyValue
Left284
Top44
Width240
Height150
EnabledTrue
VisibleTrue
TabIndex1
Anchor edgesLeft, Top
optStandard · exact Inspector values
PropertyValue
Left16
Top24
Width200
Height32
EnabledTrue
VisibleTrue
Caption"Standard delivery"
GroupName"delivery"
CheckedTrue
TabIndex2
Anchor edgesLeft, Top
optExpress · exact Inspector values
PropertyValue
Left16
Top72
Width200
Height32
EnabledTrue
VisibleTrue
Caption"Express delivery"
GroupName"delivery"
CheckedFalse
TabIndex3
Anchor edgesLeft, Top
optCard · exact Inspector values
PropertyValue
Left16
Top24
Width200
Height32
EnabledTrue
VisibleTrue
Caption"Card"
GroupName"payment"
CheckedTrue
TabIndex4
Anchor edgesLeft, Top
optCash · exact Inspector values
PropertyValue
Left16
Top72
Width200
Height32
EnabledTrue
VisibleTrue
Caption"Cash"
GroupName"payment"
CheckedFalse
TabIndex5
Anchor edgesLeft, Top
optPersonal · exact Inspector values
PropertyValue
Left24
Top220
Width240
Height32
EnabledTrue
VisibleTrue
Caption"Personal account"
GroupName"account"
CheckedTrue
TabIndex6
Anchor edgesLeft, Top
optBusiness · exact Inspector values
PropertyValue
Left284
Top220
Width240
Height32
EnabledTrue
VisibleTrue
Caption"Business account"
GroupName"account"
CheckedFalse
TabIndex7
Anchor edgesLeft, Top
lblState · exact Inspector values
PropertyValue
Left24
Top274
Width570
Height42
EnabledTrue
VisibleTrue
Caption"Ready"
TabIndex8
Anchor edgesLeft, Top
lblClick · exact Inspector values
PropertyValue
Left24
Top320
Width570
Height32
EnabledTrue
VisibleTrue
Caption"Choose an option"
TabIndex9
Anchor edgesLeft, Top
cmdExpress · exact Inspector values
PropertyValue
Left24
Top366
Width280
Height32
EnabledTrue
VisibleTrue
Caption"Select express from BASIC"
TabIndex10
Anchor edgesLeft, Top

Step 3Connect the events explicitly#

frmMain

ObjectEventProcedureParameters
FormLoadForm_Load()

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 UpdateState()

Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.

Forms/frmMain.bas · UpdateState
Private Sub UpdateState()
    lblState.Caption = "Express: " & CStr(optExpress.Checked) & "; Cash: " & CStr(optCash.Checked) & "; Business: " & CStr(optBusiness.Checked)
End Sub
Public Sub Form_Load()

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

Forms/frmMain.bas · Form_Load
Public Sub Form_Load()
    cmdExpress.Default = True
    cmdExpress.Cancel = True
    lblClick.Caption = "Named group: " & optStandard.GroupName
    Call UpdateState()
End Sub
Public Sub cmdExpress_Click()

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

Forms/frmMain.bas · cmdExpress_Click
Public Sub cmdExpress_Click()
    optExpress.Checked = True
End Sub
Public Sub optStandard_Change()

Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.

Forms/frmMain.bas · optStandard_Change
Public Sub optStandard_Change()
    Call UpdateState()
End Sub
Public Sub optStandard_Click()

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

Forms/frmMain.bas · optStandard_Click
Public Sub optStandard_Click()
    lblClick.Caption = "Click: optStandard"
End Sub
Public Sub optExpress_Change()

Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.

Forms/frmMain.bas · optExpress_Change
Public Sub optExpress_Change()
    Call UpdateState()
End Sub
Public Sub optExpress_Click()

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

Forms/frmMain.bas · optExpress_Click
Public Sub optExpress_Click()
    lblClick.Caption = "Click: optExpress"
End Sub
Public Sub optCard_Change()

Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.

Forms/frmMain.bas · optCard_Change
Public Sub optCard_Change()
    Call UpdateState()
End Sub
Public Sub optCard_Click()

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

Forms/frmMain.bas · optCard_Click
Public Sub optCard_Click()
    lblClick.Caption = "Click: optCard"
End Sub
Public Sub optCash_Change()

Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.

Forms/frmMain.bas · optCash_Change
Public Sub optCash_Change()
    Call UpdateState()
End Sub
Public Sub optCash_Click()

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

Forms/frmMain.bas · optCash_Click
Public Sub optCash_Click()
    lblClick.Caption = "Click: optCash"
End Sub
Public Sub optPersonal_Change()

Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.

Forms/frmMain.bas · optPersonal_Change
Public Sub optPersonal_Change()
    Call UpdateState()
End Sub
Public Sub optPersonal_Click()

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

Forms/frmMain.bas · optPersonal_Click
Public Sub optPersonal_Click()
    lblClick.Caption = "Click: optPersonal"
End Sub
Public Sub optBusiness_Change()

Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.

Forms/frmMain.bas · optBusiness_Change
Public Sub optBusiness_Change()
    Call UpdateState()
End Sub
Public Sub optBusiness_Click()

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

Forms/frmMain.bas · optBusiness_Click
Public Sub optBusiness_Click()
    lblClick.Caption = "Click: optBusiness"
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 UpdateState()
    lblState.Caption = "Express: " & CStr(optExpress.Checked) & "; Cash: " & CStr(optCash.Checked) & "; Business: " & CStr(optBusiness.Checked)
End Sub

Public Sub Form_Load()
    cmdExpress.Default = True
    cmdExpress.Cancel = True
    lblClick.Caption = "Named group: " & optStandard.GroupName
    Call UpdateState()
End Sub

Public Sub cmdExpress_Click()
    optExpress.Checked = True
End Sub

Public Sub optStandard_Change()
    Call UpdateState()
End Sub

Public Sub optStandard_Click()
    lblClick.Caption = "Click: optStandard"
End Sub

Public Sub optExpress_Change()
    Call UpdateState()
End Sub

Public Sub optExpress_Click()
    lblClick.Caption = "Click: optExpress"
End Sub

Public Sub optCard_Change()
    Call UpdateState()
End Sub

Public Sub optCard_Click()
    lblClick.Caption = "Click: optCard"
End Sub

Public Sub optCash_Change()
    Call UpdateState()
End Sub

Public Sub optCash_Click()
    lblClick.Caption = "Click: optCash"
End Sub

Public Sub optPersonal_Change()
    Call UpdateState()
End Sub

Public Sub optPersonal_Click()
    lblClick.Caption = "Click: optPersonal"
End Sub

Public Sub optBusiness_Change()
    Call UpdateState()
End Sub

Public Sub optBusiness_Click()
    lblClick.Caption = "Click: optBusiness"
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 OptionGroups.mcproj
mcbasic run OptionGroups.mcproj

Acceptance checklist

  • Change delivery without changing payment.
  • Click an already-selected option and compare Click with Change.
  • Use the Express command to select an option programmatically.

Step 7Make one change and repeat the tests#

Add another delivery choice while preserving the other two groups.

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