NumEdit.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // NumEdit.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "NumEdit.h"
  5. // CNumEdit
  6. IMPLEMENT_DYNAMIC(CNumEdit, CEdit)
  7. CNumEdit::CNumEdit()
  8. {
  9. m_bNegative = FALSE;
  10. m_bPoint = FALSE;
  11. m_bZero = FALSE;
  12. }
  13. CNumEdit::~CNumEdit()
  14. {
  15. }
  16. BEGIN_MESSAGE_MAP(CNumEdit, CEdit)
  17. ON_WM_CHAR()
  18. END_MESSAGE_MAP()
  19. // CNumEdit 消息处理程序
  20. void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  21. {
  22. // 获取插入符在客户区的坐标值;
  23. POINT caret;
  24. ::GetCaretPos(&caret);
  25. // 根据插入符位置获取最近的字符索引(插入符的前一个字符位置);
  26. caret.x = LOWORD(CharFromPos(caret));
  27. CString strEdit;
  28. GetWindowText(strEdit);
  29. if ( strEdit.IsEmpty() )
  30. {// 如果文本框空,一键还原;
  31. m_bPoint = FALSE;
  32. m_bZero = FALSE;
  33. m_bNegative = FALSE;
  34. }
  35. if ( strEdit.Find(_T(".")) == -1 )
  36. m_bPoint = FALSE;
  37. if ( strEdit.Find(_T("-")) == -1 )
  38. m_bNegative = FALSE;
  39. // 退格键处理;
  40. if (nChar == VK_BACK && strEdit.GetLength()) //退格键;
  41. {
  42. // 是否删除了小数点;
  43. if ( caret.x && strEdit[caret.x-1] == _T('.') )
  44. m_bPoint = FALSE;
  45. // 是否删除了负号;
  46. if ( caret.x && strEdit[caret.x-1] == _T('-') )
  47. m_bNegative = FALSE;
  48. if ( m_bNegative )
  49. {
  50. if ( m_bPoint )
  51. {
  52. if ( m_bZero && caret.x == 2 )
  53. {
  54. m_bZero = FALSE;
  55. }
  56. }
  57. else
  58. {
  59. if ( m_bZero && caret.x == 2 && ( strEdit.GetLength() < 2 || strEdit[2] != _T('0')) )
  60. {
  61. m_bZero = FALSE;
  62. }
  63. }
  64. }
  65. else
  66. {
  67. if ( m_bPoint )
  68. {
  69. if ( m_bZero && caret.x == 1 )
  70. {
  71. m_bZero = FALSE;
  72. }
  73. }
  74. else
  75. {
  76. if ( m_bZero && caret.x == 1 && ( strEdit.GetLength() < 1 || strEdit[1] != _T('0')) )
  77. {
  78. m_bZero = FALSE;
  79. }
  80. }
  81. }
  82. CEdit::OnChar(nChar, nRepCnt, nFlags);
  83. }
  84. // 数字键处理;
  85. if (isdigit(nChar))
  86. {
  87. // 判断是否已有负号,若字符在负号前,退出;
  88. if ( m_bNegative && caret.x == 0 )
  89. return;
  90. if ( m_bNegative )
  91. {
  92. // 负号前不能有任何字符,或者再输入负号;
  93. if ( caret.x == 0 || nChar == _T('-'))
  94. return;
  95. if ( m_bZero )
  96. {
  97. // 前置零前后都不能再有零;
  98. if ( (caret.x == 1 || caret.x == 2 ) && nChar == _T('0') )
  99. return;
  100. }
  101. else
  102. {
  103. // 负号的前置0只能在负号后面;
  104. if (caret.x == 1 && nChar == _T('0'))
  105. {
  106. m_bZero = TRUE;
  107. }
  108. }
  109. }
  110. else
  111. {
  112. if ( m_bZero )
  113. {
  114. // 已有前置0,不能再设置前置0;
  115. if ( (caret.x == 0 || caret.x == 1) && nChar == _T('0'))
  116. return;
  117. }
  118. else
  119. {
  120. if (caret.x == 0 && nChar == _T('0'))
  121. {
  122. m_bZero = TRUE;
  123. }
  124. }
  125. }
  126. CEdit::OnChar(nChar, nRepCnt, nFlags);
  127. }
  128. else if (nChar == '-' && !m_bNegative)
  129. {// 负号只能在第一位;
  130. if (0 != caret.x)
  131. return;
  132. m_bNegative = TRUE;
  133. CEdit::OnChar(nChar, nRepCnt, nFlags);
  134. }
  135. else if (nChar == '.' && !m_bPoint)
  136. {//小数点可以在第一位,但不能在负号后面;
  137. if ( m_bNegative && caret.x == 1)
  138. {// 小数点不能在负号后面,即第二个字符索引;
  139. return;
  140. }
  141. m_bPoint = TRUE;
  142. CEdit::OnChar(nChar, nRepCnt, nFlags);
  143. }
  144. }
  145. BOOL CNumEdit::PreTranslateMessage(MSG* pMsg)
  146. {
  147. // TODO: 在此添加专用代码和/或调用基类
  148. if ( pMsg->message == WM_KEYDOWN )
  149. {
  150. if ( pMsg->wParam == VK_DELETE )
  151. {
  152. POINT caret;
  153. ::GetCaretPos(&caret);
  154. // 根据插入符位置获取最近的字符索引(插入符的前一个字符位置);
  155. LONG nPos = LOWORD(CharFromPos(caret));
  156. printf("NumEdit,%d,%d\t 插入符最近的字符位置:%d\n", caret.x, caret.y, nPos);
  157. CString strEdit;
  158. GetWindowText(strEdit);
  159. if (strEdit.GetLength())
  160. {
  161. // 是否删除了小数点或负号;
  162. if ( strEdit.GetAt(nPos) == _T('.') )
  163. m_bPoint = FALSE;
  164. if ( strEdit.GetAt(nPos) == _T('-') )
  165. m_bNegative = FALSE;
  166. if ( m_bNegative )
  167. {
  168. if ( m_bPoint )
  169. {
  170. if ( m_bZero && caret.x == 2 )
  171. {
  172. m_bZero = FALSE;
  173. }
  174. }
  175. else
  176. {
  177. if ( m_bZero && caret.x == 2 && ( strEdit.GetLength() < 2 || strEdit[2] != _T('0')) )
  178. {
  179. m_bZero = FALSE;
  180. }
  181. }
  182. }
  183. else
  184. {
  185. if ( m_bPoint )
  186. {
  187. if ( m_bZero && caret.x == 1 )
  188. {
  189. m_bZero = FALSE;
  190. }
  191. }
  192. else
  193. {
  194. if ( m_bZero && caret.x == 1 && ( strEdit.GetLength() < 1 || strEdit[1] != _T('0')) )
  195. {
  196. m_bZero = FALSE;
  197. }
  198. }
  199. }
  200. }
  201. }
  202. }
  203. return CEdit::PreTranslateMessage(pMsg);
  204. }