ListEdit.h
上传用户:sztopon
上传日期:2014-01-21
资源大小:55k
文件大小:6k
源码类别:

ListView/ListBox

开发平台:

Visual C++

  1. #pragma once
  2. #include "ListTypes.h"
  3. class CListEdit : public CWindowImpl< CListEdit, CEdit >
  4. {
  5. public:
  6. CListEdit()
  7. {
  8. m_nItem = NULL_ITEM;
  9. m_nSubItem = NULL_SUBITEM;
  10. m_nFlags = ITEM_FLAGS_NONE;
  11. m_nExitChar = 0;
  12. }
  13. ~CListEdit()
  14. {
  15. }
  16. protected:
  17. int m_nItem;
  18. int m_nSubItem;
  19. UINT m_nFlags;
  20. TCHAR m_nExitChar;
  21. CFont m_fntEditFont;
  22. public:
  23. BOOL Create( HWND hWndParent, int nItem, int nSubItem, CRect& rcRect, UINT nFlags, LPCTSTR lpszItemText )
  24. {
  25. m_nItem = nItem;
  26. m_nSubItem = nSubItem;
  27. m_nFlags = nFlags;
  28. m_nExitChar = 0;
  29. // destroy old edit control...
  30. if ( IsWindow() )
  31. DestroyWindow();
  32. DWORD dwStyle = WS_CHILD | ES_AUTOHSCROLL;
  33. // right-justify numbers
  34. if ( nFlags & ( ITEM_FLAGS_EDIT_NUMBER | ITEM_FLAGS_EDIT_FLOAT ) )
  35. dwStyle |= ES_RIGHT;
  36. if ( nFlags & ITEM_FLAGS_EDIT_UPPER )
  37. dwStyle |= ES_UPPERCASE;
  38. // create edit control
  39. if ( CWindowImpl< CListEdit, CEdit >::Create( hWndParent, CRect( rcRect.left + 2, rcRect.top + 3, rcRect.right - 3, rcRect.bottom - 2 ), NULL, dwStyle ) == NULL )
  40. return FALSE;
  41. // get system message font
  42. CLogFont logFont;
  43. logFont.SetMessageBoxFont();
  44. if ( !m_fntEditFont.IsNull() )
  45. m_fntEditFont.DeleteObject();
  46. if ( m_fntEditFont.CreateFontIndirect( &logFont ) == NULL )
  47. return FALSE;
  48. SetFont( m_fntEditFont );
  49. SetMargins( ITEM_EDIT_MARGIN, ITEM_EDIT_MARGIN );
  50. SetWindowText( lpszItemText );
  51. // show edit control
  52. ShowWindow( SW_SHOW );
  53. SetSelAll();
  54. SetFocus();
  55. return TRUE;
  56. }
  57. BOOL IsValid( TCHAR nChar )
  58. {
  59. // validate number and float input
  60. if ( !( m_nFlags & ( ITEM_FLAGS_EDIT_NUMBER | ITEM_FLAGS_EDIT_FLOAT ) ) || nChar == VK_BACK )
  61. return TRUE;
  62. CString strValue;
  63. int nValueLength = GetWindowTextLength() + 1;
  64. GetWindowText( strValue.GetBuffer( nValueLength ), nValueLength );
  65. strValue.ReleaseBuffer();
  66. // get selected positions
  67. int nStartChar;
  68. int nEndChar;
  69. GetSel( nStartChar, nEndChar );
  70. // are we changing the sign?
  71. if ( ( m_nFlags & ITEM_FLAGS_EDIT_NEGATIVE ) && nChar == _T( '-' ) )
  72. {
  73. BOOL bNegative = FALSE;
  74. if ( m_nFlags & ITEM_FLAGS_EDIT_FLOAT )
  75. {
  76. double dblValue = _tstof( strValue );
  77. bNegative = ( dblValue < 0 );
  78. strValue.Format( _T( "%lf" ), -dblValue );
  79. }
  80. else
  81. {
  82. long lValue = _ttol( strValue );
  83. bNegative = ( lValue < 0 );
  84. strValue.Format( _T( "%ld" ), -lValue );
  85. }
  86. SetWindowText( strValue );
  87. // restore select position
  88. SetSel( bNegative ? nStartChar - 1 : nStartChar + 1, bNegative ? nEndChar - 1 : nEndChar + 1 );
  89. return FALSE;
  90. }
  91. // construct new value string using entered character
  92. CString strNewValue = strValue.Left( nStartChar ) + nChar + strValue.Right( strValue.GetLength() - nEndChar );
  93. int nGreaterThan = 0;
  94. int nLessThan = 0;
  95. int nEquals = 0;
  96. int nDecimalPoint = 0;
  97. int nNegativeIndex = -1;
  98. int nGreaterIndex = -1;
  99. int nLessIndex = -1;
  100. int nEqualIndex = -1;
  101. int nDecimalIndex = -1;
  102. int nDigitIndex = -1;
  103. for ( int nCharIndex = 0; nCharIndex < strNewValue.GetLength(); nCharIndex++ )
  104. {
  105. TCHAR nCharValue = strNewValue[ nCharIndex ];
  106. switch ( nCharValue )
  107. {
  108. case _T( '-' ): nNegativeIndex = nCharIndex;
  109. break;
  110. case _T( '>' ): if ( !( m_nFlags & ITEM_FLAGS_EDIT_OPERATOR ) )
  111. return FALSE;
  112. nGreaterIndex = nCharIndex;
  113. nGreaterThan++;
  114. break;
  115. case _T( '<' ): if ( !( m_nFlags & ITEM_FLAGS_EDIT_OPERATOR ) )
  116. return FALSE;
  117. nLessIndex = nCharIndex;
  118. nLessThan++;
  119. break;
  120. case _T( '=' ): if ( !( m_nFlags & ITEM_FLAGS_EDIT_OPERATOR ) )
  121. return FALSE;
  122. nEqualIndex = nCharIndex;
  123. nEquals++;
  124. break;
  125. case _T( '.' ): if ( !( m_nFlags & ITEM_FLAGS_EDIT_FLOAT ) )
  126. return FALSE;
  127. nDecimalIndex = nCharIndex;
  128. nDecimalPoint++;
  129. break;
  130. default: if ( !_istdigit( nCharValue ) )
  131. return FALSE;
  132. if ( nDigitIndex < 0 )
  133. nDigitIndex = nCharIndex;
  134. break;
  135. }
  136. // invalid if text contains more than one '>', '<', '=' or '.'
  137. if ( nGreaterThan > 1 || nLessThan > 1 || nEquals > 1 || nDecimalPoint > 1 )
  138. return FALSE;
  139. }
  140. // invalid if text contains '=>' or '=<'
  141. if ( nGreaterIndex != -1 && nEqualIndex != -1 && nGreaterIndex > nEqualIndex )
  142. return FALSE;
  143. if ( nLessIndex != -1 && nEqualIndex != -1 && nLessIndex > nEqualIndex )
  144. return FALSE;
  145. // invalid if digits exist before operator
  146. if ( nDigitIndex != -1 && nGreaterIndex != -1 && nGreaterIndex > nDigitIndex )
  147. return FALSE;
  148. if ( nDigitIndex != -1 && nLessIndex != -1 && nLessIndex > nDigitIndex )
  149. return FALSE;
  150. if ( nDigitIndex != -1 && nEqualIndex != -1 && nEqualIndex > nDigitIndex )
  151. return FALSE;
  152. if ( nDigitIndex != -1 && nNegativeIndex != -1 && nNegativeIndex > nDigitIndex )
  153. return FALSE;
  154. return TRUE;
  155. }
  156. BEGIN_MSG_MAP_EX(CListEdit)
  157. MSG_WM_KILLFOCUS(OnKillFocus)
  158. MSG_WM_GETDLGCODE(OnGetDlgCode)
  159. MSG_WM_CHAR(OnChar)
  160. END_MSG_MAP_EX()
  161. void OnKillFocus( HWND hNewWnd )
  162. {
  163. CWindow wndParent( GetParent() );
  164. if ( wndParent.IsWindow() )
  165. {
  166. CString strValue;
  167. int nValueLength = GetWindowTextLength() + 1;
  168. GetWindowText( strValue.GetBuffer( nValueLength ), nValueLength );
  169. strValue.ReleaseBuffer();
  170. CListNotify listNotify;
  171. listNotify.m_hdrNotify.hwndFrom = m_hWnd;
  172. listNotify.m_hdrNotify.idFrom = GetDlgCtrlID();
  173. listNotify.m_hdrNotify.code = LCN_ENDEDIT;
  174. listNotify.m_nItem = m_nItem;
  175. listNotify.m_nSubItem = m_nSubItem;
  176. listNotify.m_nExitChar = m_nExitChar;
  177. listNotify.m_lpszItemText = strValue;
  178. listNotify.m_lpItemDate = NULL;
  179. // forward notification to parent
  180. FORWARD_WM_NOTIFY( wndParent, listNotify.m_hdrNotify.idFrom, &listNotify.m_hdrNotify, ::SendMessage );
  181. }
  182. ShowWindow( SW_HIDE );
  183. }
  184. UINT OnGetDlgCode( LPMSG lpMessage )
  185. {
  186. return DLGC_WANTALLKEYS;
  187. }
  188. void OnChar( TCHAR nChar, UINT nRepCnt, UINT nFlags )
  189. {
  190. switch ( nChar )
  191. {
  192. case VK_TAB:
  193. case VK_RETURN:
  194. case VK_ESCAPE: {
  195. m_nExitChar = nChar;
  196. CWindow wndParent( GetParent() );
  197. if ( wndParent.IsWindow() )
  198. wndParent.SetFocus();
  199. }
  200. break;
  201. default: SetMsgHandled( !IsValid( nChar ) );
  202. break;
  203. }
  204. }
  205. };