#include "stdafx.h"
#include "NumberEdit.h"
CNumberEdit::CNumberEdit()
{
m_iAfterDotLen = 2;
m_str = _T("0");
}
CNumberEdit::~CNumberEdit()
{
}
BEGIN_MESSAGE_MAP(CNumberEdit, CEdit)
//{{AFX_MSG_MAP(CNumberEdit)
ON_WM_CHAR()
ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CNumberEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// 修改消息响应
if(nChar == 8)
{
//退格
CEdit::OnChar(nChar, nRepCnt, nFlags);
return;
}
BOOL bChange = FALSE;
GetWindowText(m_str);
if(CheckNumber(nChar,nRepCnt,nFlags))
{
//检查输入为数字
bChange = TRUE;
}
else if(CheckOneMinus(nChar,nRepCnt,nFlags))
{
//检查只有一个负号,且只能是第一个字符
bChange = TRUE;
}
else if(CheckOneDot(nChar,nRepCnt,nFlags))
{
//检查只有一个小数点
bChange = TRUE;
}
if(bChange)
{
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
void CNumberEdit::OnKillfocus()
{
// 修改消息响应
//失去焦点时,小数按设置的小数点后数据长度补齐
GetWindowText(m_str);
if(m_str.IsEmpty())
{
//未输入数据则设为0
m_str = "0";
}
else if(m_str.GetLength() == 1 && m_str[0] == TCHAR('-'))
{
//只输入了一个负号
m_str = "0";
}
else
{
int iDotPos = m_str.Find(TCHAR('.'));
if(iDotPos <0)
{
//没有找到小数点
SetWindowText(m_str);
return;
}
if(iDotPos >0)
{
//小数点后已有位数
int iLen = m_str.GetLength() - 1 - iDotPos;
if(iLen >= m_iAfterDotLen)
{
//已有位数超过设定
return;
}
if (iLen == 0)
{
//小数点后没有数据则用0补齐
m_str+="0";
}
}
}
SetWindowText(m_str);
}
BOOL CNumberEdit::CheckNumber(UINT nChar,UINT nRepCnt,UINT nFlags)
{
if(::isdigit(nChar)==0)
{
//是否数字
return FALSE;
}
//小数点位置
int iDotPos = m_str.Find(TCHAR('.'));
if(iDotPos >= 0)
{
//小数据点后数据长度
int iLen = m_str.GetLength() - 1 - iDotPos;
if( (GetCaretXPos() >= iDotPos) && (iLen >= m_iAfterDotLen))
{
//超过设置的长度
return FALSE;
}
}
return TRUE;
}
BOOL CNumberEdit::CheckOneMinus(UINT nChar,UINT nRepCnt,UINT nFlags)
{
if(nChar != '-')
{
//不是'-'
return FALSE;
}
if(GetCaretXPos() != 0)
{
//不在第一个位置
return FALSE;
}
if(!m_str.IsEmpty() && m_str.GetAt(0) == TCHAR('-'))
{
return FALSE;
}
return TRUE;
}
BOOL CNumberEdit::CheckOneDot(UINT nChar,UINT nRepCnt,UINT nFlags)
{
if (m_iAfterDotLen == 0)
{
//小数点后不加数据(限制为整数)
return FALSE;
}
if(nChar != '.')
{
//不是小数点
return FALSE;
}
if(m_str.Find(TCHAR('.')) >=0)
{
//已有小数点
return FALSE;
}
int iPos = GetCaretXPos();
if(iPos == 0)
{
//第一个字符就是小数点!
return FALSE;
}
else if(iPos==1 && m_str[0] == TCHAR('-'))
{
//第一个字符是'-',第二个是小数点
return FALSE;
}
return TRUE;
}
int CNumberEdit::GetCaretXPos()
{
CPoint p = GetCaretPos();
return (p.x - p.y)/6;
}
double CNumberEdit::GetDouble()
{
GetWindowText(m_str);
return atof(m_str);
}
long CNumberEdit::GetLong()
{
GetWindowText(m_str);
return atol(m_str);
}
void CNumberEdit::SetWindowText( CString str )
{
m_str = str;
char nChar;
UINT nRepCnt = 0;
UINT nFlags = 0;
BOOL bChange = FALSE;
for (int nstr = 0;nstr < str.GetLength() - 1;++nstr)
{
//取得字符
nChar = str.GetAt(nstr);
if(!CheckNumber(nChar,nRepCnt,nFlags) && (!CheckOneMinus
(nChar,nRepCnt,nFlags))
&& (!CheckOneDot(nChar,nRepCnt,nFlags)))
{
//检查初始化文本数据
bChange = TRUE;
}
}
if(!bChange)
{
int iDotPos = m_str.Find(TCHAR('.'));
if(iDotPos >0)
{
//小数点后已有位数
int iLen = m_str.GetLength() - 1 - iDotPos;
if (iLen == 0)
{
//小数点后没有数据则用0补齐
m_str+="0";
}
}
CEdit::SetWindowText(m_str);
}
}
VC++ 中的 VC-文本框只能输入数字和小数 源文件

评论 (0) 