#include "stdafx.h"
|
#include "RegexEdit.h"
|
#include <stdexcept>
|
|
IMPLEMENT_DYNAMIC(CRegexEdit, CEdit)
|
|
CRegexEdit::CRegexEdit()
|
{
|
m_enRegexType = RegexType::Alphanumeric;
|
m_dMinValue = LDBL_MIN;
|
m_dMaxValue = LDBL_MAX;
|
}
|
|
CRegexEdit::~CRegexEdit()
|
{
|
}
|
|
void CRegexEdit::SetRegexType(RegexType enType)
|
{
|
m_enRegexType = enType;
|
}
|
|
void CRegexEdit::SetCustomRegex(const std::string& strCustomRegex)
|
{
|
m_strCustomRegex = strCustomRegex;
|
}
|
|
void CRegexEdit::SetValueRange(long double dMinValue, long double dMaxValue)
|
{
|
m_dMinValue = dMinValue;
|
m_dMaxValue = dMaxValue;
|
}
|
|
void CRegexEdit::SetCustomComparator(std::function<bool(const std::string&)> comparator)
|
{
|
m_customComparator = comparator;
|
}
|
|
void CRegexEdit::SetInvalidInputCallback(std::function<void()> callback)
|
{
|
m_invalidInputCallback = callback;
|
}
|
|
std::regex CRegexEdit::GetCurrentRegex() const
|
{
|
switch (m_enRegexType)
|
{
|
case RegexType::Alphanumeric:
|
return std::regex("^[a-zA-Z0-9]*$"); // ×ÖĸºÍÊý×Ö
|
case RegexType::Letters:
|
return std::regex("^[a-zA-Z]*$"); // Ö»ÔÊÐí×Öĸ
|
case RegexType::Digits:
|
return std::regex("^\\d*$"); // Ö»ÔÊÐíÊý×Ö
|
case RegexType::Decimal:
|
return std::regex("^[-+]?\\d+(\\.\\d+)?$"); // ÔÊÐíСÊýºÍÕûÊý
|
case RegexType::Custom:
|
return std::regex(m_strCustomRegex); // ×Ô¶¨ÒåÕýÔò
|
default:
|
return std::regex(".*"); // ĬÈÏÔÊÐíÊäÈëÈκÎÄÚÈÝ
|
}
|
}
|
|
bool CRegexEdit::IsValueInRange(const std::string& strText)
|
{
|
try {
|
if (m_enRegexType == RegexType::Digits || m_enRegexType == RegexType::Decimal) {
|
if (strText.find('.') == std::string::npos) {
|
int nValue = std::stoi(strText);
|
return nValue >= static_cast<int>(m_dMinValue) && nValue <= static_cast<int>(m_dMaxValue);
|
}
|
else {
|
double dValue = std::stod(strText);
|
return dValue >= m_dMinValue && dValue <= m_dMaxValue;
|
}
|
}
|
}
|
catch (const std::invalid_argument&) {
|
return false;
|
}
|
|
return true;
|
}
|
|
BEGIN_MESSAGE_MAP(CRegexEdit, CEdit)
|
ON_WM_CHAR()
|
END_MESSAGE_MAP()
|
|
void CRegexEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
{
|
// ´¦Àíɾ³ý¼üºÍÍ˸ñ¼ü
|
if (nChar == VK_BACK || nChar == VK_DELETE) {
|
CEdit::OnChar(nChar, nRepCnt, nFlags);
|
return;
|
}
|
|
CString strCurrent;
|
GetWindowText(strCurrent);
|
|
// »ñÈ¡¹â±êµ±Ç°Î»ÖÃ
|
int nStartChar, nEndChar;
|
GetSel(nStartChar, nEndChar); // »ñÈ¡µ±Ç°Ñ¡ÇøµÄÆðʼºÍ½áÊøÎ»ÖÃ
|
|
std::string strText(CT2A(strCurrent.GetBuffer()));
|
strText.insert(strText.begin() + nStartChar, (char)nChar);
|
|
bool bValid = m_customComparator ? m_customComparator(strText) : IsValueInRange(strText);
|
if (std::regex_match(strText, GetCurrentRegex()) && bValid) {
|
CEdit::OnChar(nChar, nRepCnt, nFlags);
|
}
|
else {
|
if (m_invalidInputCallback) {
|
m_invalidInputCallback();
|
}
|
}
|
}
|