Programmatically getting the console width in character

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
#1
I have a console (C++) program that I wrote that can produce a fairly large number of different error/warning messages, some of which can be quite long. I find it annoying that when lines are too long, they "wrap" to the next line, often (usually!) in the middle of a word or file name. So I set out to fix this by getting the width of the console in characters and wrapping messages to new lines at appropriate blanks in the line. The way I get the width of the console in characters is to use the Windows API function GetConsoleScreenBufferInfo, which fills in a GetConsoleScreenBufferInfo structure with the appropriate information (the console width appears in the dwSize.X member of the structure). This works just fine in plain old Microsoft DOS (which I don't use very often), but when I execute the code in TCC the dwSize.X member of the structure contains (the useless!!!) number "52427"(?????). This program is/will be used by a number of people other than me, all of whom still use Plain Old DOS (despite my urgings for them to upgrade to something better!!!) and the program works just fine for them. I have to say that I find it somewhat ironic that the only person that the program doesn't work well for is me, and I wrote the program. I will also acknowledge that I could work around the problem by just hard-coding a reasonable number into the program, but I really hate doing that because it only works well if the user is using the same font as I am (and I use a very large font because of bad eyesight). I would guess that you can anticipate my question: How do you get the width of the console window (in characters) in TCC?
 
Aug 9, 2009
133
0
#2
LoL i hate the way your message in this forum comes over "fill to maximum" screen width it makes
it HARD TO READ!




>
> I have a console (C++) program that I wrote that can produce a fairly large number of different
> error/warning messages, some of which can be quite long. I find it annoying that when lines are too
> long, they "wrap" to the next line, often (usually!) in the middle of a word or file name. So I set
> out to fix this by getting the width of the console in characters and wrapping messages to new
> lines at appropriate blanks in the line. The way I get the width of the console in characters is to
> use the Windows API function *GetConsoleScreenBufferInfo*, which fills in a
> *GetConsoleScreenBufferInfo* structure with the appropriate information (the console width appears
> in the *dwSize.X* member of the structure). This works just fine in plain old Microsoft DOS (which
> I don't use very often), but when I execute the code in TCC the dwSize.X member of the structure
> contains (the useless!!!) number "52427"(?????). This program is/will be used by a number of people
> other than me, all of whom still use Plain Old DOS (*despite* my urgings for them to upgrade to
> something better!!!) and the program works just fine for them. I have to say that I find it
> somewhat ironic that the only person that the program doesn't work well for is *me*, and I *wrote*
> the program. I will also acknowledge that I could work around the problem by just hard-coding a
> reasonable number into the program, but I really hate doing that because it only works well if the
> user is using the same font as I am (and I use a very large font because of bad eyesight). I would
> guess that you can anticipate my question: How do you get the width of the console window (in
> characters) in TCC?
>
>
>
>
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
3,429
40
Albuquerque, NM
prospero.unm.edu
#3
I have a console (C++) program that I wrote that can produce a fairly large number of different error/warning messages, some of which can be quite long. I find it annoying that when lines are too long, they "wrap" to the next line, often (usually!) in the middle of a word or file name. So I set out to fix this by getting the width of the console in characters and wrapping messages to new lines at appropriate blanks in the line. The way I get the width of the console in characters is to use the Windows API function GetConsoleScreenBufferInfo, which fills in a GetConsoleScreenBufferInfo structure with the appropriate information (the console width appears in the dwSize.X member of the structure). This works just fine in plain old Microsoft DOS (which I don't use very often), but when I execute the code in TCC the dwSize.X member of the structure contains (the useless!!!) number "52427"(?????). This program is/will be used by a number of people other than me, all of whom still use Plain Old DOS (despite my urgings for them to upgrade to something better!!!) and the program works just fine for them. I have to say that I find it somewhat ironic that the only person that the program doesn't work well for is me, and I wrote the program. I will also acknowledge that I could work around the problem by just hard-coding a reasonable number into the program, but I really hate doing that because it only works well if the user is using the same font as I am (and I use a very large font because of bad eyesight). I would guess that you can anticipate my question: How do you get the width of the console window (in characters) in TCC?
GetConsoleScreenBufferInfo() works fine for me. Have you tried Vince's 4CONSOLE plugin? ftp://vefatica.net/4plugins/4console.zip It has a console-width function which also works fine under Take Command. AFAIK, it also calls GetConsoleScreenBufferInfo().
 

rconn

Administrator
Staff member
May 14, 2008
10,210
86
#4
Your message is unfortunately mostly incomprehensible to me. Is this a DOS app or a Windows console app? You say "DOS" several times, but you're also referring to "GetConsoleScreenBufferInfo", which is a Windows console API.

TCC does *nothing* to the console size; that's strictly controlled by Windows.

If you're running TCC in a TCMD tab window, TCMD will ask Windows to resize the (hidden) TCC console to the width of the tab window.

But in all cases, the values returned by GetConsoleScreenBufferInfo are set by Windows, not by TCC. I suspect you've got an error in your API call -- the value you're seeing is a typical C++ uninitialized variable. If you'll post the appropriate excerpt from your code it will be easier to diagnose the problem.
 
#5
I use either .srWindow.Right - .srWindow.Left or .dwSize.X depending on
whether I want just the visible area or the entire scrollable window, in my
program.

On Wed, Jan 5, 2011 at 06:03, Charles Dye <> wrote:


> ---Quote (Originally by mathewsdw)---
> I have a console (C++) program that I wrote that can produce a fairly large
> number of different error/warning messages, some of which can be quite long.
> I find it annoying that when lines are too long, they "wrap" to the next
> line, often (usually!) in the middle of a word or file name. So I set out to
> fix this by getting the width of the console in characters and wrapping
> messages to new lines at appropriate blanks in the line. The way I get the
> width of the console in characters is to use the Windows API function
> *GetConsoleScreenBufferInfo*, which fills in a *GetConsoleScreenBufferInfo*
> structure with the appropriate information (the console width appears in the
> *dwSize.X* member of the structure). This works just fine in plain old
> Microsoft DOS (which I don't use very often), but when I execute the code in
> TCC the dwSize.X member of the structure contains (the useless!!!) number
> "52427"(?????). This program is/will be used by a number of people other
> than me, all of whom still use Plain Old DOS (*despite* my urgings for them
> to upgrade to something better!!!) and the program works just fine for them.
> I have to say that I find it somewhat ironic that the only person that the
> program doesn't work well for is *me*, and I *wrote* the program. I will
> also acknowledge that I could work around the problem by just hard-coding a
> reasonable number into the program, but I really hate doing that because it
> only works well if the user is using the same font as I am (and I use a very
> large font because of bad eyesight). I would guess that you can anticipate
> my question: How do you get the width of the console window (in characters)
> in TCC?
> ---End Quote---
> GetConsoleScreenBufferInfo() works fine for me. Have you tried Vince's
> 4CONSOLE plugin?
> ftp://barnyard.syr.edu/pub/vefatica/4plugins/4console.zip It has a
> console-width function which also works fine under Take Command. AFAIK, it
> also calls GetConsoleScreenBufferInfo().
>
>
>
>
>


--
Jim Cook
2010 Sundays: 4/4, 6/6, 8/8, 10/10, 12/12 and 5/9, 9/5, 7/11, 11/7.
Next year they're Monday.
 
Dec 2, 2008
212
2
Canada
#6
I think what he is try to say is that, he uses a command line compiler that generates errors to the TCC or DOS console that looks messy and hard to read. I think he wants to capture the output from the compiler (redirect stdout and stderr using a pipe) and process it using his program. I think he is asking how his program (in C++, I assume) would determine the width of the TCC console running the compile.

Craig
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
3,429
40
Albuquerque, NM
prospero.unm.edu
#7
Your message is unfortunately mostly incomprehensible to me. Is this a DOS app or a Windows console app? You say "DOS" several times, but you're also referring to "GetConsoleScreenBufferInfo", which is a Windows console API.
The misuse of "DOS" to mean "console" is so widespread as to be ineradicable. I blame Microsoft.

(I was once accused of "using DOS" while running bash in a telnet session.)
 
#8
---- Original Message ----
From: mathewsdw
| I have a console (C++) program that I wrote that can produce a fairly
| large number of different error/warning messages, some of which can
| be quite long.
| ...
| the Windows API function GetConsoleScreenBufferInfo
| ...
| (the console width appears in the dwSize.X member of the structure).
| This works just fine in plain old Microsoft DOS (which I don't use
| very often), but when I execute the code in TCC the dwSize.X member
| of the structure contains (the useless!!!) number "52427"(?????).
First, when you use MS-DOS, you don't use Windows. They are different operating systems! Did you mean the command processor CMD.EXE which is bundled with Windows? I presume the latter...
Second, when you use TCC, is it in a TCMD tab, or is it a stand-alone window?
Third, is the command that starts your C++ program from TCC, the same as the command that starts it from CMD.EXE?
Fourth, what is that command?
Fifth, what version of Windows and of TCC are you dealing with?
--
Steve
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
3,429
40
Albuquerque, NM
prospero.unm.edu
#9
---- Original Message ----
First, when you use MS-DOS, you don't use Windows. They are different operating systems! Did you mean the command processor CMD.EXE which is bundled with Windows? I presume the latter...
Second, when you use TCC, is it in a TCMD tab, or is it a stand-alone window?
Third, is the command that starts your C++ program from TCC, the same as the command that starts it from CMD.EXE?
Fourth, what is that command?
Fifth, what version of Windows and of TCC are you dealing with?
Sixth: Are you checking the return code from GetConsoleScreenBufferInfo()? Zero indicates an error, in which case the contents of the structure may be uninitialized garbage as Rex suggests.

Seventh: Are you certain that the handle you are passing is in fact a console handle? Or are you perhaps passing stdout or stderr, on the assumption that these are usually to the console?
 
#10
On Wed, 05 Jan 2011 02:23:01 -0500, mathewsdw <> wrote:

|How do you get the width of the console window (in characters) in TCC?

Any Win32 console app gets the width of the console to which it's writing in the
same way.

Code:
CONSOLE_SCREEN_BUFFER_INFO csbi;

if ( !GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE) , &csbi) )
{
	/* GCSBI() fails when output has been redirected */
}
else
{
	wprintf(L"The buffer is %u wide and the window is %u wide.\n",
		csbi.dwSize.X,
		csbi.srWindow.Right - csbi.srWindow.Left + 1);
}
I have used GetConsoleScreenBufferInfo() hundreds of times and I have never seen
it fail except in the case of redirected output.

Wrapping occurs at csbi.dwSize.X, not at the right edge of the window (although
those two places are often the same).
 
#12
LoL i hate the way your message in this forum comes over "fill to maximum" screen width it makes
it HARD TO READ!
Since I have no clue why it's doing that, I have no clue how to fix it! (I will note that there may be a button/menu option/etc. to fix this, since I have very poor eyesight I can't find it, and I've looked...)
 
Aug 9, 2009
133
0
#13
Your looking for "Mail formatting Line wrap" depending on what client your
using!



> Subject: RE: [Support-t-2516] Re: Programmatically getting the console
> width in character
>
>
> ---Quote (Originally by Kachupp)---
> LoL i hate the way your message in this forum comes over "fill to
> maximum" screen width it makes
> it HARD TO READ!
> ---End Quote---
>
> Since I have *no clue* why it's doing that, I have *no clue* how to
> fix it! (I will note that there *may* be a button/menu option/etc.
> to fix this, since I have very poor eyesight I can't find it, and
> I've looked...)
>
>
>
>
 
#14
On Wed, 05 Jan 2011 13:35:54 -0500, Charles Dye <> wrote:

|Well, maybe not quite the same way. I've been opening my own console handle so I don't have to worry about redirection.

How? ... with CreateFile(L"CONOUT$", ...);
 
#15
I think what he is try to say is that, he uses a command line compiler that generates errors to the TCC or DOS console that looks messy and hard to read. I think he wants to capture the output from the compiler (redirect stdout and stderr using a pipe) and process it using his program. I think he is asking how his program (in C++, I assume) would determine the width of the TCC console running the compile.

Craig
First, this is a reply to several of the replies to my original question. Secondly, somebody made a reference to "DOS" app vs. "Windows" app and I have no idea whatsoever about what he is referring to - my app is a Windows app (making Windows API calls) that runs in the console and has no Windows GUI at all. I have no idea what a significant and useful "DOS" program would be that didn't make Windows API calls. Thirdly, I am doing the "right" thing because the code works absolutely as it should when run in a standard DOS (cmd.exe) window - except when the output is being redirected to a file or the "more" command - and in those cases the API function returns a ridiculous value that I can identify as such and supply a reasonable "default" value - which is what is happening in every case under TCMD/TCC, and my "reasonable default value" is something that is appropriate for cmd.exe, and not (with my selected window size and font) specifically TCMD/TCC. Lastly, as far as I can see nobody accepted/commented on the fact that this API function is not returning sensible values under TCMD/TCC (and I am not redirecting the output of the command to anything.) I am supplying the function with "STD_OUT_HANDLE" as its parameter, and it also doesn't return a sensible value if I try to use it with "STD_ERROR_HANDLE" or "STD_INPUT_HANDLE", and again, I am not redirecting the output of the command to anything in these tests. So, finally as my last comment on this issue, I am running TCC 12.00.42 under Windows 7 6.1.7600. It would appear that nobody knows the answer to this quiestion because nobody else is having this problem.

- Dan
 
#17
If I remember correctly, I had to translate the handles you mention. When I get near my source again I will let you know my code sequence that works for me.

Sent from Cookie's iPhone
Jim Cook

On Jan 5, 2011, at 18:12, mathewsdw <> wrote:


> ---Quote (Originally by cgunhouse)---
> I think what he is try to say is that, he uses a command line compiler that generates errors to the TCC or DOS console that looks messy and hard to read. I think he wants to capture the output from the compiler (redirect stdout and stderr using a pipe) and process it using his program. I think he is asking how his program (in C++, I assume) would determine the width of the TCC console running the compile.
>
> Craig
> ---End Quote---
>
> First, this is a reply to *several* of the replies to my original question. Secondly, somebody made a reference to "DOS" app vs. "Windows" app and I have *no idea whatsoever* about what he is referring to - my app is a Windows app (making Windows API calls) that runs in the console and has no Windows GUI at all. I have *no idea* what a significant and useful "DOS" program would be that *didn't* make Windows API calls. Thirdly, I am doing the "right" thing because the code works *absolutely as it should* when run in a standard DOS (cmd.exe) window -* except* when the output is being redirected to a file or the "more" command - and in those cases the API function returns a ridiculous value that I can identify as such and supply a reasonable "default" value - which is what is happening in *every case* under TCMD/TCC, and my "reasonable default value" is something that is appropriate for cmd.exe, and *not* (with my selected window size and font) specifically TCMD/TCC. Lastly, as far as I can see nobody accepted/commented on the fact that this API function *is not returning sensible values* under TCMD/TCC (and I am *not* redirecting the output of the command to *anything*.) I am supplying the function with "STD_OUT_HANDLE" as its parameter, and it also doesn't return a sensible value if I try to use it with "STD_ERROR_HANDLE" or "STD_INPUT_HANDLE", and again, I am *not* redirecting the output of the command to *anything* in these tests. So, finally as my last comment on this issue, I am running TCC 12.00.42 under Windows 7 6.1.7600. It would appear that nobody knows the answer to this quiestion because nobody else is having this problem.
>
> - Dan
>
>
>
>
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
3,429
40
Albuquerque, NM
prospero.unm.edu
#18
Lastly, as far as I can see nobody accepted/commented on the fact that this API function is not returning sensible values under TCMD/TCC (and I am not redirecting the output of the command to anything.)


Are you checking the return value of GetConsoleScreenBufferInfo()? Because if it returns 0, the strange values you're seeing were not returned by the function -- they are just whatever happened to be in the structure before you called it.

I am supplying the function with "STD_OUT_HANDLE" as its parameter, and it also doesn't return a sensible value if I try to use it with "STD_ERROR_HANDLE" or "STD_INPUT_HANDLE", and again, I am not redirecting the output of the command to anything in these tests.
Are you passing STD_OUT_HANDLE, or GetStdHandle(STD_OUT_HANDLE) ?
 
#19
On Wed, 05 Jan 2011 21:12:34 -0500, mathewsdw <> wrote:

|First, this is a reply to *several* of the replies to my original question. Secondly, somebody made a reference to "DOS" app vs. "Windows" app and I have *no idea whatsoever* about what he is referring to - my app is a Windows app (making Windows API calls) that runs in the console and has no Windows GUI at all. I have *no idea* what a significant and useful "DOS" program would be that *didn't* make Windows API calls. Thirdly, I am doing the "right" thing because the code works *absolutely as it should* when run in a standard DOS (cmd.exe) window -* except* when the output is being redirected to a file or the "more" command - and in those cases the API function returns a ridiculous value that I can identify as such and supply a reasonable "default" value - which is what is happening in *every case* under TCMD/TCC, and my "reasonable default value" is something that is appropriate for cmd.exe, and *not* (with my selected window size and font) specifically TCMD/TCC. Lastly, as far as |I can see nobody accepted/commented on the fact that this API function *is not returning sensible values* under TCMD/TCC (and I am *not* redirecting the output of the command to *anything*.) I am supplying the function with "STD_OUT_HANDLE" as its parameter, and it also doesn't return a sensible value if I try to use it with "STD_ERROR_HANDLE" or "STD_INPUT_HANDLE", and again, I am *not* redirecting the output of the command to *anything* in these tests. So, finally as my last comment on this issue, I am running TCC 12.00.42 under Windows 7 6.1.7600. It would appear that nobody knows the answer to this quiestion because nobody else is having this problem.

There is nothing "DOS" about CMD.EXE. It's simply a command processor just like
TCC (and BASH, and TCSH, and POWER SHELL, et al.); they all just use a console
(supplied by CSRSS.EXE) just like TCC does.

If it's a Windows CUI (console user interface) EXE then it's not "under" TCC.
It's running independently of TCC; it merely shares a console with TCC. TCC
simply can't have anything to do with how GetConsoleScreenBufferInfo() works.

There's no such thing as STD_OUT_HANDLE. And STD_OUTPUT_HANDLE is just a
pseudo-handle. With GetConsoleScreenBufferInfo() you should be using
GetStdHandle(STD_OUTPUT_HANDLE) as the first parameter.

Are you checking to see if GetConsoleScreenBufferInfo() succeeds (returns TRUE)?

You didn't mention TCMD before. Here, that seems to introduce no problems.

The info below (identical in stand-alone TCC and TCC-in-TCMD) is provided by
GetConsoleScreenBufferInfo() in a Win32 CUI EXE.

Code:
Console info (chars)

    Current:         80 x 24
    Buffer:          80 x 5000