Blinking text in a form creating by PowerShell - winforms

I search the way to blink a text label in a windows.form.
This is a part of my script :
$Form = New-Object system.Windows.Forms.Form
$Form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$Form.ClientSize = '600,800'
$Form.text = "USMT - Sauvegarde des profils"
$Label1 = New-Object system.Windows.Forms.Label
$Label1.text = "1. Chemin vers scanstate.exe :"
$Label1.AutoSize = $true
$Label1.width = 25
$Label1.height = 10
$Label1.location = New-Object System.Drawing.Point(20,10)
$Label1.Font = 'Microsoft Sans Serif,10'
Here I search a solution to blink $Label1.text
Thanks for help !

Create a timer, add an event handler to its Tick event and toggle visibility of the label from there. Creating GUIs and reacting to events isn't particularly nice in PowerShell, but it can be done.

You can create a System.Windows.Forms.Timer object and set its Interval to a suitable value (milliseconds) and then by handling its Tick event, do whatever you need to blink the label, for example toggle visibility of the label. You need to start the timer when loading form:
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$label = New-Object System.Windows.Forms.Label
$label.Text = "This is my label."
$label.AutoSize = $true
$form.Controls.Add($label)
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 250
$timer.Add_Tick({$label.Visible = -not($label.Visible)})
$form.Add_Load({$timer.Start()})
$form.ShowDialog()
$timer.Dispose()
$form.Dispose()

Related

PowerShell and Windows Forms Tooltip custom colour

I'm trying to customise a simple tooltip with a black background (and black border if possible) and white text. I have the following code, but at the moment it's flakey, sometimes works, other times doesn't.
Can somebody please advise how to make this more reliable? Thanks.
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Windows.Forms.Application]::EnableVisualStyles()
Add-Type -AssemblyName System.Drawing
#create form
$form = New-Object System.Windows.Forms.Form
$shutdownBtn = New-Object System.Windows.Forms.Button
$shutdownBtn.Size = New-Object System.Drawing.Size(200, 40)
$shutdownBtn.Text = "Shut down"
$form.Controls.Add($shutdownBtn)
$tooltip2 = New-Object System.Windows.Forms.ToolTip
$tooltip2.SetToolTip($shutdownBtn, "Shut down.")
$tooltip2.OwnerDraw = $true
$tooltip2.Add_Draw($tooltip2_Draw)
$tooltip2_Draw=[System.Windows.Forms.DrawToolTipEventHandler]{
$fontstyle = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Normal)
$format = [System.Drawing.StringFormat]::GenericTypographic
$myBrush1 = new-object Drawing.SolidBrush White
$_.Graphics.DrawString($_.ToolTipText, $fontstyle, $myBrush1, $_.Bounds.X, $_.Bounds.Y, $format)
$myBrush2 = new-object Drawing.SolidBrush Black
$_.Graphics.FillRectangle($myBrush2, $_.Bounds)
$_.DrawBackground()
$_.DrawBorder()
$_.DrawText()
}
$form_cleanup =
{
$tooltip2.Remove_Draw($tooltip2_Draw)
$form.remove_FormClosed($form_cleanup)
}
$form.add_FormClosed($form_cleanup)
[void]$form.ShowDialog()
$form.Dispose()
I'll answer my own question:
There were a couple of glaring errors from a tired mind. Firstly:
$tooltip2.Add_Draw($tooltip2_Draw)
should have been called after I declared
$tooltip2_Draw
Secondly, I needed to call
FillRectangle
before i called
DrawString
And finally, since I set OwnerDraw = $true I didn't need to call:
$_.DrawBackground()
$_.DrawBorder()
$_.DrawText()
So here is the solution:
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Windows.Forms.Application]::EnableVisualStyles()
Add-Type -AssemblyName System.Drawing
#create form
$form = New-Object System.Windows.Forms.Form
$shutdownBtn = New-Object System.Windows.Forms.Button
$shutdownBtn.Size = New-Object System.Drawing.Size(200, 40)
$shutdownBtn.Text = "Shut down"
$form.Controls.Add($shutdownBtn)
$tooltip2 = New-Object System.Windows.Forms.ToolTip
$tooltip2.SetToolTip($shutdownBtn, "Shut down now.")
$tooltip2.OwnerDraw = $true
$tooltip2_Draw=[System.Windows.Forms.DrawToolTipEventHandler]{
$fontstyle = new-object System.Drawing.Font('Microsoft Sans Serif', 16, [System.Drawing.FontStyle]::Regular)
$format = [System.Drawing.StringFormat]::GenericTypographic
$format.LineAlignment = [System.Drawing.StringAlignment]::Center;
$format.Alignment = [System.Drawing.StringAlignment]::Center;
$whiteBrush = new-object Drawing.SolidBrush White
$blackBrush = new-object Drawing.SolidBrush Black
$_.Graphics.FillRectangle($blackBrush, $_.Bounds)
$_.Graphics.DrawString($_.ToolTipText, $fontstyle, $whiteBrush, ($_.Bounds.X + ($_.Bounds.Width/2)), ($_.Bounds.Y + ($_.Bounds.Height/2)), $format)
}
$tooltip2.Add_Draw($tooltip2_Draw)
$form_cleanup =
{
$tooltip2.Remove_Draw($tooltip2_Draw)
$form.remove_FormClosed($form_cleanup)
}
$form.add_FormClosed($form_cleanup)
[void]$form.ShowDialog()
$form.Dispose()

Populate listbox from a selected.item in another listbox

Good day to you all!
I have a Powershell program that I am making for my company. I have 2 listbox, one with the make of printers and the other will be for the models of printers. I was hoping for help to populate the 'model' list with what the user selects in the 'make' list. I understand doing a selecteditem could work, but whatever I do, it doesn't populate the 'model' list.
This is my first time programming and am self-taught. Right now, I am using Windows.Forms to make the GUI.
Any help is appreciated. Thank you so much for this wonderful community of like-minded awesomeness!
*Code:
Add-Type -AssemblyName System.Windows.Forms
$Form_Service = New-Object system.Windows.Forms.Form
$Form_Service.ClientSize = '452,400'
$Form_Service.text = "Service Call"
$Form_Service.TopMost = $true
$Form_Service.StartPosition = 'CenterScreen'
$Label_ValleyID = New-Object system.Windows.Forms.Label
$Label_ValleyID.text = "Enter Valley ID"
$Label_ValleyID.AutoSize = $true
$Label_ValleyID.width= 25
$Label_ValleyID.height = 10
$Label_ValleyID.location = New-Object System.Drawing.Point(45,41)
$Label_ValleyID.Font = 'Microsoft Sans Serif,10'
$TextBox_ValleyID= New-Object system.Windows.Forms.TextBox
$TextBox_ValleyID.multiline= $false
$TextBox_ValleyID.width= 180
$TextBox_ValleyID.height = 20
$TextBox_ValleyID.location = New-Object System.Drawing.Point(45,62)
$TextBox_ValleyID.Font = 'Microsoft Sans Serif,10'
$Label_Make= New-Object system.Windows.Forms.Label
$Label_Make.text = "Make"
$Label_Make.AutoSize = $true
$Label_Make.width= 25
$Label_Make.height = 10
$Label_Make.location = New-Object System.Drawing.Point(45,108)
$Label_Make.Font = 'Microsoft Sans Serif,10'
$ListBox_Make= New-Object system.Windows.Forms.ListBox
$ListBox_Make.text = "Make"
$ListBox_Make.width= 144
$ListBox_Make.height = 50
$ListBox_Make.location = New-Object System.Drawing.Point(45,129)
[void] $ListBox_Make.Items.Add('Brother')
[void] $ListBox_Make.Items.Add('Canon')
[void] $ListBox_Make.Items.Add('HP')
[void] $ListBox_Make.Items.Add('Kyocera')
[void] $ListBox_Make.Items.Add('Ricoh')
[void] $ListBox_Make.Items.Add('Sharp')
$Label_Model = New-Object system.Windows.Forms.Label
$Label_Model.text= "Model"
$Label_Model.AutoSize= $true
$Label_Model.width = 25
$Label_Model.height= 10
$Label_Model.location= New-Object System.Drawing.Point(259,108)
$Label_Model.Font= 'Microsoft Sans Serif,10'
$ListBox_Model = New-Object system.Windows.Forms.ListBox
$ListBox_Model.text= "Model"
$ListBox_Model.width = 146
$ListBox_Model.height= 50
$ListBox_Model.location= New-Object System.Drawing.Point(259,129)
$Label_Location= New-Object system.Windows.Forms.Label
$Label_Location.text = "Location"
$Label_Location.AutoSize = $true
$Label_Location.width= 25
$Label_Location.height = 10
$Label_Location.location = New-Object System.Drawing.Point(45,195)
$Label_Location.Font = 'Microsoft Sans Serif,10'
$TextBox_Location= New-Object system.Windows.Forms.TextBox
$TextBox_Location.multiline= $false
$TextBox_Location.width= 363
$TextBox_Location.height = 20
$TextBox_Location.location = New-Object System.Drawing.Point(45,215)
$TextBox_Location.Font = 'Microsoft Sans Serif,10'
$Label_Problem = New-Object system.Windows.Forms.Label
$Label_Problem.text= "State what is wrong:"
$Label_Problem.AutoSize= $true
$Label_Problem.width = 25
$Label_Problem.height= 10
$Label_Problem.location= New-Object System.Drawing.Point(45,250)
$Label_Problem.Font= 'Microsoft Sans Serif,10'
$TextBox_Problem = New-Object system.Windows.Forms.TextBox
$TextBox_Problem.multiline = $false
$TextBox_Problem.width = 364
$TextBox_Problem.height= 100
$TextBox_Problem.location= New-Object System.Drawing.Point(45,270)
$TextBox_Problem.Font= 'Microsoft Sans Serif,10'
$CheckBox_Nope = New-Object system.Windows.Forms.CheckBox
$CheckBox_Nope.text= "Is your printer inoperable?"
$CheckBox_Nope.width = 250
$CheckBox_Nope.height= 50
$CheckBox_Nope.location= New-Object System.Drawing.Point(145,295)
$CheckBox_Nope.Font = 'Microsoft Sans Serif,10'
$Button_Submit = New-Object system.Windows.Forms.Button
$Button_Submit.text= "Submit"
$Button_Submit.width = 70
$Button_Submit.height= 30
$Button_Submit.location= New-Object System.Drawing.Point(189,345)
$Button_Submit.Font= 'Microsoft Sans Serif,10'
$Form_Service.controls.AddRange(#($Label_ValleyID,$Label_Make,$Label_Model,$Label_Location,$Label_Problem,$TextBox_ValleyID,$ListBox_Make,$ListBox_Model,$TextBox_Location,$TextBox_Problem,$Button_Submit,$CheckBox_Nope))
if ($ListBox_Make.SelectedItem -eq "Brother"){
[void] $ListBox_Model.Items.Add('MP301')
}
[void]$Form_Service.ShowDialog()
OK so what you are looking for is called events. Events are actions that take place that then allow you to run code after the action. Like when Mouse Clicks on a object or Keyboard button is pressed.
In Powershell when dealing with Winforms you can use
$Control.Add_EventName{
Code Here
}
Put the events after the controls are already called. I usally put them right before i show a form.
$ListBox_Make.Add_Click{
$ListBox_Model.Items.Add($ListBox_Make.SelectedItem)
}
[void]$Form_Service.ShowDialog()
in your exact case you could use :
$ListBox_Make.Add_Click{
if ($ListBox_Make.SelectedItem -eq "Brother"){
[void] $ListBox_Model.Items.Add('MP301')
}
}
Hopefully this puts you on the right track.
Also instead of a bunch of if Statements try a Switch instead
$ListBox_Make.Add_Click{
switch ($ListBox_Make.SelectedItem){
"Brother"{
$ListBox_Model.Items.Add('MP301')
}
"Canon"{
$ListBox_Model.Items.Add('LT45')
}
"HP"{
$ListBox_Model.Items.Add('ABC2133')
}
}
}
You can find the events for listbox
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.listbox?view=netframework-4.7.2#events

How to prevent null/whitespace value in Windows Form textbox (using Powershell)?

I made a Windows Form (this is the last portion of it) that allows the user to enter a search term in a textbox. The whole script checks a server for log files, and downloads them to the user's machine. The textbox data contains a string (date, account #, etc.)...and if left blank it is treated as a wildcard, downloading every log file in the folder chosen. I'm not sure if I can disable the "ok" button until data is entered or give a pop-up/message box prompting the user to enter a search term? I left the prior code/variables out of this example, as it has no bearing on the issue. I appreciate any help in advance!
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Enter search criteria"
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Enter search term"
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox)
$form.Topmost = $True
$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$Search = $textBox.Text
$Search
}
$UserPath = "C:\GetFiles\getfiles"
& cmd /c $UserPath" "$Search
Here would be one way you could handle it.
$okbutton.enabled = $false # make this a default
if(![string]::IsNullOrEmpty($textbox.text)) #only enable when you have text in the text box
{
$okbutton.enabled = $true
}
You'll have to use an event from the textbox to change the value of the $okbutton to enabled once text has been entered. I believe this is the event you'll need:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.textchanged?view=netframework-4.7.2
Depending on what you are doing you may need some of the other events as well.
I figured it out. Thank you to Thom Schumacher for helping me with the syntax necessary to complete this:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Enter search criteria"
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Enter loan number or date to search"
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox)
$form.Topmost = $True
$form.Add_Shown({$textBox.Select()})
do
{
$result = $form.ShowDialog()
if ([string]::IsNullOrEmpty($textbox.text))
{
Write-Warning 'Please enter search term.'
}
}
until(![string]::IsNullOrEmpty($textbox.text))
{
}
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$Search = $textBox.Text
$Search
}

Powershell - Close form after time period

I have a power-shell form prompting user if they would like to postpone a shutdown time (the time of the shutdown is given by another ps script as an argument which is calculated in the initial script).
I'd like to close the form after 30 minutes of inactivity, how would I go about this?
Powershell Code (Form):
#creating the form object
$form = New-Object System.Windows.Forms.Form
#setting the from title
$form.Text = "System warning"
#setting the form dimesnions and positions
$form.Size = New-Object System.Drawing.Size(300,250)
$form.StartPosition = "CenterScreen"
#claculate time before shut down:
$StartDate=(GET-DATE)
#this ill have to be replaced by a parameter which indicates the shut down date
$EndDate = $EndDate | Get-Date
$timeDifference = NEW-TIMESPAN –Start $StartDate –End $EndDate
$secondsTilShutdown = $timeDifference.TotalSeconds
#time remaining message
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,40)
$label.Text = "This computer is scheduled to shutdown at " + $EndDate
$form.Controls.Add($label)
#second message
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,70)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Postpone the shutdown by : "
$form.Controls.Add($label)
#setting up the drop down box (time in minutes)
$TimePeriods = 60, 120, 180, 240
$DropDown = new-object System.Windows.Forms.ComboBox
$DropDown.Location = new-object System.Drawing.Size(10,90)
$DropDown.Size = new-object System.Drawing.Size(130,30)
ForEach ($time in $TimePeriods) {
[void] $DropDown.Items.Add([string]($time/60) + " hours")
}
#1 hour is the default
$DropDown.SelectedItem = $DropDown.Items[0]
$Form.Controls.Add($DropDown)
#creating the postpone button
$OKButton = New-Object System.Windows.Forms.Button
#position of the button on the form
$OKButton.Location = New-Object System.Drawing.Point(25,130)
#size of the button
$OKButton.Size = New-Object System.Drawing.Size(100,50)
#text of the button
$OKButton.Text = "Postpone"
#the value that the from dialog will return if we click on ok
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
#assigns a key down on the enter key to the button
$form.AcceptButton = $OKButton
#adds the button to the form
$form.Controls.Add($OKButton)
#creating the ignore button
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(175,130)
$CancelButton.Size = New-Object System.Drawing.Size(100,50)
$CancelButton.Text = "Continue with scheduled shutdown"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox)
$form.Topmost = $True
$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()
###processing form results :
#if the postpone button button was selected
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
#logic
}
elseif($result -eq [System.Windows.Forms.DialogResult]::Cancel)
{
#we do not push back the shut down time
}
use a timer, i give you a example to timer wich close form
Function ClearAndClose()
{
$Timer.Stop();
$Form.Close();
$Form.Dispose();
$Timer.Dispose();
$Script:CountDown=5
}
Function Button_Click()
{
ClearAndClose
}
Function Timer_Tick()
{
$Label.Text = "Your system will reboot in $Script:CountDown seconds"
--$Script:CountDown
if ($Script:CountDown -lt 0)
{
ClearAndClose
}
}
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$Form = New-Object system.Windows.Forms.Form
$Form.Text = "Attention redémarrage!!"
$Form.Size = New-Object System.Drawing.Size(250,100)
$Form.StartPosition = "CenterScreen"
$Form.Topmost = $True
$Label = New-Object System.Windows.Forms.Label
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(20,5)
$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(55,35)
$Button.Size = New-Object System.Drawing.Size(120,23)
$Button.Text = "STOP"
$Button.DialogResult=[System.Windows.Forms.DialogResult]::OK
$Timer = New-Object System.Windows.Forms.Timer
$Timer.Interval = 1000
$Form.Controls.Add($Label)
$Form.Controls.Add($Button)
$Script:CountDown = 6
$Button.Add_Click({Button_Click})
$Timer.Add_Tick({ Timer_Tick})
$Timer.Start()
$Form.ShowDialog()

.NET DateTimePicker calendar not appearing in PowerShell form

I am trying to show a DateTimePicker in a WinForms form in PowerShell. When the form appears, the date can be changed, but hitting the dropdown button doesn't show the calendar. It seems like something is happening, it's just not visible.
What stupid thing am I missing here?
$form = New-Object Windows.Forms.Form
$form.Size = New-Object Drawing.Size #(400, 400)
$form.StartPosition = "CenterScreen"
$form.Text = "When do you want the snapshot to be taken?"
$form.Font = New-Object Drawing.Font("Microsoft Sans Serif",12)
$form.FormBorderStyle = [Windows.Forms.FormBorderStyle]::Fixed3D
$panel = New-Object Windows.Forms.FlowLayoutPanel
$panel.Height = 400
$panel.Width = 400
$panel.AutoScroll = $true
$panel.FlowDirection = [Windows.Forms.FlowDirection]::TopDown
$panel.WrapContents = $false
$titleText = New-Object Windows.Forms.Label
$titleText.AutoSize = $true
$titleText.Text = "When do you want the snapshot to be taken?"
$panel.Controls.Add($titleText)
$datePicker = New-Object Windows.Forms.DateTimePicker
$datePicker.ShowUpDown = $false
$datePicker.MinDate = $now
$datePicker.MaxDate = $now.AddMonths(3); #arbitrary
$datePicker.MaxSelectionCount = 1
$datePicker.Width = 350
$datePicker.Enabled = $false
$panel.Controls.Add($datePicker)
$form.Controls.Add($panel)
$drc = $form.ShowDialog()
Your code seems to work fine on my computer. I copy-pasted your code and added Add-Type to top:
Add-Type -AssemblyName System.Windows.Forms
And changed the $datePicker.Enabled:
$datePicker.Enabled = $true
When run, I can change the date/time and also the dropdown is working as expected:

Resources