| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #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; |
| | | } |
| | | |
| | | bool CRegexEdit::FindMatch(const std::string& pattern, std::string& foundText) |
| | | { |
| | | CString currentText; |
| | | GetWindowText(currentText); |
| | | |
| | | std::string text(CT2A(currentText.GetString())); |
| | | std::regex regexPattern(pattern); |
| | | std::smatch match; |
| | | |
| | | if (std::regex_search(text, match, regexPattern)) { |
| | | foundText = match.str(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | void CRegexEdit::ReplaceMatch(const std::string& pattern, const std::string& replacement) |
| | | { |
| | | CString currentText; |
| | | GetWindowText(currentText); |
| | | |
| | | std::string text(CT2A(currentText.GetString())); |
| | | std::regex regexPattern(pattern); |
| | | std::string result = std::regex_replace(text, regexPattern, replacement); |
| | | |
| | | SetWindowText(CString(result.c_str())); |
| | | } |
| | | |
| | | 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(); |
| | | } |
| | | } |
| | | } |