CEditLog - 使用 cout 快速将日志记录到编辑控件






4.69/5 (30投票s)
使用编辑控件记录消息并重定向 cout。
问题
我曾经想使用一个编辑控件来进行快速、异步的文本输出。我需要从许多线程记录消息,有时每秒超过 1000 条。而且由于我已经创建了将我的对象转储到 std::cout
的函数,我也希望将编辑控件用作 std::ostream
。
特点
- 异步、非常快速的输出到任何编辑控件
- 用户可以在输出期间滚动、选择和复制文本等
- 可以与或不与 MFC 一起使用(示例是一个 MFC 项目)
- 使用窗口子类化,因此即使对于派生自 CEdit 的控件也可以使用它
- 保存以便由多个线程使用
- 特殊的
basic_streambuf
类,用于创建或重定向std::ostream
(例如std::cout
)到编辑控件
使用 CEditLog
只需创建一个 CEditLog
的实例,并使用 SetEditControl()
函数将其附加到编辑控件。然后,您可以使用 AddText()
成员之一将文本添加到编辑控件的末尾
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
重定向到使用编辑日志。
CEditLog
使用 William E. Kempf 编写的 CSubclassWnd
类来实现。我已将 CSubclassWnd
的源代码包含在示例项目中,完整的文章也在此处 CodeProject 上提供。
历史
版本 | 注释 |
1.0 | 首次发布 |
1.1 | 小幅修订。现在使用 SubclassWindow 的 V2.0 版本。现在确实可以在 Win9x 上工作(V1.0 在内部数据处理中使用 UNICODE,并在 Win9x 系统上失败。现在代码检查它是否在 Win9x 上运行并进行必要的转换。) |
1.2 | 小幅修订。现在即使在 VC.NET 2003 中也能很好地编译。 |