 |
|
 |
I think it is a good idea to limit the amount of text that this edit control diplays.This should be placed in CHistoryEdit::AppendString to do that:
str += "\r\n";
SetRedraw(FALSE);
int start, end;
GetSel(start, end);
DWORD len = GetWindowTextLength();
if (len>MAXCHARS)
{
int toline= LineFromChar(len-MAXCHARS);
if (LineIndex(toline) != -1)
{
SetSel(0, LineIndex(toline)+LineLength(toline));
ReplaceSel("");
}
}
SetSel(len, len, TRUE);
ReplaceSel(str);
SetSel(start, end, TRUE);
SetRedraw(TRUE);
DWORD newLen = GetWindowTextLength();
SetSel(newLen, newLen, FALSE);
You should as well define MAXCHARS to the desired maximum number of chars to allow.It should be under 64k(Ansi)32k(Unicode).
I got inspired by Kupriyanov Anatolij's message.
|
|
|
|
 |
|
 |
Good point! I'll update the article soon.
Thanks,
/ravi
|
|
|
|
 |
|
 |
First of all, Thank you for this control. This is exactly what I needed for my app.
You may also want to be able to limit the number of lines that you can have in the edit box. This can be easily done:
- add member m_maxLines
- add accessor / mutator and a default value
- add the following code to AppendString:
SetRedraw(FALSE);
....
SetWindowText(strBuffer);
//New code to limit number of lines
if (GetLineCount() > m_maxLines)
{
int nDel = 0;
for (int i = 0; i < GetLineCount() - m_maxLines; i++)
{
nDel += strBuffer.Find("\n", nDel) + 1;
}
SetSel(0, nDel, TRUE);
ReplaceSel("");
}
SetRedraw(TRUE);
//End new code
LineScroll( GetLineCount(), 0);
....
|
|
|
|
 |
|
 |
Why do you have to subclass the control?
|
|
|
|
 |
|
 |
I introduce good routine for appending string to control. void CEditHistoryView::AppendLine(CString text) { text += "\r\n"; SetRedraw(FALSE); int start, end; GetSel(start, end); DWORD len = GetWindowTextLength(); SetSel(len, len, TRUE); ReplaceSel(text); SetSel(start, end, TRUE); SetRedraw(TRUE); if(start == end && len == start) {// If cursor was at end of box, then scroll to the end DWORD newLen = GetWindowTextLength(); SetSel(newLen, newLen, FALSE); } } WBR, kan
|
|
|
|
 |
|
 |
The problem with your solution is flickering.
How do you avoid it ?
|
|
|
|
 |
|
 |
Here's a slight modification to allow variable args like printf. I also changed the CString arg to a LPCSTR because it avoids unnecessary construction of a CString. Current calls to the AppendString method don't change.
----------
// HistoryEdit.h
// ...
#ifndef _HistoryEdit_h_
#define _HistoryEdit_h_
#include
// ...
// Operations
public:
void AppendString (LPCSTR str, ...);
// ...
----------
// HistoryEdit.cpp
// ...
void CHistoryEdit::AppendString
(LPCSTR str, ... )
{
CString strBuffer; // current contents of edit control
va_list marker;
va_start( marker, str );
TCHAR szBuf[ 4096 ];
_vsnprintf( szBuf, sizeof szBuf, str, marker );
va_end( marker );
CString strNew( szBuf );
strNew.Replace( _T("\n"), _T("\r\n") );
// Append string
GetWindowText (strBuffer);
if ( !strBuffer.IsEmpty() && strBuffer.Right(1).Compare( _T("\n") ) )
strBuffer += "\r\n";
strBuffer += strNew;
SetWindowText (strBuffer);
// Scroll the edit control
LineScroll (GetLineCount(), 0);
}
// ...
Glenn
|
|
|
|
 |
|
 |
I'm trying to expand this thingie to only scroll if the caret is on the last line of the editcontrol. Now that's not hard, but the hard part is the repositioning of the caret/selection after the adding of text, Any Ideas?
so far I've come up with this (which works partially):
void CLogDlg::DisplayLogMessage(CString string)
{
//determine if selection on last row
BOOL bscroll = FALSE;
if (m_ctrlLogEdit.LineFromChar /
(m_ctrlLogEdit.LineIndex()) /
== m_ctrlLogEdit.GetLineCount() - 1)
{
bscroll = TRUE;
}
//add carriage return linefeed
string += "\r\n";
//Get your original selection
if (!bscroll)
{
int start;
int end;
m_ctrlLogEdit.GetSel(start, end);
}
int len = m_ctrlLogEdit.GetWindowTextLength();
//append string
m_ctrlLogEdit.SetSel(len, len);
m_ctrlLogEdit.ReplaceSel(string);
//reset to your original selection or scroll
if (!bscroll)
m_ctrlLogEdit.SetSel(start, end);
else
{
m_ctrlLogEdit.LineScroll /
(m_ctrlLogEdit.GetLineCount(), 0);
len = m_ctrlLogEdit.GetWindowTextLength();
//be on last line next time
m_ctrlLogEdit.SetSel(len, len);
}
|
|
|
|
 |