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

界面编程

开发平台:

Visual C++

  1. // This is part of the Professional User Interface Suite library.
  2. // Copyright (C) 2001-2009 FOSS Software, Inc.
  3. // All rights reserved.
  4. //
  5. // http://www.prof-uis.com
  6. // mailto:support@prof-uis.com
  7. //
  8. // This source code can be used, modified and redistributed
  9. // under the terms of the license agreement that is included
  10. // in the Professional User Interface Suite package.
  11. //
  12. // Warranties and Disclaimers:
  13. // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND
  14. // INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  16. // IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT,
  17. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES,
  18. // INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA,
  19. // INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE
  20. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  21. #include "stdafx.h"
  22. #if (!defined __EXT_EDIT_H)
  23. #include <ExtEdit.h>
  24. #endif
  25. #if (!defined __EXT_MEMORY_DC_H)
  26. #include <../Src/ExtMemoryDC.h>
  27. #endif
  28. #if (!defined __EXT_POPUP_MENU_WND_H)
  29. #include <ExtPopupMenuWnd.h>
  30. #endif
  31. #if (!defined __EXT_TOOLCONTROLBAR_H)
  32. #include <ExtToolControlBar.h>
  33. #endif
  34. #if (!defined __EXT_PAINT_MANAGER_H)
  35. #include <ExtPaintManager.h>
  36. #endif
  37. #if (!defined __ExtCmdManager_H)
  38. #include <ExtCmdManager.h>
  39. #endif
  40. #ifdef _DEBUG
  41. #define new DEBUG_NEW
  42. #undef THIS_FILE
  43. static char THIS_FILE[] = __FILE__;
  44. #endif
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CExtEditBase
  47. IMPLEMENT_DYNCREATE( CExtEditBase, CEdit );
  48. IMPLEMENT_CExtPmBridge_MEMBERS( CExtEditBase );
  49. HWND CExtEditBase::g_hWndEditInAltKeyCodeMode = NULL;
  50. CExtEditBase::CExtEditBase()
  51. : m_bHandleCtxMenus( true )
  52. , m_clrBack( COLORREF(-1L) )
  53. , m_clrBackPrev( COLORREF(-1L) )
  54. , m_clrText( COLORREF(-1L) )
  55. , m_bRichMode( false )
  56. , m_bHandleAltKeyCodes( true )
  57. , m_bAltKeyCodeMode( false )
  58. , m_nTrackedAltKeyCode( 0L )
  59. {
  60. EnableToolTips();
  61. PmBridge_Install();
  62. }
  63. CExtEditBase::~CExtEditBase()
  64. {
  65. PmBridge_Uninstall();
  66. if( m_brBack.GetSafeHandle() != NULL )
  67. m_brBack.DeleteObject();
  68. }
  69. BEGIN_MESSAGE_MAP( CExtEditBase, CEdit )
  70. //{{AFX_MSG_MAP(CExtEditBase)
  71. ON_WM_PAINT()
  72. ON_WM_CONTEXTMENU()
  73. ON_WM_CTLCOLOR_REFLECT()
  74. //}}AFX_MSG_MAP
  75. END_MESSAGE_MAP()
  76. DWORD CALLBACK CExtEditBase::stat_Rich_CallBack_StreamIn( __EXT_MFC_DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb )
  77. {
  78. ASSERT( pcb != NULL );
  79. CExtSafeString * pStr = (CExtSafeString*)dwCookie;
  80. ASSERT( pStr != NULL );
  81. LONG nLength = pStr->GetLength();
  82. // if( nLength < cb )
  83. // {
  84. // (*pcb) = nLength;
  85. // ::memcpy( pbBuff, (LPCTSTR)*pStr, (*pcb)*sizeof(TCHAR) );
  86. // pStr->Empty();
  87. // }
  88. // else
  89. // {
  90. // (*pcb) = cb;
  91. // ::memcpy( pbBuff, (LPCTSTR)*pStr, (*pcb)*sizeof(TCHAR) );
  92. // *pStr = pStr->Right( nLength - cb );
  93. // }
  94. USES_CONVERSION;
  95. if( nLength < cb )
  96. {
  97. LPCSTR strA = T2CA( LPCTSTR(*pStr) );
  98. (*pcb) = nLength;
  99. ::memcpy( pbBuff, LPVOID(strA), (*pcb)*sizeof(CHAR) );
  100. pStr->Empty();
  101. }
  102. else
  103. {
  104. CExtSafeString strPart = pStr->Left( cb );
  105. LPCSTR strA = T2CA( LPCTSTR(strPart) );
  106. (*pcb) = cb;
  107. ::memcpy( pbBuff, LPVOID(strA), (*pcb) * sizeof(CHAR) );
  108. *pStr = pStr->Right( nLength - cb );
  109. }
  110. return 0;
  111. }
  112. DWORD CALLBACK CExtEditBase::stat_Rich_CallBack_StreamOut( __EXT_MFC_DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb )
  113. {
  114. pcb;
  115. CExtSafeString * pStr = (CExtSafeString*) dwCookie;
  116. //CExtSafeString strTmp = _T("");
  117. // ASSERT( pStr != NULL );
  118. // strTmp = (CExtSafeString)pbBuff;
  119. // (*pStr) += strTmp.Left( cb );
  120. if( cb <= 0 )
  121. return 0;
  122. CHAR * pLocalBuffer = (CHAR *) ::malloc( cb + 1 );
  123. if( pLocalBuffer == NULL )
  124. return 0;
  125. pLocalBuffer[ cb ] = CHAR(0);
  126. ::memcpy( pLocalBuffer, pbBuff, cb * sizeof(CHAR) );
  127. USES_CONVERSION;
  128. LPCTSTR strT = A2CT(pLocalBuffer);
  129. (*pStr) += strT;
  130. ::free( pLocalBuffer );
  131. return 0;
  132. }
  133. void CExtEditBase::OnPaint()
  134. {
  135.     // Let base class do it's thing
  136.     CEdit::OnPaint();
  137.     // Now we can do our painting for cue banner stuff
  138. if( GetWindowTextLength() > 0 || ::GetFocus() == m_hWnd )
  139.         return;
  140. CExtSafeString strCueBanner = GetCueBanner();
  141.     if( strCueBanner.IsEmpty() )
  142.         return;
  143. CExtPaintManager * pPM = PmBridge_GetPM();
  144. ASSERT_VALID( pPM );
  145. LOGFONT _lf;
  146. ::memset( &_lf, 0 , sizeof(LOGFONT) );
  147.     if( ! pPM->m_FontNormal.GetLogFont( &_lf ) )
  148. return;
  149. CFont _font;
  150. _lf.lfItalic = TRUE;
  151. if( ! _font.CreateFontIndirect( &_lf ) )
  152. return;
  153. CRect rcClient;
  154. GetClientRect( &rcClient );
  155. CRect rcCueBanner = rcClient;
  156. rcCueBanner.DeflateRect( 3, 1 );
  157. CClientDC dc( this );
  158. CFont * pOldFont = dc.SelectObject( &_font );
  159. COLORREF clrOldText = dc.SetTextColor( pPM->GetColor( COLOR_GRAYTEXT ) );
  160. INT nOldBkMode = dc.SetBkMode( TRANSPARENT );
  161. dc.DrawText( LPCTSTR(strCueBanner), strCueBanner.GetLength(), &rcCueBanner, DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS );
  162. dc.SetBkMode( nOldBkMode );
  163. dc.SetTextColor( clrOldText );
  164. dc.SelectObject( pOldFont );
  165. }
  166. bool CExtEditBase::SetCueBanner( __EXT_MFC_SAFE_LPCTSTR lpcText )
  167. {
  168.     ASSERT_VALID( this );
  169. if( lpcText == NULL )
  170. m_strCueBanner.Empty();
  171. else
  172. m_strCueBanner = lpcText;
  173. if( GetSafeHwnd() != NULL && GetWindowTextLength() > 0 && ::GetFocus() != m_hWnd )
  174. Invalidate();
  175.     return true;
  176. }
  177. bool CExtEditBase::GetCueBanner( __EXT_MFC_SAFE_LPTSTR lpText, int cchText ) const
  178. {
  179.     ASSERT_VALID( this );
  180.     if( lpText == NULL )
  181. return false;
  182. __EXT_MFC_STRNCPY( lpText, cchText, LPCTSTR(m_strCueBanner), m_strCueBanner.GetLength() );
  183.     return true;
  184. }
  185. CExtSafeString CExtEditBase::GetCueBanner() const
  186. {
  187.     ASSERT_VALID( this );
  188. return m_strCueBanner;
  189. }
  190. void CExtEditBase::OnContextMenu(CWnd* pWnd,CPoint pos )
  191. {
  192. if( ! m_bHandleCtxMenus )
  193. {
  194. CEdit::OnContextMenu( pWnd, pos );
  195. return;
  196. } // if( ! m_bHandleCtxMenus )
  197. LPCTSTR strProfileName =
  198. g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() );
  199. if( strProfileName == NULL )
  200. {
  201. CEdit::OnContextMenu( pWnd, pos );
  202. return;
  203. }
  204. CExtPopupMenuWnd * pPopup =
  205. CExtPopupMenuWnd::InstantiatePopupMenu(
  206. GetParent()->GetSafeHwnd(),
  207. RUNTIME_CLASS(CExtPopupMenuWnd),
  208. this
  209. );
  210. if( ! pPopup->CreatePopupMenu( GetSafeHwnd() ) )
  211. {
  212. ASSERT( FALSE );
  213. delete pPopup;
  214. CEdit::OnContextMenu( pWnd, pos );
  215. return;
  216. }
  217. static struct
  218. {
  219. UINT m_nCmdID;
  220. LPCTSTR m_sMenuText;
  221. } arrCmds[] =
  222. {
  223. { ID_EDIT_UNDO, _T("&Undo") },
  224. // { ID_EDIT_REDO, _T("&Redo") },
  225. { ID_SEPARATOR, NULL },
  226. { ID_EDIT_CUT, _T("Cu&t") },
  227. { ID_EDIT_COPY, _T("&Copy") },
  228. { ID_EDIT_PASTE, _T("&Paste") },
  229. { ID_EDIT_CLEAR, _T("Cl&ear") },
  230. { ID_SEPARATOR, NULL },
  231. { ID_EDIT_SELECT_ALL, _T("Select &All") },
  232. };
  233. for( int i = 0; i < sizeof(arrCmds)/sizeof(arrCmds[0]); i++ )
  234. {
  235. if( arrCmds[i].m_nCmdID == ID_SEPARATOR )
  236. {
  237. VERIFY( pPopup->ItemInsert( ID_SEPARATOR ) );
  238. continue;
  239. } // if( arrCmds[i].m_nCmdID == ID_SEPARATOR )
  240. CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( strProfileName, arrCmds[i].m_nCmdID );
  241. if( pCmdItem == NULL )
  242. pCmdItem = g_CmdManager->CmdAllocPtr( strProfileName, arrCmds[i].m_nCmdID );
  243. ASSERT( pCmdItem != NULL );
  244. if( pCmdItem == NULL )
  245. continue;
  246. if( pCmdItem->m_sMenuText.IsEmpty() )
  247. {
  248. CExtSafeString sText;
  249. if( g_ResourceManager->LoadString( sText, arrCmds[i].m_nCmdID ) )
  250. {
  251. sText.Replace( _T("t"), _T(" ") );
  252. sText.Replace( _T("r"), _T("") );
  253. sText.TrimLeft();
  254. sText.TrimRight();
  255. if( ! sText.IsEmpty() )
  256. {
  257. INT nSep = INT( sText.ReverseFind('n') );
  258. if( nSep < 0 )
  259. {
  260. pCmdItem->m_sMenuText = sText;
  261. } // if( nSep < 0 )
  262. else
  263. {
  264. int nLen = sText.GetLength();
  265. pCmdItem->m_sMenuText = sText.Right( nLen - nSep );
  266. pCmdItem->m_sMenuText.TrimLeft();
  267. pCmdItem->m_sMenuText.TrimRight();
  268. } // else from if( nSep < 0 )
  269. } // if( ! sText.IsEmpty() )
  270. }
  271. if( pCmdItem->m_sMenuText.IsEmpty() )
  272. pCmdItem->m_sMenuText = arrCmds[i].m_sMenuText;
  273. } // if( pCmdItem->m_sMenuText.IsEmpty() )
  274. pCmdItem->StateSetBasic();
  275. VERIFY( pPopup->ItemInsert( arrCmds[i].m_nCmdID ) );
  276. } // for( int i = 0; i < sizeof(arrCmds)/sizeof(arrCmds[0]); i++ )
  277. CRect rcClient;
  278. GetClientRect( &rcClient );
  279. ClientToScreen( &rcClient );
  280. if( !rcClient.PtInRect( pos ) )
  281. pos = rcClient.CenterPoint();
  282. SetFocus();
  283. HWND hWndOwn = m_hWnd;
  284. if( ! pPopup->TrackPopupMenu( TPMX_OWNERDRAW_FIXED|TPMX_DO_MESSAGE_LOOP, pos.x, pos.y, NULL, this, NULL, NULL, true )  )
  285. {
  286. //ASSERT( FALSE );
  287. //delete pPopup;
  288. if( ! ::IsWindow( hWndOwn ) )
  289. return;
  290. CEdit::OnContextMenu( pWnd, pos );
  291. return;
  292. }
  293. else
  294. {
  295. if( ! ::IsWindow( hWndOwn ) )
  296. return;
  297. VERIFY( RedrawWindow( NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_ERASENOW|RDW_FRAME|RDW_ALLCHILDREN ) );
  298. }
  299. }
  300. __EXT_MFC_INT_PTR CExtEditBase::OnToolHitTest( CPoint point, TOOLINFO * pTI ) const
  301. {
  302. __PROF_UIS_MANAGE_STATE;
  303. __EXT_MFC_IMPLEMENT_TT_REDIR_OnToolHitTest( CExtEditBase, CExtToolControlBar );
  304. return CEdit::OnToolHitTest( point, pTI );
  305. }
  306. COLORREF CExtEditBase::OnQueryBackColor() const
  307. ASSERT_VALID( this );
  308. return m_clrBack; 
  309. }
  310. COLORREF CExtEditBase::OnQueryTextColor() const
  311. ASSERT_VALID( this );
  312. return m_clrText; 
  313. }
  314. void CExtEditBase::InitToolTip()
  315. {
  316. if( m_wndToolTip.m_hWnd == NULL )
  317. {
  318. m_wndToolTip.Create( this );
  319. m_wndToolTip.Activate( FALSE );
  320. }
  321. }
  322. int CExtEditBase::OnQueryMaxTipWidth( __EXT_MFC_SAFE_LPCTSTR lpszText )
  323. {
  324. lpszText;
  325. return 250;
  326. }
  327. void CExtEditBase::ActivateTooltip(BOOL bActivate)
  328. {
  329. if( m_wndToolTip.GetToolCount() == 0 )
  330. return;
  331. m_wndToolTip.Activate( bActivate );
  332. }
  333. void CExtEditBase::SetTooltipText(
  334. CExtSafeString * spText,
  335. BOOL bActivate // = TRUE
  336. )
  337. {
  338. if( spText == NULL )
  339. return;
  340. InitToolTip();
  341. if( m_wndToolTip.GetToolCount() == 0 )
  342. {
  343. CRect rectBtn; 
  344. GetClientRect( rectBtn );
  345. m_wndToolTip.AddTool( this, *spText, rectBtn, 1 );
  346. }
  347. CWnd::CancelToolTips();
  348. m_wndToolTip.UpdateTipText( *spText, this, 1 );
  349. m_wndToolTip.SetMaxTipWidth( -1 );
  350. if( spText->Find( _T("r") ) >= 0 )
  351. m_wndToolTip.SetMaxTipWidth( OnQueryMaxTipWidth( *spText ) );
  352. m_wndToolTip.Activate( bActivate );
  353. }
  354. void CExtEditBase::SetTooltipText(
  355. CExtSafeString & sText,
  356. BOOL bActivate // = TRUE
  357. )
  358. {
  359. if( sText.IsEmpty() )
  360. return;
  361. InitToolTip();
  362. if( m_wndToolTip.GetToolCount() == 0 )
  363. {
  364. CRect rectBtn; 
  365. GetClientRect(rectBtn);
  366. m_wndToolTip.AddTool( this, sText, rectBtn, 1 );
  367. }
  368. CWnd::CancelToolTips();
  369. m_wndToolTip.UpdateTipText( sText, this, 1 );
  370. m_wndToolTip.SetMaxTipWidth( -1 );
  371. if( sText.Find( _T("r") ) >= 0 )
  372. m_wndToolTip.SetMaxTipWidth( OnQueryMaxTipWidth( sText ) );
  373. m_wndToolTip.Activate( bActivate );
  374. }
  375. void CExtEditBase::SetTooltipText(
  376. __EXT_MFC_SAFE_LPCTSTR sText,
  377. BOOL bActivate // = TRUE
  378. )
  379. {
  380. if( sText == NULL
  381. || _tcslen( sText ) == 0
  382. )
  383. return;
  384. InitToolTip();
  385. if( m_wndToolTip.GetToolCount() == 0 )
  386. {
  387. CRect rectBtn; 
  388. GetClientRect(rectBtn);
  389. m_wndToolTip.AddTool(this,sText,rectBtn,1);
  390. }
  391. CWnd::CancelToolTips();
  392. m_wndToolTip.UpdateTipText(sText,this,1);
  393. m_wndToolTip.SetMaxTipWidth( -1 );
  394. CExtSafeString strText( sText );
  395. if( strText.Find( _T("r") ) >= 0 )
  396. m_wndToolTip.SetMaxTipWidth( OnQueryMaxTipWidth( LPCTSTR(sText) ) );
  397. m_wndToolTip.Activate(bActivate);
  398. }
  399. void CExtEditBase::SetTooltipText(
  400. int nId,
  401. BOOL bActivate // = TRUE
  402. )
  403. {
  404. CExtSafeString sText;
  405. g_ResourceManager->LoadString( sText, nId );
  406. if( ! sText.IsEmpty() )
  407. SetTooltipText( &sText, bActivate );
  408. }
  409. void CExtEditBase::SetBkColor( COLORREF clrBk )
  410. ASSERT_VALID( this );
  411. m_clrBack = clrBk; 
  412. if( GetSafeHwnd() != NULL )
  413. RedrawWindow( NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_ERASENOW|RDW_FRAME |RDW_FRAME|RDW_ALLCHILDREN );
  414. }
  415. COLORREF CExtEditBase::GetBkColor() const
  416. ASSERT_VALID( this );
  417. return OnQueryBackColor(); 
  418. }
  419. void CExtEditBase::SetTextColor( COLORREF clrText )
  420. ASSERT_VALID( this );
  421. m_clrText = clrText; 
  422. if( GetSafeHwnd() != NULL )
  423. Invalidate();
  424. }
  425. COLORREF CExtEditBase::GetTextColor() const
  426. ASSERT_VALID( this );
  427. return OnQueryTextColor(); 
  428. }
  429. LRESULT CExtEditBase::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  430. {
  431. switch( message )
  432. {
  433. case WM_KEYDOWN:
  434. case WM_KEYUP:
  435. case WM_SYSKEYDOWN:
  436. case WM_SYSKEYUP:
  437. { // block - clipboard commands
  438. bool bAlt = ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 ) ? true : false;
  439. bool bCtrl = ( (::GetAsyncKeyState(VK_CONTROL)&0x8000) != 0 ) ? true : false;
  440. bool bShift = ( (::GetAsyncKeyState(VK_SHIFT)&0x8000) != 0 ) ? true : false;
  441. if( ! bAlt )
  442. {
  443. if( bCtrl && ! bShift 
  444. && ( INT(wParam) == VK_INSERT 
  445. || INT(wParam) == INT( _T('C') )
  446. )
  447. )
  448. {
  449. if( message == WM_KEYDOWN )
  450. SendMessage( WM_COPY, 0, 0 );
  451. return 0L;
  452. }
  453. if( ( bCtrl && (!bShift) && int(wParam) == int( _T('V') ) )
  454. || ( (!bCtrl) && bShift && int(wParam) == VK_INSERT )
  455. )
  456. {
  457. if( message == WM_KEYDOWN && ( GetStyle() & ES_READONLY ) == 0 )
  458. {
  459. //SendMessage( WM_PASTE, 0, 0 );
  460. Default();
  461. }
  462. return 0L;
  463. }
  464. if( ( bCtrl && (!bShift) && int(wParam) == int( _T('X') ) )
  465. || ( (!bCtrl) && bShift && int(wParam) == VK_DELETE )
  466. )
  467. {
  468. if( message == WM_KEYDOWN )
  469. SendMessage( ( ( GetStyle() & ES_READONLY ) == 0 ) ? WM_CUT : WM_COPY, 0, 0 );
  470. return 0L;
  471. }
  472. }
  473. } // block - clipboard commands
  474. // if( ( GetStyle() & ES_READONLY ) != 0 )
  475. // {
  476. // bool bAlt = ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 ) ? true : false;
  477. // if( ! bAlt )
  478. // {
  479. // bool bCtrl = ( (::GetAsyncKeyState(VK_CONTROL)&0x8000) != 0 ) ? true : false;
  480. // bool bShift = ( (::GetAsyncKeyState(VK_SHIFT)&0x8000) != 0 ) ? true : false;
  481. // if( ( bCtrl
  482. // && ( wParam == WPARAM('X')
  483. // || wParam == WPARAM('x')
  484. // || wParam == WPARAM('V')
  485. // || wParam == WPARAM('v')
  486. // || wParam == WPARAM('Z')
  487. // || wParam == WPARAM('z')
  488. // )
  489. // )
  490. // || ( bShift
  491. // && ( wParam == VK_INSERT
  492. // || wParam == VK_DELETE
  493. // )
  494. // )
  495. // || ( ( ! ( bCtrl || bShift ) )
  496. // && ( wParam == VK_DELETE || wParam == VK_BACK )
  497. // )
  498. // )
  499. // return 0L;
  500. // }
  501. // else
  502. // {
  503. // if( wParam == VK_BACK )
  504. // return 0L;
  505. // }
  506. // }
  507. if( m_bHandleAltKeyCodes )
  508. {
  509. bool bKeyDown = ( message == WM_KEYDOWN || message == WM_SYSKEYDOWN ) ? true : false;
  510. switch( wParam )
  511. {
  512. case VK_MENU:
  513. if( bKeyDown )
  514. {
  515. if( ( GetStyle() & ES_READONLY ) != 0 )
  516. {
  517. m_bAltKeyCodeMode = false;
  518. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  519. g_hWndEditInAltKeyCodeMode = NULL;
  520. m_nTrackedAltKeyCode = 0L;
  521. break;
  522. }
  523. m_bAltKeyCodeMode = true;
  524. g_hWndEditInAltKeyCodeMode = m_hWnd;
  525. m_nTrackedAltKeyCode = 0L;
  526. return 0L;
  527. } // if( bKeyDown )
  528. else if( m_bAltKeyCodeMode )
  529. {
  530. m_bAltKeyCodeMode = false;
  531. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  532. g_hWndEditInAltKeyCodeMode = NULL;
  533. if( m_nTrackedAltKeyCode > 0L )
  534. {
  535. USES_CONVERSION;
  536. WCHAR wstr[2] = { WCHAR(m_nTrackedAltKeyCode), L'' };
  537. LPCTSTR str = W2CT( wstr );
  538. //ReplaceSel( str );
  539. m_nTrackedAltKeyCode = 0L;
  540. for( MSG _msg; ::PeekMessage( &_msg, m_hWnd, WM_CHAR, WM_CHAR, PM_REMOVE ); );
  541. SendMessage( WM_CHAR, WPARAM(str[0]), 1L );
  542. }
  543. return 0L;
  544. } // else if( m_bAltKeyCodeMode )
  545. break;
  546. case VK_INSERT:
  547. case VK_END:
  548. case VK_DOWN:
  549. case VK_NEXT:
  550. case VK_LEFT:
  551. case 0x0C: // VK_CLEAR
  552. case VK_RIGHT:
  553. case VK_HOME:
  554. case VK_UP:
  555. case VK_PRIOR:
  556. if( m_bAltKeyCodeMode )
  557. {
  558. if( ! CExtPopupMenuWnd::IsKeyPressed( VK_MENU ) )
  559. {
  560. m_bAltKeyCodeMode = false;
  561. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  562. g_hWndEditInAltKeyCodeMode = NULL;
  563. m_nTrackedAltKeyCode = 0L;
  564. break;
  565. }
  566. if( bKeyDown )
  567. {
  568. LONG nAdd = -1L;
  569. bool bIsExtendedKey = ( ( lParam & (1L<<24L) ) == 0 ) ? true : false;
  570. if( bIsExtendedKey )
  571. {
  572. switch( wParam )
  573. {
  574. case VK_INSERT: nAdd = 0L; break;
  575. case VK_END: nAdd = 1L; break;
  576. case VK_DOWN: nAdd = 2L; break;
  577. case VK_NEXT: nAdd = 3L; break;
  578. case VK_LEFT: nAdd = 4L; break;
  579. case 0x0C: nAdd = 5L; break; // VK_CLEAR
  580. case VK_RIGHT: nAdd = 6L; break;
  581. case VK_HOME: nAdd = 7L; break;
  582. case VK_UP: nAdd = 8L; break;
  583. case VK_PRIOR: nAdd = 9L; break;
  584. } // switch( wParam )
  585. } // if( bIsExtendedKey )
  586. if( nAdd >= 0L )
  587. {
  588. m_nTrackedAltKeyCode *= 10;
  589. ASSERT( 0L <= nAdd && nAdd <= 9L );
  590. m_nTrackedAltKeyCode += nAdd;
  591. }
  592. } // if( message == WM_KEYDOWN )
  593. return 0L;
  594. } // if( m_bAltKeyCodeMode )
  595. break;
  596. case VK_NUMPAD0:
  597. case VK_NUMPAD1:
  598. case VK_NUMPAD2:
  599. case VK_NUMPAD3:
  600. case VK_NUMPAD4:
  601. case VK_NUMPAD5:
  602. case VK_NUMPAD6:
  603. case VK_NUMPAD7:
  604. case VK_NUMPAD8:
  605. case VK_NUMPAD9:
  606. if( m_bAltKeyCodeMode )
  607. {
  608. if( ! CExtPopupMenuWnd::IsKeyPressed( VK_MENU ) )
  609. {
  610. m_bAltKeyCodeMode = false;
  611. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  612. g_hWndEditInAltKeyCodeMode = NULL;
  613. m_nTrackedAltKeyCode = 0L;
  614. break;
  615. }
  616. if( bKeyDown )
  617. {
  618. bool bIsExtendedKey = ( ( lParam & (1L<<24L) ) == 0 ) ? true : false;
  619. if( bIsExtendedKey )
  620. {
  621. m_nTrackedAltKeyCode *= 10;
  622. LONG nAdd = LONG(wParam) - LONG(VK_NUMPAD0);
  623. ASSERT( 0L <= nAdd && nAdd <= 9L );
  624. m_nTrackedAltKeyCode += nAdd;
  625. } // if( bIsExtendedKey )
  626. } // if( message == WM_KEYDOWN )
  627. return 0L;
  628. } // if( m_bAltKeyCodeMode )
  629. break;
  630. case WPARAM('0'):
  631. case WPARAM('1'):
  632. case WPARAM('2'):
  633. case WPARAM('3'):
  634. case WPARAM('4'):
  635. case WPARAM('5'):
  636. case WPARAM('6'):
  637. case WPARAM('7'):
  638. case WPARAM('8'):
  639. case WPARAM('9'):
  640. if( m_bAltKeyCodeMode )
  641. {
  642. if( ! CExtPopupMenuWnd::IsKeyPressed( VK_MENU ) )
  643. {
  644. m_bAltKeyCodeMode = false;
  645. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  646. g_hWndEditInAltKeyCodeMode = NULL;
  647. m_nTrackedAltKeyCode = 0L;
  648. break;
  649. }
  650. if( bKeyDown )
  651. {
  652. bool bIsExtendedKey = ( ( lParam & (1L<<24L) ) == 0 ) ? true : false;
  653. if( bIsExtendedKey )
  654. {
  655. m_nTrackedAltKeyCode *= 10;
  656. LONG nAdd = LONG(wParam) - LONG('0');
  657. ASSERT( 0L <= nAdd && nAdd <= 9L );
  658. m_nTrackedAltKeyCode += nAdd;
  659. } // if( bIsExtendedKey )
  660. } // if( message == WM_KEYDOWN )
  661. return 0L;
  662. } // if( m_bAltKeyCodeMode )
  663. break;
  664. default:
  665. m_bAltKeyCodeMode = false;
  666. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  667. g_hWndEditInAltKeyCodeMode = NULL;
  668. m_nTrackedAltKeyCode = 0L;
  669. break;
  670. } // switch( wParam )
  671. } // if( m_bHandleAltKeyCodes )
  672. else
  673. {
  674. m_bAltKeyCodeMode = false;
  675. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  676. g_hWndEditInAltKeyCodeMode = NULL;
  677. m_nTrackedAltKeyCode = 0L;
  678. } // else from if( m_bHandleAltKeyCodes )
  679. break;
  680. case WM_CANCELMODE:
  681. case WM_ACTIVATE:
  682. case WM_ACTIVATEAPP:
  683. case WM_KILLFOCUS:
  684. case WM_DESTROY:
  685. case WM_SETTINGCHANGE:
  686. case WM_DISPLAYCHANGE:
  687. case WM_SHOWWINDOW:
  688. case WM_SIZE:
  689. case WM_WINDOWPOSCHANGING:
  690. case WM_WINDOWPOSCHANGED:
  691. case EM_SETSEL:
  692. case EM_REPLACESEL:
  693. case EM_UNDO:
  694. case EM_REDO:
  695. m_bAltKeyCodeMode = false;
  696. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  697. g_hWndEditInAltKeyCodeMode = NULL;
  698. m_nTrackedAltKeyCode = 0L;
  699. break;
  700. case WM_STYLECHANGED:
  701. if( ( GetStyle() & ES_READONLY ) != 0 )
  702. {
  703. m_bAltKeyCodeMode = false;
  704. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  705. g_hWndEditInAltKeyCodeMode = NULL;
  706. m_nTrackedAltKeyCode = 0L;
  707. break;
  708. }
  709. break;
  710. case WM_SYSCHAR:
  711. case WM_CHAR:
  712. if( ( GetStyle() & ES_READONLY ) != 0
  713. && (! CExtPopupMenuWnd::IsKeyPressed( VK_CONTROL ) )
  714. )
  715. return 0L;
  716. break;
  717. case WM_PASTE:
  718. {
  719. m_bAltKeyCodeMode = false;
  720. if( g_hWndEditInAltKeyCodeMode == m_hWnd )
  721. g_hWndEditInAltKeyCodeMode = NULL;
  722. m_nTrackedAltKeyCode = 0L;
  723. }
  724. break;
  725. } // switch( message )
  726. if( message == WM_NOTIFY
  727. && m_wndToolTip.GetSafeHwnd() != NULL
  728. && IsWindow( m_wndToolTip.GetSafeHwnd() )
  729. && ((LPNMHDR)lParam) != NULL
  730. && ((LPNMHDR)lParam)->hwndFrom == m_wndToolTip.GetSafeHwnd()
  731. && ((LPNMHDR)lParam)->code == TTN_SHOW
  732. )
  733. ::SetWindowPos(
  734. m_wndToolTip.GetSafeHwnd(),
  735. HWND_TOP,
  736. 0,0,0,0,
  737. SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE
  738. );
  739. LRESULT lResult = CEdit::WindowProc( message, wParam, lParam );
  740. return lResult;
  741. }
  742. BOOL CExtEditBase::PreTranslateMessage( MSG * pMsg )
  743. {
  744. if( ! CExtPopupMenuWnd::IsMenuTracking() )
  745. {
  746. InitToolTip();
  747. m_wndToolTip.RelayEvent(pMsg);
  748. }
  749. return CEdit::PreTranslateMessage( pMsg );
  750. }
  751. BOOL CExtEditBase::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) 
  752. {
  753. if( m_bHandleCtxMenus
  754. && ( nCode == CN_UPDATE_COMMAND_UI
  755. || nCode == CN_COMMAND
  756. )
  757. )
  758. {
  759. bool bReadOnly = ( ( GetStyle() & ES_READONLY ) != 0 ) ? true : false;
  760. DWORD nSelection = GetSel();
  761. if( nID == ID_EDIT_UNDO )
  762. {
  763. if( nCode == CN_UPDATE_COMMAND_UI )
  764. {
  765. CCmdUI * pCmdUI = (CCmdUI *)pExtra;
  766. ASSERT( pCmdUI != NULL );
  767. pCmdUI->Enable( ( CanUndo() && (! bReadOnly ) ) ? TRUE : FALSE );
  768. } // if( nCode == CN_UPDATE_COMMAND_UI )
  769. else
  770. Undo();
  771. return TRUE;
  772. } // if( nID == ID_EDIT_UNDO )
  773. // if( nID == ID_EDIT_REDO )
  774. // {
  775. // if( nCode == CN_UPDATE_COMMAND_UI )
  776. // {
  777. // CCmdUI * pCmdUI = (CCmdUI *)pExtra;
  778. // ASSERT( pCmdUI != NULL );
  779. // pCmdUI->Enable(
  780. // (BOOL) ( SendMessage( EM_CANREDO ) && (! bReadOnly )
  781. // );
  782. // } // if( nCode == CN_UPDATE_COMMAND_UI )
  783. // else
  784. // SendMessage( EM_REDO );
  785. // return TRUE;
  786. // } // if( nID == ID_EDIT_REDO )
  787. if( nID == ID_EDIT_CUT )
  788. {
  789. if( nCode == CN_UPDATE_COMMAND_UI )
  790. {
  791. CCmdUI * pCmdUI = (CCmdUI *)pExtra;
  792. ASSERT( pCmdUI != NULL );
  793. pCmdUI->Enable( (LOWORD(nSelection)) != (HIWORD(nSelection)) && (! bReadOnly ) );
  794. } // if( nCode == CN_UPDATE_COMMAND_UI )
  795. else
  796. SendMessage( WM_CUT );
  797. return TRUE;
  798. } // if( nID == ID_EDIT_CUT )
  799. if( nID == ID_EDIT_COPY )
  800. {
  801. if( nCode == CN_UPDATE_COMMAND_UI )
  802. {
  803. CCmdUI * pCmdUI = (CCmdUI *)pExtra;
  804. ASSERT( pCmdUI != NULL );
  805. pCmdUI->Enable( (LOWORD(nSelection)) != (HIWORD(nSelection)) );
  806. } // if( nCode == CN_UPDATE_COMMAND_UI )
  807. else
  808. SendMessage( WM_COPY );
  809. return TRUE;
  810. } // if( nID == ID_EDIT_COPY )
  811. if( nID == ID_EDIT_PASTE )
  812. {
  813. if( nCode == CN_UPDATE_COMMAND_UI )
  814. {
  815. CCmdUI * pCmdUI = (CCmdUI *)pExtra;
  816. ASSERT( pCmdUI != NULL );
  817. pCmdUI->Enable(
  818. ( ::IsClipboardFormatAvailable( CF_TEXT )
  819. || ( g_PaintManager.m_bIsWinNT4orLater && ::IsClipboardFormatAvailable( CF_UNICODETEXT ) )
  820. )
  821. && (! bReadOnly )
  822. );
  823. } // if( nCode == CN_UPDATE_COMMAND_UI )
  824. else
  825. SendMessage( WM_PASTE );
  826. return TRUE;
  827. } // if( nID == ID_EDIT_PASTE )
  828. if( nID == ID_EDIT_CLEAR )
  829. {
  830. if( nCode == CN_UPDATE_COMMAND_UI )
  831. {
  832. CCmdUI * pCmdUI = (CCmdUI *)pExtra;
  833. ASSERT( pCmdUI != NULL );
  834. pCmdUI->Enable( (LOWORD(nSelection)) != (HIWORD(nSelection)) && (! bReadOnly ) );
  835. } // if( nCode == CN_UPDATE_COMMAND_UI )
  836. else
  837. SendMessage( WM_CLEAR );
  838. return TRUE;
  839. } // if( nID == ID_EDIT_CLEAR )
  840. if( nID == ID_EDIT_SELECT_ALL )
  841. {
  842. if( nCode == CN_UPDATE_COMMAND_UI )
  843. {
  844. CCmdUI * pCmdUI = (CCmdUI *)pExtra;
  845. ASSERT( pCmdUI != NULL );
  846. int nLength = GetWindowTextLength();
  847. pCmdUI->Enable(
  848. nLength > 0
  849. && (!( (LOWORD(nSelection)) == 0 
  850. && (HIWORD(nSelection)) == nLength
  851. ))
  852. );
  853. } // if( nCode == CN_UPDATE_COMMAND_UI )
  854. else
  855. SetSel( 0, -1 );
  856. return TRUE;
  857. } // if( nID == ID_EDIT_SELECT_ALL )
  858. } // if( m_bHandleCtxMenus ...
  859. return CEdit::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  860. }
  861. HBRUSH CExtEditBase::CtlColor( CDC* pDC, UINT nCtlColor )
  862. {
  863. ASSERT_VALID( this );
  864. if( nCtlColor == CTLCOLOR_EDIT 
  865. || nCtlColor == CTLCOLOR_MSGBOX
  866. || nCtlColor == CTLCOLOR_STATIC
  867. )
  868. {
  869. CExtPaintManager * pPM = PmBridge_GetPM();
  870. ASSERT_VALID( pPM );
  871. bool bReadOnly = ( GetStyle() & ES_READONLY ) != 0;
  872. bool bDisabled = OnQueryWindowEnabledState() ? false : true;
  873. COLORREF clrText = GetTextColor();
  874. if( clrText == COLORREF(-1L) )
  875. clrText = pPM->GetColor( bDisabled ? CExtPaintManager::CLR_TEXT_DISABLED : COLOR_WINDOWTEXT, this );
  876. COLORREF clrBk = GetBkColor();
  877. if( clrBk == COLORREF(-1L) )
  878. clrBk = pPM->GetColor( ( bReadOnly || bDisabled ) ? CExtPaintManager::CLR_3DFACE_OUT : COLOR_WINDOW, this );
  879. pDC->SetBkColor( clrBk );
  880. pDC->SetTextColor( clrText );
  881. if( m_clrBackPrev != clrBk )
  882. {
  883. if( m_brBack.GetSafeHandle() != NULL )
  884. m_brBack.DeleteObject();
  885. m_brBack.CreateSolidBrush( clrBk );
  886. m_clrBackPrev = clrBk;
  887. }
  888. return m_brBack;
  889. }
  890. else
  891. return (HBRUSH)Default();
  892. }
  893. void CExtEditBase::stat_DoPaintNc(
  894. bool bEnabled,
  895. bool bMouseOver,
  896. CWnd * pWnd,
  897. CExtPmBridge * pPmBridge,
  898. CDC * pDC
  899. )
  900. {
  901. ASSERT_VALID( pWnd );
  902. ASSERT( pWnd->GetSafeHwnd() != NULL );
  903. ASSERT( pPmBridge != NULL );
  904. ASSERT_VALID( pDC );
  905. ASSERT( pDC->GetSafeHdc() != NULL );
  906. CRect rcInBarWnd, rcInBarClient;
  907. pWnd->GetWindowRect( &rcInBarWnd );
  908. pWnd->GetClientRect( &rcInBarClient );
  909. pWnd->ClientToScreen( &rcInBarClient );
  910. if( rcInBarWnd == rcInBarClient )
  911. return;
  912. CPoint ptDevOffset = -rcInBarWnd.TopLeft();
  913. rcInBarWnd.OffsetRect( ptDevOffset );
  914. rcInBarClient.OffsetRect( ptDevOffset );
  915. const INT cx = ::GetSystemMetrics( SM_CXVSCROLL );
  916. const INT cy = ::GetSystemMetrics( SM_CYHSCROLL );
  917. DWORD dwStyle = pWnd->GetStyle();
  918. bool bHasVerticalSB = ( (dwStyle&WS_VSCROLL) != 0 ) ? true : false;
  919. bool bHasHorizontalSB = ( (dwStyle&WS_HSCROLL) != 0 ) ? true : false;
  920. if( bHasVerticalSB && bHasHorizontalSB )
  921. {
  922. INT nNcX = rcInBarWnd.right - rcInBarClient.right - cx;
  923. INT nNcY = rcInBarWnd.bottom - rcInBarClient.bottom - cy;
  924. pDC->FillSolidRect(
  925. rcInBarWnd.right - cx - nNcX, rcInBarWnd.bottom - cy - nNcY, cx, cy,
  926. pPmBridge->PmBridge_GetPM()->GetColor( COLOR_WINDOW, pWnd )
  927. );
  928. }
  929. CRect rcExclude( rcInBarClient );
  930. if( bHasVerticalSB )
  931. rcExclude.right += cx;
  932. if( bHasHorizontalSB )
  933. rcExclude.bottom += cy;
  934. #ifndef __EXT_MFC_NO_SPINWND
  935. CWnd * pWndParent = pWnd->GetParent();
  936. ASSERT_VALID( pWndParent );
  937. bool bBuddyWithSpin = false;
  938. bool bSpinAlignRight = false;
  939. bool bSpinAlignLeft = false;
  940. CWnd * pWndTest = pWnd->GetWindow( GW_HWNDNEXT );
  941. if( pWndTest->GetSafeHwnd() != NULL )
  942. {
  943. ASSERT_VALID( pWndTest );
  944. static const TCHAR szSpin[] = UPDOWN_CLASS;
  945. TCHAR szCompare[ sizeof(szSpin)/sizeof(szSpin[0]) + 1 ] = _T("");
  946. ::GetClassName( pWndTest->GetSafeHwnd(), szCompare, sizeof(szCompare)/sizeof(szCompare[0]) );
  947. if( ! lstrcmpi( szCompare, szSpin ) )
  948. {
  949. DWORD dwStyle = pWndTest->GetStyle();
  950. bSpinAlignRight = ( ( dwStyle & UDS_ALIGNRIGHT ) != 0 ) ? true : false;
  951. bSpinAlignLeft  = ( ( dwStyle & UDS_ALIGNLEFT ) != 0 ) ? true : false;
  952. bBuddyWithSpin  = ( ( dwStyle & UDS_AUTOBUDDY ) != 0 && ( bSpinAlignRight || bSpinAlignLeft ) ) ? true : false;
  953. }
  954. }
  955. if( bBuddyWithSpin )
  956. {
  957. CRect rcSpin;
  958. pWndTest->GetClientRect( &rcSpin );
  959. if( bSpinAlignRight )
  960. {
  961. rcInBarWnd.right += rcSpin.Width();
  962. rcExclude.right += rcSpin.Width();
  963. }
  964. else if( bSpinAlignLeft )
  965. {
  966. rcInBarWnd.left -= rcSpin.Width();
  967. rcExclude.left -= rcSpin.Width();
  968. }
  969. }
  970. #endif // __EXT_MFC_NO_SPINWND
  971. pDC->ExcludeClipRect( &rcExclude );
  972. if( bHasVerticalSB || bHasHorizontalSB )
  973. {
  974. struct default_friendly_t : public CWnd
  975. {
  976. friend void CExtEditBase::stat_DoPaintNc( bool bEnabled, bool bMouseOver, CWnd * pWnd, CExtPmBridge * pPmBridge, CDC * pDC );
  977. };
  978. ((default_friendly_t*)pWnd)->Default();
  979. }
  980. bool bReadOnly = ( ( pWnd->GetStyle() & ES_READONLY ) != 0 ) ? true : false;
  981. COLORREF clrSysBk = pPmBridge->PmBridge_GetPM()->GetColor( ( bReadOnly || (!bEnabled) ) ? CExtPaintManager::CLR_3DFACE_OUT : COLOR_WINDOW, pWnd );
  982. CExtEditBase::stat_DrawEditImpl( bEnabled, bMouseOver, pWnd, pPmBridge, rcInBarWnd, pDC );
  983. pDC->SelectClipRgn( NULL );
  984. #ifndef __EXT_MFC_NO_SPINWND
  985. if( bBuddyWithSpin )
  986. {
  987. CRect rcSpinWnd, rcSpinClient;
  988. pWndTest->GetWindowRect( &rcSpinWnd );
  989. pWndTest->GetClientRect( &rcSpinClient );
  990. pWndTest->ClientToScreen( &rcSpinClient );
  991. CPoint ptDevOffset = -rcSpinWnd.TopLeft();
  992. rcSpinWnd.OffsetRect( ptDevOffset );
  993. rcSpinClient.OffsetRect( ptDevOffset );
  994. __EXT_MFC_LONG_PTR dwExStyle = ::__EXT_MFC_GetWindowLong( pWndTest->GetSafeHwnd(), GWL_EXSTYLE );
  995. bool bRTL = ( (dwExStyle & WS_EX_LAYOUTRTL) != 0 ) ? true : false;
  996. if( bRTL )
  997. rcSpinClient.OffsetRect( -3, 0 );
  998. CWindowDC dcSpin( pWndTest );
  999. dcSpin.ExcludeClipRect( &rcSpinClient );
  1000. dcSpin.FillSolidRect( &rcSpinWnd, clrSysBk );
  1001. if( bSpinAlignRight )
  1002. rcSpinWnd.left -= rcInBarClient.Width();
  1003. else if( bSpinAlignLeft )
  1004. rcSpinWnd.right += rcInBarClient.Width();
  1005. CExtEditBase::stat_DrawEditImpl( bEnabled, bMouseOver, pWnd, pPmBridge, rcSpinWnd, &dcSpin );
  1006. dcSpin.SelectClipRgn( NULL );
  1007. }
  1008. #endif // __EXT_MFC_NO_SPINWND
  1009. }
  1010. void CExtEditBase::stat_DrawEditImpl(
  1011. bool bEnabled,
  1012. bool bMouseOver,
  1013. CWnd * pWnd,
  1014. CExtPmBridge * pPmBridge,
  1015. CRect rectClient,
  1016. CDC * pDC
  1017. )
  1018. {
  1019. ASSERT_VALID( pWnd );
  1020. ASSERT( pWnd->GetSafeHwnd() != NULL );
  1021. ASSERT( pPmBridge != NULL );
  1022. ASSERT_VALID( pDC );
  1023. ASSERT( pDC->GetSafeHdc() != NULL );
  1024. bool bNeedReleaseDC = false;
  1025. if( pDC == NULL )
  1026. {
  1027. pDC = pWnd->GetDC();
  1028. bNeedReleaseDC = true;
  1029. }
  1030. ASSERT_VALID( pDC );
  1031. bool bFocus = false;
  1032. if( ::GetFocus() == pWnd->m_hWnd && (! CExtPopupMenuWnd::IsMenuTracking() ) )
  1033. bFocus = true;
  1034. bool bReadOnly = ( ( pWnd->GetStyle() & ES_READONLY ) != 0 ) ? true : false;
  1035. CExtPaintManager::PAINTCONTROLFRAMEDATA _pcfd( pWnd, rectClient, true, bMouseOver, bEnabled, bFocus, bReadOnly );
  1036. pPmBridge->PmBridge_GetPM()->PaintControlFrame( *pDC, _pcfd );
  1037. if( bNeedReleaseDC )
  1038. pWnd->ReleaseDC(pDC);
  1039. }
  1040. void CExtEditBase::stat_PrintClient(
  1041. bool bEnabled,
  1042. bool bMouseOver,
  1043. UINT message,
  1044. LPARAM lParam,
  1045. CWnd * pWnd,
  1046. CExtPmBridge * pPmBridge,
  1047. CDC * pDC
  1048. )
  1049. {
  1050. ASSERT_VALID( pWnd );
  1051. ASSERT( pWnd->GetSafeHwnd() != NULL );
  1052. ASSERT( pPmBridge != NULL );
  1053. ASSERT_VALID( pDC );
  1054. ASSERT( pDC->GetSafeHdc() != NULL );
  1055. CRect rcWnd;
  1056. pWnd->GetWindowRect( &rcWnd );
  1057. rcWnd.OffsetRect( -rcWnd.TopLeft() );
  1058. CExtMemoryDC dc( pDC, &rcWnd, CExtMemoryDC::MDCOPT_TO_MEMORY|CExtMemoryDC::MDCOPT_FILL_BITS|CExtMemoryDC::MDCOPT_RTL_COMPATIBILITY );
  1059. if( (lParam&PRF_NONCLIENT) != 0 )
  1060. CExtEditBase::stat_DoPaintNc( bEnabled, bMouseOver, pWnd, pPmBridge, pDC );
  1061. if( (lParam&PRF_CHILDREN) != 0 )
  1062. CExtPaintManager::stat_PrintChildren( pWnd->m_hWnd, message, dc.GetSafeHdc(), lParam, false );
  1063. }
  1064. /////////////////////////////////////////////////////////////////////////////
  1065. // CExtEdit
  1066. IMPLEMENT_DYNCREATE( CExtEdit, CExtEditBase );
  1067. CExtEdit::CExtEdit()
  1068. {
  1069. }
  1070. CExtEdit::~CExtEdit()
  1071. {
  1072. }
  1073. BEGIN_MESSAGE_MAP(CExtEdit, CExtED < CExtEditBase >)
  1074. //{{AFX_MSG_MAP(CExtEdit)
  1075. //}}AFX_MSG_MAP
  1076. END_MESSAGE_MAP()
  1077. /////////////////////////////////////////////////////////////////////////////
  1078. // CExtIPAddressCtrl
  1079. CTypedPtrList < CPtrList, CExtIPAddressCtrl * > CExtIPAddressCtrl::g_listTargets;
  1080. IMPLEMENT_DYNCREATE( CExtIPAddressCtrl, CIPAddressCtrl );
  1081. IMPLEMENT_CExtPmBridge_MEMBERS( CExtIPAddressCtrl );
  1082. CExtIPAddressCtrl::CExtIPAddressCtrl()
  1083. : m_bDirectCreateCall( false )
  1084. , m_bInitialized( false )
  1085. , m_bMouseOver( false )
  1086. {
  1087. for( INT nIndex = 0; nIndex < 4; nIndex++ )
  1088. {
  1089. m_pWNDPROC[nIndex] = NULL;
  1090. m_hWndHooked[nIndex] = NULL;
  1091. }
  1092. PmBridge_Install();
  1093. }
  1094. CExtIPAddressCtrl::~CExtIPAddressCtrl()
  1095. {
  1096. PmBridge_Uninstall();
  1097. }
  1098. BEGIN_MESSAGE_MAP(CExtIPAddressCtrl, CIPAddressCtrl)
  1099. //{{AFX_MSG_MAP(CExtIPAddressCtrl)
  1100. ON_WM_DESTROY()
  1101. ON_WM_TIMER()
  1102. ON_WM_SETFOCUS()
  1103. ON_WM_KILLFOCUS()
  1104. ON_WM_NCPAINT()
  1105. ON_WM_SETCURSOR()
  1106. //}}AFX_MSG_MAP
  1107. END_MESSAGE_MAP()
  1108. /////////////////////////////////////////////////////////////////////////////
  1109. // CExtIPAddressCtrl message handlers
  1110. BOOL CExtIPAddressCtrl::OnSetCursor( CWnd * pWnd, UINT nHitTest, UINT message )
  1111. {
  1112. if( message == WM_MOUSEMOVE )
  1113. {
  1114. CRect rcWnd;
  1115. GetWindowRect( &rcWnd );
  1116. if( rcWnd.PtInRect( GetCurrentMessage()->pt ) )
  1117. {
  1118. SetTimer( __EXT_EDIT_UPDATE_TIMER, __EXT_EDIT_UPDATE_TIMER_PERIOD, NULL );
  1119. SendMessage( WM_TIMER, __EXT_EDIT_UPDATE_TIMER, 0L );
  1120. }
  1121. }
  1122. return CIPAddressCtrl::OnSetCursor(pWnd, nHitTest, message);
  1123. }
  1124. void CExtIPAddressCtrl::OnTimer( __EXT_MFC_UINT_PTR nIDEvent ) 
  1125. {
  1126. if( nIDEvent != __EXT_EDIT_UPDATE_TIMER )
  1127. {
  1128. CIPAddressCtrl::OnTimer( nIDEvent );
  1129. return;
  1130. }
  1131. POINT pt;
  1132. if( ! ::GetCursorPos(&pt) )
  1133. return;
  1134. if( IsWindowVisible() )
  1135. {
  1136. bool bOldMouseOver = m_bMouseOver;
  1137. CRect rectItem;
  1138. GetWindowRect( &rectItem );
  1139. if( !rectItem.PtInRect(pt) )
  1140. {
  1141. KillTimer( __EXT_EDIT_UPDATE_TIMER );
  1142. m_bMouseOver = false;
  1143. }
  1144. else 
  1145. {
  1146. HWND hWndFromPoint = ::WindowFromPoint( pt );
  1147. if( hWndFromPoint == m_hWnd )
  1148. m_bMouseOver = true;
  1149. else
  1150. {
  1151. for( HWND hWnd = ::GetWindow( m_hWnd, GW_CHILD ); hWnd != NULL; hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ) )
  1152. {
  1153. if( hWnd != NULL && ::IsWindow( hWnd ) )
  1154. {
  1155. if( hWnd == hWndFromPoint )
  1156. {
  1157. m_bMouseOver = true;
  1158. break;
  1159. }
  1160. }
  1161. }
  1162. }
  1163. }
  1164. if( bOldMouseOver != m_bMouseOver )
  1165. _PostRedraw();
  1166. } // if( IsWindowVisible() )
  1167. }
  1168. void CExtIPAddressCtrl::_PostRedraw()
  1169. {
  1170. VERIFY(
  1171. RedrawWindow(
  1172. NULL,
  1173. NULL,
  1174. RDW_INVALIDATE | RDW_UPDATENOW
  1175. | RDW_ERASE | RDW_ERASENOW
  1176. | RDW_FRAME | RDW_ALLCHILDREN
  1177. )
  1178. );
  1179. }
  1180. void CExtIPAddressCtrl::_DrawEditImpl(
  1181. CRect rectClient,
  1182. CDC * pDC // = NULL
  1183. )
  1184. {
  1185. bool bNeedReleaseDC = false;
  1186. if( pDC == NULL )
  1187. {
  1188. pDC = GetDC();
  1189. bNeedReleaseDC = true;
  1190. }
  1191. ASSERT_VALID( pDC );
  1192. bool bFocus = false;
  1193. if( ! CExtPopupMenuWnd::IsMenuTracking() )
  1194. {
  1195. HWND hWndFocused = GetFocus()->GetSafeHwnd();
  1196. if( hWndFocused == m_hWnd )
  1197. bFocus = true;
  1198. else
  1199. {
  1200. for( HWND hWnd = ::GetWindow( m_hWnd, GW_CHILD ); hWnd != NULL; hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ) )
  1201. {
  1202. if( hWnd != NULL && ::IsWindow( hWnd ) )
  1203. {
  1204. if( hWnd == hWndFocused )
  1205. {
  1206. bFocus = true;
  1207. break;
  1208. }
  1209. }
  1210. }
  1211. }
  1212. }
  1213. rectClient.InflateRect( 3, 3 );
  1214. bool bEnabled = IsWindowEnabled() ? true : false;
  1215. bool bReadOnly = ( ( GetStyle() & ES_READONLY ) != 0 ) ? true : false;
  1216. CExtPaintManager::PAINTCONTROLFRAMEDATA _pcfd( this, rectClient, true, m_bMouseOver, bEnabled, bFocus, bReadOnly );
  1217. PmBridge_GetPM()->PaintControlFrame( *pDC, _pcfd );
  1218. if( bNeedReleaseDC )
  1219. ReleaseDC(pDC);
  1220. }
  1221. void CExtIPAddressCtrl::OnSetFocus(CWnd* pOldWnd) 
  1222. {
  1223. CIPAddressCtrl::OnSetFocus(pOldWnd);
  1224. _PostRedraw();
  1225. }
  1226. void CExtIPAddressCtrl::OnKillFocus(CWnd* pNewWnd) 
  1227. {
  1228. CIPAddressCtrl::OnKillFocus(pNewWnd);
  1229. _PostRedraw();
  1230. }
  1231. void CExtIPAddressCtrl::OnNcPaint() 
  1232. {
  1233. ASSERT_VALID( this );
  1234. CWindowDC dc( this );
  1235. _DoPaintNC( &dc );
  1236. }
  1237. void CExtIPAddressCtrl::_DoPaintNC( CDC * pDC )
  1238. {
  1239. ASSERT_VALID( this );
  1240. ASSERT_VALID( pDC );
  1241. ASSERT( pDC->GetSafeHdc() != NULL );
  1242. if( ! m_bInitialized )
  1243. return;
  1244. CRect rcInBarWnd, rcInBarClient;
  1245.     GetWindowRect( &rcInBarWnd );
  1246.     GetClientRect( &rcInBarClient );
  1247.     ClientToScreen( &rcInBarClient );
  1248.     if( rcInBarWnd == rcInBarClient )
  1249.         return;
  1250. CPoint ptDevOffset = -rcInBarWnd.TopLeft();
  1251.     rcInBarWnd.OffsetRect( ptDevOffset );
  1252.     rcInBarClient.OffsetRect( ptDevOffset );
  1253. const INT cx = ::GetSystemMetrics( SM_CXVSCROLL );
  1254. const INT cy = ::GetSystemMetrics( SM_CYHSCROLL );
  1255. DWORD dwStyle = GetStyle();
  1256. bool bHasVerticalSB = ( ( dwStyle & WS_VSCROLL ) != 0 ) ? true : false;
  1257. bool bHasHorizontalSB = ( ( dwStyle & WS_HSCROLL ) != 0 ) ? true : false;
  1258.     if( bHasVerticalSB && bHasHorizontalSB )
  1259.     {
  1260. INT nNcX = rcInBarWnd.right - rcInBarClient.right - cx;
  1261. INT nNcY = rcInBarWnd.bottom - rcInBarClient.bottom - cy;
  1262.         pDC->FillSolidRect(
  1263.             rcInBarWnd.right - cx - nNcX, rcInBarWnd.bottom - cy - nNcY, cx, cy,
  1264.             PmBridge_GetPM()->GetColor( COLOR_WINDOW, this )
  1265.             );
  1266.     }
  1267. CRect rcExclude( rcInBarClient );
  1268.     if( bHasVerticalSB )
  1269.         rcExclude.right += cx;
  1270.     if( bHasHorizontalSB )
  1271.         rcExclude.bottom += cy;
  1272. pDC->ExcludeClipRect( &rcExclude );
  1273.     if( bHasVerticalSB || bHasHorizontalSB )
  1274. Default();
  1275. rcInBarWnd.DeflateRect( 3, 3 );
  1276. _DrawEditImpl( rcInBarWnd, pDC );
  1277. pDC->SelectClipRgn( NULL );
  1278. }
  1279. LRESULT CExtIPAddressCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  1280. {
  1281. if( message == WM_PRINT 
  1282. || message == WM_PRINTCLIENT
  1283. )
  1284. {
  1285. CDC * pDC = CDC::FromHandle( (HDC) wParam );
  1286. CRect rcWnd;
  1287. GetWindowRect( &rcWnd );
  1288. rcWnd.OffsetRect( -rcWnd.TopLeft() );
  1289. CExtMemoryDC dc( pDC, &rcWnd );
  1290. if( ( lParam & PRF_NONCLIENT ) != 0 )
  1291. _DoPaintNC( &dc );
  1292. if( ( lParam & PRF_CHILDREN ) != 0 )
  1293. CExtPaintManager::stat_PrintChildren( m_hWnd, message, dc.GetSafeHdc(), lParam, false );
  1294. return (!0);
  1295. }
  1296. return CIPAddressCtrl::WindowProc(message, wParam, lParam);
  1297. }
  1298. void CExtIPAddressCtrl::OnDestroy() 
  1299. {
  1300. POSITION pos = g_listTargets.Find( this );
  1301. if( pos == NULL )
  1302. return;
  1303. g_listTargets.RemoveAt( pos );
  1304. for( INT nIndexWnd = 0; nIndexWnd < 4; nIndexWnd++ )
  1305. {
  1306. if( m_hWndHooked[ nIndexWnd ] != NULL
  1307. && ::IsWindow(m_hWndHooked[ nIndexWnd ])
  1308. && m_pWNDPROC[ nIndexWnd ] != NULL
  1309. )
  1310. {
  1311. ::__EXT_MFC_SetWindowLong(
  1312. m_hWndHooked[ nIndexWnd ],
  1313. __EXT_MFC_GWL_WNDPROC,
  1314. #if defined(_WIN64)
  1315. (__EXT_MFC_LONG_PTR)
  1316. #else
  1317. (LONG)(__EXT_MFC_LONG_PTR)
  1318. #endif
  1319. m_pWNDPROC[ nIndexWnd ]
  1320. );
  1321. }
  1322. }
  1323. CIPAddressCtrl::OnDestroy();
  1324. }
  1325. LRESULT CALLBACK CExtIPAddressCtrl::g_HookWndProc( HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam )
  1326. {
  1327. for( POSITION pos = g_listTargets.GetHeadPosition(); pos != NULL; )
  1328. {
  1329. CExtIPAddressCtrl * pWndTarget = g_listTargets.GetNext( pos );
  1330. if( pWndTarget != NULL && pWndTarget->GetSafeHwnd() != NULL )
  1331. {
  1332. if( nMessage == WM_SETCURSOR )
  1333.   ::SendMessage( pWndTarget->m_hWnd, nMessage, wParam, lParam );
  1334. else if( nMessage == WM_SETFOCUS || nMessage == WM_KILLFOCUS )
  1335.   pWndTarget->RedrawWindow( NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_ERASENOW|RDW_FRAME|RDW_ALLCHILDREN );
  1336. for( INT nIndexWnd = 0; nIndexWnd < 4; nIndexWnd++ )
  1337. {
  1338. HWND hWndHooked = pWndTarget->m_hWndHooked[ nIndexWnd ];
  1339. WNDPROC pWNDPROC  = pWndTarget->m_pWNDPROC[ nIndexWnd ];
  1340. if( hWndHooked != NULL && ::IsWindow(hWndHooked) && hWndHooked == hWnd )
  1341. {
  1342. ASSERT( pWNDPROC != NULL );
  1343. return ::CallWindowProc( pWNDPROC, hWnd, nMessage, wParam, lParam );
  1344. }
  1345. }
  1346. }
  1347. } // for( POSITION pos = g_listTargets.GetHeadPosition(); pos != NULL; )
  1348. return 0L;
  1349. }
  1350. void CExtIPAddressCtrl::PreSubclassWindow() 
  1351. {
  1352. CIPAddressCtrl::PreSubclassWindow();
  1353. if( m_bDirectCreateCall )
  1354. return;
  1355. if( ! _CreateHelper() )
  1356. {
  1357. ASSERT( FALSE );
  1358. return;
  1359. }
  1360. m_bInitialized = true;
  1361. }
  1362. BOOL CExtIPAddressCtrl::Create(
  1363. DWORD dwStyle, 
  1364. const RECT & rect,
  1365. CWnd * pParentWnd, 
  1366. UINT nID
  1367. )
  1368. {
  1369. if( ! CIPAddressCtrl::Create( dwStyle, rect, pParentWnd, nID ) )
  1370. {
  1371. ASSERT( FALSE );
  1372. return FALSE;
  1373. }
  1374. return TRUE;
  1375. }
  1376. BOOL CExtIPAddressCtrl::Create(
  1377. LPCTSTR lpszClassName, 
  1378. LPCTSTR lpszWindowName, 
  1379. DWORD dwStyle, 
  1380. const RECT & rect, 
  1381. CWnd * pParentWnd, 
  1382. UINT nID, CCreateContext * pContext
  1383. {
  1384. ASSERT_VALID( this );
  1385. m_bDirectCreateCall = true;
  1386. if( ! CWnd::Create( lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext ) )
  1387. {
  1388. ASSERT( FALSE );
  1389. return FALSE;
  1390. }
  1391. if( ! _CreateHelper() )
  1392. {
  1393. ASSERT( FALSE );
  1394. return FALSE;
  1395. }
  1396. m_bInitialized = true;
  1397. return TRUE;
  1398. }
  1399. bool CExtIPAddressCtrl::_CreateHelper()
  1400. {
  1401. ASSERT_VALID( this );
  1402. if( m_bInitialized )
  1403. return true;
  1404. if( m_hWnd == NULL || ( !::IsWindow( m_hWnd ) ) )
  1405. return false;
  1406. // hook all the child edit controls
  1407. POSITION pos = g_listTargets.Find( this );
  1408. if( pos == NULL )
  1409. g_listTargets.AddHead( this );
  1410. bool bInit = false;
  1411. INT nIndexWnd = 0;
  1412. for( HWND hWnd = ::GetWindow( m_hWnd, GW_CHILD ); ((hWnd != NULL) && (nIndexWnd < 4)); hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ), nIndexWnd++ )
  1413. {
  1414. m_hWndHooked[ nIndexWnd ] = hWnd;
  1415. if( m_hWndHooked[ nIndexWnd ] == NULL || (!::IsWindow(m_hWndHooked[ nIndexWnd ])) )
  1416. {
  1417. ASSERT( FALSE );
  1418. bInit = false;
  1419. break;
  1420. }
  1421. bInit = true;
  1422. m_pWNDPROC[ nIndexWnd ] = (WNDPROC)(__EXT_MFC_LONG_PTR)
  1423. ::__EXT_MFC_SetWindowLong(
  1424. m_hWndHooked[ nIndexWnd ],
  1425. __EXT_MFC_GWL_WNDPROC,
  1426. #if defined(_WIN64)
  1427. (__EXT_MFC_LONG_PTR)
  1428. #else
  1429. (LONG)(__EXT_MFC_LONG_PTR)
  1430. #endif
  1431. g_HookWndProc
  1432. );
  1433. ASSERT( m_pWNDPROC[ nIndexWnd ] != NULL );
  1434. }
  1435. if( ! bInit )
  1436. return false;
  1437. return true;
  1438. }
  1439. /////////////////////////////////////////////////////////////////////////////
  1440. // CExtEditHotKeyBase window
  1441. IMPLEMENT_DYNCREATE( CExtEditHotKeyBase, CExtEditBase );
  1442. CExtEditHotKeyBase::CExtEditHotKeyBase()
  1443. : m_bAllowTabKeyInput( false )
  1444. , m_nSimpleKeyModifiers( (BYTE)0 )
  1445. {
  1446. ::memset( &m_dataAccel, 0, sizeof(ACCEL) );
  1447. }
  1448. CExtEditHotKeyBase::~CExtEditHotKeyBase()
  1449. {
  1450. }
  1451. BEGIN_MESSAGE_MAP( CExtEditHotKeyBase, CExtEditBase )
  1452.     //{{AFX_MSG_MAP(CExtEditHotKeyBase)
  1453. //}}AFX_MSG_MAP
  1454. END_MESSAGE_MAP()
  1455. CExtSafeString CExtEditHotKeyBase::stat_GetSingleKeyName(
  1456. HKL hKeyboardLayout,
  1457. WORD nKey,
  1458. __EXT_MFC_SAFE_LPCTSTR strAppendIfNonEmpty, // = NULL
  1459. bool bMakeOnlyFirstLettersUpper // = true
  1460. )
  1461. {
  1462. UINT nScan = ::MapVirtualKeyEx( (UINT)nKey, 0, hKeyboardLayout );
  1463. nScan &= 0x0FFFF;
  1464. switch( nKey )
  1465. {
  1466. case VK_INSERT:
  1467. case VK_DELETE:
  1468. case VK_PRIOR:
  1469. case VK_NEXT:
  1470. case VK_END:
  1471. case VK_HOME:
  1472. case VK_LEFT:
  1473. case VK_UP:
  1474. case VK_RIGHT:
  1475. case VK_DOWN:
  1476. case VK_SELECT:
  1477. case VK_PRINT:
  1478. case VK_EXECUTE:
  1479. case VK_SNAPSHOT:
  1480. case VK_HELP:
  1481. nScan |= 0x0300;
  1482. break;
  1483. } // switch( nKey )
  1484. LPARAM lParam = MAKELPARAM( 1, nScan );
  1485. const int nMaxKeyName = 256;
  1486. CExtSafeString strKeyText;
  1487. LPTSTR pBuffer = strKeyText.GetBuffer(nMaxKeyName);
  1488. ASSERT( pBuffer != NULL );
  1489. ::memset( pBuffer, 0, nMaxKeyName*sizeof(TCHAR) );
  1490. ::GetKeyNameText( (LONG)lParam, pBuffer, nMaxKeyName );
  1491. strKeyText.ReleaseBuffer();
  1492. if( strKeyText.IsEmpty())
  1493. return strKeyText;
  1494. if( ! bMakeOnlyFirstLettersUpper )
  1495. {
  1496. if( strAppendIfNonEmpty != NULL )
  1497. strKeyText += strAppendIfNonEmpty;
  1498. return strKeyText;
  1499. }
  1500. strKeyText.MakeLower();
  1501. bool bPrevSpace = true;
  1502. for( int i = 0; i < strKeyText.GetLength(); i++ )
  1503. {
  1504. TCHAR chr = strKeyText[i];
  1505. if( _istspace(chr) )
  1506. {
  1507. bPrevSpace = true;
  1508. continue;
  1509. } // if( _istspace(chr) )
  1510. if( _istalpha(chr) && bPrevSpace )
  1511. {
  1512. chr = (TCHAR)_totupper( chr );
  1513. strKeyText.SetAt( i, chr );
  1514. } // if( _istalpha(chr) && bPrevSpace )
  1515. bPrevSpace = false;
  1516. } // for( int i = 0; i < strKeyText.GetLength(); i++ )
  1517. if( strAppendIfNonEmpty != NULL )
  1518. strKeyText += strAppendIfNonEmpty;
  1519. return strKeyText;
  1520. }
  1521. CExtSafeString CExtEditHotKeyBase::stat_FormatAccelText( const ACCEL & _dataAccel )
  1522. {
  1523. HKL hKeyboardLayout = ::GetKeyboardLayout( ( ::AfxGetThread() ) -> m_nThreadID );
  1524. static TCHAR strTextBetweenKeys[] = _T("+");
  1525. CExtSafeString strAccelText;
  1526. if( _dataAccel.fVirt & FCONTROL )
  1527. strAccelText += CExtEditHotKeyBase::stat_GetSingleKeyName( hKeyboardLayout, VK_CONTROL, strTextBetweenKeys );
  1528. if( _dataAccel.fVirt & FSHIFT )
  1529. strAccelText += CExtEditHotKeyBase::stat_GetSingleKeyName( hKeyboardLayout, VK_SHIFT, strTextBetweenKeys );
  1530. if( _dataAccel.fVirt & FALT )
  1531. strAccelText += CExtEditHotKeyBase::stat_GetSingleKeyName( hKeyboardLayout, VK_MENU, strTextBetweenKeys );
  1532. if( _dataAccel.key == 0 )
  1533. return strAccelText;
  1534. if( _dataAccel.fVirt & FVIRTKEY )
  1535. strAccelText += CExtEditHotKeyBase::stat_GetSingleKeyName( hKeyboardLayout, _dataAccel.key );
  1536. else
  1537. strAccelText += (TCHAR)_dataAccel.key;
  1538. return strAccelText;
  1539. }
  1540. void CExtEditHotKeyBase::_SyncEditText()
  1541. {
  1542. ASSERT_VALID( this );
  1543. if( GetSafeHwnd() == NULL || ( ! ::IsWindow(GetSafeHwnd()) ) )
  1544. return;
  1545. CExtSafeString strText = OnGetAccelText();
  1546. SetRedraw( FALSE );
  1547. CExtEditBase::SetSel( 0, -1 );
  1548. CExtEditBase::ReplaceSel( strText );
  1549. CExtEditBase::SetSel( -1, -1 );
  1550. SetRedraw( TRUE );
  1551. Invalidate();
  1552. }
  1553. bool CExtEditHotKeyBase::IsAccelDefined() const
  1554. {
  1555. if( KeyGet() != 0 )
  1556. return true;
  1557. return false;
  1558. }
  1559. bool CExtEditHotKeyBase::IsEmpty() const
  1560. {
  1561. ASSERT_VALID( this );
  1562. if( KeyGet() == 0 && ModifiersGet() == 0 )
  1563. return true;
  1564. return false;
  1565. }
  1566. void CExtEditHotKeyBase::Empty()
  1567. {
  1568. _Empty();
  1569. _SyncEditText();
  1570. }
  1571. void CExtEditHotKeyBase::_Empty()
  1572. {
  1573. ASSERT_VALID( this );
  1574. ::memset( &m_dataAccel, 0, sizeof(ACCEL) );
  1575. }
  1576. const ACCEL & CExtEditHotKeyBase::AccelGet() const
  1577. {
  1578. ASSERT_VALID( this );
  1579. return m_dataAccel;
  1580. }
  1581. void CExtEditHotKeyBase::AccelSet( const ACCEL & _dataAccel )
  1582. {
  1583. ASSERT_VALID( this );
  1584. __EXT_MFC_MEMCPY( &m_dataAccel, sizeof(ACCEL), &_dataAccel, sizeof(ACCEL) );
  1585. _SyncEditText();
  1586. }
  1587. WORD CExtEditHotKeyBase::KeyGet() const
  1588. {
  1589. ASSERT_VALID( this );
  1590. return m_dataAccel.key;
  1591. }
  1592. void CExtEditHotKeyBase::KeySet( WORD nKey )
  1593. {
  1594. ASSERT_VALID( this );
  1595. if( m_dataAccel.key == nKey )
  1596. return;
  1597. m_dataAccel.key = nKey;
  1598. _SyncEditText();
  1599. OnAccelChanged();
  1600. if( IsAccelDefined() )
  1601. OnAccelDefined();
  1602. }
  1603. BYTE CExtEditHotKeyBase::ModifiersGet() const
  1604. {
  1605. ASSERT_VALID( this );
  1606. return m_dataAccel.fVirt;
  1607. }
  1608. void CExtEditHotKeyBase::ModifiersSet( BYTE nModifiers )
  1609. {
  1610. ASSERT_VALID( this );
  1611. if( m_dataAccel.fVirt == nModifiers )
  1612. return;
  1613. m_dataAccel.fVirt = nModifiers;
  1614. _SyncEditText();
  1615. OnAccelChanged();
  1616. if( IsAccelDefined() )
  1617. OnAccelDefined();
  1618. }
  1619. BYTE CExtEditHotKeyBase::SimpleKeyModifiersGet() const
  1620. {
  1621. ASSERT_VALID( this );
  1622. return m_nSimpleKeyModifiers;
  1623. }
  1624. void CExtEditHotKeyBase::SimpleKeyModifiersSet( 
  1625. BYTE nModifiers 
  1626. )
  1627. {
  1628. ASSERT_VALID( this );
  1629. m_nSimpleKeyModifiers = nModifiers;
  1630. m_nSimpleKeyModifiers &= FCONTROL|FALT|FSHIFT;
  1631. }
  1632. bool CExtEditHotKeyBase::AllowTabKeyInputGet() const
  1633. {
  1634. ASSERT_VALID( this );
  1635. return m_bAllowTabKeyInput;
  1636. }
  1637. void CExtEditHotKeyBase::AllowTabKeyInputSet( 
  1638. bool bAllowTabKeyInput 
  1639. )
  1640. {
  1641. ASSERT_VALID( this );
  1642. m_bAllowTabKeyInput = bAllowTabKeyInput;
  1643. }
  1644. CExtSafeString CExtEditHotKeyBase::OnGetEmptyText()
  1645. {
  1646. ASSERT_VALID( this );
  1647. return CExtSafeString( _T("") );
  1648. }
  1649. CExtSafeString CExtEditHotKeyBase::OnGetAccelText()
  1650. {
  1651. ASSERT_VALID( this );
  1652. if( IsEmpty() ) 
  1653. return OnGetEmptyText();
  1654. CExtSafeString strText = stat_FormatAccelText( m_dataAccel );
  1655. return strText;
  1656. }
  1657. bool CExtEditHotKeyBase::OnTestEraseAccel( 
  1658. const ACCEL & _dataAccel 
  1659. )
  1660. {
  1661. ASSERT_VALID( this );
  1662. if( ( _dataAccel.key == VK_BACK
  1663. || _dataAccel.key == VK_DELETE
  1664. || _dataAccel.key == VK_ESCAPE
  1665. )
  1666. && ( _dataAccel.fVirt&(FCONTROL|FALT|FSHIFT) ) == 0
  1667. )
  1668. return true;
  1669. return false;
  1670. }
  1671. bool CExtEditHotKeyBase::OnAccelChanging( const ACCEL & _dataAccelOld, const ACCEL & _dataAccelNew )
  1672. {
  1673. ASSERT_VALID( this );
  1674. _dataAccelOld;
  1675. _dataAccelNew;
  1676. return true; // allow any changes
  1677. }
  1678. void CExtEditHotKeyBase::OnAccelChanged()
  1679. {
  1680. ASSERT_VALID( this );
  1681. }
  1682. void CExtEditHotKeyBase::OnAccelDefined()
  1683. {
  1684. ASSERT_VALID( this );
  1685. }
  1686. bool CExtEditHotKeyBase::OnTestSimpleKey( WORD nKey  )
  1687. {
  1688. ASSERT_VALID( this );
  1689. if( ( 0x30 <= nKey && nKey <= 0x39 ) // Numbers
  1690. || ( 0x41 <= nKey && nKey <= 0x5A ) // Letters
  1691. || nKey == VK_SPACE
  1692. || nKey == 0xC0 // '`'
  1693. || nKey == 0xBD // '-'
  1694. || nKey == 0xBB // '='
  1695. || nKey == 0xDC // '\'
  1696. || nKey == 0xDB // '['
  1697. || nKey == 0xDD // ']'
  1698. || nKey == 0xBA // ';'
  1699. || nKey == 0xDE // '''
  1700. || nKey == 0xBC // ','
  1701. || nKey == 0xBE // '.'
  1702. || nKey == 0xBF // '/'
  1703. || nKey == VK_LEFT
  1704. || nKey == VK_RIGHT
  1705. || nKey == VK_UP
  1706. || nKey == VK_DOWN
  1707. || nKey == VK_INSERT
  1708. || nKey == VK_DELETE
  1709. || nKey == VK_HOME
  1710. || nKey == VK_END
  1711. || nKey == VK_PRIOR
  1712. || nKey == VK_NEXT
  1713. )
  1714. return true;
  1715. return false;
  1716. }
  1717. bool CExtEditHotKeyBase::OnTestDisabledKey( WORD nKey )
  1718. {
  1719. ASSERT_VALID( this );
  1720. if( nKey == VK_NUMLOCK
  1721. || nKey == VK_PRINT
  1722. || nKey == VK_PAUSE
  1723. )
  1724. return true;
  1725. return false;
  1726. }
  1727. BOOL CExtEditHotKeyBase::PreTranslateMessage( MSG * pMsg )
  1728. {
  1729. ASSERT_VALID( this );
  1730. if( pMsg->message != WM_KEYDOWN
  1731. && pMsg->message != WM_KEYUP
  1732. && pMsg->message != WM_SYSKEYDOWN
  1733. && pMsg->message != WM_SYSKEYUP
  1734. )
  1735. return CExtEditBase::PreTranslateMessage( pMsg );
  1736. if( OnTestDisabledKey( (WORD)pMsg->wParam ) )
  1737. return TRUE;
  1738. HWND hWndFocus = ::GetFocus();
  1739. if( hWndFocus == NULL || hWndFocus != m_hWnd )
  1740. return CExtEditBase::PreTranslateMessage( pMsg );
  1741. bool bDown = ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN ) ? true : false;
  1742. if( ! bDown )
  1743. return TRUE;
  1744. bool bAlt = ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 ) ? true : false;
  1745. bool bCtrl = ( (::GetAsyncKeyState(VK_CONTROL)&0x8000) != 0 ) ? true : false;
  1746. bool bShift = ( (::GetAsyncKeyState(VK_SHIFT)&0x8000) != 0 ) ? true : false;
  1747. if( pMsg->wParam == VK_TAB && (!AllowTabKeyInputGet()) )
  1748. {
  1749. if( bAlt || bCtrl )
  1750. return TRUE;
  1751. ::SendMessage( ::GetParent(m_hWnd), WM_NEXTDLGCTL, bShift ? 1 : 0, 0 );
  1752. return TRUE;
  1753. } // if( pMsg->wParam == VK_TAB && (!AllowTabKeyInputGet()) )
  1754. ACCEL _dataAccelSave;
  1755. __EXT_MFC_MEMCPY(
  1756. &_dataAccelSave,
  1757. sizeof(ACCEL),
  1758. &m_dataAccel, 
  1759. sizeof(ACCEL) 
  1760. );
  1761. _Empty();
  1762. m_dataAccel.fVirt &= ~(FCONTROL|FALT|FSHIFT);
  1763. if( pMsg->wParam != VK_CONTROL
  1764. && pMsg->wParam != VK_MENU
  1765. && pMsg->wParam != VK_SHIFT
  1766. )
  1767. {
  1768. m_dataAccel.fVirt |= FVIRTKEY;
  1769. m_dataAccel.key = (WORD)pMsg->wParam;
  1770. }
  1771. else
  1772. m_dataAccel.key = 0;
  1773. if( bCtrl )
  1774. m_dataAccel.fVirt |= FCONTROL;
  1775. if( bAlt )
  1776. m_dataAccel.fVirt |= FALT;
  1777. if( bShift )
  1778. m_dataAccel.fVirt |= FSHIFT;
  1779. if( ( m_dataAccel.fVirt&(FCONTROL|FALT|FSHIFT) ) == 0
  1780. && SimpleKeyModifiersGet() != 0
  1781. && OnTestSimpleKey( m_dataAccel.key )
  1782. )
  1783. m_dataAccel.fVirt |= SimpleKeyModifiersGet();
  1784. if( OnTestEraseAccel(m_dataAccel) )
  1785. _Empty();
  1786. if( ::memcmp( &_dataAccelSave, &m_dataAccel, sizeof(ACCEL) ) == 0 )
  1787. return TRUE;
  1788. if( ! OnAccelChanging( _dataAccelSave, m_dataAccel ) )
  1789. {
  1790. __EXT_MFC_MEMCPY( &m_dataAccel, sizeof(ACCEL), &_dataAccelSave, sizeof(ACCEL) );
  1791. return TRUE;
  1792. }
  1793. _SyncEditText();
  1794. OnAccelChanged();
  1795. if( IsAccelDefined() )
  1796. OnAccelDefined();
  1797. return TRUE;
  1798. }
  1799. LRESULT CExtEditHotKeyBase::WindowProc(
  1800. UINT message,
  1801. WPARAM wParam,
  1802. LPARAM lParam
  1803. )
  1804. {
  1805. if( WM_KEYFIRST <= message && message <= WM_KEYLAST )
  1806. return 0;
  1807. if( message == WM_COPY
  1808. || message == WM_CUT
  1809. || message == WM_PASTE
  1810. || message == WM_CLEAR
  1811. || message == EM_UNDO
  1812. )
  1813. return 0;
  1814. if( message == WM_RBUTTONUP
  1815. || message == WM_RBUTTONDOWN
  1816. || message == WM_RBUTTONDBLCLK
  1817. )
  1818. {
  1819. if( ::GetFocus() != m_hWnd )
  1820. SetFocus();
  1821. return 0;
  1822. }
  1823. return CExtEditBase::WindowProc( message, wParam, lParam );
  1824. }
  1825. /////////////////////////////////////////////////////////////////////////////
  1826. // CExtEditHotKey
  1827. IMPLEMENT_DYNCREATE( CExtEditHotKey, CExtEditHotKeyBase );
  1828. CExtEditHotKey::CExtEditHotKey()
  1829. {
  1830. }
  1831. CExtEditHotKey::~CExtEditHotKey()
  1832. {
  1833. }
  1834. BEGIN_MESSAGE_MAP(CExtEditHotKey, CExtED < CExtEditHotKeyBase >)
  1835. //{{AFX_MSG_MAP(CExtEditHotKey)
  1836. //}}AFX_MSG_MAP
  1837. END_MESSAGE_MAP()
  1838. void AFXAPI __EXT_MFC_DDX_HotKey( CDataExchange * pDX, INT nIDC, ACCEL & value )
  1839. {
  1840. HWND hWndCtrl = pDX->PrepareCtrl( nIDC );
  1841. ASSERT( hWndCtrl != NULL );
  1842. ASSERT( ::IsWindow( hWndCtrl ) );
  1843. CExtEditHotKey * pWnd = 
  1844. DYNAMIC_DOWNCAST( CExtEditHotKey, CWnd::FromHandle( hWndCtrl ) );
  1845. if( pWnd != NULL )
  1846. {
  1847. ASSERT_VALID( pWnd );
  1848. if( pDX->m_bSaveAndValidate )
  1849. value = pWnd->AccelGet();
  1850. else
  1851. pWnd->AccelSet( value );
  1852. }
  1853. }
  1854. /////////////////////////////////////////////////////////////////////////////
  1855. // CExtEditWithBehavior
  1856. IMPLEMENT_DYNAMIC( CExtEditWithBehavior, CExtEdit );
  1857. CExtEditWithBehavior::CExtEditWithBehavior()
  1858. : m_nInternalFlags( __EISF_CLEAN )
  1859. , m_bRichPainting( false )
  1860. , m_clrRichTextNormal( COLORREF(-1L) )
  1861. , m_clrRichTextReadOnly( COLORREF(-1L) )
  1862. , m_clrRichTextDisabled( COLORREF(-1L) )
  1863. , m_clrRichBackNormal( COLORREF(-1L) )
  1864. , m_clrRichBackReadOnly( COLORREF(-1L) )
  1865. , m_clrRichBackDisabled( COLORREF(-1L) )
  1866. {
  1867. }
  1868. CExtEditWithBehavior::~CExtEditWithBehavior()
  1869. {
  1870. }
  1871. BEGIN_MESSAGE_MAP( CExtEditWithBehavior, CExtEdit )
  1872. //{{AFX_MSG_MAP(CExtEditWithBehavior)
  1873. ON_WM_KEYDOWN()
  1874. // ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
  1875. // ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
  1876. //}}AFX_MSG_MAP
  1877. ON_MESSAGE( WM_CUT, OnCut )
  1878. ON_MESSAGE( WM_PASTE, OnPaste )
  1879. ON_MESSAGE( WM_CLEAR, OnClear )
  1880. ON_MESSAGE( WM_SETTEXT, OnSetText )
  1881. ON_NOTIFY_REFLECT( EN_PROTECTED, OnProtected )
  1882. END_MESSAGE_MAP()
  1883. void CExtEditWithBehavior::PreSubclassWindow()
  1884. {
  1885. CExtEdit::PreSubclassWindow();
  1886. m_bRichMode = false;
  1887. CExtSafeString sClassName;
  1888. ::GetClassName( m_hWnd, LPTSTR( sClassName.GetBuffer( _MAX_PATH+1 ) ), _MAX_PATH );
  1889. sClassName.ReleaseBuffer();
  1890. sClassName.MakeLower();
  1891. if( sClassName.Find( _T("rich") ) >= 0 )
  1892. {
  1893. m_bRichMode = true;
  1894. m_bRichPainting = true;
  1895. ::SendMessage( m_hWnd, EM_SETEVENTMASK, 0, ENM_CHANGE|ENM_SELCHANGE|ENM_PROTECTED );
  1896. ::SendMessage( m_hWnd, EM_SETOPTIONS, WPARAM(ECOOP_AND), LPARAM(ECO_AUTOWORDSELECTION|ECO_AUTOHSCROLL /*|ECO_NOHIDESEL*/ ) );
  1897. static CExtNotImplRichEditOleCallBack g_stat_cb_not_impl;
  1898. ::SendMessage( m_hWnd, EM_SETOLECALLBACK, 0, (LPARAM)(&g_stat_cb_not_impl) );
  1899. CHARFORMAT cfDefault;
  1900. ::memset( &cfDefault, 0, sizeof(CHARFORMAT) );
  1901. cfDefault.cbSize = sizeof(CHARFORMAT);
  1902. cfDefault.dwMask = CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_PROTECTED|CFM_COLOR;
  1903. cfDefault.dwEffects = CFE_PROTECTED; 
  1904. //cfDefault.yHeight = 180;
  1905. //cfDefault.crTextColor = ::GetSysColor( COLOR_WINDOWTEXT );
  1906. CFont * pFont = GetFont();
  1907. if( pFont->GetSafeHandle() == NULL )
  1908. {
  1909. CWnd * pWndParent = GetParent();
  1910. if( pWndParent->GetSafeHwnd() != NULL )
  1911. pFont = pWndParent->GetFont();
  1912. if( pFont->GetSafeHandle() == NULL )
  1913. pFont = &(PmBridge_GetPM()->m_FontNormal);
  1914. }
  1915. LOGFONT _lf; ::memset( &_lf, 0, sizeof(LOGFONT) );
  1916. pFont->GetLogFont( &_lf );
  1917. #if (! defined _RICHEDIT_VER )
  1918. USES_CONVERSION;
  1919. strcpy( cfDefault.szFaceName, T2CA(_lf.lfFaceName) );
  1920. #else
  1921. #if ( _RICHEDIT_VER < 0x0200 )
  1922. USES_CONVERSION;
  1923. strcpy( cfDefault.szFaceName, T2CA(_lf.lfFaceName) );
  1924. #else
  1925. __EXT_MFC_STRCPY( cfDefault.szFaceName, sizeof(cfDefault.szFaceName)/sizeof(cfDefault.szFaceName[0]), _lf.lfFaceName );
  1926. #endif
  1927. #endif
  1928. CWindowDC dcDesktop( NULL );
  1929. cfDefault.yHeight = ::MulDiv( _lf.lfHeight, 72 * 20, dcDesktop.GetDeviceCaps( LOGPIXELSY ) );
  1930. cfDefault.yHeight = abs( cfDefault.yHeight );
  1931. cfDefault.bCharSet = DEFAULT_CHARSET;
  1932. bool bEnabled = IsWindowEnabled() ? true : false, bReadOnly = ( ( GetStyle() & ES_READONLY ) != 0 ) ? true : false;
  1933. cfDefault.crTextColor = OnQueryTextColor();
  1934. if( cfDefault.crTextColor == COLORREF(-1L) )
  1935. {
  1936. cfDefault.crTextColor = bEnabled ? ( bReadOnly ? m_clrRichTextReadOnly : m_clrRichTextNormal ) : m_clrRichTextDisabled;
  1937. if( cfDefault.crTextColor == COLORREF(-1L) )
  1938. cfDefault.crTextColor = ::GetSysColor( bEnabled ? ( bReadOnly ? COLOR_3DSHADOW : COLOR_WINDOWTEXT ) : COLOR_GRAYTEXT );
  1939. }
  1940. COLORREF clrBack = OnQueryBackColor();
  1941. if( clrBack == COLORREF(-1L) )
  1942. {
  1943. clrBack = bEnabled ? ( bReadOnly ? m_clrRichBackReadOnly : m_clrRichBackNormal ) : m_clrRichBackDisabled;
  1944. if( clrBack == COLORREF(-1L) )
  1945. clrBack = ::GetSysColor( bEnabled ? ( bReadOnly ? COLOR_3DFACE : COLOR_WINDOW ) : COLOR_3DFACE );
  1946. }
  1947. Rich_SetBackgroundColor( FALSE, clrBack );
  1948. Rich_HideSelection( true, false );
  1949. CHARRANGE crRestore;
  1950. Rich_GetSel( crRestore );
  1951. Rich_SetSel( 0, -1 ); 
  1952. SendMessage( EM_SETCHARFORMAT, SCF_DEFAULT, LPARAM(&cfDefault) );
  1953. SendMessage( EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(&cfDefault) );
  1954. Rich_SetSelectionColor( cfDefault.crTextColor );
  1955. Rich_SetSel( crRestore );
  1956. Rich_HideSelection( false, false );
  1957. m_bRichPainting = false;
  1958. }
  1959. }
  1960. LRESULT CExtEditWithBehavior::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  1961. {
  1962. //  if( WM_KEYFIRST <= message && message <= WM_KEYLAST )
  1963. //  {
  1964. //  bool bAlt = ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 ) ? true : false;
  1965. //  bool bCtrl = ( (::GetAsyncKeyState(VK_CONTROL)&0x8000) != 0 ) ? true : false;
  1966. //  bool bShift = ( (::GetAsyncKeyState(VK_SHIFT)&0x8000) != 0 ) ? true : false;
  1967. //  if( ! bAlt )
  1968. //  {
  1969. //  if( bCtrl && ! bShift 
  1970. //  && ( INT(wParam) == VK_INSERT 
  1971. //  || INT(wParam) == INT( _T('C') )
  1972. //  )
  1973. //  )
  1974. //  {
  1975. //  if( message == WM_KEYDOWN )
  1976. //  SendMessage( WM_COPY, 0, 0 );
  1977. //  return 0L;
  1978. //  }
  1979. // 
  1980. //  if( ( bCtrl && (!bShift) && int(wParam) == int( _T('V') ) )
  1981. //  || ( (!bCtrl) && bShift && int(wParam) == VK_INSERT )
  1982. //  )
  1983. //  {
  1984. //  if( message == WM_KEYDOWN && ( GetStyle() & ES_READONLY ) == 0 )
  1985. //  SendMessage( WM_PASTE, 0, 0 );
  1986. //  return 0L;
  1987. //  }
  1988. //  if( ( bCtrl && (!bShift) && int(wParam) == int( _T('X') ) )
  1989. //  || ( (!bCtrl) && bShift && int(wParam) == VK_DELETE )
  1990. //  )
  1991. //  {
  1992. //  if( message == WM_KEYDOWN )
  1993. //  SendMessage( ( ( GetStyle() & ES_READONLY ) == 0 ) ? WM_CUT : WM_COPY, 0, 0 );
  1994. //  return 0L;
  1995. //  }
  1996. //  }
  1997. //  }
  1998. return CExtEdit::WindowProc( message, wParam, lParam );
  1999. }
  2000. void CExtEditWithBehavior::OnProtected( NMHDR * pNMHDR, LRESULT * pResult )
  2001. {
  2002. ASSERT_VALID( this );
  2003. if( ! m_bRichMode )
  2004. return;
  2005. ENPROTECTED * pEP = (ENPROTECTED*)pNMHDR;
  2006. (*pResult) = _Rich_OnProtected( pEP );
  2007. }
  2008. BOOL CExtEditWithBehavior::_Rich_OnProtected( ENPROTECTED * pEP )
  2009. {
  2010. ASSERT_VALID( this );
  2011. if( pEP->msg != EM_SETCHARFORMAT )
  2012. {
  2013. _Rich_OnDraw();
  2014. //HWND hWndParent = ::GetParent( m_hWnd );
  2015. //::SendMessage( hWndParent, WM_COMMAND, MAKEWPARAM( GetDlgCtrlID(), EN_CHANGE ), LPARAM(m_hWnd) );
  2016. }
  2017. return FALSE;
  2018. }
  2019. CExtSafeString CExtEditWithBehavior::TextGet() const
  2020. {
  2021. ASSERT_VALID( this );
  2022. CExtSafeString strRetVal( _T("") );
  2023. if( GetSafeHwnd() == NULL )
  2024. return strRetVal;
  2025. if( m_bRichMode )
  2026. strRetVal = Rich_PlainText_Get();
  2027. else
  2028. {
  2029. CString strText;
  2030. GetWindowText( strText );
  2031. strRetVal = LPCTSTR(strText);
  2032. }
  2033. return strRetVal;
  2034. }
  2035. CExtSafeString CExtEditWithBehavior::TextGetTrimmed() const
  2036. {
  2037. ASSERT_VALID( this );
  2038. CExtSafeString strText = TextGet();
  2039.     strText.TrimLeft();
  2040.     strText.TrimRight();
  2041.     return CExtSafeString( strText );
  2042. }
  2043. void CExtEditWithBehavior::TextSet( __EXT_MFC_SAFE_LPCTSTR strText )
  2044. {
  2045. ASSERT_VALID( this );
  2046. if( GetSafeHwnd() == NULL )
  2047. return;
  2048. LPCTSTR strTextToSet = (LPCTSTR(strText) != NULL) ? LPCTSTR(strText) : _T("");
  2049. if( m_bRichMode )
  2050. {
  2051. ASSERT( ! m_bRichPainting );
  2052. Rich_PlainText_Set( strTextToSet );
  2053. _Rich_OnDraw();
  2054. }
  2055. else
  2056. SetWindowText( strTextToSet );
  2057. }
  2058. void CExtEditWithBehavior::_Rich_OnDraw()
  2059. {
  2060. ASSERT_VALID( this );
  2061. // if( ! m_bRichMode )
  2062. // return;
  2063. // if( GetSafeHwnd() == NULL )
  2064. // return;
  2065. // if( m_bRichPainting )
  2066. // return;
  2067. // m_bRichPainting = true;
  2068. // . . .
  2069. // m_bRichPainting = false;
  2070. }
  2071. CExtSafeString CExtEditWithBehavior::TextGetValid() const
  2072. {
  2073. ASSERT_VALID( this );
  2074. return TextGet();
  2075. }
  2076. void CExtEditWithBehavior::_UpdateContent()
  2077. {
  2078. ASSERT_VALID( this );
  2079. if( GetSafeHwnd() == NULL )
  2080. return;
  2081. CExtSafeString strTextValid = TextGetValid();
  2082. CExtSafeString strTextCurrent = TextGet();
  2083. if( strTextValid != strTextCurrent )
  2084. {
  2085. //SetWindowText( LPCTSTR(strTextValid) );
  2086. LPCTSTR strTextToSet = (LPCTSTR(strTextValid) != NULL) ? LPCTSTR(strTextValid) : _T("");
  2087. if( m_bRichMode )
  2088. {
  2089. ASSERT( ! m_bRichPainting );
  2090. Rich_PlainText_Set( strTextToSet );
  2091. _Rich_OnDraw();
  2092. }
  2093. else
  2094. SetWindowText( strTextToSet );
  2095. }
  2096. }
  2097. bool CExtEditWithBehavior::Behavior_OnQueryCharEnabledTyping( __EXT_MFC_SAFE_TCHAR _tchr ) const
  2098. {
  2099. ASSERT_VALID( this );
  2100. _tchr;
  2101. return true;
  2102. }
  2103. LRESULT CExtEditWithBehavior::OnCut( WPARAM wParam, LPARAM lParam )
  2104. {
  2105. ASSERT_VALID( this );
  2106. wParam;
  2107. lParam;
  2108. int nStart, nEnd;
  2109. GetSel( nStart, nEnd );
  2110. if( nStart < nEnd )
  2111. {
  2112. SendMessage( WM_COPY );
  2113. SendMessage( WM_KEYDOWN, VK_DELETE );
  2114. }
  2115. return 0;
  2116. }
  2117. LRESULT CExtEditWithBehavior::OnClear( WPARAM wParam, LPARAM lParam )
  2118. {
  2119. ASSERT_VALID( this );
  2120. wParam;
  2121. lParam;
  2122. int nStart, nEnd;
  2123. GetSel(nStart, nEnd);
  2124. if( nStart < nEnd )
  2125. SendMessage( WM_KEYDOWN, VK_DELETE );
  2126. return 0;
  2127. }
  2128. LRESULT CExtEditWithBehavior::OnPaste( WPARAM wParam, LPARAM lParam )
  2129. {
  2130. ASSERT_VALID( this );
  2131. if( ( GetStyle() & ES_READONLY ) != 0 )
  2132. return 0;
  2133. wParam;
  2134. lParam;
  2135. int nStart, nEnd;
  2136. GetSel(nStart, nEnd);
  2137. Default();
  2138. CExtSafeString strTextValid = TextGetValid();
  2139. CExtSafeString strTextCurrent = TextGet();
  2140. if( strTextValid != strTextCurrent )
  2141. {
  2142. //SetWindowText( LPCTSTR(strTextValid) );
  2143. LPCTSTR strTextToSet = (LPCTSTR(strTextValid) != NULL) ? LPCTSTR(strTextValid) : _T("");
  2144. if( m_bRichMode )
  2145. {
  2146. ASSERT( ! m_bRichPainting );
  2147. Rich_PlainText_Set( strTextToSet );
  2148. _Rich_OnDraw();
  2149. }
  2150. else
  2151. SetWindowText( strTextToSet );
  2152. SetSel( nStart, nEnd );
  2153. }
  2154. return 0;
  2155. }
  2156. LRESULT CExtEditWithBehavior::OnSetText( WPARAM wParam, LPARAM lParam )
  2157. {
  2158. ASSERT_VALID( this );
  2159. wParam;
  2160. LRESULT nResult = Default();
  2161. CExtSafeString strText = TextGetValid();
  2162. if( strText != LPCTSTR(lParam) )
  2163. {
  2164. //SetWindowText( strText );
  2165. LPCTSTR strTextToSet = (LPCTSTR(strText) != NULL) ? LPCTSTR(strText) : _T("");
  2166. if( m_bRichMode )
  2167. {
  2168. ASSERT( ! m_bRichPainting );
  2169. Rich_PlainText_Set( strTextToSet );
  2170. _Rich_OnDraw();
  2171. }
  2172. else
  2173. SetWindowText( strTextToSet );
  2174. }
  2175. else if( m_bRichMode )
  2176. {
  2177. _Rich_OnDraw();
  2178. }
  2179. if( IsWindowVisible() )
  2180. Invalidate();
  2181. return nResult;
  2182. }
  2183. /////////////////////////////////////////////////////////////////////////////
  2184. // CExtEditWithBehavior::CBehaviorBase
  2185. CExtEditWithBehavior::CBehaviorBase::CBehaviorBase()
  2186. : m_pEditWithBehaviorWnd( NULL )
  2187. , m_nBehaviorFlags( 0 )
  2188. {
  2189. }
  2190. CExtEditWithBehavior::CBehaviorBase::~CBehaviorBase()
  2191. {
  2192. }
  2193. bool CExtEditWithBehavior::CBehaviorBase::_FlagsModify( UINT nAdd, UINT nRemove )
  2194. {
  2195. UINT nFlags = ( m_nBehaviorFlags & (~nRemove) ) | nAdd;
  2196. if( m_nBehaviorFlags == nFlags )
  2197. return false;
  2198. m_nBehaviorFlags = nFlags;
  2199. _Redraw();
  2200. return true;
  2201. }
  2202. UINT CExtEditWithBehavior::CBehaviorBase::_FlagsGet() const
  2203. {
  2204. return m_nBehaviorFlags;
  2205. }
  2206. void CExtEditWithBehavior::CBehaviorBase::Behavior_OnChar( UINT uChar, UINT nRepCnt, UINT nFlags )
  2207. {
  2208. if( m_pEditWithBehaviorWnd->GetSafeHwnd() == NULL )
  2209. return;
  2210. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2211. m_pEditWithBehaviorWnd->OnChar( uChar, nRepCnt, nFlags );
  2212. m_pEditWithBehaviorWnd->_Rich_OnDraw();
  2213. }
  2214. void CExtEditWithBehavior::CBehaviorBase::Behavior_OnKeyDown( UINT uChar, UINT nRepCnt, UINT nFlags )
  2215. {
  2216. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2217. m_pEditWithBehaviorWnd->OnKeyDown( uChar, nRepCnt, nFlags );
  2218. // if( uChar == VK_DELETE || uChar == VK_BACK )
  2219. // m_pEditWithBehaviorWnd->_Rich_OnDraw();
  2220. }
  2221. void CExtEditWithBehavior::CBehaviorBase::Behavior_OnKillFocus( CWnd * pNewWnd ) 
  2222. {
  2223. if( m_pEditWithBehaviorWnd->GetSafeHwnd() == NULL )
  2224. return;
  2225. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2226. m_pEditWithBehaviorWnd->OnKillFocus( pNewWnd );
  2227. }
  2228. LRESULT CExtEditWithBehavior::CBehaviorBase::Behavior_OnPaste( WPARAM wParam, LPARAM lParam )
  2229. {
  2230. if( m_pEditWithBehaviorWnd->GetSafeHwnd() == NULL )
  2231. return 0L;
  2232. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2233. if( ( m_pEditWithBehaviorWnd->GetStyle() & ES_READONLY ) != 0 )
  2234. return 0;
  2235. LRESULT nRetVal = m_pEditWithBehaviorWnd->OnPaste( wParam, lParam );
  2236. // m_pEditWithBehaviorWnd->_Rich_OnDraw();
  2237. return nRetVal;
  2238. }
  2239. LRESULT CExtEditWithBehavior::CBehaviorBase::_Default()
  2240. {
  2241. if( m_pEditWithBehaviorWnd->GetSafeHwnd() == NULL )
  2242. return 0L;
  2243. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2244. return m_pEditWithBehaviorWnd->Default();
  2245. }
  2246. void CExtEditWithBehavior::CBehaviorBase::_Redraw()
  2247. {
  2248. if( m_pEditWithBehaviorWnd->GetSafeHwnd() == NULL )
  2249. return;
  2250. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2251. m_pEditWithBehaviorWnd->_UpdateContent();
  2252. }
  2253. bool CExtEditWithBehavior::CBehaviorBase::Behavior_OnQueryCharEnabledTyping( __EXT_MFC_SAFE_TCHAR _tchr ) const
  2254. {
  2255. if( m_pEditWithBehaviorWnd->GetSafeHwnd() == NULL )
  2256. return true;
  2257. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2258. return m_pEditWithBehaviorWnd->Behavior_OnQueryCharEnabledTyping( _tchr );
  2259. }
  2260. /////////////////////////////////////////////////////////////////////////////
  2261. // CExtEditWithBehavior::CBehaviorMasked
  2262. CExtEditWithBehavior::CBehaviorMasked::CBehaviorMasked(
  2263. __EXT_MFC_SAFE_LPCTSTR strMask // = _T("")
  2264. )
  2265. : m_strMask( strMask )
  2266. , m_bInsertMode( false )
  2267. , m_bNullableMode( true )
  2268. , m_bFieldSelectionMode( true )
  2269. , m_bBack( false )
  2270. , m_tchrNullChar( _T('_') )
  2271. {
  2272. // default mask symbol number
  2273. CharRule _rule1( __EXT_MFC_SAFE_TCHAR( _T('#') ), (CharRule::ValidationFunction)_istdigit );
  2274. m_arrRules.Add( _rule1 );
  2275. // default mask symbol letter
  2276. CharRule _rule2( __EXT_MFC_SAFE_TCHAR( _T('@') ), (CharRule::ValidationFunction)_istalpha );
  2277. m_arrRules.Add( _rule2 );
  2278. // default mask symbol number and letter
  2279. CharRule _rule3( __EXT_MFC_SAFE_TCHAR( _T('$') ), (CharRule::ValidationFunction)_istalnum );
  2280. m_arrRules.Add( _rule3 );
  2281. }
  2282. __EXT_MFC_SAFE_LPCTSTR CExtEditWithBehavior::CBehaviorMasked::MaskGet() const
  2283. {
  2284. return __EXT_MFC_SAFE_LPCTSTR(LPCTSTR(m_strMask));
  2285. }
  2286. void CExtEditWithBehavior::CBehaviorMasked::MaskSet( __EXT_MFC_SAFE_LPCTSTR strMask )
  2287. {
  2288. if( m_strMask == LPCTSTR(strMask) )
  2289. return;
  2290. m_strMask = LPCTSTR(strMask);
  2291. _ShowNullableMask();
  2292. _Redraw();
  2293. }
  2294. CExtSafeString CExtEditWithBehavior::CBehaviorMasked::_GetNumericText() const
  2295. {
  2296. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2297. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  2298. CExtSafeString strResult;
  2299. INT nIndex, nCount = INT(strText.GetLength());
  2300. for( nIndex = 0; nIndex < nCount; nIndex++ )
  2301. {
  2302. __EXT_MFC_SAFE_TCHAR _tchr = strText[ nIndex ];
  2303. if(_istdigit( _tchr ) )
  2304. {
  2305. TCHAR _tstr[2] = { _tchr, TCHAR(0) };
  2306. strResult += _tstr;
  2307. }
  2308. }
  2309. return strResult;
  2310. }
  2311. CExtSafeString CExtEditWithBehavior::CBehaviorMasked::Behavior_GetValidText(
  2312. bool bSetSel // = false
  2313. ) const
  2314. {
  2315. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2316. bSetSel;
  2317. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  2318. INT nMaskLen = INT( m_strMask.GetLength() );
  2319. if( nMaskLen == 0 )
  2320. return strText;
  2321. CExtSafeString strNewText;
  2322. bool bNullableMode = NullableModeGet();
  2323. __EXT_MFC_SAFE_TCHAR _tchrNullChar = NullCharGet();
  2324. INT nLength = INT(strText.GetLength()), nPos, nMaskPos;
  2325. for( nPos = 0, nMaskPos = 0; nPos < nLength; nPos++, nMaskPos++ )
  2326. {
  2327. __EXT_MFC_SAFE_TCHAR _tchr = strText[nPos];
  2328. __EXT_MFC_SAFE_TCHAR _tchrMask = static_cast < __EXT_MFC_SAFE_TCHAR > ( nMaskPos < nMaskLen ? m_strMask[ nMaskPos ] : 0 );
  2329. if( ! TCHAR(_tchrMask) )
  2330. break;
  2331. INT nSymbolIndex, nSymbolCount = INT(m_arrRules.GetSize());
  2332. for( nSymbolIndex = 0; nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  2333. {
  2334. const CharRule & symbol = m_arrRules[ nSymbolIndex ];
  2335. if( _tchrMask != symbol || ! symbol.Validate(_tchr) )
  2336. continue;
  2337. for( ; nMaskPos < nMaskLen; nMaskPos++ )
  2338. {
  2339. _tchrMask = m_strMask[ nMaskPos ];
  2340. if( _tchrMask == symbol )
  2341. {
  2342. TCHAR _tstr[2] = { symbol.Convert(_tchr), TCHAR(0) };
  2343. strNewText += _tstr;
  2344. break;
  2345. else
  2346. {
  2347. int iSymbol2 = 0;
  2348. for( iSymbol2 = 0; iSymbol2 < nSymbolCount; iSymbol2++ )
  2349. {
  2350. if( _tchrMask == m_arrRules[ iSymbol2 ] )
  2351. {
  2352. TCHAR _tstr[2] = { symbol.Convert(_tchr), TCHAR(0) };
  2353. strNewText += _tstr;
  2354. break;
  2355. }
  2356. }
  2357. if( iSymbol2 < nSymbolCount )
  2358. break;
  2359. TCHAR _tstr[2] = { TCHAR(_tchrMask), TCHAR(0) };
  2360. strNewText += _tstr;
  2361. }
  2362. }
  2363. break;
  2364. }
  2365. if( nSymbolIndex == nSymbolCount )
  2366. {
  2367. if( _tchr == _tchrMask )
  2368. {
  2369. for( nSymbolIndex = 0; nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  2370. {
  2371. if( _tchrMask == m_arrRules[nSymbolIndex] )
  2372. break;
  2373. }
  2374. if (nSymbolIndex == nSymbolCount)
  2375. {
  2376. TCHAR _tstr[2] = { TCHAR(_tchr), TCHAR(0) };
  2377. strNewText += _tstr;
  2378. continue;
  2379. }
  2380. }
  2381. if( bNullableMode && _tchr == _tchrNullChar)
  2382. {
  2383. TCHAR _tstr[2] = { TCHAR(_tchr), TCHAR(0) };
  2384. strNewText += _tstr;
  2385. continue;
  2386. }
  2387. break;
  2388. }
  2389. }
  2390. return strNewText;
  2391. }
  2392. void CExtEditWithBehavior::CBehaviorMasked::Behavior_OnChar( UINT uChar, UINT nRepCnt, UINT nFlags )
  2393. {
  2394. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2395. if( m_strMask.IsEmpty() )
  2396. {
  2397. CBehaviorBase::Behavior_OnChar( uChar, nRepCnt, nFlags );
  2398. return;
  2399. }
  2400. if( ( m_pEditWithBehaviorWnd->GetStyle() & ES_READONLY ) != 0 )
  2401. return;
  2402. if( uChar == VK_BACK )
  2403. return;
  2404. __EXT_MFC_SAFE_TCHAR _tchr = static_cast < TCHAR > ( uChar );
  2405. INT nMaskLen = INT(m_strMask.GetLength());
  2406. if( nMaskLen == 0 )
  2407. {
  2408. if( Behavior_OnQueryCharEnabledTyping( _tchr ) )
  2409. CBehaviorBase::Behavior_OnChar( uChar, nRepCnt, nFlags );
  2410. return;
  2411. }
  2412. int nStart, nEnd;
  2413. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  2414. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  2415. INT nLength = INT(strText.GetLength());
  2416. INT _posNullChar = -1;
  2417. bool _nullCharBeforePos = _NullCharBefore( nStart );
  2418. bool bInsertMode = InsertModeGet();
  2419. bool bNullableMode = NullableModeGet();
  2420. bool _nullCharIs = _IsNullChar( _posNullChar );
  2421. if( nLength == nMaskLen
  2422.   && ( ( bInsertMode && ( bNullableMode && ! _nullCharIs ) )
  2423. || ( bInsertMode && ! bNullableMode )
  2424. )
  2425. && nStart == nEnd
  2426. )
  2427. {
  2428. OnCheckText( true );
  2429. return;
  2430. }
  2431. if( ! ( _istprint( _tchr ) || IsCharAlphaNumeric( _tchr ) ) )
  2432. {
  2433. if( Behavior_OnQueryCharEnabledTyping( _tchr ) )
  2434. CBehaviorBase::Behavior_OnChar( uChar, nRepCnt, nFlags );
  2435. return;
  2436. }
  2437. else
  2438. {
  2439. if( nStart >= m_strMask.GetLength() )
  2440. return;
  2441. }
  2442. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask[nStart];
  2443. __EXT_MFC_SAFE_TCHAR chTextCurrentSymbols = _T('');
  2444. if( /*( ! strText.IsEmpty() )*/ nStart < strText.GetLength() && bNullableMode )
  2445. chTextCurrentSymbols = strText.GetAt( nStart );
  2446. __EXT_MFC_SAFE_TCHAR _tchrNullChar = NullCharGet();
  2447. INT nSymbolIndex, nSymbolCount = INT(m_arrRules.GetSize());
  2448. for( nSymbolIndex = 0; nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  2449. {
  2450. const CharRule & symbol = m_arrRules[nSymbolIndex];
  2451. if( _tchrMask == symbol )
  2452. {
  2453. if( symbol.Validate(_tchr) && Behavior_OnQueryCharEnabledTyping(_tchr) )
  2454. {
  2455. if( ( ! bInsertMode || ( bNullableMode && ( chTextCurrentSymbols == _tchrNullChar ) ) )
  2456. && nStart == nEnd
  2457. )
  2458. nEnd = ( nEnd == nLength ? nEnd : ( nStart + 1 ) );
  2459. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2460. _SymbolInsert( CExtSafeString( TCHAR(symbol.Convert(_tchr)) ) );
  2461. m_pEditWithBehaviorWnd->SetSel( nStart + 1, nStart + 1 );
  2462. bool _inserMaskSymbol = _AddSymbolMaskToEnd();
  2463. if( ( _posNullChar != -1 ) && ( _posNullChar < nStart )
  2464. && bInsertMode
  2465. && ( chTextCurrentSymbols != _tchrNullChar )
  2466. && ! _nullCharBeforePos
  2467. )
  2468. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  2469. if( ( bInsertMode && ! bNullableMode )
  2470. || bNullableMode
  2471. )
  2472. OnCheckText( true );
  2473. if( ! _inserMaskSymbol )
  2474. _GetFieldSelection( nStart );
  2475. }
  2476. return;
  2477. }
  2478. }
  2479. if( _tchrMask == _tchr && Behavior_OnQueryCharEnabledTyping(_tchr) )
  2480. {
  2481. if( ! bInsertMode || ( bNullableMode && ( chTextCurrentSymbols == _tchrNullChar ) ) )
  2482. nEnd = ( nEnd == nLength ? nEnd : ( nStart + 1 ) );
  2483. m_pEditWithBehaviorWnd->SetSel( nStart, nEnd );
  2484. _SymbolInsert( CExtSafeString( TCHAR(_tchr) ) );
  2485. m_pEditWithBehaviorWnd->SetSel( nStart + 1, nStart + 1 );
  2486. if( ( _posNullChar != -1 ) && ( _posNullChar < nStart ) 
  2487. && bInsertMode
  2488. && ( chTextCurrentSymbols != _tchrNullChar )
  2489. && ! _nullCharBeforePos
  2490. )
  2491. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  2492. if( ( bInsertMode && ! bNullableMode )
  2493. || bNullableMode
  2494. )
  2495. OnCheckText( true );
  2496. _GetFieldSelection( nStart );
  2497. return;
  2498. }
  2499. CExtSafeString strSymbols;
  2500. for( nSymbolIndex = 0; nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  2501. strSymbols += TCHAR(__EXT_MFC_SAFE_TCHAR(m_arrRules[nSymbolIndex]));
  2502. for( nSymbolIndex = 0; nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  2503. {
  2504. const CharRule & symbol = m_arrRules[nSymbolIndex];
  2505. if( ! symbol.Validate( _tchr ) )
  2506. continue;
  2507. CExtSafeString strMaskPortion = m_strMask.Mid( nStart );
  2508. INT nMaskPos = INT( strMaskPortion.FindOneOf( strSymbols ) );
  2509. if( nMaskPos >= 0 && TCHAR(strMaskPortion[nMaskPos]) == TCHAR(__EXT_MFC_SAFE_TCHAR(symbol)) && Behavior_OnQueryCharEnabledTyping(_tchr) )
  2510. {
  2511. if( nStart != nEnd )
  2512. {
  2513. _SymbolInsert( CExtSafeString( TCHAR(symbol.Convert(_tchr)) ) );
  2514. m_pEditWithBehaviorWnd->SetSel( nStart + nMaskPos + 1, nStart + nMaskPos + 1 );
  2515. if( bNullableMode )
  2516. OnCheckText( true );
  2517. return;
  2518. }
  2519. m_pEditWithBehaviorWnd->SetSel( nStart, nStart + nMaskPos );
  2520. m_pEditWithBehaviorWnd->ReplaceSel( strMaskPortion.Left( nMaskPos ), TRUE );
  2521. Behavior_OnChar( uChar, nRepCnt, nFlags );
  2522. return;
  2523. }
  2524. }
  2525. }
  2526. bool CExtEditWithBehavior::CBehaviorMasked::_AddSymbolMaskToEnd()
  2527. {
  2528. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2529. INT nMaskSymbolCount = _GetCountMaskSymbolsFromEnd();
  2530. if( nMaskSymbolCount == 0 )
  2531. return false;
  2532. int _nStart, _nEnd;
  2533. m_pEditWithBehaviorWnd->GetSel( _nStart, _nEnd );
  2534. ASSERT( _nStart == _nEnd );
  2535. CExtSafeString _str = m_pEditWithBehaviorWnd->TextGet();
  2536. INT nMaskLen = INT( m_strMask.GetLength() );
  2537. if( ( nMaskLen - _nStart ) != nMaskSymbolCount )
  2538. return false;
  2539. for( INT i = _nStart; i < nMaskLen; i++ )
  2540. {
  2541. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask.GetAt( i );
  2542. TCHAR _tstr[2] = { TCHAR(_tchrMask), TCHAR(0) };
  2543. _str += _tstr;
  2544. }
  2545. m_pEditWithBehaviorWnd->TextSet( _str );
  2546. m_pEditWithBehaviorWnd->SetSel( _nStart, _nEnd );
  2547. return true;
  2548. }
  2549. INT CExtEditWithBehavior::CBehaviorMasked::_GetCountMaskSymbolsFromEnd()
  2550. {
  2551. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2552. INT nMaskLen = INT( m_strMask.GetLength() );
  2553. INT nMaskSymbolCount = 0;
  2554. if( nMaskLen == 0 )
  2555. return nMaskSymbolCount;
  2556. INT i = nMaskLen - 1;
  2557. for( ; i >= 0; i-- )
  2558. {
  2559. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask.GetAt( i );
  2560. if( m_arrRules.FindPos( _tchrMask ) < 0 )
  2561. nMaskSymbolCount ++;
  2562. else
  2563. break;
  2564. }
  2565. return nMaskSymbolCount;
  2566. }
  2567. void CExtEditWithBehavior::CBehaviorMasked::Behavior_OnKeyDown(UINT uChar, UINT nRepCnt, UINT nFlags) 
  2568. {
  2569. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2570. if( m_strMask.IsEmpty() )
  2571. {
  2572. CBehaviorBase::Behavior_OnKeyDown( uChar, nRepCnt, nFlags );
  2573. return;
  2574. }
  2575. switch( uChar )
  2576. {
  2577. case VK_BACK:
  2578. {
  2579. if( ( m_pEditWithBehaviorWnd->GetStyle() & ES_READONLY ) != 0 )
  2580. return;
  2581. m_bBack = true;
  2582. int nStart, nEnd;
  2583. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  2584. CExtSafeString str = m_pEditWithBehaviorWnd->TextGet();
  2585. INT nLength = INT(str.GetLength());
  2586. if( nStart != nEnd )
  2587. m_pEditWithBehaviorWnd->SendMessage( WM_KEYDOWN, VK_DELETE );
  2588. else if( nEnd != 0 )
  2589. {
  2590. nEnd --;
  2591. bool bJumpMode = false;
  2592. INT nMaskLen = INT( m_strMask.GetLength() );
  2593. if( nEnd < nMaskLen )
  2594. {
  2595. for( ; nEnd >= 0 ; )
  2596. {
  2597. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  2598. __EXT_MFC_SAFE_TCHAR tchrMask = m_strMask[ nEnd ];
  2599. __EXT_MFC_SAFE_TCHAR tchrSymbol = str.GetAt( nEnd );
  2600. if( ( nEnd == ( nMaskLen - 1 ) )
  2601. && tchrMask == tchrSymbol
  2602. )
  2603. return;
  2604. bool bSymbolFind = false;
  2605. for( INT nSymbolIndex = 0, nSymbolCount = INT(m_arrRules.GetSize()); nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  2606. {
  2607. const CharRule & symbol = m_arrRules[nSymbolIndex];
  2608. if( tchrMask == symbol )
  2609. {
  2610. bSymbolFind = true;
  2611. break;
  2612. }
  2613. }
  2614. if( bSymbolFind )
  2615. {
  2616. if( ! bJumpMode )
  2617. m_pEditWithBehaviorWnd->SendMessage( WM_KEYDOWN, VK_DELETE );
  2618. break;
  2619. }
  2620. else
  2621. {
  2622. if( ( nEnd + 1 ) == nLength )
  2623. {
  2624. m_pEditWithBehaviorWnd->SendMessage( WM_KEYDOWN, VK_DELETE );
  2625. break;
  2626. }
  2627. bJumpMode = true;
  2628. nEnd --;
  2629. continue;
  2630. }
  2631. } // for( ; nEnd > 0 ; )
  2632. if( bJumpMode )
  2633. {
  2634. nEnd ++;
  2635. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  2636. }
  2637. } // if( nEnd < nMaskLen )
  2638. } // else if( nEnd != 0 )
  2639. }
  2640. return;
  2641. case VK_DELETE:
  2642. {
  2643. if( ( m_pEditWithBehaviorWnd->GetStyle() & ES_READONLY ) != 0 )
  2644. return;
  2645. int nStart, nEnd;
  2646. bool bNullableMode = NullableModeGet();
  2647. CExtSafeString str = m_pEditWithBehaviorWnd->TextGet();
  2648. INT nLength = INT(str.GetLength());
  2649. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  2650. if( nStart == nEnd )
  2651. {
  2652. bool bJumpMode = false;
  2653. INT nMaskLen = INT( m_strMask.GetLength() );
  2654. for( ; true ; )
  2655. {
  2656. if( nEnd < nMaskLen )
  2657. {
  2658. __EXT_MFC_SAFE_TCHAR tchrMask = m_strMask[ nEnd ];
  2659. __EXT_MFC_SAFE_TCHAR tchrSymbol = str.GetAt( nEnd );
  2660. if( ( nEnd == ( nMaskLen - 1 ) )
  2661. && tchrMask == tchrSymbol
  2662. )
  2663. return;
  2664. bool bSymbolFind = false;
  2665. for( INT nSymbolIndex = 0, nSymbolCount = INT(m_arrRules.GetSize()); nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  2666. {
  2667. const CharRule& symbol = m_arrRules[nSymbolIndex];
  2668. if( tchrMask == symbol )
  2669. {
  2670. bSymbolFind = true;
  2671. break;
  2672. }
  2673. }
  2674. if( ! bSymbolFind && nLength == ( nEnd + 1 ) )
  2675. break;
  2676. if( ! bSymbolFind )
  2677. {
  2678. nEnd ++;
  2679. m_pEditWithBehaviorWnd->SendMessage( WM_KEYDOWN, VK_RIGHT );
  2680. bJumpMode = true;
  2681. continue;
  2682. }
  2683. else
  2684. break;
  2685. }
  2686. else
  2687. break;
  2688. } // for( ; true ; )
  2689. if( bJumpMode )
  2690. return;
  2691. if( (! m_bBack) && bNullableMode )
  2692. {
  2693. if( nEnd == nMaskLen )
  2694. return;
  2695. __EXT_MFC_SAFE_TCHAR tchrNullChar = NullCharGet();
  2696. CExtSafeString strText = TCHAR(tchrNullChar);
  2697. m_pEditWithBehaviorWnd->SetSel( nEnd, ( nEnd + 1 ) );
  2698. m_pEditWithBehaviorWnd->ReplaceSel( strText, TRUE );
  2699. m_pEditWithBehaviorWnd->SetSel( ( nEnd + 1 ), ( nEnd + 1 ) );
  2700. return;
  2701. }
  2702. else if( m_bBack && bNullableMode )
  2703. {
  2704. __EXT_MFC_SAFE_TCHAR tchrNullChar = NullCharGet();
  2705. CExtSafeString strText = TCHAR(tchrNullChar);
  2706. m_pEditWithBehaviorWnd->SetSel( nEnd, ( nEnd + 1 ) );
  2707. m_pEditWithBehaviorWnd->ReplaceSel( strText, TRUE );
  2708. m_pEditWithBehaviorWnd->SetSel( nEnd, nEnd );
  2709. m_bBack = false;
  2710. return;
  2711. }
  2712. m_bBack = false;
  2713. } // if( nStart == nEnd )
  2714. }
  2715. break;
  2716. } // switch( uChar )
  2717. switch( uChar )
  2718. {
  2719. case VK_BACK:
  2720. case VK_DELETE:
  2721. {
  2722. if( ( m_pEditWithBehaviorWnd->GetStyle() & ES_READONLY ) != 0 )
  2723. return;
  2724. int _nStart, _nEnd;
  2725. int nStart, nEnd;
  2726. bool bNullableMode = NullableModeGet();
  2727. __EXT_MFC_SAFE_TCHAR _tchrNullChar = NullCharGet();
  2728. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  2729. _DefineNewPosition( _nStart, _nEnd );
  2730. if( nStart != nEnd && _nStart == _nEnd )
  2731. {
  2732. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  2733. return;
  2734. }
  2735. CExtSafeString _strNew;
  2736. _MaskSymbolDelete( _strNew );
  2737. //m_pEditWithBehaviorWnd->TextSet( _strNew );
  2738. if( _nStart == _nEnd )
  2739. _strNew.Delete( _nStart, 1 );
  2740. else
  2741. _strNew.Delete( _nStart, ( _nEnd - _nStart ) );
  2742. if( bNullableMode && m_strMask.GetLength() > 0 )
  2743. {
  2744. if( _nStart == _nEnd )
  2745. _strNew.Insert( _nStart, _tchrNullChar );
  2746. else
  2747. for( int i = 0; i < ( _nEnd - _nStart ); i++ )
  2748. _strNew.Insert( _nStart, _tchrNullChar );
  2749. }
  2750. _MaskSymbolInsert( _strNew );
  2751. if( bNullableMode )
  2752. OnCheckText( false );
  2753. m_pEditWithBehaviorWnd->SetSel( nStart, nStart );
  2754. }
  2755. break;
  2756. default:
  2757. CBehaviorBase::Behavior_OnKeyDown( uChar, nRepCnt, nFlags );
  2758. break;
  2759. } // switch( uChar )
  2760. }
  2761. void CExtEditWithBehavior::CBehaviorMasked::_GetMaskBasedGroupArrays(
  2762. CExtSafeStringArray & arrMaskGroups,
  2763. CExtSafeStringArray * p_arrEnteredValues, // = NULL
  2764. bool bJoinSimilarRules, // = true
  2765. bool bJoinDifferentRules, // = false
  2766. bool bPutNullableCharIntoValueArray // = false
  2767. )
  2768. {
  2769. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2770. arrMaskGroups.RemoveAll();
  2771. if( p_arrEnteredValues != NULL )
  2772. p_arrEnteredValues->RemoveAll();
  2773. // (###) ###-#### x####
  2774. //-------------------------- with bJoinSimilarRules == true
  2775. //  0    1   2     3
  2776. //  ###  ### ####  #### ---> save into arrMaskGroups
  2777. //-------------------------- with bJoinSimilarRules == false
  2778. //  0 1 2 3 4 5 6 7 ....
  2779. //  # # # # # # # # # # # # # # ---> save into arrMaskGroups
  2780. //
  2781. //==================================================================
  2782. // sample with different rules # and $, #-digit, $-alpha
  2783. // #$-##-$$
  2784. //-------------------------- with bJoinSimilarRules == true and bJoinDifferentRules == true
  2785. // #$-##-$$
  2786. //  0  1  2
  2787. // #$ ## $$
  2788. //-------------------------- with bJoinSimilarRules == true and bJoinDifferentRules == false
  2789. // #$-##-$$
  2790. //  0 1 2  3
  2791. // # $ ## $$
  2792. //-------------------------- with bJoinSimilarRules == false and bJoinDifferentRules == true
  2793. // #$-##-$$
  2794. //  0  1 2 3 4
  2795. // #$ # # $ $
  2796. //-------------------------- with bJoinSimilarRules == false and bJoinDifferentRules == false
  2797. // #$-##-$$
  2798. //  0 1 2 3 4 5
  2799. // # $ # # $ $
  2800. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  2801. INT nLenText = INT( strText.GetLength() );
  2802. INT nLenMask = INT( m_strMask.GetLength() );
  2803. INT i;
  2804. CExtSafeString strAsmMask, strAsmVal;
  2805. for( i = 0; i < nLenMask; i++ )
  2806. {
  2807. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask.GetAt(i);
  2808. __EXT_MFC_SAFE_TCHAR _tchrText = ( p_arrEnteredValues != NULL && i < nLenText ) ? __EXT_MFC_SAFE_TCHAR(strText.GetAt(0)) : __EXT_MFC_SAFE_TCHAR(0);
  2809. if( m_arrRules.FindPos( _tchrMask ) < 0 )
  2810. continue;
  2811. bool bAppendToCurrentAsm = false;
  2812. if( bJoinDifferentRules )
  2813. bAppendToCurrentAsm = true;
  2814. else if( strAsmMask.IsEmpty() )
  2815. bAppendToCurrentAsm = true;
  2816. else if(
  2817. bJoinSimilarRules
  2818. && TCHAR( strAsmMask.GetAt( strAsmMask.GetLength() - 1 ) ) == TCHAR(_tchrMask)
  2819. )
  2820. bAppendToCurrentAsm = true;
  2821. if( bAppendToCurrentAsm )
  2822. {
  2823. TCHAR _tstr[2] = { TCHAR(_tchrMask), TCHAR(0) };
  2824. strAsmMask += _tstr;
  2825. if( _tchrText != 0 )
  2826. {
  2827. TCHAR _tstr[2] = { TCHAR(_tchrText), TCHAR(0) };
  2828. strAsmVal += _tstr;
  2829. }
  2830. }
  2831. else
  2832. {
  2833. ASSERT( ! strAsmMask.IsEmpty() );
  2834. arrMaskGroups.Add( strAsmMask );
  2835. strAsmMask.Empty();
  2836. if( p_arrEnteredValues != NULL )
  2837. {
  2838. p_arrEnteredValues->Add( strAsmVal );
  2839. strAsmVal.Empty();
  2840. }
  2841. }
  2842. } // for( i = 0; i < nLenMask; i++ )
  2843. if( ! strAsmMask.IsEmpty() )
  2844. {
  2845. arrMaskGroups.Add( strAsmMask );
  2846. strAsmMask.Empty();
  2847. if( p_arrEnteredValues != NULL )
  2848. {
  2849. p_arrEnteredValues->Add( strAsmVal );
  2850. strAsmVal.Empty();
  2851. }
  2852. } // if( ! strAsmMask.IsEmpty() )
  2853. if( (!bPutNullableCharIntoValueArray) && p_arrEnteredValues != NULL )
  2854. {
  2855. __EXT_MFC_SAFE_TCHAR strWithNullableChar[ 2 ] = { NullCharGet(), _T('') };
  2856. INT nCount = INT( p_arrEnteredValues->GetSize() );
  2857. for( i = 0; i < nCount; i++ )
  2858. p_arrEnteredValues->ElementAt( i ).Replace( LPCTSTR(strWithNullableChar), _T("") );
  2859. } // if( (!bPutNullableCharIntoValueArray) && p_arrEnteredValues != NULL )
  2860. }
  2861. void CExtEditWithBehavior::CBehaviorMasked::OnCheckText(
  2862. bool bAppendEndChars
  2863. )
  2864. {
  2865. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2866. ASSERT( m_pEditWithBehaviorWnd->GetSafeHwnd() != NULL );
  2867. int nStart, nEnd;
  2868. m_pEditWithBehaviorWnd->GetSel(nStart, nEnd);
  2869. INT nLenMask = INT( m_strMask.GetLength() );
  2870. CExtSafeString strTextInitial = m_pEditWithBehaviorWnd->TextGet();
  2871. INT nLenInitial = INT( strTextInitial.GetLength() );
  2872. CExtSafeString strText = strTextInitial;
  2873. CExtSafeString strEnd;
  2874. INT i = 0;
  2875. bool bNullableMode = NullableModeGet();
  2876. __EXT_MFC_SAFE_TCHAR _tchrNullChar = NullCharGet();
  2877. __EXT_MFC_SAFE_TCHAR _tchrText, _tchrMask;
  2878. if( ( nLenInitial > nLenMask ) && bNullableMode )
  2879. {
  2880. for( i = 0; i < (nLenInitial - 1); i++ )
  2881. {
  2882. _tchrText = strText.GetAt(i);
  2883. if( _tchrText == _tchrNullChar )
  2884. {
  2885. strText.Delete(i);
  2886. break;
  2887. }
  2888. }
  2889. i = 0;
  2890. }
  2891. for( ; ! strText.IsEmpty(); )
  2892. {
  2893. if( bNullableMode && nLenMask <= i )
  2894. {
  2895. _tchrText = strText.GetAt(0);
  2896. ASSERT( _tchrText == _tchrNullChar );
  2897. break;
  2898. }
  2899. _tchrText = strText.GetAt(0);
  2900. _tchrMask = m_strMask.GetAt(i);
  2901. bool bRuleWasFound = false;
  2902. if( ( bNullableMode
  2903. && _tchrText == _tchrNullChar
  2904. && m_arrRules.FindPos( _tchrMask ) >= 0
  2905. )
  2906. || m_arrRules.CheckRule( _tchrMask, _tchrText, &bRuleWasFound )
  2907. )
  2908. {
  2909. TCHAR _tstr[2] = { TCHAR(_tchrText), TCHAR(0) };
  2910. strEnd += _tstr;
  2911. strText.Delete(0);
  2912. i++;
  2913. continue;
  2914. }
  2915. if( bRuleWasFound )
  2916. {
  2917. strText.Delete(0);
  2918. }
  2919. else
  2920. {
  2921. TCHAR _tstr[2] = { TCHAR(_tchrMask), TCHAR(0) };
  2922. strEnd += _tstr;
  2923. i++;
  2924. }
  2925. }
  2926. INT nResetSelPos = min( nStart, nEnd );
  2927. INT nLenComposed = INT( strEnd.GetLength() );
  2928. ASSERT( nLenComposed <= nLenMask );
  2929. if( bAppendEndChars )
  2930. {
  2931. if( nLenComposed < nLenMask )
  2932. {
  2933. bool bMoveSelToAppended = ( nEnd == nLenComposed ) ? true : false;
  2934. for( i = nLenComposed; i < nLenMask; i ++ )
  2935. {
  2936. _tchrMask = m_strMask.GetAt(i);
  2937. if( m_arrRules.FindPos( _tchrMask ) < 0 )
  2938. {
  2939. TCHAR _tstr[2] = { TCHAR(_tchrMask), TCHAR(0) };
  2940. strEnd += _tstr;
  2941. nLenComposed ++;
  2942. }
  2943. else
  2944. break;
  2945. }
  2946. if( bMoveSelToAppended )
  2947. nResetSelPos = i;
  2948. }
  2949. }
  2950. INT strLen = INT(strEnd.GetLength());
  2951. if( bNullableMode  )
  2952. {
  2953. if( strLen < nLenMask )
  2954. {
  2955. nEnd = strLen;
  2956. for( ; strLen < nLenMask; strLen ++ )
  2957. {
  2958. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask.GetAt( strLen );
  2959. if( m_arrRules.FindPos( _tchrMask ) >= 0 )
  2960. _tchrMask = _tchrNullChar;
  2961. TCHAR _tstr[2] = { TCHAR(_tchrMask), TCHAR(0) };
  2962. strEnd += _tstr;
  2963. }
  2964. }
  2965. }
  2966. if( strEnd == strTextInitial )
  2967. return;
  2968. OnInputChar( strEnd );
  2969. if( strEnd == strTextInitial )
  2970. return;
  2971. m_pEditWithBehaviorWnd->TextSet( strEnd );
  2972. m_pEditWithBehaviorWnd->SetSel( nResetSelPos, nResetSelPos );
  2973. }
  2974. void CExtEditWithBehavior::CBehaviorMasked::OnInputChar( CExtSafeString & str )
  2975. {
  2976. str;
  2977. }
  2978. void CExtEditWithBehavior::CBehaviorMasked::_DefineNewPosition( int & _nStart, int & _nEnd )
  2979. {
  2980. ASSERT_VALID( m_pEditWithBehaviorWnd );
  2981. int nStart, nEnd;
  2982. m_pEditWithBehaviorWnd->GetSel( nStart, nEnd );
  2983. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  2984. if( strText.IsEmpty() )
  2985. return;
  2986. INT nMaskCountAfterStartPos = 0, nMaskCountBetweenStartPosEndPos = 0, i;
  2987. for( i = 0; i < nStart; i++ )
  2988. {
  2989. __EXT_MFC_SAFE_TCHAR _tchrSymbol = strText.GetAt( i );
  2990. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask.GetAt( i );
  2991. if( _tchrSymbol == _tchrMask )
  2992. nMaskCountAfterStartPos ++;
  2993. }
  2994. _nStart = nStart - nMaskCountAfterStartPos;
  2995. _nEnd = _nStart;
  2996. INT nTextLen = (INT)strText.GetLength();
  2997. //INT nMaskLen = (INT)m_strMask.GetLength();
  2998. nStart = min( nStart, nTextLen );
  2999. nEnd = min( nEnd, nTextLen );
  3000. if( nStart != nEnd )
  3001. {
  3002. if( ! m_strMask.IsEmpty() )
  3003. {
  3004. for( i = nStart; i < nEnd; i++ )
  3005. {
  3006. __EXT_MFC_SAFE_TCHAR _tchrSymbol = strText.GetAt( i );
  3007. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask.GetAt( i );
  3008. if( _tchrSymbol == _tchrMask )
  3009. nMaskCountBetweenStartPosEndPos ++;
  3010. }
  3011. }
  3012. _nEnd = nEnd - nMaskCountBetweenStartPosEndPos - nMaskCountAfterStartPos;
  3013. }
  3014. }
  3015. void CExtEditWithBehavior::CBehaviorMasked::_MaskSymbolDelete( CExtSafeString & _str )
  3016. {
  3017. ASSERT_VALID( m_pEditWithBehaviorWnd );
  3018. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  3019. if( strText.IsEmpty() )
  3020. return;
  3021. INT nLenStr = INT(strText.GetLength()), nLenMask = INT(m_strMask.GetLength()), i;
  3022. _str = _T("");
  3023. if( nLenMask < nLenStr )
  3024. return;
  3025. for( i = 0; i < nLenStr; i++ )
  3026. {
  3027. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask.GetAt( i );
  3028. __EXT_MFC_SAFE_TCHAR _tchrSymbol = strText.GetAt( i );
  3029. if( _tchrSymbol != _tchrMask )
  3030. {
  3031. TCHAR _tstr[2] = { TCHAR(_tchrSymbol), TCHAR(0) };
  3032. _str += _tstr;
  3033. }
  3034. }
  3035. }
  3036. void CExtEditWithBehavior::CBehaviorMasked::_MaskSymbolInsert( CExtSafeString _str )
  3037. {
  3038. ASSERT_VALID( m_pEditWithBehaviorWnd );
  3039. if( _str.IsEmpty() )
  3040. {
  3041. m_pEditWithBehaviorWnd->TextSet( _str );
  3042. return;
  3043. }
  3044. INT nMaskLen = INT( m_strMask.GetLength() );
  3045. CExtSafeString strText = _T("");
  3046. INT i = 0;
  3047. if( nMaskLen > 0 )
  3048. {
  3049. for( ; ! _str.IsEmpty(); )
  3050. {
  3051. __EXT_MFC_SAFE_TCHAR _tchrMask = m_strMask.GetAt( i );
  3052. __EXT_MFC_SAFE_TCHAR _tchrSymbol = _str.GetAt( 0 );
  3053. if( m_arrRules.FindPos( _tchrMask ) >= 0 )
  3054. {
  3055. TCHAR _tstr[2] = { TCHAR(_tchrSymbol), TCHAR(0) };
  3056. strText += _tstr;
  3057. _str.Delete( 0 );
  3058. }
  3059. else
  3060. {
  3061. TCHAR _tstr[2] = { TCHAR(_tchrMask), TCHAR(0) };
  3062. strText += _tstr;
  3063. }
  3064. i ++;
  3065. if( i >= nMaskLen )
  3066. break;
  3067. }
  3068. }
  3069. m_pEditWithBehaviorWnd->TextSet( strText );
  3070. }
  3071. void CExtEditWithBehavior::CBehaviorMasked::_SymbolInsert( CExtSafeString _str )
  3072. {
  3073. ASSERT_VALID( m_pEditWithBehaviorWnd );
  3074. bool bNullableMode = NullableModeGet();
  3075. bool bInsertMode = InsertModeGet();
  3076. int _nStart, _nEnd;
  3077. _DefineNewPosition( _nStart, _nEnd );
  3078. CExtSafeString _strNew;
  3079. _MaskSymbolDelete( _strNew );
  3080. INT nLenStr = INT(_strNew.GetLength());
  3081. __EXT_MFC_SAFE_TCHAR _tchrNullChar = NullCharGet();
  3082. INT nPosNullChar = -1;
  3083. bool bNullChar = _IsNullChar( nPosNullChar );
  3084. bool bDeleteNullCharSymbolAfterPos = false;
  3085. if( bNullableMode && bInsertMode
  3086. && TCHAR(_strNew.GetAt( _nStart )) != TCHAR(_tchrNullChar)
  3087. && bNullChar
  3088. && _nEnd == _nStart
  3089. )
  3090. {
  3091. INT i;
  3092. for( i = _nStart; i < nLenStr; i++ )
  3093. {
  3094. __EXT_MFC_SAFE_TCHAR _tchrSymbol = _strNew.GetAt( i );
  3095. if( _tchrSymbol == _tchrNullChar )
  3096. {
  3097. _strNew.Delete( i );
  3098. bDeleteNullCharSymbolAfterPos = true;
  3099. break;
  3100. }
  3101. }
  3102. if( ! bDeleteNullCharSymbolAfterPos )
  3103. {
  3104. for( i = _nStart; i >= 0; i-- )
  3105. {
  3106. __EXT_MFC_SAFE_TCHAR _tchrSymbol = _strNew.GetAt( i );
  3107. if( _tchrSymbol == _tchrNullChar )
  3108. {
  3109. _strNew.Delete( i );
  3110. break;
  3111. }
  3112. }
  3113. }
  3114. }
  3115. if( _nStart == _nEnd )
  3116. {
  3117. if( bDeleteNullCharSymbolAfterPos || ! bNullableMode )
  3118. _strNew.Insert( _nStart, _str );
  3119. else
  3120. _strNew.Insert( _nStart - 1, _str );
  3121. }
  3122. else
  3123. {
  3124. _strNew.Delete( _nStart, ( _nEnd - _nStart ) );
  3125. _strNew.Insert( _nStart, _str );
  3126. }
  3127. _MaskSymbolInsert( _strNew );
  3128. }
  3129. bool CExtEditWithBehavior::CBehaviorMasked::_NullCharBefore( int _nPos )
  3130. {
  3131. ASSERT_VALID( m_pEditWithBehaviorWnd );
  3132. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  3133. INT nLenStr = INT(strText.GetLength()), i;
  3134. __EXT_MFC_SAFE_TCHAR _tchrNullChar = NullCharGet();
  3135. __EXT_MFC_SAFE_TCHAR _tchrSymbol;
  3136. for( i = _nPos; i < nLenStr; i++ )
  3137. {
  3138. _tchrSymbol = strText.GetAt( i );
  3139. if( _tchrSymbol == _tchrNullChar )
  3140. return true;
  3141. }
  3142. return false;
  3143. }
  3144. CExtEditWithBehavior::CBehaviorMasked::CharRuleArray & CExtEditWithBehavior::CBehaviorMasked::GetSymbolArray()
  3145. {
  3146. return m_arrRules;
  3147. }
  3148. void CExtEditWithBehavior::CBehaviorMasked::InsertModeSet( bool bInsertMode )
  3149. {
  3150. m_bInsertMode = bInsertMode;
  3151. }
  3152. bool CExtEditWithBehavior::CBehaviorMasked::InsertModeGet() const
  3153. {
  3154. return m_bInsertMode;
  3155. }
  3156. void CExtEditWithBehavior::CBehaviorMasked::NullableModeSet( bool bNullableMode )
  3157. {
  3158. m_bNullableMode = bNullableMode;
  3159. }
  3160. bool CExtEditWithBehavior::CBehaviorMasked::NullableModeGet() const
  3161. {
  3162. return m_bNullableMode;
  3163. }
  3164. void CExtEditWithBehavior::CBehaviorMasked::NullCharSet( __EXT_MFC_SAFE_TCHAR _tchrNullChar )
  3165. {
  3166. m_tchrNullChar = _tchrNullChar;
  3167. _Redraw();
  3168. }
  3169. void CExtEditWithBehavior::CBehaviorMasked::FieldSelectionModeSet( bool bFieldSelectionMode )
  3170. {
  3171. m_bFieldSelectionMode = bFieldSelectionMode;
  3172. }
  3173. bool CExtEditWithBehavior::CBehaviorMasked::FieldSelectionModeGet() const
  3174. {
  3175. return m_bFieldSelectionMode;
  3176. }
  3177. __EXT_MFC_SAFE_TCHAR CExtEditWithBehavior::CBehaviorMasked::NullCharGet() const
  3178. {
  3179. return m_tchrNullChar;
  3180. }
  3181. bool CExtEditWithBehavior::CBehaviorMasked::_IsNullChar( int & _pos ) const
  3182. {
  3183. // ASSERT_VALID( m_pEditWithBehaviorWnd );
  3184. CExtSafeString strTextInitial = m_pEditWithBehaviorWnd->TextGet();
  3185. INT nLength = INT(strTextInitial.GetLength()), i;
  3186. TCHAR tchrText;
  3187. TCHAR _tchrNullChar = TCHAR( NullCharGet() );
  3188. for( i = 0; i < nLength; i++ )
  3189. {
  3190. tchrText = strTextInitial.GetAt( i );
  3191. if( tchrText == _tchrNullChar )
  3192. {
  3193. _pos = i;
  3194. return true;
  3195. }
  3196. }
  3197. return false;
  3198. }
  3199. bool CExtEditWithBehavior::CBehaviorMasked::_GetFieldSelection( int _currentPosition )
  3200. {
  3201. bool bFieldSelectionMode = FieldSelectionModeGet();
  3202. if( m_pEditWithBehaviorWnd->GetSafeHwnd() == NULL )
  3203. return bFieldSelectionMode;
  3204. ASSERT_VALID( m_pEditWithBehaviorWnd );
  3205. if( ! bFieldSelectionMode )
  3206. return false;
  3207. CExtSafeString strText = m_pEditWithBehaviorWnd->TextGet();
  3208. if( strText.IsEmpty() )
  3209. return false;
  3210. INT nLength = INT( strText.GetLength() );
  3211. bool bNullableMode = NullableModeGet();
  3212. TCHAR _tchrNullChar = TCHAR( NullCharGet() );
  3213. TCHAR _tchrMask = m_strMask.GetAt(_currentPosition);
  3214. CExtSafeString strSymbols;
  3215. INT nSymbolIndex, nSymbolCount = INT(m_arrRules.GetSize());
  3216. for( nSymbolIndex = 0; nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  3217. strSymbols += TCHAR(__EXT_MFC_SAFE_TCHAR(m_arrRules[nSymbolIndex]));
  3218. if( strSymbols.FindOneOf( & _tchrMask ) < 0 )
  3219. return false;
  3220. INT _maskLen = m_strMask.GetLength();
  3221. if( _maskLen == _currentPosition + 1 )
  3222. return false;
  3223. _tchrMask = m_strMask.GetAt(_currentPosition + 1);
  3224. if( strSymbols.FindOneOf( & _tchrMask ) >= 0 )
  3225. return false;
  3226. INT _startPosition = -1;
  3227. INT _endPosition = -1;
  3228. INT i = _currentPosition + 1;
  3229. for( ; i < nLength; i++ )
  3230. {
  3231. _tchrMask = m_strMask.GetAt(i);
  3232. if( strSymbols.FindOneOf( & _tchrMask ) >= 0 )
  3233. {
  3234. _startPosition = i;
  3235. break;
  3236. }
  3237. }
  3238. if( _startPosition < 0 )
  3239. return false;
  3240. for( i = _startPosition; i < nLength; i++ )
  3241. {
  3242. _tchrMask = m_strMask.GetAt(i);
  3243. if( strSymbols.FindOneOf( & _tchrMask ) < 0 )
  3244. {
  3245. _endPosition = i;
  3246. break;
  3247. }
  3248. }
  3249. if( _endPosition < 0 )
  3250. _endPosition = nLength;
  3251. m_pEditWithBehaviorWnd->SetSel( _startPosition, _endPosition );
  3252. CExtSafeString strIns;
  3253. for( i = _startPosition; i < _endPosition; i ++ )
  3254. strIns += _tchrNullChar;
  3255. if( ! strIns.IsEmpty() && bNullableMode )
  3256. {
  3257. m_pEditWithBehaviorWnd->ReplaceSel( strIns, TRUE );
  3258. m_pEditWithBehaviorWnd->SetSel( _startPosition, _endPosition );
  3259. }
  3260. return true;
  3261. }
  3262. void CExtEditWithBehavior::CBehaviorMasked::_ShowNullableMask()
  3263. {
  3264. if( m_pEditWithBehaviorWnd->GetSafeHwnd() == NULL )
  3265. return;
  3266. ASSERT_VALID( m_pEditWithBehaviorWnd );
  3267. bool bNullableMode = NullableModeGet();
  3268. if( ! bNullableMode || m_pEditWithBehaviorWnd == NULL )
  3269. return;
  3270. INT nMaskLength = INT( m_strMask.GetLength() );
  3271. TCHAR _tchrNullChar = TCHAR(NullCharGet());
  3272. CExtSafeString strText;
  3273. for( INT i = 0; i < nMaskLength; i ++ )
  3274. {
  3275. TCHAR _tchrMask = m_strMask.GetAt( i );
  3276. INT nSymbolIndex, nSymbolCount = INT(m_arrRules.GetSize());
  3277. for( nSymbolIndex = 0; nSymbolIndex < nSymbolCount; nSymbolIndex++ )
  3278. {
  3279. const CharRule & symbol = m_arrRules[nSymbolIndex];
  3280. if( _tchrMask == TCHAR(__EXT_MFC_SAFE_TCHAR(symbol)) )
  3281. _tchrMask = _tchrNullChar;
  3282. }
  3283. strText += _tchrMask;
  3284. }
  3285. m_pEditWithBehaviorWnd->TextSet( strText );
  3286. }
  3287. /////////////////////////////////////////////////////////////////////////////
  3288. // CExtEditWithBehavior::CBehaviorMasked::CharRule
  3289. CExtEditWithBehavior::CBehaviorMasked::CharRule::CharRule()
  3290. : m_cSymbol( __EXT_MFC_SAFE_TCHAR(TCHAR(0)) )
  3291. , m_fnValidation( NULL )
  3292. , m_fnConversion( NULL )
  3293. , m_clrSymbol( COLORREF(-1L) )
  3294. {
  3295. }
  3296. CExtEditWithBehavior::CBehaviorMasked::CharRule::CharRule( __EXT_MFC_SAFE_TCHAR cSymbol, ValidationFunction fnValidation, ConversionFunction fnConversion /*= NULL*/ )
  3297. : m_cSymbol( cSymbol )