Recent

Author Topic: [SOLVED]Access private functions in CRT unit, trying to get console width  (Read 1872 times)

old_DOS_err

  • New Member
  • *
  • Posts: 44
Hi all,

An oldy, but still seems no simple way to get console width. I have done the usual gymnastics trying to get this. I’m writing a simple util to display small files (it’s primarily for checking results of output files). I have screen wrapping (using WhereX), but it is not reliable as the console can easily be resized.

I saw some people in forums saying WindMaxX - WinMinX, but that clearly doesn’t work as they are constants. I did however put them in a loop just to confirm they did not change as the console size was changed. Just to be sure.

I found GetConsoleScreenBufferInfo, which I found initially in unit JwaWinCon. I got the code to compile but the function failed, suspect I needed the JEDI package, which I am not going to do.

A search for that term (I wrote my own text search program, not complete but works) in the Lazarus folder found in it func.inc and a few others. I tried doing a direct include, but no go (it didn't recognise the command).

A further search online brought me back to CRT. Opened up CRT and it has the functions I want, especially GetScreenWidth (which calls GetConsoleScreenBufferInfo and takes care of the vars). But that is not recognised, but the normal public functions, like NormVideo are recognised (just to confirm it was actually reaching CRT).

So the hopefully simple question is how I can access this GetScreenWidth in CRT? Or is there any other simple way to get the console width?

Any help would be much appreciated.

Phil
« Last Edit: August 10, 2025, 08:15:36 pm by old_DOS_err »

Thaddy

  • Hero Member
  • *****
  • Posts: 18363
  • Here stood a man who saw the Elbe and jumped it.
Re: Access private functions in CRT unit, trying to get console width
« Reply #1 on: August 09, 2025, 08:46:19 pm »
Screenwidth <> ConsoleWidth, so what do you actually mean?
Do you want the ScreenWidth, which is likely different but can be equal to or do you want the ConsoleWidth?
Imo you should just need the console width and that is already accessible.
« Last Edit: August 09, 2025, 08:48:33 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

old_DOS_err

  • New Member
  • *
  • Posts: 44
Re: Access private functions in CRT unit, trying to get console width
« Reply #2 on: August 10, 2025, 01:51:54 pm »
Thanks Thaddy for the reply.

Sadly my body started to decline a couple of years ago and lately my brain has started to follow. I feel I'm being incredibly stupid with this, but I could not find ConsoleWidth. I ran a text search on the Lazarus folder and found console.inc, but a text search for console.inc did not turn up anything useful.

So if you could tell me which unit I need to add, which object to use, or at worst, which package to add, then that would be extremely helpful. As I say, it's kind of embarrassing, I feel like an ex runner who now can barely walk to the local shops.

Here is the basic demo I was working on. This would be very simple using a form. I think I'm getting lost between old DOS (my world, but the screen size never changed) and forms, where resizing is a basic part of the development.

Code: Pascal  [Select][+][-]
  1. Uses
  2.   Classes, SysUtils,
  3.   CRT,
  4.   // these are the other units or similar I tried
  5.   //JwaWinBase, JwaWinCon, JwaWinType, // MAY NEED PACKAGE - function was recognised, but failed
  6.   //FPUsrScr,  // not found. looked like part of a package
  7.   //w32smsg, ditto
  8.   // func.inc looks good, but cannot find a reference to in Lazarus
  9.  
  10. Procedure test_win_coords;
  11. {
  12.   So what I want this demo to do is that each time through the loop, I can change the console (window) size with the mouse,
  13.   then if I press Return I want it to show the new width.
  14. }
  15.   Var
  16.     s : String;
  17.     //h : HANDLE;
  18.     //C : _CONSOLE_SCREEN_BUFFER_INFO;
  19.     x, y : DWord;
  20.  
  21.   Begin
  22.     WriteLn( '|  Press Enter to rerun, E and Enter to end' );
  23.     Repeat
  24.       //WriteLn( '|  WindMinX = ', WindMinX, ',  WindMaxX = ', WindMaxX, ',  WindMinY = ', WindMinY, ', WindMaxY = ', WindMaxY );  THESE ARE FIXED AND DO NOT CHANGE
  25.       //x := p_int__really_stupid_get_console_width;  // I tried writing a poor alternative that moved the cursor along by 1 until it didn't change, it didn't work
  26.       //x := {ConsoleWidth;} ScreenWidth;  // compiler did not recognise either
  27.       WriteLn( '|  Screen Width = ', x );  // I want x to reflect the current width after I change the console size
  28.       ReadLn( s );
  29.     Until UpCase( s ) = 'E';
  30.  
  31. {    If Not GetConsoleScreenBufferInfo( h, c ) Then  // this was in JwaWinCon, above, ran but function failed
  32.       WriteLn( '|  Get function failed' )
  33.     Else
  34.       WriteLn( '|  Get function good:' );
  35. }
  36.     //WriteLn( '|  ScreenWidth = ', GetScreenWidth );  // this was in CRT.pp but I could not find how to access
  37.     //NormVideo;  // just checking was reaching CRT
  38.     //GetScreenCursor( x, y );  // think this was also in CRT.pp
  39.   End;
  40.  

I know I'm going to feel very stupid when someone points outs the bleeding obvious, the mental equivalent of going out and forgetting to put your trousers on.

Phil

Thaddy

  • Hero Member
  • *****
  • Posts: 18363
  • Here stood a man who saw the Elbe and jumped it.
Re: Access private functions in CRT unit, trying to get console width
« Reply #3 on: August 10, 2025, 04:30:18 pm »
You should take a look at Screen which is a global variable of TScreen and has lots of info you need.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

old_DOS_err

  • New Member
  • *
  • Posts: 44
Re: Access private functions in CRT unit, trying to get console width
« Reply #4 on: August 10, 2025, 05:24:17 pm »
Sorry Thaddy, I feel I'm being really dumb here.

I tried Screen, not recognised. Searched online for TScreen, found the Free Pascal page. This made a reference to package x11. A search online found a lot of references, but none directly useful, though they mentioned various other names, including xlib and xauth. A search in the Lazarus package lists did not mention x11, xlib, xauth, etc.

In the Free Pascal page on x11, they gave a demo, that used the units xlib, x, ctypes. I put those in direct, only ctypes was recognised.

It seems like what I am trying to do, i.e. just get the current width of the console (terminal, DOS window), should be incredibly easy, but given how many people read this, you have been the only one to reply. I know I didn't word it very well, but I would have thought someone MUST have done that.

I think unless you can put me out of misery and tell what I am missing (beside a huge number of brain cells), I will leave this for a while and maybe repost a simplified version (if that is possible for me) in the beginners section. For now I am just focussing on doing the file output of my ‘simple’ util, that is to show a data file in byte form (a bit like a hex editor), that bit was easy, oh the irony.

Phil

bytebites

  • Hero Member
  • *****
  • Posts: 756
Re: Access private functions in CRT unit, trying to get console width
« Reply #5 on: August 10, 2025, 05:32:58 pm »
TScreen is for GUI application not console.

old_DOS_err

  • New Member
  • *
  • Posts: 44
Re: Access private functions in CRT unit, trying to get console width
« Reply #6 on: August 10, 2025, 06:09:47 pm »
Thanks bytebites.

Do you know what the DOS equivalent is? Preferably without trying to install some mysterious package ::)

Thaddy

  • Hero Member
  • *****
  • Posts: 18363
  • Here stood a man who saw the Elbe and jumped it.
Re: Access private functions in CRT unit, trying to get console width
« Reply #7 on: August 10, 2025, 06:25:30 pm »
TScreen is for running a console app in a GUI too...
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

cdbc

  • Hero Member
  • *****
  • Posts: 2473
    • http://www.cdbc.dk
Re: Access private functions in CRT unit, trying to get console width
« Reply #8 on: August 10, 2025, 06:25:57 pm »
Hi
You can try, if the attached unit can help you...
Regards Benny

eta: You can get a hold of the 'Handle' like this:
Code: Pascal  [Select][+][-]
  1. function StandardIn: THANDLE;
  2. begin
  3.  {$IfDef WINDOWS}
  4.  Result := GetStdHandle(STD_INPUT_HANDLE);
  5.  {$Else}
  6.  Result := StdInputHandle;
  7.  {$EndIf}
  8. end;
  9.  
  10. function StandardOut: THANDLE;
  11. begin
  12.  {$IfDef WINDOWS}
  13.  Result := GetStdHandle(STD_OUTPUT_HANDLE);
  14.  {$Else}
  15.  Result := StdOutputHandle;
  16.  {$EndIf}
  17. end;
  18.  
  19. function StandardErr: THANDLE;
  20. begin
  21.  {$IfDef WINDOWS}
  22.  Result := GetStdHandle(STD_ERROR_HANDLE);
  23.  {$Else}
  24.  Result := StdErrorHandle;
  25.  {$EndIf}
  26. end;
\o/
« Last Edit: August 10, 2025, 06:36:55 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6 -> FPC 3.2.2 -> Lazarus 4.0 up until Jan 2025 from then on it's both above &: KDE6/QT6 -> FPC 3.3.1 -> Lazarus 4.99

old_DOS_err

  • New Member
  • *
  • Posts: 44
Re: Access private functions in CRT unit, trying to get console width
« Reply #9 on: August 10, 2025, 07:42:56 pm »
Thank you Benny, I really appreciate that, was trying to work out how to get GetConsoleScreenBufferInfo working.

Yah, awesome (a man my age should not be using that word).

That was getting a lot closer, but x and y returned 1. Traced into your function and the record csbi contained 0 for the coords. I assume I messed up the handle as I didn't know what that should be, it looks like it is expecting a value, since the other vars were Out. Another look online under pascal GetConsoleScreenBufferInfo found a very old freepascal forum entry, that had the line,

loc_Out:=GetStdHandle(STD_OUTPUT_HANDLE);

Tried that, didn’t work, then noted they had used windows in the uses section, added that. Perfect. Additionally I ran a heap check, just to be sure I didn’t need to free the handle.

{oopsadaisy, missed your code for the handle, only just saw when I went back to check I got your name correct, I think I caught your reply so quickly the code hadn't come through}

I can now complete my util, but also can add to any DOS routine which requires any kind of wrapping or awareness of the boundary, this is nice and simple.

Thank you again.

Phil

Below is the working demo, each time through the loop resize the console window with the mouse and press return and it will show the new max x and y.

Code: Pascal  [Select][+][-]
  1. Program demo_with_cdbc_unit;
  2. {$mode objfpc}{$H+}
  3. Uses
  4.   Classes, SysUtils,
  5.   windows,  // had to add this to get the handle command
  6.   tui.screen,  // from cdbc
  7.   p_general_types, p_file_unit, p_internals_unit;
  8.  
  9. Procedure test_win_coords;
  10.   Var
  11.     h : THandle;
  12.     x, y : Integer;
  13.     s : String;
  14.  
  15.   Begin
  16.     WriteLn( '|  Press Enter to rerun, E and Enter to end' );
  17.     h := GetStdHandle( STD_OUTPUT_HANDLE );
  18.     Repeat
  19.       GetWindowSize( h, y, x );  // thee call
  20.       WriteLn( '|  x = ', x, ',  y = ', y );
  21.       ReadLn( s );
  22.     Until UpCase( s ) = 'E';
  23.   End;
  24.  
  25. Begin
  26.   test_win_coords;
  27.  
  28.   WriteLn; WriteLn('Finished...'); ReadLn;
  29. End.
  30.  

cdbc

  • Hero Member
  • *****
  • Posts: 2473
    • http://www.cdbc.dk
Re: Access private functions in CRT unit, trying to get console width
« Reply #10 on: August 10, 2025, 08:03:14 pm »
Hi Phil
Cool  8-)
I'm glad you got it to work to your satisfaction \o/\ö/\o/
I had a hard time finding that short piece of code  ...but ofc. it was /hiding/ in my "area 51" section on my hdd  :D ;D
Happy coding mate.
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6 -> FPC 3.2.2 -> Lazarus 4.0 up until Jan 2025 from then on it's both above &: KDE6/QT6 -> FPC 3.3.1 -> Lazarus 4.99

 

TinyPortal © 2005-2018