目录
跟 SetConsoleScreenBufferSize 的关系
什么是 SetConsoleWindowInfo?
SetConsoleWindowInfo 是一个 Windows API 函数,用来设置控制台的窗口区域(visible window area),也就是你在屏幕上实际看到的显示区域的大小和位置。它不改变缓冲区的大小,只控制“窗口”部分。
-
画布和窗口比喻:
-
缓冲区是整个画布(由 SetConsoleScreenBufferSize 设置)。
-
窗口是画布上你能看到的那块“框”,可以用 SetConsoleWindowInfo 调整框的大小和位置。
-
-
作用:
-
决定显示哪部分缓冲区内容,超出窗口的部分可以用滚动条查看。
-
函数签名
这个函数的作用是设置(Set)控制台(Console)窗口(Window)的信息(Info),
可以拆解成以下部分来理解:
-
Set
:表示设置(更改某个值)。 -
Console
:指的是控制台(Console),即 Windows 终端窗口。 -
Window
:表示窗口,指的是控制台的可视区域(即用户能看到的部分)。 -
Info
:表示信息,在这里指的是窗口的位置和大小。
它的定义是:
BOOL SetConsoleWindowInfo(
HANDLE hConsoleOutput, // 屏幕的“钥匙”
BOOL bAbsolute, // 坐标是绝对还是相对
const SMALL_RECT* lpConsoleWindow // 窗口的新位置和大小
);
返回值:BOOL,TRUE 表示成功,FALSE 表示失败。
参数详解
1. HANDLE hConsoleOutput - 屏幕的“钥匙”
-
这是什么:你用 GetStdHandle(STD_OUTPUT_HANDLE) 拿到的屏幕句柄。
-
作用:告诉函数要调整哪个控制台的窗口。
-
怎么用:
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
2. BOOL bAbsolute - 坐标是绝对还是相对
-
这是什么:一个布尔值,决定 lpConsoleWindow 的坐标是绝对坐标还是相对坐标。
-
作用:
-
TRUE:坐标是缓冲区的绝对位置(从 (0,0) 开始)。
-
FALSE:坐标是相对于当前窗口位置的偏移(很少用)。
-
-
怎么用:
-
一般设为 TRUE,用绝对坐标更直观。
-
BOOL bAbsolute = TRUE;
3. const SMALL_RECT* lpConsoleWindow - 窗口的新位置和大小
-
这是什么:一个 SMALL_RECT 结构体,定义窗口的左上角和右下角坐标。
-
作用:指定窗口在缓冲区中的位置和尺寸。
-
定义:
typedef struct _SMALL_RECT {
SHORT Left; // 左边界(起始列)
SHORT Top; // 上边界(起始行)
SHORT Right; // 右边界(结束列)
SHORT Bottom; // 下边界(结束行)
} SMALL_RECT;
怎么用:
-
比如窗口是 30 列 × 20 行,从 (0,0) 开始:
SMALL_RECT rect = {0, 0, 29, 19};
注意:Right 和 Bottom 是结束坐标,所以宽度 = Right - Left + 1,高度 = Bottom - Top + 1。
用法
我们写个例子,把窗口设为 30×20,从缓冲区的 (0,0) 开始:
#include <windows.h>
int main() {
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
if (screen == INVALID_HANDLE_VALUE) {
return 1;
}
// 设置缓冲区为 50x50
COORD size = {50, 50};
SetConsoleScreenBufferSize(screen, size);
// 设置窗口为 30x20
SMALL_RECT rect = {0, 0, 29, 19}; // 0-29 列,0-19 行
if (!SetConsoleWindowInfo(screen, TRUE, &rect)) {
return 1; // 设置失败
}
return 0;
}
运行结果
-
缓冲区是 50×50。
-
窗口显示 30 列 × 20 行,从缓冲区的左上角 (0,0) 到 (29,19)。
-
如果缓冲区有内容,窗口只显示这部分,多余部分可用滚动条查看。
跟 SetConsoleScreenBufferSize 的关系
-
SetConsoleScreenBufferSize:
-
设置缓冲区大小(整个画布)。
-
比如 50×50。
-
-
SetConsoleWindowInfo:
-
设置窗口大小和位置(画布上的可见框)。
-
比如 30×20,位置从 (0,0) 开始。
-
-
约束:
-
窗口大小不能超过缓冲区。
-
比如缓冲区是 50×50,窗口最多 50×50。
-
顺序
-
先设缓冲区,再设窗口:
-
如果先设窗口为 30×20,再设缓冲区为 20×20,会失败(缓冲区不能小于窗口)。
-
正确顺序:
-
SetConsoleScreenBufferSize(screen, {50, 50});
SetConsoleWindowInfo(screen, TRUE, &rect);
搭配 FillConsoleOutputAttribute
我们设缓冲区为 50×50,窗口为 40×40,填充居中 10×10:
#include <windows.h>
int main() {
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
if (screen == INVALID_HANDLE_VALUE) {
return 1;
}
// 设置缓冲区为 50x50
COORD size = {50, 50};
SetConsoleScreenBufferSize(screen, size);
// 设置窗口为 40x40
SMALL_RECT rect = {0, 0, 39, 39}; // 0-39 列,0-39 行
SetConsoleWindowInfo(screen, TRUE, &rect);
// 填充居中 10x10
SHORT start_x = (40 - 10) / 2; // 15
SHORT start_y = (40 - 10) / 2; // 15
DWORD written;
for (int y = start_y; y < start_y + 10; y++) {
COORD start = {start_x, (SHORT)y};
FillConsoleOutputAttribute(screen, BACKGROUND_GREEN, 10, start, &written);
}
return 0;
}
效果:
-
缓冲区 50×50,窗口 40×40。
-
绿色 10×10 在窗口中间(15,15)到(24,24)。
移动窗口位置
如果想让窗口显示缓冲区的不同部分,可以调整 rect:
SMALL_RECT rect = {10, 10, 49, 49}; // 从 (10,10) 到 (49,49)
SetConsoleWindowInfo(screen, TRUE, &rect);
-
窗口显示缓冲区的 (10,10) 到 (49,49),大小仍是 40×40。
-
相当于把窗口“移动”到缓冲区的右下角。
注意事项
-
窗口不能大于缓冲区:
-
Right - Left + 1 <= 缓冲区宽度。
-
Bottom - Top + 1 <= 缓冲区高度。
-
比如缓冲区 50×50,rect = {0, 0, 50, 50} 会失败(最大是 49,49)。
-
-
最小限制:
-
窗口有最小值(比如 18 列 × 8 行,取决于字体),小于此会失败。
-
-
检查返回值:
if (!SetConsoleWindowInfo(screen, TRUE, &rect)) {
return 1; // 出错了
}
4.bAbsolute:
-
几乎总是用 TRUE,相对坐标(FALSE)很少用。