Click here to Skip to main content
15,880,392 members
Articles / Desktop Programming / MFC
Article

CEditLog - fast logging into an edit control with cout

Rate me:
Please Sign up or sign in to vote.
4.69/5 (32 votes)
1 Nov 2003CPOL 310.1K   4K   86   84
Use an edit control for logging messages and redirect cout

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

VersionComments
1.0First Release
1.1Minor 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.2Minor 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)


Written By
Germany Germany
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.

Comments and Discussions

 
GeneralNo output at all when switching between several output destinations Pin
asango@gmx.net29-Apr-05 9:49
asango@gmx.net29-Apr-05 9:49 
GeneralRe: No output at all when switching between several output destinations Pin
Daniel Lohmann2-May-05 2:56
Daniel Lohmann2-May-05 2:56 
GeneralRe: No output at all when switching between several output destinations Pin
asango@gmx.net2-May-05 8:07
asango@gmx.net2-May-05 8:07 
GeneralSave the log content into file. Pin
ronenw5-Dec-04 4:02
ronenw5-Dec-04 4:02 
GeneralUseful tool. Pin
ronenw24-Nov-04 4:16
ronenw24-Nov-04 4:16 
Generalnot using standard c++ libraries Pin
S.Cartwright21-Sep-04 17:16
S.Cartwright21-Sep-04 17:16 
QuestionIs it really thread safed? Pin
yuancc@21cn.com15-Jun-04 2:59
sussyuancc@21cn.com15-Jun-04 2:59 
AnswerRe: Is it really thread safed? Pin
Daniel Lohmann18-Jun-04 0:06
Daniel Lohmann18-Jun-04 0:06 
yuancc@21cn.com wrote:
In the following code:
// Retrieve the text from our buffer
// We store it in a local variable to prevent long time locking
::EnterCriticalSection( &m_csLock );
wsText = m_wsStore; // Is this line thread-safed?
m_bMessagePending = false;
::LeaveCriticalSection( &m_csLock );

both wsText and m_wsStore maybe share the string buffer but increasing a reference count. if std::string isn't thread-safed, I think we really need a deeply copy on m_wsStore object.


Thats an interesting point! OMG | :OMG:

Well, on the first sight I was thinking that you are absolutely right here. However, on the second sight, I am not so sure that it isn't threadsafe. As far as I understood, STL is thread-safe on the class level (different instances may be used by different threads) unless explicitly stated otherwise. And it should be not that difficult to implement this for std::basic_string. If the buffer is shared between string instances, it is shared only for reading and a copy on write is performed, before any one of the threads is performing a write operation. I have not the time to take a look in the actual implementation, however, if it is just clever enough to decrement the reference count after performing the copy, it should be threadsafe in any case, because it could never happen that a shared buffer is written to.

Have fun!

--

Daniel Lohmann

http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there Big Grin | :-D )
GeneralRe: Is it really thread safed? Pin
yuancc@21cn.com19-Jun-04 0:30
sussyuancc@21cn.com19-Jun-04 0:30 
QuestionHow to reduce Flicker? Pin
pmackell17-Sep-03 9:08
pmackell17-Sep-03 9:08 
AnswerRe: How to reduce Flicker? Pin
gbiddison24-Jun-04 20:09
gbiddison24-Jun-04 20:09 
GeneralRe: How to reduce Flicker? Pin
RJSoft23-Aug-04 3:04
RJSoft23-Aug-04 3:04 
AnswerRe: How to reduce Flicker? Pin
lano11064-Jul-06 18:47
lano11064-Jul-06 18:47 
Questionwhat about printf? Pin
omasoud14-Jul-03 14:32
omasoud14-Jul-03 14:32 
AnswerRe: what about printf? Pin
Daniel Lohmann14-Jul-03 21:28
Daniel Lohmann14-Jul-03 21:28 
GeneralRe: what about printf? Pin
omasoud15-Jul-03 0:35
omasoud15-Jul-03 0:35 
GeneralRe: what about printf? Pin
Daniel Lohmann16-Jul-03 5:32
Daniel Lohmann16-Jul-03 5:32 
GeneralHi Pin
annum14-Jun-03 16:19
annum14-Jun-03 16:19 
GeneralRe: Hi Pin
Daniel Lohmann15-Jun-03 1:33
Daniel Lohmann15-Jun-03 1:33 
GeneralRe: Hi Coloring Pin
pmackell17-Sep-03 9:06
pmackell17-Sep-03 9:06 
GeneralCEditLog and FormView Pin
abstract312-Jun-03 8:59
abstract312-Jun-03 8:59 
GeneralRe: CEditLog and FormView Pin
Daniel Lohmann15-Jun-03 1:40
Daniel Lohmann15-Jun-03 1:40 
GeneralRe: CEditLog and FormView Pin
S.Cartwright6-Dec-04 14:52
S.Cartwright6-Dec-04 14:52 
GeneralRe: CEditLog and FormView Pin
S.Cartwright6-Dec-04 15:13
S.Cartwright6-Dec-04 15:13 
GeneralRe: CEditLog and FormView Pin
Daniel Lohmann6-Dec-04 21:42
Daniel Lohmann6-Dec-04 21:42 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.