4

可以使用 cout 语法显示 windows 消息框吗?

我还需要抑制/隐藏命令提示符窗口。

有很多方法可以调用 messagebox 函数并通过其用法显示文本,但这里的主要约束是必须使用 cout 语法。

cout <<  "message";

我正在考虑在 cout 输出中调用 VB msgbox 命令,但找不到任何有效的方法。

有任何想法吗?

4

7 回答 7

11

C++ 流与控制台或文件流一起使用。Windows 在或多或少完全不同的范式上工作,因此 cout 上下文并不是一个真正适合使用它的范式。您可能会完全混搭一些最终或多或少会起作用的东西,并且看起来或多或少类似于这种语法,但是当您可以这样做时,它并不值得:

MessageBox( NULL, message, "", MB_OK );

有关更多信息,请参阅MessageBox上的完整文档。

于 2009-11-13T16:48:39.390 回答
9

您应该考虑的第一件事是 MessageBox 会停止线程,直到您关闭窗口。如果这是您想要的行为,请继续。

您可以创建自定义 streambuf 并将其设置为std::cout

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

namespace {
    class mb_streambuf : public std::stringbuf {
        virtual ~mb_streambuf() { if (str().size() > 0) sync(); }
        virtual int sync() {
            MessageBoxA(0, str().c_str(), "", MB_OK);
            str("");
            return 0;
        }
    } mb_buf;

    struct static_initializer {
        static_initializer() { 
            std::cout.rdbuf(&mb_buf); 
        }
    } cout_buffer_switch;
}

int main()
{
    std::cout << "Hello \nworld!"; // Will show a popup
}

每当刷新 std::cout 流时,都会显示一个弹出窗口。

于 2009-11-14T11:39:31.967 回答
6

通过包含sstream,您可以使用std::ostringstreamiostream 库来使用和构建消息。然后,您可以调用.str().c_str()并获取char *传递给 MessageBox。

于 2009-11-13T17:11:18.800 回答
6

过去遇到这种情况时,我使用了 astringstream和一个显示 using 的当前内容的操纵stringstreamMessageBox

#include <windows.h>
#include <sstream>
#include <ostream>

std::ostream &MessageBox(std::ostream &s) {
    std::ostringstream *st = dynamic_cast<std::ostringstream *>(&s);
    if (NULL != st)
        ::MessageBox(NULL, st->str().c_str(), "", MB_OK);
    return s;
}

要使用它,语法看起来很像 using cout,但要MessageBox替换std::endl. 例如:

std::ostringstream stm;
stm  << " blah blah blah. Value: " << 1213.1231 << MessageBox;

编辑:主要用于 fnieto。在这种情况下,垂头丧气确实必要的。原因很简单:典型的插入器接收并返回对 ostream 的引用:

std::ostream &operator<<(std::ostream &os, T const &t) { 
    // code here to insert t into os, then return os;
}

这将获取原始的 stringstream 对象并以静默方式(并且安全地)将其转换为简单的 ostream。这本身很好,并且对于大多数插入器和操纵器都可以正常工作,因为它们只与ostream界面本身交互。

然而,这个操纵器有点不同——它使用了根本没有定义的str()成员。ostream对于str()解析和编译的调用,我们必须将 转换ostream &ostringstream &,因此编译器知道我们正在使用的对象确实会有一个str()成员。

为了消除向下转换,我们实际上只有一个选择:将其参数设为ostringstream &. 只要我们从未链接过运算符,这将起作用:

my_stream << x;
my_stream << MessageBox;

但试图链接那些会失败:

// should be equivalent:
my_stream << x << MessageBox;

更糟糕的是,编译器的错误消息可能会试图告诉用户一些关于 的信息std::basic_ostream<char>::str(),而用户的代码中根本没有提到。更糟糕的是,大多数人已经习惯于链接或不给出相同的结果,以至于他们可能需要一段时间才能弄清楚为什么代码有时可以正常工作,而有时却无法编译,并带有完全难以理解的错误消息。

于 2009-11-13T18:43:23.097 回答
3

反正没有简单的方法。

cout 中的 c 代表控制台,所以你可能不走运。

如果它只是您要复制的语法,那么您可以编写自己的流类,在后台创建一个消息框并显示它。

于 2009-11-13T16:49:34.710 回答
3

您可能想检查一下: 如何将标准输出重定向到 Windows 应用程序中的某些可见显示?

于 2009-11-13T16:50:40.730 回答
1

可以使用 cout 语法显示 windows 消息框吗?

你不能用std::cout. std::cout甚至不承诺处理 Unicode/宽字符(请参阅 参考资料std::wcout),尽管 Windowscout处理宽字符没有问题。

您可以使用相同的语法轻松完成;也就是说,您可以轻松编写一个重载operator<<以显示对话框的库。但是,尝试以这种方式将所有信息传递到对话框将非常困难(您如何说要显示哪些按钮,这些按钮在按下时应该做什么,这些按钮应该在哪里,以及窗口本身?)。

您可能想查看类似ncurses的内容。语法不同,但我感觉这是您的同事正在寻找的。

于 2009-11-13T18:13:31.223 回答