Event-Driven Programming in QBasic

Event-driven programming is a programming paradigm centered around the response to events. Unlike procedural programming, where the flow of execution is determined by a sequence of instructions, event-driven programming waits for events or user actions to trigger code execution. This approach has gained prominence, especially in the development of graphical user interfaces (GUIs). In this article, we will explore the principles of event-driven programming in QBasic, particularly how it applies to building simple GUIs.

Understanding Events in QBasic

In the context of QBasic, an event is any action that occurs during the execution of a program, such as mouse clicks, keyboard presses, or timer events. To effectively manage these events, QBasic utilizes a loop structure called the event loop. This loop continuously checks for events and executes the corresponding event handler when an event is detected.

In QBasic, event-driven programming can be simulated using graphics and input handling commands. While QBasic does not have built-in support for GUI event handling like modern languages, we can create our mechanisms to respond to user actions. The most common events you’ll deal with include:

  • Mouse Events: Actions such as clicks or movement of the mouse.
  • Keyboard Events: Key presses that can trigger functions or commands.
  • Timer Events: Events that occur after a specific duration, allowing you to implement time-based actions.

Setting Up the Environment

Before diving into event-driven programming, ensure you have QBasic set up properly. You can download QBasic from various archives online, as it is a legacy environment. Run the QBasic IDE, and you're ready to start coding.

Event Loop Structure

The core of an event-driven program is the event loop. It continuously checks for user inputs and executes the relevant code. Below is a basic structure of an event loop in QBasic:

DO
    ' Check for keyboard events
    IF INKEY$ <> "" THEN
        ' Handle the keyboard input
        key = INKEY$
        PRINT "You pressed: "; key
    END IF
    
    ' Check for mouse events
    ' (Mouse support in QBasic is more complicated and generally involves using interrupts)
    
    ' Implement other event checks as needed

    ' Optional: Add a delay to prevent rapid processing
    SLEEP 1
LOOP UNTIL key = "ESC"  ' Exit the loop when ESC is pressed

This basic structure reflects the continually running nature of an event-driven program. The program constantly checks for user input and reacts where necessary. However, handling mouse events requires a more in-depth approach.

Handling Mouse Events

To handle mouse events in QBasic, you'll typically need to use BIOS interrupts to capture mouse actions. Here’s a simplified example of how you can create a mouse click event handler:

DECLARE SUB InitMouse
DECLARE FUNCTION MouseX%() AS INTEGER
DECLARE FUNCTION MouseY%() AS INTEGER
DECLARE FUNCTION ButtonPressed%() AS INTEGER

SUB InitMouse
    ' Initialize the mouse
    MOV AX, 0
    INT 33h  ' BIOS mouse interrupt
END SUB

FUNCTION MouseX%() AS INTEGER
    DIM x AS INTEGER
    DIM y AS INTEGER
    ' Get mouse position
    MOV AX, 3  ' Function 3
    INT 33h
    x = CX
    MouseX% = x
END FUNCTION

FUNCTION MouseY%() AS INTEGER
    DIM x AS INTEGER
    DIM y AS INTEGER
    ' Get mouse position
    MOV AX, 3  ' Function 3
    INT 33h
    y = DX
    MouseY% = y
END FUNCTION

FUNCTION ButtonPressed%() AS INTEGER
    DIM MouseStatus AS INTEGER
    ' Get mouse button status
    MOV AX, 3  ' Function 3
    INT 33h
    ButtonPressed% = AL
END FUNCTION

Now, you can enhance our event loop to include mouse checks:

InitMouse  ' Prepare mouse for use
DO
    ' Handle keyboard input as before
    IF INKEY$ <> "" THEN
        key = INKEY$
        PRINT "You pressed: "; key
    END IF
    
    ' Handle mouse input
    IF ButtonPressed%() THEN
        x = MouseX%()
        y = MouseY%()
        PRINT "Mouse clicked at: "; x; ", "; y
    END IF

    SLEEP 1
LOOP UNTIL key = "ESC"

Building a Simple GUI

With our event loop and mouse handling set up, we can create a simple application that simulates a graphical user interface. For this, we can create buttons and allow users to click them, responding appropriately to each click.

SUB DrawButton (x%, y%, width%, height%, label$)
    ' Draw a rectangle for the button
    LINE (x%, y%) - (x% + width%, y% + height%), 15, BF
    ' Print the label in the center of the button
    LOCATE (y% + height% / 2 + 1), (x% + width% / 2) / 8
    PRINT label$
END SUB

' Create buttons
DrawButton 10, 10, 50, 20, "Click Me"
DrawButton 70, 10, 50, 20, "Exit"

DO
    ' Event handling as before
    IF ButtonPressed%() THEN
        x = MouseX%()
        y = MouseY%()
        IF x >= 10 AND x <= 60 AND y >= 10 AND y <= 30 THEN
            PRINT "Button 'Click Me' was clicked!"
        ELSEIF x >= 70 AND x <= 120 AND y >= 10 AND y <= 30 THEN
            PRINT "Button 'Exit' was clicked!"
            EXIT DO
        END IF
    END IF
    SLEEP 1
LOOP

In this example, we’ve created two buttons: "Click Me" and "Exit." Each button reacts to mouse clicks by checking the coordinates of the mouse pointer, allowing users to interact with the GUI.

Conclusion

Event-driven programming in QBasic might not be as straightforward as using modern programming languages with built-in GUI support, but it is accessible and a fun challenge for those looking to delve deeper into programming concepts. By understanding events, constructing an event loop, and handling various input methods, you can create interactive applications even within the confines of QBasic.

While this article provided a foundational understanding of event-driven programming in QBasic, there is much more to explore. As you experiment with your applications, consider how you might expand upon this foundation—such as adding more buttons, enhancing keyboard interactions, or introducing timer events for animations.

So go ahead, unleash your creativity in QBasic, and remember, coding is about solving problems—it’s about harnessing the power of events to breathe life into your programs! Happy coding!