SPMaskEditT.h 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519
  1. /********************************************
  2. ** 工作室:S&P工作室
  3. ** 作者 :张东斌
  4. ** 日期 :2006年3月
  5. *********************************************/
  6. #if !defined(__XTMASKEDITEX_H__)
  7. #define __XTMASKEDITEX_H__
  8. #if _MSC_VER >= 1000
  9. #pragma once
  10. #endif // _MSC_VER >= 1000
  11. //////////////////////////////////////////////////////////////////////
  12. // Summary:
  13. // CXTMaskEditT is a template class. It allows text masking to be
  14. // applied to the control to format it for special editing restrictions.
  15. //////////////////////////////////////////////////////////////////////
  16. template < class TBase >
  17. class CXTMaskEditT : public TBase
  18. {
  19. public:
  20. //-----------------------------------------------------------------------
  21. // Summary:
  22. // Constructs a CXTMaskEditT object
  23. //-----------------------------------------------------------------------
  24. CXTMaskEditT() : m_nStartChar( 0 ) , m_nEndChar( 0 ) , m_bOverType( true ) , m_bUseMask( true ) , m_bRedo( false ) , m_bModified( false ) , m_strWindowText( _T( "" ) ) , m_strMask( _T( "" ) ) , m_strLiteral( _T( "" ) ) , m_strDefault( _T( "" ) ) , m_strUndoBuffer( _T( "" ) ) , m_chPrompt( _T( '_' ) )
  25. {
  26. }
  27. public:
  28. //-----------------------------------------------------------------------
  29. // Parameters:
  30. // bUseMask - true to enable the mask. false to disable the mask.
  31. // Summary:
  32. // Call this member function to enable or disable the mask for the mask
  33. // edit control.
  34. //-----------------------------------------------------------------------
  35. void SetUseMask( bool bUseMask )
  36. {
  37. m_bUseMask = bUseMask;
  38. }
  39. //-----------------------------------------------------------------------
  40. // Summary:
  41. // This member function is called to determine if the mask for the edit
  42. // control can be used.
  43. // Returns:
  44. // true if the mask can be used, otherwise returns false.
  45. //-----------------------------------------------------------------------
  46. bool CanUseMask()
  47. {
  48. return m_bUseMask && ( ( GetStyle() & ES_READONLY ) == 0 );
  49. }
  50. //-----------------------------------------------------------------------
  51. // Summary:
  52. // This member function is called to enable or disable type over, also
  53. // known as insert mode.
  54. // Parameters:
  55. // bOverType - true to enable type over.
  56. //-----------------------------------------------------------------------
  57. void SetOverType( bool bOverType )
  58. {
  59. m_bOverType = bOverType;
  60. }
  61. //-----------------------------------------------------------------------
  62. // Summary:
  63. // This member function is called to determine if type over has been enabled.
  64. // Returns:
  65. // true if type over is enabled, otherwise returns false.
  66. //-----------------------------------------------------------------------
  67. bool CanOverType()
  68. {
  69. return m_bOverType;
  70. }
  71. //-----------------------------------------------------------------------
  72. // Summary:
  73. // This member function is called to determine if the index specified
  74. // by 'iPos' is a valid index for the currently displayed edit text.
  75. // Parameters:
  76. // iPos - Index of the character to check.
  77. // Returns:
  78. // true if the index is valid, otherwise returns false.
  79. //-----------------------------------------------------------------------
  80. bool PosInRange( int iPos )
  81. {
  82. return ( ( iPos >= 0 ) && ( iPos < m_strLiteral.GetLength() ) );
  83. }
  84. //-----------------------------------------------------------------------
  85. // Summary:
  86. // This member function retrieves the character that is currently used as
  87. // the mask prompt. The mask prompt indicates that the field is editable.
  88. // Returns:
  89. // A TCHAR data type.
  90. //-----------------------------------------------------------------------
  91. TCHAR GetPromptChar()
  92. {
  93. return m_chPrompt;
  94. }
  95. //-----------------------------------------------------------------------
  96. // Summary:
  97. // This member function is called to set the prompt character that is
  98. // displayed to the user that indicates the field can be edited.
  99. // Parameters:
  100. // ch - A TCHAR data type.
  101. //-----------------------------------------------------------------------
  102. void SetPromptChar( TCHAR ch )
  103. {
  104. if ( m_chPrompt == ch )
  105. {
  106. return;
  107. }
  108. for ( int i = 0; i < m_strLiteral.GetLength(); i++ )
  109. {
  110. if ( m_strLiteral[i] == m_chPrompt )
  111. {
  112. m_strLiteral.SetAt( i,ch );
  113. }
  114. }
  115. for ( int j = 0; j < m_strWindowText.GetLength(); j++ )
  116. {
  117. if ( m_strWindowText[j] == m_chPrompt )
  118. {
  119. m_strWindowText.SetAt( j,ch );
  120. }
  121. }
  122. m_chPrompt = ch;
  123. SetWindowText( m_strWindowText );
  124. }
  125. //-----------------------------------------------------------------------
  126. // Summary:
  127. // This member function is called to perform a cut operation using the
  128. // currently selected text.
  129. //-----------------------------------------------------------------------
  130. void MaskCut()
  131. {
  132. if ( !CanUseMask() )
  133. {
  134. DefWindowProc( WM_CUT,0,0 );
  135. }
  136. else
  137. {
  138. MaskCopy();
  139. MaskClear();
  140. m_bRedo = false;
  141. m_bModified = true;
  142. SetWindowText( m_strWindowText );
  143. CorrectPosition( m_nStartChar );
  144. m_nEndChar = m_nStartChar;
  145. SetSel( m_nStartChar,m_nEndChar );
  146. }
  147. }
  148. //-----------------------------------------------------------------------
  149. // Summary:
  150. // This member function is called to perform a copy operation using the
  151. // currently selected text.
  152. //-----------------------------------------------------------------------
  153. void MaskCopy()
  154. {
  155. if ( !CanUseMask() )
  156. {
  157. DefWindowProc( WM_COPY,0,0 );
  158. }
  159. else
  160. {
  161. GetSel( m_nStartChar,m_nEndChar );
  162. CString strBuffer;
  163. int i;
  164. for ( i = m_nStartChar; i < m_nEndChar; ++i )
  165. {
  166. if ( m_strLiteral.GetAt( i ) == m_chPrompt )
  167. {
  168. if ( m_strWindowText.GetAt( i ) == m_chPrompt )
  169. continue;
  170. strBuffer += m_strWindowText.GetAt( i );
  171. }
  172. }
  173. CopyToClipboard( strBuffer );
  174. }
  175. }
  176. //-----------------------------------------------------------------------
  177. // Summary:
  178. // This member function is called to perform a paste operation using the
  179. // current clipboard text.
  180. //-----------------------------------------------------------------------
  181. void MaskPaste()
  182. {
  183. if ( !CanUseMask() )
  184. {
  185. DefWindowProc( WM_PASTE,0,0 );
  186. }
  187. else
  188. {
  189. GetSel( m_nStartChar,m_nEndChar );
  190. MaskClear();
  191. if ( !OpenClipboard() )
  192. return;
  193. LPTSTR lptstrPaste = NULL;
  194. HGLOBAL hglbPaste = ::GetClipboardData( CF_TEXT );
  195. if ( hglbPaste != NULL )
  196. {
  197. lptstrPaste = ( TCHAR * ) ::GlobalLock( hglbPaste );
  198. if ( lptstrPaste != NULL )
  199. {
  200. ::GlobalUnlock( hglbPaste );
  201. }
  202. }
  203. ::CloseClipboard();
  204. int i, x = m_nStartChar, iLen = ( int ) _tcslen( lptstrPaste );
  205. for ( i = 0; i < iLen; ++i )
  206. {
  207. UINT ch = lptstrPaste[i];
  208. if ( CheckChar( ch,false ) )
  209. {
  210. InsertCharAt( x,( TCHAR ) ch );
  211. ++x;
  212. if ( x == m_strWindowText.GetLength() )
  213. break;
  214. }
  215. }
  216. m_bRedo = false;
  217. m_bModified = true;
  218. SetWindowText( m_strWindowText );
  219. m_nEndChar = m_nStartChar;
  220. SetSel( m_nStartChar,m_nEndChar );
  221. }
  222. }
  223. //-----------------------------------------------------------------------
  224. // Summary:
  225. // This member function is called to clear the current text selection.
  226. //-----------------------------------------------------------------------
  227. void MaskClear()
  228. {
  229. if ( !CanUseMask() )
  230. {
  231. DefWindowProc( WM_CLEAR,0,0 );
  232. }
  233. else
  234. {
  235. if ( m_nStartChar == m_nEndChar )
  236. return;
  237. // check to see if there is anything left to delete
  238. int iLength = m_strWindowText.GetLength();
  239. int i;
  240. for ( i = m_nStartChar; i < iLength; ++i )
  241. {
  242. TCHAR ch1 = m_strLiteral.GetAt( i );
  243. TCHAR ch2 = m_strWindowText.GetAt( i );
  244. if ( ( ch1 == m_chPrompt ) && ( ch2 != m_chPrompt ) )
  245. {
  246. break;
  247. }
  248. }
  249. if ( i == iLength )
  250. {
  251. ::MessageBeep( ( UINT ) - 1 );
  252. return;
  253. }
  254. for ( i = m_nStartChar; i < m_nEndChar; ++i )
  255. {
  256. if ( m_strLiteral.GetAt( i ) == m_chPrompt )
  257. {
  258. DeleteCharAt( m_nStartChar );
  259. }
  260. }
  261. m_bRedo = false;
  262. m_bModified = true;
  263. SetWindowText( m_strWindowText );
  264. m_nEndChar = m_nStartChar;
  265. SetSel( m_nStartChar,m_nEndChar );
  266. }
  267. }
  268. //-----------------------------------------------------------------------
  269. // Summary:
  270. // This member function is called to undo the previous action.
  271. //-----------------------------------------------------------------------
  272. void MaskUndo()
  273. {
  274. if ( !CanUseMask() )
  275. {
  276. DefWindowProc( EM_UNDO,0,0 );
  277. }
  278. else
  279. {
  280. GetSel( m_nStartChar,m_nEndChar );
  281. if ( m_bRedo )
  282. {
  283. m_bRedo = false;
  284. m_bModified = true;
  285. SetWindowText( m_strRedoBuffer );
  286. }
  287. else
  288. {
  289. m_bRedo = true;
  290. m_bModified = true;
  291. GetWindowText( m_strRedoBuffer );
  292. SetWindowText( m_strUndoBuffer );
  293. }
  294. GetWindowText( m_strWindowText );
  295. m_nEndChar = m_nStartChar;
  296. SetSel( m_nStartChar,m_nEndChar );
  297. }
  298. }
  299. //-----------------------------------------------------------------------
  300. // Summary:
  301. // This member function is called to select all text in the mask edit
  302. // control.
  303. //-----------------------------------------------------------------------
  304. void MaskSelectAll()
  305. {
  306. if ( !CanUseMask() )
  307. {
  308. CEdit::SetSel( 0,-1 );
  309. }
  310. else
  311. {
  312. m_nStartChar = 0;
  313. CorrectPosition( m_nStartChar );
  314. SetSel( m_nStartChar,-1 );
  315. }
  316. }
  317. //-----------------------------------------------------------------------}
  318. // Summary:
  319. // This member function is called to determine if the text has been modified.
  320. // Returns:
  321. // true if the text has changed, otherwise returns false.
  322. //-----------------------------------------------------------------------
  323. bool IsModified()
  324. {
  325. return m_bModified;
  326. }
  327. //-----------------------------------------------------------------------
  328. // Summary:
  329. // This method called to set masked text for the edit control.
  330. // Parameters:
  331. // lpszMaskedText - Text string without mask.
  332. // Remarks:
  333. // If a mask is used, then the mask will be applied to the text
  334. // in lpszMaskedText.
  335. //-----------------------------------------------------------------------
  336. void SetMaskedText( LPCTSTR lpszMaskedText )
  337. {
  338. CString strMaskedText = lpszMaskedText;
  339. int nLen = strMaskedText.GetLength();
  340. int x = 0;
  341. m_strWindowText = m_strLiteral;
  342. for ( int i = 0; ( i < m_strWindowText.GetLength() ) && ( x < nLen ); i++ )
  343. {
  344. if ( strMaskedText[x] == m_strWindowText[i] )
  345. {
  346. x ++;
  347. }
  348. else if ( m_strWindowText[i] == m_chPrompt )
  349. {
  350. m_strWindowText.SetAt( i,strMaskedText[x] );
  351. x ++;
  352. }
  353. }
  354. // set the window text for the control.
  355. m_bRedo = false;
  356. m_bModified = false;
  357. SetWindowText( m_strWindowText );
  358. m_strUndoBuffer = m_strWindowText;
  359. }
  360. //-----------------------------------------------------------------------
  361. // Summary:
  362. // This member function will set the mask for the edit control.
  363. // Parameters:
  364. // lpszMask - The format for the mask field. For example, if you wanted to set
  365. // the mask for a phone number, and you only wanted digits to be entered,
  366. // your mask might look like this; _T("(000) 000-0000").
  367. // lpszLiteral - The literal format is entered here. Wherever you place an underscore
  368. // ('_') is where the user will be allowed to enter data only. Using
  369. // the phone number example; _T("(___) ___-____").
  370. // lpszDefault - Text that is to be displayed when the control is initialized. For
  371. // example; _T("(800) 555-1212"). If NULL, 'lpszLiteral' is used to initialize
  372. // the edit text.
  373. // Remarks:
  374. // The values that can be set are:
  375. // <TABLE>
  376. // <b>Mask Character</b> <b>Description</b>
  377. // --------------------- ------------------------
  378. // 0 Numeric (0-9)
  379. // 9 Numeric (0-9) or space (' ')
  380. // # Numeric (0-9) or space (' ') or ('+') or ('-')
  381. // L Alpha (a-Z)
  382. // ? Alpha (a-Z) or space (' ')
  383. // A Alpha numeric (0-9 and a-Z)
  384. // a Alpha numeric (0-9 and a-Z) or space (' ')
  385. // & All print character only
  386. // H Hex digit (0-9 and A-F)
  387. // X Hex digit (0-9 and A-F) and space (' ')
  388. // > Forces characters to upper case (A-Z)
  389. // < Forces characters to lower case (a-z)
  390. // </TABLE>
  391. //-----------------------------------------------------------------------
  392. virtual void SetEditMask( LPCTSTR lpszMask , LPCTSTR lpszLiteral , LPCTSTR lpszDefault = NULL )
  393. {
  394. ASSERT( lpszMask );
  395. ASSERT( lpszLiteral );
  396. // initialize the mask for the control.
  397. m_strMask = lpszMask;
  398. m_strLiteral = lpszLiteral;
  399. ASSERT( m_strMask.GetLength() == m_strLiteral.GetLength() );
  400. if ( lpszDefault == NULL )
  401. {
  402. m_strWindowText = lpszLiteral;
  403. m_strDefault = lpszLiteral;
  404. }
  405. else
  406. {
  407. SetMaskedText( lpszDefault );
  408. m_strDefault = m_strWindowText;
  409. }
  410. ASSERT( m_strWindowText.GetLength() == m_strLiteral.GetLength() );
  411. // set the window text for the control.
  412. m_bRedo = false;
  413. m_bModified = false;
  414. SetWindowText( m_strWindowText );
  415. m_strUndoBuffer = m_strWindowText;
  416. }
  417. //-----------------------------------------------------------------------
  418. // Summary:
  419. // Converts character to Upper/Lower case.
  420. // Parameters:
  421. // nChar - Char to be converted
  422. // bUpperCase - TRUE to convert to upper case
  423. // Returns:
  424. // Converted character.
  425. //-----------------------------------------------------------------------
  426. TCHAR ConvertUnicodeAlpha( TCHAR nChar , BOOL bUpperCase )
  427. {
  428. CString strTemp ( nChar );
  429. if ( bUpperCase )
  430. {
  431. strTemp.MakeUpper();
  432. }
  433. else
  434. {
  435. strTemp.MakeLower();
  436. }
  437. return strTemp[0];
  438. }
  439. //-----------------------------------------------------------------------
  440. // Summary:
  441. // This method determines if nChar is alpha character
  442. // Parameters:
  443. // nChar - Character need to test
  444. // Returns:
  445. // true if nChar is alpha character.
  446. //-----------------------------------------------------------------------
  447. bool IsUnicodeAlpha( TCHAR nChar )
  448. {
  449. if ( ConvertUnicodeAlpha( nChar,TRUE ) != nChar )
  450. {
  451. return TRUE;
  452. }
  453. if ( ConvertUnicodeAlpha( nChar,FALSE ) != nChar )
  454. {
  455. return TRUE;
  456. }
  457. return FALSE;
  458. }
  459. //-----------------------------------------------------------------------
  460. // Summary:
  461. // This member function is used internally to validate the character indicated
  462. // by 'nChar'.
  463. // Parameters:
  464. // nChar - Contains the character code value of the key.
  465. // bBeep - true to enable beep. false to disable beep.
  466. // Returns:
  467. // true if successful, otherwise returns false.
  468. //-----------------------------------------------------------------------
  469. virtual bool CheckChar( UINT & nChar , bool bBeep = true )
  470. {
  471. // do not use mask
  472. if ( !CanUseMask() )
  473. {
  474. return false;
  475. }
  476. // control character, OK
  477. if ( !_istprint( ( TCHAR ) nChar ) && !IsUnicodeAlpha( ( TCHAR ) nChar ) )
  478. {
  479. return true;
  480. }
  481. // advance to the first character input position.
  482. int i;
  483. for ( i = m_nStartChar; i < m_strLiteral.GetLength(); ++i )
  484. {
  485. if ( m_strLiteral.GetAt( i ) == m_chPrompt )
  486. {
  487. SetSel( i,i );
  488. break;
  489. }
  490. }
  491. // make sure the string is not longer than the mask
  492. if ( i >= m_strMask.GetLength() )
  493. {
  494. if ( bBeep )
  495. {
  496. :: MessageBeep( ( UINT ) - 1 );
  497. }
  498. return false;
  499. }
  500. if ( !ProcessMask( nChar,i ) )
  501. {
  502. if ( bBeep )
  503. {
  504. :: MessageBeep( ( UINT ) - 1 );
  505. }
  506. return false;
  507. }
  508. return true;
  509. }
  510. //-----------------------------------------------------------------------
  511. // Summary:
  512. // This member function is used internally to process the character passed
  513. // in by 'nChar' whose index is specified by 'nEndPos'.
  514. // Parameters:
  515. // nChar - Contains the character code value of the key.
  516. // nEndPos - Index of character in display string.
  517. // Returns:
  518. // true if successful, otherwise returns false.
  519. //-----------------------------------------------------------------------
  520. virtual bool ProcessMask( UINT & nChar , int nEndPos )
  521. {
  522. // check the key against the mask
  523. switch ( m_strMask.GetAt( nEndPos ) )
  524. {
  525. case '0':
  526. // digit only //completely changed this
  527. {
  528. if ( _istdigit( ( TCHAR ) nChar ) )
  529. {
  530. return true;
  531. }
  532. break;
  533. }
  534. case '9':
  535. // digit or space
  536. {
  537. if ( _istdigit( ( TCHAR ) nChar ) )
  538. {
  539. return true;
  540. }
  541. if ( nChar == ' ' )
  542. {
  543. return true;
  544. }
  545. break;
  546. }
  547. case '#':
  548. // digit or space or '+' or '-'
  549. {
  550. if ( _istdigit( ( TCHAR ) nChar ) )
  551. {
  552. return true;
  553. }
  554. if ( nChar == ' ' || nChar == '-' || nChar == '+' )
  555. {
  556. return true;
  557. }
  558. break;
  559. }
  560. case 'd':
  561. // decimal
  562. {
  563. if ( _istdigit( ( TCHAR ) nChar ) )
  564. {
  565. return true;
  566. }
  567. if ( nChar == ' ' || nChar == '-' || nChar == '+' || nChar == '.' || nChar == ',' )
  568. {
  569. return true;
  570. }
  571. break;
  572. }
  573. case 'L':
  574. // alpha only
  575. {
  576. if ( _istalpha( ( TCHAR ) nChar ) || IsUnicodeAlpha( ( TCHAR ) nChar ) )
  577. {
  578. return true;
  579. }
  580. break;
  581. }
  582. case '?':
  583. // alpha or space
  584. {
  585. if ( _istalpha( ( TCHAR ) nChar ) || IsUnicodeAlpha( ( TCHAR ) nChar ) )
  586. {
  587. return true;
  588. }
  589. if ( nChar == ' ' )
  590. {
  591. return true;
  592. }
  593. break;
  594. }
  595. case 'A':
  596. // alpha numeric only
  597. {
  598. if ( _istalnum( ( TCHAR ) nChar ) || IsUnicodeAlpha( ( TCHAR ) nChar ) )
  599. {
  600. return true;
  601. }
  602. break;
  603. }
  604. case 'a':
  605. // alpha numeric or space
  606. {
  607. if ( _istalnum( ( TCHAR ) nChar ) || IsUnicodeAlpha( ( TCHAR ) nChar ) )
  608. {
  609. return true;
  610. }
  611. if ( nChar == ' ' )
  612. {
  613. return true;
  614. }
  615. break;
  616. }
  617. case '&':
  618. // all print character only
  619. {
  620. if ( _istprint( ( TCHAR ) nChar ) || IsUnicodeAlpha( ( TCHAR ) nChar ) )
  621. {
  622. return true;
  623. }
  624. break;
  625. }
  626. case 'H':
  627. // hex digit
  628. {
  629. if ( _istxdigit( ( TCHAR ) nChar ) )
  630. {
  631. return true;
  632. }
  633. break;
  634. }
  635. case 'X':
  636. // hex digit or space
  637. {
  638. if ( _istxdigit( ( TCHAR ) nChar ) )
  639. {
  640. return true;
  641. }
  642. if ( nChar == ' ' )
  643. {
  644. return true;
  645. }
  646. break;
  647. }
  648. case '>':
  649. {
  650. if ( _istalpha( ( TCHAR ) nChar ) || IsUnicodeAlpha( ( TCHAR ) nChar ) )
  651. {
  652. nChar = ConvertUnicodeAlpha( ( TCHAR ) nChar,TRUE );
  653. return true;
  654. }
  655. break;
  656. }
  657. case '<':
  658. {
  659. if ( _istalpha( ( TCHAR ) nChar ) || IsUnicodeAlpha( ( TCHAR ) nChar ) )
  660. {
  661. nChar = ConvertUnicodeAlpha( ( TCHAR ) nChar,FALSE );
  662. return true;
  663. }
  664. break;
  665. }
  666. }
  667. return false;
  668. }
  669. public:
  670. //-----------------------------------------------------------------------
  671. // Summary:
  672. // Used by class CWinApp to translate window messages before they are dispatched to theTranslateMessage andDispatchMessage Windows functions.
  673. // Parameters:
  674. // pMsg - Points to a MSG structure that contains the message to process.
  675. // Returns:
  676. // Nonzero if the message was translated and should not be dispatched; 0 if the message was not translated and should be dispatched.
  677. //-----------------------------------------------------------------------
  678. virtual BOOL PreTranslateMessage( MSG * pMsg )
  679. {
  680. if ( !CanUseMask() )
  681. {
  682. return TBase::PreTranslateMessage( pMsg );
  683. }
  684. // intercept Ctrl+C (copy), Ctrl+V (paste), Ctrl+X (cut) and Ctrl+Z (undo)
  685. // before CEdit base class gets a hold of them.
  686. if ( pMsg->message == WM_KEYDOWN )
  687. {
  688. if ( ::GetKeyState( VK_SUBTRACT ) < 0 )
  689. {
  690. OnChar( '-',1,1 );
  691. return TRUE;
  692. }
  693. if ( ::GetKeyState( VK_ADD ) < 0 )
  694. {
  695. OnChar( '+',1,1 );
  696. return TRUE;
  697. }
  698. if ( ::GetKeyState( VK_CONTROL ) < 0 )
  699. {
  700. switch ( pMsg->wParam )
  701. {
  702. case 'X':
  703. case 'x':
  704. {
  705. MaskCut();
  706. return TRUE;
  707. }
  708. case 'C':
  709. case 'c':
  710. {
  711. MaskCopy();
  712. return TRUE;
  713. }
  714. case 'V':
  715. case 'v':
  716. {
  717. MaskPaste();
  718. return TRUE;
  719. }
  720. case 'Z':
  721. case 'z':
  722. {
  723. MaskUndo();
  724. return TRUE;
  725. }
  726. }
  727. }
  728. else
  729. {
  730. switch ( pMsg->wParam )
  731. {
  732. case '-':
  733. {
  734. OnChar( '-',1,1 );
  735. return TRUE;
  736. }
  737. case '+':
  738. {
  739. OnChar( '+',1,1 );
  740. return TRUE;
  741. }
  742. }
  743. }
  744. }
  745. return TBase::PreTranslateMessage( pMsg );
  746. }
  747. //{{AFX_CODEJOCK_PRIVATE
  748. virtual bool CorrectPosition(int& iPos, bool bForward=true, bool bBeep=true) // used internally
  749. {
  750. GetWindowText( m_strWindowText );
  751. int iLen = m_strWindowText.GetLength( );
  752. if ( iPos == iLen )
  753. {
  754. if ( bBeep )
  755. {
  756. ::MessageBeep( ( UINT )-1 );
  757. }
  758. return false;
  759. }
  760. if (! PosInRange(iPos))
  761. return false;
  762. if ( m_strLiteral.GetAt( iPos ) != m_chPrompt )
  763. {
  764. int i;
  765. if ( bForward )
  766. {
  767. for ( i = iPos; i < iLen; ++i )
  768. {
  769. if ( m_strLiteral.GetAt( i ) == m_chPrompt )
  770. {
  771. iPos = i;
  772. break;
  773. }
  774. }
  775. }
  776. else
  777. {
  778. for ( i = iPos; i >= 0; --i )
  779. {
  780. if ( m_strLiteral.GetAt( i ) == m_chPrompt )
  781. {
  782. iPos = i;
  783. break;
  784. }
  785. }
  786. if ( i == -1 )
  787. {
  788. iPos++;
  789. if ( bBeep )
  790. {
  791. ::MessageBeep( ( UINT )-1 );
  792. }
  793. return false;
  794. }
  795. }
  796. if ( i == iLen )
  797. {
  798. if ( bBeep )
  799. {
  800. ::MessageBeep( ( UINT )-1 );
  801. }
  802. return false;
  803. }
  804. }
  805. return true;
  806. }
  807. //}}AFX_CODEJOCK_PRIVATE
  808. //-----------------------------------------------------------------------
  809. // Summary:
  810. // Deletes character in specified position
  811. // Parameters:
  812. // iPos - Position for character to be deleted.
  813. //-----------------------------------------------------------------------
  814. virtual void DeleteCharAt( int iPos )
  815. {
  816. if ( !PosInRange( iPos ) )
  817. {
  818. return;
  819. }
  820. CString strBuffer = GetMaskedText( iPos + 1 );
  821. strBuffer += m_chPrompt;
  822. int x = 0;
  823. int iLen = strBuffer.GetLength();
  824. int i;
  825. for ( i = iPos; i < m_strLiteral.GetLength(); ++i )
  826. {
  827. if ( ( m_strLiteral.GetAt( i ) == m_chPrompt ) )
  828. {
  829. m_strWindowText.SetAt( i,strBuffer.GetAt( x ) );
  830. ++x;
  831. if ( x == iLen )
  832. break;
  833. }
  834. }
  835. }
  836. //-----------------------------------------------------------------------
  837. // Summary:
  838. // Inserts character to specified position.
  839. // Parameters:
  840. // iPos - Position to insert
  841. // nChar - Character to be inserted
  842. //-----------------------------------------------------------------------
  843. virtual void InsertCharAt( int iPos , TCHAR nChar )
  844. {
  845. if ( !PosInRange( iPos ) )
  846. {
  847. return;
  848. }
  849. UINT uChar = nChar;
  850. if ( !CheckChar( uChar,false ) )
  851. {
  852. return;
  853. }
  854. CString strBuffer = GetMaskedText( iPos );
  855. CString strTemp ( nChar );
  856. int i, x = 0, iLen = strBuffer.GetLength();
  857. for ( i = 1; i < strBuffer.GetLength(); ++i )
  858. {
  859. strTemp += strBuffer.GetAt( i - 1 );
  860. }
  861. strBuffer = strTemp;
  862. for ( i = iPos; i < m_strWindowText.GetLength(); ++i )
  863. {
  864. if ( m_strLiteral.GetAt( i ) == m_chPrompt )
  865. {
  866. m_strWindowText.SetAt( i,strBuffer[x] );
  867. ++x;
  868. if ( x == iLen )
  869. break;
  870. }
  871. }
  872. }
  873. //-----------------------------------------------------------------------
  874. // Summary:
  875. // Copies text to system clipboard
  876. // Parameters:
  877. // lpszText - Text to be copied
  878. // Returns:
  879. // TRUE if successful; otherwise returns FALSE
  880. //-----------------------------------------------------------------------
  881. virtual bool CopyToClipboard( LPCTSTR lpszText )
  882. {
  883. if ( !OpenClipboard() )
  884. {
  885. return false;
  886. }
  887. ::EmptyClipboard();
  888. int iLen = ( int ) _tcslen( lpszText ) + 1;
  889. HGLOBAL hglbCopy = ::GlobalAlloc( GMEM_MOVEABLE,iLen );
  890. if ( hglbCopy == NULL )
  891. {
  892. ::CloseClipboard();
  893. return false;
  894. }
  895. LPTSTR lptstrCopy = ( TCHAR * ) ::GlobalLock( hglbCopy );
  896. memcpy( lptstrCopy,lpszText,iLen );
  897. ::GlobalUnlock( hglbCopy );
  898. ::SetClipboardData( CF_TEXT,hglbCopy );
  899. if ( !::CloseClipboard() )
  900. {
  901. return false;
  902. }
  903. return true;
  904. }
  905. //-----------------------------------------------------------------------
  906. // Summary:
  907. // Retrieves masked text of the control
  908. // Parameters:
  909. // iPos - Start position
  910. // Returns:
  911. // Masked text of the control.
  912. //-----------------------------------------------------------------------
  913. virtual CString GetMaskedText( int iPos = 0 )
  914. {
  915. int iWndLen = m_strWindowText.GetLength();
  916. ASSERT( iWndLen == m_strLiteral.GetLength() ); // must be equal in length
  917. CString strBuffer;
  918. int i;
  919. for ( i = iPos; i < iWndLen; ++i )
  920. {
  921. if ( m_strLiteral.GetAt( i ) == m_chPrompt )
  922. {
  923. strBuffer += m_strWindowText.GetAt( i );
  924. }
  925. }
  926. return strBuffer;
  927. }
  928. //-----------------------------------------------------------------------
  929. // Summary:
  930. // Call this member function to determine if a selection has been made
  931. // Returns:
  932. // TRUE if successful; otherwise returns FALSE
  933. //-----------------------------------------------------------------------
  934. virtual BOOL SelectionMade()
  935. {
  936. GetSel( m_nStartChar,m_nEndChar ); return ( m_nStartChar != m_nEndChar );
  937. }
  938. protected:
  939. //{{AFX_CODEJOCK_PRIVATE
  940. afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  941. {
  942. if (!CanUseMask())
  943. {
  944. TBase::OnKeyDown( nChar, nRepCnt, nFlags ); // default processing.
  945. return;
  946. }
  947. GetWindowText( m_strWindowText ); // refresh
  948. GetSel( m_nStartChar, m_nEndChar );
  949. if ( m_strMask.IsEmpty( ) )
  950. {
  951. TBase::OnKeyDown( nChar, nRepCnt, nFlags ); // default processing.
  952. return;
  953. }
  954. bool bShift = (::GetKeyState(VK_SHIFT) < 0);
  955. switch ( nChar )
  956. {
  957. case VK_UP:
  958. case VK_LEFT:
  959. {
  960. TBase::OnKeyDown( nChar, nRepCnt, nFlags );
  961. GetSel( m_nStartChar, m_nEndChar );
  962. int iStartChar = m_nStartChar;
  963. CorrectPosition( iStartChar, false, false );
  964. if ( m_nStartChar < iStartChar )
  965. {
  966. m_nStartChar = iStartChar;
  967. if ( !bShift )
  968. m_nEndChar = iStartChar;
  969. SetSel( m_nStartChar, m_nEndChar );
  970. }
  971. }
  972. return;
  973. case VK_DOWN:
  974. case VK_RIGHT:
  975. {
  976. TBase::OnKeyDown( nChar, nRepCnt, nFlags );
  977. GetSel( m_nStartChar, m_nEndChar );
  978. int iEndChar = m_nEndChar;
  979. CorrectPosition( iEndChar, true, false );
  980. if ( m_nEndChar > iEndChar )
  981. {
  982. m_nEndChar = iEndChar;
  983. if ( !bShift )
  984. m_nStartChar = iEndChar;
  985. SetSel( m_nStartChar, m_nEndChar );
  986. }
  987. }
  988. return;
  989. case VK_HOME:
  990. {
  991. TBase::OnKeyDown( nChar, nRepCnt, nFlags );
  992. GetSel( m_nStartChar, m_nEndChar );
  993. int iStartChar = m_nStartChar;
  994. CorrectPosition( iStartChar, true, false );
  995. if ( m_nStartChar < iStartChar )
  996. {
  997. m_nStartChar = iStartChar;
  998. if (!bShift)
  999. {
  1000. m_nEndChar = m_nStartChar;
  1001. }
  1002. SetSel( m_nStartChar, m_nEndChar );
  1003. }
  1004. }
  1005. return;
  1006. case VK_END:
  1007. {
  1008. TBase::OnKeyDown( nChar, nRepCnt, nFlags );
  1009. GetSel( m_nStartChar, m_nEndChar );
  1010. int iEndChar = m_nEndChar;
  1011. CorrectPosition( iEndChar, true, false );
  1012. if ( m_nEndChar > iEndChar )
  1013. {
  1014. m_nEndChar = iEndChar;
  1015. if ( !bShift )
  1016. m_nStartChar = iEndChar;
  1017. SetSel( m_nStartChar, m_nEndChar );
  1018. }
  1019. }
  1020. return;
  1021. case VK_INSERT:
  1022. {
  1023. if ( bShift )
  1024. {
  1025. MaskPaste( );
  1026. }
  1027. else
  1028. {
  1029. m_bOverType = !m_bOverType; // set the type-over flag
  1030. }
  1031. }
  1032. return;
  1033. case VK_DELETE:
  1034. {
  1035. if ( m_nStartChar == m_nEndChar )
  1036. {
  1037. if ( CorrectPosition( m_nStartChar ) )
  1038. {
  1039. DeleteCharAt( m_nStartChar );
  1040. m_bRedo = false;
  1041. m_bModified = true;
  1042. SetWindowText( m_strWindowText );
  1043. m_nEndChar = m_nStartChar;
  1044. SetSel( m_nStartChar, m_nEndChar );
  1045. }
  1046. }
  1047. else
  1048. {
  1049. MaskClear( );
  1050. }
  1051. }
  1052. return;
  1053. case VK_SPACE:
  1054. {
  1055. GetWindowText( m_strWindowText ); // refresh
  1056. if ( CorrectPosition( m_nStartChar ) )
  1057. {
  1058. if ( m_nStartChar < m_strLiteral.GetLength( ) )
  1059. {
  1060. if ( ProcessMask( nChar, m_nStartChar ) )
  1061. {
  1062. if ( CanOverType( ) )
  1063. {
  1064. m_strWindowText.SetAt( m_nStartChar, ' ' );
  1065. }
  1066. else
  1067. {
  1068. InsertCharAt( m_nStartChar, ( TCHAR )nChar );
  1069. }
  1070. }
  1071. else
  1072. {
  1073. m_strWindowText.SetAt( m_nStartChar, m_chPrompt );
  1074. }
  1075. m_bRedo = false;
  1076. m_bModified = true;
  1077. SetWindowText( m_strWindowText );
  1078. m_nStartChar++;
  1079. m_nEndChar = m_nStartChar;
  1080. SetSel( m_nStartChar, m_nEndChar );
  1081. }
  1082. else
  1083. {
  1084. ::MessageBeep( ( UINT )-1 );
  1085. }
  1086. }
  1087. }
  1088. return;
  1089. case VK_BACK:
  1090. {
  1091. GetWindowText( m_strWindowText ); // refresh
  1092. if ( ( m_nStartChar > 0 ) &&
  1093. ( m_nStartChar <= m_strLiteral.GetLength( ) ) )
  1094. {
  1095. m_nStartChar--;
  1096. if ( CorrectPosition( m_nStartChar, false ) )
  1097. {
  1098. TCHAR ch = m_chPrompt;
  1099. // get the masked literal representation.
  1100. if ( !m_strDefault.IsEmpty( ) )
  1101. {
  1102. ch = m_strDefault.GetAt( m_nStartChar );
  1103. }
  1104. m_strWindowText.SetAt( m_nStartChar, ch );
  1105. m_bRedo = false;
  1106. m_bModified = true;
  1107. SetWindowText( m_strWindowText );
  1108. m_nEndChar = m_nStartChar;
  1109. SetSel( m_nStartChar, m_nEndChar );
  1110. }
  1111. }
  1112. else
  1113. {
  1114. ::MessageBeep( ( UINT )-1 );
  1115. }
  1116. }
  1117. return;
  1118. }
  1119. TBase::OnKeyDown( nChar, nRepCnt, nFlags );
  1120. }
  1121. afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  1122. {
  1123. if (!CanUseMask())
  1124. {
  1125. TBase::OnChar(nChar, nRepCnt, nFlags);
  1126. return;
  1127. }
  1128. switch ( nChar )
  1129. {
  1130. case VK_UP:
  1131. case VK_LEFT:
  1132. case VK_DOWN:
  1133. case VK_RIGHT:
  1134. case VK_HOME:
  1135. case VK_END:
  1136. case VK_DELETE:
  1137. case VK_SPACE:
  1138. case VK_BACK:
  1139. return; // handled in WM_KEYDOWN
  1140. }
  1141. if (!CheckChar(nChar))
  1142. {
  1143. return;
  1144. }
  1145. if ( CanUseMask( ) )
  1146. {
  1147. if ( _istprint( ( TCHAR )nChar ) || IsUnicodeAlpha(( TCHAR )nChar))
  1148. {
  1149. int iLen = m_strLiteral.GetLength( );
  1150. if ( m_nStartChar >= iLen )
  1151. {
  1152. ::MessageBeep( ( UINT )-1 );
  1153. return;
  1154. }
  1155. if ( m_nEndChar >= iLen )
  1156. m_nEndChar = iLen-1;
  1157. if ( m_nStartChar != m_nEndChar )
  1158. {
  1159. int i;
  1160. for ( i = m_nStartChar; i < m_nEndChar; ++i )
  1161. {
  1162. if ( m_strLiteral.GetAt( i ) == m_chPrompt )
  1163. {
  1164. DeleteCharAt( m_nStartChar );
  1165. }
  1166. }
  1167. }
  1168. SetWindowText( m_strWindowText );
  1169. if ( CorrectPosition( m_nStartChar ) )
  1170. {
  1171. if ( CanOverType( ) )
  1172. {
  1173. if ( m_nStartChar != m_nEndChar )
  1174. {
  1175. InsertCharAt( m_nStartChar, ( TCHAR )nChar );
  1176. }
  1177. else
  1178. {
  1179. m_strWindowText.SetAt( m_nStartChar, ( TCHAR )nChar );
  1180. }
  1181. }
  1182. else
  1183. {
  1184. InsertCharAt( m_nStartChar, ( TCHAR )nChar );
  1185. }
  1186. }
  1187. m_bRedo = false;
  1188. m_bModified = true;
  1189. SetWindowText( m_strWindowText );
  1190. if (m_nStartChar < iLen )
  1191. m_nStartChar++;
  1192. if ( m_nStartChar < iLen )
  1193. CorrectPosition( m_nStartChar );
  1194. m_nEndChar = m_nStartChar;
  1195. SetSel( m_nStartChar, m_nEndChar );
  1196. return;
  1197. }
  1198. }
  1199. if (nChar != 127)
  1200. TBase::OnChar(nChar, nRepCnt, nFlags);
  1201. // update the window text string.
  1202. GetWindowText( m_strWindowText );
  1203. }
  1204. afx_msg void OnLButtonDown(UINT nFlags, CPoint point)
  1205. {
  1206. TBase::OnLButtonDown(nFlags, point);
  1207. if (!CanUseMask())
  1208. {
  1209. return;
  1210. }
  1211. GetSel( m_nStartChar, m_nEndChar );
  1212. CorrectPosition( m_nStartChar, true, false );
  1213. if ( ::GetKeyState( VK_SHIFT ) < 0 )
  1214. m_nEndChar = m_nStartChar;
  1215. SetSel( m_nStartChar, m_nEndChar );
  1216. }
  1217. afx_msg void OnSetFocus(CWnd* pOldWnd)
  1218. {
  1219. TBase::OnSetFocus(pOldWnd);
  1220. if (!CanUseMask())
  1221. {
  1222. return;
  1223. }
  1224. GetSel( m_nStartChar, m_nEndChar );
  1225. CorrectPosition( m_nStartChar, true, false );
  1226. m_nEndChar = m_nStartChar;
  1227. SetSel( m_nStartChar, m_nEndChar );
  1228. }
  1229. afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point)
  1230. {
  1231. TBase::OnLButtonDblClk(nFlags, point);
  1232. if (!CanUseMask())
  1233. {
  1234. return;
  1235. }
  1236. GetSel( m_nStartChar, m_nEndChar );
  1237. CorrectPosition( m_nStartChar, true, false );
  1238. CorrectPosition( m_nEndChar, true, false );
  1239. SetSel( m_nStartChar, m_nEndChar );
  1240. }
  1241. afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI)
  1242. {
  1243. if (!CanUseMask())
  1244. {
  1245. pCmdUI->Enable( CanUndo( ) );
  1246. }
  1247. else
  1248. {
  1249. pCmdUI->Enable( m_bModified );
  1250. }
  1251. }
  1252. //}}AFX_CODEJOCK_PRIVATE
  1253. //-----------------------------------------------------------------------
  1254. // Summary:
  1255. // The framework calls this member function when the user selects an item from a menu
  1256. // Parameters:
  1257. // wParam - The low-order word of wParam identifies the command ID of the menu item, control, or accelerator. The high-order word of wParam specifies the notification message if the message is from a control. If the message is from an accelerator, the high-order word is 1. If the message is from a menu, the high-order word is 0
  1258. // lParam - Identifies the control that sends the message if the message is from a control. Otherwise, lParam is 0.
  1259. // Returns:
  1260. // An application returns nonzero if it processes this message; otherwise 0.
  1261. //-----------------------------------------------------------------------
  1262. virtual BOOL OnCommand( WPARAM wParam , LPARAM lParam )
  1263. {
  1264. switch ( LOWORD( wParam ) )
  1265. {
  1266. case ID_EDIT_CUT:
  1267. if ( !CanUseMask() )
  1268. CEdit::Cut();
  1269. else
  1270. MaskCut();
  1271. return TRUE;
  1272. case ID_EDIT_COPY:
  1273. if ( !CanUseMask() )
  1274. CEdit::Copy();
  1275. else
  1276. MaskCopy();
  1277. return TRUE;
  1278. case ID_EDIT_PASTE:
  1279. if ( !CanUseMask() )
  1280. CEdit::Paste();
  1281. else
  1282. MaskPaste();
  1283. return TRUE;
  1284. case ID_EDIT_CLEAR:
  1285. if ( !CanUseMask() )
  1286. CEdit::Clear();
  1287. else
  1288. MaskClear();
  1289. return TRUE;
  1290. case ID_EDIT_UNDO:
  1291. if ( !CanUseMask() )
  1292. CEdit::Undo();
  1293. else
  1294. MaskUndo();
  1295. return TRUE;
  1296. case ID_EDIT_SELECT_ALL:
  1297. MaskSelectAll();
  1298. return TRUE;
  1299. }
  1300. return TBase::OnCommand( wParam,lParam );
  1301. }
  1302. protected:
  1303. int m_nStartChar; // Current position of the first character in the current selection.
  1304. int m_nEndChar; // Current position of the first non-selected character past the end of the current selection.
  1305. bool m_bUseMask; // true to use the edit mask.
  1306. bool m_bOverType; // true to over type the text, set with VK_INSERT key press.
  1307. bool m_bRedo; // true to redo, or false to undo.
  1308. bool m_bModified; // true if mask edit has been modified.
  1309. TCHAR m_chPrompt; // Prompt character used to identify the text entry.
  1310. CString m_strMask; // Buffer that holds the actual edit mask value.
  1311. CString m_strDefault; // Contains the edit controls default display text.
  1312. CString m_strUndoBuffer; // Holds the contents of the undo buffer.
  1313. CString m_strRedoBuffer; // Holds the contents of the redo buffer.
  1314. CString m_strWindowText; // Buffer that holds the actual edit text.
  1315. CString m_strLiteral; // Literal format that restricts where the user can enter text.
  1316. };
  1317. //{{AFX_CODEJOCK_PRIVATE
  1318. #define ON_MASKEDIT_REFLECT\
  1319. ON_MESSAGE_VOID(WM_CUT, MaskCut)\
  1320. ON_MESSAGE_VOID(WM_PASTE, MaskPaste)\
  1321. ON_MESSAGE_VOID(WM_CLEAR, MaskClear)\
  1322. ON_MESSAGE_VOID(WM_UNDO, MaskUndo)\
  1323. ON_MESSAGE_VOID(WM_COPY, MaskCopy)\
  1324. ON_WM_KEYDOWN()\
  1325. ON_WM_CHAR()\
  1326. ON_WM_LBUTTONDOWN()\
  1327. ON_WM_SETFOCUS()\
  1328. ON_WM_LBUTTONDBLCLK
  1329. //}}AFX_CODEJOCK_PRIVATE
  1330. //////////////////////////////////////////////////////////////////////
  1331. #endif // #if !defined(__XTMASKEDITEX_H__)