 |
|
 |
if you just want to scroll to the last line after you append some text. you can do it like this, it 's more simple:
AppendLog(...);
//..
SendMessage( hwndRichEdit, WM_VSCROLL, MAKELONG( SB_BOTTOM, 0), NULL);
it will make the vertical scroll bar to scroll to the bottom, and make the text you just insert visible at the bottom of the control.
|
|
|
|
 |
|
 |
Thank you very much for this hint!
Best regards,
Volker
|
|
|
|
 |
|
 |
Thank You, Typke ! Very helpful. I'm putting together a generic test bed in VS 2010 to test code in, at first need is to test DLL code from explorer extensions, which are hard to debug. I wanted a reasonably good GUI logger. I had a fair one, but it had issues in 2010. Yours works great, with the new improvements. Here's an additional improvement that took me a little while to work out. It's not perfect, but does work well. It adds in line breaks that are appropriate for the width of the Rich Edit Control and considers placing them after the last word that will fit on the line before 'running' off the edge.
The core of the code goes in the middle of your AppendToLogAndScroll member :
m_ctrlLog.SetSelectionCharFormat(cf);
int nBreaks = str.GetLength() / m_OutSize.cx ;
int iPos = 0 , nlbPos = 0 , ePos = 0 ;
CString rfind ;
for(int ilb=1; ilb <= nBreaks; ilb++)
{
nlbPos = str.Find( _T("\r\n"), iPos );
if( nlbPos == -1 ) nlbPos = iPos + m_OutSize.cx ;
if( nlbPos < iPos + m_OutSize.cx )
{
iPos = nlbPos + 2 ;
}
else if( nlbPos > iPos + m_OutSize.cx )
{
rfind.Empty();
ePos = min( str.GetLength()-1, iPos + m_OutSize.cx ) ;
rfind = str.Mid( iPos, ePos - iPos );
ePos = rfind.ReverseFind( ' ' ) + iPos ;
str.Insert( ePos, _T("\r\n") ) ;
iPos = 2 + ePos ;
}
}
m_ctrlLog.ReplaceSel(str);
The member m_OutSize is a CSize data member of the Width and Height of the Rich Edit Control, defined as follows, placed at the end of the dialog's OnInitDialog() :
TEXTMETRIC tm;
CDC* pDC = m_ctrlLog.GetDC();
pDC->GetTextMetrics(&tm);
m_ctrlLog..ReleaseDC(pDC);
CRect r;
m_ctrlLog.GetRect(&r);
theApp.m_OutSize.cx = (r.Width() / tm.tmAveCharWidth) ;
theApp.m_OutSize.cy = (r.Height() / tm.tmHeight ) ;
I found the width produced by this code usually is about 2/3 the actual width, due to variance in the characters used and by the font used. For Example, in my Log box m_OutSize.cx is 65 but a line of repeating digits 0 to 9 shows the log box can handle 72 digits with the vertical scroll bar showing. This is where some improvement in my code are needed, but at least it factors toward the safe side !
Thanks Again !
|
|
|
|
 |
|
 |
Thank you for your improvement suggestions. It's good to hear that the article actually did help someone. That's what keeps you motivated in publishing things...
Best regards,
Volker
|
|
|
|
 |
|
 |
Useful and very well explained! The code is pretty self explanatory.
Regards
N. Sharjith
|
|
|
|
 |
|
 |
Thanks typke
This article is really good to learn.
|
|
|
|
 |
|
 |
thanks dude...
From Indonesia with love..!!
|
|
|
|
 |
|
 |
Nice work typke
I struggled for 2 days to insert log text (mostly debugging) into a richeditctrl and to make it look like a console. I tried to adapt the StreamIn function to do that, but this function is useful to insert text from a file and it inserts the whole text at once. Your idea was exactly what I needed.
Thanks a lot!
PS - your article should be added to the documentation of the richeditctrl from MSDN
|
|
|
|
 |
|
 |
If I had not find your article I would probably spend another 2 hours wondering why it does not work (program just terminates). Not only it works now, but it is exactly what I needed! Thanks!
|
|
|
|
 |
|
 |
Thanks for the hint that you have to turn off CFE_AUTOCOLOR to enable user-specified colours!
|
|
|
|
 |
|
 |
Hi,
I want to read RTF file in Chunk by chunk.
And I want to append in StreamIn i.e. RichEditCtrl.
But Chunk by chunk upending is not working. If I read
whole file in buffer and append/insert, it works fine.
I set SF_RTF and SFF_SELECTION flags for StreamIn.
If anyone knows about RTF & RichEdit control,
please help me.
Ashok
|
|
|
|
 |
|
 |
all the dll has been updated on Win98 , but when i run RichEditLog_Demo.exe,nothing happened , i try to use AfxInitRichEdit2(),but still can not resolve this problem , please help me
peterleex@163.com
thanks
|
|
|
|
 |
|
 |
Well, I have never tried to run the code on a Win98 machine. I am afraid I won't even be able to help much concerning this problem. Anyways, I can try to...
Now what exactly happens?
I guess the application does show up but when you click on a button, no text is inserted?
Did you use the already compiled version from the Release subfolder or did you re-compile the project first (and for what configuration - debug or release)?
Please note that the project was built in Visual Studio .NET 2003, so the project is not compatible with Visual Studio 6 (but that should not affect the code itself, but only the project file).
Best regards,
Volker
|
|
|
|
 |
|
 |
1.The application doesn't show up
2.I use already compiled version from the Release subfolder
3.I use Visual Studio .NET 2003 too
|
|
|
|
 |
|
 |
1.The application doesn't show up
2.I use already compiled version from the Release subfolder
3.I use Visual Studio .NET 2003 too
i try to use AfxInitRichEdit2() in InitInstance ,but still can't work .
Best regards
peter
|
|
|
|
 |
|
 |
Now that is very strange. I checked the stdafx.h file yesterday to make sure the windows version is set to a value low enough to support windows 98:
...
#ifndef _WIN32_WINDOWS
#define _WIN32_WINDOWS 0x0410 // Win98 ...
#endif
...
The application should work with AfxInitRichEdit() as well. This is the old version. Anyways, you are right to use AfxInitRichEdit2() on a VC++ .NET system.
Now please do the following:
- Search your system for RICHED32.DLL and/or RICHED20.DLL (for AfxInitRichEdit() and AfxInitRichEdit2(), respectively). A DLL like that is required by the application.
- Please debug the code in the CRichEditLog_DemoApp::InitInstance() function, step by step, and try to find out if any of the initilization function fails (insert a boolean variable and assign the return value of AfxInitRichEdit/2() to it and then debug the code and see what is assigned to your variable. It should be true on success.)
b = AfxInitRichEdit();
If all fails, then do the following:
- Have a look in the resource file (.rc) in the main project folder. In there you will find a line
CONTROL "",IDC_RICHEDIT21,"RichEdit20A",ES_MULTILINE |
ES_AUTOVSCROLL | ES_READONLY | ES_WANTRETURN | WS_BORDER |
WS_VSCROLL | WS_TABSTOP,7,87,306,106
Try replacing "RichEdit20A" by "RICHEDIT" and then also make sure you use AfxInitRichEdit() only. This is the version 1.0 style initialization of the control. However, I do not know if there are any other things that must be changed in order for this to work...
If this also fails, I suggest you build a new, empty project and simply insert the RichEditCtrl in your own VC++ .NET. Create a dialog based application, add a CRichEditCtrl to your dialog (taken from the toolbox) and then insert the appropriate code...
I hope this helps.
Best regards,
Volker
|
|
|
|
 |
|
 |
max text size is 65K.
and scroll using EM_SCROLLCARET (see docs)
CHARRANGE cr;
CHARFORMAT cf;
cf.cbSize = sizeof(CHARFORMAT);
cf.dwMask = CFM_COLOR;
cf.dwEffects = 0; // To disable CFE_AUTOCOLOR
nLength = GetWindowTextLength(hLogWnd);
if(nLength > 16*1024)
{
cr.cpMin = 0; cr.cpMax = nLength/2;
SendMessage(hLogWnd, EM_EXSETSEL, 0, (LPARAM)&cr);
SendMessage(hLogWnd, EM_REPLACESEL, FALSE, (LPARAM)stCLRF);
}
cr.cpMin = cr.cpMax = -1;
cf.crTextColor = color;
SendMessage(hLogWnd, EM_EXSETSEL, 0, (LPARAM)&cr);
SendMessage(hLogWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
SendMessage(hLogWnd, EM_REPLACESEL, FALSE, (LPARAM)stMessage);
cr.cpMin = cr.cpMax = -1;
SendMessage(hLogWnd, EM_EXSETSEL, 0, (LPARAM)&cr);
SendMessage(hLogWnd, EM_REPLACESEL, FALSE, (LPARAM)stCLRF);
SendMessage(hLogWnd, EM_SCROLLCARET, 0, 0);
|
|
|
|
 |
|
 |
This sample code is very helpful. I could easily extend my existing project to have a colorful event log now instead of the existing B/W one...
I agree with you: it's not that very sophisticated stuff, but it greatly helps to sort out daily issues. Thanks for sharing and keep up posting!
Regards
tomei
|
|
|
|
 |
|
 |
Thank you very much for your positive feedback!
Best regards,
Volker
|
|
|
|
 |
|
 |
Since I'm new to this, I appreciate very much your example.
The next thing that comes to mind is how to also set the font...
Any quick suggestions?
Got my 5!
Best Regards.
Steve
|
|
|
|
 |
|
 |
Hi Steve!
You can set the Font for the whole Rich Edit Control by using something like:
CFont Font;
Font.CreateFont(14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("Arial"));
m_ctrlLog.SetFont(&Font);
(where m_ctrlLog is an object of type CRichEditCtrl).
If you are interested in setting a font line by line using the AppendToLog() function, you require something like this:
CHARFORMAT cf;
char szFaceName[LF_FACESIZE] = "Courier";
.
.
.
cf.dwMask = CFM_COLOR | CFM_FACE;
.
.
.
strcpy (cf.szFaceName, szFaceName);
.
.
.
(The dots denote code already shown in my AppendToLog() example function, simply add the new stuff.)
Don't forget to set the CFM_FACE flag!
The constant LF_FACESIZE is given in the MFC already (it's 16 in my current version of MFC). Just play around with some font names to find the right name.
Obviously you can also copy directly into the font name array:
strcpy (cf.szFaceName, "Courier");
Best regards,
Volker
-- modified at 2:21 Thursday 20th April, 2006
|
|
|
|
 |
|
 |
This is what I am looking for. I just want a simple text editor, which can change text colors. CEdit does not do me good, RichEdit is suit for me. this article is very good, simple and intuitive.
I feel with someone call this article a "sh*t". So rude!
Thanks to author. We support you for sharing goodies.
|
|
|
|
 |
|
 |
This is *exactly* what I was looking for, thanks for sharing!
|
|
|
|
 |
|
 |
And thank you for your positive feedback.
Some folks wrote me I should not post this kind of "sh*t", which I don't quite understand. If this code is too simple for them, then why do they read my article in the first place? It's labelled "BEGINNER", so I don't expect experts to read or rate it at all.
The code is really simple, but sometimes people need quite a while to figure out how to do things, and therefore even such "beginners level" articles may be just the right thing...
The two "Thank you" replies show that I was right sharing these simple code lines. So thank you for your positive comments!
Best regards,
Volker
|
|
|
|
 |
|
 |
Thanks for this great little "blurb"! This is EXACTLY what I was looking for. Being new to RichEdit controls, I wasn't sure how to go about doing this.
Thanks again for posting this short little bit of code!
|
|
|
|
 |