|
Good work, thanks!
Is there any way to control number of lines in the control? I need to log an application for many days.
|
|
|
|
|
Hi,
Great job !!!
I have a question,
My application used to be a console one and it uses printf a lot.
Is there a way to redirect printf as well ?
Thanks
|
|
|
|
|
Hello!
I met the same problem,and made no progress although i try to find many materials related to redirection problem.
Do you have any solution now? Thanks!!
|
|
|
|
|
Hi
I've download your program and try to comiple it in VC05. I've got some error message like:
"editlog.cpp(22) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int". It denotes "const WM_ADDTEXT = WM_USER + 500;" in line 22 of editlog.cpp is illegal now. I've changed it to const int and it works fine now. Anyway, thanks you to create this nice class.
Anson Chen
|
|
|
|
|
it was a mistake.
just read the error message:
const int WM_ADDTEXT = WM_USER+500;
is the correct statement.
|
|
|
|
|
Nice,
--------------------------------------------------------------------------
For high quality flow/diagram MFC/C++ Visio Like visualization Source Code,download XD++ at:
http://www.ucancode.net
|
|
|
|
|
Hi,
I'm using CEditLog to log some mathematical calculations.
However, the CEdit is not update after each cout (nor AddText) but only a the end of the computations.
Is there a way to force the update of the CEdit ?
Thanks
Vince
|
|
|
|
|
Hi Vince,
The edit control is updated "immediately" if the caret resides in the last line or at least every 500 msec. 500 msec is the default, the timeout is configurable at construction time.
Note that the update is actually performed by the thread who owns the edit control and not by the thread calling AddText() . Moreover, the UI thread (the thread owning the edit control) needs to process messages. So if your calculation thread has a higher priority than the UI thread and induces a high CPU load, this may cause the update delays as the UI thread never gets the chance to update the edit control. Maybe it would help to add a Sleep(0) after the output in the worker thread to yield the CPU to another thread.
If the calculation is actually performed by the same thread that owns the UI, this may also cause delays if your thread does not process messages during the calculations, which is required to update the UI. In this case it may help to invoke message processing explicitly.
Hope that helps
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
Hi,
I am trying to use CEditLog in my application (MFC MDI). I am using Scintilla edit control in place of CEdit. Everything is working fine except when I close the app there is a memory exception happenning (Could not read the memory ....). Apperantly it seems that there is a problem with the following two lines
// Redirect cout to our Edit-Control
m_pOldBuf = cout.rdbuf( &m_EditStrBuf );
// and also the unicode version
m_pOldBufW = wcout.rdbuf( &m_EditStrBufW );
Am I doing something wrong. Plase help.
|
|
|
|
|
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<char>* _cold_in;
std::basic_streambuf<char>* _cold_out;
std::basic_streambuf<char>* _cold_err;
std::basic_streambuf<char>* _cold_log;
std::basic_streambuf<wchar_t>* _wcold_in;
std::basic_streambuf<wchar_t>* _wcold_out;
std::basic_streambuf<wchar_t>* _wcold_err;
std::basic_streambuf<wchar_t>* _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<char>* m_pOldBuf;
std::basic_streambuf<wchar_t>* 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
|
|
|
|
|
Hello Daniel, Hello other codeproject guys!
These lines of code are really powerful - really nice component. Thank you very much or "Herzliches Dankeschön"!
I use these code in a document-view project with splitter windows. All things work well but I am not able to change the font. I am always getting a NULL pointer back, that is the code:
..CErrorEditView::OnCreate(...
{
CEdit& pme = this -> GetEditCtrl();
CFont* pf = pme.GetFont();
if (pf) <- this is always NULL
{
LOGFONT lf;
...
pf -> getLogFont(&lf);
lf.lfHeight = 15;
...
...
SetFont(pf);
}
...
}
Why I can't get a valid pointer?
This code works for other views (for instance with treeViews
Thank you very much / kind regards from Dresden
Marko Winter
SysMik GmbH Dresden
Germany
|
|
|
|
|
Are you sure this is a CEditLog related problem?
Is it working with a plain CEditView derived class that does not use CEditLog?
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
Hello Daniel!
Thanks for the hint - no that isn't a CEditLog related problem! I see same behaviour if I use a plain CEditView derived class.
That surprises me - because such code works with other CView derived classes.
But now I get a solution: creating a CFont member of class, setting the properties and set these font in onCreate
Thank you very much - thanks for the code too!
I wish you a nice weekend! with kind regards
Marko Winter
-------------------------------------------
Software & Systems
-------------------------------------------
SysMik GmbH Dresden | www.sysmik.de
-------------------------------------------
Dezentral automatisieren
LON over IP mit INLINE von Phoenix Contact
-------------------------------------------
SysMik | ICS – InlineControlServer
die neue Controllergeneration
-------------------------------------------
SysMik GmbH Dresden
Bertolt-Brecht-Allee 24
01309 Dresden, Germany
Tel/Fax +49-(0)351-43358 -30 / -29
-----------------------------------------
|
|
|
|
|
|
You might find thunk structure for x64 on the source: "C:\Program Files\Microsoft Visual Studio ####\VC\atlmfc\include\atlstdthunk.h", but wont works well.
I had managed to build x64 binary using other CSubclassWnd.
|
|
|
|
|
This is some outstanding code I think, very very good idea.
Well Done.
Iain Fraser
sd
|
|
|
|
|
Hi,
I'm experiencing the following problem:
Everything works as long as I output to one window:
m_EditLogger.SetEditCtrl( m_Edit111.m_hWnd );
m_EditLogger.AddText( String );
As soon as I switch from one edit field to another by something like:
m_EditLogger.SetEditCtrl( m_Edit111.m_hWnd );
m_EditLogger.AddText( String );
m_EditLogger.SetEditCtrl( m_Edit222.m_hWnd );
m_EditLogger.AddText( String );
sometimes I get no output at all any more (Works for a while sometimes, but after a while no new output is displayed any more (or as said above, sometimes nothing at all displayed right from the beginning).
Any idea what the problem is?
Thank you very much.
|
|
|
|
|
Strange...
Did you try to explicitly unsubclass the edit control before subclassing the new one. e.g.
m_EditLogger.SetEditCtrl( m_Edit111.m_hWnd );
m_EditLogger.AddText( String );
m_EditLogger.SetEditCtrl( NULL );
m_EditLogger.SetEditCtrl( m_Edit222.m_hWnd );
m_EditLogger.AddText( String );
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
Yes, but no change.
Indeed, even your suggestion to unsubclass before directing to another output control itself has the same destructive effect as my second "SetEditCtrl" to a real second control.
In both cases there's no output at all.
And it's not a special problem in my source adaption:
You can easily see this in your own provided original sample source by just adding a second output control and directing any output to the first and then to the second control right one after the other.
BTW: Same problem no matter if using "cout" or "AddText".
So seems that the message handling gets disorganized if 2 -"SetEditCtrl" and " AddText"- to different controls are issued right one after the other, if the text update itself of the first control (paint message or something?) has not been carried out already and the handles get mixed up that way. (Are you using PostMessage instead of SendMessage somewhere?)
|
|
|
|
|
Is it possible to save the entire content of the edit control into some text file ?
|
|
|
|
|
Very good class for logging implementation using CEdit control.
Two comments for other users:
1. Don't forget the "using namespace std;" declaration on *.cpp files.
2. Don't forget the below declaration on your stdafx.h
// Include core STL header
#include <string>
#include <streambuf>
#include <iostream>
Thanks.
|
|
|
|
|
I'm trying to send the ouput of flex and bison to a window. This code uses the old ostreams (by including <iostream.h> instead of <iostream> , and you your code:
cout.rdbuf( &m_EditStrBuf );
wont work because rdbuf doesn't take any parameters in the old library.
Can you give me an idea of how to go about this when cout is defined as:
extern ostream_withassign _CRTIMP cout;
Thanks,
Sam
|
|
|
|
|
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.
|
|
|
|
|
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!
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 )
|
|
|
|
|
who can understand vc's stl code written by P.J. Plauger ?
But I think in this implement, the reference count isn't protected by mutex as I can't find any related code.
Actually, the thread problem won't happen when another thread is appending a new string to m_csStore while the main UI thread is updating the edit box using wsText, becuase the m_csStroe find its ref count is 1 and then it should alloc a new buffer.
But the problem will happen, when wsText's destructor is calling, the ref count is decrementing from 1 to 0, but at same time, maybe the shared m_csStore is decrementing the ref count too. if no mutex protected, the ref count maybe less than 0 which is a potential problem.
the destructor of std::string in vc's stl is like this without thread protection but it should be a atomic operation in a multiple thread environment.
if( refcount == 0)
free(m_buffer);
else //maybe another thread is also decrementing the refcount and now it is 0 now.
else refcount--;
|
|
|
|