0

Context: I am writing a small library to output ansi formatted media to stdout (similar to ncurses). What i want to do is to remove the scrollbar of the terminal window independently of the plattform the code is compiled on (Win / MacOS / Unix). Heres a little example of what the window should look like (this was done with ncurses): example of scrollbar missing

To remove the scrollbar on Windows with c++, you simply set the screen buffer height to be the same size as the height of the window like so:

#include <Windows.h>
#include <iostream>

int main() {
    CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo; 

    // Get console handle and get screen buffer information from that handle.
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hConsole, &screenBufferInfo);

    // Get rid of the scrollbar by setting the screen buffer size the same as 
    // the console window size.
    COORD new_screen_buffer_size;

    // screenBufferInfo.srWindow allows us to obtain the width and height info 
    // of the visible console in character cells.
    // That visible portion is what we want to set the screen buffer to, so that 
    // no scroll bars are needed to view the entire buffer.
    new_screen_buffer_size.X = screenBufferInfo.srWindow.Right - 
    screenBufferInfo.srWindow.Left + 1; // Columns
    new_screen_buffer_size.Y = screenBufferInfo.srWindow.Bottom - 
    screenBufferInfo.srWindow.Top + 1; // Rows

    // Set new buffer size
    SetConsoleScreenBufferSize(hConsole, new_screen_buffer_size);

    std::cout << "There are no scrollbars in this console!" << std::endl;

    return 0;
}

see here

My question now is: How could I remove the scrollbar on other plattforms and use their respective method with #if defined(_whatever plattform_) similar to another code snippet in my project (plain c):

// writes terminal dimensions to 'rows' and 'cols'
// returns 0 if successful
int window_dimensions()
{
#if defined(__APPLE__) || defined(__linux__)
    struct winsize w;

    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);

    rows = w.ws_row;
    cols = w.ws_col;
    return 0;
#elif defined(_WIN32)
    CONSOLE_SCREEN_BUFFER_INFO csbi;

    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
    cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    return 0;
#endif
    return 1;
}
bj4rne
  • 1
  • 1
  • 2
  • You've posted C++ code, not C. They are not the same language. – Andrew Henle Feb 13 '22 at 13:52
  • @AndrewHenle yes, i know the first example is c++, but the question is more about how to do it in general. I would gladly accept advice in either language. – bj4rne Feb 13 '22 at 13:58
  • Then edit the question and add the C++ tag. – Andrew Henle Feb 13 '22 at 13:59
  • There are dozens of different terminal emulators people could be using. Something that works on one of them might not work on others. I wouldn't even bother trying. – Shawn Feb 13 '22 at 15:22
  • @Shawn Im not going for every terminal on every system ever made. Win10, a pretty recent MacOS and a common Linux like Ubuntu 20 are good enough. My Program won't run on anything other than a termios environment anyway... – bj4rne Feb 13 '22 at 17:15

1 Answers1

0

For anyone finding this questions in the future and wondering, i have deemed it impossible in the scope of my little project.

Users who wish to hide the Scrollbar on MacOS can go to System Preferences -> General and change Show scroll bars to When scrolling.

For Linux users, the bar on most terminals isnt even that much of an inconvenience so you should be able to just live with it.

On Windows machines i've settled with this approach in c:

int remove_scrollbar(int x_, int y_)
{
#if defined(_WIN32)
    CONSOLE_SCREEN_BUFFER_INFOEX csbiex;

    csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);

    GetConsoleScreenBufferInfoEx(GetStdHandle(STD_OUTPUT_HANDLE), &csbiex);

    csbiex.dwSize.X = x_;
    csbiex.dwSize.Y = y_;

    SMALL_RECT s1;
    s1.Top = 0;
    s1.Left = 0;
    s1.Bottom = y_;
    s1.Right = x_;

    csbiex.srWindow = s1;

    COORD mws1;
    mws1.X = x_;
    mws1.Y = y_;

    csbiex.dwMaximumWindowSize = mws1;

    SetConsoleScreenBufferInfoEx(GetStdHandle(STD_OUTPUT_HANDLE), &csbiex); //this also resizes the window to x_, y_
    return 0;
#endif
    return 1;
}

I went for CONSOLE_SCREEN_BUFFER_INFOEX because it worked better in my testing than CONSOLE_SCREEN_BUFFER_INFO but either should be fine.

bj4rne
  • 1
  • 1
  • 2