VC限制只能输入常规数字的CEdit控件

MFC提供的CEdit控件,可以设置其属性为NUM,也就是限定只能输入数字,但是,有个问题就是小数点没法输入了。

在订单系统编写的时候,我想限制价钱和重量的输入只能是数字,整数或者浮点数。因为都是正数,所以我就没有考虑负号的因素,有兴趣的可以加上这一功能。

所以,只能自己编写一个数字的CEdit控件,过程:

1.从标准CEdit控件派生出CNumEdit控件

2.重载CEdit的OnChar函数,实现输入字符的限制,只能是小数点和数字,不过还得考虑响应退格键。其次,还得考虑小数点的输入次数,只能为一个

void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
 // TODO: Add your message handler code here and/or call default
 CString ss;
 char ch = char(nChar);
 GetWindowText(ss);  // 获得当前已输入的字符序列

// 对当前输入字符进行判断
 if(!isdigit(ch)) // 如果不是数字
 {
  if(ch == '.') // 是小数点
  {
   if(ss.Find('.') != -1) // 检查是否已经输入了小数点
    return;
  }
  else // 不是小数点
  {
   if(ch == '\b') // 是退格键
   {
    ; 
   }
   else // 不是退格键,则退出
    return;
  }
 } 

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

3.在输入结束后,模仿CEdit的数字规范化的功能,也就是类似0011-->11、11.100 ->11.1  .1100->0.11

重载CEdit的OnKillFocus函数,在编辑框失去焦点的时候进行规范化

void CNumEdit::OnKillFocus(CWnd* pNewWnd)
{
 CEdit::OnKillFocus(pNewWnd);
 
 // TODO: Add your message handler code here
 
 GetWindowText(m_sValue);
 
 int i;
 char ch;
 int nLen = m_sValue.GetLength();

 if(nLen == 0)
  return;

 ch = m_sValue[0];

 
 for(i = 0; i < nLen; i++)
 {
  if(m_sValue[i] != '0') // 直到第一个不是0的字符
   break;
 }

 if(i < nLen) // 不是全 0 的情况
 {
  m_sValue = m_sValue.Mid(i); // 将第一个非 0 字符前面的 0 去掉

  nLen = m_sValue.GetLength();

  int nDotPos = m_sValue.Find('.');
  if(nDotPos != -1) // 含有小数点
  {
   for(i = nLen - 1; i >= 0; i--)
   {
    if(m_sValue[i] != '0')
     break;
   }

   m_sValue = m_sValue.Left(i + 1); // 去掉了小数后面的0
  }

  nLen = m_sValue.GetLength();
  
  if(nDotPos == nLen - 1) // 小数点在最后
  {
   m_sValue = m_sValue.Left(nLen - 1);
  }
  if(nDotPos == 0) // 小数点在最开始
   m_sValue = "0" + m_sValue;
 }
 else // 全 0
 {
  m_sValue = '0';
 }
 SetSel(0, -1);
 ReplaceSel(m_sValue);
}

原文地址:https://www.cnblogs.com/ganmk/p/1527186.html