SetConsoleScreenBufferInfoEx работает не так, как SetConsoleTextAttribute - PullRequest
0 голосов
/ 26 октября 2019

Недавно я попытался напечатать текст на C с подчеркиванием. Моя консоль не поддерживает управляющий символ ANSI, поэтому я попытался использовать DBCS, который поддерживает моя консоль. Для этого мне пришлось изменить текстовые атрибуты консоли. Вначале я использовал SetConsoleTextAttribute, чтобы изменить его, но позже, когда мне захотелось запомнить цвет и изменить ТОЛЬКО подчеркивание, я начал использовать GetConsoleScreenBufferInfoEx и SetConsoleScreenBufferInfoEx, чтобы также получить предыдущие атрибуты. Именно тогда я заметил, что когда я использую первый, он влияет только на текст, который я печатаю после вызова, а в случае последнего я также изменяю атрибуты предыдущего текста.

Например,Я написал 2 коротких кода и скомпилировал их.

Код 1:

#include <Windows.h>
#include <stdio.h>

int main()
{
    printf("Code 1:\n");
    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD mode = 0;
    int flag = 1;
    flag &= GetConsoleMode(out, &mode);
    flag &= SetConsoleMode(out, mode | ENABLE_LVB_GRID_WORLDWIDE);
    //7 is the default foreground - gray
    SetConsoleTextAttribute(out, 7 | COMMON_LVB_UNDERSCORE);
    printf("Hello World! 1==%d", flag);
    getchar();
    SetConsoleTextAttribute(out, 7);
    printf("Goodbye World! 1==%d", flag);
    getchar();
    return 0;
}

И код 2:

#include <Windows.h>
#include <stdio.h>

typedef CONSOLE_SCREEN_BUFFER_INFOEX CSBI;

int main()
{
    printf("Code 2:\n");
    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD mode = 0;
    int flag = 1;
    flag &= GetConsoleMode(out, &mode);
    flag &= SetConsoleMode(out, mode | ENABLE_LVB_GRID_WORLDWIDE);
    CSBI csbi = { 0 };
    csbi.cbSize = sizeof(csbi);
    flag &= GetConsoleScreenBufferInfoEx(out, &csbi);
    csbi.wAttributes |= COMMON_LVB_UNDERSCORE;
    flag &= SetConsoleScreenBufferInfoEx(out, &csbi);
    printf("Hello World! 1==%d", flag);
    getchar();
    csbi.wAttributes &= ~COMMON_LVB_UNDERSCORE;
    flag &= SetConsoleScreenBufferInfoEx(out, &csbi);
    printf("Goodbye World! 1==%d", flag);
    getchar();
    return 0;
}

, флаг должен гарантировать, что все функции возвращаютсяTRUE

В первом коде «Код 1» останется без подчеркивания «Hello World!»Подчеркну, и "Прощай, мир!"не будет подчеркивания.

Во втором коде все будет подчеркивать, пока я не введу новую строку, и тогда все потеряет свое подчеркивание.

У кого-нибудь есть идея, почемуэто так? Я думаю, что они будут делать то же самое с текстовыми атрибутами консоли.

Спасибо, Рой

1 Ответ

0 голосов
/ 28 октября 2019

Во втором коде все будет иметь подчеркивание, пока я не введу новую строку, и тогда все потеряет свое подчеркивание.

После моего теста окончательный эффект двух частейкода тот же.

enter image description here

У кого-нибудь есть идеи, почему это так? Я думаю, что они будут делать то же самое с текстовыми атрибутами консоли.

SetConsoleTextAttribute: Устанавливает атрибуты символов, записываемых в экранный буфер консоли функцией WriteFile или WriteConsole, или отражаются функцией ReadFile. или функция ReadConsole. Эта функция влияет на текст, написанный после вызова функции.

SetConsoleScreenBufferInfoEx: Устанавливает расширенную информацию об указанном буфере экрана консоли.

Для комментария о свойствах текста консоли, SetConsoleTextAttribute и SetConsoleScreenBufferInfoEx могут достигать того же эффекта, например , изменяя цвет текста или добавляя подчеркивание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...