|
I think you can toy arround with the On-erase-background message (excuse me for not remembering exact name).
You can stop the flicker by returning false. But that is not the answer since it will not erase previous.
But you might try duplicating text output there. You can also employ double buffering by declaring a MemDC (CreateCompatibleDC) and selecting a hbitmap (CreateCompatibleBitmap). Doing this allows you to do your slow GDI TextOut or DrawText function to faster MemDC memory. Then BitBlt the results to the control dc.
Hope this helps
RJ
|
|
|
|
|
Hi,
The answer is simple. MSDev's output windows are not implemented with the edit commun control. They developped their own custom logging control that do not redraw itself if the bottom line is not visible. You can see it by youself by using Spy++ and look with which Window classes VC++ is made of. You will not see "edit"!
The solution to obtain the same effect is not trivial. You have to write your own control that does the same. I am working on such a control. Stay tuned....
Olivier Langlois
http://www.olivierlanglois.net
|
|
|
|
|
This is an excellent class!
I was wondering if it is possible to redirect printf and wprintf, and anything that writes to stdout and stderr too? Any ideas (other than trapping WriteFile)?
|
|
|
|
|
Thanks for your feedback
omasoud wrote:
I was wondering if it is possible to redirect printf and wprintf, and anything that writes to stdout and stderr too? Any ideas (other than trapping WriteFile)?
I was also thinking about it. In principle it should be possible to redirect a CRT FILE* to whatever you want, but I had given up to detect how it exactly works in the sources. Its completly undocumented.
Another idea (instead of catching WriteFile) might be to create an anonymous pipe and set it as osfilehandle for stdout / stderr (using the _open_osfhandle() CRT function and SetStdHandle() Win32 API function). However, you would also need to use an additional thread that waits for input on the pipe and then sends it to the EditLog. A clear benefit of this would be that any output that is going to stdout (even if a DLL is usig WriteFile( GetStdHandle( STDOUT_HANDLE) ) would go to the edit control. STDOUT and STDERR would also be automatically passed to child processes.
The most simple solution I use all the time is to define a small printf-like custom function in my stdafx.h which redirects the output to the editlog. Then I #undef printf and re- #define it to my custom function. Of course this does not work with externally compiled code.
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
http://dslweb.nwnexus.com/~ast/dload/guicon.htm
I've tried the code in the above link and it does work in redirecting stdout and stderr (even cin, cout, cerr work). Not sure how to use it with your class though.
The only documentation from microsoft about this that I found is in the following link:
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q105/3/05.asp&NoWebContent=1
|
|
|
|
|
omasoud wrote:
http://dslweb.nwnexus.com/~ast/dload/guicon.htm
I've tried the code in the above link and it does work in redirecting stdout and stderr (even cin, cout, cerr work). Not sure how to use it with your class though.
Well, this code actually does only part of it. It shows how to attach an Win32 file HANDLE (in this case a console handle) to CRT output (stdout, stderr, cout, cerr) at runtime.
The other things to do are:
- create an anonymous pipe with CreatePipe and use its write end HANDLE (and not a console handle) as STDOUT and STDERR as shown in the example code you found.
- create a worker thread that reads from the pipe's read end HANDLE and dumps the output to the CEditLog.
Because CEditLog has been designed to be thread-safe, this all should not be too difficult. You just have to take care (a bit) about when creating the thread, CEditLog and how to shut all of them down in a correct and graceful order.
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
First thanks for the great class! I have used it and it works great
What I wan't to do is add coloring capability to it, that dpending on the text I can change its color.
Any pointers, suggestions as I think that would be a goot addition
Thanks again
|
|
|
|
|
annum wrote:
What I wan't to do is add coloring capability to it, that dpending on the text I can change its color.
This should be possible by building CEditLog around a RichEdit control instead of an ordinary edit control. (As a side effect this would also remove the 64kb limit on Win9x - however, I never really cared about this )
Since RichEdit understoods most (all) of the messages of an edit control, the task should not be that difficult. The point that let me intentionally avoid RichEdit in the days I wrote this code, was the versioning chaos around it (it seemed to depend on Windows /IE / common-control and whatever versions...).
Have fun!
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
When I tried to link up CEditLog to a RichEditCtrl. It crashed after a few seconds of scrolling. The callstack was pretty messed up, but I think it had to do with a windows message proc.
-p
|
|
|
|
|
Hi,
I was wondering if anyone has tried to use CEditLog on an Cedit control in a FormView ... I just set everything up and the program runs... no compile errors... the program does not crash... BUT when I send text to the CEditLog nothing happens???
Anyone have any idea what I am doing wrong, or why CEditLog would not work on a Cedit control in Formview?
Thanks for your help.
Abstract3
|
|
|
|
|
I have to admit that I never used a CFormView, but I just do not believe that it would not work. An edit control is an edit control is an edit control!
I would recommend to use Spy++ and check if and which messages are sent to the edit control. If no WM_USER messages arrive, it seems to be not connected to the CEditLog. Also some breakpoints in the CEditLog code might help to figure this out.
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
Im having the same problem using CRichEditCtrl.
The problem seems to be with the values returned from GetScrollInfo.
Im working on a fix now.
|
|
|
|
|
Seems that GetScrollInfo may not return the correct information (well, correct for our purposes) if the scroll bar is not yet visible.
replace the following:
::GetScrollInfo( GetSafeHwnd(), SB_VERT, &si );
if( si.nPos >= si.nMax - (int) si.nPage + 1 )
with
::GetScrollInfo( GetSafeHwnd(), SB_VERT, &si );
if( si.nPos >= si.nMax - (int) si.nPage + 1 ||
!::GetScrollPos(GetSafeHwnd(), SB_VERT) )
GetScrollPos will return 0 on error (ie, the scroll bar is not visible). Note that I replaced the GetHandle calls with GetSafeHwnd (Im using a CRichEditCtrl)
|
|
|
|
|
sammyc wrote:
Seems that GetScrollInfo may not return the correct information (well, correct for our purposes) if the scroll bar is not yet visible.
replace the following:
::GetScrollInfo( GetSafeHwnd(), SB_VERT, &si );
if( si.nPos >= si.nMax - (int) si.nPage + 1 )
with
::GetScrollInfo( GetSafeHwnd(), SB_VERT, &si );
if( si.nPos >= si.nMax - (int) si.nPage + 1 ||
!::GetScrollPos(GetSafeHwnd(), SB_VERT) )
GetScrollPos will return 0 on error (ie, the scroll bar is not visible). Note that I replaced the GetHandle calls with GetSafeHwnd (Im using a CRichEditCtrl)
Thanks a lot about sharing your insights. Does it really work with rich edit controls now?
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
Gives error:
fatal error C1001: INTERNAL COMPILER ERROR
|
|
|
|
|
Sorry for the late reaction...
It took some time to get VS2003, install it and so on. However, I finally found it out. Seems that VS2003 is much more hysterical of using types defined in templates with the typename keyword.
So go to line 125 and replace:
basic_editstreambuf< E, T, BUF_SIZE >::int_type basic_editstreambuf< E,T,BUF_SIZE >::overflow(
int_type c
)
with
typename basic_editstreambuf< E, T, BUF_SIZE >::int_type basic_editstreambuf< E,T,BUF_SIZE >::overflow(
int_type c
)
I am going to update the article project in the very next days.
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
Still does not work. Even after repalcing this line, the sample project does not compile and gives internal compiler error.
|
|
|
|
|
Same here,
still not working
|
|
|
|
|
Hi all,
The updated demo project incorporates the changes I described in this thread. It now uses typename everywhere and compiles fine on VC.NET 2003.
(Boy, I hate this typename stuff. It bloats the source code a lot and nearly everything you refer from a template is a type! The standard comitee should have made types the default and introduced a no_type to destinguish template elemets that are no types...)
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
Is there a possibility to restrict the number of lines?
So the buffer would not grow to "infinity" and you can only scroll back the last x lines.
I want to use it to log program actions, but I also write them to a log file. So it is not necessary to have all the lines in the buffer all the time.
I'm thinking about this, because my logfile can become very big.
But also without this functionality your CEditLog seems to be the best solution for my problem! Thanx!
|
|
|
|
|
I've been trying to get this to work effectively.... seems to be OK on a win2000/NT machine, but I've been having issues with it on win98.
Quite simply... when you're adding text, just do this too
nSize = (int) ::SendMessage( hEdit, WM_GETTEXTLENGTH, 0, 0 );
if ( nSize > MAX_TEXT_LEN ) {
::SendMessage( hEdit, EM_SETSEL, (WPARAM) 0, (LPARAM) TEXT_TRUNCATE_LEN );
if ( g_bIsWinNT ) {
::SendMessageW( hEdit, EM_REPLACESEL, 0, (LPARAM) "" );
} else {
::SendMessage( hEdit, EM_REPLACESEL, 0, (LPARAM) _W2A( (LPCWSTR) "" ) );
}
nSize = (int) ::SendMessage( hEdit, WM_GETTEXTLENGTH, 0, 0 );
}
Then use EM_SETSEL message with nSize params to set selection point to end of text.
Not 100% but worth a start for discussion purposes
|
|
|
|
|
Hi,
I had problem using your wonderful CEditLog class with a CEditView in a otherwise also strange environment (SDI app, multiple Views and the latest addition CEditLog with CEditView). The problem is, that the CEditView::OnDestroy handler isn't called and therefor the EditView doesn't tell the MainFrame to deactivate the CEditView during shutdown resulting in a crash.
As far as I have understood CSubclassWnd there is no chance to send a message to the subclassed window, after you called UnsubclassWindow (). So the subclassed CEditView doesn't see the message, since you call UnsublcassWindow within the WM_DESTROY handler.
The first solution I came up with was to call the DefWindowProc myself within the CEditLog::OnDestroy before you unsubclass the CEditCtrl
void CEditLog::OnDestroy()
{
DefWindowProc ();
UnsubclassWindow();
}
The second solution would be to remove the WM_DESTROY handling in CEditLog all together, since UnsubclassWindow is called during the WM_NCDESTROY handler from within CSublcassWnd anyway, naturally after the mesage has been passed to the subclassed window
There is this OnFinalMessage handler that you can use to do custom cleanup.
I would prefer the second solution, but I'm not sure why you introduced this handling of WM_DESTROY into your CEditLog. Perhaps some artifical relict.
As a second note: even if the following case handling will do no harm, I doesn't look like good coding style
case WM_ERASEBKGND:
if( m_bNoPaint )
return TRUE;
case WM_PAINT:
if( m_bNoPaint )
return TRUE;
You better combine those two cases and introduce a break. This is the funny behavoir if you introduce a further case statement and wonder why it is called in some strange situations.
Thanks for the class
Dirk
|
|
|
|
|
Thanks Dirk!
Very good points!
I would prefer the second solution, but I'm not sure why you introduced this handling of WM_DESTROY into your CEditLog. Perhaps some artifical relict.
To be honest - I don't know exactly why I am doing this. I assume it is still there because the original V1.0 of CSubclassWnd did not handle WM_NCDESTROY.
I will remove it in the next version
As a second note: even if the following case handling will do no harm, I doesn't look like good coding style
case WM_ERASEBKGND:
if( m_bNoPaint )
return TRUE;
case WM_PAINT:
if( m_bNoPaint )
return TRUE;
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
I am trying to display data from an array (lets just say a CString array) in a standard CEdit control with each item in the array on its own line. Is there a way to do this in a CEdit? I have tried to read the data into one big string with "\n"s between the items but this does not work. I am using SetWindowText() to display this data in the edit control. When I do that with "\n"s in the string, it just displays a "|" character where the line breaks are and keeps writing the rest of the text on the same line. There must be an easy way to do this. Please help!!!!!!
Newby,
Anthony
|
|
|
|
|