代码之家  ›  专栏  ›  技术社区  ›  CheeseConQueso

在Windows对话框中使用“cOUT”-C++显示消息

  •  4
  • CheeseConQueso  · 技术社区  · 16 年前

    是否可以使用cout语法显示Windows消息框?

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

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

    cout <<  "message";
    

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

    有什么想法吗?

    7 回复  |  直到 16 年前
        1
  •  9
  •   Fernando N.    16 年前

    首先要考虑的是,在关闭窗口之前,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流被刷新时,都会显示一个弹出窗口。

        2
  •  10
  •   Russell Newquist    16 年前

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

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

    查看上的完整文档 MessageBox 更多信息。

        3
  •  6
  •   Stephen Newell    16 年前

    通过包括 sstream ,你可以使用 std::ostringstream 并使用iostream库构建消息。然后你可以打电话 .str().c_str() 得到一个 char * 传递到消息框。

        4
  •  6
  •   Jerry Coffin    16 年前

    在过去遇到这种情况时,我用了 stringstream 以及显示 横流 使用 MessageBox :

    #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;
    }
    

    要使用它,语法看起来相当像使用 cout 但是 对话框 替代 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() 成员,哪个 溪流 完全没有定义。为了我们的召唤 str()。 要解析和编译,我们必须转换 ostream & 对 ostringstream & ,因此编译器意识到我们正在处理的对象 () 成员。

    为了消除负面影响,我们只有一个选择:使其参数为 ostringstream& . 只要我们不链接操作员:

    my_stream << x;
    my_stream << MessageBox;
    

    但是试图将这些链条连接起来会失败:

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

    更糟的是,编译器的错误消息可能会试图告诉用户关于 std::basic_ostream<char>::str() ,用户代码中根本没有提到。更糟糕的是,大多数人已经足够习惯于链接或者不给出相同的结果,这可能需要花费他们一段时间来弄清楚为什么代码有时工作得很好,而其他时候由于完全无法识别的错误消息而无法编译。

        5
  •  3
  •   Glen    16 年前

    无论如何都不是简单的方法。

    C in c out代表控制台,所以你可能走运了。

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

        7
  •  1
  •   Max Lybbert    16 年前

    是否可以使用cout语法显示Windows消息框?

    你不能用 std::cout . 性病:咳嗽 甚至不承诺处理unicode/wide字符(请参见 std::wcout ,尽管Windows的 cout 对宽字符没有问题。

    你也可以很容易地做到 句法 ;也就是说,您可以轻松地编写一个重载的库。 operator<< 显示对话框。但是,试图以这种方式将所有信息传递到对话框是非常困难的(您会怎么说要显示哪些按钮,按下这些按钮时应该做什么,这些按钮应该在哪里,以及窗口本身的大小和位置?).

    你可能想看看 ncurses . 语法不同,但我有一个 感觉这就是你的同事想要的。