Ejemplo n.º 1
0
void CTitleTimeEdit::KeyInDel()
{
    int nCharPos = CharFromPos(GetCaretPos());

    int nSelStart	= 0;
    int nSelEnd		= 0;
    GetSel(nSelStart, nSelEnd);

    if(nSelStart == nSelEnd)
    {
        if(nCharPos < 12)
        {
            m_szTimeChar[nCharPos] = s_szDefTMChar[nCharPos];
            nCharPos ++;
            if(s_szDefTMChar[nCharPos] != '0')
                nCharPos ++;
        }
    }
    else
    {
        DeleteRange(nSelStart, nSelEnd);
    }
    Update();
    SetSel(nCharPos, nCharPos);
}
Ejemplo n.º 2
0
void CTitleTimeEdit::KeyInNumeric(UINT nChar)
{
    int nCharPos = CharFromPos(GetCaretPos());

    int nSelStart	= 0;
    int nSelEnd		= 0;
    GetSel(nSelStart, nSelEnd);
    if(nSelStart == nSelEnd)
    {
        if(nCharPos < 12)
        {
            if((s_szDefTMChar[nCharPos] == '0')
                    &&(nChar <= (UINT)s_szMaxTMChar[nCharPos]))
            {
                m_szTimeChar[nCharPos] = nChar;
            }
            nCharPos ++;
            if(s_szDefTMChar[nCharPos] != '0')
                nCharPos ++;
        }
    }
    else
    {
        if((s_szDefTMChar[nSelStart] == '0')
                &&(nChar <= (UINT)s_szMaxTMChar[nCharPos]))
        {
            m_szTimeChar[nSelStart] = nChar;
        }
    }
    Update();
    SetSel(nCharPos, nCharPos);
}
Ejemplo n.º 3
0
LRESULT ChatCtrl::OnRButtonDown(POINT pt) {
	selectedLine = LineFromPos(pt);
	selectedUser.clear();
	selectedIP.clear();

	// Po kliku dovnitr oznaceneho textu si zkusime poznamenat pripadnej nick ci ip...
	// jinak by nam to neuznalo napriklad druhej klik na uz oznaceny nick =)
	long lSelBegin = 0, lSelEnd = 0;
	GetSel(lSelBegin, lSelEnd);

	int iCharPos = CharFromPos(pt), iBegin = 0, iEnd = 0;
	if((lSelEnd > lSelBegin) && (iCharPos >= lSelBegin) && (iCharPos <= lSelEnd)) {
		if(!HitIP(pt, selectedIP, iBegin, iEnd))
			HitNick(pt, selectedUser, iBegin, iEnd);

		return 1;
	}

	// hightlight IP or nick when clicking on it
	if(HitIP(pt, selectedIP, iBegin, iEnd) || HitNick(pt, selectedUser, iBegin, iEnd)) {
		SetSel(iBegin, iEnd);
		InvalidateRect(NULL);
	}
	return 1;
}
/*
================
CSyntaxRichEditCtrl::GetNameForMousePosition
================
*/
bool CSyntaxRichEditCtrl::GetNameForMousePosition(idStr &name) const
{
	int charIndex, startCharIndex, endCharIndex, type;
	idStr text;

	charIndex = CharFromPos(mousePoint);

	for (startCharIndex = charIndex; startCharIndex > 0; startCharIndex--) {
		GetText(text, startCharIndex - 1, startCharIndex);
		type = charType[text[0]];

		if (type != CT_NAME && type != CT_NUMBER) {
			break;
		}
	}

	for (endCharIndex = charIndex; endCharIndex < GetTextLength(); endCharIndex++) {
		GetText(text, endCharIndex, endCharIndex + 1);
		type = charType[text[0]];

		if (type != CT_NAME && type != CT_NUMBER) {
			break;
		}
	}

	GetText(name, startCharIndex, endCharIndex);

	return (endCharIndex > startCharIndex);
}
Ejemplo n.º 5
0
bool CHSNumEdit::CheckInput (UINT nChar)
{
	// checks no digit or dots before a minus sign
	// and no more than m_digits after '.'
	int pos = CharFromPos(GetCaretPos()); 
	CString txt;
	GetWindowText(txt);
	int len = txt.GetLength();
	//////// no digits or dot before a minus sign
	int sign = txt.Find('-');
	if ( pos <= sign )
		return false;
	//// no dot before m_digit from end of string
	int dot = txt.ReverseFind('.');
	if ( dot == -1 )
	{
		// no dot - check position before accepting
		if ( pos >= len -m_digits )
			return true;
		//else
		//	return false;
	}
	/////// limit digits after '.' 
	if ( len - pos < dot) 
	{
		// no insert if 
		// there is more than m_digits digits after zero.
		if ( pos -dot > m_digits )
			return false;
		// the insert will cause the same
		if ( len - dot> m_digits) 
			return false;
	}
	return true;
}
Ejemplo n.º 6
0
LRESULT CFulEditCtrl::onMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {
	//set this here since it will always be false
	bHandled = FALSE;

	if(!isSet(URL_SINGLE_CLICK) && !isSet(URL_DOUBLE_CLICK)){
		return 1;
	}

	//if a mouse button is pressed revert to the standard beam cursor
	if(wParam != 0) {
		SetCursor(beamCursor);
		showHandCursor = false;
		return 1;
	}

	POINT mousePT = {GET_X_LPARAM(lParam) , GET_Y_LPARAM(lParam)};
	int ch = CharFromPos(mousePT);
	POINT charPT = PosFromChar(ch);

	//since CharFromPos returns the last character even if the cursor is past the end of text
	//we have to check if the pointer was actually above the last char

	//check xpos
	if( mousePT.x > ( charPT.x + 3 ) ) {
		SetCursor(beamCursor);
		showHandCursor = false;
		return 1;
	}

	//check ypos
	if( mousePT.y > (charPT.y +  fontHeight ) ) {
		SetCursor(beamCursor);
		showHandCursor = false;
		return 1;
	}

	//let's start from the end, it's probably the last urls inserted that will be
	//visible anyway, might save a few cycles =)
	for(UrlRange::reverse_iterator i = urlRanges.rbegin(); i != urlRanges.rend(); ++i) {
		if( ch >= i->cpMin && ch <= i->cpMax ) {
			showHandCursor = true;
			SetCursor(handCursor);
			return 1;
		}
	}

	SetCursor(beamCursor);
	showHandCursor = false;
	return 1;
}
Ejemplo n.º 7
0
void TranscriptEdit::StartEdit(Skein::Node* node, const CRect& nodeRect, CPoint point)
{
  m_node = node;
  const CStringW& text = node->GetExpectedText();
  SetTextRange(0,-1,text);

  MoveWindow(nodeRect,FALSE);
  ShowWindow(SW_SHOW);

  ScreenToClient(&point);
  int pos = CharFromPos(point);
  SetSel(pos,pos);

  SetFocus();
}
Ejemplo n.º 8
0
tstring ChatCtrl::LineFromPos(const POINT& p) const {
	int iCharPos = CharFromPos(p);
	int len = LineLength(iCharPos);

	if(len < 3) {
		return Util::emptyStringT;
	}

	tstring tmp;
	tmp.resize(len);

	GetLine(LineFromChar(iCharPos), &tmp[0], len);

	return tmp;
}
Ejemplo n.º 9
0
tstring::size_type CFulEditCtrl::TextUnderCursor(POINT mousePT, tstring& x) {
	
	tstring::size_type start = tstring::npos;

	int ch = CharFromPos(mousePT);
	POINT charPT = PosFromChar(ch);

	//since CharFromPos returns the last character even if the cursor is past the end of text
	//we have to check if the pointer was actually above the last char

	//check xpos
	if( mousePT.x > ( charPT.x + 3 ) ) 
		return start;

	//check ypos
	if( mousePT.y > (charPT.y + fontHeight ) )
		return start;

	FINDTEXT ft;
	ft.chrg.cpMin = ch;
	ft.chrg.cpMax = -1;
	ft.lpstrText = _T("\r");

	int begin = (int)SendMessage(EM_FINDTEXT, 0, (LPARAM)&ft) + 1;
	int rEnd = (int)SendMessage(EM_FINDTEXT, FR_DOWN, (LPARAM)&ft);

	if(begin < 0) {
		begin = 0;
	}

	if(rEnd == -1) {
		rEnd = GetTextLengthEx(GTL_NUMCHARS);
	}

	if(rEnd > begin) {
		TCHAR *buf = new TCHAR[(rEnd-begin)+1];
		if(buf) {
			GetTextRange(begin, rEnd, buf);
			x = buf;
			delete[] buf;
			start = ch - begin;
		}
	}
	return start;
}
Ejemplo n.º 10
0
bool ChatCtrl::HitIP(const POINT& p, tstring& sIP, int& iBegin, int& iEnd) {
	int iCharPos = CharFromPos(p), len = LineLength(iCharPos) + 1;
	if(len < 3)
		return false;

	DWORD lPosBegin = FindWordBreak(WB_LEFT, iCharPos);
	DWORD lPosEnd = FindWordBreak(WB_RIGHTBREAK, iCharPos);
	len = lPosEnd - lPosBegin;

	tstring sText;
	sText.resize(len);
	GetTextRange(lPosBegin, lPosEnd, &sText[0]);

	for(int i = 0; i < len; i++) {
		if(!((sText[i] == 0) || (sText[i] == '.') || ((sText[i] >= '0') && (sText[i] <= '9')))) {
			return false;
		}
	}

	sText += _T('.');
	size_t iFindBegin = 0, iPos = tstring::npos, iEnd2 = 0;

	for(int i = 0; i < 4; ++i) {
		iPos = sText.find(_T('.'), iFindBegin);
		if(iPos == tstring::npos) {
			return false;
		}
		iEnd2 = atoi(Text::fromT(sText.substr(iFindBegin)).c_str());
		if((iEnd2 < 0) || (iEnd2 > 255)) { // 13197	V547	Expression 'iEnd2 < 0' is always false. Unsigned type value is never < 0.
			return false;
		}
		iFindBegin = iPos + 1;
	}

		sIP = sText.substr(0, iPos);
		iBegin = lPosBegin;
		iEnd = lPosEnd;

	return true;
}
Ejemplo n.º 11
0
void CRichEditExtn::OnLButtonDown(UINT nFlags, CPoint point)
{
  // Get the scroll bar position.
  int nScrollHPos = GetScrollPos(SB_HORZ);
  int nScrollVPos = GetScrollPos(SB_VERT);

  int n = CharFromPos(point);
  m_lastposition = HIWORD(n);
  m_nStartChar = m_nEndChar = LOWORD(n);

  CRichEditCtrl::OnLButtonDown(nFlags, point);

  // Reset the scroll bar position.
  SetScrollPos(SB_HORZ, nScrollHPos);
  SetScrollPos(SB_VERT, nScrollVPos);

  // Reset the display scroll position.
  SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, nScrollHPos), 0);
  SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBTRACK, nScrollVPos), 0);

  SetSel(m_nStartChar, m_nEndChar);
}
Ejemplo n.º 12
0
void CHTRichEditCtrl::AddLine(LPCTSTR pszMsg, int iLen, bool bLink, COLORREF cr, COLORREF bk, DWORD mask)
{
	int iMsgLen = (iLen == -1) ? _tcslen(pszMsg) : iLen;
	if (iMsgLen == 0)
		return;
#ifdef _DEBUG
	//	if (pszMsg[iMsgLen - 1] == _T('\n'))
	//		ASSERT( iMsgLen >= 2 && pszMsg[iMsgLen - 2] == _T('\r') );
#endif

	// Get Edit contents dimensions and cursor position
	long lStartChar, lEndChar;
	GetSel(lStartChar, lEndChar);
	int iSize = GetWindowTextLength();

	if (lStartChar == iSize && iSize == lEndChar)
	{
		// The cursor resides at the end of text
		SCROLLINFO si;
		si.cbSize = sizeof si;
		si.fMask = SIF_ALL;
		if (m_bAutoScroll && GetScrollInfo(SB_VERT, &si) && si.nPos >= (int)(si.nMax - si.nPage + 1))
		{
			// Not scrolled away
			SafeAddLine(iSize, pszMsg, iLen, lStartChar, lEndChar, bLink, cr, bk, mask);
			if (m_bAutoScroll && !IsWindowVisible())
				ScrollToLastLine();
		}
		else
		{
			// Reduce flicker by ignoring WM_PAINT
			m_bNoPaint = true;
			BOOL bIsVisible = IsWindowVisible();
			if (bIsVisible)
				SetRedraw(FALSE);

			// Remember where we are
			int iFirstLine = !m_bAutoScroll ? GetFirstVisibleLine() : 0;

			// Select at the end of text and replace the selection
			// This is a very fast way to add text to an edit control
			SafeAddLine(iSize, pszMsg, iLen, lStartChar, lEndChar, bLink, cr, bk, mask);
			//if (m_bAutoScroll && lStartChar == lEndChar)
			//	lStartChar = lEndChar = -1;
			SetSel(lStartChar, lEndChar); // Restore our previous selection

			if (!m_bAutoScroll)
				LineScroll(iFirstLine - GetFirstVisibleLine());
			else
				ScrollToLastLine();

			m_bNoPaint = false;
			if (bIsVisible){
				SetRedraw();
				if (m_bRichEdit)
					Invalidate();
			}
		}
	}
	else
	{
		// We should add the text anyway...

		// Reduce flicker by ignoring WM_PAINT
		m_bNoPaint = true;
		BOOL bIsVisible = IsWindowVisible();
		if (bIsVisible)
			SetRedraw(FALSE);

		// Remember where we are
		int iFirstLine = !m_bAutoScroll ? GetFirstVisibleLine() : 0;
		// Very annoying problems with EM_GETSCROLLPOS/EM_SETSCROLLPOS. Depending
		// on the amount of data in the control, the control may start to scroll up
		// by itself(!!) -- obviously because of some internal rounding errors..
		//
		// Using 'LineScroll' also gives glitches (also depending on the amount of
		// data stored in the control), but at least it doesn't start to show some 'life'
		/*POINT ptScrollPos;
		if (!m_bAutoScroll)
			SendMessage(EM_GETSCROLLPOS, 0, (LPARAM)&ptScrollPos);*/

		if (lStartChar != lEndChar)
		{
			// If we are currently selecting some text, we have to find out
			// if the caret is near the beginning of this block or near the end.
			// Note that this does not always work. Because of the EM_CHARFROMPOS
			// message returning only 16 bits this will fail if the user has selected
			// a block with a length dividable by 64k.

			// NOTE: This may cause a lot of terrible CRASHES within the RichEdit control when used for a RichEdit control!?
			// To reproduce the crash: click in the RE control while it's drawing a line and start a selection!
			if (!m_bRichEdit){
				CPoint pt;
				::GetCaretPos(&pt);
				int iCaretPos = CharFromPos(pt);
				if (abs((lStartChar % 0xffff - iCaretPos)) < abs((lEndChar % 0xffff - iCaretPos)))
				{
					iCaretPos = lStartChar;
					lStartChar = lEndChar;
					lEndChar = iCaretPos;
				}
			}
		}

		// Note: This will flicker, if someone has a good idea how to prevent this - let me know

		// Select at the end of text and replace the selection
		// This is a very fast way to add text to an edit control
		SafeAddLine(iSize, pszMsg, iLen, lStartChar, lEndChar, bLink, cr, bk, mask);
		//if (m_bAutoScroll && lStartChar == lEndChar)
		//	lStartChar = lEndChar = -1;
		SetSel(lStartChar, lEndChar); // Restore our previous selection

		if (!m_bAutoScroll){
			LineScroll(iFirstLine - GetFirstVisibleLine());
			//SendMessage(EM_SETSCROLLPOS, 0, (LPARAM)&ptScrollPos);
		}
		else
			ScrollToLastLine();

		m_bNoPaint = false;
		if (bIsVisible){
			SetRedraw();
			if (m_bRichEdit)
				Invalidate();
		}
	}
}
Ejemplo n.º 13
0
void CTitleTimeEdit::KeyInDown()
{
    int nCharPos = CharFromPos(GetCaretPos());
    if(nCharPos < 3)
    {
        if(m_szTimeChar[1] > '0')
            m_szTimeChar[1] --;
        else if(m_szTimeChar[1] == '0')
        {
            if(m_szTimeChar[0] > '0')
            {
                m_szTimeChar[0] --;
                m_szTimeChar[1] = s_szMaxTMChar[1];
            }
        }
    }
    else if(nCharPos < 6)
    {
        if(m_szTimeChar[4] > '0')
            m_szTimeChar[4] --;
        else if(m_szTimeChar[4] == '0')
        {
            if(m_szTimeChar[3] > '0')
            {
                m_szTimeChar[3] --;
                m_szTimeChar[4] = s_szMaxTMChar[4];
            }
        }
    }
    else if(nCharPos < 9)
    {
        if(m_szTimeChar[7] > '0')
            m_szTimeChar[7] --;
        else if(m_szTimeChar[7] ==  '0')
        {
            if(m_szTimeChar[6] > '0')
            {
                m_szTimeChar[6] --;
                m_szTimeChar[7] = s_szMaxTMChar[7];
            }
        }
    }
    else
    {
        if(m_szTimeChar[11] > '0')
            m_szTimeChar[11] --;
        else if(m_szTimeChar[11] == '0')
        {
            if(m_szTimeChar[10] > '0')
            {
                m_szTimeChar[10] --;
                m_szTimeChar[11] = s_szMaxTMChar[11];
            }
            else if(m_szTimeChar[10] == '0')
            {
                if(m_szTimeChar[9] > '0')
                {
                    m_szTimeChar[9] --;
                    m_szTimeChar[10] = s_szMaxTMChar[10];
                    m_szTimeChar[11] = s_szMaxTMChar[11];
                }
            }
        }
    }
    Update();
    SetSel(nCharPos, nCharPos);
}
Ejemplo n.º 14
0
void CTitleTimeEdit::KeyInUp()
{
    int nCharPos = CharFromPos(GetCaretPos());
    if(nCharPos < 3)
    {
        if(m_szTimeChar[1] < s_szMaxTMChar[1])
            m_szTimeChar[1] ++;
        else if(m_szTimeChar[1] == s_szMaxTMChar[1])
        {
            if(m_szTimeChar[0] < s_szMaxTMChar[0])
            {
                m_szTimeChar[0] ++;
                m_szTimeChar[1] = '0';
            }
        }
    }
    else if(nCharPos < 6)
    {
        if(m_szTimeChar[4] < s_szMaxTMChar[4])
            m_szTimeChar[4] ++;
        else if(m_szTimeChar[4] == s_szMaxTMChar[4])
        {
            if(m_szTimeChar[3] < s_szMaxTMChar[3])
            {
                m_szTimeChar[3] ++;
                m_szTimeChar[4] = '0';
            }
        }
    }
    else if(nCharPos < 9)
    {
        if(m_szTimeChar[7] < s_szMaxTMChar[7])
            m_szTimeChar[7] ++;
        else if(m_szTimeChar[7] == s_szMaxTMChar[7])
        {
            if(m_szTimeChar[6] < s_szMaxTMChar[6])
            {
                m_szTimeChar[6] ++;
                m_szTimeChar[7] = '0';
            }
        }
    }
    else
    {
        if(m_szTimeChar[11] < s_szMaxTMChar[11])
            m_szTimeChar[11] ++;
        else if(m_szTimeChar[11] == s_szMaxTMChar[11])
        {
            if(m_szTimeChar[10] < s_szMaxTMChar[10])
            {
                m_szTimeChar[10] ++;
                m_szTimeChar[11] = '0';
            }
            else if(m_szTimeChar[10] == s_szMaxTMChar[10])
            {
                if(m_szTimeChar[9] < s_szMaxTMChar[9])
                {
                    m_szTimeChar[9] ++;
                    m_szTimeChar[10] = '0';
                    m_szTimeChar[11] = '0';
                }
            }
        }
    }
    Update();
    SetSel(nCharPos, nCharPos);
}
Ejemplo n.º 15
0
bool ChatCtrl::HitNick(const POINT& p, tstring& sNick, int& iBegin, int& iEnd) {
	if(client == NULL) return false;
	
	int iCharPos = CharFromPos(p), line = LineFromChar(iCharPos), len = LineLength(iCharPos) + 1;
	long lSelBegin = 0, lSelEnd = 0;
	if(len < 3)
		return false;

	// Metoda FindWordBreak nestaci, protoze v nicku mohou byt znaky povazovane za konec slova
	int iFindBegin = LineIndex(line), iEnd1 = LineIndex(line) + LineLength(iCharPos);

	for(lSelBegin = iCharPos; lSelBegin >= iFindBegin; lSelBegin--) {
		if(FindWordBreak(WB_ISDELIMITER, lSelBegin))
			break;
	}
	lSelBegin++;
	for(lSelEnd = iCharPos; lSelEnd < iEnd1; lSelEnd++) {
		if(FindWordBreak(WB_ISDELIMITER, lSelEnd))
			break;
	}

	len = lSelEnd - lSelBegin;
	if(len <= 0)
		return false;

	tstring sText;
	sText.resize(len);

	GetTextRange(lSelBegin, lSelEnd, &sText[0]);

	size_t iLeft = 0, iRight = 0, iCRLF = sText.size(), iPos = sText.find(_T('<'));
	if(iPos != tstring::npos) {
		iLeft = iPos + 1;
		iPos = sText.find(_T('>'), iLeft);
		if(iPos == tstring::npos) 
			return false;

		iRight = iPos - 1;
		iCRLF = iRight - iLeft + 1;
	} else {
		iLeft = 0;
	}

	tstring sN = sText.substr(iLeft, iCRLF);
	if(sN.empty())
		return false;

	if(client->findUser(Text::fromT(sN)) != NULL) {
		sNick = sN;
		iBegin = lSelBegin + iLeft;
		iEnd = lSelBegin + iLeft + iCRLF;
		return true;
	}
    
	// Jeste pokus odmazat eventualni koncovou ':' nebo '>' 
	// Nebo pro obecnost posledni znak 
	// A taky prvni znak 
	// A pak prvni i posledni :-)
	if(iCRLF > 1) {
		sN = sText.substr(iLeft, iCRLF - 1);
		if(client->findUser(Text::fromT(sN)) != NULL) {
			sNick = sN;
   			iBegin = lSelBegin + iLeft;
   			iEnd = lSelBegin + iLeft + iCRLF - 1;
			return true;
		}

		sN = sText.substr(iLeft + 1, iCRLF - 1);
		if(client->findUser(Text::fromT(sN)) != NULL) {
        	sNick = sN;
			iBegin = lSelBegin + iLeft + 1;
			iEnd = lSelBegin + iLeft + iCRLF;
			return true;
		}

		sN = sText.substr(iLeft + 1, iCRLF - 2);
		if(client->findUser(Text::fromT(sN)) != NULL) {
			sNick = sN;
   			iBegin = lSelBegin + iLeft + 1;
			iEnd = lSelBegin + iLeft + iCRLF - 1;
			return true;
		}
	}	
	return false;
}
Ejemplo n.º 16
0
//////////////////////////////////////////////////////////////////////////////
// This function is based on Daniel Lohmann's article "CEditLog - fast logging
// into an edit control with cout" at http://www.codeproject.com
void CLogEditCtrl::AddLine(LPCTSTR pszMsg, int iLen)
{
	int iMsgLen = (iLen == -1) ? _tcslen(pszMsg) : iLen;
	if (iMsgLen == 0)
		return;
#ifdef _DEBUG
	if (pszMsg[iMsgLen - 1] == _T('\n'))
		ASSERT( iMsgLen >= 2 && pszMsg[iMsgLen - 2] == _T('\r') );
#endif

	// Get Edit contents dimensions and cursor position
	int iStartChar, iEndChar;
	GetSel(iStartChar, iEndChar);
	int iWndTxtLen = GetWindowTextLength();

	if (iStartChar == iWndTxtLen && iWndTxtLen == iEndChar)
	{
		// The cursor resides at the end of text
		SCROLLINFO si;
		si.cbSize = sizeof si;
		si.fMask = SIF_ALL;
		if (m_bAutoScroll && GetScrollInfo(SB_VERT, &si) && si.nPos >= (int)(si.nMax - si.nPage + 1))
		{
			// Not scrolled away
			SafeAddLine(iWndTxtLen, iMsgLen, pszMsg, iStartChar, iEndChar);
			if (m_bAutoScroll && !IsWindowVisible())
				ScrollToLastLine();
		}
		else
		{
			// Reduce flicker by ignoring WM_PAINT
			m_bNoPaint = true;
			BOOL bIsVisible = IsWindowVisible();
			if (bIsVisible)
				SetRedraw(FALSE);

			// Remember where we are
			int nFirstLine = !m_bAutoScroll ? GetFirstVisibleLine() : 0;
		
			// Select at the end of text and replace the selection
			// This is a very fast way to add text to an edit control
			SafeAddLine(iWndTxtLen, iMsgLen, pszMsg, iStartChar, iEndChar);
			SetSel(iStartChar, iEndChar, TRUE); // Restore our previous selection

			if (!m_bAutoScroll)
				LineScroll(nFirstLine - GetFirstVisibleLine());
			else
				ScrollToLastLine();

			m_bNoPaint = false;
			if (bIsVisible){
				SetRedraw();
				if (m_bRichEdit)
					Invalidate();
			}
		}
	}
	else
	{
		// We should add the text anyway...

		// Reduce flicker by ignoring WM_PAINT
		m_bNoPaint = true;
		BOOL bIsVisible = IsWindowVisible();
		if (bIsVisible)
			SetRedraw(FALSE);

		// Remember where we are
		int nFirstLine = !m_bAutoScroll ? GetFirstVisibleLine() : 0;
	
		if (iStartChar != iEndChar)
		{
			// If we are currently selecting some text, we have to find out
			// if the caret is near the beginning of this block or near the end.
			// Note that this does not always work. Because of the EM_CHARFROMPOS
			// message returning only 16 bits this will fail if the user has selected 
			// a block with a length dividable by 64k.

			// NOTE: This may cause a lot of terrible CRASHES within the RichEdit control when used for a RichEdit control!?
			// To reproduce the crash: click in the RE control while it's drawing a line an start a selection!
			if (!m_bRichEdit){
			    CPoint pt;
			    ::GetCaretPos(&pt);
			    int nCaretPos = CharFromPos(pt);
			    if (abs((iStartChar % 0xffff - nCaretPos)) < abs((iEndChar % 0xffff - nCaretPos)))
			    {
				    nCaretPos = iStartChar;
				    iStartChar = iEndChar;
				    iEndChar = nCaretPos;
			    }
		    }
		}

		// Note: This will flicker, if someone has a good idea how to prevent this - let me know
		
		// Select at the end of text and replace the selection
		// This is a very fast way to add text to an edit control
		SafeAddLine(iWndTxtLen, iMsgLen, pszMsg, iStartChar, iEndChar);
		SetSel(iStartChar, iEndChar, TRUE); // Restore our previous selection

		if (!m_bAutoScroll)
			LineScroll(nFirstLine - GetFirstVisibleLine());
		else
			ScrollToLastLine();

		m_bNoPaint = false;
		if (bIsVisible){
			SetRedraw();
			if (m_bRichEdit)
				Invalidate();
		}
	}
}