Click here to Skip to main content
Click here to Skip to main content

CEditLog - fast logging into an edit control with cout

By , 1 Nov 2003
 

Problem

I once wanted to use an edit control for fast, asynchronous text output. I need to log messages from a lot of threads, sometimes more than 1000 per second. And since I created already functions to dump my objects to std::cout I also wanted to use an edit control as std::ostream.

Features

  • Asynchronous, very fast output to any edit control
  • User can scroll back, select and copy text and so on during output
  • Can be used with or without MFC (Sample is a MFC project)
  • Uses window-subclassing, so you can use it even with CEdit-derived controls
  • Save to be used by multiple threads
  • Special basic_streambuf class to create or redirect a std::ostream (such as std::cout) to an edit control

Using CEditLog

Just create an Instance of CEditLog and attach an edit control to it using the SetEditControl() function. Then you can add text to the end of the edit control using one of the AddText() members:

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

    ...
};

The sample project

The included sample project shows the usage of CEditLog and how to use basic_editstrbuf to redirect std::cout to use the edit log.

CEditLog uses the CSubclassWnd class, written by William E. Kempf for implementation. I have included the soure of CSubclassWnd in the sample project, the complete article is also available here at CodeProject.

History

Version Comments
1.0 First Release
1.1 Minor Revision. Now uses V2.0 of SubclassWindow.
Now really works on Win9x (V1.0 used UNICODE for internal data handling and failed on Win9x systems. Now the code checks if it runs on Win9x and does the required conversions.)
1.2 Minor Revision. Now compiles fine even in VC.NET 2003.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Daniel Lohmann
Germany Germany
Member
Daniel Lohmann (daniel@losoft.de) is Assistant Professor at the Distributed Systems and Operating Systems department at Friedrich-Alexander-University Erlangen-Nuremberg, Germany. His main research topic is the design of a highly customizable and scalable operating system product line for deeply embedded systems using static configuration and aspect-oriented techniques. Before joining Universität Erlangen he worked as a freelance trainer and consultant for NT system programming, advanced C++ programming and OOA/OOD. He is interested in upcoming programming techniques like aspect-oriented programming, generative programming and C++ meta coding and has written some nice and handy tools for Windows NT which you can download at his web site.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionhow I can add color to ceditlog?memberMember 328166623 Apr '13 - 5:18 
GeneralPassed on compiling, but failed on running on Windows VistamemberGolden Lee3 Dec '09 - 19:25 
GeneralRe: Passed on compiling, but failed on running on Windows VistamemberDaniel Lohmann7 Dec '09 - 0:37 
AnswerRe: Passed on compiling, but failed on running on Windows Vistamemberysliou19 May '11 - 3:53 
GeneralRe: Passed on compiling, but failed on running on Windows Vistamember Randor 7 Jul '12 - 13:50 
GeneralRe: Passed on compiling, but failed on running on Windows VistamemberWalter Schmoll19 Sep '12 - 22:40 
GeneralRe: Passed on compiling, but failed on running on Windows Vistamember Randor 17 Oct '12 - 14:09 
QuestionHow can I change the text color in this Classmemberhuyphuc9 Dec '08 - 15:42 
QuestionHow do i use it for CRichEditCtrl?membersmalti16 Aug '07 - 3:02 
GeneralMax. number of lines controlmemberVic Siu7 Oct '06 - 15:59 
QuestionWhat about printfmemberAvri27 Sep '06 - 19:54 
AnswerRe: What about printfmembernikestone24 Nov '06 - 17:31 
GeneralNice but some error in VC2005memberansoncat13 Jun '06 - 19:02 
GeneralRe: Nice but some error in VC2005memberw00tzenheimer21 Jul '06 - 19:39 
GeneralNicememberucc8012 Feb '06 - 23:03 
GeneralSlow logmembervdaanen25 Nov '05 - 1:26 
GeneralRe: Slow logmemberDaniel Lohmann26 Nov '05 - 3:28 
QuestionApplication Crash on exitmemberProf.S.Mukherjee13 Nov '05 - 20:47 
AnswerRe: Application Crash on exitmemberchurl-hee Jo9 May '06 - 18:29 
Hi,
 
I think that it was not recovered stream.
Simply, We need to restore the streams.
 
And, I added the following code in .h and .cpp.
 

//
class CEditLogger : public CDialog
{
private:
std::basic_streambuf* _cold_in;
std::basic_streambuf* _cold_out;
std::basic_streambuf* _cold_err;
std::basic_streambuf* _cold_log;
 
std::basic_streambuf* _wcold_in;
std::basic_streambuf* _wcold_out;
std::basic_streambuf* _wcold_err;
std::basic_streambuf* _wcold_log;
 

protected:
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* m_pOldBuf;
std::basic_streambuf* m_pOldBufW;
:
:
}
 

 
CEditLogger::CEditLogger(CWnd* pParent /*=NULL*/)
: CDialog(CEditLogger::IDD, pParent), m_EditStrBuf( m_EditLogger ), m_EditStrBufW( m_EditLogger )
{
_cold_in = cin.rdbuf();
_cold_out = cout.rdbuf();
_cold_err = cerr.rdbuf();
_cold_log = clog.rdbuf();
 
_wcold_in = wcin.rdbuf();
_wcold_out = wcout.rdbuf();
_wcold_err = wcerr.rdbuf();
_wcold_log = wclog.rdbuf();
 
//{{AFX_DATA_INIT(CEditLogger)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
 
void CEditLogger::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
cin.rdbuf( _cold_in );
cout.rdbuf( _cold_out );
cerr.rdbuf( _cold_err );
clog.rdbuf( _cold_log );
 
wcin.rdbuf( _wcold_in );
wcout.rdbuf( _wcold_out );
wcerr.rdbuf( _wcold_err );
wclog.rdbuf( _wcold_log );
 
CDialog::PostNcDestroy();
}
 

 
I
QuestionHow to change fontmemberMarko Winter13 Jul '05 - 1:38 
AnswerRe: How to change fontmemberDaniel Lohmann13 Jul '05 - 22:24 
GeneralRe: How to change fontmemberMarko Winter14 Jul '05 - 23:42 
Generalx64 (AMD64) portability problemmemberModMa28 Jun '05 - 6:36 
AnswerRe: x64 (AMD64) portability problemmemberpc_jisakker5 Apr '09 - 5:19 
GeneralVery GoodmemberIain Fraser / Zeus9 May '05 - 4:21 
GeneralNo output at all when switching between several output destinationssussasango29 Apr '05 - 9:49 
GeneralRe: No output at all when switching between several output destinationsmemberDaniel Lohmann2 May '05 - 2:56 
GeneralRe: No output at all when switching between several output destinationsmemberasango@gmx.net2 May '05 - 8:07 
GeneralSave the log content into file.memberronenw5 Dec '04 - 4:02 
GeneralUseful tool.memberronenw24 Nov '04 - 4:16 
Generalnot using standard c++ librariesmembersammyc21 Sep '04 - 17:16 
QuestionIs it really thread safed?sussyuancc@21cn.com15 Jun '04 - 2:59 
AnswerRe: Is it really thread safed?memberDaniel Lohmann18 Jun '04 - 0:06 
GeneralRe: Is it really thread safed?sussyuancc@21cn.com19 Jun '04 - 0:30 
QuestionHow to reduce Flicker?memberpmackell17 Sep '03 - 9:08 
AnswerRe: How to reduce Flicker?membergbiddison24 Jun '04 - 20:09 
GeneralRe: How to reduce Flicker?memberRJSoft23 Aug '04 - 3:04 
AnswerRe: How to reduce Flicker?memberlano11064 Jul '06 - 18:47 
Questionwhat about printf?memberomasoud14 Jul '03 - 14:32 
AnswerRe: what about printf?memberDaniel Lohmann14 Jul '03 - 21:28 
GeneralRe: what about printf?memberomasoud15 Jul '03 - 0:35 
GeneralRe: what about printf?memberDaniel Lohmann16 Jul '03 - 5:32 
GeneralHimemberannum14 Jun '03 - 16:19 
GeneralRe: HimemberDaniel Lohmann15 Jun '03 - 1:33 
GeneralRe: Hi Coloringmemberpmackell17 Sep '03 - 9:06 
GeneralCEditLog and FormViewmemberabstract312 Jun '03 - 8:59 
GeneralRe: CEditLog and FormViewmemberDaniel Lohmann15 Jun '03 - 1:40 
GeneralRe: CEditLog and FormViewmembersammyc6 Dec '04 - 14:52 
GeneralRe: CEditLog and FormViewmembersammyc6 Dec '04 - 15:13 
GeneralRe: CEditLog and FormViewmemberDaniel Lohmann6 Dec '04 - 21:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 2 Nov 2003
Article Copyright 2000 by Daniel Lohmann
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid