windows C/C++ 使控制台窗口全屏

背景

  时间[2018年07月23日 中午]
  在写windows控制台应用程序的时候,我们希望修改一下控制台窗口的大小以及位置等信息。

方法

方法一:使用cmd命令mode

  语法: MODE CON[:] [COLS=c] [LINES=n]
  指定控制台行数及列数,行、列的单位为字符。
  C/C++中使用system()调用该命令,例如:
  system(“mode con: cols=120 lines=40”);
  
  要使用控制台窗口全屏化,首先要得到屏幕的大小,分别使用GetSystemMetrics(SM_CXSCREEN)和GetSystemMetrics(SM_CYSCREEN)获取屏幕的宽度和高度,单位为像素。由于mode con的单位是字符,需要将屏幕大小信息进行转换,因此我们又需要得到每个字符的宽和高所占用的像素数,可以使用GetCurrentConsoleFont()和GetConsoleFontSize()来获取。
  
示例代码:

/*******************************************************************************
 * 获取控制台当前字体大小
 ******************************************************************************/
COORD get_font_size()
{
    COORD font_size;
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    /* 字体信息 */
    struct CONSOLE_FONT
    {
        DWORD index;
        COORD dim;
    } cfi;
    typedef COORD (WINAPI *PROCGETCONSOLEFONTSIZE)(HANDLE, DWORD);
    typedef BOOL (WINAPI *PROCGETCURRENTCONSOLEFONT)(HANDLE, BOOL, struct CONSOLE_FONT*);

    HMODULE hKernel32 = GetModuleHandle("kernel32");
    PROCGETCONSOLEFONTSIZE GetConsoleFontSize = (PROCGETCONSOLEFONTSIZE)GetProcAddress(hKernel32,"GetConsoleFontSize");
    PROCGETCURRENTCONSOLEFONT GetCurrentConsoleFont = (PROCGETCURRENTCONSOLEFONT)GetProcAddress(hKernel32,"GetCurrentConsoleFont");

    GetCurrentConsoleFont(handle, FALSE, &cfi);             /* 获取当前字体索引信息 */
    font_size = GetConsoleFontSize(handle, cfi.index);      /* 获取当前字体宽高信息[字符宽度及高度所占像素数] */

    return font_size;
}

/*******************************************************************************
 * 最大化展示控制台窗口
 ******************************************************************************/
void full_screen()
{
    HWND hwnd = GetForegroundWindow();
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);   /* 标准输出缓冲区句柄 */
    int cx = GetSystemMetrics(SM_CXSCREEN);            /* 屏幕宽度 */
    int cy = GetSystemMetrics(SM_CYSCREEN);            /* 屏幕高度 */

    COORD size = get_font_size();
    char cmd[32] = { 0 };
    sprintf(cmd, "MODE CON: COLS=%d LINES=%d", cx / size.X, cy / size.Y);
    system(cmd);
    SetWindowPos(hwnd, HWND_TOP, 0, 0, cx, cy, 0);
}

  到目前为止,代码可以运行了,但运行效果并不尽如人意,比如,我不想让控制台窗口的标题栏、状态栏、边框、滚动条等展示出来。在网上搜索了一翻,发现一种解决方案,是将屏幕的宽、高信息添加一个固定的数值,比如300,最后使用MoveWindow()函数设置窗口的左上角位置,即设置了一个大小为标题栏高度的偏移量,如-33,将标题栏放在了可视区之外。这种方法在win8.1上是可行的,但在win10中无效,只能另辟蹊径了。
  

方法二:使用windows api

  相关函数:
  GetWindowLong() 用于获取窗口信息
  SetWindowLong() 用于设置窗口信息
  SetWindowPos() 设置窗口起始位置及大小
  要了解更详细的使用说明,可以查看官方文档。
  
示例代码:

/*******************************************************************************
 * 全屏控制台窗口
 * 取消标题栏及边框
 ******************************************************************************/
void full_screen()
{   
    HWND hwnd = GetForegroundWindow();
    int cx = GetSystemMetrics(SM_CXSCREEN);            /* 屏幕宽度 像素 */
    int cy = GetSystemMetrics(SM_CYSCREEN);            /* 屏幕高度 像素 */

    LONG l_WinStyle = GetWindowLong(hwnd,GWL_STYLE);   /* 获取窗口信息 */
    /* 设置窗口信息 最大化 取消标题栏及边框 */
    SetWindowLong(hwnd,GWL_STYLE,(l_WinStyle | WS_POPUP | WS_MAXIMIZE) & ~WS_CAPTION & ~WS_THICKFRAME & ~WS_BORDER);

    SetWindowPos(hwnd, HWND_TOP, 0, 0, cx, cy, 0);
}

运行结果[win10 + vc6]:
这里写图片描述

附:

  使用api修改控制台缓冲区大小
  SetConsoleScreenBufferSize() 设置控制台缓冲区大小
  
示例代码

/*******************************************************************************
 * 设置控制台窗口起始位置,缓冲区大小及窗口大小
 * top   : 左上角X坐标
 * left  : 左上角Y坐标
 * width :宽度   单位 字符
 * height: 高度  单位 字符
 ******************************************************************************/
void full_screen(int top, int left, SHORT width, SHORT height)
{
    COORD size;
    HWND hwnd = GetForegroundWindow();
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD font_size = get_font_size();

    width = width > GetSystemMetrics(SM_CXMIN) ? width : GetSystemMetrics(SM_CXMIN);
    height = height > GetSystemMetrics(SM_CYMIN) ? height : GetSystemMetrics(SM_CYMIN);
    size.X = width;
    size.Y = height;

    SetConsoleScreenBufferSize(handle, size);
    SetWindowPos(hwnd, HWND_TOP, top, left, size.X * font_size.X, size.Y * font_size.Y, 0);
}

猜你喜欢

转载自blog.csdn.net/linuxwuj/article/details/81165885