SourceCode/Bond/BoounionPLC/AxisSettingsDlg.cpp
@@ -8,6 +8,7 @@
#include "AxisDetailSettingsDlg.h"
#include "ToolUnits.h"
#include <cctype>
#include <regex>
#define COLOR_GREEN_ON    RGB(0, 255, 0)  // 正常状态绿色
@@ -53,10 +54,6 @@
      m_pBlBtns[i] = new CBlButton();
   }
   for (int i = 0; i < EDIT_MAX; i++) {
      m_pRegexEdit[i] = new CRegexEdit();
   }
   for (int i = 0; i < LABEL_MAX; i++) {
      m_pBlLabels[i] = new CBLLabel();
   }
@@ -73,10 +70,6 @@
{
   for (int i = 0; i < BTN_MAX; i++) {
      delete m_pBlBtns[i];
   }
   for (int i = 0; i < EDIT_MAX; i++) {
      delete m_pRegexEdit[i];
   }
   for (int i = 0; i < LABEL_MAX; i++) {
@@ -179,27 +172,10 @@
   SetLabelColorBasedOnState(*m_pBlLabels[LABEL_ERR], m_bErr, COLOR_RED, COLOR_GREEN_OFF);
}
void CAxisSettingsDlg::UpdateRegexEdit(CRegexEdit* pRegexEdit, const ValueRange& range, const CString& title)
{
   auto formatDouble = [](double value) -> CString {
      CString str;
      str.Format(_T("%.3f"), value);
      return str;
   };
   pRegexEdit->SetWindowText(formatDouble(range.currentValue));
   pRegexEdit->SetRegexType(RegexType::Decimal);
   pRegexEdit->SetValueRange(range.minValue, range.maxValue);
   pRegexEdit->SetInvalidInputCallback([title, range]() {
      CString strError;
      strError.Format(_T("%s的值必须在 %.3f 和 %.3f 之间!"), title, range.minValue, range.maxValue);
      AfxMessageBox(strError);
   });
}
void CAxisSettingsDlg::UpdatePageButtonStates()
{
   for (int i = 0; i < AXIS_PAGE_SIZE; ++i) {
      m_pBlBtns[i]->SetFrameColor(BTN_PAGE_FRAME_COLOR);
      BOOL bSelect = (i + 1 == m_currentPage);
      m_pBlBtns[i]->SetFaceColor(bSelect ?
         BTN_PAGE_FACE_SELECT_COLOR: BTN_PAGE_FACE_NORMAL_COLOR);
@@ -270,11 +246,11 @@
   m_staticAxisDescription.SetWindowText(CString(axisDetails.description.c_str()));   // 轴描述
   m_staticStartAddress.SetWindowText(CString(axisDetails.startAddress.c_str()));      // 起始地址
   UpdateRegexEdit(m_pRegexEdit[EDIT_MICROMENTUM], axisDetails.jogDistance, _T("微动量"));
   UpdateRegexEdit(m_pRegexEdit[EDIT_MANUAL_SPEED], axisDetails.manualSpeed, _T("手动速度"));
   UpdateRegexEdit(m_pRegexEdit[EDIT_AUTO_SPEED], axisDetails.autoSpeed, _T("自动速度"));
   UpdateRegexEdit(m_pRegexEdit[EDIT_ACCE_TIME], axisDetails.accelerationTime, _T("加速时间"));
   UpdateRegexEdit(m_pRegexEdit[EDIT_DECE_TIME], axisDetails.decelerationTime, _T("减速时间"));
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_MANUAL_SPEED)->SetWindowText(formatDouble(axisDetails.manualSpeed.currentValue));
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED)->SetWindowText(formatDouble(axisDetails.autoSpeed.currentValue));
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME)->SetWindowText(formatDouble(axisDetails.accelerationTime.currentValue));
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME)->SetWindowText(formatDouble(axisDetails.decelerationTime.currentValue));
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM)->SetWindowText(formatDouble(axisDetails.jogDistance.currentValue));
}
void CAxisSettingsDlg::RefreshPositionDetails(int nAxisId, int pageNumber)
@@ -308,13 +284,16 @@
         CString value;
         value.Format(_T("%.3f"), position.range.currentValue);
         if (pPositionCtrl) {
            pPositionCtrl->SetWindowText(value);
            pPositionCtrl->EnableWindow(position.isEnable);
            if (position.isEnable) {
               CString strError;
               strError.Format(_T("定位点%d"), i + 1);
               UpdateRegexEdit((CRegexEdit*)pPositionCtrl, position.range, strError);
               if (!IsFloatInRange((LPTSTR)(LPCTSTR)value, position.range.minValue, position.range.maxValue)) {
                  CString strError;
                  strError.Format(_T("定位点%d值必须在 %.3f 和 %.3f 之间!"), i + 1, position.range.minValue, position.range.maxValue);
                  ShowTipText(strError, 5);
               }
               else {
                  pPositionCtrl->SetWindowText(value);
               }
            }
         }
      }
@@ -363,8 +342,8 @@
   // 判断输入的值是否在合法范围内
   if (enteredValue < minValue || enteredValue > maxValue) {
      CString strError;
      strError.Format(_T("定位点的值必须在 %f 和 %f 之间!"), minValue, maxValue);
      pDescriptionCtrl->SetWindowText(strError);
      strError.Format(_T("定位点%d的值必须在 %f 和 %f 之间!"), currentIndex + 1, minValue, maxValue);
      ShowTipText(strError, 5);
   }
   else {
      position.range.currentValue = enteredValue;
@@ -402,19 +381,19 @@
   // 获取界面上的修改参数
   CString text;
   m_pRegexEdit[EDIT_MANUAL_SPEED]->GetWindowText(text);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_MANUAL_SPEED)->GetWindowText(text);
   axisData.manualSpeed.currentValue = _ttof(text);
   m_pRegexEdit[EDIT_AUTO_SPEED]->GetWindowText(text);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED)->GetWindowText(text);
   axisData.autoSpeed.currentValue = _ttof(text);
   m_pRegexEdit[EDIT_ACCE_TIME]->GetWindowText(text);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME)->GetWindowText(text);
   axisData.accelerationTime.currentValue = _ttof(text);
   m_pRegexEdit[EDIT_DECE_TIME]->GetWindowText(text);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME)->GetWindowText(text);
   axisData.decelerationTime.currentValue = _ttof(text);
   m_pRegexEdit[EDIT_MICROMENTUM]->GetWindowText(text);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM)->GetWindowText(text);
   axisData.jogDistance.currentValue = _ttof(text);
   // 更新定位点数据
@@ -773,11 +752,15 @@
   ON_BN_CLICKED(IDC_BUTTON_AXIS_UPDATE_UI, &CAxisSettingsDlg::OnBnClickedButtonAxisUpdateUi)
   ON_BN_CLICKED(IDC_BUTTON_AXIS_DETAIL_SETTINGS, &CAxisSettingsDlg::OnBnClickedButtonAxisDetailSettings)
   ON_MESSAGE(ID_MSG_UPDATA_DATA_TO_UI, &CAxisSettingsDlg::OnUpdateDataToUI)
   ON_EN_KILLFOCUS(IDC_EDIT_AXIS_MODITFY_MANUAL_SPEED, &CAxisSettingsDlg::OnKillfocusEditAxisModitfyManualSpeed)
   ON_EN_KILLFOCUS(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED, &CAxisSettingsDlg::OnKillfocusEditAxisModitfyAutoSpeed)
   ON_EN_KILLFOCUS(IDC_EDIT_AXIS_MODITFY_DECE_TIME, &CAxisSettingsDlg::OnKillfocusEditAxisModitfyDeceTime)
   ON_EN_KILLFOCUS(IDC_EDIT_AXIS_MODITFY_ACCE_TIME, &CAxisSettingsDlg::OnKillfocusEditAxisModitfyAcceTime)
   ON_EN_KILLFOCUS(IDC_EDIT_AXIS_MODITFY_MICROMENTUM, &CAxisSettingsDlg::OnEnKillfocusEditAxisModitfyMicromentum)
   ON_WM_SIZE()
   ON_WM_TIMER()
   ON_WM_CLOSE()
   ON_WM_CTLCOLOR()
   ON_EN_KILLFOCUS(IDC_EDIT_AXIS_MODITFY_MICROMENTUM, &CAxisSettingsDlg::OnEnKillfocusEditAxisModitfyMicromentum)
END_MESSAGE_MAP()
@@ -825,18 +808,6 @@
      AdjustLabelFont(*pLabel);
   }
   // 初始化编辑框
   m_pRegexEdit[EDIT_MANUAL_SPEED]->SubclassDlgItem(IDC_EDIT_AXIS_MODITFY_MANUAL_SPEED, this);
   m_pRegexEdit[EDIT_AUTO_SPEED]->SubclassDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED, this);
   m_pRegexEdit[EDIT_ACCE_TIME]->SubclassDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME, this);
   m_pRegexEdit[EDIT_DECE_TIME]->SubclassDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME, this);
   m_pRegexEdit[EDIT_MICROMENTUM]->SubclassDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM, this);
   m_pRegexEdit[EDIT_ANCHOR_POINT1]->SubclassDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT1, this);
   m_pRegexEdit[EDIT_ANCHOR_POINT2]->SubclassDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT2, this);
   m_pRegexEdit[EDIT_ANCHOR_POINT3]->SubclassDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT3, this);
   m_pRegexEdit[EDIT_ANCHOR_POINT4]->SubclassDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT4, this);
   m_pRegexEdit[EDIT_ANCHOR_POINT5]->SubclassDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT5, this);
   // 按钮初始化
   m_pBlBtns[BTN_PAGE1]->SubclassDlgItem(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP1, this);
@@ -1384,6 +1355,110 @@
   return 0;
}
void CAxisSettingsDlg::OnKillfocusEditAxisModitfyManualSpeed()
{
   // TODO: 在此添加控件通知处理程序代码
   int nAxisId = GetCurrentSelectedAxisID();
   if (nAxisId == -1) {
      AfxMessageBox(_T("请选择一个有效的轴编号!"));
      return;
   }
   auto axisDetails = m_pAxisManager->GetAxis(nAxisId);
   auto dMinValue = axisDetails.manualSpeed.minValue;
   auto dMaxValue = axisDetails.manualSpeed.maxValue;
   CString strText;
   GetDlgItemText(IDC_EDIT_AXIS_MODITFY_MANUAL_SPEED, strText);
   if (!IsFloatInRange((LPTSTR)(LPCTSTR)strText, dMinValue, dMaxValue)) {
      CString strError;
      strError.Format(_T("手动速度值必须在 %.3f 和 %.3f 之间!"), dMinValue, dMaxValue);
      ShowTipText(strError, 5);
   }
}
void CAxisSettingsDlg::OnKillfocusEditAxisModitfyAutoSpeed()
{
   // TODO: 在此添加控件通知处理程序代码
   int nAxisId = GetCurrentSelectedAxisID();
   if (nAxisId == -1) {
      AfxMessageBox(_T("请选择一个有效的轴编号!"));
      return;
   }
   auto axisDetails = m_pAxisManager->GetAxis(nAxisId);
   auto dMinValue = axisDetails.autoSpeed.minValue;
   auto dMaxValue = axisDetails.autoSpeed.maxValue;
   CString strText;
   GetDlgItemText(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED, strText);
   if (!IsFloatInRange((LPTSTR)(LPCTSTR)strText, dMinValue, dMaxValue)) {
      CString strError;
      strError.Format(_T("自动速度值必须在 %.3f 和 %.3f 之间!"), dMinValue, dMaxValue);
      ShowTipText(strError, 5);
   }
}
void CAxisSettingsDlg::OnKillfocusEditAxisModitfyAcceTime()
{
   // TODO: 在此添加控件通知处理程序代码
   int nAxisId = GetCurrentSelectedAxisID();
   if (nAxisId == -1) {
      AfxMessageBox(_T("请选择一个有效的轴编号!"));
      return;
   }
   auto axisDetails = m_pAxisManager->GetAxis(nAxisId);
   auto dMinValue = axisDetails.accelerationTime.minValue;
   auto dMaxValue = axisDetails.accelerationTime.maxValue;
   CString strText;
   GetDlgItemText(IDC_EDIT_AXIS_MODITFY_ACCE_TIME, strText);
   if (!IsFloatInRange((LPTSTR)(LPCTSTR)strText, dMinValue, dMaxValue)) {
      CString strError;
      strError.Format(_T("加速时间值必须在 %.3f 和 %.3f 之间!"), dMinValue, dMaxValue);
      ShowTipText(strError, 5);
   }
}
void CAxisSettingsDlg::OnKillfocusEditAxisModitfyDeceTime()
{
   // TODO: 在此添加控件通知处理程序代码
   int nAxisId = GetCurrentSelectedAxisID();
   if (nAxisId == -1) {
      AfxMessageBox(_T("请选择一个有效的轴编号!"));
      return;
   }
   auto axisDetails = m_pAxisManager->GetAxis(nAxisId);
   auto dMinValue = axisDetails.decelerationTime.minValue;
   auto dMaxValue = axisDetails.decelerationTime.maxValue;
   CString strText;
   GetDlgItemText(IDC_EDIT_AXIS_MODITFY_DECE_TIME, strText);
   if (!IsFloatInRange((LPTSTR)(LPCTSTR)strText, dMinValue, dMaxValue)) {
      CString strError;
      strError.Format(_T("减速时间值必须在 %.3f 和 %.3f 之间!"), dMinValue, dMaxValue);
      ShowTipText(strError, 5);
   }
}
void CAxisSettingsDlg::OnEnKillfocusEditAxisModitfyMicromentum()
{
   int nAxisId = GetCurrentSelectedAxisID();
   if (nAxisId == -1) {
      AfxMessageBox(_T("请选择一个有效的轴编号!"));
      return;
   }
   auto axisDetails = m_pAxisManager->GetAxis(nAxisId);
   auto dMinValue = axisDetails.jogDistance.minValue;
   auto dMaxValue = axisDetails.jogDistance.maxValue;
   CString strText;
   GetDlgItemText(IDC_EDIT_AXIS_MODITFY_MICROMENTUM, strText);
   if (!IsFloatInRange((LPTSTR)(LPCTSTR)strText, dMinValue, dMaxValue)) {
      CString strError;
      strError.Format(_T("微动量值必须在 %.3f 和 %.3f 之间!"), dMinValue, dMaxValue);
      ShowTipText(strError, 5);
   }
}
void CAxisSettingsDlg::OnTimer(UINT_PTR nIDEvent)
{
   if (TIMER_READ_PLC_DATA == nIDEvent) {
@@ -1454,12 +1529,19 @@
   GetDlgItem(IDC_LABEL_TIP)->ShowWindow(SW_HIDE);
}
void CAxisSettingsDlg::OnEnKillfocusEditAxisModitfyMicromentum()
bool CAxisSettingsDlg::IsFloatInRange(const std::string& strInput, double fLowerBound, double fUpperBound)
{
   CString strText;
   GetDlgItemText(IDC_EDIT_AXIS_MODITFY_MICROMENTUM, strText);
   double value = atof(strText);
   if (value < 0.0 || value > 0.1) {
      ShowTipText("微动量值必须在0.0 ~ 0.1之间", 5);
   // 是否为合法浮点数
   std::regex floatRegex(R"([-+]?\d*\.?\d+([eE][-+]?\d+)?)");
   if (!std::regex_match(strInput, floatRegex)) {
      return false;
   }
   try {
      double value = std::stod(strInput);
      return value >= fLowerBound && value <= fUpperBound;
   }
   catch (const std::exception&) {
      return false;
   }
}