Page 1 of 1

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

Posted: 31 May 2011 19:56
by orange_batch
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.

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

Posted: 31 May 2011 20:03
by nitt
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.

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

Posted: 31 May 2011 20:04
by orange_batch
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.

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

Posted: 31 May 2011 20:07
by nitt
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.

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

Posted: 31 May 2011 20:12
by orange_batch
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.

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

Posted: 31 May 2011 20:18
by nitt
Oh, so you have a flowing input with a space underneath... I didn't even know there was flowing input.

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

Posted: 31 May 2011 21:07
by Ed Dyreen
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 :?

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

Posted: 01 Jun 2011 01:25
by orange_batch
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.

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

Posted: 01 Jun 2011 16:28
by jeb
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

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

Posted: 01 Jun 2011 16:39
by orange_batch
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.