Masked.cpp
上传用户:xujuna1
上传日期:2007-01-02
资源大小:37k
文件大小:9k
源码类别:

编辑框

开发平台:

Visual C++

  1. // MaskEd.cpp : implementation file
  2. //
  3. // Orginially written by : DunnoWho
  4. // Modified by : Jeremy Davis, 24/07/1998
  5. //     Added CTimeEdit::SetMins and CTimeEdit::SetHours
  6. #include "stdafx.h"
  7. #include "TestEdit.h"
  8. #include "MaskEd.h"
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. /////////////////////////////////////////////////////////////////////////////
  15. // COleDateTime read /write
  16. COleDateTime ReadCOleDateTime(LPCSTR lpszData)
  17. {
  18.   COleDateTime DateTime;
  19.   DateTime.ParseDateTime(lpszData);
  20.   return DateTime;
  21. }
  22. void FormatCOleDateTime(CString& strData, COleDateTime DateTime, int len)
  23. {
  24.   strData = "";
  25.   if (DateTime.m_dt == 0) return;
  26.   if (len == 8)
  27.     strData = DateTime.Format("%d/%m/%y");
  28.   else if(len == 5) // added these two
  29. strData = DateTime.Format("%H:%M");
  30.   else
  31.     strData = DateTime.Format("%d/%m/%Y");
  32. }
  33. /////////////////////////////////////////////////////////////////////////////
  34. // DDX for mask control
  35. void AFXAPI DDX_OleDate(CDataExchange* pDX, int nIDC, CDateEdit& rControl, COleDateTime& Date)
  36. {
  37.   DDX_Control(pDX, nIDC, (CWnd&)rControl);
  38.   if (!pDX->m_bSaveAndValidate)
  39.     rControl.SetDate(Date);
  40.   else
  41.     Date = rControl.GetDate();
  42. }
  43.   
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CMaskEdit class
  46. IMPLEMENT_DYNAMIC(CMaskEdit, CEdit)
  47. BEGIN_MESSAGE_MAP(CMaskEdit, CEdit)
  48.   //{{AFX_MSG_MAP(CMaskEdit)
  49.   ON_WM_CHAR()
  50.   ON_WM_KEYDOWN()
  51.   //}}AFX_MSG_MAP
  52. END_MESSAGE_MAP()
  53. CMaskEdit::CMaskEdit()
  54. {
  55.   m_bUseMask = FALSE;
  56.   m_strMask = _T("");
  57.   m_strLiteral = _T("");
  58.   m_strValid = _T("");
  59.   m_strHours = _T("47");
  60.   m_strMins = _T("59");
  61.   m_bMaskKeyInProgress = FALSE;
  62.   m_strMaskLiteral = _T("");
  63. }
  64. void CMaskEdit::SetMask(LPCSTR lpMask, LPCSTR lpLiteral, LPCSTR lpValid)
  65. {
  66.   m_bUseMask = FALSE;
  67.   if (lpMask == NULL) return;
  68.   m_strMask = lpMask;
  69.   if (m_strMask.IsEmpty()) return;
  70.   if (lpLiteral != NULL)
  71.   {
  72.     m_strLiteral = lpLiteral;
  73.     if (m_strLiteral.GetLength() != m_strMask.GetLength())
  74.       m_strLiteral.Empty();
  75.   }
  76.   else
  77.     m_strLiteral.Empty();
  78.   if (lpValid != NULL)
  79.     m_strValid = lpValid;
  80.   else
  81.     m_strValid.Empty();
  82.   m_bUseMask = TRUE;
  83. }
  84. void CMaskEdit::SendChar(UINT nChar)
  85. {
  86.   m_bMaskKeyInProgress = TRUE;
  87.   #ifdef WIN32
  88.     AfxCallWndProc(this, m_hWnd, WM_CHAR, nChar, 1);
  89.   #else
  90.     SendMessage(WM_CHAR, nChar, 1);
  91.   #endif
  92.   m_bMaskKeyInProgress = FALSE;
  93. }
  94. void CMaskEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
  95. {
  96. if (!m_bMaskKeyInProgress)
  97. if (!CheckChar(nChar)) return;
  98. if (m_bUseMask)
  99. {
  100. if (isprint(nChar))
  101. {
  102. // si un masque existe, on est en insert mode
  103. int startPos, endPos;
  104. GetSel(startPos, endPos);
  105. SetSel(startPos, endPos+1);
  106. Clear();
  107. m_str.SetAt(endPos, nChar); // added this
  108. }
  109. else if (nChar == VK_BACK)
  110. {
  111. int startPos, endPos;
  112. GetSel(startPos, endPos);
  113. // sanity range check
  114. if ((startPos == endPos) && (startPos >= 1) && (startPos <= m_str.GetLength()))
  115. {
  116. char c;
  117.         // get the masked literal representation
  118.     if (!m_strMaskLiteral.IsEmpty())
  119. c = m_strMaskLiteral[startPos-1];
  120. TRACE("m_strMaskLiteral = [%s](%s)n", m_strMaskLiteral, m_str);
  121. // back space the cursor
  122. SendMessage(WM_KEYDOWN, VK_LEFT, 0);
  123. if (!m_strMaskLiteral.IsEmpty())
  124. {
  125. // update the char backspacing over
  126. SendChar(c);
  127. // back space the cursor again
  128. SendMessage(WM_KEYDOWN, VK_LEFT, 0);
  129. }
  130. }
  131. else // out of range or have more than one char selected
  132. MessageBeep((UINT)-1);
  133. return;
  134. }
  135. }
  136. CEdit::OnChar(nChar, nRepCnt, nFlags);
  137. if (!m_bMaskKeyInProgress && m_bUseMask && !m_strLiteral.IsEmpty())
  138. {
  139. int startPos, endPos;
  140. GetSel(startPos, endPos);
  141. // make sure the string is not longer than the mask
  142. if (endPos < m_strLiteral.GetLength())
  143. {
  144. UINT c = m_strLiteral.GetAt(endPos);
  145. if (c != '_') SendChar(c);
  146. }
  147. }
  148. }
  149. BOOL CMaskEdit::CheckChar(UINT nChar)
  150. {
  151.   UINT c;
  152.   // do not use mask
  153.   if (!m_bUseMask) return TRUE;
  154.   // control character, OK
  155.   if (!isprint(nChar)) return TRUE;
  156.   // unselect all selections, if any
  157.   int startPos, endPos;
  158.   GetSel(startPos, endPos);
  159.   SetSel(-1, 0);
  160.   SetSel(startPos, startPos);
  161.   // check the key against the mask
  162.   GetSel(startPos, endPos);
  163.   // make sure the string is not longer than the mask
  164.   if (endPos >= m_strMask.GetLength())
  165.   {
  166.     MessageBeep((UINT)-1);
  167.     return FALSE;
  168.   }
  169.   // check to see if a literal is in this position
  170.   c = '_';
  171.   if (!m_strLiteral.IsEmpty())
  172.     c = m_strLiteral.GetAt(endPos);
  173.   if (c != '_')
  174.   {
  175.     SendChar(c);
  176.     GetSel(startPos, endPos);
  177.   }
  178.   // check the valid string character
  179.   if (m_strValid.Find(nChar) != -1) return TRUE;
  180.   // check the key against the mask
  181.   c = m_strMask.GetAt(endPos);
  182.   BOOL doit = TRUE;
  183.   switch (c)
  184.   {
  185.     case '0': // digit only //completely changed this
  186.     {
  187. BOOL doit = TRUE;
  188. if(isdigit(nChar))
  189. {
  190. if(m_isdate)
  191. {
  192. if(endPos == 0)
  193. {
  194. if(nChar > '3')
  195. doit = FALSE;
  196. }
  197. if(endPos == 1)
  198. {
  199. if(m_str.GetAt(0) == '3')
  200. {
  201. if(nChar > '1')
  202. doit = FALSE;
  203. }
  204. }
  205. if(endPos == 3)
  206. {
  207. if(nChar > '1')
  208. doit = FALSE;
  209. }
  210. if(endPos == 4)
  211. {
  212. if(m_str.GetAt(3) == '1')
  213. {
  214. if(nChar > '2')
  215. doit = FALSE;
  216. }
  217. }
  218. }
  219. else
  220. {
  221. if(endPos == 0)
  222. {
  223. if(nChar > (UINT)m_strHours[0])
  224. doit = FALSE;
  225. }
  226. if(endPos == 1)
  227. {
  228. if(m_str.GetAt(0) == m_strHours[0])
  229. {
  230. if(nChar > (UINT)m_strHours[1])
  231. doit = FALSE;
  232. }
  233. }
  234. if(endPos == 3)
  235. {
  236. if(nChar > (UINT)m_strMins[0])
  237. doit = FALSE;
  238. }
  239. if(endPos == 4)
  240. {
  241. if(m_str.GetAt(3) == m_strMins[0])
  242. {
  243. if(nChar > (UINT)m_strMins[1])
  244. doit = FALSE;
  245. }
  246. }
  247. }
  248.         return doit;
  249. }
  250.       break;
  251.     }
  252.     case '9': // digit or space
  253.     {
  254.       if (isdigit(nChar)) return TRUE;
  255.       if (nChar != VK_SPACE) return TRUE;
  256.       break;
  257.     }
  258.     case '#': // digit or space or '+' or '-'
  259.     {
  260.       if (isdigit(nChar)) return TRUE;
  261.       if (nChar == VK_SPACE || nChar == VK_ADD || nChar == VK_SUBTRACT) return TRUE;
  262.       break;
  263.     }
  264.     case 'L': // alpha only
  265.     {
  266.       if (isalpha(nChar)) return TRUE;
  267.       break;
  268.     }
  269.     case '?': // alpha or space
  270.     {
  271.       if (isalpha(nChar)) return TRUE;
  272.       if (nChar == VK_SPACE) return TRUE;
  273.       break;
  274.     }
  275.     case 'A': // alpha numeric only
  276.     {
  277.       if (isalnum(nChar)) return TRUE;
  278.       break;
  279.     }
  280.     case 'a': // alpha numeric or space
  281.     {
  282.       if (isalnum(nChar)) return TRUE;
  283.       if (nChar == VK_SPACE) return TRUE;
  284.       break;
  285.     }
  286.     case '&': // all print character only
  287.     {
  288.       if (isprint(nChar)) return TRUE;
  289.       break;
  290.     }
  291.   }
  292.   MessageBeep((UINT)-1);
  293.   return FALSE;
  294. }
  295. void CMaskEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  296. {
  297.   // si un masque existe, tester les touches sp閏iales
  298.   if (m_bUseMask)
  299.   {
  300.     switch (nChar)
  301.     {
  302.       case VK_DELETE:
  303.       case VK_INSERT: return;
  304.     }
  305.   }
  306.   CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
  307. }
  308. /////////////////////////////////////////////////////////////////////////////
  309. // CDateEdit class
  310. IMPLEMENT_DYNAMIC(CDateEdit, CMaskEdit)
  311. BEGIN_MESSAGE_MAP(CDateEdit, CMaskEdit)
  312.   //{{AFX_MSG_MAP(CDateEdit)
  313.   //}}AFX_MSG_MAP
  314. END_MESSAGE_MAP()
  315. CDateEdit::CDateEdit()
  316. {
  317.   m_bUseMask = TRUE;
  318.   m_isdate = TRUE; //added this
  319.   m_strMask = _T("00/00/0000");
  320.   m_strLiteral = _T("__/__/____");
  321. }
  322. void CDateEdit::SetDate(COleDateTime& Date)
  323. {
  324.   CString strText;
  325.   FormatCOleDateTime(strText, Date, 10);
  326.   m_str = m_strMaskLiteral = strText;
  327.   SetWindowText(strText);
  328. }
  329. COleDateTime CDateEdit::GetDate()
  330. {
  331.   CString strText;
  332.   GetWindowText(strText);
  333.   return ReadCOleDateTime(strText);
  334. }
  335. /////////////////////////////////////////////////////////////////////////////
  336. // CTimeEdit class completely new
  337. IMPLEMENT_DYNAMIC(CTimeEdit, CMaskEdit)
  338. BEGIN_MESSAGE_MAP(CTimeEdit, CMaskEdit)
  339.   //{{AFX_MSG_MAP(CTimeEdit)
  340.   //}}AFX_MSG_MAP
  341. END_MESSAGE_MAP()
  342. CTimeEdit::CTimeEdit()
  343. {
  344.   m_bUseMask = TRUE;
  345.   m_isdate = FALSE; 
  346.   m_strMask = _T("00:00");
  347.   m_strLiteral = _T("__:__");
  348. }
  349. void CTimeEdit::SetTime(COleDateTime& Date)
  350. {
  351.   CString strText;
  352.   FormatCOleDateTime(strText, Date, 5);
  353.   m_str = m_strMaskLiteral = strText;
  354.   SetWindowText(strText);
  355. }
  356. void CTimeEdit::SetTime(CString Date)
  357. {
  358. m_str = m_strMaskLiteral = Date;
  359. SetWindowText(Date);
  360. }
  361. COleDateTime CTimeEdit::GetTime()
  362. {
  363.   CString strText;
  364.   GetWindowText(strText);
  365.   return ReadCOleDateTime(strText);
  366. }
  367. CString CTimeEdit::GetTimeStr()
  368. {
  369. CString strText;
  370. GetWindowText(strText);
  371. return strText;
  372. }
  373. void CTimeEdit::SetHours(int hrs)
  374. {
  375. m_strHours.Format("%d", hrs);
  376. }
  377. void CTimeEdit::SetMins(int hrs)
  378. {
  379. m_strMins.Format("%d", hrs);
  380. }