VB6Parse / Library / Interaction / doevents

VB6 Library Reference

DoEvents Function

Yields execution so that the operating system can process other events and messages.

Syntax

DoEvents()

Parameters

None.

Return Value

Returns an Integer representing the number of open forms in stand-alone versions of Visual Basic. Returns 0 in all other applications.

Remarks

The DoEvents function temporarily yields execution to the operating system, allowing it to process other events such as user input, timers, and system messages. This is essential for keeping an application responsive during long-running operations. Important Characteristics: - Yields control to the operating system - Allows message queue processing - Prevents UI from appearing frozen during long operations - Can cause reentrancy issues if not used carefully - Slows down operations slightly due to context switching - Returns number of open forms (VB6 stand-alone only) - In most contexts, return value is ignored - Does not create a new thread or async operation - Processes Windows messages in the queue - Can trigger event handlers and user interactions

When to Use DoEvents

When NOT to Use DoEvents

Examples

Basic Usage

' Process large dataset while keeping UI responsive
Dim i As Long
For i = 1 To 100000
    ProcessRecord i
    ' Yield every 100 iterations
    If i Mod 100 = 0 Then
        DoEvents
    End If
Next i
' Simple DoEvents call
DoEvents
' Check return value (rarely used)
Dim formCount As Integer
formCount = DoEvents()

Progress Bar Update

Sub ProcessWithProgress()
    Dim i As Long
    Dim total As Long
    total = 10000
    ProgressBar1.Min = 0
    ProgressBar1.Max = total
    For i = 1 To total
        ProcessItem i
        ' Update progress bar
        ProgressBar1.Value = i
        lblStatus.Caption = "Processing " & i & " of " & total
        ' Allow UI to refresh
        DoEvents
    Next i
    MsgBox "Processing complete!"
End Sub

File Processing

Sub ProcessLargeFile(filePath As String)
    Dim fileNum As Integer
    Dim line As String
    Dim lineCount As Long
    fileNum = FreeFile
    Open filePath For Input As #fileNum
    lineCount = 0
    Do Until EOF(fileNum)
        Line Input #fileNum, line
        ProcessLine line
        lineCount = lineCount + 1
        ' Yield every 100 lines
        If lineCount Mod 100 = 0 Then
            DoEvents
        End If
    Loop
    Close #fileNum
End Sub

Common Patterns

Cancellable Long Operation

Private cancelOperation As Boolean
Sub PerformCancellableOperation()
    Dim i As Long
    cancelOperation = False
    cmdCancel.Enabled = True
    For i = 1 To 100000
        If cancelOperation Then
            MsgBox "Operation cancelled"
            Exit For
        End If
        ProcessItem i
        If i Mod 100 = 0 Then
            DoEvents  ' Allows cancel button to be clicked
        End If
    Next i
    cmdCancel.Enabled = False
End Sub
Private Sub cmdCancel_Click()
    cancelOperation = True
End Sub

Batch Import with Status

Sub ImportRecords(records As Variant)
    Dim i As Long
    Dim startTime As Double
    startTime = Timer
    For i = LBound(records) To UBound(records)
        ImportRecord records(i)
        ' Update status every 50 records
        If i Mod 50 = 0 Then
            lblStatus.Caption = "Imported " & i & " records..."
            DoEvents
        End If
    Next i
    lblStatus.Caption = "Import complete: " & UBound(records) - LBound(records) + 1 & _
                        " records in " & Format(Timer - startTime, "0.00") & " seconds"
End Sub

Prevent UI Freeze During Calculation

Function CalculateComplexResult(data As Variant) As Double
    Dim i As Long
    Dim result As Double
    Dim iterations As Long
    iterations = 0
    result = 0
    For i = LBound(data) To UBound(data)
        result = result + PerformComplexCalculation(data(i))
        iterations = iterations + 1
        ' Yield periodically
        If iterations Mod 500 = 0 Then
            DoEvents
        End If
    Next i
    CalculateComplexResult = result
End Function

Database Batch Update

Sub UpdateRecordsBatch(rs As ADODB.Recordset)
    Dim count As Long
    count = 0
    Do Until rs.EOF
        rs("Status") = "Processed"
        rs("ProcessDate") = Date
        rs.Update
        count = count + 1
        If count Mod 25 = 0 Then
            lblProgress.Caption = count & " records updated"
            DoEvents
        End If
        rs.MoveNext
    Loop
End Sub

Search Operation with Live Results

Sub SearchFiles(rootPath As String, searchTerm As String)
    Dim fileName As String
    Dim matchCount As Long
    matchCount = 0
    lstResults.Clear
    fileName = Dir(rootPath & "\*.*")
    Do While fileName <> ""
        If InStr(1, fileName, searchTerm, vbTextCompare) > 0 Then
            lstResults.AddItem fileName
            matchCount = matchCount + 1
        End If
        fileName = Dir
        DoEvents  ' Keep UI responsive, allow viewing results
    Loop
    lblStatus.Caption = matchCount & " matches found"
End Sub

Report Generation

Sub GenerateReport(data As Collection)
    Dim item As Variant
    Dim lineNum As Long
    lineNum = 0
    For Each item In data
        WriteReportLine item
        lineNum = lineNum + 1
        If lineNum Mod 20 = 0 Then
            lblProgress.Caption = "Generated " & lineNum & " lines..."
            DoEvents
        End If
    Next item
End Sub

Animation or Visual Feedback

Sub ShowProcessingAnimation()
    Dim i As Integer
    For i = 1 To 100
        ' Update visual indicator
        shpIndicator.Left = i * 50
        DoEvents
        ' Simulate work
        Sleep 10
    Next i
End Sub

Multi-Step Process

Sub MultiStepProcess()
    lblStatus.Caption = "Step 1: Loading data..."
    DoEvents
    LoadData
    lblStatus.Caption = "Step 2: Processing data..."
    DoEvents
    ProcessData
    lblStatus.Caption = "Step 3: Saving results..."
    DoEvents
    SaveResults
    lblStatus.Caption = "Complete!"
    DoEvents
End Sub

Advanced Usage

Prevent Reentrancy

Private isProcessing As Boolean
Sub SafeProcessWithDoEvents()
    ' Prevent re-entry
    If isProcessing Then
        MsgBox "Already processing"
        Exit Sub
    End If
    isProcessing = True
    Dim i As Long
    For i = 1 To 10000
        ProcessItem i
        If i Mod 100 = 0 Then
            DoEvents
        End If
    Next i
    isProcessing = False
End Sub

Throttled DoEvents

Sub ProcessWithThrottledDoEvents()
    Dim i As Long
    Dim lastDoEvents As Double
    Dim doEventsInterval As Double
    doEventsInterval = 0.1  ' 100ms
    lastDoEvents = Timer
    For i = 1 To 100000
        ProcessItem i
        ' DoEvents based on time, not iteration count
        If Timer - lastDoEvents > doEventsInterval Then
            DoEvents
            lastDoEvents = Timer
        End If
    Next i
End Sub

Disable Controls During Processing

Sub ProcessWithDisabledControls()
    ' Disable controls to prevent reentrancy
    DisableControls
    Dim i As Long
    For i = 1 To 10000
        ProcessItem i
        If i Mod 100 = 0 Then
            UpdateProgress i
            DoEvents  ' Safe because controls are disabled
        End If
    Next i
    EnableControls
End Sub
Sub DisableControls()
    Dim ctrl As Control
    For Each ctrl In Me.Controls
        If TypeOf ctrl Is CommandButton Then
            ctrl.Enabled = False
        End If
    Next ctrl
End Sub
Sub EnableControls()
    Dim ctrl As Control
    For Each ctrl In Me.Controls
        If TypeOf ctrl Is CommandButton Then
            ctrl.Enabled = True
        End If
    Next ctrl
End Sub

Background Processing Simulation

' Simulates background processing using DoEvents
Private processingComplete As Boolean
Sub StartBackgroundTask()
    processingComplete = False
    ' Start the "background" task
    ProcessInBackground
    ' Show modal dialog that waits
    Do Until processingComplete
        DoEvents
        Sleep 10  ' Small delay to reduce CPU usage
    Loop
    MsgBox "Background task complete"
End Sub
Sub ProcessInBackground()
    Dim i As Long
    For i = 1 To 10000
        ProcessItem i
        If i Mod 100 = 0 Then
            DoEvents
        End If
    Next i
    processingComplete = True
End Sub

Smart DoEvents with CPU Management

Sub ProcessWithCPUManagement()
    Dim i As Long
    Dim processingTime As Double
    Dim doEventsTime As Double
    For i = 1 To 100000
        processingTime = Timer
        ProcessItem i
        processingTime = Timer - processingTime
        ' DoEvents if processing takes significant time
        If processingTime > 0.05 Then  ' More than 50ms
            doEventsTime = Timer
            DoEvents
            doEventsTime = Timer - doEventsTime
            ' Adjust strategy if DoEvents takes too long
            If doEventsTime > processingTime * 0.1 Then
                ' DoEvents overhead is too high, reduce frequency
                ' (implementation-specific logic here)
            End If
        End If
    Next i
End Sub

Export with User Interaction

Sub ExportDataWithOptions()
    Dim i As Long
    Dim exportCount As Long
    exportCount = 0
    For i = 1 To RecordCount
        If chkIncludeDeleted.Value = vbChecked Or Not IsDeleted(i) Then
            ExportRecord i
            exportCount = exportCount + 1
        End If
        ' Update UI and allow user to change options
        If i Mod 50 = 0 Then
            lblProgress.Caption = exportCount & " records exported"
            DoEvents
            ' User can check/uncheck options, affecting subsequent exports
        End If
    Next i
End Sub

Error Handling

Sub ProcessWithErrorHandling()
    On Error GoTo ErrorHandler
    Dim i As Long
    For i = 1 To 10000
        ProcessItem i
        If i Mod 100 = 0 Then
            DoEvents
        End If
    Next i
    Exit Sub
ErrorHandler:
    ' DoEvents can trigger errors if event handlers fail
    MsgBox "Error during processing: " & Err.Description
    Resume Next
End Sub

Common Errors

Performance Considerations

Best Practices

Call Periodically, Not Every Iteration

' Good - DoEvents every 100 iterations
For i = 1 To 100000
    ProcessItem i
    If i Mod 100 = 0 Then DoEvents
Next i
' Bad - DoEvents every iteration (slow)
For i = 1 To 100000
    ProcessItem i
    DoEvents  ' Too frequent!
Next i

Protect Against Reentrancy

' Good - Use flag to prevent reentrancy
Private isProcessing As Boolean
Sub Process()
    If isProcessing Then Exit Sub
    isProcessing = True
    ' ... processing with DoEvents ...
    isProcessing = False
End Sub
' Bad - No protection
Sub Process()
    ' ... processing with DoEvents ...
    ' Can be called again through DoEvents
End Sub

Disable User Input When Needed

' Good - Disable controls that could cause problems
cmdProcess.Enabled = False
For i = 1 To 10000
    ProcessItem i
    If i Mod 100 = 0 Then DoEvents
Next i
cmdProcess.Enabled = True

Consider Alternatives

' For very long operations, consider:
' 1. Timer control for asynchronous processing
' 2. Threading (in modern applications)
' 3. Breaking into smaller chunks with callbacks
' 4. Progress forms with asynchronous updates

Comparison with Other Approaches

DoEvents vs Timer Control

' DoEvents - Synchronous, blocks until complete
For i = 1 To 10000
    ProcessItem i
    If i Mod 100 = 0 Then DoEvents
Next i
' Timer - Asynchronous, processes in chunks
Private currentIndex As Long
Private Sub Timer1_Timer()
    Dim i As Long
    For i = currentIndex To currentIndex + 99
        If i > 10000 Then
            Timer1.Enabled = False
            Exit Sub
        End If
        ProcessItem i
    Next i
    currentIndex = i
End Sub

DoEvents vs Application.Wait (Excel VBA)

' DoEvents - Yields immediately
DoEvents
' Application.Wait - Yields for specific duration
Application.Wait Now + TimeValue("00:00:01")

Limitations

← Back to Interaction | View all functions