#include "stdafx.h" #include "RealEdit.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNCREATE(CRealEdit, CEdit) CRealEdit::CRealEdit() { m_eType = CRealEdit::eString; m_bInEdit = FALSE; } CRealEdit::~CRealEdit() { } BEGIN_MESSAGE_MAP(CRealEdit, CEdit) //{{AFX_MSG_MAP(CRealEdit) ON_CONTROL_REFLECT_EX(EN_CHANGE, OnChange) ON_WM_CHAR() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CRealEdit::SetDataType(CRealEdit::EDataType eType) { m_eType = eType; } CRealEdit::EDataType CRealEdit::GetDataType() { return m_eType; } void CRealEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { if (m_eType == CRealEdit::eString || _istprint(nChar) == 0 || _istdigit(nChar) || nChar == _T('+') || nChar == _T('-') || nChar == _T('.') || nChar == _T('E') || nChar == _T('e')) { CEdit::OnChar(nChar, nRepCnt, nFlags); } } BOOL CRealEdit::OnChange() { if (m_bInEdit) return TRUE; if (m_eType == CRealEdit::eString) return FALSE; int iStart, iEnd; CEdit::GetSel(iStart, iEnd); CString sText; CEdit::GetWindowText(sText); int iLen = sText.GetLength(); if (iLen <= 0) return FALSE; if (iEnd < iStart) iEnd = iLen; switch (m_eType) { case CRealEdit::eInteger: case CRealEdit::ePosInt: case CRealEdit::eNegInt: CRealEdit::DoInteger(sText, iStart, iEnd); break; case CRealEdit::eReal: case CRealEdit::ePosReal: case CRealEdit::eNegReal: CRealEdit::DoReal(sText, iStart, iEnd); break; default: return FALSE; } m_bInEdit = TRUE; CEdit::SetWindowText(sText); CEdit::SetSel(iStart, iEnd); m_bInEdit = FALSE; return FALSE; } void CRealEdit::DoInteger(CString& sText, int& iStart, int& iEnd) { int iLen = sText.GetLength(); int i = 0; TCHAR chVal; while (i < iLen) { chVal = sText[i]; if (m_eType != CRealEdit::ePosInt && chVal == _T('-') || m_eType != CRealEdit::eNegInt && chVal == _T('+') || _istdigit(chVal) != 0) { i++; break; } else { sText.Delete(i); if (i < iStart) iStart--, iEnd--, iLen--; else if (i < iEnd) iEnd--, iLen--; else if (i < iLen) iLen--; } } if (m_eType == CRealEdit::eNegInt && (iLen <= 0 || sText[0] != _T('-'))) { sText.Insert(0, _T('-')); i++; iStart++; iEnd++; iLen++; } while (i < iLen) { chVal = sText[i]; if (_istdigit(chVal) != 0) { i++; } else { sText.Delete(i); if (i < iStart) iStart--, iEnd--, iLen--; else if (i < iEnd) iEnd--, iLen--; else if (i < iLen) iLen--; } } } void CRealEdit::DoReal(CString& sText, int& iStart, int& iEnd) { int iLen = sText.GetLength(); int i = 0; TCHAR chVal; BOOL bPoint = FALSE; while (i < iLen) { chVal = sText[i]; if (m_eType != CRealEdit::ePosReal && chVal == _T('-') || m_eType != CRealEdit::eNegReal && chVal == _T('+') || (bPoint = (chVal == _T('.'))) || _istdigit(chVal) != 0) { i++; break; } else { sText.Delete(i); if (i < iStart) iStart--, iEnd--, iLen--; else if (i < iEnd) iEnd--, iLen--; else if (i < iLen) iLen--; } } if (m_eType == CRealEdit::eNegReal && (iLen <= 0 || sText[0] != _T('-'))) { sText.Insert(0, _T('-')); i++; iStart++; iEnd++; iLen++; } BOOL bExp = FALSE; while (i < iLen) { chVal = sText[i]; if (_istdigit(chVal) != 0 || !bPoint && (bPoint = (chVal == _T('.'))) || !bExp && ((bExp = (chVal == _T('E'))) || (bExp = (chVal == _T('e'))))) { i++; if (bExp && i < iLen) { chVal = sText[i]; if (chVal == _T('-') || chVal == _T('+')) i++; } } else { sText.Delete(i); if (i < iStart) iStart--, iEnd--, iLen--; else if (i < iEnd) iEnd--, iLen--; else if (i < iLen) iLen--; } } }