Last active
February 26, 2024 15:07
-
-
Save sba923/7ea3d013b1f758a947eea6c2e4f89f73 to your computer and use it in GitHub Desktop.
Utilities to help working with Sysinternals ZoomIt
This file contains hidden or 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
# this is one of Stéphane BARIZIEN's public domain scripts | |
# the most recent version can be found at: | |
# https://gist.github.com/sba923/7ea3d013b1f758a947eea6c2e4f89f73#file-get-zoomithelp-ps1 | |
<# | |
.SYNOPSIS | |
Show help for ZoomIt functions, with currently configured hotkeys | |
.DESCRIPTION | |
This script outputs help information the ZoomIt functions | |
that can be accessed via keyboard and/or mouse. | |
It calls Get-ZoomItOption.ps1 to extract information from the registry. | |
It outputs warnings about hotkeys that might be problematic to use or remember | |
e.g., because they might override AltGr+key combinations or because the main function | |
is Shift+something and another function is Shift+that function. | |
.PARAMETER SortByFunction | |
Sort the objects by 'Function'. | |
If not specified, help is output in logical functional groups. | |
.PARAMETER OnlyShowWarnings | |
If specified, only outputs (via Write-Host) warnings about hotkeys that might be problematic. | |
.INPUTS | |
None | |
.OUTPUTS | |
An array of PSCustomObject's with properties 'Function' and 'HelpText' | |
.EXAMPLE | |
PS> Get-ZoomItHelp.ps1 | |
WARNING: hotkey for 'Record window' is 'Ctrl+Alt+(', will override 'AltGr+(' | |
WARNING: hotkey for 'Save screen region' is 'Ctrl+R' | |
Function HelpText | |
-------- -------- | |
Zoom toggle Ctrl+& [user-configurable] | |
Copy screen during zoom Ctrl+C | |
Save screen during zoom Ctrl+S | |
Copy screen region during zoom Ctrl+Shift+C | |
Save screen region during zoom Ctrl+Shift+S | |
Live Zoom toggle Ctrl+' [user-configurable] | |
Live Zoom zoom-in Ctrl+Up | |
Live Zoom zoom-out Ctrl+Down | |
Change pen width / font size Ctrl+<mousewheel>, Up, Down | |
Set pen color R (red) G (green) B (blue) O (orange) Y (yellow) P (pink) X (blur) | |
Translucent highlighter color Shift+<color key [RGBOYP]> | |
Draw line Shift+<mouse> | |
Draw rectangle Ctrl+<mouse> | |
Draw ellipse Tab+<mouse> | |
Draw arrow Ctrl+Shift+<mouse> | |
Draw text t | |
Draw right-aligned text Shift+t | |
Clear screen W (white) K (black) | |
Draw without zoom Ctrl+é [user-configurable] | |
Enter timer mode Ctrl+" [user-configurable] | |
Record screen Ctrl+( [user-configurable] | |
Record screen region Ctrl+Shift+( [user-configurable] | |
Record window Ctrl+Alt+( [user-configurable] | |
Copy screen region Ctrl+Shift+R [user-configurable] | |
Save screen region Ctrl+R [user-configurable] | |
Undo Ctrl+Z | |
Erase E | |
Exit drawing mode RightClick | |
#> | |
param([switch]$SortByFunction, [switch]$OnlyShowWarnings) | |
# Add help entries from array of hashtables (for non-configurable functions) | |
function Get-HelpEntries([hashtable[]]$HelpEntries) | |
{ | |
$HelpEntries | Foreach-Object { | |
$helpentry = $_ | |
if ($helpentry.Keys.Count -ne 1) | |
{ | |
throw "INTERNAL ERROR: Get-HelpEntries needs array of single-key hashtable" | |
} | |
foreach ($key in $helpentry.Keys) | |
{ | |
[PSCustomObject]@{ | |
Function = $key | |
HelpText = $helpentry[$key] | |
} | |
} | |
} | |
} | |
# Add help for a hotkey | |
# This rewrites the string representation for a hotkey | |
# 1. account for duplicate modifiers e.g., Shift+Ctrl+Shift+R becomes Ctrl+R (with a warning) | |
# 2. sort modifiers in Ctrl, Alt, Shift order | |
function Get-HelpForConfigurableFunction([Parameter(Mandatory = $true)][string] $Function, [Parameter(Mandatory = $true)][string]$HotkeyString) | |
{ | |
# parse the string | |
if ($HotkeyString -match '^(.*)\+([^\+]+\+$)') | |
{ | |
$tokens = $Matches[1] -split '\+' | |
$tokens += , $Matches[2] | |
} | |
else | |
{ | |
$tokens = $HotkeyString -split '\+' | |
} | |
# extract the character | |
$character = $tokens[$tokens.Count - 1] | |
$modifiers = $tokens[0..($tokens.Count - 2)] | |
$newmodifiers = @() | |
$warning = $false | |
$modifiers | Group-Object | Foreach-Object { | |
if ($_.Count -eq 1) | |
{ | |
$newmodifiers += $_.Name | |
} | |
elseif ($_.Count -eq 2) | |
{ | |
$warning = $true | |
$null = $warning # $null assignment to avoid PSSA 'not used' warning | |
} | |
else | |
{ | |
throw "INTERNAL ERROR: cannot have more than 2 occurrences of modifier: {0}" -f $HotkeyString | |
} | |
} | |
$newhotkeystring = (($newmodifiers | Sort-Object -Property { "CtrlAltShift".IndexOf($_) }) -join '+') + '+' + $character | |
if ($warning) | |
{ | |
Write-Host -ForegroundColor Magenta ("WARNING: hotkey for '{0}' is '{1}'" -f $Function, $newhotkeystring) | |
} | |
# warn if Ctrl+Alt+<not a letter>, will override AltGr+<key> | |
if ($newhotkeystring -match 'Ctrl\+Alt\+(?:.*\+|)([^a-z])$') | |
{ | |
Write-Host -ForegroundColor Magenta ("WARNING: hotkey for '{0}' is '{1}', will override 'AltGr+{2}'" -f $Function, $newhotkeystring, $Matches[1]) | |
} | |
[PSCustomObject] @{ | |
Function = $Function | |
HelpText = $newhotkeystring + ' [user-configurable]' | |
} | |
} | |
# create help for ZoomIt functions, either fixed or extracted from the registry via Get-ZoomItOption.ps1 | |
#TODO error handling e.g., Get-ZoomItOption.ps1 not found or fails | |
$zoomitoptions = Get-ZoomItOption.ps1 | |
$help = @() | |
$help += Get-HelpForConfigurableFunction -Function 'Zoom toggle' -HotkeyString $zoomitoptions.ToggleKey | |
$help += Get-HelpEntries -HelpEntries @( | |
@{'Copy screen during zoom' = 'Ctrl+C' } | |
@{'Save screen during zoom' = 'Ctrl+S' } | |
@{'Copy screen region during zoom' = 'Ctrl+Shift+C' } | |
@{'Save screen region during zoom' = 'Ctrl+Shift+S' } | |
) | |
$help += Get-HelpForConfigurableFunction -Function 'Live Zoom toggle' -HotkeyString $zoomitoptions.LiveZoomToggleKey | |
$help += Get-HelpEntries -HelpEntries @( | |
@{'Live Zoom zoom-in' = 'Ctrl+Up' } | |
@{'Live Zoom zoom-out' = 'Ctrl+Down' } | |
@{'Change pen width / font size' = 'Ctrl+<mousewheel>, Up, Down' } | |
@{'Set pen color' = 'R (red) G (green) B (blue) O (orange) Y (yellow) P (pink) X (blur)' } | |
@{'Translucent highlighter color' = 'Shift+<color key [RGBOYP]>' } | |
@{'Draw line' = 'Shift+<mouse>' } | |
@{'Draw rectangle' = 'Ctrl+<mouse>' } | |
@{'Draw ellipse' = 'Tab+<mouse>' } | |
@{'Draw arrow' = 'Ctrl+Shift+<mouse>' } | |
@{'Draw text' = 't' } | |
@{'Draw right-aligned text' = 'Shift+t' } | |
@{'Clear screen' = 'W (white) K (black)' } | |
) | |
$help += Get-HelpForConfigurableFunction -Function 'Draw without zoom' -HotkeyString $zoomitoptions.DrawToggleKey | |
$help += Get-HelpForConfigurableFunction -Function 'Enter timer mode' -HotkeyString $zoomitoptions.BreakTimerKey | |
$help += Get-HelpForConfigurableFunction -Function 'Record screen' -HotkeyString $zoomitoptions.RecordToggleKey | |
$help += Get-HelpForConfigurableFunction -Function 'Record screen region' -HotkeyString ('Shift+' + $zoomitoptions.RecordToggleKey) | |
$help += Get-HelpForConfigurableFunction -Function 'Record window' -HotkeyString ('Alt+' + $zoomitoptions.RecordToggleKey) | |
$help += Get-HelpForConfigurableFunction -Function 'Copy screen region' -HotkeyString $zoomitoptions.SnipToggleKey | |
$help += Get-HelpForConfigurableFunction -Function 'Save screen region' -HotkeyString ('Shift+' + $zoomitoptions.SnipToggleKey) | |
$help += Get-HelpEntries -HelpEntries @( | |
@{'Undo' = 'Ctrl+Z' } | |
@{'Erase' = 'E' } | |
@{'Exit drawing mode' = 'RightClick' } | |
) | |
if (!$OnlyShowWarnings) | |
{ | |
# output 'as is' or sorted by function name | |
if (!$SortByFunction) | |
{ | |
$help | |
} | |
else | |
{ | |
$help | Sort-Object -Property 'Function' | |
} | |
} |
This file contains hidden or 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
# this is one of Stéphane BARIZIEN's public domain scripts | |
# the most recent version can be found at: | |
# https://gist.github.com/sba923/7ea3d013b1f758a947eea6c2e4f89f73#file-get-zoomitoption-ps1 | |
<# | |
.SYNOPSIS | |
Get ZoomIt configuration information from the registry | |
.DESCRIPTION | |
This extracts the configuration information for ZoomIt from the registry in human-usable form | |
.INPUTS | |
None | |
.OUTPUTS | |
A PSCustomObject whose properties are the registry values under HKEY_CURRENT_USER\Software\Sysinternals\ZoomIt, | |
some of which (e.g., Font, hotkeys, PenColor) are rewritten to be human-usable. | |
#> | |
#TODO error handling e.g., if ZoomIt has never been run (registry entries not present) | |
$_ZoomItOptionWin32TypeName = "ZoomItOptionWin32" | |
# # avoid an error if sourcing the script multiple times e.g., when debugging in VScode | |
# if (-not ([System.Management.Automation.PSTypeName]$_ZoomItOptionWin32TypeName).Type) | |
# { | |
$_ZoomItOptionWin32Type = Add-Type -MemberDefinition @" | |
[DllImport("user32.dll")] | |
public static extern int MapVirtualKeyEx(int uCode, int uMapType, int dwhkl, ref uint lpChar, int uFlags); | |
"@ -Name $_ZoomItOptionWin32TypeName -Namespace "User32" -PassThru | |
# } | |
# else | |
# { | |
# Write-Host -ForegroundColor 'Magenta' ("Type '{0}' already defined" -f $_ZoomItOptionWin32TypeName) | |
# } | |
function Convert-KeycodeToString([int]$Keycode) | |
{ | |
$modifier = "" | |
if (($Keycode -band 0x200) -ne 0) | |
{ | |
$modifier = "Ctrl+" + $modifier | |
} | |
if (($Keycode -band 0x400) -ne 0) | |
{ | |
$modifier = "Alt+" + $modifier | |
} | |
if (($Keycode -band 0x100) -ne 0) | |
{ | |
$modifier = "Shift+" + $modifier | |
} | |
# $scanCode = 0 | |
# $keyboardState = New-Object byte[] 256 | |
$charBuffer = New-Object char[] 1 | |
# $bufferSize = $charBuffer.Length | |
$flags = 0 | |
$layout = [System.Globalization.CultureInfo]::CurrentCulture.KeyboardLayoutId | |
$char = $_ZoomItOptionWin32Type::MapVirtualKeyEx($Keycode -band 0xFF, 2, $layout, [ref]$charBuffer[0], $flags) | |
if (($Keycode -band 0xF0) -eq 0x60) | |
{ | |
$modifier + 'NumPad' + [char]$char | |
} | |
else | |
{ | |
$modifier + [char]$char | |
} | |
} | |
$zoomitoptions = Get-ItemProperty 'HKCU:\Software\Sysinternals\ZoomIt' | |
# convert keycodes to human-readable strings | |
$zoomitoptions.PSObject.Properties.Name -match 'Key$' | Foreach-Object { | |
$optionname = $_ | |
$zoomitoptions.$optionname = (Convert-KeycodeToString -Keycode $zoomitoptions.$optionname) | |
} | |
# convert pen color to #nnnnnn hex value | |
$zoomitoptions.PenColor = "#{0:x6}" -f $zoomitoptions.PenColor | |
# convert fontname to string | |
$zoomitoptions.Font = [System.Text.Encoding]::Unicode.GetString($zoomitoptions.Font[28..($zoomitoptions.Font.Count - 1)]) | |
$zoomitoptions |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment