Discussion:
clearing screen
(too old to reply)
muta...@gmail.com
2020-10-20 20:37:34 UTC
Permalink
I (believe I) have figured out the behavior of GetConsoleScreenBufferInfo

hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOutput, &csbi);
printf("size char_info is %d\n", sizeof(CHAR_INFO));
printf("%d %d\n", (int)csbi.dwSize.X, (int)csbi.dwSize.Y);
printf("%d %d\n", (int)csbi.dwMaximumWindowSize.X, (int)csbi.dwMaximumWindowSize.Y);
printf("%d %d\n", (int)csbi.srWindow.Right, (int)csbi.srWindow.Bottom);


The window sizes (rows) include the size of the
scrollback buffer. Except for the "Maximum" -
that reflects the actual screen size.

Regardless, when I attempt to write to row 16
like this:

sz.X = 16;
sz.Y = 1;
coord.X = 0;
coord.Y = 0;
rect.Left = 1;
rect.Top = 10; /* was 10 */
rect.Right = 17; /* was 17 */
rect.Bottom = 10; /* was 10 */
ret = WriteConsoleOutput(hConsoleOutput,
mybuf,
sz,
coord,
&rect);

it does actually write to row 16, but it is row 16
of the scrollback buffer, so it's not actually
visible on my screen.

If I run "cls" first, then everything is reset and
everything works as I want.

My question is - is there a call to clear the
screen? Or some other approach?

Besides system("cls");

Thanks. Paul.
R.Wieser
2020-10-21 06:06:10 UTC
Permalink
Muta,
Post by ***@gmail.com
My question is - is there a call to clear the
screen? Or some other approach?
Are you sure you want that ? Clearing whatever you are looking at in the
scrollback buffer I mean.

Just imagine having scrolled back some (to look at previous output), and
than clearing the screen. You than have previous output above *and* below
the currently blank screen. I don't think that is what you want....

If you just want to scroll the previous output up so you have an empty
screen (but can still scroll back) you could try to use
ScrollConsoleScreenBuffer. Another possibility is to try
FillConsoleOutputCharacter. For both you will need the scrollback buffers
dimensions, which you can get with GetConsoleScreenBufferInfo

You can find more Console functions here:
https://docs.microsoft.com/en-us/windows/console/console-functions

Regards,
Rudy Wieser
JJ
2020-10-21 15:00:55 UTC
Permalink
Post by ***@gmail.com
Regardless, when I attempt to write to row 16
[snip]
Post by ***@gmail.com
it does actually write to row 16, but it is row 16
of the scrollback buffer, so it's not actually
visible on my screen.
If I run "cls" first, then everything is reset and
everything works as I want.
The screen buffer is not only for the buffer that is currently displayed in
the console window's viewport. The screen buffer refers to the buffer of the
whole console contents including the old and future lines (which may be
outside of the console window's viewport.

Buffer coordinates are also refer to the coordinates relative to the whole
console contents. Not the coordinates relative to the console window's
viewport. You'll need to calculate the coordinate if you want to refer to a
character within the console window's viewport. i.e. based on the current
scroll position of the buffer.
Post by ***@gmail.com
My question is - is there a call to clear the
screen? Or some other approach?
Besides system("cls");
Thanks. Paul.
There's no single Windows API function for the `CLS` command of a Command
Prompt. Only third party libraries would provide such function.

`CLS` command fills the screen buffer with blank data (i.e. space characters
and the default character attributes), scrolls the screen buffer to the top,
then move the cursor to the start of the screen buffer.
muta...@gmail.com
2020-10-21 21:02:01 UTC
Permalink
Post by JJ
Buffer coordinates are also refer to the coordinates relative to the whole
console contents. Not the coordinates relative to the console window's
viewport. You'll need to calculate the coordinate if you want to refer to a
character within the console window's viewport. i.e. based on the current
scroll position of the buffer.
Thanks, this explains a bit of the problem. My test
program needs to make use of the "Top" variable
to write onto the actual visible screen.

However, when I run micro-emacs (which is what I
am really trying to get to work), it somehow
manages to look like a "cls" was done - I can no
longer scroll the window back to see the old data.
Any idea how it is managing to do that?

If it can manage that, then I shouldn't need to use
the "srWindow.Top" variable, as it should always
be 0/1.

Thanks. Paul.
JJ
2020-10-22 07:48:52 UTC
Permalink
Post by ***@gmail.com
However, when I run micro-emacs (which is what I
am really trying to get to work), it somehow
manages to look like a "cls" was done - I can no
longer scroll the window back to see the old data.
Any idea how it is managing to do that?
If it can manage that, then I shouldn't need to use
the "srWindow.Top" variable, as it should always
be 0/1.
Thanks. Paul.
The scrollbar of a console window will only appear if any side of the screen
buffer dimension is larger than the console window's dimension, in
characters. What micro-emacs did can be done by changing the screen buffer
size dynamically as needed. i.e. set the screen buffer height to match the
viewport height at clear screen; then when a new line is needed and there
are no more room for a new line using current screen buffer height, extend
the screen buffer height as needed.

I don't know about micro-emacs, but keep in mind that not all console
windows are real console windows - especially for third party softwares, and
cross platform softwares. i.e. they're console softwares and have console
window(s), but the console window(s) are actually normal pixel based window,
rather than character based window or native console window. Technically,
their window class name is not `ConsoleWindowClass`, which is Windows'
native console window. IOTW, they're emulated console windows with different
window class name. Such example application that I know are: ConEmu and
ConsoleZ.
muta...@gmail.com
2020-10-23 06:45:03 UTC
Permalink
Post by JJ
The scrollbar of a console window will only appear if any side of the screen
buffer dimension is larger than the console window's dimension, in
characters. What micro-emacs did can be done by changing the screen buffer
size dynamically as needed. i.e. set the screen buffer height to match the
viewport height at clear screen;
Do you see, especially in the ntopen() function here:

https://github.com/pmachapman/memacs/blob/master/src/ntconio.c#L714

how micro-emacs is able to change the screen buffer
size so that I can't scroll back anymore?

Thanks. Paul.
JJ
2020-10-23 13:18:29 UTC
Permalink
Post by ***@gmail.com
https://github.com/pmachapman/memacs/blob/master/src/ntconio.c#L714
how micro-emacs is able to change the screen buffer
size so that I can't scroll back anymore?
Thanks. Paul.
No. That function doesn't actually do that. If it does, it would be a code
somewhere else.
muta...@gmail.com
2020-10-26 22:11:07 UTC
Permalink
Post by JJ
Post by ***@gmail.com
how micro-emacs is able to change the screen buffer
size so that I can't scroll back anymore?
No. That function doesn't actually do that. If it does, it would be a code
somewhere else.
I thought of a different approach - do you know the
name of the Win32 function that does a screen
resize so that you can't scroll back anymore?

Thanks. Paul.
JJ
2020-10-28 09:26:48 UTC
Permalink
Post by ***@gmail.com
I thought of a different approach - do you know the
name of the Win32 function that does a screen
resize so that you can't scroll back anymore?
Thanks. Paul.
Use a third party library.
R.Wieser
2020-10-28 11:17:14 UTC
Permalink
Muta,
do you know the name of the Win32 function that
does a screen resize so that you can't scroll back
anymore?
You already got a link to the webpage naming all the functions related to
the Console. Why don't you take a peek at them yourself and than you tell
us which one(s) you think are likely candidates for it ?

I have never tried to clear that screenbuffer, as I always automatically
directly switch to full-screen 80x25 DOS style mode (Win XP). So, I would
need to make a guess myself. Though I think I see at least two likely
candidates ...

Regards,
Rudy Wieser
muta...@gmail.com
2020-10-29 07:38:22 UTC
Permalink
Ok, I finally figured out how micro-emacs is
managing to prevent scroll-up.

It is using this to set the position of the cursor:
SetConsoleCursorPosition(hConsoleOutput, dwCursorPosition);

and if you set that to 1/1, you can only scroll up
one line, so they must be setting it to 0.

And what that means is that when micro-emacs
exits, the cursor is placed way up in the screen
buffer, and so the command prompt sees a
whole lot of rubbish from old commands.

Now that I (believe I) know what is happening,
I think I need to fill the screen buffer with
blanks so that junk isn't seen, and that should
be good enough. I'll ponder it some more.

Thanks all for your help.

BFN. Paul.
muta...@gmail.com
2020-11-21 03:24:16 UTC
Permalink
Here is the code that I ended up using, which works
on both Windows 10 and HX DOS (previously I used
-1 for length which didn't work on HX DOS):

CONSOLE_SCREEN_BUFFER_INFO Console;
COORD dwCursorPosition;
DWORD written;

/* Position cursor at the top of buffer */
dwCursorPosition.X = 0;
dwCursorPosition.Y = 0;
SetConsoleCursorPosition(hOutput, dwCursorPosition);

/* get a ptr to the output screen buffer */
GetConsoleScreenBufferInfo(hOutput, &Console);

/* clear screen */
FillConsoleOutputCharacter(hOutput,
' ',
(DWORD)Console.dwSize.Y * Console.dwSize.X,
dwCursorPosition,
&written);

FillConsoleOutputAttribute(hOutput,
FOREGROUND_BLUE
| FOREGROUND_GREEN
| FOREGROUND_RED,
(DWORD)Console.dwSize.Y * Console.dwSize.X,
dwCursorPosition,
&written);

Then this is set correctly (thanks to the positioning to 0/0):

/* let MicroEMACS know our starting screen size */
term.t_nrow = Console.srWindow.Bottom;
term.t_ncol = Console.srWindow.Right + 1;


BFN. Paul.

Loading...