ExtEdit.cpp
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:204k
源码类别:

界面编程

开发平台:

Visual C++

  1. , m_fnValidation( fnValidation )
  2. , m_fnConversion( fnConversion )
  3. , m_clrSymbol( COLORREF(-1L) )
  4. {
  5. }
  6. CExtEditWithBehavior::CBehaviorMasked::CharRule::CharRule( COLORREF clrSymbol, __EXT_MFC_SAFE_TCHAR cSymbol, ValidationFunction fnValidation, ConversionFunction fnConversion /*= NULL*/ )
  7. : m_cSymbol( cSymbol )
  8. , m_fnValidation( fnValidation )
  9. , m_fnConversion( fnConversion )
  10. , m_clrSymbol( clrSymbol )
  11. {
  12. }
  13. CExtEditWithBehavior::CBehaviorMasked::CharRule::~CharRule()
  14. {
  15. }
  16. bool CExtEditWithBehavior::CBehaviorMasked::CharRule::Validate( __EXT_MFC_SAFE_TCHAR _tchr ) const
  17. {
  18. if( m_fnValidation != NULL )
  19. return ( m_fnValidation( _tchr ) != 0 ) ? true : false;
  20. return true;
  21. }
  22. __EXT_MFC_SAFE_TCHAR CExtEditWithBehavior::CBehaviorMasked::CharRule::Convert( __EXT_MFC_SAFE_TCHAR _tchr ) const
  23. {
  24. if( m_fnConversion != NULL )
  25. return (TCHAR)m_fnConversion( _tchr );
  26. return _tchr;
  27. }
  28. void CExtEditWithBehavior::CBehaviorMasked::CharRule::Set(__EXT_MFC_SAFE_TCHAR cSymbol)
  29. {
  30. m_cSymbol = cSymbol;
  31. }
  32. __EXT_MFC_SAFE_TCHAR CExtEditWithBehavior::CBehaviorMasked::CharRule::Get() const
  33. {
  34. return m_cSymbol;
  35. }
  36. CExtEditWithBehavior::CBehaviorMasked::CharRule::operator __EXT_MFC_SAFE_TCHAR() const
  37. {
  38. return m_cSymbol;
  39. }
  40. //void CExtEditWithBehavior::OnChange() 
  41. //{
  42. //}
  43. //
  44. //void CExtEditWithBehavior::OnUpdate() 
  45. //{
  46. //}
  47. void CExtEditWithBehavior::CBehaviorMasked::CharRule::Serialize( CArchive & ar )
  48. {
  49. if( ar.IsStoring() )
  50. {
  51. ar << DWORD(TCHAR(__EXT_MFC_SAFE_TCHAR(m_cSymbol)));
  52. ar << DWORD(m_clrSymbol);
  53. }
  54. else
  55. {
  56. DWORD dwTmp;
  57. ar >> dwTmp;
  58. m_cSymbol = (__EXT_MFC_SAFE_TCHAR)(TCHAR)(dwTmp);
  59. ar >> dwTmp;
  60. m_clrSymbol = (COLORREF)dwTmp;
  61. }
  62. }
  63. void CExtEditWithBehavior::CBehaviorMasked::CharRuleArray::Serialize( CArchive & ar )
  64. {
  65. DWORD dwIndex, dwCount;
  66. if( ar.IsStoring() )
  67. {
  68. dwCount = DWORD( GetSize() );
  69. ar << dwCount;
  70. }
  71. else
  72. {
  73. RemoveAll();
  74. ar >> dwCount;
  75. SetSize( INT(dwCount) );
  76. }
  77. for( dwIndex = 0; dwIndex < dwCount; dwIndex ++ )
  78. {
  79. CharRule & _cr = ElementAt( INT(dwIndex) );
  80. _cr.Serialize( ar );
  81. }
  82. }
  83. /////////////////////////////////////////////////////////////////////////////
  84. // CExtEditMasked
  85. IMPLEMENT_DYNCREATE( CExtEditMasked, CExtEditWithBehavior );
  86. CExtEditMasked::CExtEditMasked(
  87. __EXT_MFC_SAFE_LPCTSTR strMask // = _T("")
  88. )
  89. : CBehaviorMasked( strMask )
  90. , m_clrDefault( COLORREF(-1L) )
  91. {
  92. m_pEditWithBehaviorWnd = this;
  93. }
  94. BEGIN_MESSAGE_MAP( CExtEditMasked, CExtEditWithBehavior )
  95. //{{AFX_MSG_MAP(CExtEditMasked)
  96. ON_WM_CHAR()
  97. ON_WM_KEYDOWN()
  98. ON_WM_KILLFOCUS()
  99. //}}AFX_MSG_MAP
  100. END_MESSAGE_MAP()
  101. void CExtEditMasked::_Rich_OnDraw()
  102. {
  103. ASSERT_VALID( this );
  104. if( ! m_bRichMode )
  105. return;
  106. if( GetSafeHwnd() == NULL )
  107. return;
  108. if( m_bRichPainting )
  109. return;
  110. m_bRichPainting = true;
  111. CExtSafeString strText = TextGet();
  112. CExtSafeString strMask = MaskGet();
  113. INT nTextLen = INT( strText.GetLength() );
  114. INT nMaskLen = INT( strMask.GetLength() );
  115. INT nWalkLen = min( nTextLen, nMaskLen );
  116. if( nWalkLen > 0 )
  117. {
  118. COLORREF clrDefault = m_clrDefault;
  119. if( clrDefault == COLORREF(-1L) )
  120. {
  121. if( IsWindowEnabled() && ( GetStyle() & ES_READONLY ) == 0 )
  122. clrDefault = ::GetSysColor( COLOR_WINDOWTEXT );
  123. else
  124. clrDefault = ::GetSysColor( COLOR_3DSHADOW );
  125. }
  126. CHARFORMAT cfDefault;
  127. ::memset( &cfDefault, 0, sizeof(CHARFORMAT) );
  128. cfDefault.dwMask = CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_PROTECTED|CFM_COLOR;
  129. cfDefault.dwEffects = CFE_PROTECTED; 
  130. CFont * pFont = GetFont();
  131. if( pFont->GetSafeHandle() == NULL )
  132. {
  133. CWnd * pWndParent = GetParent();
  134. if( pWndParent->GetSafeHwnd() != NULL )
  135. pFont = pWndParent->GetFont();
  136. if( pFont->GetSafeHandle() == NULL )
  137. pFont = &(PmBridge_GetPM()->m_FontNormal);
  138. }
  139. LOGFONT _lf; ::memset( &_lf, 0, sizeof(LOGFONT) );
  140. pFont->GetLogFont( &_lf );
  141. #if (! defined _RICHEDIT_VER )
  142. USES_CONVERSION;
  143. strcpy( cfDefault.szFaceName, T2CA(_lf.lfFaceName) );
  144. #else
  145. #if ( _RICHEDIT_VER < 0x0200 )
  146. USES_CONVERSION;
  147. strcpy( cfDefault.szFaceName, T2CA(_lf.lfFaceName) );
  148. #else
  149. __EXT_MFC_STRCPY( cfDefault.szFaceName, sizeof(cfDefault.szFaceName)/sizeof(cfDefault.szFaceName[0]), _lf.lfFaceName );
  150. #endif
  151. #endif
  152. CWindowDC dcDesktop( NULL );
  153. cfDefault.yHeight = ::MulDiv( _lf.lfHeight, 72 * 20, dcDesktop.GetDeviceCaps( LOGPIXELSY ) );
  154. cfDefault.yHeight = abs( cfDefault.yHeight );
  155. bool bEnabled = IsWindowEnabled() ? true : false, bReadOnly = ( ( GetStyle() & ES_READONLY ) != 0 ) ? true : false;
  156. cfDefault.crTextColor = bEnabled ? ( bReadOnly ? m_clrRichTextReadOnly : m_clrRichTextNormal ) : m_clrRichTextDisabled;
  157. if( cfDefault.crTextColor == COLORREF(-1L) )
  158. {
  159. if( bEnabled )
  160. {
  161. if( bReadOnly )
  162. cfDefault.crTextColor = ::GetSysColor( COLOR_3DSHADOW );
  163. else
  164. cfDefault.crTextColor = ::GetSysColor( COLOR_WINDOWTEXT );
  165. }
  166. else
  167. cfDefault.crTextColor = ::GetSysColor( COLOR_GRAYTEXT );
  168. }
  169. COLORREF clrBack = OnQueryBackColor();
  170. if( clrBack == COLORREF(-1L) )
  171. {
  172. clrBack = bEnabled ? ( bReadOnly ? m_clrRichBackReadOnly : m_clrRichBackNormal ) : m_clrRichBackDisabled;
  173. if( clrBack == COLORREF(-1L) )
  174. {
  175. if( bEnabled )
  176. {
  177. if( bReadOnly )
  178. clrBack = ::GetSysColor( COLOR_3DFACE );
  179. else
  180. clrBack = ::GetSysColor( COLOR_WINDOW );
  181. }
  182. else
  183. clrBack = ::GetSysColor( COLOR_3DFACE );
  184. }
  185. }
  186. Rich_SetBackgroundColor( FALSE, clrBack );
  187. Rich_HideSelection( true, false );
  188. CHARRANGE crRestore;
  189. Rich_GetSel( crRestore );
  190. Rich_SetSel( 0, -1 ); 
  191. SendMessage( EM_SETCHARFORMAT, SCF_DEFAULT, LPARAM(&cfDefault) );
  192. SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(&cfDefault) );
  193. Rich_SetSelectionColor( cfDefault.crTextColor );
  194. CharRuleArray & arrCharRules = GetSymbolArray();
  195. INT nWalkIndex;
  196. for( nWalkIndex = 0; nWalkIndex < nWalkLen; nWalkIndex ++ )
  197. {
  198. TCHAR tchrMask = strMask[ nWalkIndex ];
  199. INT nRuleNo = arrCharRules.FindPos( tchrMask );
  200. if( nRuleNo < 0 )
  201. continue;
  202. CharRule & theCharRule = arrCharRules.ElementAt( nRuleNo );
  203. if( theCharRule.m_clrSymbol == COLORREF(-1L) )
  204. continue;
  205. Rich_SetSel( nWalkIndex, ( nWalkIndex + 1 ) );
  206. Rich_SetSelectionColor( theCharRule.m_clrSymbol );
  207. }
  208. Rich_SetSel( crRestore );
  209. Rich_HideSelection( false, false );
  210. } // if( nWalkLen > 0 )
  211. m_bRichPainting = false;
  212. }
  213. CExtSafeString CExtEditMasked::TextGetValid() const
  214. {
  215. ASSERT_VALID( this );
  216. return Behavior_GetValidText();
  217. }
  218. #ifndef _UNICODE
  219. int CExtEditMasked::stat_IsCharDigit( UINT c ) { return _istdigit( (TCHAR)c ); } // similar to _istdigit()
  220. int CExtEditMasked::stat_IsCharAlpha( UINT c ) { return IsCharAlpha( (TCHAR)c ); } // similar to _istalpha()
  221. int CExtEditMasked::stat_IsCharAlphaOrDigit( UINT c ) { return IsCharAlphaNumeric( (TCHAR)c ); } // similar to _istalnum()
  222. #else
  223. int CExtEditMasked::stat_IsCharDigit( __EXT_MFC_SAFE_TCHAR c ) { return _istdigit( (TCHAR)c ); } // similar to _istdigit()
  224. int CExtEditMasked::stat_IsCharAlpha( __EXT_MFC_SAFE_TCHAR c ) { return IsCharAlpha( (TCHAR)c ); } // similar to _istalpha()
  225. int CExtEditMasked::stat_IsCharAlphaOrDigit( __EXT_MFC_SAFE_TCHAR c ) { return IsCharAlphaNumeric( (TCHAR)c ); } // similar to _istalnum()
  226. #endif
  227. void CExtEditMasked::OnChar( UINT uChar, UINT nRepCnt, UINT nFlags )
  228. {
  229. ASSERT_VALID( this );
  230. Behavior_OnChar( uChar, nRepCnt, nFlags );
  231. // _Rich_OnDraw();
  232. }
  233. void CExtEditMasked::OnKeyDown( UINT uChar, UINT nRepCnt, UINT nFlags )
  234. {
  235. ASSERT_VALID( this );
  236. Behavior_OnKeyDown( uChar, nRepCnt, nFlags );
  237. }
  238. void CExtEditMasked::OnKillFocus( CWnd * pNewWnd )
  239. {
  240. ASSERT_VALID( this );
  241. Behavior_OnKillFocus( pNewWnd );
  242. }
  243. /////////////////////////////////////////////////////////////////////////////
  244. // CExtEditSystemNumberCurrencyBase window
  245. IMPLEMENT_DYNAMIC( CExtEditSystemNumberCurrencyBase, CExtEditWithBehavior );
  246. CExtEditSystemNumberCurrencyBase::CExtEditSystemNumberCurrencyBase(
  247. INT nMaxWholeDigits, // = __EXT_MFC_DEFAULT_MAX_WHOLE_DIGITS
  248. INT nMaxFractionDigits // = __EXT_MFC_DEFAULT_FRACTION_WHOLE_DIGITS
  249. )
  250. : m_nMaxWholeDigits( nMaxWholeDigits >= 0 ? nMaxWholeDigits : (-nMaxWholeDigits) )
  251. , m_nMaxFractionDigits( nMaxFractionDigits )
  252. , m_nNegSignMatch( 0 )
  253. , m_strNegativeSign( _T("-") )
  254. , m_strDecimalPoint( _T('.') )
  255. , m_strGroupSeparator( _T(',') )
  256. , m_nNegativeFormatIndex( 0 )
  257. , m_nPositiveFormatIndex( 0 )
  258. , m_lfMin( __EXT_MFC_SYSTEM_NUMBER_MIN )
  259. , m_lfMax( __EXT_MFC_SYSTEM_NUMBER_MAX )
  260. , m_bAdjustingSeparators( false )
  261. , m_bBackspace( false )
  262. , m_nStartSel( -1 )
  263. , m_nEndSel( -1 )
  264. , m_clrNumber( COLORREF(-1L) )
  265. , m_clrFraction( COLORREF(-1L) )
  266. , m_clrGroupSeparator( COLORREF(-1L) )
  267. , m_clrDecimalSeparator( COLORREF(-1L) )
  268. , m_clrSign( COLORREF(-1L) )
  269. , m_clrBrackets( COLORREF(-1L) )
  270. , m_strCurrencySymbol( _T("$") )
  271. {
  272. ASSERT( m_nMaxWholeDigits > 0 ); // must have at least 1 digit to the left of the decimal
  273. ASSERT( m_nMaxFractionDigits >= 0 ); // decimal places must be positive
  274. m_pEditWithBehaviorWnd = this;
  275. if( nMaxWholeDigits < 0 )
  276. CBehaviorBase::m_nBehaviorFlags |= __ESE_DISABLE_NEGATIVE;
  277. }
  278. CExtEditSystemNumberCurrencyBase::~CExtEditSystemNumberCurrencyBase()
  279. {
  280. }
  281. BEGIN_MESSAGE_MAP( CExtEditSystemNumberCurrencyBase, CExtEditWithBehavior )
  282. //{{AFX_MSG_MAP(CExtEditWithBehavior)
  283. ON_WM_CHAR()
  284. ON_WM_KEYDOWN()
  285. ON_WM_KILLFOCUS()
  286. ON_MESSAGE( WM_PASTE, OnPaste )
  287. //}}AFX_MSG_MAP
  288. END_MESSAGE_MAP()
  289. void CExtEditSystemNumberCurrencyBase::CurrencySet( const CURRENCY & _cy )
  290. {
  291. ASSERT_VALID( this );
  292. long double lfVal = ((long double)_cy.int64) / ((long double)10000.0);
  293. LongDoubleSet( lfVal );
  294. }
  295. COleCurrency CExtEditSystemNumberCurrencyBase::CurrencyGet() const
  296. {
  297. ASSERT_VALID( this );
  298. long double lfVal = LongDoubleGet() * ((long double)10000.0);
  299. COleCurrency _oleCurrency;
  300. _oleCurrency.m_cur.int64 = (LONGLONG)lfVal;
  301. return _oleCurrency;
  302. }
  303. void CExtEditSystemNumberCurrencyBase::LongDoubleSet( long double lfValue, bool bTrimTrailingZeros /*= true*/ )
  304. {
  305. ASSERT_VALID( this );
  306. if( GetSafeHwnd() == NULL )
  307. return;
  308. m_pEditWithBehaviorWnd->SetWindowText( _GetDoubleText( lfValue, bTrimTrailingZeros ) );
  309. }
  310. void CExtEditSystemNumberCurrencyBase::MaxWholeDigitsSet( INT nMaxWholeDigits )
  311. {
  312. ASSERT_VALID( this );
  313. ASSERT( nMaxWholeDigits );
  314. bool bAllowNegative = (nMaxWholeDigits >= 0);
  315. if( nMaxWholeDigits < 0 )
  316. nMaxWholeDigits = -nMaxWholeDigits;
  317. if( m_nMaxWholeDigits == nMaxWholeDigits && AllowNegativeGet() == bAllowNegative )
  318. return;
  319. m_nMaxWholeDigits = nMaxWholeDigits;
  320. if( ! _FlagsModify( bAllowNegative ? 0 : __ESE_DISABLE_NEGATIVE, bAllowNegative ? __ESE_DISABLE_NEGATIVE : 0 ) )
  321. _Redraw();
  322. }
  323. INT CExtEditSystemNumberCurrencyBase::MaxWholeDigitsGet() const
  324. {
  325. ASSERT_VALID( this );
  326. return m_nMaxWholeDigits;
  327. }
  328. void CExtEditSystemNumberCurrencyBase::MaxFractionDigitsSet( INT nMaxFractionDigits )
  329. {
  330. ASSERT_VALID( this );
  331. ASSERT( nMaxFractionDigits >= 0 );
  332. if( m_nMaxFractionDigits == nMaxFractionDigits )
  333. return;
  334. m_nMaxFractionDigits = nMaxFractionDigits;
  335. _Redraw();
  336. }
  337. INT CExtEditSystemNumberCurrencyBase::MaxFractionDigitsGet() const
  338. {
  339. ASSERT_VALID( this );
  340. return m_nMaxFractionDigits;
  341. }
  342. void CExtEditSystemNumberCurrencyBase::AllowNegativeSet( bool bAllowNegative /*= true*/ )
  343. {
  344. ASSERT_VALID( this );
  345. _FlagsModify( bAllowNegative ? 0 : __ESE_DISABLE_NEGATIVE, bAllowNegative ? __ESE_DISABLE_NEGATIVE : 0 );
  346. }
  347. bool CExtEditSystemNumberCurrencyBase::AllowNegativeGet() const
  348. {
  349. ASSERT_VALID( this );
  350. bool bAllowNegative = ( ( CBehaviorBase::m_nBehaviorFlags & __ESE_DISABLE_NEGATIVE ) != 0 ) ? false : true;
  351. return bAllowNegative;
  352. }
  353. void CExtEditSystemNumberCurrencyBase::RangeSet( long double lfMin, long double lfMax )
  354. {
  355. ASSERT_VALID( this );
  356. ASSERT( lfMin <= lfMax );
  357. m_lfMin = lfMin;
  358. m_lfMax = lfMax;
  359. _AdjustWithinRange();
  360. _Redraw();
  361. }
  362. void CExtEditSystemNumberCurrencyBase::RangeGet( long double * p_lfMin, long double * p_lfMax ) const
  363. {
  364. ASSERT_VALID( this );
  365. if( p_lfMin != NULL )
  366. (*p_lfMin) = m_lfMin;
  367. if( p_lfMax != NULL )
  368. (*p_lfMax) = m_lfMax;
  369. }
  370. void CExtEditSystemNumberCurrencyBase::NumberColorSet( COLORREF clrNumber /* = COLORREF(-1L) */ )
  371. {
  372. ASSERT_VALID( this );
  373. if( m_clrNumber == clrNumber )
  374. return;
  375. m_clrNumber = clrNumber;
  376. _Rich_OnDraw();
  377. }
  378. COLORREF CExtEditSystemNumberCurrencyBase::NumberColorGet() const
  379. {
  380. ASSERT_VALID( this );
  381. return m_clrNumber;
  382. }
  383. void CExtEditSystemNumberCurrencyBase::FractionColorSet( COLORREF clrFraction /* = COLORREF(-1L) */ )
  384. {
  385. ASSERT_VALID( this );
  386. if( m_clrFraction == clrFraction )
  387. return;
  388. m_clrFraction = clrFraction;
  389. _Rich_OnDraw();
  390. }
  391. COLORREF CExtEditSystemNumberCurrencyBase::FractionColorGet() const
  392. {
  393. ASSERT_VALID( this );
  394. return m_clrFraction;
  395. }
  396. void CExtEditSystemNumberCurrencyBase::GroupSeparatorColorSet( COLORREF clrGroupSeparator /* = COLORREF(-1L) */ )
  397. {
  398. ASSERT_VALID( this );
  399. if( m_clrGroupSeparator == clrGroupSeparator )
  400. return;
  401. m_clrGroupSeparator = clrGroupSeparator;
  402. _Rich_OnDraw();
  403. }
  404. COLORREF CExtEditSystemNumberCurrencyBase::GroupSeparatorColorGet() const
  405. {
  406. ASSERT_VALID( this );
  407. return m_clrGroupSeparator;
  408. }
  409. void CExtEditSystemNumberCurrencyBase::DecimalSeparatorColorSet( COLORREF clrDecimalSeparator /* = COLORREF(-1L) */ )
  410. {
  411. ASSERT_VALID( this );
  412. if( m_clrDecimalSeparator == clrDecimalSeparator )
  413. return;
  414. m_clrDecimalSeparator = clrDecimalSeparator;
  415. _Rich_OnDraw();
  416. }
  417. COLORREF CExtEditSystemNumberCurrencyBase::DecimalSeparatorColorGet() const
  418. {
  419. ASSERT_VALID( this );
  420. return m_clrDecimalSeparator;
  421. }
  422. void CExtEditSystemNumberCurrencyBase::SignColorSet( COLORREF clrSign /* = COLORREF(-1L) */ )
  423. {
  424. ASSERT_VALID( this );
  425. if( m_clrSign == clrSign )
  426. return;
  427. m_clrSign = clrSign;
  428. _Rich_OnDraw();
  429. }
  430. COLORREF CExtEditSystemNumberCurrencyBase::SignColorGet() const
  431. {
  432. ASSERT_VALID( this );
  433. return m_clrSign;
  434. }
  435. void CExtEditSystemNumberCurrencyBase::BracketsColorSet( COLORREF clrBrackets /* = COLORREF(-1L) */ )
  436. {
  437. ASSERT_VALID( this );
  438. if( m_clrBrackets == clrBrackets )
  439. return;
  440. m_clrBrackets = clrBrackets;
  441. _Rich_OnDraw();
  442. }
  443. COLORREF CExtEditSystemNumberCurrencyBase::BracketsColorGet() const
  444. {
  445. ASSERT_VALID( this );
  446. return m_clrBrackets;
  447. }
  448. bool CExtEditSystemNumberCurrencyBase::_IsValid() const
  449. {
  450. ASSERT_VALID( this );
  451. long double lfValue = LongDoubleGet();
  452. bool bRetVal = ( m_lfMin <= lfValue && lfValue <= m_lfMax ) ? true : false;
  453. return bRetVal;
  454. }
  455. INT CExtEditSystemNumberCurrencyBase::_GetGroupSeparatorCount( const CExtSafeString & strText ) const
  456. {
  457. ASSERT_VALID( this );
  458. INT nPos = 0, nSepCount = 0;
  459. for( ; true; )
  460. {
  461. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  462. if( nPos == -1 )
  463. break;
  464. nSepCount ++;
  465. nPos ++;
  466. }
  467. return nSepCount;
  468. }
  469. void CExtEditSystemNumberCurrencyBase::_AdjustSeparators( 
  470. INT nCurrentSeparatorCount, 
  471. bool bDecimalPoint // = false
  472. )
  473. {
  474. ASSERT_VALID( this );
  475. nCurrentSeparatorCount; 
  476. bDecimalPoint;
  477. m_bAdjustingSeparators = true;
  478. CExtSafeString strText = Behavior_GetValidText( true );
  479. m_bAdjustingSeparators = false;
  480. }
  481. void CExtEditSystemNumberCurrencyBase::stat_InsertZeros( CExtSafeString * pStrText, INT nPos, INT nCount )
  482. {
  483. ASSERT( pStrText != NULL );
  484. if( nPos < 0 && nCount > 0 )
  485. nPos = INT( pStrText->GetLength() );
  486. for( INT iZero = 0; iZero < nCount; iZero++ )
  487. pStrText->Insert( nPos, _T('0') );
  488. }
  489. CExtSafeString CExtEditSystemNumberCurrencyBase::TextGetValid() const
  490. {
  491. ASSERT_VALID( this );
  492. return Behavior_GetValidText();
  493. }
  494. void CExtEditSystemNumberCurrencyBase::OnChar( UINT uChar, UINT nRepCnt, UINT nFlags )
  495. {
  496. ASSERT_VALID( this );
  497. Behavior_OnChar( uChar, nRepCnt, nFlags );
  498. // _Rich_OnDraw();
  499. }
  500. void CExtEditSystemNumberCurrencyBase::OnKeyDown( UINT uChar, UINT nRepCnt, UINT nFlags )
  501. {
  502. ASSERT_VALID( this );
  503. Behavior_OnKeyDown( uChar, nRepCnt, nFlags );
  504. }
  505. void CExtEditSystemNumberCurrencyBase::OnKillFocus( CWnd * pNewWnd )
  506. {
  507. ASSERT_VALID( this );
  508. Behavior_OnKillFocus( pNewWnd );
  509. }
  510. LRESULT CExtEditSystemNumberCurrencyBase::OnPaste( WPARAM wParam, LPARAM lParam )
  511. {
  512. ASSERT_VALID( this );
  513. if( ( GetStyle() & ES_READONLY ) != 0 )
  514. return 0;
  515. LRESULT lResult = Behavior_OnPaste( wParam, lParam );
  516. return lResult;
  517. }
  518. void CExtEditSystemNumberCurrencyBase::_CheckFlags()
  519. {
  520. ASSERT_VALID( this );
  521. if( GetSafeHwnd() == NULL )
  522. return;
  523. // test whether value is empty
  524. CExtSafeString strOriginalText = _GetNumericText( m_pEditWithBehaviorWnd->TextGet() );
  525. CExtSafeString strText = strOriginalText;
  526. INT nLen = INT( strText.GetLength() );
  527. // optionally remove any extra leading zeros but always leave one in front of the decimal point
  528. if( ( CBehaviorBase::m_nBehaviorFlags & __ESE_KF_REMOVE_EXTRA_LEADING_ZEROS ) != 0 && nLen > 0 )
  529. {
  530. bool bIsNegative = _IsNegative( strText );
  531. INT _nStart = 0, _nEnd = 0;
  532. _GetTextWithoutMarks( strText, _nStart, _nEnd );
  533. strText.TrimLeft( _T('0') );
  534. INT nDecimalSignPos = (INT)strText.Find( m_strDecimalPoint );
  535. if( strText.IsEmpty() || nDecimalSignPos == 0 )
  536. strText.Insert( 0, _T('0') );
  537. _GetTextWithMarks( strText, _nStart, _nEnd, bIsNegative );
  538. }
  539. else if( nLen == 0 && ( CBehaviorBase::m_nBehaviorFlags & __ESE_KF_DONT_PAD_WITH_ZEROS_IF_EMPTY ) != 0 )
  540. return;
  541. // test whether we need to pad the number with zeros after decimal point
  542. if( ( CBehaviorBase::m_nBehaviorFlags & __ESE_KF_PAD_WITH_ZEROS_AFTER_DECIMAL ) != 0 && m_nMaxFractionDigits > 0 )
  543. {
  544. bool bIsNegative = _IsNegative( strText );
  545. INT _nStart = 0, _nEnd = 0;
  546. _GetTextWithoutMarks( strText, _nStart, _nEnd );
  547. INT nDecimalSignPos = (INT)strText.Find( m_strDecimalPoint );
  548. INT nLen = INT( strText.GetLength() );
  549. if( nDecimalSignPos < 0 )
  550. {
  551. if( nLen == 0 )
  552. {
  553. strText = _T('0');
  554. nLen = (INT)strText.GetLength();
  555. }
  556. strText += m_strDecimalPoint;
  557. nDecimalSignPos = (INT)strText.Find( m_strDecimalPoint );
  558. }
  559. INT _nRightPartLen = (INT)strText.Mid( nDecimalSignPos + (INT)m_strDecimalPoint.GetLength() ).GetLength();
  560. if( _nRightPartLen > m_nMaxFractionDigits )
  561. strText.Delete( nDecimalSignPos + m_nMaxFractionDigits + m_strDecimalPoint.GetLength() );
  562. stat_InsertZeros( &strText, -1, m_nMaxFractionDigits - _nRightPartLen );
  563. _GetTextWithoutMarks( strText, _nStart, _nEnd );
  564. _GetTextWithMarks( strText, _nStart, _nEnd, bIsNegative );
  565. }
  566. // test whether we need to pad the number with zeros before the decimal point
  567. if( ( CBehaviorBase::m_nBehaviorFlags & __ESE_KF_PAD_WITH_ZEROS_BEFORE_DECIMAL ) != 0 && m_nMaxWholeDigits > 0 )
  568. {
  569. bool bIsNegative = _IsNegative( strText );
  570. INT _nStart = 0, _nEnd = 0;
  571. _GetTextWithoutMarks( strText, _nStart, _nEnd );
  572. INT nDecimalSignPos = (INT)strText.Find( m_strDecimalPoint );
  573. INT nLen = INT( strText.GetLength() );
  574. INT nZeroCount = 0, nZeroPos = -1;
  575. if( nDecimalSignPos < 0 )
  576. {
  577. nZeroCount = m_nMaxWholeDigits - nLen;
  578. nZeroPos = nLen;
  579. }
  580. else
  581. {
  582. nZeroCount = m_nMaxWholeDigits - nDecimalSignPos;
  583. nZeroPos = nDecimalSignPos;
  584. }
  585. stat_InsertZeros( &strText, nZeroPos, nZeroCount );
  586. _GetTextWithoutMarks( strText, _nStart, _nEnd );
  587. _GetTextWithMarks( strText, _nStart, _nEnd, bIsNegative );
  588. }
  589. if( strText != strOriginalText )
  590. m_pEditWithBehaviorWnd->SetWindowText( strText );
  591. }
  592. void CExtEditSystemNumberCurrencyBase::Behavior_OnKeyDown( UINT uChar, UINT nRepCnt, UINT nFlags ) 
  593. {
  594. ASSERT_VALID( this );
  595. switch( uChar )
  596. {
  597. case VK_DELETE:
  598. {
  599. if( ( GetStyle() & ES_READONLY ) != 0 )
  600. return;
  601. INT nStart = 0, nEnd = 0;
  602. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  603. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  604. if( _DeleteSymbols( strText, nStart, nEnd ) )
  605. {
  606. m_pEditWithBehaviorWnd->SetWindowText( strText );
  607. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  608. }
  609. else
  610. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  611. // _Rich_OnDraw();
  612. return;
  613. }
  614. case VK_BACK:
  615. {
  616. if( ( GetStyle() & ES_READONLY ) != 0 )
  617. return;
  618. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  619. if( strText.IsEmpty() )
  620. return;
  621. INT nStart = 0, nEnd = 0;
  622. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  623. if( _DeleteSymbols( strText, nStart, nEnd, true ) )
  624. m_pEditWithBehaviorWnd->SetWindowText( strText );
  625. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  626. // _Rich_OnDraw();
  627. return;
  628. }
  629. }
  630. //CExtEditWithBehavior::CBehaviorBase::Behavior_OnKeyDown( uChar, nRepCnt, nFlags );
  631. CBehaviorBase::Behavior_OnKeyDown( uChar, nRepCnt, nFlags );
  632. }
  633. void CExtEditSystemNumberCurrencyBase::Behavior_OnKillFocus( CWnd * pNewWnd )
  634. {
  635. ASSERT_VALID( this );
  636. //CExtEditWithBehavior::CBehaviorBase::Behavior_OnKillFocus( pNewWnd );
  637. CBehaviorBase::Behavior_OnKillFocus( pNewWnd );
  638. _CheckFlags();
  639. }
  640. LRESULT CExtEditSystemNumberCurrencyBase::Behavior_OnPaste( WPARAM wParam, LPARAM lParam )
  641. {
  642. ASSERT_VALID( this );
  643. wParam;
  644. lParam;
  645. if( ( GetStyle() & ES_READONLY ) != 0 )
  646. return 0;
  647. INT nStart = 0, nEnd = 0;
  648. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  649. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  650. // paste from clipboard
  651. if( OpenClipboard() )
  652. {
  653. CExtSafeString strClipboardText;
  654. bool bHaveClipboardText = false;
  655. if( g_PaintManager.m_bIsWinNT4orLater && ::IsClipboardFormatAvailable( CF_UNICODETEXT ) )
  656. {
  657. HGLOBAL h = ::GetClipboardData( CF_UNICODETEXT );
  658. if( h != NULL )
  659. {
  660. LPWSTR strUnicodeBuffer = (LPWSTR) ::GlobalLock( h );
  661. if( strUnicodeBuffer != NULL )
  662. {
  663. bHaveClipboardText = true;
  664. USES_CONVERSION;
  665. LPCTSTR strBuffer = W2CT(strUnicodeBuffer);
  666. strClipboardText = strBuffer;
  667. ::GlobalUnlock( h );
  668. }
  669. }
  670. } // if( g_PaintManager.m_bIsWinNT4orLater && ::IsClipboardFormatAvailable( CF_UNICODETEXT ) )
  671. if( ( ! bHaveClipboardText ) && ::IsClipboardFormatAvailable( CF_TEXT ) )
  672. {
  673. HGLOBAL h = ::GetClipboardData( CF_TEXT );
  674. if( h != NULL )
  675. {
  676. LPSTR strBuffer = (LPSTR) ::GlobalLock( h );
  677. if( strBuffer != NULL )
  678. {
  679. bHaveClipboardText = true;
  680. strClipboardText = LPCTSTR(strBuffer);
  681. ::GlobalUnlock( h );
  682. } // if( strBuffer != NULL )
  683. }
  684. } // if( ( ! bHaveClipboardText ) && ::IsClipboardFormatAvailable( CF_TEXT ) )
  685. if( bHaveClipboardText )
  686. {
  687. bool bNegative = _IsNegative( strText );
  688. _GetTextWithoutMarks( strText, nStart, nEnd );
  689. INT _nStart = 0, _nEnd = 0;
  690. INT nDecimalPointPos = INT( strText.Find( m_strDecimalPoint ) );
  691. INT nDecimalPointLen = INT( m_strDecimalPoint.GetLength() );
  692. if( nDecimalPointPos != -1 )
  693. _GetTextWithoutMarks( strClipboardText, _nStart, _nEnd, true );
  694. else
  695. _GetTextWithoutMarks( strClipboardText, _nStart, _nEnd );
  696. if( strText.IsEmpty() )
  697. _GetTextWithoutMarks( strClipboardText, _nStart, _nEnd, true );
  698. INT nClipboardTextLen = INT( strClipboardText.GetLength() );
  699. if( ( nEnd - nStart ) > 0 )
  700. strText.Delete( nStart, ( nEnd - nStart ) );
  701. nDecimalPointPos = INT( strText.Find( m_strDecimalPoint ) );
  702. bool bStartInFrontOfDecimalPoint = ( nStart <= nDecimalPointPos );
  703. strText.Insert( nStart, strClipboardText );
  704. nDecimalPointPos = INT( strText.Find( m_strDecimalPoint ) );
  705. if( nDecimalPointPos > m_nMaxWholeDigits )
  706. {
  707. strText.Delete( nDecimalPointPos, nDecimalPointLen );
  708. strText.Insert( m_nMaxWholeDigits, m_strDecimalPoint );
  709. nDecimalPointPos = m_nMaxWholeDigits;
  710. }
  711. if( nDecimalPointPos != -1 )
  712. nDecimalPointPos = INT( strText.Find( m_strDecimalPoint ) );
  713. INT nMaxLen = m_nMaxWholeDigits + m_nMaxFractionDigits + ( ( nDecimalPointPos != -1 ) ? nDecimalPointLen : 0 );
  714. nEnd = nStart + nClipboardTextLen;
  715. if( bStartInFrontOfDecimalPoint 
  716. && nEnd > nDecimalPointPos
  717. )
  718. nEnd += nDecimalPointLen;
  719. if( nMaxLen < strText.GetLength() )
  720. {
  721. strText.Delete( nMaxLen, ( strText.GetLength() - nMaxLen ) );
  722. if( nDecimalPointPos != -1 )
  723. {
  724. nDecimalPointPos = INT( strText.Find( m_strDecimalPoint ) );
  725. // check if DecimalPoint deleted
  726. if( nDecimalPointPos == -1 )
  727. {
  728. nMaxLen -= nDecimalPointLen;
  729. strText.Delete( nMaxLen, nDecimalPointLen );
  730. }
  731. }
  732. if( nDecimalPointPos != -1 && nDecimalPointPos > m_nMaxWholeDigits )
  733. {
  734. strText.Delete( nDecimalPointPos, nDecimalPointLen );
  735. strText.Insert( m_nMaxWholeDigits, m_strDecimalPoint );
  736. if( nEnd >= m_nMaxWholeDigits )
  737. nEnd += nDecimalPointLen;
  738. }
  739. }
  740. _GetTextWithMarks( strText, nStart, nEnd, bNegative );
  741. m_pEditWithBehaviorWnd->TextSet( strText );
  742. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  743. } // if( bHaveClipboardText )
  744. ::CloseClipboard();
  745. } // if( OpenClipboard() )
  746. // _Rich_OnDraw();
  747. return 0;
  748. }
  749. BOOL CExtEditSystemNumberCurrencyBase::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) 
  750. {
  751. ASSERT_VALID( this );
  752. if( message == WM_COMMAND )
  753. {
  754. INT nCode = HIWORD(wParam);
  755. switch( nCode )
  756. {
  757. case EN_CHANGE:
  758. _AdjustWithinRange();
  759. break;
  760. }
  761. }
  762. return CExtEditWithBehavior::OnChildNotify(message, wParam, lParam, pLResult);
  763. }
  764. /////////////////////////////////////////////////////////////////////////////
  765. // CExtEditSystemNumber window
  766. IMPLEMENT_DYNCREATE( CExtEditSystemNumber, CExtEditSystemNumberCurrencyBase );
  767. CExtEditSystemNumber::CExtEditSystemNumber(
  768. INT nMaxWholeDigits, // = __EXT_MFC_DEFAULT_MAX_WHOLE_DIGITS,
  769. INT nMaxFractionDigits // = __EXT_MFC_DEFAULT_FRACTION_WHOLE_DIGITS
  770. )
  771. : CExtEditSystemNumberCurrencyBase( nMaxWholeDigits, nMaxFractionDigits )
  772. {
  773. _Init();
  774. }
  775. CExtEditSystemNumber::~CExtEditSystemNumber()
  776. {
  777. }
  778. BEGIN_MESSAGE_MAP( CExtEditSystemNumber, CExtEditSystemNumberCurrencyBase )
  779. //{{AFX_MSG_MAP(CExtEditSystemNumberCurrencyBase)
  780. //}}AFX_MSG_MAP
  781. __EXT_MFC_SAFE_ON_WM_SETTINGCHANGE()
  782. END_MESSAGE_MAP()
  783. void CExtEditSystemNumber::_Init()
  784. {
  785. ASSERT_VALID( this );
  786. // negative sign
  787. if( g_ResourceManager->GetLocaleInfo( LOCALE_SNEGATIVESIGN, NULL, 0 ) )
  788. {
  789. g_ResourceManager->GetLocaleInfo( LOCALE_SNEGATIVESIGN, m_strNegativeSign.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  790. m_strNegativeSign.ReleaseBuffer();
  791. }
  792. // decimal point
  793. if( g_ResourceManager->GetLocaleInfo( LOCALE_SDECIMAL, NULL, 0 ) )
  794. g_ResourceManager->GetLocaleInfo( LOCALE_SDECIMAL, m_strDecimalPoint.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  795. m_strDecimalPoint.ReleaseBuffer();
  796. // group separator
  797. if( g_ResourceManager->GetLocaleInfo( LOCALE_STHOUSAND, NULL, 0 ) )
  798. g_ResourceManager->GetLocaleInfo( LOCALE_STHOUSAND, m_strGroupSeparator.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  799. m_strGroupSeparator.ReleaseBuffer();
  800. TCHAR cNegNumFormatIndex = _T('0');
  801. if( g_ResourceManager->GetLocaleInfo( LOCALE_INEGNUMBER, NULL, 0 ) )
  802. g_ResourceManager->GetLocaleInfo( LOCALE_INEGNUMBER, &cNegNumFormatIndex, sizeof( cNegNumFormatIndex ) / sizeof(TCHAR) );
  803. m_nNegativeFormatIndex = _ttoi( & cNegNumFormatIndex );
  804. CExtSafeString strDigitGrouping = _T("0");
  805. if( g_ResourceManager->GetLocaleInfo( LOCALE_SGROUPING, NULL, 0 ) )
  806. {
  807. g_ResourceManager->GetLocaleInfo( LOCALE_SGROUPING, strDigitGrouping.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  808. strDigitGrouping.ReleaseBuffer();
  809. INT nStrLen = INT( strDigitGrouping.GetLength() );
  810. CExtSafeString _strGroup = _T("");
  811. INT nGroup = 0;
  812. if( m_listDigitGrouping.GetCount() > 0 )
  813. m_listDigitGrouping.RemoveAll();
  814. for( INT i = 0; i < nStrLen; i++ )
  815. {
  816. TCHAR ch = strDigitGrouping[i];
  817. if( ch == _T(';') )
  818. {
  819. nGroup = _ttoi( _strGroup );
  820. m_listDigitGrouping.AddTail( nGroup );
  821. _strGroup = _T("");
  822. nGroup = 0;
  823. }
  824. else
  825. _strGroup = _strGroup + ch;
  826. }
  827. nGroup = _ttoi( _strGroup );
  828. m_listDigitGrouping.AddTail( nGroup );
  829. }
  830. TCHAR cNoOfDigitsAfterDecimal = _T('0');
  831. if( g_ResourceManager->GetLocaleInfo( LOCALE_IDIGITS, NULL, 0 ) )
  832. g_ResourceManager->GetLocaleInfo( LOCALE_IDIGITS, &cNoOfDigitsAfterDecimal, sizeof( cNoOfDigitsAfterDecimal ) / sizeof(TCHAR) );
  833. m_nMaxFractionDigits = _ttoi( & cNoOfDigitsAfterDecimal );
  834. TCHAR cDisplayLeadingZeros = _T('0');
  835. if( g_ResourceManager->GetLocaleInfo( LOCALE_ILZERO, NULL, 0 ) )
  836. g_ResourceManager->GetLocaleInfo( LOCALE_ILZERO, &cDisplayLeadingZeros, sizeof( cDisplayLeadingZeros ) / sizeof(TCHAR) );
  837. m_nDisplayLeadingZeros = _ttoi( & cDisplayLeadingZeros );
  838. TCHAR cDigitGrouping[20] = _T("");
  839. if( g_ResourceManager->GetLocaleInfo( LOCALE_SGROUPING, NULL, 0 ) )
  840. g_ResourceManager->GetLocaleInfo( LOCALE_SGROUPING, cDigitGrouping, sizeof( cDigitGrouping ) / sizeof( cDigitGrouping[0] ) );
  841. // ensure the separators are not the same
  842. if( m_strDecimalPoint == m_strGroupSeparator
  843. && ( m_strDecimalPoint == _T(".")
  844. || m_strDecimalPoint == _T(",")
  845. )
  846. )
  847. m_strGroupSeparator = ( m_strDecimalPoint == _T(",") ? _T(".") : _T(",") );
  848. if( m_strDecimalPoint == m_strGroupSeparator
  849. && ( m_strDecimalPoint != _T(".")
  850. && m_strDecimalPoint != _T(",")
  851. )
  852. )
  853. m_strDecimalPoint == _T(".");
  854. }
  855. void CExtEditSystemNumber::OnSettingChange(UINT uFlags, __EXT_MFC_SAFE_LPCTSTR lpszSection) 
  856. {
  857. ASSERT_VALID( this );
  858. CExtEditSystemNumberCurrencyBase::OnSettingChange( uFlags, lpszSection );
  859. if( _tcscmp( lpszSection, _T("intl") ) == 0 )
  860. {
  861. long double lfSaved = LongDoubleGet();
  862. _Init();
  863. LongDoubleSet( lfSaved );
  864. SetSel( -1, -1 );
  865. }
  866. }
  867. CExtSafeString CExtEditSystemNumber::_GetNumericText(
  868. const CExtSafeString & strText,
  869. bool bUseMathSymbols // = false
  870. ) const
  871. {
  872. ASSERT_VALID( this );
  873. CExtSafeString strNewText;
  874. bool bIsNegative = _IsNegative(strText); // false;
  875. bool bHasDecimalPoint = false;
  876. INT nDecimalSignLen = INT( m_strDecimalPoint.GetLength() );
  877. INT nDecimalSignPos = INT( strText.Find( m_strDecimalPoint ) );
  878. INT nPos, nLen;
  879. for( nPos = 0, nLen = INT( strText.GetLength() ); nPos < nLen; nPos++ )
  880. {
  881. TCHAR c = strText[nPos];
  882. if( _istdigit(c) )
  883. strNewText += c;
  884. else if( nPos == nDecimalSignPos && !bHasDecimalPoint )
  885. {
  886. bHasDecimalPoint = true;
  887. strNewText += ( bUseMathSymbols ? _T(".") : m_strDecimalPoint );
  888. nPos += nDecimalSignLen - 1;
  889. }
  890. }
  891. // add negative sign to the front of the number
  892. if( bIsNegative )
  893. {
  894. CExtSafeString strNegativeSign;
  895. if( m_nNegativeFormatIndex == 1 || m_nNegativeFormatIndex == 3 )
  896. strNegativeSign = m_strNegativeSign;
  897. if( m_nNegativeFormatIndex == 2 )
  898. strNegativeSign = m_strNegativeSign + _T(" ");
  899. if( m_nNegativeFormatIndex == 4 )
  900. strNegativeSign = _T(" ") + m_strNegativeSign;
  901. if( bUseMathSymbols )
  902. {
  903. strNewText.Insert( 0, _T('-') );
  904. }
  905. else
  906. {
  907. INT nIndex = ( m_nNegativeFormatIndex == 1 || m_nNegativeFormatIndex == 2 ) ? 0 : strNewText.GetLength();
  908. if( m_nNegativeFormatIndex != 0 )
  909. strNewText.Insert( nIndex, bUseMathSymbols ? _T("-") : strNegativeSign );
  910. else
  911. {
  912. strNewText.Insert( strNewText.GetLength(), _T(')') );
  913. strNewText.Insert( 0, _T('(') );
  914. }
  915. }
  916. }
  917. return strNewText;
  918. }
  919. CExtSafeString CExtEditSystemNumber::_GetDoubleText( long double lfValue, bool bTrimTrailingZeros /*= true*/ ) const
  920. {
  921. ASSERT_VALID( this );
  922. CExtSafeString strText;
  923. strText.Format( _T("%lf"), lfValue );
  924. if( m_strDecimalPoint != _T(".") )
  925. strText.Replace( _T("."), m_strDecimalPoint );
  926. if( bTrimTrailingZeros )
  927. {
  928. strText.TrimRight( _T('0') );
  929. strText.TrimRight( m_strDecimalPoint );
  930. }
  931. bool bNegative = ( strText.Find( _T("-") ) == 0 ) ? true : false;
  932. if( bNegative )
  933. {
  934. strText.Delete( 0 );
  935. CExtSafeString _strBefore = _T("");
  936. CExtSafeString _strAfter = _T("");
  937. switch( m_nNegativeFormatIndex )
  938. {
  939. case 0:
  940. _strBefore = _T("(");
  941. _strAfter = _T(")");
  942. break;
  943. case 1:
  944. _strBefore = m_strNegativeSign;
  945. break;
  946. case 2:
  947. _strBefore = m_strNegativeSign + _T(" ");
  948. break;
  949. case 3:
  950. _strAfter = m_strNegativeSign;
  951. break;
  952. case 4:
  953. _strAfter = _T(" ") + m_strNegativeSign;
  954. break;
  955. }
  956. INT nLen = INT( strText.GetLength() );
  957. if( ! _strAfter.IsEmpty() )
  958. strText.Insert( nLen, _strAfter );
  959. if( ! _strBefore.IsEmpty() )
  960. strText.Insert( 0, _strBefore );
  961. }
  962. return strText;
  963. }
  964. void CExtEditSystemNumber::IntSet( INT nVal )
  965. {
  966. ASSERT_VALID( this );
  967. CExtSafeString strText;
  968. strText.Format( _T("%d"), nVal );
  969. bool bNegative = ( strText.Find( _T("-") ) == 0 ) ? true : false;
  970. if( bNegative )
  971. {
  972. strText.Delete( 0 );
  973. CExtSafeString _strBefore = _T("");
  974. CExtSafeString _strAfter = _T("");
  975. switch( m_nNegativeFormatIndex )
  976. {
  977. case 0:
  978. _strBefore = _T("(");
  979. _strAfter = _T(")");
  980. break;
  981. case 1:
  982. _strBefore = m_strNegativeSign;
  983. break;
  984. case 2:
  985. _strBefore = m_strNegativeSign + _T(" ");
  986. break;
  987. case 3:
  988. _strAfter = m_strNegativeSign;
  989. break;
  990. case 4:
  991. _strAfter = _T(" ") + m_strNegativeSign;
  992. break;
  993. }
  994. INT nLen = INT( strText.GetLength() );
  995. if( ! _strAfter.IsEmpty() )
  996. strText.Insert( nLen, _strAfter );
  997. if( ! _strBefore.IsEmpty() )
  998. strText.Insert( 0, _strBefore );
  999. }
  1000. m_pEditWithBehaviorWnd->SetWindowText(strText);
  1001. }
  1002. long double CExtEditSystemNumber::LongDoubleGet() const
  1003. {
  1004. ASSERT_VALID( this );
  1005. // return _tcstod( _GetNumericText( m_pEditWithBehaviorWnd->TextGet(), true ), NULL );
  1006. CExtSafeString str = _GetNumericText( m_pEditWithBehaviorWnd->TextGet() ); //, true 
  1007. if( str.IsEmpty()
  1008. || str == _T(".")
  1009. || str == LPCTSTR(m_strDecimalPoint)
  1010. || ( str.GetLength() == 1 && m_strDecimalPoint.GetLength() > 0 && str[0] == m_strDecimalPoint[0] )
  1011. )
  1012. return 0.0;
  1013. LCID _LCID = LANG_USER_DEFAULT;
  1014. if( g_ResourceManager->IsCustomLangAllowed() )
  1015. _LCID = g_ResourceManager->GetLangIdDesired();
  1016. DOUBLE lfTmp = 0.0;
  1017. USES_CONVERSION;
  1018. HRESULT hr = ::VarR8FromStr( (LPOLESTR) T2COLE( LPCTSTR(str) ), _LCID, 0, &lfTmp );
  1019. ASSERT( SUCCEEDED( hr ) );
  1020. hr;
  1021. long double lfVal = (long double)lfTmp;
  1022. return lfVal;
  1023. }
  1024. INT CExtEditSystemNumber::IntGet() const
  1025. {
  1026. ASSERT_VALID( this );
  1027. // return (INT)_ttoi( _GetNumericText( m_pEditWithBehaviorWnd->TextGet(), true ) );
  1028. CExtSafeString str = _GetNumericText( m_pEditWithBehaviorWnd->TextGet() ); //, true 
  1029. if( str.IsEmpty() )
  1030. return 0;
  1031. LCID _LCID = LANG_USER_DEFAULT;
  1032. if( g_ResourceManager->IsCustomLangAllowed() )
  1033. _LCID = g_ResourceManager->GetLangIdDesired();
  1034. LONG nTmp = 0L;
  1035. USES_CONVERSION;
  1036. HRESULT hr = ::VarI4FromStr( (LPOLESTR) T2COLE( LPCTSTR(str) ), _LCID, 0, &nTmp );
  1037. ASSERT( SUCCEEDED( hr ) );
  1038. hr;
  1039. return INT(nTmp);
  1040. }
  1041. CExtSafeString CExtEditSystemNumber::Behavior_GetValidText(
  1042. bool bSetSel // = false
  1043. ) const
  1044. {
  1045. ASSERT_VALID( this );
  1046. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  1047. CExtSafeString strNewText = strText;
  1048. bool bIsNegative = _IsNegative( strText );
  1049. INT nStart, nEnd;
  1050. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  1051. _GetTextWithoutMarks( strNewText, nStart, nEnd );
  1052. _GetTextWithMarks( strNewText, nStart, nEnd );
  1053. // insert the negative sign if it is not present
  1054. if( bIsNegative && AllowNegativeGet() )
  1055. {
  1056. INT nNegSignLen = INT( m_strNegativeSign.GetLength() ) + ( ( m_nNegativeFormatIndex == 2 || m_nNegativeFormatIndex == 4 ) ? 1: 0 );
  1057. if( m_nNegativeFormatIndex == 0 )
  1058. nNegSignLen = 1;
  1059. CExtSafeString _strNegativeSign = ( (m_nNegativeFormatIndex == 4) ? _T(" "): _T("") ) + m_strNegativeSign + ( (m_nNegativeFormatIndex == 2) ? _T(" "): _T("") );
  1060. if( m_nNegativeFormatIndex == 0 )
  1061. {
  1062. strNewText.Insert( strNewText.GetLength(), _T(")") );
  1063. strNewText.Insert( 0, _T("(") );
  1064. nStart += 1;
  1065. nEnd += 1;
  1066. }
  1067. if( m_nNegativeFormatIndex == 1 || m_nNegativeFormatIndex == 2 )
  1068. strNewText.Insert( 0, _strNegativeSign );
  1069. if( m_nNegativeFormatIndex == 3 || m_nNegativeFormatIndex == 4 )
  1070. strNewText.Insert( strNewText.GetLength(), _strNegativeSign );
  1071. if( m_nNegativeFormatIndex == 1 || m_nNegativeFormatIndex == 2 )
  1072. {
  1073. nStart += nNegSignLen;
  1074. nEnd += nNegSignLen;
  1075. }
  1076. }
  1077. if( bSetSel && ( ! m_bRichPainting ) )
  1078. {
  1079. CExtSafeString strCurrentText = m_pEditWithBehaviorWnd->TextGet();
  1080. if( strNewText != strCurrentText )
  1081. m_pEditWithBehaviorWnd->SetWindowText( strNewText );
  1082. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  1083. }
  1084. return strNewText;
  1085. }
  1086. void CExtEditSystemNumber::Behavior_OnChar( UINT uChar, UINT nRepCnt, UINT nFlags )
  1087. {
  1088. ASSERT_VALID( this );
  1089. if( m_pEditWithBehaviorWnd->GetStyle() & ES_READONLY )
  1090. return;
  1091. TCHAR c = static_cast<TCHAR>( uChar );
  1092. INT nStart, nEnd;
  1093. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  1094. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  1095. CExtSafeString strNumericText = _GetNumericText( strText );
  1096. INT nDecimalPos = INT( strText.Find( m_strDecimalPoint ) );
  1097. INT nNumericDecimalPos = INT( strNumericText.Find( m_strDecimalPoint ) );
  1098. INT nLen = INT( strText.GetLength() );
  1099. INT nNumericLen = INT( strNumericText.GetLength() );
  1100. INT nSepCount = _GetGroupSeparatorCount( strText );
  1101. bool bNeedAdjustment = false;
  1102. INT nNegSignLen = INT( m_strNegativeSign.GetLength() );
  1103. bool bIsNegative = false;
  1104. bool bIsDecimalPoint = false;
  1105. if( ( c == m_strNegativeSign[0/*nNegSignMatch*/] )
  1106. || ( m_nNegativeFormatIndex == 0 
  1107. && c == _T('(') 
  1108. )
  1109. || ( c == _T('-') )
  1110. )
  1111. bIsNegative = true;
  1112. // check if it's a negative sign
  1113. if( bIsNegative && AllowNegativeGet() )
  1114. {
  1115. bool bNegative = _IsNegative( strText );
  1116. CExtSafeString _strBefore = _T(""), _strAfter = _T("");
  1117. switch( m_nNegativeFormatIndex )
  1118. {
  1119. case 0:
  1120. _strBefore = _T("(");
  1121. _strAfter = _T(")");
  1122. break;
  1123. case 1:
  1124. _strBefore = m_strNegativeSign;
  1125. break;
  1126. case 2:
  1127. _strBefore = m_strNegativeSign + _T(" ");
  1128. break;
  1129. case 3:
  1130. _strAfter = m_strNegativeSign;
  1131. break;
  1132. case 4:
  1133. _strAfter = _T(" ") + m_strNegativeSign;
  1134. break;
  1135. }
  1136. INT nBeforLen = INT( _strBefore.GetLength() );
  1137. INT nAfterLen = INT( _strAfter.GetLength() );
  1138. CExtSafeString strNewText = strText;
  1139. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  1140. if( bNegative )
  1141. {
  1142. if( nStart < nBeforLen )
  1143. nStart = nBeforLen;
  1144. if( nEnd > ( nLen - nAfterLen ) )
  1145. nEnd = ( nLen - nAfterLen );
  1146. }
  1147. _GetTextWithoutMarks( strNewText, nStart, nEnd );
  1148. _GetTextWithMarks( strNewText, nStart, nEnd, ! bNegative );
  1149. CExtSafeString strCurrentText = m_pEditWithBehaviorWnd->TextGet();
  1150. if( strNewText != strCurrentText )
  1151. m_pEditWithBehaviorWnd->SetWindowText( strNewText );
  1152. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  1153. return;
  1154. }
  1155. // test whether it is decimal point (only one is enabled)
  1156. else if( c == m_strDecimalPoint[0] && m_nMaxFractionDigits > 0 )
  1157. {
  1158. if( nDecimalPos >= 0 )
  1159. {
  1160. // test decimal point replacement
  1161. if( nDecimalPos >= nStart && nDecimalPos < nEnd )
  1162. {
  1163. bNeedAdjustment = true;
  1164. bIsDecimalPoint = true;
  1165. }
  1166. else
  1167. { // else set caret
  1168. m_pEditWithBehaviorWnd->SetSel( nDecimalPos + m_strDecimalPoint.GetLength(), nDecimalPos + m_strDecimalPoint.GetLength() );
  1169. return;
  1170. }
  1171. }
  1172. else
  1173. {
  1174. bNeedAdjustment = true;
  1175. bIsDecimalPoint = true;
  1176. }
  1177. }
  1178. else if( _istdigit(c) )
  1179. {
  1180. // test we're on the right of the decimal point.
  1181. if( nDecimalPos >= 0 && nDecimalPos < nStart )
  1182. {
  1183. bool bIsNegative = ( ! strNumericText.IsEmpty() && ( strNumericText.Find( m_strNegativeSign ) >= 0 ) && ( m_nNegativeFormatIndex == 3 || m_nNegativeFormatIndex == 4 ) );
  1184. if( ! bIsNegative )
  1185. bIsNegative = ( ! strNumericText.IsEmpty() && ( strNumericText.Find( _T('(') ) >= 0 ) && m_nNegativeFormatIndex == 0 );
  1186. INT nNegLength = 0;
  1187. if( m_nNegativeFormatIndex != 0 )
  1188. nNegLength = nNegSignLen + ( ( m_nNegativeFormatIndex == 4 ) ? 1 : 0 );
  1189. else
  1190. nNegLength = 1;
  1191. if( bIsNegative )
  1192. {
  1193. INT nNegSignPos = -1;
  1194. if( m_nNegativeFormatIndex == 3 )
  1195. nNegSignPos = INT( strText.Find( m_strNegativeSign ) );
  1196. if( m_nNegativeFormatIndex == 4 )
  1197. nNegSignPos = INT( strText.Find( _T(' ') + m_strNegativeSign ) );
  1198. if( m_nNegativeFormatIndex == 0 )
  1199. nNegSignPos = INT( strText.Find( _T(')') ) );
  1200. if( ( nStart > nNegSignPos ) && ( nStart <= nLen ) && nNegSignPos != -1 )
  1201. {
  1202. nStart = nNegSignPos;
  1203. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  1204. }
  1205. }
  1206. INT nDecimalSeparatorLen = INT( m_strDecimalPoint.GetLength() );
  1207. if( nDecimalPos <= nStart && nStart < ( nDecimalPos + nDecimalSeparatorLen ) )
  1208. {
  1209. INT nPrevStart = nStart;
  1210. nStart = ( nDecimalPos + nDecimalSeparatorLen );
  1211. if( nEnd == nPrevStart 
  1212. || nEnd < nPrevStart 
  1213. || ( nEnd > nPrevStart 
  1214. && nEnd < nStart
  1215. )
  1216. )
  1217. nEnd = nStart;
  1218. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  1219. }
  1220. if( strNumericText.Mid( /*nDecimalPos */ nNumericDecimalPos + nDecimalSeparatorLen ).GetLength() == ( m_nMaxFractionDigits + ( bIsNegative ? nNegLength : 0 ) ) )
  1221. {
  1222. if( nStart <= ( nDecimalPos + m_nMaxFractionDigits + nDecimalSeparatorLen - 1 ) )
  1223. {
  1224. nEnd = ( ( ( nEnd == nLen ) || ( nEnd > ( nStart + 1 ) ) ) ? nEnd : (nStart + 1) );
  1225. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  1226. m_pEditWithBehaviorWnd->ReplaceSel( CExtSafeString(c), TRUE );
  1227. CExtSafeString strReplaceText = Behavior_GetValidText();
  1228. }
  1229. return;
  1230. }
  1231. else if( strNumericText.Mid( /*nDecimalPos */ nNumericDecimalPos + nDecimalSeparatorLen ).GetLength() > ( m_nMaxFractionDigits + ( bIsNegative ? nNegLength : 0 ) ) )
  1232. {
  1233. ASSERT(false);
  1234. return;
  1235. }
  1236. }
  1237. // we're on the left side of the decimal point
  1238. else
  1239. {
  1240. bool bIsNegative = ( ! strNumericText.IsEmpty() && ( strNumericText.Find( m_strNegativeSign ) >= 0 ) && ( m_nNegativeFormatIndex == 1 || m_nNegativeFormatIndex == 2 ) );
  1241. if( ! bIsNegative )
  1242. bIsNegative = ( ! strNumericText.IsEmpty() && ( strNumericText.Find( _T('(') ) >= 0 ) && m_nNegativeFormatIndex == 0 );
  1243. bool bIsNegativeRight = ( ! strNumericText.IsEmpty() && ( strNumericText.Find( m_strNegativeSign ) >= 0 ) && ( m_nNegativeFormatIndex == 3 || m_nNegativeFormatIndex == 4 ) );
  1244. INT nNegLength = 0;
  1245. nNegLength 
  1246. = nNegSignLen
  1247. + (
  1248. ( m_nNegativeFormatIndex == 2 
  1249. || m_nNegativeFormatIndex == 4
  1250. ) ? 1 : 0 
  1251. );
  1252. if( m_nNegativeFormatIndex == 0 )
  1253. nNegLength = 1;
  1254. if( bIsNegative )
  1255. {
  1256. if( ( nStart >= 0 ) && ( nStart < nNegLength ) )
  1257. {
  1258. nStart = nNegLength;
  1259. if( nStart > nEnd )
  1260. nEnd = nStart;
  1261. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  1262. }
  1263. }
  1264. if( bIsNegativeRight || ( bIsNegative && m_nNegativeFormatIndex == 0 ) )
  1265. {
  1266. if( ( nEnd >= ( nLen - nNegLength ) ) && ( nEnd <= nLen ) )
  1267. {
  1268. nEnd = nLen - nNegLength;
  1269. if( nStart > nEnd )
  1270. nStart = nEnd;
  1271. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  1272. }
  1273. if( ( nStart >= ( nLen - nNegLength ) ) && ( nStart <= nLen ) )
  1274. {
  1275. nStart = nLen - nNegLength;
  1276. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  1277. }
  1278. }
  1279. INT nGroupSeparatorLen = INT( m_strGroupSeparator.GetLength() );
  1280. INT nDecimalSignLen = INT( m_strDecimalPoint.GetLength() );
  1281. // ensure we can still enter digits.
  1282. INT nDecPos = m_nMaxWholeDigits + ( bIsNegative ? nNegLength : 0 ) + ( nSepCount * nGroupSeparatorLen );
  1283. if( nStart == nDecPos )
  1284. {
  1285. UINT nFlags = CBehaviorBase::m_nBehaviorFlags;
  1286. if(  ( nFlags & __ESE_ADD_DECIMAL_AFTER_MAX_WHOLE_DIGITS ) != 0 && m_nMaxFractionDigits > 0 )
  1287. {
  1288. nEnd = ( ( ( nEnd == nLen ) || ( ( nEnd > nStart ) && ( ( nEnd - nStart ) > 1 ) ) ) ? nEnd : ( nStart + nDecimalSignLen + 1 ) );
  1289. if( bIsNegativeRight || ( bIsNegative && m_nNegativeFormatIndex == 0 ) )
  1290. {
  1291. m_pEditWithBehaviorWnd->SetSel( nStart, strText.GetLength() );
  1292. m_pEditWithBehaviorWnd->ReplaceSel( _T(""), TRUE );
  1293. }
  1294. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  1295. m_pEditWithBehaviorWnd->ReplaceSel( m_strDecimalPoint + c, TRUE );
  1296. if( bIsNegativeRight || ( bIsNegative && m_nNegativeFormatIndex == 0 ) )
  1297. {
  1298. CExtSafeString strChangedText = m_pEditWithBehaviorWnd->TextGet();
  1299. CExtSafeString _strNegativeSign = ( m_nNegativeFormatIndex == 4 ? _T(" "): _T("") ) + m_strNegativeSign;
  1300. nEnd = INT( strChangedText.GetLength() );
  1301. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  1302. if( m_nNegativeFormatIndex != 0 )
  1303. m_pEditWithBehaviorWnd->ReplaceSel( _strNegativeSign, TRUE );
  1304. else
  1305. m_pEditWithBehaviorWnd->ReplaceSel( _T(")"), TRUE );
  1306. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  1307. }
  1308. CExtSafeString strReplaceText = Behavior_GetValidText(true);
  1309. }
  1310. return;
  1311. }
  1312. if( strNumericText.Mid( 
  1313. 0, 
  1314. ( ( nNumericDecimalPos >= 0 )
  1315. ? nNumericDecimalPos
  1316. : nNumericLen
  1317. )
  1318. ).GetLength()
  1319. == ( m_nMaxWholeDigits + ( bIsNegative ? nNegLength : 0 ) ) //  + ( ( nNumericDecimalPos >= 0 ) ? ( m_strDecimalPoint.GetLength() ) : 0 )
  1320. )
  1321. {
  1322. {
  1323. INT nPos = 0;
  1324. for( ; true; )
  1325. {
  1326. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  1327. if( nPos == -1 )
  1328. break;
  1329. if( nPos <= nStart && nStart < ( nPos + nGroupSeparatorLen ) )
  1330. {
  1331. nStart = nPos + nGroupSeparatorLen;
  1332. break;
  1333. }
  1334. nPos ++;
  1335. }
  1336. INT _nNegativeSignLen = INT( m_strNegativeSign.GetLength() ) + ( (m_nNegativeFormatIndex == 2 || m_nNegativeFormatIndex == 4) ? 1: 0 );
  1337. if( m_nNegativeFormatIndex == 0 )
  1338. _nNegativeSignLen = 1;
  1339. if( nStart < _nNegativeSignLen && bIsNegative )
  1340. nStart = _nNegativeSignLen;
  1341. nEnd = ( ( ( nEnd == nLen ) || ( nEnd > ( nStart + 1 ) ) ) ? nEnd : ( nStart + 1 ) );
  1342. if( bIsNegativeRight )
  1343. {
  1344. INT nNegSignPos = INT( strText.Find( m_strNegativeSign ) );
  1345. if( nEnd > nNegSignPos )
  1346. nEnd = nNegSignPos;
  1347. }
  1348. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  1349. m_pEditWithBehaviorWnd->ReplaceSel( CExtSafeString(c), TRUE );
  1350. CExtSafeString strReplaceText = Behavior_GetValidText(true);
  1351. }
  1352. return;
  1353. }
  1354. bNeedAdjustment = true;
  1355. }
  1356. }
  1357. // test whether it is a non-printable character (i.e. backspace, ctrl+c )
  1358. else if( ! ( _istprint( c ) || IsCharAlphaNumeric( c ) ) )
  1359. bNeedAdjustment = true;
  1360. else
  1361. return;
  1362. if( ! m_bBackspace )
  1363. {
  1364. //CExtEditSystemNumberCurrencyBase::CBehaviorBase::Behavior_OnChar( uChar, nRepCnt, nFlags );
  1365. CBehaviorBase::Behavior_OnChar( uChar, nRepCnt, nFlags );
  1366. // if the decimal point was added/removed or a separator needs adding/removing, adjust the text
  1367. if( bNeedAdjustment )
  1368. _AdjustSeparators( nSepCount, bIsDecimalPoint );
  1369. }
  1370. else
  1371. m_bBackspace = false;
  1372. }
  1373. bool CExtEditSystemNumber::_DeleteSymbols( 
  1374. CExtSafeString & strText, 
  1375. INT & nStart, 
  1376. INT & nEnd, 
  1377. bool bBackspace // = false
  1378. )
  1379. {
  1380. ASSERT_VALID( this );
  1381. ASSERT( ! m_bRichPainting );
  1382. INT nLen = INT( strText.GetLength() );
  1383. bool bNegative = _IsNegative( strText );
  1384. CExtSafeString strTextLen = strText;
  1385. INT nStLen = 0, nEndLen = 0;
  1386. _GetTextWithoutMarks( strTextLen, nStLen, nEndLen );
  1387. INT nTextLen = INT( strTextLen.GetLength() );
  1388. INT nDecSepPosLen = INT( strTextLen.Find( m_strDecimalPoint ) );
  1389. INT nGroupSeparatorLen = INT( m_strGroupSeparator.GetLength() );
  1390. INT nDecimalSeparatorLen = INT( m_strDecimalPoint.GetLength() );
  1391. INT nDecimalSeparatorPos = INT( strText.Find( m_strDecimalPoint ) );
  1392. INT _nPos = 0, _nGroupSignBeforeStart = 0, _nGroupSignCount = (INT)_GetGroupSeparatorCount( strText );
  1393. for( ; true; )
  1394. {
  1395. _nPos = (INT)strText.Find( m_strGroupSeparator, _nPos );
  1396. if( _nPos < 0 )
  1397. break;
  1398. if( _nPos < nStart )
  1399. _nGroupSignBeforeStart ++;
  1400. _nPos ++;
  1401. }
  1402. _nGroupSignBeforeStart = _nGroupSignCount - _nGroupSignBeforeStart;
  1403. if( bBackspace )
  1404. {
  1405. if( nStart == 0 && nStart == nEnd )
  1406. return false;
  1407. INT nPos = 0;
  1408. if( nStart >= 0 )
  1409. {
  1410. if( ( nDecimalSeparatorPos < nStart
  1411. || ( nDecimalSeparatorPos == nStart
  1412. && nStart != nEnd
  1413. )
  1414. )
  1415. && nStart <= ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  1416. && nEnd <= ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  1417. && nDecSepPosLen == m_nMaxWholeDigits
  1418. && ( nTextLen > ( nDecSepPosLen + nDecimalSeparatorLen )
  1419. && nDecSepPosLen != -1
  1420. )
  1421. )
  1422. {
  1423. nStart = nDecimalSeparatorPos;
  1424. nEnd = nDecimalSeparatorPos;
  1425. m_bBackspace = true;
  1426. return false;
  1427. }
  1428. for( ; true; )
  1429. {
  1430. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  1431. if( nPos == -1 )
  1432. break;
  1433. if( ( nPos < nStart 
  1434. || ( nPos == nStart 
  1435. && nStart != nEnd
  1436. )
  1437. )
  1438. && nStart <= ( nPos + nGroupSeparatorLen )
  1439. && nEnd <= ( nPos + nGroupSeparatorLen )
  1440. )
  1441. {
  1442. nStart = nPos;
  1443. nEnd = nPos;
  1444. m_bBackspace = true;
  1445. return false;
  1446. }
  1447. nPos ++;
  1448. }
  1449. }
  1450. }
  1451. else
  1452. {
  1453. if( nStart == nLen )
  1454. return false;
  1455. INT nPos = 0;
  1456. if( nStart < nLen )
  1457. {
  1458. if( nDecimalSeparatorPos <= nStart
  1459. && nStart < ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  1460. && nEnd <= ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  1461. && nDecSepPosLen == m_nMaxWholeDigits
  1462. && ( nTextLen > ( nDecSepPosLen + nDecimalSeparatorLen )
  1463. && nDecSepPosLen != -1
  1464. )
  1465. )
  1466. {
  1467. nStart = nDecimalSeparatorPos + nDecimalSeparatorLen;
  1468. nEnd = nDecimalSeparatorPos + nDecimalSeparatorLen;
  1469. return false;
  1470. }
  1471. for( ; true; )
  1472. {
  1473. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  1474. if( nPos == -1 )
  1475. break;
  1476. if( nPos <= nStart 
  1477. && nStart < ( nPos + nGroupSeparatorLen )
  1478. && nEnd <= ( nPos + nGroupSeparatorLen )
  1479. )
  1480. {
  1481. nStart = nPos + nGroupSeparatorLen;
  1482. nEnd = nPos + nGroupSeparatorLen;
  1483. return false;
  1484. }
  1485. nPos ++;
  1486. }
  1487. }
  1488. }
  1489. if( nStart != nEnd )
  1490. {
  1491. if( nDecimalSeparatorPos < nStart
  1492. && nStart < ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  1493. )
  1494. {
  1495. nStart = nDecimalSeparatorPos + nDecimalSeparatorLen;
  1496. if( nStart > nEnd )
  1497. nEnd = nStart;
  1498. }
  1499. if( nDecimalSeparatorPos < nEnd
  1500. && nEnd <= ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  1501. )
  1502. nEnd = nDecimalSeparatorPos;
  1503. INT nPos = 0;
  1504. for( ; true; )
  1505. {
  1506. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  1507. if( nPos == -1 )
  1508. break;
  1509. if( nPos < nStart 
  1510. && nStart < ( nPos + nGroupSeparatorLen )
  1511. )
  1512. {
  1513. nStart = nPos + nGroupSeparatorLen;
  1514. if( nStart >= nEnd )
  1515. {
  1516. nEnd = nStart;
  1517. break;
  1518. }
  1519. }
  1520. if( nPos < nEnd 
  1521. && nEnd < ( nPos + nGroupSeparatorLen )
  1522. )
  1523. {
  1524. nEnd = nPos;
  1525. if( nEnd < nStart )
  1526. nStart = nEnd;
  1527. if( nEnd >= nStart )
  1528. break;
  1529. }
  1530. nPos ++;
  1531. }
  1532. }
  1533. {
  1534. INT nNegSignLen = INT( m_strNegativeSign.GetLength() ) + ( ( m_nNegativeFormatIndex == 2 || m_nNegativeFormatIndex == 4 ) ? 1 : 0 );
  1535. if( m_nNegativeFormatIndex == 0 )
  1536. nNegSignLen = 1;
  1537. bool bNegDel = false;
  1538. if( bNegative )
  1539. {
  1540. if( ( nStart < nNegSignLen || ( nStart == nNegSignLen  && nStart == nEnd  && bBackspace ) ) 
  1541. && ( m_nNegativeFormatIndex == 1 || m_nNegativeFormatIndex == 2 || m_nNegativeFormatIndex == 0 ) 
  1542. )
  1543. {
  1544. bNegative = false;
  1545. bNegDel = true;
  1546. }
  1547. if( ( ( nStart >= ( nLen - nNegSignLen )
  1548. && ! bBackspace
  1549. )
  1550. || nEnd > ( nLen - nNegSignLen )
  1551. || ( nStart > ( nLen - nNegSignLen )
  1552. && bBackspace
  1553. )
  1554. || ( nStart == nLen
  1555. && nStart == nEnd
  1556. && bBackspace
  1557. )
  1558. )
  1559. && ( m_nNegativeFormatIndex == 3
  1560. || m_nNegativeFormatIndex == 4
  1561. || m_nNegativeFormatIndex == 0
  1562. )
  1563. )
  1564. {
  1565. bNegative = false;
  1566. bNegDel = true;
  1567. }
  1568. }
  1569. _GetTextWithoutMarks( strText, nStart, nEnd );
  1570. if( bBackspace )
  1571. {
  1572. bool bSelect = ( nStart != nEnd ) ? true : false;
  1573. strText.Delete( ( nStart != nEnd ) ? nStart : ( nStart - 1 ), ( nStart != nEnd ) ? ( nEnd - nStart ) : ( bNegDel ? 0 : 1 ) );
  1574. if( ! bSelect && ! bNegDel )
  1575. nStart --;
  1576. m_bBackspace = true;
  1577. }
  1578. else
  1579. {
  1580. INT _nDecimalPointPos = INT( strText.Find( m_strDecimalPoint ) );
  1581. if( _nDecimalPointPos != -1 )
  1582. {
  1583. if( nStart > _nDecimalPointPos 
  1584. && nStart < ( _nDecimalPointPos + nDecimalSeparatorLen )
  1585. )
  1586. nStart = _nDecimalPointPos;
  1587. if( nEnd > _nDecimalPointPos 
  1588. && nEnd < ( _nDecimalPointPos + nDecimalSeparatorLen )
  1589. )
  1590. nEnd = _nDecimalPointPos + nDecimalSeparatorLen;
  1591. }
  1592. strText.Delete( nStart, ( nStart != nEnd ) ? ( nEnd - nStart ) : ( bNegDel ? 0 : 1 ) );
  1593. }
  1594. _GetTextWithoutMarks( strText, nStart, nEnd );
  1595. _GetTextWithMarks( strText, nStart, nEnd, bNegative );
  1596. if( m_bBackspace && ( nStart - nGroupSeparatorLen ) >= 0 )
  1597. {
  1598. INT nGroupSepPos = (INT)strText.Find( m_strGroupSeparator, ( nStart - nGroupSeparatorLen ) );
  1599. if( nGroupSepPos >= 0 )
  1600. {
  1601. INT _nPos = 0, _nGroupSignBeforeStartAfterDelete = 0;
  1602. bool _bChangePos = false;
  1603. INT _nGroupSignCountAfterDelete = (INT)_GetGroupSeparatorCount( strText );
  1604. for( ; true; )
  1605. {
  1606. _nPos = (INT)strText.Find( m_strGroupSeparator, _nPos );
  1607. if( _nPos == -1 )
  1608. break;
  1609. if( _nPos < nStart )
  1610. _nGroupSignBeforeStartAfterDelete ++;
  1611. _nPos ++;
  1612. }
  1613. _nGroupSignBeforeStartAfterDelete = _nGroupSignCountAfterDelete - _nGroupSignBeforeStartAfterDelete;
  1614. if( ( _nGroupSignBeforeStart - 1 ) == _nGroupSignBeforeStartAfterDelete )
  1615. _bChangePos = true;
  1616. if( nGroupSepPos == ( nStart - nGroupSeparatorLen ) && _bChangePos )
  1617. nStart = nGroupSepPos;
  1618. }
  1619. }
  1620. }
  1621. return true;
  1622. }
  1623. void CExtEditSystemNumber::_GetTextWithoutMarks( 
  1624. CExtSafeString & strText, 
  1625. INT & nStart, 
  1626. INT & nEnd, 
  1627. bool bCutDecimalPoint // = false 
  1628. ) const
  1629. {
  1630. ASSERT_VALID( this );
  1631. CExtSafeString strCurrentText;
  1632. INT nStartPos = nStart, nEndPos = nEnd;
  1633. INT nSignCountBeforeStartPos ,nSignCountBeforeEndPos ,nSignCount;
  1634. INT nStrLen = INT( strText.GetLength() );
  1635. INT nDecimalSeparatorLen = INT( m_strDecimalPoint.GetLength() );
  1636. INT nDecimalSeparatorPos = INT( strText.Find( m_strDecimalPoint ) );
  1637. nSignCount = 0;
  1638. if( nEndPos > strText.GetLength() )
  1639. nEndPos = INT( strText.GetLength() );
  1640. nSignCountBeforeStartPos = nSignCountBeforeEndPos = nSignCount = 0;
  1641. for( INT i = 0; i < nStrLen; i++ )
  1642. {
  1643. TCHAR _tchr = strText[i];
  1644. bool bUseSymbol = false;
  1645. if( _T('0') <= _tchr && _tchr <= _T('9') ) //  || ( _tchr == m_strDecimalPoint && ! bCutDecimalPoint ) 
  1646. {
  1647. strCurrentText += _tchr;
  1648. bUseSymbol = true;
  1649. }
  1650. if( i >= nDecimalSeparatorPos && i < ( nDecimalSeparatorPos + nDecimalSeparatorLen ) && ! bCutDecimalPoint && nDecimalSeparatorPos != -1 )
  1651. {
  1652. strCurrentText += _tchr;
  1653. bUseSymbol = true;
  1654. }
  1655. if( ! bUseSymbol )
  1656. nSignCount++;
  1657. if( i == ( nStartPos - 1 ) )
  1658. nSignCountBeforeStartPos = nSignCount;
  1659. else if( i == ( nEndPos - 1 ) )
  1660. nSignCountBeforeEndPos = nSignCount;
  1661. }
  1662. nStartPos -= nSignCountBeforeStartPos;
  1663. nEndPos -= nSignCountBeforeEndPos;
  1664. if( nStartPos < 0 )
  1665. nStartPos = 0;
  1666. if( nEndPos < 0 )
  1667. nEndPos = 0;
  1668. strText = strCurrentText;
  1669. if( nStart != nEnd )
  1670. {
  1671. nStart = nStartPos;
  1672. nEnd = nEndPos;
  1673. }
  1674. else
  1675. nStart = nEnd = nStartPos;
  1676. }
  1677. void CExtEditSystemNumber::_GetTextWithMarks( 
  1678. CExtSafeString & strText, 
  1679. INT & nStart, 
  1680. INT & nEnd, 
  1681. bool bInsertNegSign  // = false
  1682. ) const
  1683. {
  1684. ASSERT_VALID( this );
  1685. if( strText.IsEmpty() )
  1686. return;
  1687. INT nTextLen = INT( strText.GetLength() );
  1688. CExtSafeString strTextChange;
  1689. INT nGroupSeparatorLen = INT( m_strGroupSeparator.GetLength() );
  1690. INT nDecimalSeparatorLen = INT( m_strDecimalPoint.GetLength() );
  1691. INT nPositionDecimalPoint = INT( strText.Find( m_strDecimalPoint ) );
  1692. INT nMaxLen = m_nMaxWholeDigits + m_nMaxFractionDigits + ( ( nPositionDecimalPoint >= 0 ) ? nDecimalSeparatorLen : 0 );
  1693. if( nTextLen > nMaxLen )
  1694. {
  1695. if( nPositionDecimalPoint >= 0 )
  1696. {
  1697. CExtSafeString _strDecimalPoint = _T("");
  1698. _strDecimalPoint = m_strDecimalPoint;
  1699. strText.Replace( _strDecimalPoint, _T("") );
  1700. if( nPositionDecimalPoint > m_nMaxWholeDigits )
  1701. strText.Insert( m_nMaxWholeDigits, m_strDecimalPoint );
  1702. else
  1703. strText.Insert( nPositionDecimalPoint, m_strDecimalPoint );
  1704. }
  1705. nTextLen = INT( strText.GetLength() );
  1706. }
  1707. INT nWholeNumber = ( ( nPositionDecimalPoint >= 0 ) ? ( ( nPositionDecimalPoint < m_nMaxWholeDigits ) ? nPositionDecimalPoint : m_nMaxWholeDigits ) : ( ( m_nMaxWholeDigits >= nTextLen ) ?  nTextLen : m_nMaxWholeDigits ) );
  1708. INT nDecimalPointLen = nDecimalSeparatorLen; // 1
  1709. INT nCorectTextLen = nWholeNumber + nDecimalPointLen + m_nMaxFractionDigits;
  1710. nCorectTextLen = ( nCorectTextLen > nTextLen ) ? nTextLen : nCorectTextLen;
  1711. INT nCountDigitGroups = INT( m_listDigitGrouping.GetCount() );
  1712. CList < INT, INT > _listPos;
  1713. bool bLastZiro = ( m_listDigitGrouping.GetAt( m_listDigitGrouping.FindIndex( nCountDigitGroups - 1 ) ) == 0 ) ? true : false;
  1714. ASSERT( nWholeNumber <= m_nMaxWholeDigits );
  1715. INT nPos = nWholeNumber;
  1716. INT i = 0;
  1717. INT nPreviousCount = -1;
  1718. for( ; true; )
  1719. {
  1720. INT nCount = INT( m_listDigitGrouping.GetAt( m_listDigitGrouping.FindIndex(i) ) );
  1721. if( nCount == 0 && i < ( nCountDigitGroups - 1 ) )
  1722. break;
  1723. if( nCount == 0 && i == ( nCountDigitGroups - 1 ) )
  1724. {
  1725. ASSERT( nPreviousCount != -1 );
  1726. nCount = nPreviousCount;
  1727. }
  1728. nPos -= nCount;
  1729. if( nPos > 0 )
  1730. _listPos.AddHead( nPos - 1 );
  1731. else
  1732. break;
  1733. if( i == ( nCountDigitGroups - 1 ) && ! bLastZiro )
  1734. break;
  1735. if( i < ( nCountDigitGroups - 1 ) )
  1736. i ++;
  1737. nPreviousCount = nCount;
  1738. }
  1739. INT nSignCountBeforeStart = 0;
  1740. INT nSignCountBeforeEnd = 0;
  1741. bool bInsertedDecimalSignBeforeStart = false;
  1742. bool bInsertedDecimalSignBeforeEnd = false;
  1743. INT nCurDigitPos = 0;
  1744. INT nPosCount = INT( _listPos.GetCount() );
  1745. bool bCanPastGroupSep = ( nPosCount > 0 );
  1746. for( i = 0; i < nCorectTextLen; i++ )
  1747. {
  1748. TCHAR _tchr = strText[i];
  1749. strTextChange += _tchr;
  1750. bool bInsertSign = false;
  1751. INT nPosCur = 0;
  1752. if( bCanPastGroupSep )
  1753. nPosCur = _listPos.GetAt( _listPos.FindIndex( nCurDigitPos ) );
  1754. if( ( i <= nWholeNumber )
  1755. && ( i != ( nCorectTextLen - 1 ) )
  1756. && ( i == nPosCur )
  1757. && bCanPastGroupSep
  1758. )
  1759. {
  1760. strTextChange += m_strGroupSeparator;
  1761. bInsertSign = true;
  1762. if( nCurDigitPos < ( nPosCount - 1 ) )
  1763. nCurDigitPos ++;
  1764. else
  1765. bCanPastGroupSep = false;
  1766. }
  1767. if( i == ( nWholeNumber - 1 ) && ( nPositionDecimalPoint == -1 ) && ( i != nCorectTextLen - 1 ) )
  1768. {
  1769. strTextChange += m_strDecimalPoint;
  1770. if( i < ( nStart - 1 ) )
  1771. bInsertedDecimalSignBeforeStart  = true;
  1772. if( i < ( nEnd - 1 ) )
  1773. bInsertedDecimalSignBeforeEnd = true;
  1774. }
  1775. if( bInsertSign )
  1776. {
  1777. if( i < nStart )
  1778. nSignCountBeforeStart ++;
  1779. if( i < nEnd )
  1780. nSignCountBeforeEnd ++;
  1781. }
  1782. }
  1783. if( bInsertNegSign && AllowNegativeGet() )
  1784. {
  1785. INT nNegSignLen = INT( m_strNegativeSign.GetLength() ) + ( ( m_nNegativeFormatIndex == 2 || m_nNegativeFormatIndex == 4 ) ? 1: 0 );
  1786. CExtSafeString _strNegativeSign = ( (m_nNegativeFormatIndex == 4) ? _T(" "): _T("") ) + m_strNegativeSign + ( (m_nNegativeFormatIndex == 2) ? _T(" "): _T("") );
  1787. if( m_nNegativeFormatIndex == 0 )
  1788. {
  1789. strTextChange.Insert( strTextChange.GetLength(), _T(")") );
  1790. strTextChange.Insert( 0, _T("(") );
  1791. nStart += 1;
  1792. nEnd += 1;
  1793. }
  1794. if( m_nNegativeFormatIndex == 1 || m_nNegativeFormatIndex == 2 )
  1795. strTextChange.Insert( 0, _strNegativeSign );
  1796. if( m_nNegativeFormatIndex == 3 || m_nNegativeFormatIndex == 4 )
  1797. strTextChange.Insert( strTextChange.GetLength(), _strNegativeSign );
  1798. if( m_nNegativeFormatIndex == 1 || m_nNegativeFormatIndex == 2 )
  1799. {
  1800. nStart += nNegSignLen;
  1801. nEnd += nNegSignLen;
  1802. }
  1803. }
  1804. strText = strTextChange;
  1805. nStart += nGroupSeparatorLen * nSignCountBeforeStart + ( bInsertedDecimalSignBeforeStart ? nDecimalSeparatorLen : 0 );
  1806. nEnd += nGroupSeparatorLen * nSignCountBeforeEnd + ( bInsertedDecimalSignBeforeEnd ? nDecimalSeparatorLen : 0 );
  1807. }
  1808. bool CExtEditSystemNumber::_IsNegative( __EXT_MFC_SAFE_LPCTSTR strText ) const
  1809. {
  1810. ASSERT_VALID( this );
  1811. CExtSafeString _strText = strText;
  1812. bool bRetVal = ( ( _strText.Find( m_strNegativeSign ) >= 0 ) ? true: false );
  1813. if( m_nNegativeFormatIndex == 0 )
  1814. bRetVal = ( ( _strText.Find( _T('(') ) >= 0 ) ? true: false );
  1815. return bRetVal;
  1816. }
  1817. void CExtEditSystemNumber::_AdjustWithinRange()
  1818. {
  1819. ASSERT_VALID( this );
  1820. if( m_bRichPainting )
  1821. return;
  1822. if( _IsValid() )
  1823. return;
  1824. if( TextGet().IsEmpty() )
  1825. SetWindowText( _T(" ") );
  1826. else
  1827. _Redraw();
  1828. long double dValue = LongDoubleGet();
  1829.     if( dValue < m_lfMin )
  1830. LongDoubleSet( m_lfMin );
  1831.     else if( dValue > m_lfMax )
  1832. LongDoubleSet( m_lfMax );
  1833. CExtSafeString _strText = TextGet();
  1834. bool bNegative = _IsNegative( _strText );
  1835. INT nNegSignPos = -1;
  1836. INT nLen = INT( _strText.GetLength() );
  1837. if( bNegative )
  1838. {
  1839. switch( m_nNegativeFormatIndex )
  1840. {
  1841. case 0:
  1842. nNegSignPos = INT( _strText.Find( _T(")") ) );
  1843. break;
  1844. case 3:
  1845. nNegSignPos = INT( _strText.Find( m_strNegativeSign ) );
  1846. break;
  1847. case 4:
  1848. nNegSignPos = INT( _strText.Find( _T(" ") + m_strNegativeSign ) );
  1849. break;
  1850. }
  1851. }
  1852. _Rich_OnDraw();
  1853. if( ! m_bRichPainting )
  1854. {
  1855. if( nNegSignPos >= 0 )
  1856. SetSel( nNegSignPos, nNegSignPos );
  1857. else
  1858. SetSel( nLen, nLen );
  1859. }
  1860. }
  1861. void CExtEditSystemNumber::_Rich_OnDraw()
  1862. {
  1863. ASSERT_VALID( this );
  1864. if( ! m_bRichMode )
  1865. return;
  1866. if( GetSafeHwnd() == NULL )
  1867. return;
  1868. if( m_bRichPainting )
  1869. return;
  1870. m_bRichPainting = true;
  1871. CHARRANGE crRestore;
  1872. Rich_GetSel( crRestore );
  1873. CHARFORMAT cfDefault;
  1874. ::memset( &cfDefault, 0, sizeof(CHARFORMAT) );
  1875. cfDefault.dwMask = CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_PROTECTED|CFM_COLOR;
  1876. cfDefault.dwEffects = CFE_PROTECTED; 
  1877. //cfDefault.yHeight = 180;
  1878. //cfDefault.crTextColor = ::GetSysColor( COLOR_WINDOWTEXT );
  1879. CFont * pFont = GetFont();
  1880. if( pFont->GetSafeHandle() == NULL )
  1881. {
  1882. CWnd * pWndParent = GetParent();
  1883. if( pWndParent->GetSafeHwnd() != NULL )
  1884. pFont = pWndParent->GetFont();
  1885. if( pFont->GetSafeHandle() == NULL )
  1886. pFont = &(PmBridge_GetPM()->m_FontNormal);
  1887. }
  1888. LOGFONT _lf; ::memset( &_lf, 0, sizeof(LOGFONT) );
  1889. pFont->GetLogFont( &_lf );
  1890. #if (! defined _RICHEDIT_VER )
  1891. USES_CONVERSION;
  1892. strcpy( cfDefault.szFaceName, T2CA(_lf.lfFaceName) );
  1893. #else
  1894. #if ( _RICHEDIT_VER < 0x0200 )
  1895. USES_CONVERSION;
  1896. strcpy( cfDefault.szFaceName, T2CA(_lf.lfFaceName) );
  1897. #else
  1898. __EXT_MFC_STRCPY( cfDefault.szFaceName, sizeof(cfDefault.szFaceName)/sizeof(cfDefault.szFaceName[0]), _lf.lfFaceName );
  1899. #endif
  1900. #endif
  1901. CWindowDC dcDesktop( NULL );
  1902. cfDefault.yHeight = ::MulDiv( _lf.lfHeight, 72 * 20, dcDesktop.GetDeviceCaps( LOGPIXELSY ) );
  1903. cfDefault.yHeight = abs( cfDefault.yHeight );
  1904. bool bEnabled = IsWindowEnabled() ? true : false, bReadOnly = ( ( GetStyle() & ES_READONLY ) != 0 );
  1905. cfDefault.crTextColor = OnQueryTextColor();
  1906. if( cfDefault.crTextColor == COLORREF(-1L) )
  1907. {
  1908. cfDefault.crTextColor = bEnabled ? ( bReadOnly ? m_clrRichTextReadOnly : m_clrRichTextNormal ) : m_clrRichTextDisabled;
  1909. if( cfDefault.crTextColor == COLORREF(-1L) )
  1910. {
  1911. if( bEnabled )
  1912. {
  1913. if( bReadOnly )
  1914. cfDefault.crTextColor = ::GetSysColor( COLOR_3DSHADOW );
  1915. else
  1916. cfDefault.crTextColor = ::GetSysColor( COLOR_WINDOWTEXT );
  1917. }
  1918. else
  1919. cfDefault.crTextColor = ::GetSysColor( COLOR_GRAYTEXT );
  1920. }
  1921. }
  1922. COLORREF clrBack = OnQueryBackColor();
  1923. if( clrBack == COLORREF(-1L) )
  1924. {
  1925. clrBack = bEnabled ? ( bReadOnly ? m_clrRichBackReadOnly : m_clrRichBackNormal ) : m_clrRichBackDisabled;
  1926. if( clrBack == COLORREF(-1L) )
  1927. {
  1928. if( bEnabled )
  1929. {
  1930. if( bReadOnly )
  1931. clrBack = ::GetSysColor( COLOR_3DFACE );
  1932. else
  1933. clrBack = ::GetSysColor( COLOR_WINDOW );
  1934. }
  1935. else
  1936. clrBack = ::GetSysColor( COLOR_3DFACE );
  1937. }
  1938. }
  1939. Rich_SetBackgroundColor( FALSE, clrBack );
  1940. Rich_HideSelection( true, false );
  1941. Rich_SetSel( 0, -1 ); 
  1942. SendMessage( EM_SETCHARFORMAT, SCF_DEFAULT, LPARAM(&cfDefault) );
  1943. SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(&cfDefault) );
  1944. Rich_SetSelectionColor( cfDefault.crTextColor );
  1945. INT nGroupSeparatorLen = INT( m_strGroupSeparator.GetLength() );
  1946. INT nDecimalSignLen = INT( m_strDecimalPoint.GetLength() );
  1947. COLORREF clrSign = m_clrSign;
  1948. if( clrSign == COLORREF(-1L) )
  1949. clrSign = cfDefault.crTextColor;
  1950. if( m_clrNumber != COLORREF(-1L)
  1951. || m_clrFraction != COLORREF(-1L)
  1952. || m_clrGroupSeparator != COLORREF(-1L)
  1953. || m_clrDecimalSeparator != COLORREF(-1L)
  1954. || m_clrBrackets != COLORREF(-1L)
  1955. || clrSign != COLORREF(-1L)
  1956. )
  1957. {
  1958. CExtSafeString strText = TextGet();
  1959. INT nTextLen = INT( strText.GetLength() );
  1960. if( nTextLen > 0 )
  1961. {
  1962. bool bNegative = _IsNegative( strText );
  1963. INT nPositionDecimalPoint = INT( strText.Find( m_strDecimalPoint ) );
  1964. CExtSafeString _strBefore = _T(""), _strAfter = _T("");
  1965. if( bNegative )
  1966. {
  1967. switch( m_nNegativeFormatIndex )
  1968. {
  1969. case 0:
  1970. _strBefore = _T("(");
  1971. _strAfter = _T(")");
  1972. break;
  1973. case 1:
  1974. _strBefore = m_strNegativeSign;
  1975. break;
  1976. case 2:
  1977. _strBefore = m_strNegativeSign + _T(" ");
  1978. break;
  1979. case 3:
  1980. _strAfter = m_strNegativeSign;
  1981. break;
  1982. case 4:
  1983. _strAfter = _T(" ") + m_strNegativeSign;
  1984. break;
  1985. }
  1986. }
  1987. INT nBeforLen = _strBefore.GetLength();
  1988. INT nAfterLen = _strAfter.GetLength();
  1989. // Whole number
  1990. if( m_clrNumber != COLORREF(-1L) )
  1991. {
  1992. Rich_SetSel( nBeforLen, ( nPositionDecimalPoint != -1 ) ? nPositionDecimalPoint : ( nTextLen - nAfterLen ) );
  1993. Rich_SetSelectionColor( m_clrNumber );
  1994. }
  1995. if( nPositionDecimalPoint != -1 )
  1996. {
  1997. if( m_clrDecimalSeparator != COLORREF(-1L) )
  1998. {
  1999. Rich_SetSel( nPositionDecimalPoint, ( nPositionDecimalPoint + nDecimalSignLen ) );
  2000. Rich_SetSelectionColor( m_clrDecimalSeparator );
  2001. }
  2002. if( m_clrFraction != COLORREF(-1L) )
  2003. {
  2004. Rich_SetSel( nPositionDecimalPoint + nDecimalSignLen, nTextLen - nAfterLen );
  2005. Rich_SetSelectionColor( m_clrFraction );
  2006. }
  2007. }
  2008. if( m_clrGroupSeparator != COLORREF(-1L) )
  2009. {
  2010. INT nPos = 0;
  2011. for( ; true; )
  2012. {
  2013. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  2014. if( nPos == -1 )
  2015. break;
  2016. Rich_SetSel( nPos, ( nPos + nGroupSeparatorLen ) );
  2017. Rich_SetSelectionColor( m_clrGroupSeparator );
  2018. nPos ++;
  2019. }
  2020. }
  2021. if( bNegative && clrSign != COLORREF(-1L) )
  2022. {
  2023. if( ( _strAfter.IsEmpty() || _strBefore.IsEmpty() )
  2024. && ( ! _strAfter.IsEmpty() || !_strBefore.IsEmpty() )
  2025. )
  2026. {
  2027. INT nNegSignPos = INT( strText.Find( m_strNegativeSign ) );
  2028. INT nNegSignLen = INT( m_strNegativeSign.GetLength() );
  2029. if( clrSign != COLORREF(-1L) )
  2030. {
  2031. Rich_SetSel( nNegSignPos, ( nNegSignPos + nNegSignLen ) );
  2032. Rich_SetSelectionColor( clrSign );
  2033. }
  2034. }
  2035. if( ! _strAfter.IsEmpty() && ! _strBefore.IsEmpty() )
  2036. {
  2037. if( m_clrBrackets != COLORREF(-1L) )
  2038. {
  2039. INT i, nPos = 0;
  2040. CString _strBrackets = _T("()[]{}");
  2041. INT nBrackLen = _strBrackets.GetLength();
  2042. for( i = 0; i < nBrackLen; i++ )
  2043. {
  2044. nPos = 0;
  2045. for( ; true; )
  2046. {
  2047. nPos = strText.Find( _strBrackets[i], nPos );
  2048. if( nPos == -1 )
  2049. break;
  2050. Rich_SetSel( nPos, ( nPos + 1 ) );
  2051. Rich_SetSelectionColor( m_clrBrackets ); 
  2052. nPos ++;
  2053. }
  2054. }
  2055. }
  2056. }
  2057. }
  2058. } // if( nTextLen > 0 )
  2059. }
  2060. Rich_SetSel( crRestore );
  2061. Rich_HideSelection( false, false );
  2062. m_bRichPainting = false;
  2063. }
  2064. /////////////////////////////////////////////////////////////////////////////
  2065. // CExtEditSystemCurrency window
  2066. IMPLEMENT_DYNCREATE( CExtEditSystemCurrency, CExtEditSystemNumberCurrencyBase );
  2067. CExtEditSystemCurrency::CExtEditSystemCurrency(
  2068. INT nMaxWholeDigits, // = __EXT_MFC_DEFAULT_MAX_WHOLE_DIGITS
  2069. INT nMaxFractionDigits // = __EXT_MFC_DEFAULT_FRACTION_WHOLE_DIGITS
  2070. )
  2071. : CExtEditSystemNumberCurrencyBase( nMaxWholeDigits, nMaxFractionDigits )
  2072. {
  2073. _Init();
  2074. }
  2075. CExtEditSystemCurrency::~CExtEditSystemCurrency()
  2076. {
  2077. }
  2078. BEGIN_MESSAGE_MAP( CExtEditSystemCurrency, CExtEditSystemNumberCurrencyBase )
  2079. //{{AFX_MSG_MAP(CExtEditSystemNumberCurrencyBase)
  2080. //}}AFX_MSG_MAP
  2081. __EXT_MFC_SAFE_ON_WM_SETTINGCHANGE()
  2082. END_MESSAGE_MAP()
  2083. void CExtEditSystemCurrency::_Init()
  2084. {
  2085. ASSERT_VALID( this );
  2086. // negative sign
  2087. if( g_ResourceManager->GetLocaleInfo( LOCALE_SNEGATIVESIGN, NULL, 0 ) )
  2088. {
  2089. g_ResourceManager->GetLocaleInfo( LOCALE_SNEGATIVESIGN, m_strNegativeSign.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  2090. m_strNegativeSign.ReleaseBuffer();
  2091. }
  2092. if( g_ResourceManager->GetLocaleInfo( LOCALE_SCURRENCY, NULL, 0 ) )
  2093. {
  2094. g_ResourceManager->GetLocaleInfo( LOCALE_SCURRENCY, m_strCurrencySymbol.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  2095. m_strCurrencySymbol.ReleaseBuffer();
  2096. }
  2097. // decimal point
  2098. if( g_ResourceManager->GetLocaleInfo( LOCALE_SMONDECIMALSEP, NULL, 0 ) )
  2099. {
  2100. g_ResourceManager->GetLocaleInfo( LOCALE_SMONDECIMALSEP, m_strDecimalPoint.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  2101. m_strDecimalPoint.ReleaseBuffer();
  2102. }
  2103. // group separator
  2104. if( g_ResourceManager->GetLocaleInfo( LOCALE_SMONTHOUSANDSEP, NULL, 0 ) )
  2105. {
  2106. g_ResourceManager->GetLocaleInfo( LOCALE_SMONTHOUSANDSEP, m_strGroupSeparator.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  2107. m_strGroupSeparator.ReleaseBuffer();
  2108. }
  2109. TCHAR cPosCurFormatIndex = _T('0');
  2110. if( g_ResourceManager->GetLocaleInfo( LOCALE_ICURRENCY, NULL, 0 ) )
  2111. g_ResourceManager->GetLocaleInfo( LOCALE_ICURRENCY, &cPosCurFormatIndex, sizeof( cPosCurFormatIndex ) / sizeof(TCHAR) );
  2112. m_nPositiveFormatIndex = _ttoi( & cPosCurFormatIndex );
  2113. CExtSafeString strNegCurFormatIndex = _T("0");
  2114. if( g_ResourceManager->GetLocaleInfo( LOCALE_INEGCURR, NULL, 0 ) )
  2115. {
  2116. g_ResourceManager->GetLocaleInfo( LOCALE_INEGCURR, strNegCurFormatIndex.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  2117. strNegCurFormatIndex.ReleaseBuffer();
  2118. }
  2119. CExtSafeString strDigitGrouping = _T("0");
  2120. if( g_ResourceManager->GetLocaleInfo( LOCALE_SMONGROUPING, NULL, 0 ) )
  2121. {
  2122. g_ResourceManager->GetLocaleInfo( LOCALE_SMONGROUPING, strDigitGrouping.GetBuffer( _MAX_PATH + 1 ), _MAX_PATH );
  2123. strDigitGrouping.ReleaseBuffer();
  2124. INT nStrLen = INT( strDigitGrouping.GetLength() );
  2125. CExtSafeString _strGroup = _T("");
  2126. INT nGroup = 0;
  2127. if( m_listDigitGrouping.GetCount() > 0 )
  2128. m_listDigitGrouping.RemoveAll();
  2129. for( INT i = 0; i < nStrLen; i++ )
  2130. {
  2131. TCHAR ch = strDigitGrouping[i];
  2132. if( ch == _T(';') )
  2133. {
  2134. nGroup = _ttoi( _strGroup );
  2135. m_listDigitGrouping.AddTail( nGroup );
  2136. _strGroup = _T("");
  2137. nGroup = 0;
  2138. }
  2139. else
  2140. _strGroup = _strGroup + ch;
  2141. }
  2142. nGroup = _ttoi( _strGroup );
  2143. m_listDigitGrouping.AddTail( nGroup );
  2144. }
  2145. m_nNegativeFormatIndex = _ttoi( strNegCurFormatIndex );
  2146. TCHAR cNoOfDigitsAfterDecimal = _T('0');
  2147. if( g_ResourceManager->GetLocaleInfo( LOCALE_ICURRDIGITS, NULL, 0 ) )
  2148. g_ResourceManager->GetLocaleInfo( LOCALE_ICURRDIGITS, &cNoOfDigitsAfterDecimal, sizeof( cNoOfDigitsAfterDecimal ) / sizeof(TCHAR) );
  2149. m_nMaxFractionDigits = _ttoi( & cNoOfDigitsAfterDecimal );
  2150. TCHAR cDisplayLeadingZeros = _T('0');
  2151. if( g_ResourceManager->GetLocaleInfo( LOCALE_ILZERO, NULL, 0 ) )
  2152. g_ResourceManager->GetLocaleInfo( LOCALE_ILZERO, &cDisplayLeadingZeros, sizeof( cDisplayLeadingZeros ) / sizeof(TCHAR) );
  2153. m_nDisplayLeadingZeros = _ttoi( & cDisplayLeadingZeros );
  2154. TCHAR cDigitGrouping[20] = _T("");
  2155. if( g_ResourceManager->GetLocaleInfo( LOCALE_SGROUPING, NULL, 0 ) )
  2156. g_ResourceManager->GetLocaleInfo( LOCALE_SGROUPING, cDigitGrouping, sizeof( cDigitGrouping ) / sizeof( cDigitGrouping[0] ) );
  2157. // ensure the separators are not the same
  2158. if( m_strDecimalPoint == m_strGroupSeparator )
  2159. m_strGroupSeparator = ( m_strDecimalPoint == _T(",") ? _T(".") : _T(",") );
  2160. }
  2161. void CExtEditSystemCurrency::OnSettingChange( UINT uFlags, __EXT_MFC_SAFE_LPCTSTR lpszSection )
  2162. {
  2163. ASSERT_VALID( this );
  2164. CExtEditSystemNumberCurrencyBase::OnSettingChange( uFlags, lpszSection );
  2165. if( _tcscmp( lpszSection, _T("intl") ) == 0 )
  2166. {
  2167. long double lfSaved = LongDoubleGet();
  2168. _Init();
  2169. LongDoubleSet( lfSaved );
  2170. SetSel( -1, -1 );
  2171. }
  2172. }
  2173. CExtSafeString CExtEditSystemCurrency::_GetNumericText(
  2174. const CExtSafeString & strText, 
  2175. bool bUseMathSymbols // = false
  2176. ) const
  2177. {
  2178. ASSERT_VALID( this );
  2179. CExtSafeString strNewText;
  2180. bool bIsNegative = _IsNegative( strText );
  2181. bool bHasDecimalPoint = false;
  2182. INT nDecimalSignLen = INT( m_strDecimalPoint.GetLength() );
  2183. INT nDecimalSignPos = INT( strText.Find( m_strDecimalPoint ) );
  2184. INT nPos, nLen;
  2185. for( nPos = 0, nLen = INT( strText.GetLength() ); nPos < nLen; nPos++ )
  2186. {
  2187. TCHAR c = strText[nPos];
  2188. if( _istdigit(c) )
  2189. strNewText += c;
  2190. else if( nPos == nDecimalSignPos && !bHasDecimalPoint )
  2191. {
  2192. bHasDecimalPoint = true;
  2193. strNewText += ( bUseMathSymbols ? _T(".") : m_strDecimalPoint );
  2194. nPos += nDecimalSignLen - 1;
  2195. }
  2196. }
  2197. if( bUseMathSymbols )
  2198. {
  2199. if( bIsNegative )
  2200. strNewText.Insert( 0, _T("-") );
  2201. }
  2202. else
  2203. {
  2204. CExtSafeString _strBefore = _T("");
  2205. CExtSafeString _strAfter = _T("");
  2206. _GetSignStrings( _strBefore, _strAfter, bIsNegative && AllowNegativeGet() );
  2207. if( ! _strAfter.IsEmpty() )
  2208. strNewText.Insert( strNewText.GetLength(), _strAfter );
  2209. if( ! _strBefore.IsEmpty() )
  2210. strNewText.Insert( 0, _strBefore );
  2211. }
  2212. return strNewText;
  2213. }
  2214. CExtSafeString CExtEditSystemCurrency::_GetDoubleText( long double lfValue, bool bTrimTrailingZeros /*= true*/ ) const
  2215. {
  2216. ASSERT_VALID( this );
  2217. CExtSafeString strText;
  2218. strText.Format( _T("%lf"), lfValue );
  2219. if( m_strDecimalPoint != _T(".") )
  2220. strText.Replace( _T("."), m_strDecimalPoint );
  2221. if( bTrimTrailingZeros )
  2222. {
  2223. strText.TrimRight( _T("0") );
  2224. strText.TrimRight( m_strDecimalPoint );
  2225. }
  2226. bool bNegative = ( strText.Find( _T("-") ) == 0 ) ? true : false;
  2227. if( bNegative )
  2228. strText.Delete( 0 );
  2229. CExtSafeString _strBefore = _T("");
  2230. CExtSafeString _strAfter = _T("");
  2231. _GetSignStrings( _strBefore, _strAfter, bNegative && AllowNegativeGet() );
  2232. INT nLen = INT( strText.GetLength() );
  2233. if( ! _strAfter.IsEmpty() )
  2234. strText.Insert( nLen, _strAfter );
  2235. if( ! _strBefore.IsEmpty() )
  2236. strText.Insert( 0, _strBefore );
  2237. return strText;
  2238. }
  2239. void CExtEditSystemCurrency::IntSet( INT nVal )
  2240. {
  2241. ASSERT_VALID( this );
  2242. CExtSafeString strText;
  2243. strText.Format( _T("%d"), nVal );
  2244. bool bNegative = ( strText.Find( _T("-") ) == 0 ) ? true : false;
  2245. strText.Delete( 0 );
  2246. CExtSafeString _strBefore = _T("");
  2247. CExtSafeString _strAfter = _T("");
  2248. _GetSignStrings( _strBefore, _strAfter, bNegative && AllowNegativeGet() );
  2249. INT nLen = INT( strText.GetLength() );
  2250. if( ! _strAfter.IsEmpty() )
  2251. strText.Insert( nLen, _strAfter );
  2252. if( ! _strBefore.IsEmpty() )
  2253. strText.Insert( 0, _strBefore );
  2254. m_pEditWithBehaviorWnd->SetWindowText(strText);
  2255. }
  2256. long double CExtEditSystemCurrency::LongDoubleGet() const
  2257. {
  2258. ASSERT_VALID( this );
  2259. // return _tcstod( _GetNumericText( m_pEditWithBehaviorWnd->TextGet(), true ), NULL );
  2260. CExtSafeString str = _GetNumericText( m_pEditWithBehaviorWnd->TextGet(), true );
  2261. if( str.IsEmpty()
  2262.    || str == _T(".")
  2263.    || str == LPCTSTR(m_strDecimalPoint)
  2264.    || ( str.GetLength() == 1 && m_strDecimalPoint.GetLength() > 0 && str[0] == m_strDecimalPoint[0] )
  2265.    )
  2266.    return 0.0;
  2267. LCID _LCID = LANG_USER_DEFAULT;
  2268. if( g_ResourceManager->IsCustomLangAllowed() )
  2269. _LCID = g_ResourceManager->GetLangIdDesired();
  2270. COleCurrency _oleCurrency;
  2271. VERIFY( _oleCurrency.ParseCurrency( LPCTSTR(str), 0, _LCID ) );
  2272. long double lfVal = ((long double)_oleCurrency.m_cur.int64) / ((long double)10000.0);
  2273. return lfVal;
  2274. }
  2275. INT CExtEditSystemCurrency::IntGet() const
  2276. {
  2277. ASSERT_VALID( this );
  2278. // return (INT)_ttoi( _GetNumericText( m_pEditWithBehaviorWnd->TextGet() ) );
  2279. CExtSafeString str = _GetNumericText( m_pEditWithBehaviorWnd->TextGet(), true );
  2280. if( str.IsEmpty() )
  2281. return 0;
  2282. LCID _LCID = LANG_USER_DEFAULT;
  2283. if( g_ResourceManager->IsCustomLangAllowed() )
  2284. _LCID = g_ResourceManager->GetLangIdDesired();
  2285. COleCurrency _oleCurrency;
  2286. VERIFY( _oleCurrency.ParseCurrency( LPCTSTR(str), 0, _LCID ) );
  2287. __int64 nVal = ((__int64)_oleCurrency.m_cur.int64) / ((__int64)10000);
  2288. return INT(nVal);
  2289. }
  2290. CExtSafeString CExtEditSystemCurrency::Behavior_GetValidText(
  2291. bool bSetSel // = false
  2292. ) const
  2293. {
  2294. ASSERT_VALID( this );
  2295. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  2296. CExtSafeString strNewText = strText;
  2297. bool bIsNegative = _IsNegative( strText );
  2298. INT nStart, nEnd;
  2299. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  2300. _GetTextWithoutMarks( strNewText, nStart, nEnd );
  2301. _GetTextWithMarks( strNewText, nStart, nEnd, ( bIsNegative && AllowNegativeGet() ) );
  2302. if( bSetSel && ( ! m_bRichPainting ) )
  2303. {
  2304. CExtSafeString strCurrentText = m_pEditWithBehaviorWnd->TextGet();
  2305. if( strNewText != strCurrentText )
  2306. m_pEditWithBehaviorWnd->SetWindowText( strNewText );
  2307. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2308. }
  2309. return strNewText;
  2310. }
  2311. void CExtEditSystemCurrency::Behavior_OnChar( UINT uChar, UINT nRepCnt, UINT nFlags )
  2312. {
  2313. ASSERT_VALID( this );
  2314. if( m_pEditWithBehaviorWnd->GetStyle() & ES_READONLY )
  2315. return;
  2316. TCHAR c = static_cast<TCHAR>( uChar );
  2317. INT nStart, nEnd;
  2318. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  2319. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  2320. CExtSafeString strNumericText = _GetNumericText( strText );
  2321. INT nDecimalPos = INT( strText.Find( m_strDecimalPoint ) );
  2322. INT nNumericDecimalPos = INT( strNumericText.Find( m_strDecimalPoint ) );
  2323. INT nLen = INT( strText.GetLength() );
  2324. INT nNumericLen = INT( strNumericText.GetLength() );
  2325. INT nSepCount = _GetGroupSeparatorCount( strText );
  2326. bool bNeedAdjustment = false;
  2327. bool bIsNegative = false;
  2328. bool bIsDecimalPoint = false;
  2329. if( ( c == m_strNegativeSign[0] )
  2330. || ( ( m_nNegativeFormatIndex == 0
  2331. || m_nNegativeFormatIndex == 4
  2332. || m_nNegativeFormatIndex == 14
  2333. || m_nNegativeFormatIndex == 15
  2334. )
  2335. && c == _T('(') 
  2336. )
  2337. || ( c == _T('-') )
  2338. )
  2339. {
  2340. bIsNegative = true;
  2341. }
  2342. // test whether it is a negative sign
  2343. if( bIsNegative && AllowNegativeGet() )
  2344. {
  2345. bool bNegative = _IsNegative( strText );
  2346. CExtSafeString _strBefore = _T(""), _strAfter = _T("");
  2347. _GetSignStrings( _strBefore, _strAfter, bNegative );
  2348. INT nBeforLen = INT( _strBefore.GetLength() );
  2349. INT nAfterLen = INT( _strAfter.GetLength() );
  2350. CExtSafeString strNewText = strText;
  2351. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  2352. if( nStart < nBeforLen )
  2353. nStart = nBeforLen;
  2354. if( nEnd > ( nLen - nAfterLen ) )
  2355. nEnd = ( nLen - nAfterLen );
  2356. _GetTextWithoutMarks( strNewText, nStart, nEnd );
  2357. _GetTextWithMarks( strNewText, nStart, nEnd, ! bNegative );
  2358. CExtSafeString strCurrentText = m_pEditWithBehaviorWnd->TextGet();
  2359. if( strNewText != strCurrentText )
  2360. m_pEditWithBehaviorWnd->SetWindowText( strNewText );
  2361. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2362. return;
  2363. }
  2364. // test whether it is a decimal point (only one is enabled)
  2365. else if( c == m_strDecimalPoint[0] && m_nMaxFractionDigits > 0 )
  2366. {
  2367. if( nDecimalPos >= 0 )
  2368. {
  2369. // test decimal point replacement
  2370. if( nDecimalPos >= nStart && nDecimalPos < nEnd )
  2371. {
  2372. bNeedAdjustment = true;
  2373. bIsDecimalPoint = true;
  2374. }
  2375. else
  2376. { // else set caret
  2377. m_pEditWithBehaviorWnd->SetSel( nDecimalPos + m_strDecimalPoint.GetLength(), nDecimalPos + m_strDecimalPoint.GetLength() );
  2378. //m_pEditWithBehaviorWnd->SetSel( nDecimalPos + 1, nDecimalPos + 1 );
  2379. return;
  2380. }
  2381. }
  2382. else
  2383. {
  2384. bNeedAdjustment = true;
  2385. bIsDecimalPoint = true;
  2386. }
  2387. }
  2388. // test if it's a digit
  2389. else if( _istdigit(c) )
  2390. {
  2391. // test whether we're on the right of the decimal point
  2392. if( nDecimalPos >= 0 && nDecimalPos < nStart )
  2393. {
  2394. bool bIsNegative = _IsNegative( strNumericText );
  2395. CExtSafeString _strBeforeCurrency = _T("");
  2396. CExtSafeString _strAfterCurrency = _T("");
  2397. _GetSignStrings( _strBeforeCurrency, _strAfterCurrency, bIsNegative && AllowNegativeGet() );
  2398. INT nNegLength = INT( _strAfterCurrency.GetLength() );
  2399. if( ! _strAfterCurrency.IsEmpty() )
  2400. {
  2401. INT nNegSignPos = -1;
  2402. if( ! _strAfterCurrency.IsEmpty() )
  2403. nNegSignPos = INT( strText.Find( _strAfterCurrency ) );
  2404. if( ( nStart > nNegSignPos ) && ( nStart <= nLen ) && nNegSignPos != -1 )
  2405. {
  2406. nStart = nNegSignPos;
  2407. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  2408. }
  2409. }
  2410. INT nDecimalSeparatorLen = INT( m_strDecimalPoint.GetLength() );
  2411. if( nDecimalPos <= nStart && nStart < ( nDecimalPos + nDecimalSeparatorLen ) )
  2412. {
  2413. INT nPrevStart = nStart;
  2414. nStart = ( nDecimalPos + nDecimalSeparatorLen );
  2415. if( nEnd == nPrevStart 
  2416. || nEnd < nPrevStart 
  2417. || ( nEnd > nPrevStart 
  2418. && nEnd < nStart
  2419. )
  2420. )
  2421. nEnd = nStart;
  2422. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2423. }
  2424. if( strNumericText.Mid( /*nDecimalPos */nNumericDecimalPos + nDecimalSeparatorLen ).GetLength() == ( m_nMaxFractionDigits + nNegLength ) )
  2425. {
  2426. if( nStart <= ( nDecimalPos + m_nMaxFractionDigits + nDecimalSeparatorLen - 1 ) )
  2427. {
  2428. //nEnd = ( ( ( nEnd == nLen ) || ( nEnd > nStart ) ) ? nEnd : (nStart + 1) );
  2429. nEnd = ( ( ( nEnd == nLen ) || ( nEnd > ( nStart + 1 ) ) ) ? nEnd : (nStart + 1) );
  2430. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2431. m_pEditWithBehaviorWnd->ReplaceSel( CExtSafeString(c), TRUE );
  2432. }
  2433. return;
  2434. }
  2435. else if( strNumericText.Mid( nNumericDecimalPos + nDecimalSeparatorLen ).GetLength() > ( m_nMaxFractionDigits + nNegLength ) )
  2436. {
  2437. ASSERT(false);
  2438. return;
  2439. }
  2440. }
  2441. // we're on the left side of the decimal point
  2442. else
  2443. {
  2444. bool bIsNegative = _IsNegative( strNumericText );
  2445. CExtSafeString _strBeforeCurrency = _T("");
  2446. CExtSafeString _strAfterCurrency = _T("");
  2447. _GetSignStrings( _strBeforeCurrency, _strAfterCurrency, bIsNegative && AllowNegativeGet() );
  2448. INT nNegLength = INT( _strBeforeCurrency.GetLength() );
  2449. INT nAfterSignsLength = INT( _strAfterCurrency.GetLength() );
  2450. if( nNegLength > 0 )
  2451. {
  2452. if( ( nStart >= 0 ) && ( nStart < nNegLength ) )
  2453. {
  2454. nStart = nNegLength;
  2455. if( nStart > nEnd )
  2456. nEnd = nStart;
  2457. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2458. }
  2459. }
  2460. if( nAfterSignsLength > 0 )
  2461. {
  2462. if( ( nEnd >= ( nLen - nAfterSignsLength ) ) && ( nEnd <= nLen ) )
  2463. {
  2464. nEnd = nLen - nAfterSignsLength;
  2465. if( nStart > nEnd )
  2466. nStart = nEnd;
  2467. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2468. }
  2469. if( ( nStart >= ( nLen - nAfterSignsLength ) ) && ( nStart <= nLen ) )
  2470. {
  2471. nStart = nLen - nAfterSignsLength;
  2472. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  2473. }
  2474. }
  2475. INT nGroupSeparatorLen = INT( m_strGroupSeparator.GetLength() );
  2476. INT nDecimalSignLen = INT( m_strDecimalPoint.GetLength() );
  2477. // ensure we can still enter digits
  2478. INT nDecPos = m_nMaxWholeDigits + nNegLength + ( nSepCount * nGroupSeparatorLen );
  2479. if( nStart == nDecPos )
  2480. {
  2481. UINT nFlags = CBehaviorBase::m_nBehaviorFlags;
  2482. if(  nFlags & __ESE_ADD_DECIMAL_AFTER_MAX_WHOLE_DIGITS && m_nMaxFractionDigits > 0 )
  2483. {
  2484. nEnd = ( ( ( nEnd == nLen ) || ( ( nEnd > nStart ) && ( ( nEnd - nStart ) > 1 ) ) ) ? nEnd : ( nStart + nDecimalSignLen + 1 ) );
  2485. if( _strAfterCurrency.GetLength() > 0 )
  2486. {
  2487. m_pEditWithBehaviorWnd->SetSel( nStart, strText.GetLength() );
  2488. m_pEditWithBehaviorWnd->ReplaceSel( _T(""), TRUE );
  2489. }
  2490. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2491. m_pEditWithBehaviorWnd->ReplaceSel( m_strDecimalPoint + c, TRUE );
  2492. if( _strAfterCurrency.GetLength() > 0 )
  2493. {
  2494. CExtSafeString strChangedText = m_pEditWithBehaviorWnd->TextGet();
  2495. INT nEnd = INT( strChangedText.GetLength() );
  2496. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  2497. m_pEditWithBehaviorWnd->ReplaceSel( _strAfterCurrency, TRUE );
  2498. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  2499. }
  2500. CExtSafeString strReplaceText = Behavior_GetValidText( true );
  2501. }
  2502. return;
  2503. }
  2504. if( strNumericText.Mid( 
  2505. 0, 
  2506. ( ( nNumericDecimalPos >= 0 )
  2507. ? nNumericDecimalPos
  2508. : nNumericLen
  2509. )
  2510. ).GetLength()
  2511. == ( m_nMaxWholeDigits + nNegLength )
  2512. )
  2513. {
  2514. INT nPos = 0;
  2515. for( ; true; )
  2516. {
  2517. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  2518. if( nPos == -1 )
  2519. break;
  2520. if( nPos <= nStart && nStart < ( nPos + nGroupSeparatorLen ) )
  2521. {
  2522. nStart = nPos + nGroupSeparatorLen;
  2523. break;
  2524. }
  2525. nPos ++;
  2526. }
  2527. INT _nNegativeSignLen = nNegLength;
  2528. if( nStart < _nNegativeSignLen )
  2529. nStart = _nNegativeSignLen;
  2530. nEnd = ( ( ( nEnd == nLen ) || ( nEnd > nStart ) ) ? nEnd : ( nStart + 1 ) );
  2531. if( _strAfterCurrency.GetLength() > 0 )
  2532. {
  2533. INT nNegSignPos = INT( strText.Find( _strAfterCurrency ) );
  2534. if( nEnd > nNegSignPos )
  2535. nEnd = nNegSignPos;
  2536. }
  2537. if( ! m_bRichPainting )
  2538. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2539. m_pEditWithBehaviorWnd->ReplaceSel( CExtSafeString(c), TRUE );
  2540. CExtSafeString strReplaceText = Behavior_GetValidText(true);
  2541. return;
  2542. }
  2543. bNeedAdjustment = true;
  2544. }
  2545. }
  2546. // test whether it is a non-printable character (i.e. backspace, ctrl+c )
  2547. else if( ! ( _istprint( c ) || IsCharAlphaNumeric( c ) ) )
  2548. bNeedAdjustment = true;
  2549. else
  2550. return;
  2551. if( ! m_bBackspace )
  2552. {
  2553. //CExtEditSystemNumberCurrencyBase::CBehaviorBase::Behavior_OnChar( uChar, nRepCnt, nFlags );
  2554. CBehaviorBase::Behavior_OnChar( uChar, nRepCnt, nFlags );
  2555. // if the decimal point was added/removed or a separator needs adding/removing, adjust the text
  2556. if( bNeedAdjustment )
  2557. _AdjustSeparators( nSepCount, bIsDecimalPoint );
  2558. }
  2559. else
  2560. m_bBackspace = false;
  2561. }
  2562. bool CExtEditSystemCurrency::_DeleteSymbols( 
  2563. CExtSafeString & strText, 
  2564. INT & nStart, 
  2565. INT & nEnd, 
  2566. bool bBackspace // = false
  2567. )
  2568. {
  2569. ASSERT_VALID( this );
  2570. ASSERT( ! m_bRichPainting );
  2571. INT nLen = INT( strText.GetLength() );
  2572. bool bNegative = _IsNegative( strText );
  2573. CExtSafeString strTextLen = strText;
  2574. INT nStLen = 0, nEndLen = 0;
  2575. _GetTextWithoutMarks( strTextLen, nStLen, nEndLen );
  2576. INT nTextLen = INT( strTextLen.GetLength() );
  2577. INT nDecSepPosLen = INT( strTextLen.Find( m_strDecimalPoint ) );
  2578. INT nGroupSeparatorLen = INT( m_strGroupSeparator.GetLength() );
  2579. INT nDecimalSeparatorLen = INT( m_strDecimalPoint.GetLength() );
  2580. INT nDecimalSeparatorPos = INT( strText.Find( m_strDecimalPoint ) );
  2581. INT _nPos = 0, _nGroupSignBeforeStart = 0, _nGroupSignCount = (INT)_GetGroupSeparatorCount( strText );
  2582. for( ; true; )
  2583. {
  2584. _nPos = (INT)strText.Find( m_strGroupSeparator, _nPos );
  2585. if( _nPos < 0 )
  2586. break;
  2587. if( _nPos < nStart )
  2588. _nGroupSignBeforeStart ++;
  2589. _nPos ++;
  2590. }
  2591. _nGroupSignBeforeStart = _nGroupSignCount - _nGroupSignBeforeStart;
  2592. if( bBackspace )
  2593. {
  2594. if( nStart == 0 && nStart == nEnd )
  2595. return false;
  2596. INT nPos = 0;
  2597. if( nStart >= 0 )
  2598. {
  2599. if( ( nDecimalSeparatorPos < nStart
  2600. || ( nDecimalSeparatorPos == nStart
  2601. && nStart != nEnd
  2602. )
  2603. )
  2604. && nStart <= ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  2605. && nEnd <= ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  2606. && nDecSepPosLen == m_nMaxWholeDigits
  2607. && ( nTextLen > ( nDecSepPosLen + nDecimalSeparatorLen )
  2608. && nDecSepPosLen != -1
  2609. )
  2610. )
  2611. {
  2612. nStart = nDecimalSeparatorPos;
  2613. nEnd = nDecimalSeparatorPos;
  2614. m_bBackspace = true;
  2615. return false;
  2616. }
  2617. for( ; true; )
  2618. {
  2619. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  2620. if( nPos == -1 )
  2621. break;
  2622. if( ( nPos < nStart 
  2623. || ( nPos == nStart 
  2624. && nStart != nEnd
  2625. )
  2626. )
  2627. && nStart <= ( nPos + nGroupSeparatorLen )
  2628. && nEnd <= ( nPos + nGroupSeparatorLen )
  2629. )
  2630. {
  2631. nStart = nPos;
  2632. nEnd = nPos;
  2633. m_bBackspace = true;
  2634. return false;
  2635. }
  2636. nPos ++;
  2637. }
  2638. }
  2639. }
  2640. else
  2641. {
  2642. if( nStart == nLen )
  2643. return false;
  2644. INT nPos = 0;
  2645. if( nStart < nLen )
  2646. {
  2647. if( nDecimalSeparatorPos <= nStart
  2648. && nStart < ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  2649. && nEnd <= ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  2650. && nDecSepPosLen == m_nMaxWholeDigits
  2651. && ( nTextLen > ( nDecSepPosLen + nDecimalSeparatorLen )
  2652. && nDecSepPosLen != -1
  2653. )
  2654. )
  2655. {
  2656. nStart = nDecimalSeparatorPos + nDecimalSeparatorLen;
  2657. nEnd = nDecimalSeparatorPos + nDecimalSeparatorLen;
  2658. return false;
  2659. }
  2660. for( ; true; )
  2661. {
  2662. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  2663. if( nPos == -1 )
  2664. break;
  2665. if( nPos <= nStart 
  2666. && nStart < ( nPos + nGroupSeparatorLen )
  2667. && nEnd <= ( nPos + nGroupSeparatorLen )
  2668. )
  2669. {
  2670. nStart = nPos + nGroupSeparatorLen;
  2671. nEnd = nPos + nGroupSeparatorLen;
  2672. return false;
  2673. }
  2674. nPos ++;
  2675. }
  2676. }
  2677. }
  2678. if( nStart != nEnd )
  2679. {
  2680. if( nDecimalSeparatorPos < nStart
  2681. && nStart < ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  2682. )
  2683. {
  2684. nStart = nDecimalSeparatorPos + nDecimalSeparatorLen;
  2685. if( nStart > nEnd )
  2686. nEnd = nStart;
  2687. }
  2688. if( nDecimalSeparatorPos < nEnd
  2689. && nEnd <= ( nDecimalSeparatorPos + nDecimalSeparatorLen )
  2690. )
  2691. nEnd = nDecimalSeparatorPos;
  2692. INT nPos = 0;
  2693. for( ; true; )
  2694. {
  2695. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  2696. if( nPos == -1 )
  2697. break;
  2698. if( nPos < nStart 
  2699. && nStart < ( nPos + nGroupSeparatorLen )
  2700. )
  2701. {
  2702. nStart = nPos + nGroupSeparatorLen;
  2703. if( nStart >= nEnd )
  2704. {
  2705. nEnd = nStart;
  2706. break;
  2707. }
  2708. }
  2709. if( nPos < nEnd 
  2710. && nEnd < ( nPos + nGroupSeparatorLen )
  2711. )
  2712. {
  2713. nEnd = nPos;
  2714. if( nEnd < nStart )
  2715. nStart = nEnd;
  2716. if( nEnd >= nStart )
  2717. break;
  2718. }
  2719. nPos ++;
  2720. }
  2721. }
  2722. {
  2723. CExtSafeString _strBefore = _T("");
  2724. CExtSafeString _strAfter = _T("");
  2725. _GetSignStrings( _strBefore, _strAfter, bNegative && AllowNegativeGet() );
  2726. INT nBeforeLen = INT( _strBefore.GetLength() );
  2727. INT nAfterLen = INT( _strAfter.GetLength() );
  2728. bool bNegDel = false;
  2729. if( bNegative )
  2730. {
  2731. if( ( nStart < nBeforeLen
  2732. || ( nStart == nBeforeLen
  2733. && nStart == nEnd  
  2734. && bBackspace 
  2735. && nBeforeLen > 0
  2736. )
  2737. {
  2738. bNegative = false;
  2739. bNegDel = true;
  2740. }
  2741. if( ( ( nStart >= ( nLen - nAfterLen ) && ! bBackspace ) 
  2742. || ( nStart > ( nLen - nAfterLen ) && bBackspace ) 
  2743. || ( nStart == nLen  && nStart == nEnd  && bBackspace ) 
  2744. || nEnd > ( nLen - nAfterLen )
  2745. && nAfterLen > 0
  2746. )
  2747. {
  2748. bNegative = false;
  2749. bNegDel = true;
  2750. }
  2751. }
  2752. else
  2753. {
  2754. if( ( ( nStart < nBeforeLen
  2755. && nEnd <= nBeforeLen
  2756. )
  2757. || ( nStart == nBeforeLen
  2758. && nStart == nEnd  
  2759. && bBackspace 
  2760. && nBeforeLen > 0
  2761. )
  2762. {
  2763. nStart = nBeforeLen;
  2764. return true;
  2765. }
  2766. if( ( ( nStart >= ( nLen - nAfterLen ) && ! bBackspace ) 
  2767. || ( nStart > ( nLen - nAfterLen ) && bBackspace ) 
  2768. || ( nStart == nLen  && nStart == nEnd  && bBackspace ) 
  2769. && nAfterLen > 0
  2770. )
  2771. {
  2772. nStart = nLen - nAfterLen;
  2773. return true;
  2774. }
  2775. if( nEnd > ( nLen - nAfterLen ) 
  2776. && nAfterLen > 0
  2777. )
  2778. nEnd = nLen - nAfterLen;
  2779. }
  2780. _GetTextWithoutMarks( strText, nStart, nEnd );
  2781. if( bBackspace )
  2782. {
  2783. bool bSelect = ( nStart != nEnd ) ? true : false;
  2784. strText.Delete( ( nStart != nEnd ) ? nStart : ( nStart - 1 ), ( nStart != nEnd ) ? ( nEnd - nStart ) : ( bNegDel ? 0 : 1 ) );
  2785. if( ! bSelect && ! bNegDel )
  2786. nStart --;
  2787. m_bBackspace = true;
  2788. }
  2789. else
  2790. {
  2791. INT _nDecimalPointPos = INT( strText.Find( m_strDecimalPoint ) );
  2792. if( _nDecimalPointPos != -1 )
  2793. {
  2794. if( nStart > _nDecimalPointPos 
  2795. && nStart < ( _nDecimalPointPos + nDecimalSeparatorLen )
  2796. )
  2797. nStart = _nDecimalPointPos;
  2798. if( nEnd > _nDecimalPointPos 
  2799. && nEnd < ( _nDecimalPointPos + nDecimalSeparatorLen )
  2800. )
  2801. nEnd = _nDecimalPointPos + nDecimalSeparatorLen;
  2802. }
  2803. strText.Delete( nStart, ( nStart != nEnd ) ? ( nEnd - nStart ) : ( bNegDel ? 0 : 1 ) );
  2804. }
  2805. _GetTextWithoutMarks( strText, nStart, nEnd );
  2806. _GetTextWithMarks( strText, nStart, nEnd, bNegative );
  2807. if( m_bBackspace && ( nStart - nGroupSeparatorLen ) >= 0 )
  2808. {
  2809. INT nGroupSepPos = (INT)strText.Find( m_strGroupSeparator, ( nStart - nGroupSeparatorLen ) );
  2810. if( nGroupSepPos >= 0 )
  2811. {
  2812. INT _nPos = 0;
  2813. INT _nGroupSignBeforeStartAfterDelete = 0;
  2814. bool _bChangePos = false;
  2815. INT _nGroupSignCountAfterDelete = (INT)_GetGroupSeparatorCount( strText );
  2816. for( ; true; )
  2817. {
  2818. _nPos = (INT)strText.Find( m_strGroupSeparator, _nPos );
  2819. if( _nPos < 0 )
  2820. break;
  2821. if( _nPos < nStart )
  2822. _nGroupSignBeforeStartAfterDelete ++;
  2823. _nPos ++;
  2824. }
  2825. _nGroupSignBeforeStartAfterDelete = _nGroupSignCountAfterDelete - _nGroupSignBeforeStartAfterDelete;
  2826. if( ( _nGroupSignBeforeStart - 1 ) == _nGroupSignBeforeStartAfterDelete )
  2827. _bChangePos = true;
  2828. if( nGroupSepPos == ( nStart - nGroupSeparatorLen ) && _bChangePos )
  2829. nStart = nGroupSepPos;
  2830. }
  2831. }
  2832. }
  2833. return true;
  2834. }
  2835. INT CExtEditSystemCurrency::_GetSignLengthBeforeCurrency( 
  2836. bool bNegative // = false 
  2837. ) const
  2838. {
  2839. ASSERT_VALID( this );
  2840. INT nCurSignLength = INT( m_strCurrencySymbol.GetLength() );
  2841. INT nNegSignLenBeforeCur = 0;
  2842. INT nPosSignLenBeforeCur = 0;
  2843. INT nSpecificSymbLength = 1; // Bracket or Space
  2844. if( bNegative )
  2845. {
  2846. CExtSafeString strBefore = _T("");
  2847. CExtSafeString strAfter = _T("");
  2848. _GetSignStrings( strBefore, strAfter );
  2849. nNegSignLenBeforeCur = INT( strBefore.GetLength() );
  2850. }
  2851. switch( m_nPositiveFormatIndex )
  2852. {
  2853. case 0:
  2854. nPosSignLenBeforeCur = nCurSignLength;
  2855. break;
  2856. case 2:
  2857. nPosSignLenBeforeCur = nCurSignLength + nSpecificSymbLength;
  2858. break;
  2859. }
  2860. return bNegative ? nNegSignLenBeforeCur : nPosSignLenBeforeCur;
  2861. }
  2862. void CExtEditSystemCurrency::_GetSignStrings( 
  2863. CExtSafeString & strBeforeCurrency, 
  2864. CExtSafeString & strAfterCurrency,
  2865. bool bNegative // = true
  2866. ) const
  2867. {
  2868. ASSERT_VALID( this );
  2869. CExtSafeString strBefore = _T("");
  2870. CExtSafeString strAfter = _T("");
  2871. if( bNegative )
  2872. {
  2873. switch( m_nNegativeFormatIndex )
  2874. {
  2875. case 0:
  2876. strBefore = _T("(") + m_strCurrencySymbol;
  2877. strAfter = _T(")");
  2878. break;
  2879. case 1:
  2880. strBefore = m_strNegativeSign + m_strCurrencySymbol;
  2881. break;
  2882. case 2:
  2883. strBefore = m_strCurrencySymbol + m_strNegativeSign;
  2884. break;
  2885. case 3:
  2886. strBefore = m_strCurrencySymbol;
  2887. strAfter = m_strNegativeSign;
  2888. break;
  2889. case 4:
  2890. strBefore = _T("(");
  2891. strAfter = m_strCurrencySymbol + _T(")");
  2892. break;
  2893. case 5:
  2894. strBefore = m_strNegativeSign;
  2895. strAfter = m_strCurrencySymbol;
  2896. break;
  2897. case 6:
  2898. strAfter = m_strNegativeSign + m_strCurrencySymbol;
  2899. break;
  2900. case 7:
  2901. strAfter = m_strCurrencySymbol + m_strNegativeSign;
  2902. break;
  2903. case 8:
  2904. strBefore = m_strNegativeSign;
  2905. strAfter = _T(" ") + m_strCurrencySymbol;
  2906. break;
  2907. case 9:
  2908. strBefore = m_strNegativeSign + m_strCurrencySymbol + _T(" ");
  2909. break;
  2910. case 10:
  2911. strAfter = _T(" ") + m_strCurrencySymbol + m_strNegativeSign;
  2912. break;
  2913. case 11:
  2914. strBefore = m_strCurrencySymbol + _T(" ");
  2915. strAfter = m_strNegativeSign;
  2916. break;
  2917. case 12:
  2918. strBefore = m_strCurrencySymbol + _T(" ") + m_strNegativeSign;
  2919. break;
  2920. case 13:
  2921. strAfter = m_strNegativeSign + _T(" ") + m_strCurrencySymbol;
  2922. break;
  2923. case 14:
  2924. strBefore = _T("(") + m_strCurrencySymbol + _T(" ");
  2925. strAfter = _T(")");
  2926. break;
  2927. case 15:
  2928. strBefore = _T("(");
  2929. strAfter = _T(" ") + m_strCurrencySymbol + _T(")");
  2930. break;
  2931. }
  2932. }
  2933. else
  2934. {
  2935. switch( m_nPositiveFormatIndex )
  2936. {
  2937. case 0:
  2938. strBefore = m_strCurrencySymbol;
  2939. break;
  2940. case 1:
  2941. strAfter = m_strCurrencySymbol;
  2942. break;
  2943. case 2:
  2944. strBefore = m_strCurrencySymbol + _T(" ");
  2945. break;
  2946. case 3:
  2947. strAfter = _T(" ") + m_strCurrencySymbol;
  2948. break;
  2949. }
  2950. }
  2951. strBeforeCurrency = strBefore;
  2952. strAfterCurrency = strAfter;
  2953. }
  2954. void CExtEditSystemCurrency::_GetTextWithoutMarks( 
  2955. CExtSafeString & strText, 
  2956. INT & nStart, 
  2957. INT & nEnd, 
  2958. bool bCutDecimalPoint // = false 
  2959. ) const
  2960. {
  2961. ASSERT_VALID( this );
  2962. CExtSafeString strCurrentText;
  2963. INT nStartPos = nStart, nEndPos = nEnd;
  2964. INT nSignCountBeforeStartPos ,nSignCountBeforeEndPos ,nSignCount;
  2965. bool bIsNegative = _IsNegative(strText);
  2966. INT nDecimalSeparatorLen = INT( m_strDecimalPoint.GetLength() );
  2967. INT nDecimalSeparatorPos = INT( strText.Find( m_strDecimalPoint ) );
  2968. CExtSafeString _strBefore = _T("");
  2969. CExtSafeString _strAfter = _T("");
  2970. _GetSignStrings( _strBefore, _strAfter, bIsNegative );
  2971. INT nStrLen = INT( strText.GetLength() );
  2972. if( nEndPos > INT( strText.GetLength() ) )
  2973. nEndPos = INT( strText.GetLength() );
  2974. nSignCountBeforeStartPos = nSignCountBeforeEndPos = nSignCount = 0;
  2975. for( INT i = 0; i < nStrLen; i++ )
  2976. {
  2977. TCHAR _tchr = strText[i];
  2978. bool bUseSymbol = false;
  2979. if( _T('0') <= _tchr && _tchr <= _T('9') )
  2980. {
  2981. strCurrentText += _tchr;
  2982. bUseSymbol = true;
  2983. }
  2984. if( i >= nDecimalSeparatorPos && i < ( nDecimalSeparatorPos + nDecimalSeparatorLen ) && ! bCutDecimalPoint && nDecimalSeparatorPos != -1 )
  2985. {
  2986. strCurrentText += _tchr;
  2987. bUseSymbol = true;
  2988. }
  2989. if( ! bUseSymbol )
  2990. nSignCount++;
  2991. if( i == ( nStartPos - 1 ) )
  2992. nSignCountBeforeStartPos = nSignCount;
  2993. else if( i == ( nEndPos - 1 ) )
  2994. nSignCountBeforeEndPos = nSignCount;
  2995. }
  2996. nStartPos -= nSignCountBeforeStartPos;
  2997. nEndPos -= nSignCountBeforeEndPos;
  2998. if( nStartPos < 0 )
  2999. nStartPos = 0;
  3000. if( nEndPos < 0 )
  3001. nEndPos = 0;
  3002. strText = strCurrentText;
  3003. if( nStart != nEnd )
  3004. {
  3005. nStart = nStartPos;
  3006. nEnd = nEndPos;
  3007. }
  3008. else
  3009. nStart = nEnd = nStartPos;
  3010. }
  3011. void CExtEditSystemCurrency::_GetTextWithMarks( 
  3012. CExtSafeString & strText, 
  3013. INT & nStart, 
  3014. INT & nEnd, 
  3015. bool bInsertNegSign  // = false
  3016. ) const
  3017. {
  3018. ASSERT_VALID( this );
  3019. if( strText.IsEmpty() )
  3020. return;
  3021. INT nTextLen = INT( strText.GetLength() );
  3022. CExtSafeString strTextChange;
  3023. INT nGroupSeparatorLen = INT( m_strGroupSeparator.GetLength() );
  3024. INT nDecimalSeparatorLen = INT( m_strDecimalPoint.GetLength() );
  3025. INT nPositionDecimalPoint = INT( strText.Find( m_strDecimalPoint ) );
  3026. INT nMaxLen = m_nMaxWholeDigits + m_nMaxFractionDigits + ( ( nPositionDecimalPoint >= 0 ) ? nDecimalSeparatorLen : 0 );
  3027. bool bStartBehindEnd = ( nStart > INT( strText.GetLength() ) );
  3028. bool bEndBehindEnd = ( nEnd > INT( strText.GetLength() ) );
  3029. if( nTextLen > nMaxLen )
  3030. {
  3031. if( nPositionDecimalPoint >= 0 )
  3032. {
  3033. CExtSafeString _strDecimalPoint = _T("");
  3034. _strDecimalPoint = m_strDecimalPoint;
  3035. strText.Replace( _strDecimalPoint, _T("") );
  3036. if( nPositionDecimalPoint > m_nMaxWholeDigits )
  3037. {
  3038. strText.Insert( m_nMaxWholeDigits, m_strDecimalPoint );
  3039. }
  3040. else
  3041. strText.Insert( nPositionDecimalPoint, m_strDecimalPoint );
  3042. }
  3043. nTextLen = INT( strText.GetLength() );
  3044. }
  3045. INT nWholeNumber = ( ( nPositionDecimalPoint >= 0 ) ? ( ( nPositionDecimalPoint < m_nMaxWholeDigits ) ? nPositionDecimalPoint : m_nMaxWholeDigits ) : ( ( m_nMaxWholeDigits >= nTextLen ) ?  nTextLen : m_nMaxWholeDigits ) );
  3046. INT nDecimalPointLen = nDecimalSeparatorLen; // 1
  3047. INT nCorectTextLen = nWholeNumber + nDecimalPointLen + m_nMaxFractionDigits;
  3048. nCorectTextLen = ( nCorectTextLen > nTextLen ) ? nTextLen : nCorectTextLen;
  3049. INT nCountDigitGroups = INT( m_listDigitGrouping.GetCount() );
  3050. CList < INT, INT > _listPos;
  3051. bool bLastZiro = ( m_listDigitGrouping.GetAt( m_listDigitGrouping.FindIndex( nCountDigitGroups - 1 ) ) == 0 ) ? true : false;
  3052. ASSERT( nWholeNumber <= m_nMaxWholeDigits );
  3053. INT nPos = nWholeNumber;
  3054. INT i = 0;
  3055. INT nPreviousCount = -1;
  3056. for( ; true; )
  3057. {
  3058. INT nCount = m_listDigitGrouping.GetAt(m_listDigitGrouping.FindIndex(i));
  3059. if( nCount == 0 && i < ( nCountDigitGroups - 1 ) )
  3060. break;
  3061. if( nCount == 0 && i == ( nCountDigitGroups - 1 ) )
  3062. {
  3063. ASSERT( nPreviousCount != -1 );
  3064. nCount = nPreviousCount;
  3065. }
  3066. nPos -= nCount;
  3067. if( nPos > 0 )
  3068. _listPos.AddHead( nPos - 1 );
  3069. else
  3070. break;
  3071. if( i == ( nCountDigitGroups - 1 ) && ! bLastZiro )
  3072. break;
  3073. if( i < ( nCountDigitGroups - 1 ) )
  3074. i ++;
  3075. nPreviousCount = nCount;
  3076. }
  3077. INT nSignCountBeforeStart = 0;
  3078. INT nSignCountBeforeEnd = 0;
  3079. bool bInsertedDecimalSignBeforeStart = false;
  3080. bool bInsertedDecimalSignBeforeEnd = false;
  3081. INT nCurDigitPos = 0;
  3082. INT nPosCount = INT( _listPos.GetCount() );
  3083. bool bCanPastGroupSep = ( nPosCount > 0 );
  3084. for( i = 0; i < nCorectTextLen; i++ )
  3085. {
  3086. TCHAR _tchr = strText[i];
  3087. strTextChange += _tchr;
  3088. bool bInsertSign = false;
  3089. INT nPosCur = 0;
  3090. if( bCanPastGroupSep )
  3091. nPosCur = _listPos.GetAt( _listPos.FindIndex( nCurDigitPos ) );
  3092. if( ( i <= nWholeNumber )
  3093. && ( i != ( nCorectTextLen - 1 ) )
  3094. && ( i == nPosCur )
  3095. && bCanPastGroupSep
  3096. )
  3097. {
  3098. strTextChange += m_strGroupSeparator;
  3099. bInsertSign = true;
  3100. if( nCurDigitPos < ( nPosCount - 1 ) )
  3101. nCurDigitPos ++;
  3102. else
  3103. bCanPastGroupSep = false;
  3104. }
  3105. if( i == ( nWholeNumber - 1 ) && ( nPositionDecimalPoint == -1 ) && ( i != nCorectTextLen - 1 ) )
  3106. {
  3107. strTextChange += m_strDecimalPoint;
  3108. if( i < ( nStart - 1 ) )
  3109. bInsertedDecimalSignBeforeStart  = true;
  3110. if( i < ( nEnd - 1 ) )
  3111. bInsertedDecimalSignBeforeEnd = true;
  3112. }
  3113. if( bInsertSign )
  3114. {
  3115. if( i < nStart )
  3116. nSignCountBeforeStart ++;
  3117. if( i < nEnd )
  3118. nSignCountBeforeEnd ++;
  3119. }
  3120. }
  3121. CExtSafeString _strSignBefore = _T("");
  3122. CExtSafeString _strSignAfter = _T("");
  3123. _GetSignStrings( _strSignBefore, _strSignAfter, bInsertNegSign && AllowNegativeGet() );
  3124. if( _strSignAfter.GetLength() > 0 )
  3125. {
  3126. strTextChange.Insert( strTextChange.GetLength(), _strSignAfter );
  3127. if( bStartBehindEnd )
  3128. nStart += INT( _strSignAfter.GetLength() );
  3129. if( bEndBehindEnd )
  3130. nEnd += INT( _strSignAfter.GetLength() );
  3131. }
  3132. if( _strSignBefore.GetLength() > 0 )
  3133. {
  3134. strTextChange.Insert( 0, _strSignBefore );
  3135. nStart += INT( _strSignBefore.GetLength() );
  3136. nEnd += INT( _strSignBefore.GetLength() );
  3137. }
  3138. strText = strTextChange;
  3139. nStart += nGroupSeparatorLen * nSignCountBeforeStart + ( bInsertedDecimalSignBeforeStart ? nDecimalSeparatorLen : 0 );
  3140. nEnd += nGroupSeparatorLen * nSignCountBeforeEnd + ( bInsertedDecimalSignBeforeEnd ? nDecimalSeparatorLen : 0 );
  3141. }
  3142. bool CExtEditSystemCurrency::_IsNegative( __EXT_MFC_SAFE_LPCTSTR strText ) const
  3143. {
  3144. ASSERT_VALID( this );
  3145. CExtSafeString _strText = strText;
  3146. bool bRetVal = ( ( _strText.Find( m_strNegativeSign ) >= 0 ) ? true: false );
  3147. if( m_nNegativeFormatIndex == 0 
  3148. || m_nNegativeFormatIndex == 4
  3149. || m_nNegativeFormatIndex == 14
  3150. || m_nNegativeFormatIndex == 15
  3151. )
  3152. bRetVal = ( ( _strText.Find( _T('(') ) >= 0 ) ? true: false );
  3153. return bRetVal;
  3154. }
  3155. void CExtEditSystemCurrency::_AdjustWithinRange()
  3156. {
  3157. ASSERT_VALID( this );
  3158. if( _IsValid() )
  3159. return;
  3160. if( m_pEditWithBehaviorWnd->TextGet().IsEmpty() )
  3161. m_pEditWithBehaviorWnd->SetWindowText( _T(" ") );
  3162. else
  3163. _Redraw();
  3164. long double dValue = LongDoubleGet();
  3165.     if( dValue < m_lfMin )
  3166. LongDoubleSet( m_lfMin );
  3167.     else if( dValue > m_lfMax )
  3168. LongDoubleSet( m_lfMax );
  3169. CExtSafeString _strText = m_pEditWithBehaviorWnd->TextGet();
  3170. bool bNegative = _IsNegative( _strText );
  3171. CExtSafeString _strBefore = _T("");
  3172. CExtSafeString _strAfter = _T("");
  3173. _GetSignStrings( _strBefore, _strAfter, bNegative );
  3174. INT nNegSignPos = -1;
  3175. INT nLen = INT( _strText.GetLength() );
  3176. if( ! _strAfter.IsEmpty() )
  3177. nNegSignPos = INT( _strText.Find( _strAfter ) );
  3178. if( ! m_bRichPainting )
  3179. {
  3180. if( nNegSignPos >= 0 )
  3181. m_pEditWithBehaviorWnd->SetSel( nNegSignPos, nNegSignPos );
  3182. else
  3183. m_pEditWithBehaviorWnd->SetSel( nLen, nLen );
  3184. }
  3185. }
  3186. void CExtEditSystemCurrency::_Rich_OnDraw()
  3187. {
  3188. if( ! m_bRichMode )
  3189. return;
  3190. if( GetSafeHwnd() == NULL )
  3191. return;
  3192. if( m_bRichPainting )
  3193. return;
  3194. m_bRichPainting = true;
  3195. CHARRANGE crRestore;
  3196. Rich_GetSel( crRestore );
  3197. CHARFORMAT cfDefault;
  3198. ::memset( &cfDefault, 0, sizeof(CHARFORMAT) );
  3199. cfDefault.dwMask = CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_PROTECTED|CFM_COLOR;
  3200. cfDefault.dwEffects = CFE_PROTECTED; 
  3201. //cfDefault.yHeight = 180;
  3202. //cfDefault.crTextColor = ::GetSysColor( COLOR_WINDOWTEXT );
  3203. CFont * pFont = GetFont();
  3204. if( pFont->GetSafeHandle() == NULL )
  3205. {
  3206. CWnd * pWndParent = GetParent();
  3207. if( pWndParent->GetSafeHwnd() != NULL )
  3208. pFont = pWndParent->GetFont();
  3209. if( pFont->GetSafeHandle() == NULL )
  3210. pFont = &(PmBridge_GetPM()->m_FontNormal);
  3211. }
  3212. LOGFONT _lf; ::memset( &_lf, 0, sizeof(LOGFONT) );
  3213. pFont->GetLogFont( &_lf );
  3214. #if (! defined _RICHEDIT_VER )
  3215. USES_CONVERSION;
  3216. strcpy( cfDefault.szFaceName, T2CA(_lf.lfFaceName) );
  3217. #else
  3218. #if ( _RICHEDIT_VER < 0x0200 )
  3219. USES_CONVERSION;
  3220. strcpy( cfDefault.szFaceName, T2CA(_lf.lfFaceName) );
  3221. #else
  3222. __EXT_MFC_STRCPY( cfDefault.szFaceName, sizeof(cfDefault.szFaceName)/sizeof(cfDefault.szFaceName[0]), _lf.lfFaceName );
  3223. #endif
  3224. #endif
  3225. CWindowDC dcDesktop( NULL );
  3226. cfDefault.yHeight = ::MulDiv( _lf.lfHeight, 72 * 20, dcDesktop.GetDeviceCaps( LOGPIXELSY ) );
  3227. cfDefault.yHeight = abs( cfDefault.yHeight );
  3228. bool bEnabled = IsWindowEnabled() ? true : false, bReadOnly = ( ( GetStyle() & ES_READONLY ) != 0 ) ? true : false;
  3229. cfDefault.crTextColor = OnQueryTextColor();
  3230. if( cfDefault.crTextColor == COLORREF(-1L) )
  3231. {
  3232. cfDefault.crTextColor = bEnabled ? ( bReadOnly ? m_clrRichTextReadOnly : m_clrRichTextNormal ) : m_clrRichTextDisabled;
  3233. if( cfDefault.crTextColor == COLORREF(-1L) )
  3234. {
  3235. if( bEnabled )
  3236. {
  3237. if( bReadOnly )
  3238. cfDefault.crTextColor = ::GetSysColor( COLOR_3DSHADOW );
  3239. else
  3240. cfDefault.crTextColor = ::GetSysColor( COLOR_WINDOWTEXT );
  3241. }
  3242. else
  3243. cfDefault.crTextColor = ::GetSysColor( COLOR_GRAYTEXT );
  3244. }
  3245. }
  3246. COLORREF clrBack = OnQueryBackColor();
  3247. if( clrBack == COLORREF(-1L) )
  3248. {
  3249. clrBack = bEnabled ? ( bReadOnly ? m_clrRichBackReadOnly : m_clrRichBackNormal ) : m_clrRichBackDisabled;
  3250. if( clrBack == COLORREF(-1L) )
  3251. {
  3252. if( bEnabled )
  3253. {
  3254. if( bReadOnly )
  3255. clrBack = ::GetSysColor( COLOR_3DFACE );
  3256. else
  3257. clrBack = ::GetSysColor( COLOR_WINDOW );
  3258. }
  3259. else
  3260. clrBack = ::GetSysColor( COLOR_3DFACE );
  3261. }
  3262. }
  3263. Rich_SetBackgroundColor( FALSE, clrBack );
  3264. Rich_HideSelection( true, false );
  3265. Rich_SetSel( 0, -1 ); 
  3266. SendMessage( EM_SETCHARFORMAT, SCF_DEFAULT, LPARAM(&cfDefault) );
  3267. SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(&cfDefault) );
  3268. Rich_SetSelectionColor( cfDefault.crTextColor );
  3269. COLORREF clrSign = m_clrSign;
  3270. if( clrSign == COLORREF(-1L) )
  3271. clrSign = cfDefault.crTextColor;
  3272. COLORREF clrBrackets = m_clrBrackets;
  3273. if( clrSign == COLORREF(-1L) )
  3274. clrBrackets = cfDefault.crTextColor;
  3275. INT nGroupSeparatorLen = INT( m_strGroupSeparator.GetLength() );
  3276. INT nDecimalSignLen = INT( m_strDecimalPoint.GetLength() );
  3277. if( m_clrNumber != COLORREF(-1L)
  3278. || m_clrFraction != COLORREF(-1L)
  3279. || m_clrGroupSeparator != COLORREF(-1L)
  3280. || m_clrDecimalSeparator != COLORREF(-1L)
  3281. || m_clrSign != COLORREF(-1L)
  3282. || m_clrBrackets != COLORREF(-1L)
  3283. )
  3284. {
  3285. CExtSafeString strText = TextGet();
  3286. INT nTextLen = INT( strText.GetLength() );
  3287. if( nTextLen > 0 )
  3288. {
  3289. bool bNegative = _IsNegative( strText );
  3290. INT nPositionDecimalPoint = INT( strText.Find( m_strDecimalPoint ) );
  3291. CExtSafeString _strBefore = _T(""), _strAfter = _T("");
  3292. _GetSignStrings( _strBefore, _strAfter, bNegative );
  3293. INT nBeforLen = _strBefore.GetLength();
  3294. INT nAfterLen = _strAfter.GetLength();
  3295. // whole number
  3296. if( m_clrNumber != COLORREF(-1L) )
  3297. {
  3298. Rich_SetSel( nBeforLen, ( nPositionDecimalPoint != -1 ) ? nPositionDecimalPoint : ( nTextLen - nAfterLen ) );
  3299. Rich_SetSelectionColor( m_clrNumber );
  3300. }
  3301. if( nPositionDecimalPoint != -1 )
  3302. {
  3303. if( m_clrDecimalSeparator != COLORREF(-1L) )
  3304. {
  3305. Rich_SetSel( nPositionDecimalPoint, ( nPositionDecimalPoint + nDecimalSignLen ) );
  3306. Rich_SetSelectionColor( m_clrDecimalSeparator );
  3307. }
  3308. if( m_clrFraction != COLORREF(-1L) )
  3309. {
  3310. Rich_SetSel( nPositionDecimalPoint + nDecimalSignLen, nTextLen - nAfterLen );
  3311. Rich_SetSelectionColor( m_clrFraction );
  3312. }
  3313. }
  3314. if( m_clrGroupSeparator != COLORREF(-1L) )
  3315. {
  3316. INT nPos = 0;
  3317. for( ; true; )
  3318. {
  3319. nPos = INT( strText.Find( m_strGroupSeparator, nPos ) );
  3320. if( nPos == -1 )
  3321. break;
  3322. Rich_SetSel( nPos, ( nPos + nGroupSeparatorLen ) );
  3323. Rich_SetSelectionColor( m_clrGroupSeparator ); 
  3324. nPos ++;
  3325. }
  3326. }
  3327. INT nNegSignPos = INT( strText.Find( m_strNegativeSign ) );
  3328. INT nNegSignLen = INT( m_strNegativeSign.GetLength() );
  3329. if( nNegSignPos >= 0 )
  3330. {
  3331. if( m_clrSign != COLORREF(-1L) )
  3332. {
  3333. Rich_SetSel( nNegSignPos, nNegSignPos + nNegSignLen );
  3334. Rich_SetSelectionColor( m_clrSign );
  3335. }
  3336. }
  3337. if( m_clrBrackets != COLORREF(-1L) )
  3338. {
  3339. INT nPos = 0;
  3340. CExtSafeString _strBrackets = _T("()[]{}");
  3341. INT nBrackLen = INT( _strBrackets.GetLength() );
  3342. for( INT i = 0; i < nBrackLen; i++ )
  3343. {
  3344. nPos = 0;
  3345. for( ; true; )
  3346. {
  3347. nPos = INT( strText.Find( _strBrackets[i], nPos ) );
  3348. if( nPos == -1 )
  3349. break;
  3350. Rich_SetSel( nPos, ( nPos + 1 ) );
  3351. Rich_SetSelectionColor( m_clrBrackets ); 
  3352. nPos ++;
  3353. }
  3354. }
  3355. }
  3356. } // if( nTextLen > 0 )
  3357. }
  3358. Rich_SetSel( crRestore );
  3359. Rich_HideSelection( false, false );
  3360. m_bRichPainting = false;
  3361. }