Print without newline?

BlitzMax Forums/BlitzMax Beginners Area/Print without newline?

xlsior(Posted 2010) [#1]
I'm looking at putting together a very basic command line program (under Win32), and was wondering if there's an easy way to re-write a line of text in the console window.

the "Print" command automatically appends a newline so the cursor goes to the next line, but I'm hoping to have a simple progress counter which would require me to update the same line of text a number of times.

Any idea?


Zeke(Posted 2010) [#2]
Extern "win32"
	Function SetConsoleCursorPosition:Int(handle:Int , pos:Int)
End Extern

Function Locate(x:Int , y:Int)
	SetConsoleCursorposition(GetStdHandle( STD_OUTPUT_HANDLE) , y Shl 16+x)
End function


locate 10 , 10
Print "test"
locate 20 , 20
Print "it's working"

For Local i:Int = 0 To 100
	locate 30 , 0
	Print "Count: " + i
	Delay 200
Next

Here you can find other console functions: http://msdn.microsoft.com/en-us/library/ms682073%28VS.85%29.aspx
Note that this wont work when running from IDE, so you must build exe and run that.


xlsior(Posted 2010) [#3]
Very interesting...

Although for it to be usable, I'll need to figure out how to parse the current cursor position through GetconsoleScreenBufferInfo first. :-?

(Blah, I hate pointers... :-? )


xlsior(Posted 2010) [#4]
Ok, with some help of other console code by Jim Brown, I've been able to piece together some code that can also read the current location.

This will print an growing text progressbar on the same line in the active console window:
(After printing the progress bar, it will move the cursor back to the same line so the updated version overwrites the previous one)

Extern "win32"
	Function SetConsoleCursorPosition:Int(handle:Int , pos:Int)
	Function GetConsoleScreenBufferInfo(handle:Int ,sbinfo:Byte Ptr)
End Extern

Function Locate(x:Int , y:Int)
	SetConsoleCursorposition(GetStdHandle( STD_OUTPUT_HANDLE) , y Shl 16+x)
End Function

Global cursorX:Int
Global cursorY:Int
Global progressbar:String

Print
Print

For Local myloop:Int=0 To 100
	console.GetCursorPos(x,y)
	Locate cursorx,cursory-1
	Delay 100
	progressbar:String=""
	For Local myloop2:Int=0 To myloop/4
		progressbar:String=progressbar:String+"|"
	Next
	Print myloop+"% "+Progressbar:String

Next


Global sbinfo:ConsoleScreenBufferInfo=New ConsoleScreenBufferInfo


Type Console
	Const STD_INPUT_HANDLE% = -10
	Const STD_OUTPUT_HANDLE% = -11
	Global hnd% , stdOUT% , stdIN% , ForeColor%,BackColor%
	Global Width%,Height%
	Global sbinfo:ConsoleScreenBufferInfo=New ConsoleScreenBufferInfo
	Function GetCursorPos(x% Var,y% Var)
		GetConsoleScreenBufferInfo GetStdHandle( STD_OUTPUT_HANDLE),Console.sbinfo
		CursorX = Console.sbinfo.CursorXPos 
		CursorY = Console.sbinfo.CursorYPos
	End Function
End Type

Type ConsoleScreenBufferInfo
	Field numCols:Short , numRows:Short
	Field CursorXPos:Short,CursorYPos:Short
	Field Attrs:Short
    	Field sbuffL:Short,sbuffT:Short,sbuffR:Short,sbuffB:Short
	Field MaxWinXSize:Short,MaxWinYSize:Short
End Type

Function SetCursorPos(x%,y%)
	SetConsoleCursorPosition GetStdHandle( STD_OUTPUT_HANDLE), (y Shl 16) + x
End Function


Thanks for the pointer, Zeke! (and Jim, too)


d-bug(Posted 2010) [#5]
Nice one, but whats wrong with WriteStdOut?


xlsior(Posted 2010) [#6]
Nice one, but whats wrong with WriteStdOut?


Absolutely nothing...

...Had I known it existed. :-?

Looks like that one works perfectly to re-write the current line without needing to figure out where it's at:

WriteStdOut "OLD"
WriteStdOut chr$(8)+chr$(8)+chr$(8)  ' chr$(8) = Backspace
WriteStdOut "NEW"


Thanks for the heads up.


EOF(Posted 2010) [#7]
Thanks for the mention. Just a little plug, you can use my console library for doing funky stuff like changing the color attributes, clearing the screen, reading the text buffer ..


If anyone's interested:

DEMO #1

DEMO #2

ConsoleControl.bmx



xlsior(Posted 2010) [#8]
I found that in another thread, but both demos failed for me, always saying it could not create a console... (windows 7, x64)


EOF(Posted 2010) [#9]
Xlsior,
Are you running the demos as GUI build? I'm guessing BlitzMax is already opening the console window. My module handles the whole console window opening and closing affair (Console.Open / Console.Close)


xlsior(Posted 2010) [#10]
No, I wasn't using it as a GUI build -- if that's a pre-requisite then it won't work for me anyway... The entire point is that I'm creating a command line app that I can run straight from a normal DOS window, interacting with other command line applications.

If your library tries to create and conotrol its own console window that would explain the error, although that does mean it won't be usable for my purposes...