⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 medit.cpp

📁 一个很漂亮的数字时钟程序,你一定会喜欢的.
💻 CPP
字号:
// mEdit.cpp : implementation file
//

#include <afxwin.h>
#include "mEdit.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CmEdit

void AFXAPI DDX_CmEdit(CDataExchange* pDX, int nIDC, CmEdit& rControl, CString& data)
{
	DDX_Control(pDX, nIDC, (CWnd&)rControl);
	if (!pDX->m_bSaveAndValidate)
	{
		rControl.SetData(data);
	}
	else
	{
		data = rControl.GetData();
	}
}

IMPLEMENT_DYNCREATE(CmEdit, CEdit)

CmEdit::CmEdit()
      : m_bInit(FALSE)
	  , m_strPrompt("_")
	  , m_iNumChars(0)
	  , m_iCurrentChar(0)
	  , m_bShiftDown(FALSE)
{
	for (int i = 0; i < MAX_CHARS; i++)
		m_Char[i] = NULL;

	// SubclassWindow(pParent->m_hWnd);
	// pParent->SubclassWindow(this->m_hWnd);
}

CmEdit::~CmEdit()
{
	for (int i = 0; i < MAX_CHARS; i++)
	{
		if (m_Char[i] != NULL)
		{
			delete m_Char[i];
			m_Char[i] = NULL;
		}
	}
}

BEGIN_MESSAGE_MAP(CmEdit, CEdit)
	//{{AFX_MSG_MAP(CmEdit)
	ON_WM_CHAR()
	ON_WM_KEYDOWN()
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SETFOCUS()
	ON_WM_LBUTTONUP()
	ON_WM_KEYUP()
	ON_WM_LBUTTONDBLCLK()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CmEdit message handlers

int CmEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CEdit::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	return 0;
}

void CmEdit::OnDestroy() 
{
	CEdit::OnDestroy();
}

BOOL CmEdit::PreCreateWindow(CREATESTRUCT& cs) 
{
	cs.style |= WS_TABSTOP | WS_VISIBLE | WS_DISABLED | ES_AUTOHSCROLL;
	cs.dwExStyle |= WS_EX_OVERLAPPEDWINDOW;
    
	return CEdit::PreCreateWindow(cs);
}

void CmEdit::SetData(const CString& data)
{
	CString strWindowText;
	CString strData;
	int     iNextDataChar = 0;
	
	for (int i = 1; i <= m_iNumChars; i++)
	{
		if (m_Char[i - 1]->m_bStaticChar)
		{
			strWindowText += m_Char[i - 1]->m_strValids;
		}
		else
		{
			if (iNextDataChar < data.GetLength())
			{
				strData = data[iNextDataChar++];
				if (m_Char[i - 1]->m_strValids.Find(strData[0]) < 0)
					strData = m_strPrompt;
			}
			else
			{
				strData = m_strPrompt;
			}
		    
			strWindowText += strData[0];
		}
	}

	SetWindowText(strWindowText);
}

CString CmEdit::GetData()
{
	CString strWindowText;
	GetWindowText(strWindowText);
	CString strData;
	
	for (int i = 1; i <= m_iNumChars; i++)
	{
		if (!m_Char[i - 1]->m_bStaticChar)
		{
			if (strWindowText.GetLength() >= i)
			{
				if (strWindowText[i - 1] != m_strPrompt)
					strData += strWindowText[i - 1];
			}
			else
				strData += m_strPrompt;
	    }
	}
	
	return strData;
}

void CmEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	switch (nChar)
	{
		case VK_TAB:	// (((CWnd*)GetParent())->GetNextDlgTabItem(this, m_bShiftDown))->SetFocus();
						break;
    
		case VK_BACK:	if (m_iCurrentChar > 0)
						{
							int iNewNext = FindNextChar(m_iCurrentChar - 1, FALSE, FALSE);
							if (iNewNext >= 0)
							{
								SetSel(iNewNext, iNewNext + 1);
								ReplaceSel(m_strPrompt);
								m_iCurrentChar = iNewNext;
								SetSel(m_iCurrentChar, m_iCurrentChar);
							}
						} break;

		default:		int x, y, z;
						GetSel(x,y);
						
						if (x != y)
						{
							CString szReplaceText = "";
							for (z=x; z<y; z++)
							{
								if (m_Char[z]->m_bStaticChar)
								{
									szReplaceText += m_Char[z]->m_strValids;
								}
								else
								{
									szReplaceText += m_strPrompt;
								}
							}
							
							ReplaceSel(szReplaceText);
							m_iCurrentChar = FindNextChar(x, FALSE, TRUE);
							SetSel(m_iCurrentChar, m_iCurrentChar);
						}

						if (m_iCurrentChar < m_iNumChars)
						{
							if (m_Char[m_iCurrentChar]->m_strValids.Find((TCHAR)nChar) >= 0)
							{
								int iNewNext = FindNextChar(m_iCurrentChar + 1, FALSE, TRUE);
								SetSel(m_iCurrentChar, m_iCurrentChar + 1);
								ReplaceSel((CString)(char)nChar);
								if (iNewNext >= 0)
								{
									m_iCurrentChar = iNewNext;
								}
								else
								{
									m_iCurrentChar++;
								}
								SetSel(m_iCurrentChar, m_iCurrentChar);
							}
						} break;
	}

	// CEdit::OnChar(nChar, nRepCnt, nFlags);
}

void CmEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	switch (nChar)
	{
		case VK_SHIFT:	m_bShiftDown = FALSE;	break;
		default:		break;
	}
    
	CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
}

void CmEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	int iNext = 0;
	CWnd *pNextItem = NULL;
    
	switch (nChar)
	{
		case VK_TAB:	pNextItem = (((CWnd*)GetParent())->GetNextDlgTabItem(this, (m_bShiftDown) ? TRUE : FALSE));
						if (pNextItem->IsKindOf(RUNTIME_CLASS(CmEdit)))
							((CmEdit*)pNextItem)->m_bShiftDown = m_bShiftDown;
						
						(((CWnd*)GetParent())->GetNextDlgTabItem(this, (m_bShiftDown) ? TRUE : FALSE))->SetFocus();
						break;
        
		case VK_SHIFT:	m_bShiftDown = TRUE;	break;
        
		case VK_LEFT:	iNext = FindNextChar(m_iCurrentChar - 1, FALSE, FALSE);
						
						if (iNext >= 0)
						{
							m_iCurrentChar = iNext;
							SetSel(m_iCurrentChar, m_iCurrentChar);
						} break;
    
		case VK_RIGHT:	iNext = FindNextChar(m_iCurrentChar + 1, FALSE, TRUE);
						
						if (iNext >= 0)
							m_iCurrentChar = iNext;
						else
						{
							m_iCurrentChar = FindNextChar(m_iNumChars - 1, FALSE, FALSE) + 1;
						}
						
						SetSel(m_iCurrentChar, m_iCurrentChar);
						break;

		case VK_HOME:	if (m_bShiftDown)
						{
							SetSel(0, m_iCurrentChar);
						}
						else
						{
							m_iCurrentChar = FindNextChar(0, FALSE, TRUE);
							SetSel(m_iCurrentChar, m_iCurrentChar);
						}
						break;

		case VK_END:	if (m_bShiftDown)
						{
							int iLast = FindNextChar(m_iNumChars - 1, FALSE, FALSE) + 1;
							SetSel(m_iCurrentChar, iLast);
						}
						else
						{
							m_iCurrentChar = FindNextChar(m_iNumChars - 1, FALSE, FALSE) + 1;
							SetSel(m_iCurrentChar, m_iCurrentChar);
						}
						break;

		case VK_INSERT:	break;

		case VK_DELETE:	int x, y, z;
						
						GetSel(x,y);

						if (x != y)
						{
							CString szReplaceText = "";
							
							for (z = x; z < y; z++)
							{
								if (m_Char[z]->m_bStaticChar)
								{
									szReplaceText += m_Char[z]->m_strValids;
								}
								else
								{
									szReplaceText += m_strPrompt;
								}
							}
							
							ReplaceSel(szReplaceText);
							m_iCurrentChar = FindNextChar(x, FALSE, TRUE);
							SetSel(m_iCurrentChar, m_iCurrentChar);
						}
						else if (m_iCurrentChar <= FindNextChar(m_iNumChars - 1, FALSE, FALSE))
						{
							SetSel(m_iCurrentChar, m_iCurrentChar + 1);
							ReplaceSel(m_strPrompt);
							iNext = FindNextChar(m_iCurrentChar + 1, FALSE, TRUE);
							
							if (iNext >= 0)
								m_iCurrentChar = iNext;
							else
								m_iCurrentChar++;
							
							SetSel(m_iCurrentChar, m_iCurrentChar);
						} break;
		
		default:		break;
	}

	// CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}

BOOL CmEdit::Init(CString strMask, CString strInitialData)
{
	m_bInit = FALSE;
    
	if (!Parse(strMask))
	{
		SetWindowText("Init failed.");
		EnableWindow(FALSE);
		return FALSE;
	}

	if (!SetValidChars(strMask))
	{
		SetWindowText("SetValidChars failed.");
		EnableWindow(FALSE);
		return FALSE;                          
	}
    
	SetData(strInitialData);
	m_iCurrentChar = FindNextChar(0, FALSE, TRUE);
	this->SetFocus();
	SetSel(m_iCurrentChar, m_iCurrentChar);

	EnableWindow(TRUE);				// This line is important !
	m_bInit = TRUE;

	return TRUE;
}

int CmEdit::FindNextChar(int iStartPos, BOOL bStatic, BOOL bForward)
{
	int iIndex = 0;
	int iReturnVal = -1;
    
	if (bForward)
	{
		for (int iIndex = iStartPos; iIndex < m_iNumChars; iIndex++)
		{
			if (m_Char[iIndex]->m_bStaticChar == bStatic)
			{
				iReturnVal = iIndex;
				break;
			}
		}
	}
	else
	{
		for (int iIndex = iStartPos; iIndex >= 0; iIndex--)
		{
			if (m_Char[iIndex]->m_bStaticChar == bStatic)
			{
				iReturnVal = iIndex;
				break;
			}
		}
	}

	return iReturnVal;
}

BOOL CmEdit::SetValidChars(const CString& strMask)
{
	CString strChars;
	CString strRangeLow; 
	BOOL    bInside       = FALSE;
	BOOL    bInsideEscape = FALSE;
	BOOL    bInsideRange  = FALSE;
	int     iNextChar     = 0;
	int     i;
    
	/*
		Clear valid chars.
	*/
	for (i = 0; i < MAX_CHARS; i++)
	{
		if (m_Char[i] != NULL)
		{
			delete m_Char[i];
			m_Char[i] = NULL;
		}
	}

	/*
		Walk through mask string.
	*/
	for (i = 0; i < strMask.GetLength(); i++)
	{
		switch (strMask[i])
		{
			case '[':	bInside = TRUE;			// Done.
						break;

			case ']':	bInside = FALSE;
						m_Char[iNextChar++] = new CmEditChar(strChars, FALSE);
						strChars = "";
						break;

			case '-':	if (bInside)
						{
							if (bInsideEscape)
							{
								strChars += "-";
								bInsideEscape = FALSE;	// Done.
							}
							else
							{
								if (strChars.GetLength() == 0)
									return FALSE;
								
								bInsideRange = TRUE;
								strRangeLow = strChars.Right(1);
								strChars = strChars.Left(strChars.GetLength() - 1); //done
							}
						}
						else
						{
							m_Char[iNextChar++] = new CmEditChar("-", TRUE); //done
						}
						break;
			
			case '\\':  if (bInside)
						{
							if (!bInsideEscape)
							{
								bInsideEscape = TRUE;		// Done.
							}
							else
							{
								if (bInsideRange)
								{
									strChars += GetRange(strRangeLow, "\\");
									strRangeLow = "";
									bInsideRange = FALSE;	// Done.
								}
								else
								{
									strChars += "\\";
									bInsideEscape = FALSE;	// Done.
								}
							}
						}
						else
						{
							m_Char[iNextChar++] = new CmEditChar("\\", TRUE); //done
						}
						break;

			default:	if (bInside)
						{
							if (bInsideEscape)
							{
								bInsideEscape = FALSE;	// Done.
							}

							if (bInsideRange)
							{
								strChars += GetRange(strRangeLow, strMask[i]);
								strRangeLow = "";
								bInsideRange = FALSE;	// Done.
							}
							else
							{
								strChars += strMask[i];	// Done.
							}
						}
						else
						{
							m_Char[iNextChar++] = new CmEditChar(strMask[i], TRUE); //done
						}
						break;
		}
    }

	m_iNumChars = iNextChar;
	SetLimitText(m_iNumChars);
    
	return TRUE;
}

CString CmEdit::GetRange(CString szLow, CString szHigh)
{
	CString szReturn = "";

	if (szLow.GetLength() == 1 && szHigh.GetLength() == 1)
	{
		char first = szLow[0];
		char last  = szHigh[0];

		for (int i = first; i <= last; i++)
			szReturn += (CString)(char)i;
	}

	return szReturn;
}

BOOL CmEdit::Parse(const CString& strMask)
{
	BOOL bValid = TRUE;
	int iBracketState = 0;
	// int iDashState = 0;
    
	for (int i = 1; i <= strMask.GetLength(); i++)
	{
		switch (strMask[i - 1])
		{
			case '[':	iBracketState++; break;

			case ']':	iBracketState--; break;

			// case '-':	if (iBracketState > 0)
			//					iDashState = 1;
			//				break;

			default:	// if (iBracketState > 0) && iDashState == 1)
						//	iDashState = 0;
						break;
		}

		/*
			Make sure the [ ] are in sync.
		*/
		if (iBracketState < 0 || iBracketState > 1)
			bValid = FALSE;

		/*
			Make sure there is a character after a '-' inside the [ ]
			// if (iBracketState == 0 && iDashState == 1)
			//	bValid = FALSE;
		*/
	}

	return (iBracketState == 0 /*&& iDashState == 0*/ && bValid) ? TRUE : FALSE;
}

BOOL CmEdit::SetPromptChar(CString strPromptChar)
{
	if (strPromptChar.GetLength() != 1)
		return FALSE;

	m_strPrompt = strPromptChar;
	
	return TRUE;
}

void CmEdit::OnSetFocus(CWnd* pOldWnd) 
{
	CEdit::OnSetFocus(pOldWnd);
	
	// SetSel(m_iCurrentChar, m_iCurrentChar);
	SetSel(0, -1);
}

void CmEdit::OnLButtonUp(UINT nFlags, CPoint point) 
{
	int x, y;
	GetSel(x, y);

	if (x == y)
	{
		m_iCurrentChar = x;
		SetSel(m_iCurrentChar, m_iCurrentChar);
	}
	
	CEdit::OnLButtonUp(nFlags, point);
}

void CmEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	SetSel(0, -1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -