Получение размера терминала в c для Windows?

Как проверить ymax и xmax в окне консоли, под Windows, используя обычный c?

Вот этот кусок кода для Linux:

#include <stdio.h>
#include <sys/ioctl.h>
int main (void)
{
    struct winsize max;
    ioctl(0, TIOCGWINSZ , &max);
    printf ("lines %d\n", max.ws_row);
    printf ("columns %d\n", max.ws_col);
}

Теперь мне интересно, как я могу сделать то же самое для Windows. Я старался winioctl.h но это не определяет struct winsize ни какой другой с подобным именем.

Какие-нибудь советы? Благодарю.

PS. В Linux вы также можете найти размер консоли, используя getenv("LINES");, Есть ли аналогичная переменная под Windows?

PPS. Также всегда есть ncurses.hЯ предполагаю, что работают обе системы, но я избегаю этого из-за конфликтов с другими библиотеками, которые у меня есть.

PPPS. Этот вопрос здесь Получение ширины терминала в C? Есть много советов, поэтому не нужно повторять это.

3 ответа

Решение

(Частичный ответ)

Этот код:

CONSOLE_SCREEN_BUFFER_INFO csbi;
int ret;
ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ),&csbi);
if(ret)
{
    printf("Console Buffer Width: %d\n", csbi.dwSize.X);
    printf("Console Buffer Height: %d\n", csbi.dwSize.Y);
}

Дает размер буфера. Единственная проблема в том, что dwSize.Y на самом деле не размер экрана (здесь 300 вместо 25 строк). Но dwSize.X соответствует номеру столбца. Нужно только windows.h работать.

Это печатает размер консоли, а не буфера:

#include <windows.h>

int main(int argc, char *argv[]) {
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    int columns, rows;

    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;

    printf("columns: %d\n", columns);
    printf("rows: %d\n", rows);
    return 0;
}

Этот код работает, потому что srWindow "содержит координаты буфера экрана консоли верхнего левого и нижнего правого углов окна дисплея", и SMALL_RECT структура "указать строки и столбцы символьных ячеек экранного буфера" в соответствии с MSDN. Я вычел параллельные стороны, чтобы получить размер окна консоли. Так как я получил 1 меньше, чем фактическая стоимость, я добавил один.

Приведенные ниже две функции получат размер окна несколько более напрямую.

Обратите внимание, что, используя gcc, я обнаружил, что ни этот подход, ни GetConsoleScreenBufferInfo не работают, если программа передана по конвейеру. Это что-то вроде боли, так как / f тогда тоже не работает. Видимо, данные экрана недоступны в трубе.

Хм, вышеприведенное замечание, конечно, чрезвычайно глупо.;) Это STDOUT, это не экран в трубе! Это означает, что я предпочитаю использовать STD_ERROR_HANDLE выше STD_OUTPUT_HANDLE. Я гораздо менее склонен направлять стандартную ошибку с экрана, чем стандартный вывод.

typedef struct _CONSOLE_FONT_INFO {
  DWORD nFont;
  COORD dwFontSize;
} CONSOLE_FONT_INFO, *PCONSOLE_FONT_INFO;

BOOL WINAPI GetCurrentConsoleFont(
   HANDLE             hConsoleOutput,
   BOOL               bMaximumWindow,
   PCONSOLE_FONT_INFO lpConsoleCurrentFont
);

/* Get the window width */
int getww_(void)
{
    CONSOLE_FONT_INFO info;
    GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &info);
    return info.dwFontSize.X;
}

/* Get the window height */
int getwh_(void)
{
    CONSOLE_FONT_INFO info;
    GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &info);
    return info.dwFontSize.Y;
}
Другие вопросы по тегам