📄 bcgpmaskedit.cpp
字号:
case VK_RIGHT:
{
// ----------------------
// Calc last group bounds
// ----------------------
int nGroupStart, nGroupEnd;
CEdit::GetSel(nGroupStart, nGroupEnd);
ASSERT(nGroupStart != -1);
GetGroupBounds(nGroupStart, nGroupEnd, nGroupEnd, TRUE);
if (nGroupStart == -1)
{
GetGroupBounds(nGroupStart, nGroupEnd, m_str.GetLength(), FALSE);
}
ASSERT(nGroupStart != -1);
if (::GetKeyState(VK_SHIFT)&0x80)
{
int nStart, nEnd;
CEdit::GetSel(nStart, nEnd);
if (m_bSelectByGroup)
{
int nNewEnd = min(nEnd+1, nGroupEnd);
// additional
nNewEnd = max(nNewEnd, nGroupStart);
CEdit::SetSel(nStart, nNewEnd);
}
else
{
CEdit::SetSel(nStart, nEnd+1);
}
return;
}
else if (::GetKeyState(VK_CONTROL)&0x80)
{
// move to the next group
int nStart, nEnd;
CEdit::GetSel(nStart, nEnd);
ASSERT(nStart != -1);
if (nEnd < m_str.GetLength()-1) // can search next group
{
GetGroupBounds(nGroupStart, nGroupEnd, nEnd+1, TRUE);
}
if ((nGroupStart != -1) && // if previous group was found
(nGroupStart != nStart || nGroupEnd != nEnd)) // and it's not the same
{
CEdit::SetSel(nGroupStart, nGroupEnd);
}
else // no more groups
{
MessageBeep((UINT)-1);
}
return;
}
else
{
int nStart, nEnd;
CEdit::GetSel(nStart, nEnd);
// move to the next group
if ((nStart==nEnd) && (nEnd==nGroupEnd))
{
if (nEnd < m_str.GetLength()-1) // can search next group
{
GetGroupBounds(nGroupStart, nGroupEnd, nStart+1, TRUE);
}
if ((nGroupStart != -1) && (nGroupStart > nEnd)) // if next group was found
{
CEdit::SetSel(nGroupStart, nGroupStart);
}
else // no more groups
{
MessageBeep((UINT)-1);
}
}
else
{
int nNewEnd = min(nEnd+1, nGroupEnd);
// additional
nNewEnd = max(nNewEnd, nGroupStart);
CEdit::SetSel(nNewEnd, nNewEnd);
}
return;
}
}
case VK_BACK:
{
// Special processing
OnCharBackspace(nChar, nRepCnt, nFlags);
return;
}
case VK_DELETE:
{
if (::GetKeyState(VK_SHIFT)&0x80)
{
break;
}
// Special processing
OnCharDelete(nChar, nRepCnt, nFlags);
return;
}
case VK_INSERT:
{
if ((::GetKeyState(VK_CONTROL)&0x80) || (::GetKeyState(VK_SHIFT)&0x80))
{
break;
}
if (!m_strMask.IsEmpty())
{
return;
}
break;
}
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CBCGPMaskEdit::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bSelectByGroup)
{
// -----------------
// Calc group bounds
// -----------------
int nGroupStart, nGroupEnd;
CEdit::GetSel(nGroupStart, nGroupEnd);
GetGroupBounds(nGroupStart, nGroupEnd, nGroupStart, TRUE);
if (nGroupStart == -1)
{
CEdit::GetSel(nGroupStart, nGroupEnd);
GetGroupBounds(nGroupStart, nGroupEnd, nGroupStart, FALSE);
}
// -----------------
// Correct selection
// -----------------
int nStart, nEnd;
CEdit::GetSel(nStart, nEnd);
int nNewStart = max(nStart, nGroupStart);
int nNewEnd = min(nEnd, nGroupEnd);
// additional
nNewStart = min(nNewStart, nGroupEnd);
nNewEnd = max(nNewEnd ,nGroupStart);
if ((nNewEnd != nEnd) || (nNewStart != nStart))
{
CEdit::SetSel(nNewStart, nNewEnd);
}
}
CEdit::OnLButtonUp(nFlags, point);
}
void CBCGPMaskEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
TCHAR chChar = (TCHAR) nChar;
if (_istprint(chChar) && !(::GetKeyState(VK_CONTROL)&0x80))
{
OnCharPrintchar(nChar, nRepCnt, nFlags);
return;
}
else if ((nChar == VK_DELETE || nChar == VK_BACK) && (!m_strMask.IsEmpty()))
{
return;
}
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
//////////////////////////////
// Char routines
BOOL CBCGPMaskEdit::CheckChar(TCHAR chChar, int nPos) // returns TRUE if the symbol is valid
{
ASSERT(m_strMask.IsEmpty() == m_strInputTemplate.IsEmpty());
ASSERT(m_strMask.GetLength() == m_strInputTemplate.GetLength());
ASSERT(_istprint(chChar) != FALSE);
ASSERT(nPos >= 0);
// --------------
// Don't use mask
// --------------
if (m_strMask.IsEmpty())
{
// Use valid string characters
if (!m_strValid.IsEmpty())
{
return (m_strValid.Find(chChar) != -1);
}
// Don't use valid string characters
else
{
return TRUE;
}
}
else
{
ASSERT(nPos < m_strMask.GetLength());
}
// --------
// Use mask
// --------
ASSERT(m_str.GetLength() == m_strMask.GetLength());
if (m_strInputTemplate[nPos] == _T('_'))
{
BOOL bIsMaskedChar = IsMaskedChar(chChar, m_strMask[nPos]);
// Use valid string characters
if (!m_strValid.IsEmpty())
{
return bIsMaskedChar && (m_strValid.Find(chChar) != -1);
}
// Don't use valid string characters
else
{
return bIsMaskedChar;
}
}
else
{
return FALSE;
}
}
void CBCGPMaskEdit::OnCharPrintchar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
ASSERT(m_strMask.IsEmpty() == m_strInputTemplate.IsEmpty());
ASSERT(m_strMask.GetLength() == m_strInputTemplate.GetLength());
TCHAR chChar = (TCHAR) nChar;
ASSERT(_istprint(chChar) != FALSE);
// -----------------------------------------------
// Processing ES_UPPERCASE and ES_LOWERCASE styles
// -----------------------------------------------
DWORD dwStyle = GetStyle ();
if (dwStyle & ES_UPPERCASE)
{
chChar = (TCHAR)_totupper(chChar);
}
else if (dwStyle & ES_LOWERCASE)
{
chChar = (TCHAR)_totlower(chChar);
}
int nStartPos, nEndPos;
CEdit::GetSel(nStartPos, nEndPos);
ASSERT(nStartPos>=0);
ASSERT(nEndPos>=0);
ASSERT(nEndPos>=nStartPos);
// -----------------
// Calc group bounds
// -----------------
int nGroupStart, nGroupEnd;
GetGroupBounds(nGroupStart, nGroupEnd, nStartPos);
// ------------
// Out of range
// ------------
if ((nStartPos<0) && (nEndPos > m_str.GetLength()) ||
(nStartPos < nGroupStart) || (nStartPos > nGroupEnd) ||
(nEndPos < nGroupStart) || (nEndPos > nGroupEnd))
{
MessageBeep((UINT)-1);
CEdit::SetSel(nGroupStart, nGroupEnd);
return;
}
// -----------------
// No selected chars
// -----------------
if (nStartPos == nEndPos)
{
// Use m_strMask
if (!m_strMask.IsEmpty())
{
// ----------------------------------------------
// Automaticaly move the cursor to the next group
// ----------------------------------------------
if (nEndPos==nGroupEnd || // at the end of group
nStartPos < nGroupStart || nStartPos > nGroupEnd) // not in the middle of a group
{
// no space for new char
if (nEndPos >= m_str.GetLength()-1)
{
MessageBeep((UINT)-1);
return;
}
// can search next group
else if (nEndPos < m_str.GetLength()-1)
{
GetGroupBounds(nGroupStart, nGroupEnd, nEndPos+1, TRUE);
}
// if next group was found
if ((nGroupStart != -1) && (nGroupStart > nEndPos))
{
CEdit::SetSel(nGroupStart, nGroupStart);
nStartPos = nGroupStart;
nEndPos = nGroupStart;
}
// no more groups
else
{
MessageBeep((UINT)-1);
return;
}
}
// ----------------------
// Check char in position
// ----------------------
if (!CheckChar(chChar, nStartPos))
{
MessageBeep((UINT)-1);
return;
}
// ---------------------------------
// Replace char in Editbox and m_str
// ---------------------------------
CEdit::SetSel(nStartPos, nEndPos+1);
CEdit::ReplaceSel(CString(chChar), TRUE);
m_str.SetAt(nEndPos, chChar);
CEdit::SetSel(nEndPos+1, nEndPos+1);
// ----------------------------------------------
// Automaticaly move the cursor to the next group
// ----------------------------------------------
CEdit::GetSel(nStartPos, nEndPos);
if (nEndPos==nGroupEnd) // at the end of group
{
// can search next group
if (nEndPos < m_str.GetLength()-1)
{
GetGroupBounds(nGroupStart, nGroupEnd, nEndPos+1, TRUE);
}
// if next group was found
if ((nGroupStart != -1) && (nGroupStart > nEndPos))
{
CEdit::SetSel(nGroupStart, nGroupStart);
nStartPos = nGroupStart;
nEndPos = nGroupStart;
}
}
}
// Don't use m_strMask
else
{
// ----------------------
// Check char in position
// ----------------------
if (!CheckChar(chChar, nStartPos))
{
MessageBeep((UINT)-1);
return;
}
// Don't use m_chMask
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
// -------------------------------
// Have one or more chars selected
// -------------------------------
else
{
// ----------------------
// Check char in position
// ----------------------
if (!CheckChar(chChar, nStartPos))
{
MessageBeep((UINT)-1);
return;
}
// ----------------------------------
// Replace chars in Editbox and m_str
// ----------------------------------
if (!m_strInputTemplate.IsEmpty()) // Use m_strInputTemplate
{
// ---------------------------------------------------
// Calc the number of literals with the same mask char
// ---------------------------------------------------
ASSERT(nStartPos >= 0);
ASSERT(nEndPos > 0);
ASSERT(nStartPos <= m_strInputTemplate.GetLength());
int nSameMaskCharsNum = 1;
int nIndex = nStartPos; // an index of the first selected char
TCHAR chMaskChar = m_strMask[nIndex];
BOOL bScanMore = TRUE;
while (bScanMore && (nIndex + nSameMaskCharsNum < nGroupEnd))
{
if (m_strMask[nIndex + nSameMaskCharsNum] == chMaskChar)
{
nSameMaskCharsNum++;
}
else
{
bScanMore = FALSE;
}
}
// Make sure the selection has the same mask char
if (nEndPos - nStartPos > nSameMaskCharsNum)
{
MessageBeep((UINT)-1);
CEdit::SetSel(nIndex, nIndex+nSameMaskCharsNum);
return;
}
// -------------------------------
// Form the shifted replace string
// -------------------------------
ASSERT(nIndex >= nGroupStart);
ASSERT(nIndex + nSameMaskCharsNum <= nGroupEnd);
CString strReplace = m_str.Mid(nIndex, nSameMaskCharsNum);
if (nSameMaskCharsNum > 0)
{
ASSERT(nStartPos <= m_strInputTemplate.GetLength());
ASSERT(nEndPos <= m_strInputTemplate.GetLength());
int nRange = nEndPos - nStartPos;
ASSERT(nRange>0);
strReplace = strReplace.Right(nSameMaskCharsNum - nRange + 1);
strReplace += CString(m_chMaskInputTemplate, nRange - 1);
ASSERT(strReplace.GetLength() > 0);
strReplace.SetAt(0, chChar);
}
// -------------------------------------------
// Replace the content with the shifted string
// -------------------------------------------
CEdit::SetSel(nIndex, nIndex+nSameMaskCharsNum);
CEdit::ReplaceSel(strReplace, TRUE);
CEdit::SetSel(nIndex, nIndex);
for(int i=0; i < strReplace.GetLength(); i++)
{
m_str.SetAt(nIndex+i, strReplace[i]);
}
CEdit::SetSel(nStartPos+1, nStartPos+1);
}
else
{
// Don't use m_chMaskInputTemplate
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
}
void CBCGPMaskEdit::OnCharBackspace(UINT nChar, UINT nRepCnt, UINT nFlags)
{
ASSERT(m_strMask.IsEmpty() == m_strInputTemplate.IsEmpty());
ASSERT(m_strMask.GetLength() == m_strInputTemplate.GetLength());
int nStartPos, nEndPos;
CEdit::GetSel(nStartPos, nEndPos);
ASSERT(nStartPos>=0);
ASSERT(nEndPos>=0);
ASSERT(nEndPos>=nStartPos);
// -----------------
// Calc group bounds
// -----------------
int nGroupStart, nGroupEnd;
GetGroupBounds(nGroupStart, nGroupEnd, nStartPos);
// ------------
// Out of range
// ------------
if ((nStartPos<0) && (nEndPos > m_str.GetLength()) ||
(nStartPos < nGroupStart) || (nStartPos > nGroupEnd) ||
(nEndPos < nGroupStart) || (nEndPos > nGroupEnd))
{
MessageBeep((UINT)-1);
CEdit::SetSel(nGroupStart, nGroupEnd);
return;
}
// -----------------
// No selected chars
// -----------------
if (nStartPos == nEndPos)
{
// Use m_strMask
if (!m_strMask.IsEmpty())
{
// --------------------------------------------------
// Automaticaly move the cursor to the previous group
// --------------------------------------------------
if (nEndPos==nGroupStart) // at the start of group
{
// can search previous group
if (nEndPos > 1)
{
GetGroupBounds(nGroupStart, nGroupEnd, nEndPos-1, FALSE);
}
// if previous group was found
if ((nGroupStart != -1) && (nGroupEnd < nEndPos))
{
CEdit::SetSel(nGroupEnd, nGroupEnd);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -