Trick: Scroll down one line during "set /p" for aesthetics.

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Trick: Scroll down one line during "set /p" for aesthetics.

#1 Post by orange_batch » 31 May 2011 19:56

It's a way to keep a blank line between the line asking for input, and the bottom of the Command Prompt window once it starts to scroll, for purely aesthetic reasons. I spent some time thinking about a solution to this, as an alternative to nitt's CURSOR tool. I tried all combinations of using the %bs% / !bs! / %lf% / !lf! backspace/line feed-type tricks with no success. Once Command Prompt goes to a new line with static text, it will not return! I'm totally willing to be proven wrong though.

This takes advantage of Command Prompt's input buffer. You might notice you can press keys while a batch process is running, and they will be placed in the input of the following set /p. So, this inputs 80 space characters (the default max width of a single line in Command Prompt) to scroll the window to the next line, then clears it with the escape key.

Why not do this just before set /p is executed? Because the window requires focus for WshShell's SendKeys method, and using the AppActivate method is intrusive and more prone to error.

Edit: I realized, at expected focus times the window might not have focus for any particular reason, as the Windows OS allows things to start without focus. So, AppActivate works well under these circumstances. It also prevents missed SendKeys if you press enter after input, and click away from the window really fast.

space.vbs (edit added a.appactivate wscript.arguments(0))

Code: Select all

set a=wscript.createobject("wscript.shell")
a.appactivate wscript.arguments(0)
a.sendkeys "                                                                                {esc}"

Example batch: (edit added title stuff and "%title%" argument)

Code: Select all

@rem Initialization. Start the batch off with the key presses, while the window has focus.
@echo off
set title=Unique Window Name
title %title%
cscript space.vbs //nologo "%title%"

:: Get the Command Prompt scrolling.
for /l %%x in (1,1,25) do echo:

:: Do a delay as if we are processing something.
ping 0 -n 3 >nul

:: Asking for user input. See, did it work?
set /p "var=Input: "

:: Must immediately follow set /p, for the next set /p encountered.
cscript space.vbs //nologo "%title%"

:: Let's delay again, as if we are processing something.
ping 0 -n 3 >nul

:: Asking for user input again. You can see how this continues to work...
set /p "var=Input: "

:: Following again.
cscript space.vbs //nologo "%title%"

:: But, it could override pause. Read below.
pause
exit


While in my tests I had no problem with running the cscript immediately before a pause command, it's possible the keys may override the pause. To be totally safe, you need to remove the last cscripts before any pauses. This shouldn't be a problem though, because pause ignores the input buffer, and Command Prompt doesn't proceed until the Windows scripting host closes, having sent all key presses.
Last edited by orange_batch on 02 Jun 2011 02:06, edited 7 times in total.

nitt
Posts: 218
Joined: 22 Apr 2011 02:43

Re: Trick: Scroll down one line during "set /p" for aestheti

#2 Post by nitt » 31 May 2011 20:03

Wait so it sticks the input at the bottom? That's useful, I guess.

BTW, you don't need

Code: Select all

ping -n 3 -i 1 127.0.0.1>nul


to delay something. Just use

Code: Select all

ping 0 -n 3 > nul


The IP doesn't matter, so you can just set it as 0.

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Trick: Scroll down one line during "set /p" for aestheti

#3 Post by orange_batch » 31 May 2011 20:04

No, it pushes any input lines away from the bottom of the Command Prompt window once it starts to scroll. Thanks for the ping tip, I never cared much because I use vbscript sleep.

nitt
Posts: 218
Joined: 22 Apr 2011 02:43

Re: Trick: Scroll down one line during "set /p" for aestheti

#4 Post by nitt » 31 May 2011 20:07

orange_batch wrote:No, it pushes any input lines away from the bottom of the Command Prompt window once it starts to scroll. Thanks for the ping tip, I never cared much because I use vbscript sleep.


Welcome, but I'm still confused at what this does. Doesn't it already push the lines when it scrolls down?

I apologize, I'm not the brightest bulb in the haystack.

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Trick: Scroll down one line during "set /p" for aestheti

#5 Post by orange_batch » 31 May 2011 20:12

Normal Command Prompt flow/scrolling, impossible to put a blank line underneath a set /p:

Image


My solution:

Image

You could add however many lines you want by changing the number of spaces in space.vbs.
The formula would be: (max single line width) x (number of lines)

Pointless really, but it fixes the look of a program I've been working on. I always put a new line after any text I write, so it looks uniform. But I was unable to do this for when it asks for input until now.

nitt
Posts: 218
Joined: 22 Apr 2011 02:43

Re: Trick: Scroll down one line during "set /p" for aestheti

#6 Post by nitt » 31 May 2011 20:18

Oh, so you have a flowing input with a space underneath... I didn't even know there was flowing input.

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: Trick: Scroll down one line during "set /p" for aestheti

#7 Post by Ed Dyreen » 31 May 2011 21:07

So how do you do it, I mean placing a line under set?

I know the linefeed, I don't know the backspace.

How is a backspace created &why does it work the way it works ?

I mean you have put a line under set, yet the cursor is blinking on a position other than the end :o That's not possible, but it is :?

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Trick: Scroll down one line during "set /p" for aestheti

#8 Post by orange_batch » 01 Jun 2011 01:25

Re-read this line:
I tried all combinations of using the %bs% / !bs! / %lf% / !lf! backspace/line feed-type tricks with no success.

It has nothing to do with that, because it doesn't work. As I said, it's impossible to go up rows in Command Prompt. It is possible to go back columns though, using the backspace technique, but it's irrelevant to this thread. Use the search tool for that, jeb posted on it, it's the first result.

I explained this trick in my first post, but I'll explain it simply.

Make any batch file and echo repeatedly until Command Prompt starts to scroll, as a normal batch with lots of echos would cause. Then do set /p var=whatever. It's stuck on the bottom. But if you fill up the input line until it reaches the end of the line, it will wrap, which causes Command Prompt to scroll down again. If you press escape, it will clear your current input. All my code does is use vbscript's WshShell object's SendKeys method to type the required amount of characters (spaces) to cause the text wrap (followed by escape to clear the line), which causes Command Prompt to scroll down a line. SendKeys types the line to the active window, so we need to make sure the Command Prompt window is active when that line is typed. So, it's done at expected focus times - that is, on initial load, and right after entering input. Lastly, the reason it works is due to Command Prompt's input buffer. You can type anything during processing, and it will still be written on the first set /p var=whatever's line of input.

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Trick: Scroll down one line during "set /p" for aestheti

#9 Post by jeb » 01 Jun 2011 16:28

orange_batch wrote:As I said, it's impossible to go up rows in Command Prompt. It is possible to go back columns though, using the backspace technique, but it's irrelevant to this thread. Use the search tool for that, jeb posted on it, it's the first result.

8) Nothing is impossible, you currently show me a simpler way I thought about.

I figured out a way to bring the cursor up with multiple instances of cmd.exe in one window, but currently it works only with the user.
I never thought about using the set /p, but now ... :D

Code: Select all

@echo off
setlocal Enabledelayedexpansion
call :BL.String.CreateDEL_ESC
set LF=^


rem ** Two lines empty
if "%~1"=="1" goto :eins
if "%~1"=="2" goto :zwei
rem start /b %~0 1

cls
%0 1 | %0 2
echo --- ENDE
exit /b

goto :eof


:eins
set /p "x=[Press NOW one key and wait]" > con
for /L %%n in (1,1,20) do (
 (echo new%%n   )
) > con
goto :eof

:zwei
ping 127.0.0.1  -n 4 > nul
echo( > con
for /L %%n in (1,1,20) do (
 echo ....... This is line%%n
) > con

<nul set /p ".=Now press ESC and then ENTER!esc!"
rem !LF! and !ESC! seems to fail here, I can't redirect them to the "SET /p"
goto :eof


Ok, not perfect, but I can move the cursor up :!:

jeb

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Trick: Scroll down one line during "set /p" for aestheti

#10 Post by orange_batch » 01 Jun 2011 16:39

Haha, I'm not sure about that jeb.

I will say however, this problem relates to during set /p only. It's easy to create echoing/logging/refreshing functions, as I have in my systems for managing console output.

Post Reply