C++ 将控制台输出重定向到同一解决方案中的MFC屏幕输出

C++ 将控制台输出重定向到同一解决方案中的MFC屏幕输出,c++,visual-c++,mfc,C++,Visual C++,Mfc,我整天都在胡闹,试图让我的MFC应用程序在屏幕上显示控制台应用程序的日志输出。从Visual Studio 2013向导提供的内容开始,我可以修改他们的代码,将字符串作为输入,并创建应用程序消息的运行日志(如下所示): 但是,我不能从MFC函数外部调用它,原因有很多。一个是对象在全局范围内不可见,另一个是我在应用程序的控制台部分使用windows.h,它不能很好地与MFC配合使用 我的大部分应用程序都已经编写好了,我正在尝试在其周围放置一个GUI,并使用功能区功能。有没有办法将cout语句传送到

我整天都在胡闹,试图让我的MFC应用程序在屏幕上显示控制台应用程序的日志输出。从Visual Studio 2013向导提供的内容开始,我可以修改他们的代码,将字符串作为输入,并创建应用程序消息的运行日志(如下所示):

但是,我不能从MFC函数外部调用它,原因有很多。一个是对象在全局范围内不可见,另一个是我在应用程序的控制台部分使用windows.h,它不能很好地与MFC配合使用


我的大部分应用程序都已经编写好了,我正在尝试在其周围放置一个GUI,并使用功能区功能。有没有办法将cout语句传送到我的MFC应用程序中的消息日志显示?今天,我在谷歌上搜索了很多东西,没有发现任何简单明了的东西,也没有发现将MFC和控制台代码作为解决方案一部分的应用程序。我没有调用单独的可执行文件或dll。这都是作为一个单独的exe编译的。

我不知道MFC,但我会从
std::streambuf
派生一个类,将其输出重定向到MFC类,并将生成的流缓冲区安装到
std::cout
。流缓冲区处理写入流的输出,您可以在其
overflow()
sync()方法中获得写入的字符:

class windowbuf
    : std::streambuf {
    SomeHandle handle;
    char       buffer[256];
public:
    typedef std::char_traits<char> traits;
    windowbuf(SomeHandle handle): handle(handle) { this->setp(buffer, buffer + 255); }
    int overflow(int c) {
        if (!traits::eq_int_type(c, traits::eof())) {
            *this->pptr() = traits::to_char_type(c);
            this->pbump(1);
        }
        return this->sync() == -1? traits::eof(): traits::not_eof(c);
    }
    int sync() {
        writeToHandle(this->handle, this->pbase(), this->pptr() - this->pbase());
        this->setp(buffer, buffer + 255);
        return 0;
    }
};

我认为类似于上述方法的东西应该能够弥合写入
std::cout
的代码与使用某种GUI显示信息的代码的其他部分之间的差距。

您是否尝试在VS中写入调试输出窗口?不,我尝试向用户提供输出。例如,他们有一个高尔夫得分列表,我在输出屏幕上给他们最优秀的球员。或者错误,比如他们有坏数据。考虑到MFC的
包括
,声称MFC不能很好地处理
,这有点牵强。你忽略了困难的部分:连接控制台的STDOUT,
后面的部分从某处获取句柄()
。如果你做了这个非阻塞(你必须这样做,因为你是在GUI线程上运行的)。@IInspectable:我当然没有遗漏捕获程序输出到
std::cout
:这就是流缓冲区的意义所在!最初的请求实际上不是关于捕获程序输出,而是关于写入
std::cout
的内容,这要简单得多。在线程之间传输字符也不是什么大问题:只需将它们写入一个合适的队列。我明白你的意思,你的
SomeHandle
指的是GUI小部件。在线程之间传输输出仍然有些困难。不过,我还是得到了+1。我希望不会牵涉到这件事。有人会认为微软会有一个更简单的解决方案,将一个hpp文件的输出写入另一个hpp文件的窗口。@matusi143:我不能对Windows部件进行评论,我可以想象有一个类大致完成了我上面概述的工作。然而,我是一名UNIX程序员,我只能对它的IOStreams端进行评论。上述方法仍然可以为找到合适的类提供必要的起点。
class windowbuf
    : std::streambuf {
    SomeHandle handle;
    char       buffer[256];
public:
    typedef std::char_traits<char> traits;
    windowbuf(SomeHandle handle): handle(handle) { this->setp(buffer, buffer + 255); }
    int overflow(int c) {
        if (!traits::eq_int_type(c, traits::eof())) {
            *this->pptr() = traits::to_char_type(c);
            this->pbump(1);
        }
        return this->sync() == -1? traits::eof(): traits::not_eof(c);
    }
    int sync() {
        writeToHandle(this->handle, this->pbase(), this->pptr() - this->pbase());
        this->setp(buffer, buffer + 255);
        return 0;
    }
};
int main() {
    SomeHandle handle = get_a_handle_from_somewhere();
    std::streambuf* cout_rdbuf = std::cout.rdbuf(new windowbuf(handle));
    // run your program here
    std::cout.rdbuf(cout_rdbuf); // this should really be restored using RAII approaches
}