/*
================
CSyntaxRichEditCtrl::BracedSectionAdjustEndTabs
================
*/
void CSyntaxRichEditCtrl::BracedSectionAdjustEndTabs(void)
{
	int line, lineIndex, length, column, numTabs, i;
	char buffer[1024];
	idStr text;

	line = LineFromChar(bracedSection[0]);
	length = GetLine(line, buffer, sizeof(buffer));

	for (numTabs = 0; numTabs < length; numTabs++) {
		if (!idStr::CharIsTab(buffer[numTabs])) {
			break;
		}

		text.Append('\t');
	}

	line = LineFromChar(bracedSection[1]);
	lineIndex = LineIndex(line);
	length = GetLine(line, buffer, sizeof(buffer));
	column = bracedSection[1] - lineIndex;

	for (i = 0; i < column; i++) {
		if (charType[buffer[i]] != CT_WHITESPACE) {
			return;
		}
	}

	ReplaceText(lineIndex, lineIndex + column, text);

	bracedSection[1] += numTabs - column;
	SetSel(bracedSection[1]+1, bracedSection[1]+1);
}
Exemple #2
0
void CTWScriptEdit::FormatTextLines(int nLineStart, int nLineEnd)
{
	long nStart = LineIndex(LineFromChar(nLineStart));
	long nEnd = LineIndex(LineFromChar(nLineEnd));
	nEnd += LineLength(nLineEnd);

	FormatTextRange(nStart, nEnd);
}
Exemple #3
0
void CEmoticonRichEditCtrl::FormatTextLines(int nLineStart, int nLineEnd)
{		
	long nStart = LineIndex(LineFromChar(nLineStart));
	long nEnd = LineIndex(LineFromChar(nLineEnd));
	nEnd += LineLength(nLineEnd);

	FormatTextRange(nStart, nEnd);
}
Exemple #4
0
int JHCEdit::SetSelFullLines(void)
{
	int s, e, sl, el;
	GetSel(s, e);
	if (e < 0) return 0;
	sl = LineFromChar(s); el = LineFromChar(e);
	s = LineIndex(sl);
	if (e > LineIndex(el))
		e = LineIndex(el) + LineLength(e);
	else
		e = LineIndex(el) + LineLength(LineIndex(el));
	SetSel(s, e);
	return (el - sl + 1);
}
/*
================
CSyntaxRichEditCtrl::GetNameBeforeCurrentSelection
================
*/
bool CSyntaxRichEditCtrl::GetNameBeforeCurrentSelection(CString &name, int &charIndex) const
{
	long selStart, selEnd;
	int line, column, length;
	char buffer[1024];

	GetSel(selStart, selEnd);
	charIndex = selStart;
	line = LineFromChar(selStart);
	length = GetLine(line, buffer, sizeof(buffer));
	column = selStart - LineIndex(line) - 1;

	do {
		buffer[column--] = '\0';
	} while (charType[buffer[column]] == CT_WHITESPACE);

	for (length = 0; length < column; length++) {
		if (charType[buffer[column-length-1]] != CT_NAME) {
			break;
		}
	}

	if (length > 0) {
		name = buffer + column - length;
		return true;
	}

	return false;
}
Exemple #6
0
int CxEdit::GetCol(void) const 
{ 
   int begin = 0, end = 0;
   GetSel(begin, end);
   int nRow = LineFromChar();
   int nCol = begin - LineIndex(nRow);
   return nCol;
}
Exemple #7
0
void JHCEdit::SetSelStartLine(int line)
{
	int lc, i;
	lc = GetLineCount();
	if (line < 0) i = lc + line + 1; else i = line;
	if ((i < 0) || (i > lc)) return;
	i--; if (i < 0) i = LineFromChar();
	i = LineIndex(i);
	SetSel(i, i);
}
void CEditExtn::OnSetFocus(CWnd* pOldWnd)
{
  m_bIsFocused = TRUE;
  CEdit::OnSetFocus(pOldWnd);
  if (m_lastposition >= 0) {
    int iLine = LineFromChar(m_lastposition);
    LineScroll(iLine);
    SetSel(m_nStartChar, m_nEndChar); 
  }
  Invalidate(TRUE);
}
Exemple #9
0
int JHCEdit::GetLine(CString& str, int line)
{
	int n, lc, i;
	lc = GetLineCount();
	if (line < 0) i = lc + line + 1; else i = line;
	if ((i < 0) || (i > lc)) return 0;
	i--; if (i < 0) i = LineFromChar();
	n = LineLength(LineIndex(i));
	CEdit::GetLine(i, str.GetBuffer(n+1), n); str.ReleaseBuffer(n);
	return n;
}
Exemple #10
0
void CRichEditExtn::OnSetFocus(CWnd* pOldWnd)
{
  m_bIsFocused = TRUE;
  CRichEditCtrl::OnSetFocus(pOldWnd);
  if (m_lastposition >= 0) {
    int iLine = LineFromChar(m_lastposition);
    LineScroll(iLine);
    SetSel(m_nStartChar, m_nEndChar); 
  }

  SetBackgroundColor(FALSE, m_crefInFocus);
  Invalidate(TRUE);
}
Exemple #11
0
int JHCEdit::GetString(CString& str, int start, int end)
{
	int s, e, ls, le, n;
	CString ss;
	if (start < 0) GetSel(s, e); else {s = start; e = end;}
	if (e < s) e = s;
	ls = LineFromChar(s);
	le = LineFromChar(e);
	str = CString("");
	for (int i = ls; (i <= le); i++)
	{
		n = LineLength(LineIndex(i));
		CEdit::GetLine(i, ss.GetBuffer(n+1), n); ss.ReleaseBuffer(n);
		if (i == ls) ss = ss.Mid(s - LineIndex(i)); else str += CString("\r\n");
		if (i == le)
		{
			n = e - (s + str.GetLength());
			ss = ss.Left(n);
		}
		str += ss;
	}
	return str.GetLength();
}
Exemple #12
0
void JHCEdit::DeleteLine(int line)
{
	int n, lc, i;
	lc = GetLineCount();
	if (line < 0) i = lc + line + 1; else i = line;
	if ((i < 0) || (i > lc)) return;
	i--; if (i < 0) i = LineFromChar();
	i = LineIndex(i);
	n = LineLength(i);
	SetSel(i, i + n + 1);
	ReplaceSel(CString(""), TRUE);
	n = LineLength(i);
	SetSel(i, i);
}
Exemple #13
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;
}
/*
================
CSyntaxRichEditCtrl::GetCursorPos
================
*/
void CSyntaxRichEditCtrl::GetCursorPos( int &line, int &column, int &character ) const {
	long start, end;
	char buffer[MAX_STRING_CHARS];

	GetSel( start, end );
	line = LineFromChar( start );
	start -= LineIndex( line );
	GetLine( line, buffer, sizeof( buffer ) );
	for ( column = 1, character = 0; character < start; character++ ) {
		if ( idStr::CharIsTab( buffer[character] ) ) {
			column += TAB_SIZE;
			column -= column % TAB_SIZE;
		} else {
			column++;
		}
	}
	character++;
}
/*
================
CSyntaxRichEditCtrl::FindNext
================
*/
bool CSyntaxRichEditCtrl::FindNext(const char *find, bool matchCase, bool matchWholeWords, bool searchForward)
{
	long selStart, selEnd, flags, search, length, start;
	tom::ITextRange *range;

	if (find[0] == '\0') {
		return false;
	}

	GetSel(selStart, selEnd);

	flags = 0;
	flags |= matchCase ? tom::tomMatchCase : 0;
	flags |= matchWholeWords ? tom::tomMatchWord : 0;

	if (searchForward) {
		m_TextDoc->Range(selEnd, GetTextLength(), &range);
		search = GetTextLength() - selEnd;
	} else {
		m_TextDoc->Range(0, selStart, &range);
		search = -selStart;
	}

	if (range->FindShit(A2BSTR(find), search, flags, &length) == S_OK) {

		m_TextDoc->Freeze(NULL);

		range->get_Start(&start);
		range->Release();

		SetSel(start, start + length);

		int line = Max((int) LineFromChar(start) - 5, 0);
		LineScroll(line - GetFirstVisibleLine(), 0);

		UpdateVisibleRange();

		m_TextDoc->Unfreeze(NULL);
		return true;
	} else {
		range->Release();
		return false;
	}
}
const TCHAR* CCustRichEdit::GetCurLineText (CString& Buffer) {
  int	  LineSize;
  int	  LineIndex;
  TCHAR*  pBuffer;

	/* Get the current line text buffer */
  LineIndex = LineFromChar(-1);
  LineSize  = LineLength(-1);

  if (LineSize > 0) {
    pBuffer = Buffer.GetBuffer(LineSize+4);
    GetLine(LineIndex, pBuffer, LineSize+4);
    pBuffer[LineSize] = NULL_CHAR;
    Buffer.ReleaseBuffer(LineSize);
   }
  else {
    Buffer.Empty();
   }

  return (const TCHAR*) (Buffer);
 }
Exemple #17
0
int JHCEdit::DeleteChar(int count)
{
	if (count == 0) return 0;
	int s, e, ls, le;
	GetSel(s, e);
	ls = LineIndex(LineFromChar(s));
	le = ls + LineLength(ls);
	if (count > 0)
	{
		e = s + count;
		if (e > le) e = le;
	}
	else
	{
		e = s;
		s = s + count;
		if (s < ls) s = ls;
	}
	SetSel(s, e);
	Clear();
	return e - s + 1;
}
Exemple #18
0
LRESULT CScriptEditView::OnKey( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& )
{
	LRESULT lRet = DefWindowProc( uMsg, wParam, lParam );

	//if( uMsg == WM_KEYDOWN && wParam == VK_INSERT )
	//{
	//	bool bOn = ((GetKeyState(VK_INSERT) & 1) == 1);
	//	if( bOn )
	//		CreateSolidCaret( 10, 10 );
	//	else
	//		CreateSolidCaret( 2, 10 );
	//}

	// calc caret position
	long nStartPos, nEndPos;
	GetSel( nStartPos, nEndPos );
	int nRow = LineFromChar( nEndPos );
	int nCol = 0;
	int nChar = nEndPos - LineIndex();
	if( nChar > 0 )
	{
		// min = WORD for length
		LPTSTR lpstrLine = (LPTSTR)_alloca( (nChar + 2) * sizeof(TCHAR) );
		nChar = GetLine( nRow, lpstrLine, nChar );
		for( int i = 0; i < nChar; i++ )
		{
			if(lpstrLine[i] == _T('\t'))
				nCol = ((nCol / m_nTabStop) + 1) * m_nTabStop;
			else
				nCol++;
		}
	}

	WtlGetMainWnd().UndateRowCol( nRow + 1, nCol + 1 );

	return lRet;
}
/*
================
CSyntaxRichEditCtrl::OnChar
================
*/
void CSyntaxRichEditCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{

	if (nChar == VK_TAB) {
		return;	// tab is handle in OnKeyDown
	}

	CRichEditCtrl::OnChar(nChar, nRepCnt, nFlags);

	// if the auto-complete list box is up
	if (autoCompleteStart >= 0) {
		long selStart, selEnd;

		if (charType[nChar] == CT_NAME) {
			AutoCompleteUpdate();
			return;
		} else if (nChar == VK_BACK) {
			GetSel(selStart, selEnd);

			if (selStart > autoCompleteStart) {
				AutoCompleteUpdate();
			} else {
				AutoCompleteHide();
			}

			return;
		} else {
			AutoCompleteHide();
		}
	}

	// if the function parameter tool tip is up
	if (funcParmToolTipStart >= 0) {
		long selStart, selEnd;

		if (nChar == ')' || nChar == VK_ESCAPE) {
			ToolTipHide();
		} else if (nChar == VK_BACK) {
			GetSel(selStart, selEnd);

			if (selStart < funcParmToolTipStart) {
				ToolTipHide();
			}
		}
	}

	// show keyword auto-completion
	if (keyWordAutoCompletion && charType[nChar] == CT_NAME && funcParmToolTipStart < 0) {
		long selStart, selEnd;
		int line, column, length, i;
		char buffer[1024];

		GetSel(selStart, selEnd);
		line = LineFromChar(selStart);
		length = GetLine(line, buffer, sizeof(buffer));
		column = selStart - LineIndex(line);

		if (column <= 1 || charType[buffer[column-2]] == CT_WHITESPACE) {
			if (column >= length-1 || charType[buffer[column]] == CT_WHITESPACE) {

				autoCompleteListBox.ResetContent();

				for (i = 0; keyWords[i].keyWord; i++) {
					autoCompleteListBox.AddString(keyWords[i].keyWord);
				}

				AutoCompleteShow(selStart - 1);
			}
		}

		return;
	}

	// highlight braced sections
	if (nChar == '{') {
		BracedSectionStart('{', '}');
	} else if (nChar == '}') {
		BracedSectionEnd('{', '}');
	} else if (nChar == '(') {
		BracedSectionStart('(', ')');
	} else if (nChar == ')') {
		BracedSectionEnd('(', ')');
	} else if (nChar == '[') {
		BracedSectionStart('[', ']');
	} else if (nChar == ']') {
		BracedSectionEnd('[', ']');
	} else if (nChar == '<') {
		BracedSectionStart('<', '>');
	} else if (nChar == '>') {
		BracedSectionEnd('<', '>');
	}

	// show object member auto-completion
	if (nChar == '.' && GetObjectMembers && funcParmToolTipStart < 0) {
		int charIndex;
		CString name;

		if (GetNameBeforeCurrentSelection(name, charIndex)) {
			autoCompleteListBox.ResetContent();

			if (GetObjectMembers(name, autoCompleteListBox)) {
				AutoCompleteShow(charIndex);
			}
		}

		return;
	}

	// show function parameter tool tip
	if (nChar == '(' && GetFunctionParms) {
		int charIndex;
		CString name;

		if (GetNameBeforeCurrentSelection(name, charIndex)) {
			CString parmString;

			if (GetFunctionParms(name, parmString)) {
				ToolTipShow(charIndex, parmString);
			}
		}

		return;
	}
}
/*
================
CSyntaxRichEditCtrl::OnKeyDown
================
*/
void CSyntaxRichEditCtrl::OnKeyDown(UINT nKey, UINT nRepCnt, UINT nFlags)
{

	if (m_TextDoc == NULL) {
		return;
	}

	if (autoCompleteStart >= 0) {
		int sel;

		switch (nKey) {
			case VK_UP: {		// up arrow
				sel = Max(0, autoCompleteListBox.GetCurSel() - 1);
				autoCompleteListBox.SetCurSel(sel);
				return;
			}
			case VK_DOWN: {		// down arrow
				sel = Min(autoCompleteListBox.GetCount() - 1, autoCompleteListBox.GetCurSel() + 1);
				autoCompleteListBox.SetCurSel(sel);
				return;
			}
			case VK_PRIOR: {	// page up key
				sel = Max(0, autoCompleteListBox.GetCurSel() - 10);
				autoCompleteListBox.SetCurSel(sel);
				return;
			}
			case VK_NEXT: {		// page down key
				sel = Min(autoCompleteListBox.GetCount() - 1, autoCompleteListBox.GetCurSel() + 10);
				autoCompleteListBox.SetCurSel(sel);
				return;
			}
			case VK_HOME: {		// home key
				autoCompleteListBox.SetCurSel(0);
				return;
			}
			case VK_END: {
				autoCompleteListBox.SetCurSel(autoCompleteListBox.GetCount() - 1);
				return;
			}
			case VK_RETURN:		// enter key
			case VK_TAB: {		// tab key
				AutoCompleteInsertText();
				AutoCompleteHide();
				return;
			}
			case VK_LEFT:		// left arrow
			case VK_RIGHT:		// right arrow
			case VK_INSERT:		// insert key
			case VK_DELETE: {	// delete key
				return;
			}
		}
	}

	BracedSectionHide();

	switch (nKey) {
		case VK_TAB: {		// multi-line tabs
			long selStart, selEnd;

			GetSel(selStart, selEnd);

			// if multiple lines are selected add tabs to, or remove tabs from all of them
			if (selEnd > selStart) {
				CString text;

				text = GetSelText();

				if (GetAsyncKeyState(VK_SHIFT) & 0x8000) {
					if (idStr::CharIsTab(text[0])) {
						text.Delete(0, 1);
					}

					for (int i = 0; i < text.GetLength() - 2; i++) {
						if (idStr::CharIsNewLine(text[i])) {
							do {
								i++;
							} while (idStr::CharIsNewLine(text[i]));

							if (idStr::CharIsTab(text[i])) {
								text.Delete(i, 1);
							}
						}
					}
				} else {
					text.Insert(0, '\t');

					for (int i = 0; i < text.GetLength() - 1; i++) {
						if (idStr::CharIsNewLine(text[i])) {
							do {
								i++;
							} while (idStr::CharIsNewLine(text[i]));

							text.Insert(i, '\t');
						}
					}
				}

				ReplaceSel(text, TRUE);
				SetSel(selStart, selStart + text.GetLength());
			} else {
				ReplaceSel("\t", TRUE);
			}

			return;
		}
		case VK_RETURN: {	// auto-indentation
			long selStart, selEnd;
			int line, length, numTabs, i;
			char buffer[1024];
			idStr text;

			GetSel(selStart, selEnd);
			line = LineFromChar(selStart);
			length = GetLine(line, buffer, sizeof(buffer));

			for (numTabs = 0; numTabs < length; numTabs++) {
				if (!idStr::CharIsTab(buffer[numTabs])) {
					break;
				}
			}

			bool first = true;

			for (i = numTabs; i < length; i++) {
				if (buffer[i] == '{') {
					numTabs++;
					first = false;
				} else if (buffer[i] == '}' && !first) {
					numTabs--;
				}
			}

			text = "\r\n";

			for (i = 0; i < numTabs; i++) {
				text.Append('\t');
			}

			ReplaceSel(text, TRUE);
			return;
		}
	}

	m_TextDoc->Freeze(NULL);

	CRichEditCtrl::OnKeyDown(nKey, nRepCnt, nFlags);

	UpdateVisibleRange();

	m_TextDoc->Unfreeze(NULL);
}
bool CFulEditCtrl::AddLine(const tstring & line, bool aTimeStamps) {
	bool noScroll = false;
	matchedTab = false;
	timeStamps = aTimeStamps;

	tstring aLine = Util::replace(line, _T("\r\n"), _T("\r"));
	if(GetWindowTextLength() > SETTING(CHATBUFFERSIZE)) {
		SetRedraw(FALSE);
		int ch = LineIndex(LineFromChar(2000));
		SetSel(0, ch);
		ReplaceSel(_T(""));
		UpdateUrlRanges(ch);
		SetSel(GetTextLengthEx(GTL_NUMCHARS), GetTextLengthEx(GTL_NUMCHARS));
		ScrollCaret();
		SetRedraw(TRUE);
	}
	if(Util::strnicmp(_T("<") + nick + _T(">"), aLine, nick.length() + 2) == 0)
		skipLog = true;

	if(isSet(STRIP_ISP) && aLine[0] == _T('<')) {
		tstring::size_type end = aLine.find(_T(">"));
		if( end != tstring::npos ) {
			tstring::size_type pos = aLine.rfind(_T("]"), end);
			if( end > 0 && (end-1) == pos )
				pos = aLine.rfind(_T("]"), pos-1);
			
			if(pos != string::npos) 
				aLine = _T("<") + aLine.substr(pos+1);
		}
	}
		
	tstring::size_type pos = aLine.find(_T("> /me "));
	if( pos != tstring::npos)
		aLine = _T("** ") + aLine.substr(1, pos-1) +  aLine.substr(pos+5, aLine.length());

	if(timeStamps)
		aLine = _T("[") + Util::getShortTimeString() + _T("] ") + aLine;
	
	
	SetRedraw(FALSE);
	
	//Get the pos of the last char
	POINT pt = PosFromChar(GetTextLengthEx(GTL_NUMCHARS));
	CRect rc;
	GetClientRect(&rc);
	int l = -1;

	//check if the last char is visible, if not then save the
	//scrollbar position
	if(rc.PtInRect(pt)){
		noScroll = false;
	} else {
		noScroll = true;
		l = GetFirstVisibleLine();
	}
    
	AddInternalLine(aLine);
				
	//restore the scrollbar position
	if(noScroll) {
		LineScroll(l - GetFirstVisibleLine());
	} 

	SetRedraw();
	Invalidate();
	UpdateWindow();

	return matchedTab;
}
void CStatusCtrl::ShowStatus(CString status, int nType)
{
	USES_CONVERSION;

	CString rtfstr = m_RTFHeader;
	
	status.Replace(_T("\\"), _T("\\\\"));
	status.Replace(_T("{"), _T("\\{"));
	status.Replace(_T("}"), _T("\\}"));
	status.Replace(_T("\r"), _T(""));
	status.Replace(_T("\n"), _T("\\status"));
	
	CString str;
	switch (nType)
	{
	case FZ_LOG_STATUS:
		//str.LoadString(IDS_STATUSMSG_PREFIX);
		str += "\\cf2";
		break;
	case FZ_LOG_ERROR:
		//str.LoadString(IDS_ERRORMSG_PREFIX);
		str="\\cf5";
		break;
	case FZ_LOG_COMMAND:
		//str.LoadString(IDS_COMMANDMSG_PREFIX);
		str="\\cf3";
		break;
	case FZ_LOG_REPLY:
		//str.LoadString(IDS_RESPONSEMSG_PREFIX);
		str="\\cf4";
		break;
	case FZ_LOG_LIST:
		//str.LoadString(IDS_TRACEMSG_TRACE);
		str="\\cf11";
		break;
	case FZ_LOG_APIERROR:
	case FZ_LOG_WARNING:
	case FZ_LOG_INFO:
	case FZ_LOG_DEBUG:
		//str.LoadString(IDS_TRACEMSG_TRACE);
		str="\\cf7";
		break;
	}

	CString tmp;
	tmp += str;
	tmp += "\\tab ";
	tmp += status;
	status = tmp;

	if (!m_bEmpty){
		rtfstr += "\\par ";
		rtfstr += status;
	}else
	{
		m_bEmpty = FALSE;
		rtfstr += status;
	}
	
	rtfstr += "} ";


	EDITSTREAM es;

	string s = Util::ws2s(wstring(rtfstr));
	es.dwCookie = (DWORD)&s;	// Pass a pointer to the string to the callback function 
	es.pfnCallback = RichEditStreamInCallback; // Specify the pointer to the callback function.

	CWnd *pFocusWnd = GetFocus();
	if (pFocusWnd && pFocusWnd == this)
		AfxGetMainWnd()->SetFocus();
	
	long nStart, nEnd;
	GetSel(nStart, nEnd);
	BOOL nScrollToEnd = FALSE;
	
	int num = 0;            //this is the number of visible lines
	CRect rect;
	GetRect(rect);
	int height = rect.Height();
	
	for (int i = GetFirstVisibleLine();	i < GetLineCount() && GetCharPos(LineIndex(i)).y < height; i++)
		num++;


	if (GetFirstVisibleLine() + num+m_nMoveToBottom >= GetLineCount())
		nScrollToEnd = TRUE;
	HideSelection(TRUE, FALSE);
	SetSel(-1, -1);
	StreamIn(SF_RTF | SFF_SELECTION, es); // Perform the streaming

	if (GetLineCount() > 1000)
	{
		nStart -= LineLength(0) + 2;
		nEnd -= LineLength(0) + 2;
		if (nStart < 0)
			nEnd = 0;
		if (nEnd < 0)
			nEnd = 0;
		SetSel(0, LineLength(0) + 2);
		ReplaceSel(_T(""));
	}

	SetSel(nStart, nEnd);
	
	if (pFocusWnd && pFocusWnd == this)
		SetFocus();

	HideSelection(FALSE, FALSE);
	if (nScrollToEnd)
	{
		if (nStart != nEnd && (LineFromChar(nStart) >= GetFirstVisibleLine() && LineFromChar(nStart) <= GetFirstVisibleLine() + num ||
							   LineFromChar(nEnd) >= GetFirstVisibleLine() && LineFromChar(nEnd) <= GetFirstVisibleLine() + num))
			LineScroll(1);
		else 
		{
			m_nMoveToBottom++;
			if (!m_nTimerID)
				m_nTimerID = SetTimer(654, 25, NULL);
		}
	}

}
Exemple #23
0
void CStatusCtrl::ShowStatus(CString status, int nType)
{
    USES_CONVERSION;

    CString rtfstr = m_RTFHeader;

    status.Replace(_T("\\"), _T("\\\\"));
    status.Replace(_T("{"), _T("\\{"));
    status.Replace(_T("}"), _T("\\}"));
    status.Replace(_T("\r"), _T(""));
    status.Replace(_T("\n"), _T("\\status"));

    CString str;
    switch (nType)
    {
    case 0:
        str = "\\cf2";
        break;
    case 1:
        str = "\\cf5";
        break;
    case 2:
        str = "\\cf3";
        break;
    case 3:
        str = "\\cf4";
        break;
    }

    status = str + status;

    if (!m_bEmpty)
        rtfstr += "\\par " + status;
    else
    {
        m_bEmpty = FALSE;
        rtfstr += status;
    }

    rtfstr += "} ";

    char *buffer = new char[rtfstr.GetLength() + 5]; //Make it large enough to hold unicode data
    strcpy(buffer + 4, T2CA(rtfstr));
    *(int *)buffer = 0;

    EDITSTREAM es;

    es.dwCookie = (DWORD)buffer; // Pass a pointer to the CString to the callback function
    es.pfnCallback = RichEditStreamInCallback; // Specify the pointer to the callback function.

    CWnd *pFocusWnd = GetFocus();
    if (pFocusWnd && pFocusWnd == this)
        AfxGetMainWnd()->SetFocus();

    long nStart, nEnd;
    GetSel(nStart, nEnd);
    BOOL nScrollToEnd = FALSE;

    int num = 0;            //this is the number of visible lines
    CRect rect;
    GetRect(rect);
    int height = rect.Height();

    for (int i = GetFirstVisibleLine();
            i < GetLineCount() && GetCharPos(LineIndex(i)).y < height;
            i++)
        num++;


    if (GetFirstVisibleLine() + num+m_nMoveToBottom >= GetLineCount())
        nScrollToEnd = TRUE;
    HideSelection(TRUE, FALSE);
    SetSel(-1, -1);
    StreamIn(SF_RTF | SFF_SELECTION, es); // Perform the streaming

    if (GetLineCount() > 1000)
    {
        nStart -= LineLength(0) + 2;
        nEnd -= LineLength(0) + 2;
        if (nStart < 0)
            nEnd = 0;
        if (nEnd < 0)
            nEnd = 0;
        SetSel(0, LineLength(0) + 2);
        ReplaceSel(_T(""));
    }

    SetSel(nStart, nEnd);

    if (pFocusWnd && pFocusWnd == this)
        SetFocus();

    HideSelection(FALSE, FALSE);
    if (nScrollToEnd)
    {
        if (nStart != nEnd && (LineFromChar(nStart) >= GetFirstVisibleLine() && LineFromChar(nStart) <= GetFirstVisibleLine() + num ||
                               LineFromChar(nEnd) >= GetFirstVisibleLine() && LineFromChar(nEnd) <= GetFirstVisibleLine() + num))
            LineScroll(1);
        else
        {
            m_nMoveToBottom++;
            if (!m_nTimerID)
                m_nTimerID = SetTimer(654, 25, NULL);
        }
    }

    delete [] buffer;
}
Exemple #24
0
int CxEdit::GotoEnd(BOOL bScroll /*= TRUE*/)
{
   const int length = GetWindowTextLength();
   SetSel(length, length, !bScroll); // end of edit text
   return LineFromChar(length);
}
Exemple #25
0
void ChatCtrl::AppendText(const Identity& i, const tstring& sMyNick, const tstring& sTime, tstring sMsg, CHARFORMAT2& cf, bool bUseEmo/* = true*/) {
	SetRedraw(FALSE);

	SCROLLINFO si = { 0 };
	POINT pt = { 0 };

	si.cbSize = sizeof(si);
	si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
	GetScrollInfo(SB_VERT, &si);
	GetScrollPos(&pt);

	LONG lSelBegin = 0, lSelEnd = 0, lTextLimit = 0, lNewTextLen = 0;
	LONG lSelBeginSaved, lSelEndSaved;

	// Unify line endings
	tstring::size_type j = 0; 
	while((j = sMsg.find(_T("\r"), j)) != tstring::npos)
		sMsg.erase(j, 1);

	GetSel(lSelBeginSaved, lSelEndSaved);
	lSelEnd = lSelBegin = GetTextLengthEx(GTL_NUMCHARS);

	bool isMyMessage = i.getUser() == ClientManager::getInstance()->getMe();
	tstring sLine = sTime + sMsg;

	// Remove old chat if size exceeds
	lNewTextLen = sLine.size();
	lTextLimit = GetLimitText();

	if(lSelEnd + lNewTextLen > lTextLimit) {
		LONG lRemoveChars = 0;
		int multiplier = 1;

		if(lNewTextLen >= lTextLimit) {
			lRemoveChars = lSelEnd;
			magnets.clear();
		} else {
			while(lRemoveChars < lNewTextLen)
				lRemoveChars = LineIndex(LineFromChar(multiplier++ * lTextLimit / 10));
		}

		if(magnets.size()) {
			tstring buf;
			buf.resize(lRemoveChars);
			GetTextRange(0, lRemoveChars, &buf[0]);

			CHARFORMAT2 cfSel;
			cfSel.cbSize = sizeof(CHARFORMAT2);

			for(TStringMap::iterator i = magnets.begin(); i != magnets.end();) {
				tstring::size_type j = 0;
				while((j = buf.find(i->first, j)) != tstring::npos) {
					SetSel(j, j + i->first.size());
					GetSelectionCharFormat(cfSel);
					if(cfSel.dwEffects & CFE_LINK) {
						magnets.erase(i++);
						break;
					}
					j += i->first.size();
				} if(j == tstring::npos) {
					++i;
				}
			}
		}

		// Update selection ranges
		lSelEnd = lSelBegin -= lRemoveChars;
		lSelEndSaved -= lRemoveChars;
		lSelBeginSaved -= lRemoveChars;

		// ...and the scroll position
		pt.y -= PosFromChar(lRemoveChars).y;

		SetSel(0, lRemoveChars);
		ReplaceSel(_T(""));
	}


	// Add to the end
	SetSel(lSelBegin, lSelEnd);
	setText(sLine);

	CHARFORMAT2 enc;
	enc.bCharSet = RUSSIAN_CHARSET;
	enc.dwMask = CFM_CHARSET;

	SetSel(0, sLine.length());
	SetSelectionCharFormat(enc);

	// Format TimeStamp
	if(!sTime.empty()) {
		lSelEnd += sTime.size();
		SetSel(lSelBegin, lSelEnd - 1);
		SetSelectionCharFormat(WinUtil::m_TextStyleTimestamp);

		PARAFORMAT2 pf;
		memzero(&pf, sizeof(PARAFORMAT2));
		pf.dwMask = PFM_STARTINDENT; 
		pf.dxStartIndent = 0;
		SetParaFormat(pf);
	}

	// Authors nick
	tstring sAuthor = Text::toT(i.getNick());
	if(!sAuthor.empty()) {
		LONG iLen = (sMsg[0] == _T('*')) ? 1 : 0;
		LONG iAuthorLen = sAuthor.size() + 1;
		sMsg.erase(0, iAuthorLen + iLen);
   		
		lSelBegin = lSelEnd;
		lSelEnd += iAuthorLen + iLen;
		
		if(isMyMessage) {
			SetSel(lSelBegin, lSelBegin + iLen + 1);
			SetSelectionCharFormat(WinUtil::m_ChatTextMyOwn);
			SetSel(lSelBegin + iLen + 1, lSelBegin + iLen + iAuthorLen);
			SetSelectionCharFormat(WinUtil::m_TextStyleMyNick);
		} else {
			bool isFavorite = FavoriteManager::getInstance()->isFavoriteUser(i.getUser());

			if(BOOLSETTING(BOLD_AUTHOR_MESS) || isFavorite || i.isOp()) {
				SetSel(lSelBegin, lSelBegin + iLen + 1);
				SetSelectionCharFormat(cf);
				SetSel(lSelBegin + iLen + 1, lSelEnd);
				if(isFavorite){
					SetSelectionCharFormat(WinUtil::m_TextStyleFavUsers);
				} else if(i.isOp()) {
					SetSelectionCharFormat(WinUtil::m_TextStyleOPs);
				} else {
					SetSelectionCharFormat(WinUtil::m_TextStyleBold);
				}
			} else {
				SetSel(lSelBegin, lSelEnd);
				SetSelectionCharFormat(cf);
            }
		}
	} else {
		bool thirdPerson = false;
        switch(sMsg[0]) {
			case _T('*'):
				if(sMsg[1] != _T(' ')) break;
				thirdPerson = true;
            case _T('<'):
				tstring::size_type iAuthorLen = sMsg.find(thirdPerson ? _T(' ') : _T('>'), thirdPerson ? 2 : 1);
				if(iAuthorLen != tstring::npos) {
                    bool isOp = false, isFavorite = false;

                    if(client != NULL) {
						tstring nick(sMsg.c_str() + 1);
						nick.erase(iAuthorLen - 1);
						
						const OnlineUserPtr ou = client->findUser(Text::fromT(nick));
						if(ou != NULL) {
							isFavorite = FavoriteManager::getInstance()->isFavoriteUser(ou->getUser());
							isOp = ou->getIdentity().isOp();
						}
                    }
                    
					lSelBegin = lSelEnd;
					lSelEnd += iAuthorLen;
					sMsg.erase(0, iAuthorLen);

        			if(BOOLSETTING(BOLD_AUTHOR_MESS) || isFavorite || isOp) {
        				SetSel(lSelBegin, lSelBegin + 1);
        				SetSelectionCharFormat(cf);
						SetSel(lSelBegin + 1, lSelEnd);
						if(isFavorite){
							SetSelectionCharFormat(WinUtil::m_TextStyleFavUsers);
						} else if(isOp) {
							SetSelectionCharFormat(WinUtil::m_TextStyleOPs);
						} else {
							SetSelectionCharFormat(WinUtil::m_TextStyleBold);
						}
        			} else {
        				SetSel(lSelBegin, lSelEnd);
        				SetSelectionCharFormat(cf);
                    }
				}
        }
	}
				   			
	// Format the message part
	FormatChatLine(sMyNick, sMsg, cf, isMyMessage, sAuthor, lSelEnd, bUseEmo);

	SetSel(lSelBeginSaved, lSelEndSaved);
	if(	isMyMessage || ((si.nPage == 0 || (size_t)si.nPos >= (size_t)si.nMax - si.nPage - 5) &&
		(lSelBeginSaved == lSelEndSaved || !selectedUser.empty() || !selectedIP.empty() || !selectedURL.empty())))
	{
		PostMessage(EM_SCROLL, SB_BOTTOM, 0);
	} else {
		SetScrollPos(&pt);
	}

	// Force window to redraw
	SetRedraw(TRUE);
	InvalidateRect(NULL);
}
Exemple #26
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;
}
Exemple #27
0
/*----------------------------------------------------------------------------------------------
	This processes Windows messages on the window. In general, it normally calls the
	appropriate method on the edit class.
----------------------------------------------------------------------------------------------*/
bool TssEdit::FWndProc(uint wm, WPARAM wp, LPARAM lp, long & lnRet)
{
	bool fRet;

	switch (wm)
	{
	case WM_GETDLGCODE:
		// This is essential when embedded in a dialog to tell the dialog manager that it
		// wants to get key strokes. (We could try DLGC_WANTALLKEYS but I think we would then
		// get the Tab and Return keys...we may get them anyway with this combination...)
		// The last value tells Windows that when tabbing to this control we should use
		// EM_SETSEL to select all the text.
		lnRet = DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_HASSETSEL;
		return true;
	case EM_GETLINE:	// Use FW_EM_GETLINE.
	case EM_REPLACESEL:	// Use FW_EM_REPLACESEL.
		// We don't support these methods. Use the replacement TsString versions instead.
		Assert(false);
		lnRet = LB_ERR;
		return true;

	// NOTE: DO NOT send this message to a TssEdit if you want the actual text. Send the
	// FW_EM_GETTEXT message instead. This method is required for TssEdit controls on a
	// dialog because Windows will send the message to the control anytime the user hits a
	// key.
	case WM_GETTEXT:
		{
			ITsStringPtr qtss;
			GetText(&qtss);
			const wchar * pwrgch;
			int cch;
			HRESULT hr;
			IgnoreHr(hr = qtss->LockText(&pwrgch, &cch));
			if (FAILED(hr))
				return true;
			StrApp str(pwrgch, cch);
			qtss->UnlockText(pwrgch);
			lnRet = Min(cch + 1, (int)wp);
			achar * psz = reinterpret_cast<achar *>(lp);
			StrCpyN(psz, str.Chars(), lnRet);
		}
		return true;

	// NOTE: You should be sending an FW_EM_SETTEXT message instead of this.
	case WM_SETTEXT:
		{
			achar * psz = reinterpret_cast<achar *>(lp);
			StrUni stu(psz);
			ITsStrFactoryPtr qtsf;
			qtsf.CreateInstance(CLSID_TsStrFactory);
			ITsStringPtr qtss;
			CheckHr(qtsf->MakeStringRgch(stu.Chars(), stu.Length(), m_wsBase, &qtss));
			SetText(qtss);
		}
		return true;

	case EM_CANUNDO:
	case EM_CHARFROMPOS:
	case EM_EMPTYUNDOBUFFER:
	case EM_FMTLINES:
	case EM_GETFIRSTVISIBLELINE:
	case EM_GETHANDLE:
	case EM_GETMODIFY:
	case EM_GETPASSWORDCHAR:
	case EM_GETRECT:
	case EM_GETTHUMB:
	case EM_GETWORDBREAKPROC:
	case EM_POSFROMCHAR:
	case EM_SETHANDLE:
	case EM_SETMODIFY:
	case EM_SETPASSWORDCHAR:
	case EM_SETRECT:
	case EM_SETRECTNP:
	case EM_SETTABSTOPS:
	case EM_SETWORDBREAKPROC:
	case EM_UNDO:
	case WM_GETFONT:
	case WM_SETFONT:
		// We don't support these methods.
		Assert(false);
		lnRet = LB_ERR;
		return true;

	case EM_GETLIMITTEXT:
		lnRet = GetLimitText();
		return true;

	case FW_EM_GETLINE:
		lnRet = GetLine(wp, (ITsString **)lp);
		return true;

	case EM_GETLINECOUNT:
		lnRet = GetLineCount();
		return true;

	case EM_GETMARGINS:
		lnRet = GetMargins();
		return true;

	case FW_EM_GETSTYLE:
		GetStyle((StrUni *)lp, (COLORREF *)wp);
		return true;

	case EM_GETSEL:
		lnRet = GetSel((int *)wp, (int *)lp);
		return true;

	case EM_LINEFROMCHAR:
		lnRet = LineFromChar(wp);
		return true;

	case EM_LINEINDEX:
		lnRet = LineIndex(wp);
		return true;

	case EM_LINELENGTH:
		lnRet = LineLength(wp);
		return true;

	case EM_LINESCROLL:
		LineScroll(lp, wp);
		return true;

	case FW_EM_REPLACESEL:
		ReplaceSel((ITsString *)lp);
		return true;

	case EM_SCROLL:
		lnRet = ::SendMessage(m_hwnd, WM_VSCROLL, LOWORD(wp), 0);
		return true;

	case EM_SCROLLCARET:
		ScrollCaret();
		return true;

	case EM_SETLIMITTEXT:
		SetLimitText(wp);
		return true;

	case EM_SETMARGINS:
		SetMargins(wp, LOWORD(lp), HIWORD(lp));
		return true;

	case EM_SETREADONLY:
		SetReadOnly(wp);
		return true;

	case EM_SETSEL:
		SetSel(wp, lp);
		return true;

	case FW_EM_SETSTYLE:
		SetStyle((StrUni *)lp, (COLORREF)wp);
		return true;

	case WM_GETTEXTLENGTH:
		lnRet = GetTextLength();
		return true;

	case FW_EM_GETTEXT:
		GetText((ITsString **)lp);
		return true;

	case FW_EM_SETTEXT:
		SetText((ITsString *)lp);
		return true;

	case WM_COPY:
		Copy();
		return true;

	case WM_CUT:
		Cut();
		return true;

	case WM_PASTE:
		Paste();
		return true;

	case WM_HSCROLL:
		if (!OnHScroll(LOWORD(wp), HIWORD(wp), (HWND)lp))
		{
			::SendMessage(::GetParent(m_hwnd), WM_COMMAND,
				MAKEWPARAM(::GetDlgCtrlID(m_hwnd), EN_HSCROLL), (LPARAM)m_hwnd);
		}
		return true;

	case WM_VSCROLL:
		if (!OnVScroll(LOWORD(wp), HIWORD(wp), (HWND)lp))
		{
			::SendMessage(::GetParent(m_hwnd), WM_COMMAND,
				MAKEWPARAM(::GetDlgCtrlID(m_hwnd), EN_VSCROLL), (LPARAM)m_hwnd);
		}
		return true;

	case WM_KILLFOCUS:
		if (!OnKillFocus((HWND)wp))
		{
			::SendMessage(::GetParent(m_hwnd), WM_COMMAND,
				MAKEWPARAM(::GetDlgCtrlID(m_hwnd), EN_KILLFOCUS), (LPARAM)m_hwnd);
		}
		return true;

	case WM_SETFOCUS:
		if (!OnSetFocus((HWND)wp))
		{
			::SendMessage(::GetParent(m_hwnd), WM_COMMAND,
				MAKEWPARAM(::GetDlgCtrlID(m_hwnd), EN_SETFOCUS), (LPARAM)m_hwnd);
		}
		return true;
		// Calling SuperClass here causes two OnSetFocus calls for each OnKillFocus.
		//return SuperClass::FWndProc(wm, wp, lp, lnRet);

	case WM_CHAR:
		fRet = false;
		if (wp == VK_TAB)  // '\t'
		{
			fRet = OnCharTab();
		}
		else if (wp == VK_RETURN) // '\r'
		{
			fRet = OnCharEnter();
		}
		else if (wp == VK_ESCAPE) // '\33'
		{
			fRet = OnCharEscape();
		}
		if (fRet)
			return fRet;
		else
			return SuperClass::FWndProc(wm, wp, lp, lnRet);

	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_MBUTTONDOWN:
	case WM_MBUTTONUP:
	case WM_RBUTTONDOWN:
	case WM_RBUTTONUP:
	case WM_MOUSEMOVE:
		if (HasToolTip())
		{
			// Notify the tooltip belonging to the parent toolbar of the mouse message.
			Assert(m_hwndToolTip);
			MSG msg;
			msg.hwnd = m_hwnd; // ::GetParent(m_hwnd);
			msg.message = wm;
			msg.wParam = wp;
			msg.lParam = lp;
			::SendMessage(m_hwndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
		}
		break;

	default:
		break;
	}
	return SuperClass::FWndProc(wm, wp, lp, lnRet);
}
void CTabPersistPosEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	//Retrieve the TAB-key and insert tabs
	if (nChar == VK_TAB)
	{
		//NOTE: We totally ignore the nRepCnt,
		// because it is too difficult to implement
		// in the case of removing tabs.
		// However, for inserting it would be easy.
		// But lets stay consistent.

		//Undo the automatic loosing of the focus.
		SetFocus();

		//Insert or deleted trailing tabs?
		// - Get key state of Shift key (MSB == 0/1)
		bool bInsertTabs = (GetKeyState(VK_SHIFT) >= 0);

		//Get Selection
		int SelStart = 0;
		int SelEnd = 0;
		GetSel(SelStart, SelEnd);
		ASSERT(SelStart <= SelEnd);

		//Lines that contribute to the selection - at least partly
		int LineSelStart = LineFromChar(SelStart);
		int LineSelEnd = LineFromChar(SelEnd);
		ASSERT(LineSelStart <= LineSelEnd);
		int nLines = LineSelEnd - LineSelStart + 1;

		//If we have just some selected chars in one line,
		// then we replace the current selection.
		//		//But not, if this line is fully selected.
		//		bool bOneLineFullySelected = (LineIndex(LineSelStart) == SelStart)
		//																	&& (LineIndex(LineSelStart) + LineLength(SelStart) == SelEnd)
		//																	&& (SelStart != SelEnd);
		if (nLines == 1)// && !bOneLineFullySelected)
		{
			if (bInsertTabs) ReplaceSel(_T("\t"), true);
			return;
		}

		//Is the end of the selection at the start of a new line?
		//In this case, we do not treat the last line as being selected.
		if (LineIndex(LineSelEnd) == SelEnd)
		{
			--nLines;
			--LineSelEnd;
		}

		//If we have more selected lines, /*or one fully selected line*/
		// then we intend all those lines and grow the selection.
		//So lets retrieve the text and add some tabs.
		CString Text;
		GetWindowText(Text);

		// - Insert/delete the tabs at the beginning of each line.
		int nTabsRemoved = 0;
		for (int i = 0; i < nLines; i++)
		{
			//Insert or delete?
			if (bInsertTabs)
			{
				Text.Insert(LineIndex(LineSelStart + i) + i, _T('\t'));
			}
			else
			{
				//Do we have tabs at the beginning?
				if (Text[LineIndex(LineSelStart + i) - nTabsRemoved] == _T('\t'))
				{
					Text.Delete(LineIndex(LineSelStart + i) - nTabsRemoved);
					nTabsRemoved++;
				}

			}
		}

		// - Set the new text and make a good selection
		SetWindowText(Text);
		SetSel(LineIndex(LineSelStart),
		       LineIndex(LineSelEnd) + LineLength(LineIndex(LineSelEnd)) + 2);

		return;
	}

	CPersistPosEdit::OnChar(nChar, nRepCnt, nFlags);
}