控制台输出重定向到MFC的view对象里
来源:互联网 发布:淘宝开店经历 编辑:程序博客网 时间:2024/04/27 13:29
一、闲扯
今天领导心血来潮说服务器的运行界面是一个黑乎乎的控制台,太低端了,看我们能不能把它图形化,至少做成一个窗口有按钮点启动、停止。好吧,领导拍脑袋就叫人干活的事不少,也没有产品规划,也就是让他看的舒服,只能去做了。
其中有一个关键性问题,就是原先是往控制台输出的信息,使用mfc图形化之后该往哪输出,工程维护人员肯定还是希望能在图形界面上能够看到这些信息的,因此就涉及到了如何获取到输出控制台的消息(都是cout、printf这种标准输出),然后再将这些消息重写到view上。这时候想到了标准输出重定向,因此整理了下思路:
1.将标准输出重定向到管道
2.创建一个线程从管道里取出数据
3.在view的OnPaint中将数据显示出来
二、实现
1.创建管道
BOOL bRet = CreatePipe(&hRead, &hWrite, NULL, 0); // 创建匿名管道if (bRet != TRUE) printf("创建匿名管道失败,错误代码:%d\n", GetLastError());
2.将标准输出重定向到管道的写句柄中
int nOpenHandle = _open_osfhandle((intptr_t)hWrite, _O_TEXT);FILE* fp = _fdopen( nOpenHandle, "w");*stdout = *fp;
注意:这里不能使用SetStdHandle(STD_OUTPUT_HANDLE, hWrite),在MFC中SetStdHandle是没有效果的。
3.创建线程从管道取数据
boost::thread thr(boost::bind(&CKDSShellView::print_cb, this));
这里用到boost的thread创建线程,CKDSShellView就是你自己的view了,print_cb是自定义的线程函数。
void CKDSShellView::print_cb(){DWORD ReadNum = 0;char ReadBuf[1024] = {0};while (1){memset(ReadBuf, 0, 1024);ReadFile(hRead, ReadBuf, 1024, &ReadNum, NULL);if (ReadNum == 0 || ReadBuf[0] == 0){continue;}this->AppendLog(ReadBuf);}}
死循环,通过ReadFile函数从管道的读句柄hRead中取出数据,然后AppendLog到一个vector容器中。
void CKDSShellView::AppendLog(const std::string& strLog){if (log_vector.size() > 1024){log_vector.erase(log_vector.begin());}std::vector<std::string> tmp;boost::split(tmp, strLog, boost::is_any_of("\n"));for (int i = 0; i < tmp.size(); ++i){boost::trim(tmp[i]);if (!tmp[i].empty()){std::string str = tmp[i];std::string::iterator it = str.end();while(str.size() > 1){it = str.end() - 1;if(*it == '\n' || *it == '\r'){str.erase(it);}else{break;}}log_vector.push_back(str);}}if(::IsWindow(m_hWnd)){Invalidate();this->UpdateWindow();}}
由于输出的字符串有\n\r的换行符,并且可能有多条日志同时输出,在view中显示不美观,因此做了一些字串的调整,主要是有log_vector.push_back(str),这是将处理好的字符串装入容器中,然后通过UpdateWindow()触发view的OnPaint()。
void CKDSShellView::OnPaint(){CPaintDC dc(this); // device context for painting// TODO: 在此处添加消息处理程序代码// Set the text color to reddc.SetTextColor(RGB(0, 0, 0)); // 可根据日志警告级别改变字体颜色// Set the background mode for text to transparent // so background will show thru.dc.SetBkMode(TRANSPARENT);//////////////////////////////////////////////////////////////////////////TEXTMETRIC tm;dc.GetTextMetrics(&tm);int nFontHeight = tm.tmHeight; // 字体高度int nExternal = tm.tmExternalLeading; // 估计是行距CRect rect;GetWindowRect(&rect);int nMaxShowLine = rect.Height() / (nFontHeight * 1.1);int i = 0;if(nMaxShowLine < log_vector.size()){i = log_vector.size() - nMaxShowLine;}int j = 0;for(; i < log_vector.size(); i++){x = 4;y = j * nFontHeight * 1.1;dc.TextOut(x,y,log_vector[i].c_str(),log_vector[i].length());j++;}// 不为绘图消息调用 CView::OnPaint()}
效果如下图:
- 控制台输出重定向到MFC的view对象里
- MFC控制台指令的重定向输出到文件方法
- mfc重定向到控制台
- QT里重定向另外一个控制台程序的输出
- MFC:Debug控制台重定向输出
- 控制台输出重定向到Memo
- eclipse控制台输出重定向到…
- eclipse控制台输出重定向到文件
- makefile的输出重定向, 到文件里
- 控制台应用程序的输出流重定向
- 重定向控制台System.out.println输出到文件,再重定向回控制台
- C++在Win32中重定向输出数据到控制台
- eclipse控制台输出重定向
- 重定向java控制台输出 到swing 的 jtextfild组件中
- c#中重定向windows控制台程序的输出信息
- c#中重定向windows控制台程序的输出信息
- c#中重定向windows控制台程序的输出信息
- c#中重定向windows控制台程序的输出信息
- Backbone.js学习笔记——Collection篇
- API函数MoveFileEx使用详解(delphi)
- 1784:Digital Roots
- 访问网站报错“配置错误 不能在此路径中使用此配置节”
- 逻辑读与物理读
- 控制台输出重定向到MFC的view对象里
- HTTP 错误 500.22 - Internal Server Error
- 转载: OpenCV中HOG人检测以及Part Model latent SVM目标识别 | 丕子 http://www.zhizhihu.com/html/y2011/3436.html
- nyist-68
- 1072:找规律填数字
- cmd 命令oracle 中数据库完全导入导出
- Hbase for Java API
- 宏定义\字符串 多行书写时换行
- 谷歌浏览器翻译扩展工具 Google Translate 1.2.4