【问题标题】:Change Windows console size更改 Windows 控制台大小
【发布时间】:2018-11-09 08:01:59
【问题描述】:

我一直在试图弄清楚如何调整控制台窗口的大小。 这是我正在使用的函数的代码:

#include <windows.h> 
#include <stdio.h>

#define WIDTH 70
#define HEIGHT 35

HANDLE wHnd; 

void setup() {
    SMALL_RECT windowSize = {0, 0, WIDTH - 1, HEIGHT - 1};
    COORD bufferSize = { WIDTH , HEIGHT };
    wHnd = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleTitle("Conway's Game of Life");
    SetConsoleWindowInfo(wHnd, 1, &windowSize); 
    SetConsoleScreenBufferSize(wHnd, bufferSize);
}

虽然它适用于小宽度和高度(如 70 和 35)。它不适合我需要的大小(几乎是我需要的两倍大,是的,我相应地调整了缓冲区大小,总是比 windowSize 大一点)。然后它只是常规尺寸。我的下一个想法是,既然它已经很大了,为什么不全屏呢。

SetConsoleDisplayMode(wHnd, CONSOLE_FULLSCREEN_MODE, 0);

在此代码之前,sn-p 可以正常工作,但现在不能,甚至在其他 PC 上也不能。它太奇怪地停止了旧项目的工作。

知道如何全屏启动它吗? (ALT + ENTER 有效)或者在启动时使控制台窗口变大?我看过 ncurses 但我在 Windows 10 上并且不知道如何使用它,此外我的教授可能不希望我使用外部库。 谢谢你的帮助!如果我忘记了什么,请告诉我。

【问题讨论】:

  • Microsoft 在某个时候放弃了对控制台应用程序的全屏支持,转而使用 XP 和 Vista 之间的新图形驱动程序模型。 (我也懒得查了。)。如果您想调整控制台窗口的大小,您必须确保控制台输出屏幕缓冲区的大小至少与您希望窗口调整到的大小相同。
  • 是的,我也读到过,奇怪的是它在一周前有效,而现在却没有(全屏)。好吧,我的控制台输出屏幕缓冲区大于我希望窗口的大小,如您所见,但它仅适用于小尺寸,但不适用于较大尺寸

标签: c windows-console


【解决方案1】:

要最大化控制台窗口,您可以这样做:

C++

#include <cstdlib>
#include <string>
#include <iostream>
#include <memory>
#include <type_traits>

#include <windows.h>

std::string get_last_error_msg()
{
    auto error_code{ GetLastError() };
    if (!error_code)
        return {};

    LPSTR buffer{};
    auto size{ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPSTR>(&buffer), 0, nullptr) };

    // use a unique_ptr for buffer since the ctor of string could throw
    std::unique_ptr<std::remove_pointer_t<decltype(buffer)>, decltype(&LocalFree)> p{ buffer, LocalFree };
    std::string message{ p.get(), size };
    return message;
}

bool maximize_console()
{
    auto console_window{ GetConsoleWindow() };

    if (!console_window) {
        std::cerr << "GetConsoleWindow() failed :(\n\n";
        return false;
    }

    auto console_out{ GetStdHandle(STD_OUTPUT_HANDLE) };
    if (console_out == INVALID_HANDLE_VALUE) {
        std::cerr << "GetStdHandle() failed with \"" << get_last_error_msg() << "\" :(\n\n";
        return false;
    }

    auto largest_size{ GetLargestConsoleWindowSize(console_out) };
    if (!largest_size.X && !largest_size.Y) {
        std::cerr << "GetLargestConsoleWindowSize() failed with \"" << get_last_error_msg() << "\" :(\n\n";
        return false;
    }

    --largest_size.X;
    --largest_size.Y;

    if (!SetConsoleScreenBufferSize(console_out, largest_size)) {
        std::cerr << "SetConsoleScreenBufferSize() failed with \"" << get_last_error_msg() << "\" :(\n\n";
        return false;
    }

    if (!ShowWindow(console_window, SW_MAXIMIZE)) {
        std::cerr << "ShowWindow() failed :(\n\n";
        return false;
    }

    return true;
}

int main()
{
    if (!maximize_console())
        return EXIT_FAILURE;
}

C

#include <stdbool.h>
#include <stdio.h>

#include <windows.h>

LPSTR get_last_error_msg(void)
{
    DWORD error_code = GetLastError();
    if (!error_code)
        return LocalAlloc(LMEM_ZEROINIT, 1);

    LPSTR buffer = NULL;
    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL);

    return buffer;
}

bool maximize_console(void)
{
    HWND console_window = GetConsoleWindow();

    if (!console_window) {
        fputs("GetConsoleWindow() failed :(\n", stderr);
        return false;
    }

    HANDLE console_out = GetStdHandle(STD_OUTPUT_HANDLE);
    if (console_out == INVALID_HANDLE_VALUE) {
        LPSTR buffer = get_last_error_msg();
        fprintf(stderr, "GetStdHandle() failed with \"%s\" :(\n\n", buffer);
        LocalFree(buffer);
        return false;
    }

    COORD largest_size = GetLargestConsoleWindowSize(console_out);
    if (!largest_size.X && !largest_size.Y) {
        LPSTR buffer = get_last_error_msg();
        fprintf(stderr, "GetLargestConsoleWindowSize() failed with \"%s\" :(\n\n", buffer);
        LocalFree(buffer);
        return false;
    }

    --largest_size.X;
    --largest_size.Y;

    if (!SetConsoleScreenBufferSize(console_out, largest_size)) {
        LPSTR buffer = get_last_error_msg();
        fprintf(stderr, "SetConsoleScreenBufferSize() failed with \"%s\" :(\n\n", buffer);
        LocalFree(buffer);
    }

    if (!ShowWindow(console_window, SW_MAXIMIZE)) {
        fputs("ShowWindow() failed :(\n", stderr);
        return false;
    }

    return true;
}

int main(void)
{
    if (!maximize_console())
        return EXIT_FAILURE;
}

【讨论】:

  • 非常感谢!可悲的是,我必须使用 C 而不是 C++ .. 我只是注意到 stackoverflow 从标题中删除了“C -” :( 至少标签 C 仍然存在。不过它很有帮助,因为 C++ 是我想学习但没有的在 uni 但我可能可以使用部分或大部分,还没有看起来太近。非常感谢!^^
  • 这调用GetLastError 太晚了:"当函数的返回值表明这样的调用将返回有用的数据时,您应该立即调用 GetLastError 函数。 " 不要假设 C++ I/O 流库对于调用线程的最后一个错误代码不会有任何可观察到的副作用。最简单(且安全)的解决方案:将错误代码传递给get_last_error_msg(并重命名函数)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
相关资源
最近更新 更多