SetConsoleScreenBufferInfoEx的工作原理与SetConsoleTextAttribute不同

SetConsoleScreenBufferInfoEx的工作原理与SetConsoleTextAttribute不同,c,winapi,console,C,Winapi,Console,最近我尝试用带下划线的C语言打印文本。我的控制台不支持ANSI转义字符,所以我尝试使用DBCS,我的控制台支持DBCS。为此,我必须更改控制台文本属性。起初,我使用SetConsoleTextAttribute对其进行更改,但后来,当我想记住颜色并只更改下划线时,我开始使用GetConsoleScreenBufferInfoEx和SetConsoleScreenBufferInfoEx来同时获取以前的属性。这时我注意到,当我使用前者时,它只影响我在调用后打印的文本,对于后者,我还更改了前一个文本

最近我尝试用带下划线的C语言打印文本。我的控制台不支持ANSI转义字符,所以我尝试使用DBCS,我的控制台支持DBCS。为此,我必须更改控制台文本属性。起初,我使用
SetConsoleTextAttribute
对其进行更改,但后来,当我想记住颜色并只更改下划线时,我开始使用
GetConsoleScreenBufferInfoEx
SetConsoleScreenBufferInfoEx
来同时获取以前的属性。这时我注意到,当我使用前者时,它只影响我在调用后打印的文本,对于后者,我还更改了前一个文本的属性

例如,我写了两个短代码并编译它们

代码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;
}
#包括
#包括
int main()
{
printf(“代码1:\n”);
句柄输出=GetStdHandle(标准输出句柄);
DWORD模式=0;
int标志=1;
标志&=GetConsoleMode(输出模式和模式);
标志&=SetConsoleMode(输出,模式|在全球范围内启用| LVB |网格|);
//7是默认的前景-灰色
SetConsoleExtAttribute(输出,7 |公共_LVB_下划线);
printf(“你好,世界!1==%d”,标志);
getchar();
SetConsoleTextAttribute(out,7);
printf(“再见世界!1==%d”,标志);
getchar();
返回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;
}
#包括
#包括
typedef控制台屏幕缓冲区INFOEX CSBI;
int main()
{
printf(“代码2:\n”);
句柄输出=GetStdHandle(标准输出句柄);
DWORD模式=0;
int标志=1;
标志&=GetConsoleMode(输出模式和模式);
标志&=SetConsoleMode(输出,模式|在全球范围内启用| LVB |网格|);
CSBI CSBI={0};
csbi.cbSize=sizeof(csbi);
标志&=GetConsoleScreenBufferInfoEx(输出,&csbi);
csbi.wAttributes |=常用的左下划线;
标志&=SetConsoleScreenBufferInfoEx(输出,&csbi);
printf(“你好,世界!1==%d”,标志);
getchar();
csbi.wAttributes&=~常用的左下划线;
标志&=SetConsoleScreenBufferInfoEx(输出,&csbi);
printf(“再见世界!1==%d”,标志);
getchar();
返回0;
}
该标志用于确保所有函数都返回TRUE 在第一个代码中,“代码1”将不带下划线,“Hello World!”将有下划线和“再见世界!”不会有下划线

在第二段代码中,在我输入新行之前,所有内容都将有下划线,然后所有内容都将丢失下划线

有人知道为什么会这样吗?我认为他们对控制台文本属性也会这样做


谢谢,Roy在第二段代码中,在我输入新行之前,所有内容都将带有下划线,然后所有内容都将丢失下划线。

经过测试,这两段代码的最终效果是相同的

有人知道为什么会这样吗?我想他们对控制台文本属性也会这么做。

SetConsoleTextAttribute:设置写入的字符的属性 控制台屏幕缓冲区由WriteFile或WriteConsole函数, 或由ReadFile或ReadConsole函数进行响应。此函数 影响函数调用后写入的文本

SetConsoleScreenBufferInfoEx:设置有关 指定的控制台屏幕缓冲区


对于注释,在控制台文本的属性上,
SetConsoleTextAttribute
setconsolescreeesbufferinfoex
可以实现相同的效果,例如添加下划线

不知道你为什么认为他们会表现得一样。它们不是一回事,这就是它们都存在的原因。如果它们是相同的,其中一个将是完全多余的。