Rev 1 | Blame | Compare with Previous | Last modification | View Log | Download
// MaskEd.cpp : implementation file//// Orginially written by : DunnoWho// Modified by : Jeremy Davis, 24/07/1998// Added CTimeEdit::SetMins and CTimeEdit::SetHours#include "stdafx.h"//#include "TestEdit.h"#include "MaskEd.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// COleDateTime read /writeCOleDateTime ReadCOleDateTime(LPCSTR lpszData){COleDateTime DateTime;DateTime.ParseDateTime(lpszData);return DateTime;}void FormatCOleDateTime(CString& strData, COleDateTime DateTime, int len){strData = "";if (DateTime.m_dt == 0) return;if (len == 8)strData = DateTime.Format("%d/%m/%y");else if(len == 5) // added these twostrData = DateTime.Format("%H:%M");elsestrData = DateTime.Format("%d/%m/%Y");}/////////////////////////////////////////////////////////////////////////////// DDX for mask controlvoid AFXAPI DDX_OleDate(CDataExchange* pDX, int nIDC, CDateEdit& rControl, COleDateTime& Date){DDX_Control(pDX, nIDC, (CWnd&)rControl);if (!pDX->m_bSaveAndValidate)rControl.SetDate(Date);elseDate = rControl.GetDate();}/////////////////////////////////////////////////////////////////////////////// CMaskEdit classIMPLEMENT_DYNAMIC(CMaskEdit, CEdit)BEGIN_MESSAGE_MAP(CMaskEdit, CEdit)//{{AFX_MSG_MAP(CMaskEdit)ON_WM_CHAR()ON_WM_KEYDOWN()//}}AFX_MSG_MAPEND_MESSAGE_MAP()CMaskEdit::CMaskEdit(){m_bUseMask = FALSE;m_strMask = _T("");m_strLiteral = _T("");m_strValid = _T("");m_strHours = _T("47");m_strMins = _T("59");m_bMaskKeyInProgress = FALSE;m_strMaskLiteral = _T("");}void CMaskEdit::SetMask(LPCSTR lpMask, LPCSTR lpLiteral, LPCSTR lpValid){m_bUseMask = FALSE;if (lpMask == NULL) return;m_strMask = lpMask;if (m_strMask.IsEmpty()) return;if (lpLiteral != NULL){m_strLiteral = lpLiteral;if (m_strLiteral.GetLength() != m_strMask.GetLength())m_strLiteral.Empty();}elsem_strLiteral.Empty();if (lpValid != NULL)m_strValid = lpValid;elsem_strValid.Empty();m_bUseMask = TRUE;}void CMaskEdit::SendChar(UINT nChar){m_bMaskKeyInProgress = TRUE;#ifdef WIN32AfxCallWndProc(this, m_hWnd, WM_CHAR, nChar, 1);#elseSendMessage(WM_CHAR, nChar, 1);#endifm_bMaskKeyInProgress = FALSE;}void CMaskEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags){if (!m_bMaskKeyInProgress)if (!CheckChar(nChar)) return;if (m_bUseMask){if (isprint(nChar)){// si un masque existe, on est en insert modeint startPos, endPos;GetSel(startPos, endPos);SetSel(startPos, endPos+1);Clear();m_str.SetAt(endPos, nChar); // added this}else if (nChar == VK_BACK){int startPos, endPos;GetSel(startPos, endPos);// sanity range checkif ((startPos == endPos) && (startPos >= 1) && (startPos <= m_str.GetLength())){char c;// get the masked literal representationif (!m_strMaskLiteral.IsEmpty())c = m_strMaskLiteral[startPos-1];TRACE("m_strMaskLiteral = [%s](%s)\n", m_strMaskLiteral, m_str);// back space the cursorSendMessage(WM_KEYDOWN, VK_LEFT, 0);if (!m_strMaskLiteral.IsEmpty()){// update the char backspacing overSendChar(c);// back space the cursor againSendMessage(WM_KEYDOWN, VK_LEFT, 0);}}else // out of range or have more than one char selectedMessageBeep((UINT)-1);return;}}CEdit::OnChar(nChar, nRepCnt, nFlags);if (!m_bMaskKeyInProgress && m_bUseMask && !m_strLiteral.IsEmpty()){int startPos, endPos;GetSel(startPos, endPos);// make sure the string is not longer than the maskif (endPos < m_strLiteral.GetLength()){UINT c = m_strLiteral.GetAt(endPos);if (c != '_') SendChar(c);}}}BOOL CMaskEdit::CheckChar(UINT nChar){UINT c;// do not use maskif (!m_bUseMask) return TRUE;// control character, OKif (!isprint(nChar)) return TRUE;// unselect all selections, if anyint startPos, endPos;GetSel(startPos, endPos);SetSel(-1, 0);SetSel(startPos, startPos);// check the key against the maskGetSel(startPos, endPos);// make sure the string is not longer than the maskif (endPos >= m_strMask.GetLength()){MessageBeep((UINT)-1);return FALSE;}// check to see if a literal is in this positionc = '_';if (!m_strLiteral.IsEmpty())c = m_strLiteral.GetAt(endPos);if (c != '_'){SendChar(c);GetSel(startPos, endPos);}// check the valid string characterif (m_strValid.Find(nChar) != -1) return TRUE;// check the key against the maskc = m_strMask.GetAt(endPos);BOOL doit = TRUE;switch (c){case '0': // digit only //completely changed this{BOOL doit = TRUE;if(isdigit(nChar)){if(m_isdate){if(endPos == 0){if(nChar > '3')doit = FALSE;}if(endPos == 1){if(m_str.GetAt(0) == '3'){if(nChar > '1')doit = FALSE;}}if(endPos == 3){if(nChar > '1')doit = FALSE;}if(endPos == 4){if(m_str.GetAt(3) == '1'){if(nChar > '2')doit = FALSE;}}}else{if(endPos == 0){if(nChar > (UINT)m_strHours[0])doit = FALSE;}if(endPos == 1){if(m_str.GetAt(0) == m_strHours[0]){if(nChar > (UINT)m_strHours[1])doit = FALSE;}}if(endPos == 3){if(nChar > (UINT)m_strMins[0])doit = FALSE;}if(endPos == 4){if(m_str.GetAt(3) == m_strMins[0]){if(nChar > (UINT)m_strMins[1])doit = FALSE;}}}return doit;}break;}case '9': // digit or space{if (isdigit(nChar)) return TRUE;if (nChar != VK_SPACE) return TRUE;break;}case '#': // digit or space or '+' or '-'{if (isdigit(nChar)) return TRUE;if (nChar == VK_SPACE || nChar == VK_ADD || nChar == VK_SUBTRACT) return TRUE;break;}case 'L': // alpha only{if (isalpha(nChar)) return TRUE;break;}case '?': // alpha or space{if (isalpha(nChar)) return TRUE;if (nChar == VK_SPACE) return TRUE;break;}case 'A': // alpha numeric only{if (isalnum(nChar)) return TRUE;break;}case 'a': // alpha numeric or space{if (isalnum(nChar)) return TRUE;if (nChar == VK_SPACE) return TRUE;break;}case '&': // all print character only{if (isprint(nChar)) return TRUE;break;}}MessageBeep((UINT)-1);return FALSE;}void CMaskEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){// si un masque existe, tester les touches spécialesif (m_bUseMask){switch (nChar){case VK_DELETE:case VK_INSERT: return;}}CEdit::OnKeyDown(nChar, nRepCnt, nFlags);}/////////////////////////////////////////////////////////////////////////////// CDateEdit classIMPLEMENT_DYNAMIC(CDateEdit, CMaskEdit)BEGIN_MESSAGE_MAP(CDateEdit, CMaskEdit)//{{AFX_MSG_MAP(CDateEdit)//}}AFX_MSG_MAPEND_MESSAGE_MAP()CDateEdit::CDateEdit(){m_bUseMask = TRUE;m_isdate = TRUE; //added thism_strMask = _T("00/00/0000");m_strLiteral = _T("__/__/____");}void CDateEdit::SetDate(COleDateTime& Date){CString strText;FormatCOleDateTime(strText, Date, 10);m_str = m_strMaskLiteral = strText;SetWindowText(strText);}COleDateTime CDateEdit::GetDate(){CString strText;GetWindowText(strText);return ReadCOleDateTime(strText);}/////////////////////////////////////////////////////////////////////////////// CTimeEdit class completely newIMPLEMENT_DYNAMIC(CTimeEdit, CMaskEdit)BEGIN_MESSAGE_MAP(CTimeEdit, CMaskEdit)//{{AFX_MSG_MAP(CTimeEdit)//}}AFX_MSG_MAPEND_MESSAGE_MAP()CTimeEdit::CTimeEdit(){m_bUseMask = TRUE;m_isdate = FALSE;m_strMask = _T("00:00");m_strLiteral = _T("__:__");}void CTimeEdit::SetTime(COleDateTime& Date){CString strText;FormatCOleDateTime(strText, Date, 5);m_str = m_strMaskLiteral = strText;SetWindowText(strText);}void CTimeEdit::SetTime(CString Date){m_str = m_strMaskLiteral = Date;SetWindowText(Date);}COleDateTime CTimeEdit::GetTime(){CString strText;GetWindowText(strText);return ReadCOleDateTime(strText);}CString CTimeEdit::GetTimeStr(){CString strText;GetWindowText(strText);return strText;}void CTimeEdit::SetHours(int hrs){m_strHours.Format("%d", hrs);}void CTimeEdit::SetMins(int hrs){m_strMins.Format("%d", hrs);}