Discussion:
WriteConsoleOutput
(too old to reply)
Paul Edwards
2020-02-04 09:06:28 UTC
Permalink
Hi folks.

Any idea why the below code is printing:

C:\devel\develop>winctest
168 9001
168 44
ret is 1

1 = success, yet doesn't write anything
visible to the console window?

Also, any idea why uemacs 4.0 source code
is using dwSize instead of dwMaximumWindowSize
so should be getting the wrong values, ie the
entire scrollback buffer instead of the actual
screen size?

Thanks. Paul.



#include <stdio.h>

#include <windows.h>

int main(void)
{
HANDLE hConsoleOutput;
static CONSOLE_SCREEN_BUFFER_INFO csbi;
CHAR_INFO mybuf[16];
int x;
int y;
COORD sz;
COORD coord;
SMALL_RECT rect;
int ret;

hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOutput, &csbi);
printf("%d %d\n", (int)csbi.dwSize.X, (int)csbi.dwSize.Y);
printf("%d %d\n", (int)csbi.dwMaximumWindowSize.X, (int)csbi.dwMaximumWindowSize.Y);
for (x = 0; x < 16; x++)
{
mybuf[x].Char.AsciiChar = 'Z';
mybuf[x].Attributes = 0x7;
}
sz.X = 1;
sz.Y = 16;
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);
printf("ret is %d\n", ret);
return (0);
}
R.Wieser
2020-02-04 10:06:21 UTC
Permalink
Paul,
1 = success, yet doesn't write anything visible to the console window?
Take a look here:

https://docs.microsoft.com/en-us/windows/console/reading-and-writing-blocks-of-characters-and-attributes

It looks like that StdOut /isn't/ the first argument of WriteConsoleOutput.
Which stands to reason: StdOut is a (file) stream, not an array of
characters & attributes.

Regards,
Rudy Wieser
JJ
2020-02-04 16:41:24 UTC
Permalink
Post by Paul Edwards
Hi folks.
C:\devel\develop>winctest
168 9001
168 44
ret is 1
1 = success, yet doesn't write anything
visible to the console window?
Also, any idea why uemacs 4.0 source code
is using dwSize instead of dwMaximumWindowSize
so should be getting the wrong values, ie the
entire scrollback buffer instead of the actual
screen size?
Thanks. Paul.
#include <stdio.h>
#include <windows.h>
int main(void)
{
HANDLE hConsoleOutput;
static CONSOLE_SCREEN_BUFFER_INFO csbi;
CHAR_INFO mybuf[16];
int x;
int y;
COORD sz;
COORD coord;
SMALL_RECT rect;
int ret;
hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOutput, &csbi);
printf("%d %d\n", (int)csbi.dwSize.X, (int)csbi.dwSize.Y);
printf("%d %d\n", (int)csbi.dwMaximumWindowSize.X, (int)csbi.dwMaximumWindowSize.Y);
for (x = 0; x < 16; x++)
{
mybuf[x].Char.AsciiChar = 'Z';
mybuf[x].Attributes = 0x7;
}
sz.X = 1;
sz.Y = 16;
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);
printf("ret is %d\n", ret);
return (0);
}
Your source buffer size is incorrect. sz.X=1 and sz.Y=16 means 1 column 16
rows source buffer. i.e. a vertical layout data. But your console buffer
retangle is defined as (1,10)-(17,10) which is 17 columns 1 row. i.e. a
horizontal layout data. That's not the same data layout. The function simply
copies the data. It can not transform the layout of the data.

If you intend to write the text horizontally, fix the source buffer size to
sz.X=16 and sz.Y=1. Console buffer rectangle can be larger than the source
buffer rectangle, but can not be smaller.

If you intend to write the text vertically, fix the console buffer rectangle
to a vertical layout. e.g. (1,10)-(1,25)
Paul Edwards
2020-02-04 20:12:39 UTC
Permalink
Post by JJ
If you intend to write the text horizontally, fix the source buffer size to
sz.X=16 and sz.Y=1.
Thanks! That change was all I needed to get
it to work. It was happy to take a handle
to STDOUT, which is what micro-emacs 4.00
does too.

However, there's still a problem. If the
command prompt is at the bottom of the
screen, when I run my program, it sometimes
writes to line 2 instead of line 10, and
sometimes writes nothing.

If the command prompt is anywhere else it
seems to correctly work, writing to line 10.

Any idea on that one? Latest code below.

Thanks. Paul.




#include <stdio.h>

#include <windows.h>

int main(void)
{
HANDLE hConsoleOutput;
static CONSOLE_SCREEN_BUFFER_INFO csbi;
CHAR_INFO mybuf[16];
int x;
int y;
COORD sz;
COORD coord;
SMALL_RECT rect;
int ret;

hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOutput, &csbi);
/* printf("%d %d\n", (int)csbi.dwSize.X, (int)csbi.dwSize.Y);
printf("%d %d\n", (int)csbi.dwMaximumWindowSize.X, (int)csbi.dwMaximumWindowSize.Y); */
for (x = 0; x < 16; x++)
{
mybuf[x].Char.AsciiChar = 'Z';
mybuf[x].Attributes = x;
}
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);
for (;;) ;
printf("ret is %d\n", ret);
return (0);
}
JJ
2020-02-05 22:07:30 UTC
Permalink
Post by Paul Edwards
However, there's still a problem. If the
command prompt is at the bottom of the
screen, when I run my program, it sometimes
writes to line 2 instead of line 10, and
sometimes writes nothing.
If the command prompt is anywhere else it
seems to correctly work, writing to line 10.
Any idea on that one? Latest code below.
Keep in mind that the number of lines in the screen buffer can be longer
than the number of lines in the console window. So, if the console window is
80x25, and the screen buffer has enlarged to 80x50 (thus showing the
vertical scrollbar on the console window), line 10 of the screen buffer
would be off screen and no longer within the console window's viewport.
Notice that the rectangle (the `rect` structure) is for the screen buffer,
instead of the console window's viewport. You'll need to scroll the console
window up to see the written text at line 10 of the screen buffer.
Loading...