Windows控制台函数:调整控制台窗口大小函数SetConsoleWindowInfo()

目录

什么是 SetConsoleWindowInfo?

函数签名

参数详解

用法

跟 SetConsoleScreenBufferSize 的关系

搭配 FillConsoleOutputAttribute

移动窗口位置

注意事项

什么是 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。

  • 相当于把窗口“移动”到缓冲区的右下角。

注意事项

  1. 窗口不能大于缓冲区:

    • Right - Left + 1 <= 缓冲区宽度。

    • Bottom - Top + 1 <= 缓冲区高度。

    • 比如缓冲区 50×50,rect = {0, 0, 50, 50} 会失败(最大是 49,49)。

  2. 最小限制:

    • 窗口有最小值(比如 18 列 × 8 行,取决于字体),小于此会失败。

  3. 检查返回值:

if (!SetConsoleWindowInfo(screen, TRUE, &rect)) {
    return 1; // 出错了
}

   4.bAbsolute:

  • 几乎总是用 TRUE,相对坐标(FALSE)很少用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值