Friday fun: Create a WPF Clock Widget with PowerShell

The guys over at Arction have kindly made available a free Gauge control for WPF. I decided to download it and create a clock using PowerShell. The result is New-WPFClock.

Clock

To use the function, first download the free Gauge control. You’ll find the Arction.WPF.Gauges.dll in the Libs\Wpf folder. In the script on line 26, enter the location of this dll on your system.

Then simply call New-WPFClock.

The function has a couple of optional parameters:

  • Color – set the colour of the clock face
  • Height – set the height
  • Width – set the width
  • FontSize – set the size of the numbers
  • AlwaysOnTop – keep the clock on top of other windows

To close the clock, simply right-click it.

Enjoy!

Function New-WPFClock {
## Generates a clock displaying the current system time
## Requires the Arction WPF Gauges, a free download from https://www.arction.com/free-gauges/
## Set the location of the Arction Gauges dll on line 26
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$false,Position=0)]
$Color = "SteelBlue",
[Parameter(Mandatory=$false,Position=1)]
[int]$Height = 300,
[Parameter(Mandatory=$false,Position=2)]
[int]$Width = 300,
[Parameter(Mandatory=$false,Position=3)]
[int]$FontSize = 30,
[Parameter(Mandatory=$false,Position=4)]
[switch]$AlwaysOnTop
)
# Load the required assemblies
Add-Type -AssemblyName PresentationFramework,PresentationCore
Try
{
Add-Type -Path "<path>\Arction.WPF.Gauges.dll" -ErrorAction Stop
}
Catch
{
$e = New-Object 'System.IO.FileLoadException' "Could not add the Arction.WPF.Gauges.dll. Ensure it is available"
$Category = [System.Management.Automation.ErrorCategory]::ObjectNotFound
$TargetObject = ""
$errorRecord = New-Object System.Management.Automation.ErrorRecord $e, $errorID, $Category, $TargetObject
$PSCmdlet.ThrowTerminatingError($errorRecord)
}
# Create the window
$Window = [System.Windows.Window]::new()
$Window.SizeToContent = [System.Windows.SizeToContent]::WidthAndHeight
$Window.AllowsTransparency = $true
$Window.Background = "Transparent"
$Window.WindowStyle = "None"
$Window.WindowStartupLocation = "CenterScreen"
If ($AlwaysOnTop)
{
$Window.Topmost = $true
}
# Create the Gauge
$Gauge = [Arction.Gauges.Gauge]::new()
$Gauge.Margin = 5
$Gauge.Height = $Height
$Gauge.Width = $Width
$Gauge.Fill = $Color
$Gauge.FontSize = $FontSize
$Gauge.Cursor = "Hand"
# Allow drag
$Gauge.Add_MouseLeftButtonDown({
$Window.DragMove()
})
# Close on right-click
$Gauge.Add_MouseRightButtonUp({
$Window.Close()
})
# Create the Hour Scale
$HourScale = New-object Arction.Gauges.Scale
$HourScale.AngleBegin = 60
$HourScale.AngleEnd = 60
$HourScale.RangeBegin = 1
$HourScale.RangeEnd = 13
$HourScale.Theme = "None"
$HourScale.MajorTickCount = 12
$HourScale.MinorTickCount = 0
$HourScale.TertiaryTickCount = 0
$HourScale.DialShape = [Arction.Gauges.Dials.DialShape]::DefaultNeedle
$HourScale.DialLengthFactor = 0.6
$HourScale.DialColor1 = "White"
$HourScale.Label = [System.Windows.Controls.TextBlock]::new()
$HourScale.ValueIndicator.Foreground = $Color
$HoursMajorTicks = New-Object Arction.Gauges.MajorTicksLine
$HoursMajorTicks.LabelOffset = -12
$HoursMajorTicks.OffsetA = -5
$HoursMajorTicks.TickThickness = -5
$HoursMajorTicks.FontWeight = "Bold"
$HoursMajorTicks.FontFamily = "Arial"
$HoursMajorTicks.TickStroke = "White"
$HoursMajorTicks.LabelBrush = "White"
$HourScale.MajorTicks = $HoursMajorTicks
# Create the Minute Scale
$MinuteScale = New-object Arction.Gauges.Scale
$MinuteScale.AngleBegin = 90
$MinuteScale.AngleEnd = 90
$MinuteScale.RangeBegin = 0
$MinuteScale.RangeEnd = 60
$MinuteScale.Theme = "None"
$MinuteScale.MajorTickCount = 60
$MinuteScale.MinorTickCount = 0
$MinuteScale.TertiaryTickCount = 0
$MinuteScale.DialShape = [Arction.Gauges.Dials.DialShape]::DefaultNeedle
$MinuteScale.DialLengthFactor = 0.8
$MinuteScale.DialColor1 = "White"
$MinutesMajorTicks = New-Object Arction.Gauges.MajorTicksLine
$MinutesMajorTicks.OffsetA = -4
$MinutesMajorTicks.OffsetB = -2
$MinutesMajorTicks.TickThickness = 2
$MinutesMajorTicks.LabelFormat = ""
$MinutesMajorTicks.TickStroke = "White"
$MinutesMajorTicks.LabelBrush = "White"
$MinuteScale.MajorTicks = $MinutesMajorTicks
# Create the Seconds Scale
$SecondsScale = New-object Arction.Gauges.Scale
$SecondsScale.AngleBegin = 90
$SecondsScale.AngleEnd = 90
$SecondsScale.RangeBegin = 0
$SecondsScale.RangeEnd = 60
$SecondsScale.Theme = "None"
$SecondsScale.MajorTickCount = 60
$SecondsScale.MinorTickCount = 0
$SecondsScale.TertiaryTickCount = 0
$SecondsScale.DialShape = [Arction.Gauges.Dials.DialShape]::Line
$SecondsScale.DialLengthFactor = 0.8
$SecondsDial = New-Object Arction.Gauges.Dials.Dial
$SecondsDial.MaxWidth = 5
$SecondsDial.Height = 28
$SecondsDial.AspectRatio = 0.2
$SecondsScale.Dial = $SecondsDial
$SecondsMajorTicks = New-Object Arction.Gauges.MajorTicksLine
$SecondsMajorTicks.OffsetA = -4
$SecondsMajorTicks.OffsetB = -2
$SecondsMajorTicks.TickThickness = 2
$SecondsMajorTicks.LabelFormat = ""
$SecondsMajorTicks.TickStroke = "White"
$SecondsMajorTicks.LabelBrush = "White"
$SecondsScale.MajorTicks = $SecondsMajorTicks
# Add the scales to the Gauge
$Gauge.PrimaryScale = $HourScale
$Gauge.SecondaryScales.Add($MinuteScale)
$Gauge.SecondaryScales.Add($SecondsScale)
# Add the Gauge to the window
$Window.AddChild($Gauge)
# Set the initial time values
$Gauge.PrimaryScale.Value = [System.DateTime]::Now.Hour
$Gauge.SecondaryScales[0].Value = [System.DateTime]::Now.Minute
$Gauge.SecondaryScales[1].Value = [System.DateTime]::Now.Second
# Start a dispatcher timer to update the clock every second
$TimerCode = {
$Gauge.PrimaryScale.Value = [System.DateTime]::Now.Hour
$Gauge.SecondaryScales[0].Value = [System.DateTime]::Now.Minute
$Gauge.SecondaryScales[1].Value = [System.DateTime]::Now.Second
}
$DispatcherTimer = New-Object -TypeName System.Windows.Threading.DispatcherTimer
$DispatcherTimer.Interval = [TimeSpan]::FromSeconds(1)
$DispatcherTimer.Add_Tick($TimerCode)
$DispatcherTimer.Start()
# Activate the window on load
$Window.Add_Loaded({
$This.Activate()
})
# Stop the dispatcher on close
$Window.Add_Closed({
$DispatcherTimer.Stop()
})
# Display the window
$null = $window.Dispatcher.InvokeAsync{$window.ShowDialog()}.Wait()
}

view raw
New-WPFClock
hosted with ❤ by GitHub

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.