PoshCode Archive  Artifact [438b52d830]

Artifact 438b52d830fb6c5bb90c2d119641a649a3ea3ba445fb3fa0cb8872b25b5fdeda:

  • File Wizard-template.ps1 — part of check-in [7ac65ae6e0] at 2018-06-10 13:14:35 on branch trunk — This is a template intended for creating a wizard with PowerShell code from scratch. The sample consists of two sections, the template itself and the wxample of its use. (user: Alexander Petrovskiy size: 24704)

# encoding: utf-8
# api: powershell
# title: Wizard template
# description: This is a template intended for creating a wizard with PowerShell code from scratch. The sample consists of two sections, the template itself and the wxample of its use.
# version: 1.5
# type: script
# author: Alexander Petrovskiy                                                                              
# license: CC0
# function: Enable-FinishButton
# x-poshcode-id: 2699
# x-archived: 2017-04-30T09:37:28
# x-published: 2012-05-27T15:52:00
#
# The 562th line (’# Step 1: Welcome’) is now a border. All the above is the template, the remainder is how to use the template. Good luck, guys!
#
#######################################################################################################################
# File:             wizard_template.ps1						                                                          #
# Author:           Alexander Petrovskiy                                                                              #
# Publisher:        Alexander Petrovskiy, PowerShellDevTools.WordPress.Com                                            #
# Copyright:        © 2010-2011 Alexander Petrovskiy, PowerShellDevTools.WordPress.Com. All rights reserved.          #
# Usage:            To run this example no preparations needed.														  #
#					There also are the following settings you may be intersted in:									  #
#                   1. the wizard caption	                                                                          #
#                   2. default size of the wizard						                                              #
#                   3. default size of the wizard's buttons             				                              #
#                   4. button labels                                        										  #
#                   5. right-to-left layout     	    												              #
#                   All the settings mentioned are placed inside the 'adjustable settings' region                     #
#                   Please provide feedback in the PowerShellDevTools.WordPress.Com blog.                             #
#######################################################################################################################
cls
Set-StrictMode -Version 2
#region host preparations
if ($Host.Name -eq 'ConsoleHost')
{
	Add-Type -AssemblyName System.Windows.Forms;
	Add-Type -AssemblyName System.Drawing;
}
#endregion host preparations
#region the resulting wizard
	#region adjustable settings
		#region controls settings
		# Form size and caption
		[string]$script:constWizardInitialCaption = `
			'This is a sample wizard';
		[int]$script:constWizardWidth = `
			[System.Windows.Forms.SystemInformation]::VirtualScreen.Width / 2;
		[int]$script:constWizardHeight = `
			[System.Windows.Forms.SystemInformation]::VirtualScreen.Height / 2;
		# Buttons Next, Back, Cancel, Finish
		[int]$script:constButtonHeight = 23;
		[int]$script:constButtonWidth = 75;
		[int]$script:constButtonAreaHeight = `
			$script:constButtonHeight * 2;
		[string]$script:constButtonNextName = '&Next';
		[string]$script:constButtonBackName = '&Back';
		[string]$script:constButtonFinishName = '&Finish';
		[string]$script:constButtonCancelName = '&Cancel';
		# Step display name and description
		[int]$script:constLabelStepDisplayNameLeft = 5;
		[int]$script:constLabelStepDisplayNameTop = 0;
		[float]$script:constLabelStepDisplayNameFontSize = 16;
		[int]$script:constLabelStepDescriptionLeft = 5;
		[int]$script:constLabelStepDescriptionTop = 30;
		# Form properties
		[bool]$script:constWizardRigthToLeft = $false;
		# Initial step number
		[int]$script:currentStep = 0;
		#endregion controls settings
	#endregion adjustable settings
	#region mandatory settings
		#region Initialization of the SplitContainer controls
		# The outer split container
		[System.Windows.Forms.SplitContainer]$script:splitOuter = `
			New-Object System.Windows.Forms.SplitContainer;
			$script:splitOuter.Dock = [System.Windows.Forms.DockStyle]::Fill;
			$script:splitOuter.IsSplitterFixed = $true;
			$script:splitOuter.Orientation = `
				[System.Windows.Forms.Orientation]::Horizontal;
			$script:splitOuter.SplitterWidth = 5;
		# The inner split container
		[System.Windows.Forms.SplitContainer]$script:splitInner = `
			New-Object System.Windows.Forms.SplitContainer;
			$script:splitInner.Dock = [System.Windows.Forms.DockStyle]::Fill;
			$script:splitInner.IsSplitterFixed = $true;
			$script:splitInner.Orientation = `
				[System.Windows.Forms.Orientation]::Horizontal;
			$script:splitInner.SplitterWidth = 5;
			$script:splitOuter.Panel1.Controls.Add($script:splitInner);
		# The labels for the curent step name and description
		[System.Windows.Forms.Label]$script:lblStepDisplayName = `
			New-Object System.Windows.Forms.Label;
			$script:lblStepDisplayName.Left = `
				$script:constLabelStepDisplayNameLeft;
			$script:lblStepDisplayName.Top = `
				$script:constLabelStepDisplayNameTop;
			[System.Drawing.Font]$private:font = `
				$script:lblStepDisplayName.Font;
			$private:font = `
				New-Object System.Drawing.Font($private:font.Name, `
						$script:constLabelStepDisplayNameFontsize, `
			            $private:font.Style, $private:font.Unit, `
			            $private:font.GdiCharSet, $private:font.GdiVerticalFont );
			$script:lblStepDisplayName.Font = $private:font;
		[System.Windows.Forms.Label]$script:lblStepDescription = `
			New-Object System.Windows.Forms.Label;
			$script:lblStepDescription.Left = `
				$script:constLabelStepDescriptionLeft;
			$script:lblStepDescription.Top = `
				$script:constLabelStepDescriptionTop;
		$script:splitInner.Panel1.Controls.AddRange(($script:lblStepDisplayName, `
			$script:lblStepDescription));
		#endregion Initialization of the SplitContainer controls
		#region buttons functions
		function Enable-FinishButton
		{
			$script:btnNext.Enabled = $false;
			$script:btnNext.Visible = $false;
			$script:btnFinish.Enabled = $true;
			$script:btnFinish.Visible = $true;
		}
		function Enable-NextButton
		{
			$script:btnNext.Enabled = $true;
			$script:btnNext.Visible = $true;
			$script:btnFinish.Enabled = $false;
			$script:btnFinish.Visible = $false;
		}
		function Enable-BackButton
		{
			$script:btnBack.Enabled = $true;
			$script:btnBack.Visible = $true;
			$script:btnCancel.Enabled = $false;
			$script:btnCancel.Visible = $false;
		}
		function Enable-CancelButton
		{
			$script:btnBack.Enabled = $false;
			$script:btnBack.Visible = $false;
			$script:btnCancel.Enabled = $true;
			$script:btnCancel.Visible = $true;
		}
		#endregion buttons functions
		#region the Next and Back buttons
		[System.Windows.Forms.Button]$script:btnNext = `
			New-Object System.Windows.Forms.Button;
		$script:btnNext.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor `
			[System.Windows.Forms.AnchorStyles]::Right -bor `
			[System.Windows.Forms.AnchorStyles]::Top;
		$script:btnNext.Text = $script:constButtonNextName;
		[System.Windows.Forms.Button]$script:btnBack = `
			New-Object System.Windows.Forms.Button;
		$script:btnBack.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor `
			[System.Windows.Forms.AnchorStyles]::Right -bor `
			[System.Windows.Forms.AnchorStyles]::Top;
		$script:btnBack.Text = $script:constButtonBackName;
		$script:splitOuter.Panel2.Controls.AddRange(($script:btnBack, $script:btnNext));
		#endregion the Next and Back buttons
		#region the Finish and the Cancel buttons
		[System.Windows.Forms.Button]$script:btnFinish = `
			New-Object System.Windows.Forms.Button;
		$script:btnFinish.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor `
			[System.Windows.Forms.AnchorStyles]::Right -bor `
			[System.Windows.Forms.AnchorStyles]::Top;
		$script:btnFinish.Text = $script:constButtonFinishName;
		[System.Windows.Forms.Button]$script:btnCancel = `
			New-Object System.Windows.Forms.Button;
		$script:btnCancel.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor `
			[System.Windows.Forms.AnchorStyles]::Right -bor `
			[System.Windows.Forms.AnchorStyles]::Top;
		$script:btnCancel.Text = $script:constButtonCancelName;
		Enable-CancelButton;
		Enable-NextButton;
		$script:splitOuter.Panel2.Controls.AddRange(($script:btnCancel, $script:btnFinish));
		#endregion the Finish and the Cancel buttons
		#region Initialization of the main form
		$script:frmWizard = $null;
		[System.Windows.Forms.Form]$script:frmWizard = `
			New-Object System.Windows.Forms.Form;
		$script:frmWizard.Controls.Add($script:splitOuter);
		# left-to-right and right-to-left
		if ($script:constWizardRigthToLeft)
		{
			$script:frmWizard.RightToLeft = `
				[System.Windows.Forms.RightToLeft]::Yes;
			$script:frmWizard.RightToLeftLayout = $true;
		}
		else
		{
			$script:frmWizard.RightToLeft = `
				[System.Windows.Forms.RightToLeft]::No;
			$script:frmWizard.RightToLeftLayout = $false;
		}
		$script:frmWizard.Text = $script:constWizardInitialCaption;
		#endregion Initialization of the main form
	#endregion mandatory settings
	#region the Wizard steps
	[System.Collections.ArrayList]$script:wzdSteps = `
		New-Object System.Collections.ArrayList;
		# Here we create an 'enumeration' (PSObject) 
		# and begin filling ArrayList $script:wzdSteps with Panel controls
		[System.EventHandler]$script:hndlRunControlsAdd = `
			{try{$script:splitInner.Panel2.Controls.Add($script:wzdSteps[$script:currentStep]);}
			catch{Write-Debug $Error[0]; Write-Debug $global:Error[0];}};
		#region function New-WizardStep
		function New-WizardStep
		{
			param(
				  [string]$StepName,
				  [string]$StepDisplayName,
				  [string]$StepDescription = ''
				  )
			# Storing parameters in step arrays
			Add-Member -InputObject $script:steps -MemberType NoteProperty `
				-Name $StepName -Value $script:wzdSteps.Count;
			$null = $script:stepDisplayNames.Add($StepDisplayName);
			$null = $script:stepDescriptions.Add($StepDescription);
			# Adding a fake scriptblock to keep counters
			$null = $script:stepscriptblocks.Add({});
			# Create and add the new step's panel to the array
			[System.Windows.Forms.Panel]$private:panel = `
				New-Object System.Windows.Forms.Panel;
			$null = $script:wzdSteps.Add($private:panel);
			$script:currentStep = $script:wzdSteps.Count - 1;

			$script:splitInner.Panel2.Controls.Add($script:wzdSteps[$script:currentStep]);

			$script:wzdSteps[$script:currentStep].Dock = `
				[System.Windows.Forms.DockStyle]::Fill;
			# To restore initial state for this code running before the user accesses the wizard.
			$script:currentStep = 0;
		}
		#endregion function New-WizardStep
		#region function Add-ControlToStep
		function Add-ControlToStep
		# Adds a control of selected type to a wizard step
		{
			param(
				  [Parameter(Mandatory=$true)]
				  [string]$StepNumber,
				  [Parameter(Mandatory=$true)]
				  [string]$ControlType,
				  [Parameter(Mandatory=$true)]
				  [string]$ControlName,
				  [int]$ControlTop,
				  [int]$ControlLeft,
				  [int]$ControlHeight,
				  [int]$ControlWidth,
				  [string]$ControlData
				 )
			$private:ctrl = $null;
			try{
				$private:ctrl = New-Object $ControlType;
			}catch{Write-Error "Unable to create a control of $($ControlType) type";}
			try{
				$private:ctrl.Name = $ControlName;
			}catch{Write-Error "Unable to set the Name property with value $($ControlName) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Top = $ControlTop;
			}catch{Write-Error "Unable to set the Top property with value $($ControlTop) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Left = $ControlLeft;
			}catch{Write-Error "Unable to set the Left property with value $($ControlLeft) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Height = $ControlHeight;
			}catch{Write-Error "Unable to set the Height property with value $($ControlHeight) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Width = $ControlWidth;
			}catch{Write-Error "Unable to set the Width property with value $($ControlWidth) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Text = $ControlData;
			}catch{Write-Error "Unable to set the Text property with value $($ControlData) to a control of the $($ControlType) type";}
			try{
				$wzdSteps[$StepNumber].Controls.Add($private:ctrl);
			}catch{Write-Error "Unable to add a control of $($ControlType) type to the step $($StepNumber)";}
		}
		#endregion function Add-ControlToStep
		#region function Add-CodeToStep
		function Add-CodeToStep
		# Adds a scriptblock to a wizard step
		{
			param(
				  [Parameter(Mandatory=$true)]
				  [string]$StepNumber,
				  [Parameter(Mandatory=$true)]
				  [scriptblock]$StepCode
				 )
			$script:stepScriptblocks[$StepNumber] = $StepCode;
		}
		#endregion function Add-CodeToStep
		#region Step data arrays
		[psobject]$script:steps = New-Object psobject;
		[System.Collections.ArrayList]$script:stepDisplayNames = `
			New-Object System.Collections.ArrayList;
		[System.Collections.ArrayList]$script:stepDescriptions = `
			New-Object System.Collections.ArrayList;
		[System.Collections.ArrayList]$script:stepScriptblocks = `
			New-Object System.Collections.ArrayList;
		#endregion Step data arrays
	#endregion the Wizard steps
	#region events of the wizard controls
		#region resizing
			#region button sizes
	function Set-NextButtonLeft
	{
		param([int]$Left)
		$script:btnNext.Left = $Left;
		$script:btnFinish.Left = $Left;
	}
	function Set-NextButtonTop
	{
		param([int]$Top)
		$script:btnNext.Top = $Top;
		$script:btnFinish.Top = $Top;
	}
	function Set-BackButtonLeft
	{
		param([int]$Left)
		$script:btnBack.Left = $Left;
		$script:btnCancel.Left = $Left;
	}
	function Set-BackButtonTop
	{
		param([int]$Top)
		$script:btnBack.Top = $Top;
		$script:btnCancel.Top = $Top;
	}
			#endregion button sizes
			#region function Initialize-WizardControls
	function Initialize-WizardControls
	<#
		.SYNOPSIS
			The Initialize-WizardControls function sets the wizard common controls to predefined positions.
	
		.DESCRIPTION
			The Initialize-WizardControls function does the following:
			- sets Top, Left, Width and Height properties of the wizard buttons
			- positions of the step labels
			- sets the SplitterDistance property of both Splitcontainer controls
	
		.EXAMPLE
			PS C:\> Initialize-WizardControls
			This example shows how to step the wizard forward.
	
		.INPUTS
			No input
	
		.OUTPUTS
			No output
	#>
	{
		# Set sizes of buttons
		$script:btnNext.Height = $script:constButtonHeight;
		$script:btnNext.Width = $script:constButtonWidth;
		$script:btnBack.Height = $script:constButtonHeight;
		$script:btnBack.Width = $script:constButtonWidth;
		$script:btnFinish.Height = $script:btnNext.Height;
		$script:btnFinish.Width = $script:btnNext.Width;
		$script:btnCancel.Height = $script:btnBack.Height;
		$script:btnCancel.Width = $script:btnBack.Width;
		# SplitterDistance of the outer split container
		# in other words, the area where Next and Back buttons are placed
		$script:splitOuter.SplitterDistance = `
			$script:splitOuter.Height - `
			$script:constButtonAreaHeight;
		
		# Placements of the buttons
		if ($script:constWizardRigthToLeft)
		{
			Set-NextButtonLeft 10;
			Set-BackButtonLeft ($script:constButtonWidth + 20);
		}
		else
		{
			Set-NextButtonLeft ($script:splitOuter.Width - `
				$script:constButtonWidth - 10);
			Set-BackButtonLeft ($script:splitOuter.Width - `
				$script:constButtonWidth - `
				$script:constButtonWidth - 20);
		}
		Set-NextButtonTop (($script:constButtonAreaHeight - $script:constButtonHeight) / 2);
		Set-BackButtonTop (($script:constButtonAreaHeight - $script:constButtonHeight) / 2);
		
		# SplitterDistance of the inner split container
		# this is the place where step name is placed
		$script:splitInner.SplitterDistance = `
			$script:constButtonAreaHeight * 1.5;
		
		# Step Display Name and Description labels
		$script:lblStepDisplayName.Width = `
			$script:splitInner.Panel1.Width - `
			$script:constLabelStepDisplayNameLeft * 2;
		$script:lblStepDescription.Width = `
			$script:splitInner.Panel1.Width - `
			$script:constLabelStepDescriptionLeft * 2;
			
		# Refresh after we have changed placements of the controls
		[System.Windows.Forms.Application]::DoEvents();
	}
			#endregion function Initialize-WizardControls
	[System.EventHandler]$script:hndlFormResize = {Initialize-WizardControls;}
	[System.EventHandler]$script:hndlFormLoad = {Initialize-WizardControls;}
	#[System.Windows.Forms.MouseEventHandler]$script:hndlSplitMouseMove = `
	#	{Initialize-WizardControls;}
	# Initial arrange on Load form.
	$script:frmWizard.add_Load($script:hndlFormLoad);
	#$script:frmWizard.add_Resize($script:hndlFormResize);
	$script:splitOuter.add_Resize($script:hndlFormResize);
		#endregion resizing
		#region steps
			#region function Invoke-WizardStep
	function Invoke-WizardStep
	<#
		.SYNOPSIS
			The Invoke-WizardStep function sets active panel on the wizard form.
	
		.DESCRIPTION
			The Invoke-WizardStep function does the following:
			- changes internal variable $script:currentStep
			- sets/resets .Enabled property of btnNext and btnBack
			- changes .Dock and .Left properties of every panel
	
		.PARAMETER  Forward
			The optional parameter Forward is used to point out the direction the wizard goes.
	
		.EXAMPLE
			PS C:\> Invoke-WizardStep -Forward $true
			This example shows how to step the wizard forward.
	
		.INPUTS
			System.Boolean
	
		.OUTPUTS
			No output
	#>
	{
		[CmdletBinding()]
		param(
			  [Parameter(Mandatory=$false)]
			  [bool]$Forward = $true
			  )
		Begin{}
		Process{
			# run the step code
			try{
				$script:stepScriptblocks[$script:currentStep].Invoke();
			} catch {return;} #Cancel step
			if ($Forward)
			{
				Enable-BackButton;
				if ($script:currentStep -lt ($script:wzdSteps.Count - 1))
				{$script:currentStep++;}
				if ($script:currentStep -lt ($script:wzdSteps.Count - 1))
				{
					# step forward but not the last step
					Enable-NextButton;
				}
				else
				{	
					# the last step
					Enable-FinishButton;
				}
			}
			else
			{
				# go backward
				Enable-NextButton;
				if ($script:currentStep -gt 0)
				{$script:currentStep--;}
				if ($script:currentStep -gt 0)
				{
					# step backward but not the first one
					Enable-BackButton;
				}
				else
				{
					# the first step
					Enable-CancelButton;
				}
			}		
			for($private:i = 0; $private:i -lt $script:wzdSteps.Count;
				$private:i++)
			{
				if ($private:i -ne $script:currentStep)
				{	
					$script:wzdSteps[$private:i].Dock = `
						[System.Windows.Forms.DockStyle]::None;
					$script:wzdSteps[$private:i].Left = 10000;
				}
				else
				{
					$script:wzdSteps[$private:i].Dock = `
						[System.Windows.Forms.DockStyle]::Fill;
					$script:wzdSteps[$private:i].Left = 0;
				}
			}
			$script:lblStepDisplayName.Text = `
				$script:stepDisplayNames[$script:currentStep];
			$script:lblStepDescription.Text = `
				$script:stepDescriptions[$script:currentStep];
		}
		End{}
	}
			#endregion function Invoke-WizardStep
			#region function Initialize-WizardStep
	function Initialize-WizardStep
	# This is the selfsufficient function doing all the necessary
	# calculations for controls on each panel.
	# Also from the code can be seen how to address the panel you are interesting in
	# using the 'enumeration' created earlier
	# for example, $script:wzdSteps[$script:steps.Welcome]
	{
		$script:lblStepDisplayName.Text = `
			$script:stepDisplayNames[$script:currentStep];
		$script:lblStepDescription.Text = `
			$script:stepDescriptions[$script:currentStep];
	}
			#endregion function Initialize-WizardStep
			#region $hndlStepForward
	[System.EventHandler]$hndlStepForward = {
		# serve controls' data
		Initialize-WizardStep;
		# switch panels
		Invoke-WizardStep $true;
	}
			#endregion $hndlStepForward
			#region $hndlStepBack
	[System.EventHandler]$hndlStepBack = {
		# switch panels
		Invoke-WizardStep $false;
	}
			#endregion $hndlStepBack
			#region $hndlFinish
	[System.EventHandler]$hndlFinish = {
		# ask for exit
		[System.Windows.Forms.DialogResult]$private:res = `
			[System.Windows.Forms.MessageBox]::Show("Are you sure?", `
					"Question on exit", `
					[System.Windows.Forms.MessageBoxButtons]::YesNo);
		if ($res -eq [System.Windows.Forms.DialogResult]::Yes){
			# close the wizard
			$frmWizard.Close();
		}
	}
			#endregion $hndlFinish
			#region $hndlCancel
	[System.EventHandler]$hndlCancel = {
		# close the wizard
		$frmWizard.Close();
	}
			#endregion $hndlCancel
			#region wizard buttons' clicks
	$script:btnNext.add_Click($script:hndlStepForward);
	$script:btnBack.add_Click($script:hndlStepBack);
	$script:btnFinish.add_Click($script:hndlFinish);
	$script:btnCancel.add_Click($script:hndlCancel);
			#endregion wizard buttons' clicks
		#endregion steps
	#endregion events of the wizard controls
	#region wizard initialization
		#region function Initialize-Wizard
	function Initialize-Wizard
	# This is one more selfsufficient function written to make
	# the latest preparations for the form run
	{
		#region control settings
		$script:frmWizard.Width = $script:constWizardWidth;
		$script:frmWizard.Height = $script:constWizardHeight;
		#endregion control settings
		Initialize-WizardStep;
	}
		#endregion function Initialize-Wizard
	#endregion wizard initialization
#endregion the resulting wizard


		# Step 1: Welcome
		New-WizardStep 'Welcome' `
			'This is the first step' `
			'Welcome to the PowerShell Wizard, the our dear customer!';
		# Add a label
		# Please note that we can use the enumeration $steps which is being created runtime
		# on a call of the New-WizardStep function
		Add-ControlToStep $steps.Welcome `
			System.Windows.Forms.Label `
			'lblWelcome' 20 10 50 300 `
			'This Wizard carries you through the steps you need to collect the files from a given path';
		
		# Step 2
		New-WizardStep 'Input' `
			'Step Two' `
			'Here you type some in controls, plz';
		# Add a label
		Add-ControlToStep $steps.Input `
			System.Windows.Forms.Label `
			'lblInput' 20 10 20 300 `
			'Please type the path to a catalog';
		# Add a text box
		Add-ControlToStep $steps.Input `
			System.Windows.Forms.TextBox `
			'txtInput' 40 10 20 300
		# Add the code which requires that text box was not empty
		Add-CodeToStep $steps.Input `
			-StepCode {
					[string]$private:path = `
						$wzdSteps[$steps.Input].Controls['txtInput'].Text;
					if ($private:path.Length -eq 0)
					{
						# stop the step
						throw;
					}
					if (-not [System.IO.Directory]::Exists($private:path))
					{
						# stop the step
						throw;
					}
				}

		# Step 3
		New-WizardStep 'Progress' `
			'The third one' `
			'Wait, please. Sip a coffee' ;
		# Add a progress bar
		Add-ControlToStep $steps.Progress `
			'System.Windows.Forms.ProgressBar' `
			'pbDir' 200 50 100 400
		Add-CodeToStep $steps.Progress `
			-StepCode {
					# set progress bar maximum
					$wzdSteps[$steps.Progress].Controls['pbDir'].Minimum = 0;
					$wzdSteps[$steps.Progress].Controls['pbDir'].Value = 0;
					$wzdSteps[$steps.Progress].Controls['pbDir'].Maximum = `
						(Get-ChildItem $wzdSteps[$steps.Input].Controls['txtInput'].Text).Length;
					# clear the list box (from the next step)
					$wzdSteps[$steps.Output].Controls['lbxFiles'].Items.Clear();
					# add file names to the list box
					Get-ChildItem $wzdSteps[$steps.Input].Controls['txtInput'].Text | %{
							$wzdSteps[$steps.Progress].Controls['pbDir'].Value++;
							$wzdSteps[$steps.Output].Controls['lbxFiles'].Items.Add($_.Name);
						}
				}
		
		# Step 4
		New-WizardStep 'Output' 'Fourth' `
			'Now awake and read the output';
		# Add a list box
		Add-ControlToStep $steps.Output `
			System.Windows.Forms.ListBox `
			lbxFiles 50 50 300 400
        
		# Step 5: Finish
        New-WizardStep 'Finish' 'Finish!' 'Bye!';
				
		Initialize-Wizard;
		# Set the second step as active
		Invoke-WizardStep -Forward $true;
				
		$script:frmWizard.ShowDialog() | Out-Null;