问题
a while ago i were googling to find out how I could make a batch menu with a more "professional look" instead of using symbols such as:
|=====|
|-----|
|_____|
to make outlines around a menu in batch. but I had no luck. today i randomly found this article:
https://web.archive.org/web/20151204182221/https://http-server.carleton.ca/~dmcfet/menu.html
and it explains that by using ms-dos (edit.com) I can do this.
but as my computer is a 64 bit win 10. I dot have the edit.com so.... how could I make this kind of menu look by hand? (printing special characters shown on left side of the header "STEP 3, Lines, Lines, Lines.")
回答1:
Here's a batch + PowerShell menu maker I've been working on. Set the values in the batch portion, and the PowerShell stuff will auto resize and reposition as needed. When a selection is made, the console buffer restores its former contents, effectively vanishing the menu.
It looks like this:
Here's the code. Save it with a .bat extension.
<# : Batch portion
@echo off & setlocal enabledelayedexpansion
set "menu[0]=Format C:"
set "menu[1]=Send spam to boss"
set "menu[2]=Truncate database *"
set "menu[3]=Randomize user password"
set "menu[4]=Download Dilbert"
set "menu[5]=Hack local AD"
set "default=0"
powershell -noprofile "iex (gc \"%~f0\" | out-string)"
echo You chose !menu[%ERRORLEVEL%]!.
goto :EOF
: end batch / begin PowerShell hybrid chimera #>
$menutitle = "=== MENU ==="
$menuprompt = "Use the arrow keys. Hit Enter to select."
$maxlen = $menuprompt.length + 6
$menu = gci env: | ?{ $_.Name -match "^menu\[\d+\]$" } | %{
$_.Value.trim()
$len = $_.Value.trim().Length + 6
if ($len -gt $maxlen) { $maxlen = $len }
}
[int]$selection = $env:default
$h = $Host.UI.RawUI.WindowSize.Height
$w = $Host.UI.RawUI.WindowSize.Width
$xpos = [math]::floor(($w - ($maxlen + 5)) / 2)
$ypos = [math]::floor(($h - ($menu.Length + 4)) / 3)
$offY = [console]::WindowTop;
$rect = New-Object Management.Automation.Host.Rectangle `
0,$offY,($w - 1),($offY+$ypos+$menu.length+4)
$buffer = $Host.UI.RawUI.GetBufferContents($rect)
function destroy {
$coords = New-Object Management.Automation.Host.Coordinates 0,$offY
$Host.UI.RawUI.SetBufferContents($coords,$buffer)
}
function getKey {
while (-not ((37..40 + 13 + 48..(47 + $menu.length)) -contains $x)) {
$x = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
}
$x
}
# http://goo.gl/IAmdR6
function WriteTo-Pos ([string]$str, [int]$x = 0, [int]$y = 0,
[string]$bgc = [console]::BackgroundColor, [string]$fgc = [Console]::ForegroundColor) {
if($x -ge 0 -and $y -ge 0 -and $x -le [Console]::WindowWidth -and
$y -le [Console]::WindowHeight) {
$saveY = [console]::CursorTop
$offY = [console]::WindowTop
[console]::setcursorposition($x,$offY+$y)
Write-Host $str -b $bgc -f $fgc -nonewline
[console]::setcursorposition(0,$saveY)
}
}
function center([string]$what) {
$what = " $what "
$lpad = " " * [math]::max([math]::floor(($maxlen - $what.length) / 2), 0)
$rpad = " " * [math]::max(($maxlen - $what.length - $lpad.length), 0)
WriteTo-Pos "$lpad $what $rpad" $xpos $line blue yellow
}
function menu {
$line = $ypos
center $menutitle
$line++
center " "
$line++
for ($i=0; $item = $menu[$i]; $i++) {
# write-host $xpad -nonewline
$rtpad = " " * ($maxlen - $item.length)
if ($i -eq $selection) {
WriteTo-Pos " > $item <$rtpad" $xpos ($line++) yellow blue
} else {
WriteTo-Pos " $i`: $item $rtpad" $xpos ($line++) blue yellow
}
}
center " "
$line++
center $menuprompt
1
}
while (menu) {
[int]$key = getKey
switch ($key) {
37 {} # left or up
38 { if ($selection) { $selection-- }; break }
39 {} # right or down
40 { if ($selection -lt ($menu.length - 1)) { $selection++ }; break }
# number or enter
default { if ($key -gt 13) {$selection = $key - 48}; destroy; exit($selection) }
}
}
回答2:
FIX: in order to create a menu like this. you will need to use an editor such as notepad++ open a new notepad ++ file. then goto format and select western europe OEM-US charset.
then simply go here: https://en.wikipedia.org/wiki/Box-drawing_character
and copy paste the symbols you want for your menu in notepad++ and save.
example: Displayed in notepad++ :
echo ╔════════════════════════════╗
echo ║Bill register/database Menu ║
echo ╠════════════════════════════╣
echo ║ 1. -Register a bill ║
echo ║ 2. -Check Bill Info ║
echo ║ 3. Set payment ║
echo ╚════════════════════════════╝
displayed in normal notepad :
echo ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
echo ºBill register/database Menu º
echo ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
echo º 1. -Register a bill º
echo º 2. -Check Bill Info º
echo º 3. Set payment º
echo ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
so as you can see. it works with normal notepad too. but its easier to work with it in notepad++ as it displays what it actually look like.
回答3:
It's not necessary to worry about code pages or file encodings at all.
When you are on windows 10 you can use the Character Set - DEC Line Drawing Mode
This uses ansi-escape sequences to show borders.
The border characters are represented by the characters jklmnqtuvwx
.
for /F "delims=#" %%E in ('"prompt #$E# & for %%E in (1) do rem"') do set "\e=%%E"
REM *** Enable DEC Line Drawing Mode
echo %\e%(0
echo lqqk
echo x x
echo x x
echo mqqnqqk
echo x x
echo mqqj
REM *** Enable ASCII Mode (Default)
echo %\e%(B
The output is
┌──┐
│ │
│ │
└──┼──┐
│ │
└──┘
回答4:
for Notepad with ASCII and CHCP 1250 / CHCP 1252 characters are:
É Í » ş Č Ľ
来源:https://stackoverflow.com/questions/34977487/batch-menu-outlines-and-design