Thursday, October 27, 2022

Notes About PowerShell: A More Complex GUI

Building on the simplest GUI (see here); also for more info, see The Lazy Admin), we can modify the parent window's size, title, and background color, with the following script:

# Initialize the PowerShell GUI
Add-Type -AssemblyName System.Windows.Forms
  
# Create a new window form
$ParentWindow = New-Object System.Windows.Forms.Form

# Define the size, title, and background color
$ParentWindow.ClientSize = '500,300'
$ParentWindow.text = "My Parent Window"
$ParentWindow.BackColor = "#ffffff"
  
# Display the form
$ParentWindow.ShowDialog()

Now let's add an "OK" button:

# Initialize the PowerShell GUI
Add-Type -AssemblyName System.Windows.Forms
  
# Create a new window form
$ParentWindow = New-Object System.Windows.Forms.Form

# Define the size, title, and background color
$ParentWindow.ClientSize = '500,300'
$ParentWindow.text = "My Parent Window"
$ParentWindow.BackColor = "#ffffff"
  
# The OK button.
$buttonOK = New-Object 'System.Windows.Forms.Button'
$ParentWindow.Controls.Add($buttonOK)

# Display the form
$ParentWindow.ShowDialog()

When you run this script, you should see a rectangle inside the main window. It doesn't have a label, is in the wrong spot, and doesn't do anything. Let's make some changes. Also, "$ParentWindow" is a lot of typing. We could shorten it by two letters to "$MainWindow", but we don't have any daughter- or subordinate windows, so we could just call it "$Window", but let's save even more typing:

# Initialize the PowerShell GUI.
Add-Type -AssemblyName System.Windows.Forms

# Create a new window form.
$Win = New-Object System.Windows.Forms.Form
# Define the size, title, and background color.
$Win.ClientSize = '500,300'
$Win.text = "My Parent Window"
$Win.BackColor = "#ffffff"

# The OK button.
$Okee-Dokee = New-Object 'System.Windows.Forms.Button'    # Create the button.
$Okee-Dokee.Text = "Okely-dokely, good neighbor!"         # Puts text on the button.
$Okee-Dokee.Location = '400, 240'                         # 100 pixels from the 500 edge.
$Win.Controls.Add($Okee-Dokee)                            # Add the button to the form.
# Display the form
$Win.ShowDialog() 

Better, but still not quite there. Let's add a size spec (and rename the button control back to something more meaningful):

   ...
# The OK button.
$buttonOK = New-Object 'System.Windows.Forms.Button'      # Create the button.
$buttonOK.Text = "Okely-dokely, good neighbor!"           # Puts text on the button.
$buttonOK.Location = '400, 240'                           # 100 pixels from the 500 edge.
$buttonOK.Size = '175, 23'
$Win.Controls.Add($buttonOK)                              # Add the button to the form.
   ...

And now move the button:

   ...
# The OK button.
$buttonOK = New-Object 'System.Windows.Forms.Button       # Create the button.
$buttonOK.Text = "Okely-dokely, good neighbor!"           # Puts text on the button.
$buttonOK.Location = '300, 240'                           # 200 pixels from the 500 edge.
$buttonOK.Size = '175, 23'
$Win.Controls.Add($buttonOK)                              # Add the button to the form.
   ...

Note that it doesn't matter what order these elements are defined, as long as they are defined before the "Add".

Now let's have the button do something. We'll have it close the window, and print the message "OK" to the console. (Allowable results are "None, OK, Cancel, Abort, Retry, Ignore, Yes, No".) We'll also set the button to be the "I accept the window as it is, so close it" button.

# Initialize the PowerShell GUI
Add-Type -AssemblyName System.Windows.Forms

# Create a new window form
$Win = New-Object System.Windows.Forms.Form
# Define the size, title and background color
$Win.ClientSize = '500,300'
$Win.text = "My Parent Window"
$Win.BackColor = "#ffffff"

# The OK button.
$buttonOK = New-Object 'System.Windows.Forms.Button'
$buttonOK.Anchor = 'Bottom, Right'
$buttonOK.text = "Okeley-dokely, good neighbor!"
$buttonOK.Size = '175, 23'
$buttonOK.Location = '300, 240'
$buttonOK.DialogResult = "OK"
$Win.Controls.Add($buttonOK)
$Win.AcceptButton = $buttonOK

# Display the form
$Win.ShowDialog()

Write-Host("The button was pressed, returning the response: $($Win.DialogResult)")

Now let's put a text box on the form, pre-fill it with some text, pre-select that text, and then return whatever text is in the text box when the OK button is pressed. Let's also put a label atop the text. The changes to the script are bolded below.

# Initialize the PowerShell GUI
Add-Type -AssemblyName System.Windows.Forms
  
# Create a new window form
$Win = New-Object System.Windows.Forms.Form
# Define the size, title and background color
$Win.ClientSize = '500,300'
$Win.text = "My Parent Window"
$Win.BackColor = "#ffffff"
  
# The OK button.
$buttonOK = New-Object 'System.Windows.Forms.Button'
$buttonOK.Anchor = 'Bottom, Right'
$buttonOK.text = "Okeley-dokely, good neighbor!"
$buttonOK.Size = '175, 23'
$buttonOK.Location = '300, 240'
$buttonOK.DialogResult = "OK"
$Win.Controls.Add($buttonOK)
$Win.AcceptButton = $buttonOK
  
# The Name textbox.
$NameBox = New-Object "System.Windows.Forms.Textbox"
$NameBox.Size = "175,23"
$NameBox.Location = "10,40"
$NameBox.Text = "Babushka"
$Win.Controls.Add($NameBox)
$Win.ActiveControl = $NameBox
# And its label.
$Label_NameBox = New-Object 'System.Windows.Forms.Label'
$Label_NameBox.Text = "Enter your name:"
$Label_NameBox.Size = "175,23"
$Label_NameBox.Location = '10,20'
$Win.Controls.Add($Label_NameBox)

# Display the form
$Win.ShowDialog()
  
Write-Host("The button was pressed, returning the word: $($Win.DialogResult)")

# The computer is now looping forever waiting for user input.
# Once the input is the OK button or the Window's X (or
# keyboard equivalent), the window closes and the code below runs.
If ($Win.DialogResult -eq "OK")
  {
    Write-Host("The OK button was pressed. The name in the box is `"$($NameBox.Text)`".")
  }
elseif ($Win.DialogResult -eq "Cancel")
  {
    Write-Host("The X was pressed. I`'m not going to tell you the name that is in the box.")
  } # end of If

If you wanted to pre-select just a portion of the default text of the text box:

   ...
$NameBox.Text = "Babushka"
$NameBox.SelectionStart = 4
$NameBox.SelectionLength = 3
$Win.Controls.Add($NameBox)
   ...

No comments: