制作盒子菜单。我如何color/highlight选择?
Making a box menu. How do I color/highlight the selection?
所以我拼凑了一个菜单,其中包含一个标题和您可以 select 从中选择的选项。选择一个项目是通过使用箭头键完成的。我想让 selected 项目突出显示,这样您就可以知道您当前正在 selecting 哪个项目。我是 PowerShell 的新手,熟悉如何使用 write-host 更改颜色,但在这个例子中我一无所知。我认为我需要将颜色选项注入的相关行是以 $Width 开头的行。我真的很感激一些见解!这是我在开始添加实际代码之前的最后一次打嗝!
Function Create-Menu (){
Param(
[Parameter(Mandatory=$True)][String]$MenuTitle,
[Parameter(Mandatory=$True)][array]$MenuOptions
)
$MaxValue = $MenuOptions.count-1
$Selection = 0
$EnterPressed = $False
Clear-Host
While($EnterPressed -eq $False){
For ($i=0; $i -le $MaxValue; $i++){
$Width = if($Title){$Length = $Title.Length;$Length2 = $MenuOptions|%{$_.length}|Sort -Descending|Select -First 1;$Length2,$Length|Sort -Descending|Select -First 1}else{$MenuOptions|%{$_.length}|Sort -Descending|Select -First 1}
$Buffer = if(($Width*1.5) -gt 78){(78-$width)/2}else{$width/4}
if($Buffer -gt 6){$Buffer = 6}
$MaxWidth = $Buffer*2+$Width+$($MenuOptions.count).length
$Menu = @()
$Menu += "╔"+"═"*$maxwidth+"╗"
if($MenuTitle){
$Menu += "║"+" "*[Math]::Floor(($maxwidth-$MenuTitle.Length)/2)+$MenuTitle+" "*[Math]::Ceiling(($maxwidth-$MenuTitle.Length)/2)+"║"
$Menu += "╟"+"─"*$maxwidth+"╢"
}
For($i=1;$i -le $MenuOptions.count;$i++){
$Item = "$i`. "
$Menu += "║"+" "*$Buffer+$Item+$MenuOptions[$i-1]+" "*($MaxWidth-$Buffer-$Item.Length-$MenuOptions[$i-1].Length)+"║"
}
$Menu += "╚"+"═"*$maxwidth+"╝"
$menu
}
$KeyInput = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown").virtualkeycode
Switch($KeyInput){
13{
$EnterPressed = $True
$script:Selection = "$Selection"
Clear-Host
break
}
38{
If ($Selection -eq 0){
$Selection = $MaxValue
} Else {
$Selection -= 1
}
Clear-Host
break
}
40{
If ($Selection -eq $MaxValue){
$Selection = 0
} Else {
$Selection +=1
}
Clear-Host
break
}
Default{
Clear-Host
}
}
}
}
#MainMenu
Function MainMenu (){
Create-Menu -MenuTitle "Tool" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
If($script:Selection -eq 0) {Lookup}
If($script:Selection -eq 1) {PrepMenu}
If($script:Selection -eq 2) {ToolsMenu}
If($script:Selection -eq 3) {SettingsMenu}
If($script:Selection -eq 4) {CleanupAndExit}
}
MainMenu
pause
代码输出如下:
╔═════════════════════════╗
║ Tool ║
╟─────────────────────────╢
║ 1. Lookup ║
║ 2. Prep ║
║ 3. Tools ║
║ 4. Settings ║
║ 5. Cleanup and Exit ║
╚═════════════════════════╝
您可以通过对代码进行一些小的调整来添加颜色(我使用的是绿色,但这取决于您):
function Create-Menu {
Param(
[Parameter(Mandatory=$True)][String]$MenuTitle,
[Parameter(Mandatory=$True)][array]$MenuOptions
)
# test if we're not running in the ISE
if ($Host.Name -match 'ISE') {
Throw "This menu must be run in PowerShell Console"
}
$MaxValue = $MenuOptions.Count-1
$Selection = 0
$EnterPressed = $False
While(!$EnterPressed) {
# draw the menu
Clear-Host
for ($i = 0; $i -le $MaxValue; $i++){
[int]$Width = [math]::Max($MenuTitle.Length, ($MenuOptions | Measure-Object -Property Length -Maximum).Maximum)
[int]$Buffer = if (($Width * 1.5) -gt 78) { (78 - $width) / 2 } else { $width / 4 }
$Buffer = [math]::Min(6, $Buffer)
$MaxWidth = $Buffer * 2 + $Width + $MenuOptions.Count.ToString().Length
Write-Host ("╔" + "═" * $maxwidth + "╗")
# write the title if present
if (!([string]::IsNullOrWhiteSpace($MenuTitle))) {
$leftSpace = ' ' * [Math]::Floor(($maxwidth - $MenuTitle.Length)/2)
$rightSpace = ' ' * [Math]::Ceiling(($maxwidth - $MenuTitle.Length)/2)
Write-Host ("║" + $leftSpace + $MenuTitle + $rightSpace + "║")
Write-Host ("╟" + "─" * $maxwidth + "╢")
}
# write the menu option lines
for($i = 0; $i -lt $MenuOptions.Count; $i++){
$Item = "$($i + 1). "
$Option = $MenuOptions[$i]
$leftSpace = ' ' * $Buffer
$rightSpace = ' ' * ($MaxWidth - $Buffer - $Item.Length - $Option.Length)
$line = "║" + $leftSpace + $Item + $Option + $rightSpace + "║"
if ($Selection -eq $i) {
Write-Host $line -ForegroundColor Green
}
else {
Write-Host $line
}
}
Write-Host ("╚" + "═" * $maxwidth + "╝")
}
# wait for an accepted key press
do {
$KeyInput = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
} while (13, 38, 40 -notcontains $KeyInput)
Switch($KeyInput){
13{
$EnterPressed = $True
return $Selection
}
38 {
$Selection--
if ($Selection -lt 0){ $Selection = $MaxValue }
break
}
40 {
$Selection++
if ($Selection -gt $MaxValue) { $Selection = 0 }
# or: $Selection = ($Selection + 1) % ($MaxValue + 1)
break
}
}
}
}
#MainMenu
function MainMenu {
$selected = Create-Menu -MenuTitle "Tools" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
switch ($selected) {
0 {"Lookup"}
1 {"PrepMenu"}
2 {"ToolsMenu"}
3 {"SettingsMenu"}
4 {"CleanupAndExit"}
}
}
MainMenu
编辑
只是为了好玩,上面的代码在每次重绘菜单之前使用了 Clear-Host
,这导致了一个可行但闪烁的菜单。
在相同的菜单下方,但这次它在没有先清除控制台的情况下重绘 window,从而使菜单更加流畅。
function Create-Menu {
Param(
[Parameter(Mandatory=$false)][string] $MenuTitle = $null,
[Parameter(Mandatory=$true)] [string[]]$MenuOptions
)
# test if we're not running in the ISE
if ($Host.Name -match 'ISE') {
Throw "This menu must be run in PowerShell Console"
}
$MaxValue = $MenuOptions.Count-1
$Selection = 0
$EnterPressed = $False
[console]::CursorVisible = $false # prevents cursor flickering
Clear-Host
while(!$EnterPressed) {
# draw the menu without Clear-Host to prevent flicker
[console]::SetCursorPosition(0,0)
for ($i = 0; $i -le $MaxValue; $i++){
[int]$Width = [math]::Max($MenuTitle.Length, ($MenuOptions | Measure-Object -Property Length -Maximum).Maximum)
[int]$Buffer = if (($Width * 1.5) -gt 78) { (78 - $width) / 2 } else { $width / 4 }
$Buffer = [math]::Min(6, $Buffer)
$MaxWidth = $Buffer * 2 + $Width + $MenuOptions.Count.ToString().Length
Write-Host ("╔" + "═" * $maxwidth + "╗")
# write the title if present
if (!([string]::IsNullOrWhiteSpace($MenuTitle))) {
$leftSpace = ' ' * [Math]::Floor(($maxwidth - $MenuTitle.Length)/2)
$rightSpace = ' ' * [Math]::Ceiling(($maxwidth - $MenuTitle.Length)/2)
Write-Host ("║" + $leftSpace + $MenuTitle + $rightSpace + "║")
Write-Host ("╟" + "─" * $maxwidth + "╢")
}
# write the menu option lines
for($i = 0; $i -lt $MenuOptions.Count; $i++){
$Item = "$($i + 1). "
$Option = $MenuOptions[$i]
$leftSpace = ' ' * $Buffer
$rightSpace = ' ' * ($MaxWidth - $Buffer - $Item.Length - $Option.Length)
$line = "║" + $leftSpace + $Item + $Option + $rightSpace + "║"
if ($Selection -eq $i) {
Write-Host $line -ForegroundColor Green
}
else {
Write-Host $line
}
}
Write-Host ("╚" + "═" * $maxwidth + "╝")
}
# wait for an accepted key press
do {
$KeyInput = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
} while (13, 38, 40 -notcontains $KeyInput)
Switch($KeyInput){
13{
$EnterPressed = $True
[console]::CursorVisible = $true # reset the cursors visibility
return $Selection
}
38 {
$Selection--
if ($Selection -lt 0){ $Selection = $MaxValue }
break
}
40 {
$Selection++
if ($Selection -gt $MaxValue) { $Selection = 0 }
# or: $Selection = ($Selection + 1) % ($MaxValue + 1)
break
}
}
}
}
#MainMenu
function MainMenu {
$selected = Create-Menu -MenuTitle "Tools" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
switch ($selected) {
0 {"Lookup"}
1 {"PrepMenu"}
2 {"ToolsMenu"}
3 {"SettingsMenu"}
4 {"CleanupAndExit"}
}
}
MainMenu
所以我拼凑了一个菜单,其中包含一个标题和您可以 select 从中选择的选项。选择一个项目是通过使用箭头键完成的。我想让 selected 项目突出显示,这样您就可以知道您当前正在 selecting 哪个项目。我是 PowerShell 的新手,熟悉如何使用 write-host 更改颜色,但在这个例子中我一无所知。我认为我需要将颜色选项注入的相关行是以 $Width 开头的行。我真的很感激一些见解!这是我在开始添加实际代码之前的最后一次打嗝!
Function Create-Menu (){
Param(
[Parameter(Mandatory=$True)][String]$MenuTitle,
[Parameter(Mandatory=$True)][array]$MenuOptions
)
$MaxValue = $MenuOptions.count-1
$Selection = 0
$EnterPressed = $False
Clear-Host
While($EnterPressed -eq $False){
For ($i=0; $i -le $MaxValue; $i++){
$Width = if($Title){$Length = $Title.Length;$Length2 = $MenuOptions|%{$_.length}|Sort -Descending|Select -First 1;$Length2,$Length|Sort -Descending|Select -First 1}else{$MenuOptions|%{$_.length}|Sort -Descending|Select -First 1}
$Buffer = if(($Width*1.5) -gt 78){(78-$width)/2}else{$width/4}
if($Buffer -gt 6){$Buffer = 6}
$MaxWidth = $Buffer*2+$Width+$($MenuOptions.count).length
$Menu = @()
$Menu += "╔"+"═"*$maxwidth+"╗"
if($MenuTitle){
$Menu += "║"+" "*[Math]::Floor(($maxwidth-$MenuTitle.Length)/2)+$MenuTitle+" "*[Math]::Ceiling(($maxwidth-$MenuTitle.Length)/2)+"║"
$Menu += "╟"+"─"*$maxwidth+"╢"
}
For($i=1;$i -le $MenuOptions.count;$i++){
$Item = "$i`. "
$Menu += "║"+" "*$Buffer+$Item+$MenuOptions[$i-1]+" "*($MaxWidth-$Buffer-$Item.Length-$MenuOptions[$i-1].Length)+"║"
}
$Menu += "╚"+"═"*$maxwidth+"╝"
$menu
}
$KeyInput = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown").virtualkeycode
Switch($KeyInput){
13{
$EnterPressed = $True
$script:Selection = "$Selection"
Clear-Host
break
}
38{
If ($Selection -eq 0){
$Selection = $MaxValue
} Else {
$Selection -= 1
}
Clear-Host
break
}
40{
If ($Selection -eq $MaxValue){
$Selection = 0
} Else {
$Selection +=1
}
Clear-Host
break
}
Default{
Clear-Host
}
}
}
}
#MainMenu
Function MainMenu (){
Create-Menu -MenuTitle "Tool" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
If($script:Selection -eq 0) {Lookup}
If($script:Selection -eq 1) {PrepMenu}
If($script:Selection -eq 2) {ToolsMenu}
If($script:Selection -eq 3) {SettingsMenu}
If($script:Selection -eq 4) {CleanupAndExit}
}
MainMenu
pause
代码输出如下:
╔═════════════════════════╗
║ Tool ║
╟─────────────────────────╢
║ 1. Lookup ║
║ 2. Prep ║
║ 3. Tools ║
║ 4. Settings ║
║ 5. Cleanup and Exit ║
╚═════════════════════════╝
您可以通过对代码进行一些小的调整来添加颜色(我使用的是绿色,但这取决于您):
function Create-Menu {
Param(
[Parameter(Mandatory=$True)][String]$MenuTitle,
[Parameter(Mandatory=$True)][array]$MenuOptions
)
# test if we're not running in the ISE
if ($Host.Name -match 'ISE') {
Throw "This menu must be run in PowerShell Console"
}
$MaxValue = $MenuOptions.Count-1
$Selection = 0
$EnterPressed = $False
While(!$EnterPressed) {
# draw the menu
Clear-Host
for ($i = 0; $i -le $MaxValue; $i++){
[int]$Width = [math]::Max($MenuTitle.Length, ($MenuOptions | Measure-Object -Property Length -Maximum).Maximum)
[int]$Buffer = if (($Width * 1.5) -gt 78) { (78 - $width) / 2 } else { $width / 4 }
$Buffer = [math]::Min(6, $Buffer)
$MaxWidth = $Buffer * 2 + $Width + $MenuOptions.Count.ToString().Length
Write-Host ("╔" + "═" * $maxwidth + "╗")
# write the title if present
if (!([string]::IsNullOrWhiteSpace($MenuTitle))) {
$leftSpace = ' ' * [Math]::Floor(($maxwidth - $MenuTitle.Length)/2)
$rightSpace = ' ' * [Math]::Ceiling(($maxwidth - $MenuTitle.Length)/2)
Write-Host ("║" + $leftSpace + $MenuTitle + $rightSpace + "║")
Write-Host ("╟" + "─" * $maxwidth + "╢")
}
# write the menu option lines
for($i = 0; $i -lt $MenuOptions.Count; $i++){
$Item = "$($i + 1). "
$Option = $MenuOptions[$i]
$leftSpace = ' ' * $Buffer
$rightSpace = ' ' * ($MaxWidth - $Buffer - $Item.Length - $Option.Length)
$line = "║" + $leftSpace + $Item + $Option + $rightSpace + "║"
if ($Selection -eq $i) {
Write-Host $line -ForegroundColor Green
}
else {
Write-Host $line
}
}
Write-Host ("╚" + "═" * $maxwidth + "╝")
}
# wait for an accepted key press
do {
$KeyInput = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
} while (13, 38, 40 -notcontains $KeyInput)
Switch($KeyInput){
13{
$EnterPressed = $True
return $Selection
}
38 {
$Selection--
if ($Selection -lt 0){ $Selection = $MaxValue }
break
}
40 {
$Selection++
if ($Selection -gt $MaxValue) { $Selection = 0 }
# or: $Selection = ($Selection + 1) % ($MaxValue + 1)
break
}
}
}
}
#MainMenu
function MainMenu {
$selected = Create-Menu -MenuTitle "Tools" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
switch ($selected) {
0 {"Lookup"}
1 {"PrepMenu"}
2 {"ToolsMenu"}
3 {"SettingsMenu"}
4 {"CleanupAndExit"}
}
}
MainMenu
编辑
只是为了好玩,上面的代码在每次重绘菜单之前使用了 Clear-Host
,这导致了一个可行但闪烁的菜单。
在相同的菜单下方,但这次它在没有先清除控制台的情况下重绘 window,从而使菜单更加流畅。
function Create-Menu {
Param(
[Parameter(Mandatory=$false)][string] $MenuTitle = $null,
[Parameter(Mandatory=$true)] [string[]]$MenuOptions
)
# test if we're not running in the ISE
if ($Host.Name -match 'ISE') {
Throw "This menu must be run in PowerShell Console"
}
$MaxValue = $MenuOptions.Count-1
$Selection = 0
$EnterPressed = $False
[console]::CursorVisible = $false # prevents cursor flickering
Clear-Host
while(!$EnterPressed) {
# draw the menu without Clear-Host to prevent flicker
[console]::SetCursorPosition(0,0)
for ($i = 0; $i -le $MaxValue; $i++){
[int]$Width = [math]::Max($MenuTitle.Length, ($MenuOptions | Measure-Object -Property Length -Maximum).Maximum)
[int]$Buffer = if (($Width * 1.5) -gt 78) { (78 - $width) / 2 } else { $width / 4 }
$Buffer = [math]::Min(6, $Buffer)
$MaxWidth = $Buffer * 2 + $Width + $MenuOptions.Count.ToString().Length
Write-Host ("╔" + "═" * $maxwidth + "╗")
# write the title if present
if (!([string]::IsNullOrWhiteSpace($MenuTitle))) {
$leftSpace = ' ' * [Math]::Floor(($maxwidth - $MenuTitle.Length)/2)
$rightSpace = ' ' * [Math]::Ceiling(($maxwidth - $MenuTitle.Length)/2)
Write-Host ("║" + $leftSpace + $MenuTitle + $rightSpace + "║")
Write-Host ("╟" + "─" * $maxwidth + "╢")
}
# write the menu option lines
for($i = 0; $i -lt $MenuOptions.Count; $i++){
$Item = "$($i + 1). "
$Option = $MenuOptions[$i]
$leftSpace = ' ' * $Buffer
$rightSpace = ' ' * ($MaxWidth - $Buffer - $Item.Length - $Option.Length)
$line = "║" + $leftSpace + $Item + $Option + $rightSpace + "║"
if ($Selection -eq $i) {
Write-Host $line -ForegroundColor Green
}
else {
Write-Host $line
}
}
Write-Host ("╚" + "═" * $maxwidth + "╝")
}
# wait for an accepted key press
do {
$KeyInput = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
} while (13, 38, 40 -notcontains $KeyInput)
Switch($KeyInput){
13{
$EnterPressed = $True
[console]::CursorVisible = $true # reset the cursors visibility
return $Selection
}
38 {
$Selection--
if ($Selection -lt 0){ $Selection = $MaxValue }
break
}
40 {
$Selection++
if ($Selection -gt $MaxValue) { $Selection = 0 }
# or: $Selection = ($Selection + 1) % ($MaxValue + 1)
break
}
}
}
}
#MainMenu
function MainMenu {
$selected = Create-Menu -MenuTitle "Tools" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
switch ($selected) {
0 {"Lookup"}
1 {"PrepMenu"}
2 {"ToolsMenu"}
3 {"SettingsMenu"}
4 {"CleanupAndExit"}
}
}
MainMenu