【问题标题】:Print text to the middle of the screen将文本打印到屏幕中间
【发布时间】:2021-07-20 04:25:22
【问题描述】:

我在问有没有什么办法,以及如何将诸如 Windows 安装“我们正在为您设置好”之类的文本打印到屏幕中间?如果可以的话,我可以让它只显示文本,文本背景应该是你的桌面。

【问题讨论】:

  • the text background should be your desktop 这是什么意思?您想将桌面图像作为文本打印到控制台吗?
  • @phuclv 表示只显示文本,没有控制台,什么都没有,只有屏幕中间的大文本
  • 如果其中一个答案有帮助,则将其标记为已接受。如果您有不同的解决方案,请发布(并接受)您自己的答案。不要将问题标题更改为“(已解决)”。这对以后阅读您的问题的任何人都有帮助。
  • accept an answer 点击绿色复选标记。编辑问题不是本网站的工作方式。请花 1 分钟阅读tour 了解其工作原理

标签: c++ c windows console centering


【解决方案1】:

在 Windows 中处理控制台的经典方法是通过Console API。要获取控制台大小,您可以使用GetConsoleScreenBufferInfo()。这是一个非常简单的例子,在屏幕中心绘制一个字符串

#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdint>
#include <windows.h>

int main(void)
{
    auto stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
    std::string str;

    CONSOLE_SCREEN_BUFFER_INFO oldcsbi{};
    COORD coord{};
    while (1)
    {
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        GetConsoleScreenBufferInfo(stdout_handle, &csbi);
        if (csbi.srWindow.Bottom != oldcsbi.srWindow.Bottom || csbi.srWindow.Right != oldcsbi.srWindow.Right)
        {
            std::fill(str.begin(), str.end(), ' ');
            SetConsoleCursorPosition(stdout_handle, coord);
            std::cout << str; // clear the old text
            
            oldcsbi = csbi;
            std::ostringstream s;

            s << "Console size: " << csbi.srWindow.Right << 'x' << csbi.srWindow.Bottom;
            str = s.str();
            coord.X = (short)((csbi.srWindow.Right - str.size()) / 2);
            coord.Y = (short)(csbi.srWindow.Bottom/2);
            SetConsoleCursorPosition(stdout_handle, coord);
            std::cout << str; // draw the new text
        }
        Sleep(1000);
    }
}

上面的代码会定期获取控制台大小,如果大小发生变化,则重新绘制屏幕。它会无限循环,直到您按下 Ctrl+C 或关闭程序

有关控制台 API 的更多信息,请参阅Using the Console


当然polling 这样的大小不是很好,因为它使输出不是很平滑并且还占用了 CPU 周期。真正的解决方案是监听调整大小事件并在回调函数中做必要的事情

有一种称为ENABLE_WINDOW_INPUT 的模式将调整大小事件传递到控制台,您可以在控制台中通过阻塞ReadConsoleInput()PeekConsoleInput() API 读取。您可以在Reading Input Buffer Events 中查看示例。只需运行它并调整窗口大小,调整大小事件将被打印出来

不幸的是,在该模式下,只有 console buffer size change event 通过 WINDOW_BUFFER_SIZE_RECORD 触发,并且没有 控制台屏幕大小更改 事件,因此如果您更改行数,那么大多数时候没有事件被生成。这意味着您需要进入较低级别并收听名为 EVENT_CONSOLE_LAYOUTConsole Winevent

HWINEVENTHOOK eventHook = SetWinEventHook(EVENT_CONSOLE_LAYOUT, EVENT_CONSOLE_LAYOUT,
                                        NULL, EventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
...
MSG msg;
while (GetMessage(&msg, g_hWindow, EVENT_CONSOLE_LAYOUT, EVENT_CONSOLE_LAYOUT)) {
    DispatchMessage(&msg);

您可以在

中找到更多详细信息

更简单甚至更好的方法是使用ncurses 并处理类似于SIGWINCH 的内容。过去有很多 ncurses 的 Windows 端口,给定 Windows 10 控制台supportsANSI sequences,编写 ncurses 端口更加容易。事实上,现在是 recommendeduse ANSI sequences 用于终端交互,而不是用于可移植性的 ole Console API

【讨论】:

    【解决方案2】:
    <Window x:Class="YourApplication.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="600" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent"  Topmost="True">
        
        <StackPanel>
            <TextBlock Text="Your Text Here"/>
        </StackPanel>
    </Window>
    

    请注意,这仅在其他应用程序声明自己为 TopMost 之前有效。 Window “on desktop”的建议

    【讨论】:

    • 谢谢,但我想在 c/c++ 中而不是在 c# WPF 中。
    • 抱歉,没有 C/C++ 语言,因此您无法执行此操作。您也许可以在 C 语言 OR C++ 中做到这一点。
    • Thomas,我说我想用 C 或 C++ 语言来做这件事,'/' 表示“或”,所以 C 或 C++ 语言
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    相关资源
    最近更新 更多