LAPTOP-T815PCOQ\25526
2024-12-11 43419b86d6a4a2d879454938fb7db7cc84d8c011
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#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();
        }
    }
}