'**************************************
' Name: CWizardEngine
' Description:Ever wanted to implement y
' our own wizard but thought that the logi
' c to manage all the different panels wou
' ld be too complex? Here's the code you'v
' e been looking for! This class implement
' s a wizard engine. You can use it to man
' age all the displaying of any number of
' panels for your own wizard. All you have
' to do is create the individual wizard pa
' nels. Assign the panels to the WizardEng
' ine along with the Previous, Next, Cance
' l and Finish buttons and you're done. Th
' e WizardEngine handles the rest!
' By: Matthew Janofsky
'
'
' Inputs:None
'
' Returns:None
'
'Assumes:Create a new class module and p
' aste the text into it. Name the class cW
' izardEngine.
'
'Side Effects:None
'
'Warranty:
'Code provided by Planet Source Code(tm)
' (http://www.Planet-Source-Code.com) 'as
' is', without warranties as to performanc
' e, fitness, merchantability,and any othe
' r warranty (whether expressed or implied
' ).
'Terms of Agreement:
'By using this source code, you agree to
' the following terms...
' 1) You may use this source code in per
' sonal projects and may compile it into a
' n .exe/.dll/.ocx and distribute it in bi
' nary format freely and with no charge.
' 2) You MAY NOT redistribute this sourc
' e code (for example to a web site) witho
' ut written permission from the original
' author.Failure to do so is a violation o
' f copyright laws.
' 3) You may link to this code from anot
' her website, provided it is not wrapped
' in a frame.
' 4) The author of this code may have re
' tained certain additional copyright righ
' ts.If so, this is indicated in the autho
' r's description.
'**************************************
Option Explicit
Option Compare Text
'-- This class encapsulates the logic fo
' r implementing a wizard.
' Copyright Matthew Janofsky 2000
'
' To use the Wizard Engine:
' Assign the panels in the order you wan
' t them displayed.
' Panels can be any control that exposes
' the Visible
'property and the Move method.
' Assign the Next, Previous, Cancel and
' Finish buttons.
' Make sure the first panel is in the po
' sition that
'the panels should be displayed.
'
' Example:
' Option Explicit
'
' Private WithEvents m_oWiz As cWizardEn
' gine
'
' Private Sub Form_Load()
'
' Set m_oWiz = New cWizardEngine
'
' '-- Add the panels in the order we wan
' t them displayed.
' m_oWiz.AddPanel Me.Frame1
' m_oWiz.AddPanel Me.Frame2
' m_oWiz.AddPanel Me.Frame3
'
' '-- Add the buttons.
' Set m_oWiz.CancelButton = Me.cmdCancel
'
' Set m_oWiz.FinishButton = Me.cmdFinish
'
' Set m_oWiz.NextButton = Me.cmdNext
' Set m_oWiz.PrevButton = Me.cmdPrev
'
' '-- Only allow the finish button on th
' e last panel.
' m_oWiz.FinishEnabledOnAllPanels = Fals
' e
'
' '-- Start the wizard.
' m_oWiz.StartWizard
'
' End Sub
'
' Use the cWizardEngine_BeforeNext() eve
' nt to validate
' the user's entry on the current panel
' when the
' Next button is clicked.
'
' Use the cWizardEngine_AfterNext() even
' t to do any
' pre-display logic when a new panel is
' displayed
' after the Next button is clicked.
'----------------------
' Property variables
'----------------------
Private m_lCurrentPanelNbr As Long
Private m_bFinishEnabledOnAllPanels As Boolean
Private m_aPanels() As Control 'Array of panels.
Private WithEvents m_cmdCancelButton As CommandButton
Private WithEvents m_cmdFinishButton As CommandButton
Private WithEvents m_cmdNextButton As CommandButton
Private WithEvents m_cmdPrevButton As CommandButton
'----------------------
' Class variables
'----------------------
Private m_lPanelCount As Long
'----------------------
' Raised Events
'----------------------
Public Event AfterNext(NewPanelNbr As Long)
Public Event BeforeNext(CurrentPanelNbr As Long, _
Cancel As Boolean)
'----------------------
' Methods
'----------------------
Public Sub AddPanel(PanelToAdd As Control)
On Error GoTo AddPanel_Error
'-- Add a panel to the list.
m_lPanelCount = m_lPanelCount + 1
ReDim Preserve m_aPanels(m_lPanelCount)
Set m_aPanels(m_lPanelCount) = PanelToAdd
'-- If this wasn't the first panel, adju
' st the panel _
' dimensions and position to match the f
' irst panel.
If m_lPanelCount > 1 Then
With m_aPanels(1)
m_aPanels(m_lPanelCount).Move .Left, .Top, _
.Width, .Height
End With
End If
'-- Exit the procedure.
GoTo AddPanel_Exit
AddPanel_Error:
Select Case Err
'-- Add specific error cases here
'Case ...
Case Else:
Err.Raise Err.Number, "cWizardEngine::AddPanel()", _
Err.Description, Err.HelpFile, Err.HelpContext
End Select
Resume AddPanel_Exit
Resume 'For debugging purposes
AddPanel_Exit:
End Sub
Public Sub StartWizard()
On Error GoTo StartWizard_Error
Dim X As Long
'-- Set the command button properties.
m_cmdCancelButton.Enabled = True
If m_bFinishEnabledOnAllPanels = True Then
m_cmdFinishButton.Enabled = True
Else
m_cmdFinishButton.Enabled = False
End If
m_cmdNextButton.Enabled = True
m_cmdPrevButton.Enabled = False
'-- Set the panel properties. Display th
' e first panel.
m_aPanels(1).Visible = True
For X = 2 To m_lPanelCount
m_aPanels(X).Visible = False
Next
'-- Set the current panel.
m_lCurrentPanelNbr = 1
'-- Exit the procedure.
GoTo StartWizard_Exit
StartWizard_Error:
Select Case Err
'-- Add specific error cases here
'Case ...
Case Else:
Err.Raise Err.Number, _
"cWizardEngine::StartWizard()", _
Err.Description, Err.HelpFile, _
Err.HelpContext
End Select
Resume StartWizard_Exit
Resume 'For debugging purposes
StartWizard_Exit:
End Sub
'-----------------------
' Properties
'-----------------------
Public Property Set CancelButton(RHS As CommandButton)
Set m_cmdCancelButton = RHS
End Property
Public Property Get CurrentPanelNbr() As Long
'-- Return the current panel number.
CurrentPanelNbr = m_lCurrentPanelNbr
End Property
Public Property Set FinishButton(RHS As CommandButton)
Set m_cmdFinishButton = RHS
End Property
Public Property Get FinishEnabledOnAllPanels() As Boolean
FinishEnabledOnAllPanels = m_bFinishEnabledOnAllPanels
End Property
Public Property Let FinishEnabledOnAllPanels(RHS As Boolean)
m_bFinishEnabledOnAllPanels = RHS
End Property
Public Property Set NextButton(RHS As CommandButton)
Set m_cmdNextButton = RHS
End Property
Public Property Set PrevButton(RHS As CommandButton)
Set m_cmdPrevButton = RHS
End Property
'-------------------------
' Class Methods
'-------------------------
Private Sub Class_Initialize()
On Error Resume Next
m_bFinishEnabledOnAllPanels = False
m_lPanelCount = 0
m_lCurrentPanelNbr = 0
End Sub
Private Sub Class_Terminate()
On Error Resume Next
Dim X As Long
Set m_cmdCancelButton = Nothing
Set m_cmdFinishButton = Nothing
Set m_cmdNextButton = Nothing
Set m_cmdPrevButton = Nothing
For X = 1 To m_lPanelCount
Set m_aPanels(X) = Nothing
Next
End Sub
'-------------------------
' Event handlers
'-------------------------
Private Sub m_cmdCancelButton_Click()
'-- Do nothing. It is up to the caller t
' o handle it.
End Sub
Private Sub m_cmdFinishButton_Click()
'-- Do nothing. It is up to the caller t
' o handle it.
End Sub
Private Sub m_cmdNextButton_Click()
'-- Display the next panel.
On Error GoTo m_cmdNextButton_Click_Error
Dim bCancel As Boolean
'-- Give the caller a chance to cancel t
' his event.
RaiseEvent BeforeNext(m_lCurrentPanelNbr, bCancel)
If bCancel = True Then
GoTo m_cmdNextButton_Click_Exit
End If
m_aPanels(m_lCurrentPanelNbr + 1).Visible = True
'-- Hide the current panel.
m_aPanels(m_lCurrentPanelNbr).Visible = False
'-- Increment the current panel.
m_lCurrentPanelNbr = m_lCurrentPanelNbr + 1
'-- Enable the Prev button.
m_cmdPrevButton.Enabled = True
'-- If we are now on the last panel, ena
' ble the finish
' button if it is not already enabled an
' d disable
' the Next button.
If m_lCurrentPanelNbr = m_lPanelCount Then
m_cmdFinishButton.Enabled = True
m_cmdNextButton.Enabled = False
End If
'-- Let the caller know we are finished.
'
RaiseEvent AfterNext(m_lCurrentPanelNbr)
'-- Exit the procedure.
GoTo m_cmdNextButton_Click_Exit
m_cmdNextButton_Click_Error:
Select Case Err
'-- Add specific error cases here
'Case ...
Case Else:
Err.Raise Err.Number, _
"cWizardEngine::m_cmdNextButton_Click()", _
Err.Description, Err.HelpFile, _
Err.HelpContext
End Select
Resume m_cmdNextButton_Click_Exit
Resume 'For debugging purposes
m_cmdNextButton_Click_Exit:
End Sub
Private Sub m_cmdPrevButton_Click()
'-- Display the previous panel.
On Error GoTo m_cmdPrevButton_Click_Error
m_aPanels(m_lCurrentPanelNbr - 1).Visible = True
'-- Hide the current panel.
m_aPanels(m_lCurrentPanelNbr).Visible = False
'-- Decrement the current Panel.
m_lCurrentPanelNbr = m_lCurrentPanelNbr - 1
'-- Enable the Next Button.
m_cmdNextButton.Enabled = True
'-- We are not on the last panel, so dis
' able the
' Finish button.
If m_bFinishEnabledOnAllPanels = False Then
m_cmdFinishButton.Enabled = False
End If
'-- If we are on the first panel, disabl
' e the Prev button.
If m_lCurrentPanelNbr = 1 Then
m_cmdPrevButton.Enabled = False
End If
'-- Exit the procedure.
GoTo m_cmdPrevButton_Click_Exit
m_cmdPrevButton_Click_Error:
Select Case Err
'-- Add specific error cases here
'Case ...
Case Else:
Err.Raise Err.Number, _
"cWizardEngine::m_cmdPrevButton_Click()", _
Err.Description, Err.HelpFile, _
Err.HelpContext
End Select
Resume m_cmdPrevButton_Click_Exit
Resume 'For debugging purposes
m_cmdPrevButton_Click_Exit:
End Sub