您的位置:首页 > 其它

如何将cout输出显示到mfc界面

2017-06-26 18:52 946 查看
最近在做实验室项目,因为某些原因需要在MFC下开发,源码中涉及的COUT输出需要显示。

开始采取的方案一直是在控制台中显示,由于SetWindowText和GetWindowText代替了控制台的流,mfc下不能直接使用cout。

借鉴http://blog.csdn.net/wf6892/article/details/52955935

在MFC中使用cout

文中的方法如下:

1.在MainFrame.h中添加头文件:

#include <io.h>
#include <fcntl.h>

2.在MainFrame.h中声明函数:

public:
bool OpenConsole();

3.在MainFrame.cpp中添加函数定义:

bool CMainFrame::OpenConsole()
{
// 保证函数只执行一次
static bool Runed = false;
if (Runed)
return false;
Runed = true;

bool result;
HANDLE hStd;
FILE* fp;
long hFile;

result = AllocConsole();
hStd = GetStdHandle(STD_INPUT_HANDLE);
hFile = (long)_open_osfhandle((intptr_t)hStd, _O_TEXT);
fp = _fdopen(hFile, "r");
(*stdin) = (*fp);

hStd = GetStdHandle(STD_OUTPUT_HANDLE);
hFile = (long)_open_osfhandle((intptr_t)hStd, _O_TEXT);
fp = _fdopen(hFile, "w"); // 注意:必须是可写模式
(*stdout) = (*fp);

hStd = GetStdHandle(STD_ERROR_HANDLE);
hFile = (long)_open_osfhandle((intptr_t)hStd, _O_TEXT);
fp = _fdopen(hFile, "w"); // 注意:必须是可写模式
(*stderr) = (*fp);

cout << "打开控制台成功" << endl;

return result;
}

4.在MainFrame的构造函数中添加
OpenConsole();
5.在要cout的类的头文件中加入如下代码:

#include<iostream>
using namespace std;

该方法能够在MFC控制台中输出代码片中cout和printf的信息!

后面因为需要在UI界面中进行输出,所以不得不另谋他路,使用的方法是直接从流中读取数据进行输出,这里说明一下,我的控件是多行文本,如果出现字符串闪动或者太长的话,可以参考这篇博客http://blog.csdn.net/jinhill/article/details/6180321

VC编辑框追加字符串并自动滚屏功能

在UI界面输出

首先建立一个头文件

log.h

template <class Elem = char, class Tr = std::char_traits<Elem>>
class StandardOutputRedirector : public std::basic_streambuf<Elem, Tr> {
typedef void(*cb_func_ptr)(const Elem*, std::streamsize count, void* data);
//typedef void(*cb_func_ptr)(const Elem*, std::streamsize count);

public:
StandardOutputRedirector(std::ostream& stream, cb_func_ptr cb_func,
void* data)
: stream_(stream), cb_func_(cb_func), data_(data) {
buf_ = stream_.rdbuf(this);
};

~StandardOutputRedirector() { stream_.rdbuf(buf_); }

std::streamsize xsputn(const Elem* ptr, std::streamsize count) {
cb_func_(ptr, count, data_);
return count;
}

typename Tr::int_type overflow(typename Tr::int_type v) {
Elem ch = Tr::to_char_type(v);
cb_func_(&ch, 1, data_);
return Tr::not_eof(v);
}

private:
std::basic_ostream<Elem, Tr>& stream_;
std::streambuf* buf_;
cb_func_ptr cb_func_;
void* data_;
};

StandardOutputRedirector<char, std::char_traits<char>>* cout_redirector_;


在XXX.H中添加:

public:
static void update(const char* text, std::streamsize count, void* log_widget_ptr);
void show(const char* text, std::streamsize count, void* log_widget_ptr);
private:
static Reconstruction * res
在XXX.CPP中添加:

需要在XXX类构造函数中添加

res = this;
cout_redirector_ = new StandardOutputRedirector<char, std::char_traits<char>>(std::cout, update, this);另外需要添加
XXX* XXX::res;
void XXX::update(const char* text, std::streamsize count, void* log_widget_ptr) {
res->show(text, count, log_widget_ptr);

}

void XXX::show(const char* text, std::streamsize count, void* log_widget_ptr) {
std::string text_str;
for (std::streamsize i = 0; i < count; ++i) {
if (text[i] == '\n') {
text_str += "\n";
}
else {
text_str += text[i];
}
}
CEdit *pEt = (CEdit *)GetDlgItem(LOG_EDIT);
int nLength = pEt->SendMessage(WM_GETTEXTLENGTH);
pEt->SetSel(nLength, nLength);
pEt->ReplaceSel(text_str.c_str());
pEt->LineScroll(pEt->GetLineCount());
}之所以会使用到两个函数和一个静态变量,是因为出现的静态函数调用非静态成员函数或变量带来的问题,如果要对文本框进行赋值显示,必须先声明及实例化一个对象才可以,因此为了避免这点带来的问题,特意先声明一个静态变量和非静态成员函数。
如上,就应该可以在LOG_EDIT文本框中得到COUT的输出了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐