Windows C++ 控制台程序如何将窗口调整为指定的行列数?
你遇到的尺寸偏小问题核心原因是 MoveWindow 传入的是包含标题栏、窗口边框的整体窗口尺寸,而你通过单元格计算的是控制台客户区(仅字符显示区域)的尺寸,没有计入非客户区占用的像素空间。
关于单元格尺寸的获取
GetCurrentConsoleFont 返回的 CONSOLE_FONT_INFO.dwFontSize 本身就是控制台单元格的准确像素宽高,返回的X是宽度、Y是高度,已经包含字符间的预留间距,不需要额外计算。你之前用桌面尺寸除以dwMaximumWindowSize的方案不可靠,因为dwMaximumWindowSize是当前显示配置下控制台全屏可容纳的最大行列数,会扣除任务栏、系统预留边距等空间,和桌面全尺寸本身就不匹配。
两种可靠实现方案
方案1:按行列数直接设置(最省心,无需手动计算像素)
直接调用控制台API设置缓冲区和窗口的行列数,系统会自动适配窗口大小:
#include <windows.h> int main() { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); HWND hConsole = GetConsoleWindow(); // 目标行列数,按需修改即可 const short TARGET_COLS = 20; const short TARGET_ROWS = 10; CONSOLE_SCREEN_BUFFER_INFOEX csbiex = {0}; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); GetConsoleScreenBufferInfoEx(hOut, &csbiex); // 先把缓冲区大小设置为目标行列,避免窗口大小被缓冲区限制 csbiex.dwSize.X = TARGET_COLS; csbiex.dwSize.Y = TARGET_ROWS; // 设置窗口大小(注意这里传的是行列数,不是像素) SMALL_RECT windowRect = {0, 0, TARGET_COLS - 1, TARGET_ROWS - 1}; csbiex.srWindow = windowRect; SetConsoleScreenBufferInfoEx(hOut, &csbiex); SetConsoleWindowInfo(hOut, TRUE, &windowRect); // 可选:把窗口移动到左上角 SetWindowPos(hConsole, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER); return 0; }
方案2:手动计算像素尺寸设置
如果一定要自己控制像素尺寸,先通过AdjustWindowRect换算包含非客户区的窗口总尺寸:
#include <windows.h> int main() { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); HWND hConsole = GetConsoleWindow(); // 1. 获取单元格尺寸 CONSOLE_FONT_INFO fontInfo = {0}; GetCurrentConsoleFont(hOut, FALSE, &fontInfo); short cellW = fontInfo.dwFontSize.X; short cellH = fontInfo.dwFontSize.Y; // 2. 计算目标客户区尺寸:20列 * 10行 long clientW = 20 * cellW; long clientH = 10 * cellH; // 3. 换算成包含标题栏、边框的总窗口尺寸 RECT windowRect = {0, 0, clientW, clientH}; DWORD style = GetWindowLong(hConsole, GWL_STYLE); AdjustWindowRect(&windowRect, style, GetMenu(hConsole) != NULL); // 4. 移动并调整窗口大小 MoveWindow(hConsole, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, TRUE); return 0; }
注意事项
两种方案的适配误差都在1个像素以内,如果后续需要更大尺寸的窗口,只需要修改目标行列数的取值即可,不需要调整换算逻辑。
内容的提问来源于stack exchange,提问作者brandwegg
相关产品推荐
相关产品推荐

