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.
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!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} |