【问题标题】:Display message in windows dialogue box using "cout" - C++使用“cout”在 Windows 对话框中显示消息 - C++
【发布时间】:2010-12-16 08:53:06
【问题描述】:

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

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

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

cout <<  "message";

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

有什么想法吗?

【问题讨论】:

  • 如果您有一个 C++ 控制台应用程序,并且您正试图将其转变为一个 Windows 应用程序,那么您最不必担心。
  • cout &lt;&lt; "Hello" &lt;&lt; user_name; 会显示多少个对话框?
  • @Dan - 这是我所在学校的一位讲师的请求,他正在教 C++,但不希望学生能够访问命令提示符。 @Eric - 只有 1 个
  • @Cheese:我建议让学生混合使用消息框(因为它有效)和字符串流(因为它是类似于 cout 的流)将是一个更好的解决方案。见斯蒂芬纽厄尔的回答。控制台程序和消息框程序完全不同,试图强迫学生以同样的方式对待它们让我觉得这是一种糟糕的教学方式。
  • @Brian - 我同意,但我不是老师,也不是告诉老师如何上课的人 - 他是部门负责人

标签: c++ windows messagebox cout


【解决方案1】:

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

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

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

【讨论】:

  • 是的,这就是我对这个人的建议,但他们希望 cout 成为考验的一部分,原因不明
  • 他们特别想要 cout,或者他们想要类似于 cout 的流?
  • 我 90% 确定他们特别想要 cout。这是一位教练,他可能会按书本上。他们不希望学生能够访问命令提示符
  • 让他在这里登录,这样我们就可以告诉他使用 cout 是不可能的。
  • @jmucchiello,如果您不积极,请不要走得太快,看看这里:stackoverflow.com/questions/1730427/…
【解决方案2】:

您应该考虑的第一件事是 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 流时都会显示一个弹出窗口。

【讨论】:

  • 它告诉我的第一件事是包含 stdafx.h.... 在包含它之后,我遇到了一堆错误,直到那个人回来测试一些新的再次和我在一起
  • 这些问题与此代码无关,而是与项目中的“预编译头”选项有关。
  • 这里需要注意的是:以下仅显示“endl”之间的每个文本块一行。除非我用endl 显式终止输出,或者调用 cout.flush() ,否则不会显示最后一个块。 (例如 cout
  • @Jason D. 对,它应该有一个覆盖的析构函数在退出前刷新剩余数据。顺便说一句,&lt;&lt;std::endl 相当于做&lt;&lt;"\n"&lt;&lt;std::flush 所以你可以用\n 换行。
  • 让它工作...谢谢...问题不在代码中,而是项目的设置方式
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    过去遇到这个问题时,我使用了stringstream 以及一个使用MessageBox 显示stringstream 的当前内容的操纵器:

    #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,但用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 &amp; 转换为ostringstream &amp;,因此编译器知道我们正在使用的对象确实会有一个str() 成员。

    要消除向下转换,我们实际上只有一个选择:将其参数设为ostringstream &amp;。只要我们从不链接操作符,这将起作用:

    my_stream << x;
    my_stream << MessageBox;
    

    但试图将它们链接起来会失败:

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

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

    【讨论】:

      【解决方案5】:

      反正没有简单的方法。

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

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

      【讨论】:

      • 他只想要类似 cout 的语法,而不想要 cout 本身。 std::ostringstream 可用于构建要传递给 windows 对象的字符串。根据斯蒂芬纽厄尔的回答。
      • @Clifford,是的,我知道他可能只想要流语法。这就是为什么我提到使用他自己的流类来调用底层的消息框功能。也许我不够清楚......
      • 在大多数操作系统中,您可以将标准输入/输出重定向到另一个文件或管道,如果这样做了,那么它不再是“控制台输出”,而只是普通的“标准输出”
      【解决方案6】:

      【讨论】:

      • 将这种技术与 Jerry COffin 的技术结合使用可能会产生一个程序,该程序除了初始化之外没有任何改变,成功地将 cout 变成一个消息框。此外,它会很糟糕(但可能会让这个人开心)。
      【解决方案7】:

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

      std::cout 无法做到这一点。 std::cout 甚至不承诺处理 Unicode/宽字符(参见 std::wcout),尽管 Windows 的 cout 对宽字符没有任何问题。

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

      您可能想查看ncurses 之类的内容。语法不同,但我有一个 感觉这就是你的同事正在寻找的东西。

      【讨论】:

        猜你喜欢
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多