Unload all forms currently in memoryOne of the fundamental weeknesses with many VB applications is the lack of explicit unloading of unload objects. When dealing with forms, many programmers unload every form in a project on it's termination, even if only a few of the forms are actually loaded. This will cause the forms that aren't loaded to be loaded then unloaded, which may create further complications. The following code demonstrates how to explicitly unload all the forms currently in memory and even unloads them in the correct order, which is neccessary if modal forms are present. Note, two versions of this code have been supplied, one for VBA programmers and one for VB programmers.
VBA ROUTINEOption Explicit
Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long'Purpose : This routine unloads all forms in memory for this project.
'Inputs : bFormsModal
' If True the application contains modal forms and
' hence form the topmost first
'Outputs : Returns True if all the forms where successfully unloaded.
Function FormsSafeUnload(Optional bFormsModal As Boolean = True) As Boolean
Dim lForm As Long, fForm As Object, lLoopCount As Long, lActiveWindow As Long
Dim sActiveCaption As String
On Error GoTo ErrFailed
If bFormsModal Then
'Unload all visible forms from topmost first.
'Note: cannot loop as uses the active window
lActiveWindow = GetActiveWindow
Do While lActiveWindow
sActiveCaption = DialogGetCaption(lActiveWindow)
For lForm = VBA.UserForms.Count - 1 To 0 Step -1
If VBA.UserForms(lForm).Caption = sActiveCaption Then
'Found topmost form, unload it
'(Can add break point on line below)
Unload VBA.UserForms(lForm)
End If
Next
lActiveWindow = GetActiveWindow
If VBA.UserForms.Count = 0 Then
Exit Do
ElseIf lForm = -1 Then
'Failed to find active form
'(Make sure you are not debugging this loop)
Exit Do
End If
Loop
End If
'Unload forms (including hidden forms)
For Each fForm In VBA.UserForms
Unload fForm
Next FormsSafeUnload = (VBA.UserForms.Count = 0)
Exit Function
ErrFailed:
FormsSafeUnload = False
End Function'Purpose : Returns the window caption of a specified window.
'Inputs : lHwnd The handle of the window to determine the caption of.
'Outputs : Returns the window caption of a specified window.
Function DialogGetCaption(lHwnd As Long) As String
Const clMaxLen As Long = 255
Dim lLen As Long, sValue As String * clMaxLen
lLen = GetWindowText(lHwnd, sValue, clMaxLen)
If lLen Then
DialogGetCaption = Left$(sValue, lLen)
End If
End Function
VB ROUTINEOption Explicit
Private Declare Function GetActiveWindow Lib "user32" () As Long'Purpose : This routine unloads all forms in memory for this project.
'Inputs : bFormsModal If True the application contains modal forms and
' hence form the topmost first
'Outputs : Returns True if all the forms where successfully unloaded.
Function FormsSafeUnload(Optional bFormsModal As Boolean = True) As Boolean
Dim lForm As Long, fForm As Form, lLoopCount As Long, lActiveWindow As Long
On Error GoTo ErrFailed
If bFormsModal Then
'Unload all visible forms from topmost first.
'Note: cannot loop as uses the active window
lActiveWindow = GetActiveWindow
Do While lActiveWindow
For lForm = VB.Forms.Count - 1 To 0 Step -1
If VB.Forms(lForm).hWnd = lActiveWindow Then
'Found topmost form, unload it
'(Can add break point on line below)
Unload VB.Forms(lForm)
End If
Next
lActiveWindow = GetActiveWindow
If VB.Forms.Count = 0 Then
Exit Do
ElseIf lForm = -1 Then
'Failed to find active form
'(Make sure you are not debugging this loop)
Exit Do
End If
Loop
End If
'Unload forms (including hidden forms)
For Each fForm In VB.Forms
Unload fForm
Next FormsSafeUnload = (VB.Forms.Count = 0)
Exit Function
ErrFailed:
FormsSafeUnload = False
End Function
crash less, worry less
