下载:
http://www.vrixpzone.com/zone2/codeRepo/vc/EditLog_src.zip
我曾经想使用EDIT控件来快速的处理异步文本输出。我需要在很多线程里记录大量的信息。有时候每秒1000个Log信息。自从我创建了一些函数把我要的对象信息输出到 std::cout ,我也想吧edit控件作为std::ostream.
创建CEditLog 的一个实例并通过SetEditControl() 方法把它和EDIT控件绑定,然后你就可以用AddText() 成员函数来添加一些文本到EDIT控件了。
class CEditLog : protected CSubclassWnd{public: typedef CSubclassWnd root_type; // Constructs the CEditLog. You can pass the edit controls handle // here or set it later using the SetEditCtrl() function. // To increase performance CEditLog repaints the edit-control // only if the caret resides in the last line. Otherwise the // control will be refreshed only every nMaxRefreshDelay msec. CEditLog( HWND hEdit = NULL, UINT nMaxRefreshDelay = 500 ); // Adds some text to the end of the edit control. Works asynchronously // (using PostMessage()) and is save to be called by multiple threads. // If you pass true for bLFtoCRLF every LF (ASCII 10) (as it is used in // most cases for end-of-line) will be converted to a CR/LF (ASCII 10/13) // sequence as it is needed by the windows edit control. virtual void AddText( LPCWSTR pwszAdd, bool bLFtoCRLF = false ); // Converts pszAdd to UNICODE and calls the above void AddText( LPCSTR pszAdd, bool bLFtoCRLF = false ); // Sets the edit-control to be used for logging. // Pass NULL to stop text logging. virtual void SetEditCtrl( HWND hEdit ); HWND GetEditCtrl() const ...};
实例代码中演示了CEditLog 的用法以及basic_editstrbuf 如何重定向 std::cout 到EDIT控件.
CEditLog 用到了William E. Kempf 写的CSubclassWnd 类,实例代码中也包含了CSubclassWnd 类
-------------以上翻译由vrix.yan完成于2007.09.30 21:18
在使用此类的过程当中,我总结了一下的步骤:
1>将实例工程中的code子目录,复制到你的工程目录中
2>在你的对话框xxDlg.h 里引入头文件,并定义一些变量
#include "EditLog.h"#include "editlog_stream.h"
// The logger object CEditLog m_EditLogger; // ANSI and UNICODE stream buffers for the EditLogger std::editstreambuf m_EditStrBuf; std::weditstreambuf m_EditStrBufW;
// Used to save the previos values for cout and wcout std::basic_streambuf<char>* m_pOldBuf; std::basic_streambuf<wchar_t>* m_pOldBufW;
3>在你的stdafx.h中加入
// Include core STL header#include <string>#include <streambuf>#include <iostream>
4>在你的xxDlg.cpp 中记得添加一下的代码
CEditLogDlg::CEditLogDlg(CWnd* pParent /*=NULL*/) : CDialog(CEditLogDlg::IDD, pParent), m_EditStrBuf( m_EditLogger ), m_EditStrBufW( m_EditLogger )
5>在你的xxDlg.cpp里面OnInitDialog初始化
// 设置EDIT控件为LOG的目标 m_EditLogger.SetEditCtrl( m_ctrlEdit.m_hWnd ); //记得要先定义Edit 控件
// 重定向cout 的输出到 Edit控件 m_pOldBuf = cout.rdbuf( &m_EditStrBuf ); // unicode 版本 m_pOldBufW = wcout.rdbuf( &m_EditStrBufW );
// 用法 cout << "cout (ANSI) works :-)" << endl; wcout << L"wcout (UNICODE) works also ;-)" << endl; cout << "/n/n";
6>在你的WM_DESTROY消息里加入
void CEditLogDlg::OnDestroy() { // Restore the previous stream state for cout and wcout cout.rdbuf( m_pOldBuf ); wcout.rdbuf( m_pOldBufW );
CDialog::OnDestroy();}
我通过以上的步骤,成功的在我的程序里使用了EDITLOG类,希望对大家有所帮助。
vrix.yan 2007年09月30日晚 21点30分 写于 东莞
