NumEdit.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 (nChar == VK_BACK && strEdit.GetLength()) //退格键;
  30. {
  31. // 是否删除了小数点或负号;
  32. if ( caret.x && strEdit[caret.x-1] == _T('.') )
  33. m_bPoint = FALSE;
  34. if ( caret.x && strEdit[caret.x-1] == _T('-') )
  35. m_bNegative = FALSE;
  36. CEdit::OnChar(nChar, nRepCnt, nFlags);
  37. }
  38. if (isdigit(nChar))
  39. {
  40. // 判断是否已有负号,若字符在负号前,退出;
  41. if ( m_bNegative && caret.x == 0 )
  42. return;
  43. if ( m_bNegative )
  44. {
  45. if ( m_bZero && caret.x == 2 && nChar == _T('0'))
  46. return;
  47. }
  48. else
  49. {
  50. if ( !m_bPoint && m_bZero && caret.x == 1 && nChar == _T('0'))
  51. return;
  52. }
  53. if ( m_bNegative )
  54. {
  55. if (caret.x == 1 && nChar == _T('0'))
  56. {
  57. m_bZero = TRUE;
  58. }
  59. }
  60. else
  61. {// 负号后面最多只有一个0,且0后面紧接着的是'.'
  62. if (caret.x == 0 && nChar == _T('0'))
  63. {
  64. m_bZero = TRUE;
  65. }
  66. }
  67. CEdit::OnChar(nChar, nRepCnt, nFlags);
  68. }
  69. else if (nChar == '-' && !m_bNegative)
  70. {// 负号只能在第一位;
  71. if (0 != caret.x)
  72. return;
  73. m_bNegative = TRUE;
  74. CEdit::OnChar(nChar, nRepCnt, nFlags);
  75. }
  76. else if (nChar == '.' && !m_bPoint)
  77. {
  78. if ( m_bNegative && caret.x == 1)
  79. {// 小数点不能在负号后面,即第二个字符索引;
  80. return;
  81. }
  82. m_bPoint = TRUE;
  83. CEdit::OnChar(nChar, nRepCnt, nFlags);
  84. }
  85. }
  86. BOOL CNumEdit::PreTranslateMessage(MSG* pMsg)
  87. {
  88. // TODO: 在此添加专用代码和/或调用基类
  89. if ( pMsg->message == WM_LBUTTONUP )
  90. {
  91. CString strEdit;
  92. GetWindowText(strEdit);
  93. int nStart, nEnd;
  94. GetSel(nStart, nEnd);
  95. if ( nEnd > nStart) // 不区选字符;
  96. {
  97. printf("有区选光标\n");
  98. SetSel(-1,strEdit.GetLength());
  99. }
  100. }
  101. else if ( pMsg->message == WM_KEYDOWN )
  102. {
  103. if ( pMsg->wParam == VK_DELETE )
  104. {
  105. POINT caret;
  106. ::GetCaretPos(&caret);
  107. // 根据插入符位置获取最近的字符索引(插入符的前一个字符位置);
  108. LONG nPos = LOWORD(CharFromPos(caret));
  109. printf("NumEdit,%d,%d\t 插入符最近的字符位置:%d\n", caret.x, caret.y, nPos);
  110. CString strEdit;
  111. GetWindowText(strEdit);
  112. if (strEdit.GetLength())
  113. {
  114. // 是否删除了小数点或负号;
  115. if ( strEdit.GetAt(nPos) == _T('.') )
  116. m_bPoint = FALSE;
  117. if ( strEdit.GetAt(nPos) == _T('-') )
  118. m_bNegative = FALSE;
  119. }
  120. }
  121. }
  122. return CEdit::PreTranslateMessage(pMsg);
  123. }