1
votes

I have been messing around all day trying to get my MFC application to show the log output of a console application on the screen. Starting with what Visual Studio 2013's wizard gave me, I was able to modify their code to take a string as input and make a running log of application messages (below):

void COutputWnd::FillBuildWindow(std::string build_text)
{
std::wstring wsTmp(build_text.begin(), build_text.end());
std::wstring z = wsTmp;
LPTSTR x = new TCHAR[z.size() + 1];
_tcscpy(x, z.c_str());
m_wndOutputBuild.AddString(x);
free(x);
}

However, I cannot call this from outside the MFC function for a number of reasons. One is the object is not visible globally and two I am using windows.h in the console parts of my application and it does not play nicely with MFC.

Much of my application is already written and I am trying to put a GUI around it and use the ribbon features. Is there any way to take the cout statements and pipe them to a message log display in my MFC app? I have googled a ton of things today and not found anything that is either straightforward or clearly for applications which have both MFC and console code as part of their solution. I am not invoking a separate executable or dll. This is all compiled as a single standalone exe.

1
Are you trying to write to the Debug Output window in VS?Jim Rhodes
No, I am trying to present the user with output. For example they have a list of golf scores and I give them the top players in the output screen. Or errors, like they had bad data.matusi143
It's a bit of a far stretch to claim that MFC doesn't cope well with <windows.h>, considering that MFC's <afxv_w32.h> includes <windows.h>.IInspectable

1 Answers

3
votes

I have no idea about MFC but I would derive a class from std::streambuf to redirect its output to an MFC class and install the resulting stream buffer into std::cout. The stream buffer deals with the output written to a stream and you can get hold of the written characters in its overflow() and sync() methods:

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

The above is a simple stream buffer which transfers characters somewhere identified by handle when its buffer is full or when the stream is flushed. I think it should be doable to come up with some handle and a write function which transfers the characters to an MFC window although I don't know anything about that part.

To have std::cout send its characters to the above stream buffer, you just need to install this stream buffer into std::cout, e.g., using

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
}

I'd think something like the above approach should be able to bridge the gap between some code writing to std::cout and other parts of the code displaying information with some sort of GUI.