LAPTOP-T815PCOQ\25526
2024-12-10 726f0553fa435809d10c8a33abe46473ee975db1
SourceCode/Bond/BondEq/View/AxisDetailSettingsDlg.cpp
@@ -5,6 +5,8 @@
#include "BondEq.h"
#include "afxdialogex.h"
#include "AxisDetailSettingsDlg.h"
#include "NewCellTypes/GridCellCheck.h"
#include "NewCellTypes/GridCellNumeric.h"
// CAxisDetailSettingsDlg 对话框
@@ -32,6 +34,126 @@
   m_pPLC = pPLC;
}
void CAxisDetailSettingsDlg::InitAnchorPontManager()
{
   if (m_grid.GetSafeHwnd() == NULL)
      return;
   int nRows = 1;
   int nCols = 6;
   int nFixRows = 1;
   int nFixCols = 0;
   int nRowIdx = 0;
   int nColIdx = 0;
   m_grid.DeleteAllItems();
   m_grid.SetVirtualMode(FALSE);
   m_grid.GetDefaultCell(TRUE, FALSE)->SetBackClr(g_nGridFixCellColor); // 设置固定行背景色
   m_grid.GetDefaultCell(FALSE, TRUE)->SetBackClr(g_nGridFixCellColor); // 设置固定列背景色
   m_grid.GetDefaultCell(FALSE, FALSE)->SetBackClr(g_nGridCellColor);    // 设置单元格背景色
   m_grid.SetFixedTextColor(g_nGridFixFontColor);                   // 设置固定行列字体颜色
   m_grid.SetRowCount(nRows);
   m_grid.SetColumnCount(nCols);
   m_grid.SetFixedRowCount(nFixRows);
   m_grid.SetFixedColumnCount(nFixCols);
   // Col
   m_grid.SetColumnWidth(nColIdx, 10);
   m_grid.SetItemText(nRowIdx, nColIdx++, _T("No."));
   m_grid.SetColumnWidth(nColIdx, 10);
   m_grid.SetItemText(nRowIdx, nColIdx++, _T("激活"));
   m_grid.SetColumnWidth(nColIdx, 50);
   m_grid.SetItemText(nRowIdx, nColIdx++, _T("最小值"));
   m_grid.SetColumnWidth(nColIdx, 50);
   m_grid.SetItemText(nRowIdx, nColIdx++, _T("当前值"));
   m_grid.SetColumnWidth(nColIdx, 50);
   m_grid.SetItemText(nRowIdx, nColIdx++, _T("最大值"));
   m_grid.SetColumnWidth(nColIdx, 120);
   m_grid.SetItemText(nRowIdx, nColIdx++, _T("描述"));
   m_grid.SetFixedRowSelection(FALSE);
   m_grid.SetFixedColumnSelection(FALSE);
   m_grid.SetEditable(TRUE);
   m_grid.SetRowResize(FALSE);
   m_grid.SetColumnResize(TRUE);
   m_grid.ExpandColumnsToFit(TRUE);
   m_grid.SetListMode(TRUE);            // 启用列表模式
   m_grid.EnableSelection(TRUE);         // 启用选择
   m_grid.SetSingleRowSelection(TRUE);      // 自动整行高亮(限制为单行选择)
   m_grid.ExpandLastColumn();            // 最后一列填充网格
   FillAnchorPontManager();
}
void CAxisDetailSettingsDlg::FillAnchorPontManager()
{
   RecipeManager& g_recipeManager = RecipeManager::getInstance();
   auto axisDetails = g_recipeManager.getAxis(m_nAxisNO);
   int nRowIndex = 1;
   int nPositionsSize = (int)axisDetails.positions.size();
   // 清除数据行,保留表头
   for (int i = 1; i < m_grid.GetRowCount(); i++) {
      m_grid.DeleteRow(i);
   }
   // 设置表格行数
   m_grid.SetRowCount(axisDetails.positioningPointCount + 1);
   auto SetCellText = [this](int nRow, int nCol, const CString& strText, UINT nState = GVIS_READONLY) {
      m_grid.SetItemText(nRow, nCol, strText);
      m_grid.SetItemState(nRow, nCol, nState);
   };
   auto FormatFloatToString = [](double dValue) -> CString {
      CString strText;
      strText.Format(_T("%.3f"), dValue);
      return strText;
   };
   for (int nIndex = 0; nIndex < axisDetails.positioningPointCount; nIndex++) {
      m_grid.SetItemState(nIndex, 0, GVIS_READONLY); // 序号列设置只读
      SetCellText(nRowIndex, 0, CString(std::to_string(nRowIndex).c_str()));
      if (nIndex >= nPositionsSize) {
         // 添加新行的默认值
         if (m_grid.SetCellType(nRowIndex, 1, RUNTIME_CLASS(CGridCellCheck))) {
            auto* pCell = static_cast<CGridCellCheck*>(m_grid.GetCell(nRowIndex, 1));
            pCell->SetCheck(TRUE);
         }
         SetCellText(nRowIndex, 2, FormatFloatToString(0.0), GVIS_MODIFIED);
         SetCellText(nRowIndex, 3, FormatFloatToString(1.0), GVIS_MODIFIED);
         SetCellText(nRowIndex, 4, FormatFloatToString(10.0), GVIS_MODIFIED);
         SetCellText(nRowIndex, 5, CString(_T("Position ")) + CString(std::to_string(nIndex + 1).c_str()), GVIS_MODIFIED);
      }
      else {
         const auto& enPosition = axisDetails.positions[nIndex];
         if (m_grid.SetCellType(nRowIndex, 1, RUNTIME_CLASS(CGridCellCheck))) {
            auto* pCell = static_cast<CGridCellCheck*>(m_grid.GetCell(nRowIndex, 1));
            pCell->SetCheck(enPosition.isEnable);
         }
         UINT nCellState = enPosition.isEnable ? GVIS_MODIFIED : GVIS_READONLY;
         SetCellText(nRowIndex, 2, FormatFloatToString(enPosition.range.minValue), nCellState);
         SetCellText(nRowIndex, 3, FormatFloatToString(enPosition.range.currentValue), nCellState);
         SetCellText(nRowIndex, 4, FormatFloatToString(enPosition.range.maxValue), nCellState);
         SetCellText(nRowIndex, 5, CString(enPosition.description.c_str()), nCellState);
      }
      nRowIndex++;
   }
   m_grid.ExpandColumnsToFit(FALSE);
   m_grid.ExpandLastColumn();
   m_grid.Invalidate();
   m_grid.UpdateWindow();
}
void CAxisDetailSettingsDlg::UpdateAxisDetailSettings()
{
   // 获取轴数据
@@ -54,8 +176,8 @@
   m_staticAxisDescription.SetWindowText(CString(axisDetails.description.c_str()));            // 轴描述
   m_staticStartAddress.SetWindowText(CString(axisDetails.startAddress.c_str()));               // 起始地址
   GetDlgItem(IDC_EDIT_AXIS_POSITIONING_SPEED_LIMIT)->SetWindowText(formatDouble(axisDetails.maxPositioningSpeed));   // 定位速度上限
   GetDlgItem(IDC_EDIT_AXIS_JOG_SPEED_LIMIT)->SetWindowText(formatDouble(axisDetails.maxManualSpeed));               // 手动速度上限
   //GetDlgItem(IDC_EDIT_AXIS_POSITIONING_SPEED_LIMIT)->SetWindowText(formatDouble(axisDetails.maxPositioningSpeed));   // 定位速度上限
   //GetDlgItem(IDC_EDIT_AXIS_JOG_SPEED_LIMIT)->SetWindowText(formatDouble(axisDetails.maxManualSpeed));               // 手动速度上限
   GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->SetWindowText(formatInt(axisDetails.positioningPointCount));         // 定位点数
   // 微动量
@@ -90,12 +212,14 @@
   DDX_Control(pDX, IDC_STATIC_AXIS_NUMBER, m_staticAxisNO);
   DDX_Control(pDX, IDC_STATIC_AXIS_DESCRIP, m_staticAxisDescription);
   DDX_Control(pDX, IDC_STATIC_START_ADDRESS, m_staticStartAddress);
   DDX_Control(pDX, IDC_CUSTOM_AXIS_ANCHOR_POINT, m_gridAxisDetailSettings);
   DDX_Control(pDX, IDC_CUSTOM_AXIS_ANCHOR_POINT, m_grid);
}
BEGIN_MESSAGE_MAP(CAxisDetailSettingsDlg, CDialogEx)
   ON_NOTIFY(NM_CLICK, IDC_CUSTOM_AXIS_ANCHOR_POINT, &CAxisDetailSettingsDlg::OnGridItemChanged)
   ON_BN_CLICKED(IDC_BUTTON_AXIS_DETAIL_SETTINGS_SAVE, &CAxisDetailSettingsDlg::OnBnClickedButtonAxisDetailSettingsSave)
   ON_BN_CLICKED(IDC_BUTTON_SET_AXIS_POSITIONING_POINTS, &CAxisDetailSettingsDlg::OnBnClickedButtonSetAxisPositioningPoints)
END_MESSAGE_MAP()
@@ -122,13 +246,174 @@
   }
   UpdateAxisDetailSettings();
   InitAnchorPontManager();
   return TRUE;  // return TRUE unless you set the focus to a control
   // 异常: OCX 属性页应返回 FALSE
}
void CAxisDetailSettingsDlg::OnGridItemChanged(NMHDR* pNotifyStruct, LRESULT* pResult)
{
   NM_GRIDVIEW* pItem = (NM_GRIDVIEW*)pNotifyStruct;
   int nRow = pItem->iRow;
   int nCol = pItem->iColumn;
   // 处理复选框状态变化
   if (nCol == 1) {
      // 获取复选框的当前状态
      CGridCellCheck* pCell = static_cast<CGridCellCheck*>(m_grid.GetCell(nRow, nCol));
      BOOL bChecked = pCell->GetCheck();
      // 处理复选框状态变化
      m_grid.SetItemState(nRow, 2, bChecked ? GVIS_MODIFIED : GVIS_READONLY);
      m_grid.SetItemState(nRow, 3, bChecked ? GVIS_MODIFIED : GVIS_READONLY);
      m_grid.SetItemState(nRow, 4, bChecked ? GVIS_MODIFIED : GVIS_READONLY);
      m_grid.SetItemState(nRow, 5, bChecked ? GVIS_MODIFIED : GVIS_READONLY);
   }
   *pResult = 0;
}
void CAxisDetailSettingsDlg::OnBnClickedButtonAxisDetailSettingsSave()
{
   // TODO: 在此添加控件通知处理程序代码
   EndDialog(IDOK);
   // 获取轴数据
   RecipeManager& recipeManager = RecipeManager::getInstance();
   auto& axisDetails = recipeManager.getAxis(m_nAxisNO);
   // 从界面控件获取用户输入的数据并更新到 axisDetails
   // 轴编号、描述和起始地址
   CString strAxisNo, strAxisDesc, strStartAddr;
   m_staticAxisNO.GetWindowText(strAxisNo);
   m_staticAxisDescription.GetWindowText(strAxisDesc);
   m_staticStartAddress.GetWindowText(strStartAddr);
   axisDetails.number = std::string(CT2A(strAxisNo));
   axisDetails.description = std::string(CT2A(strAxisDesc));
   axisDetails.startAddress = std::string(CT2A(strStartAddr));
   // 定位速度上限
   //CString strPosSpeedLimit;
   //GetDlgItem(IDC_EDIT_AXIS_POSITIONING_SPEED_LIMIT)->GetWindowText(strPosSpeedLimit);
   //axisDetails.maxPositioningSpeed = _ttof(strPosSpeedLimit);  // 转换为 double 类型
   // 手动速度上限
   //CString strJogSpeedLimit;
   //GetDlgItem(IDC_EDIT_AXIS_JOG_SPEED_LIMIT)->GetWindowText(strJogSpeedLimit);
   //axisDetails.maxManualSpeed = _ttof(strJogSpeedLimit);
   // 定位点数
   CString strPosCount;
   GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->GetWindowText(strPosCount);
   axisDetails.positioningPointCount = _ttoi(strPosCount);   // 转换为 int 类型
   // 微动量
   CString strJogDistanceMin, strJogDistanceCur, strJogDistanceMax;
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM_MIN)->GetWindowText(strJogDistanceMin);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM)->GetWindowText(strJogDistanceCur);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM_MAX)->GetWindowText(strJogDistanceMax);
   axisDetails.jogDistance.minValue = _ttof(strJogDistanceMin);
   axisDetails.jogDistance.currentValue = _ttof(strJogDistanceCur);
   axisDetails.jogDistance.maxValue = _ttof(strJogDistanceMax);
   // 手动速度
   CString strManualSpeedMin, strManualSpeedCur, strManualSpeedMax;
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS_MIN)->GetWindowText(strManualSpeedMin);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS)->GetWindowText(strManualSpeedCur);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS_MAX)->GetWindowText(strManualSpeedMax);
   axisDetails.manualSpeed.minValue = _ttof(strManualSpeedMin);
   axisDetails.manualSpeed.currentValue = _ttof(strManualSpeedCur);
   axisDetails.manualSpeed.maxValue = _ttof(strManualSpeedMax);
   // 自动速度
   CString strAutoSpeedMin, strAutoSpeedCur, strAutoSpeedMax;
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED_MIN)->GetWindowText(strAutoSpeedMin);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED)->GetWindowText(strAutoSpeedCur);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED_MAX)->GetWindowText(strAutoSpeedMax);
   axisDetails.autoSpeed.minValue = _ttof(strAutoSpeedMin);
   axisDetails.autoSpeed.currentValue = _ttof(strAutoSpeedCur);
   axisDetails.autoSpeed.maxValue = _ttof(strAutoSpeedMax);
   // 加速时间
   CString strAcceTimeMin, strAcceTimeCur, strAcceTimeMax;
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME_MIN)->GetWindowText(strAcceTimeMin);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME)->GetWindowText(strAcceTimeCur);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME_MAX)->GetWindowText(strAcceTimeMax);
   axisDetails.accelerationTime.minValue = _ttof(strAcceTimeMin);
   axisDetails.accelerationTime.currentValue = _ttof(strAcceTimeCur);
   axisDetails.accelerationTime.maxValue = _ttof(strAcceTimeMax);
   // 减速时间
   CString strDeceTimeMin, strDeceTimeCur, strDeceTimeMax;
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MIN)->GetWindowText(strDeceTimeMin);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME)->GetWindowText(strDeceTimeCur);
   GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MAX)->GetWindowText(strDeceTimeMax);
   axisDetails.decelerationTime.minValue = _ttof(strDeceTimeMin);
   axisDetails.decelerationTime.currentValue = _ttof(strDeceTimeCur);
   axisDetails.decelerationTime.maxValue = _ttof(strDeceTimeMax);
   // 如果 positioningPointCount 和 positions.size() 不同,则调整大小
   if (axisDetails.positioningPointCount != (int)axisDetails.positions.size()) {
      axisDetails.positions.resize(axisDetails.positioningPointCount);
   }
   // 更新表格中的定位点数据
   for (int i = 0; i < axisDetails.positioningPointCount; i++) {
      auto& enPosition = axisDetails.positions[i];
      // 使能状态
      BOOL bIsChecked = ((CGridCellCheck*)m_grid.GetCell(i + 1, 1))->GetCheck();
      enPosition.isEnable = bIsChecked;
      // 最小值、当前值和最大值
      CString strMin, strCur, strMax;
      strMin = m_grid.GetItemText(i + 1, 2);
      strCur = m_grid.GetItemText(i + 1, 3);
      strMax = m_grid.GetItemText(i + 1, 4);
      enPosition.range.minValue = _ttof(strMin);
      enPosition.range.currentValue = _ttof(strCur);
      enPosition.range.maxValue = _ttof(strMax);
      // 描述
      CString strDesc;
      strDesc = m_grid.GetItemText(i + 1, 5);
      enPosition.description = std::string(CT2A(strDesc));
   }
   // 更新 RecipeManager 中的轴数据
   recipeManager.updateAxis(axisDetails);
   // 保存轴数据到文件
   CString cstrMessage;
   if (RecipeManager::getInstance().saveRecipe(std::string(CT2A(m_strRecipeName)))) {
      cstrMessage.Format(_T("保存轴 [%d] 细部参数成功!"), m_nAxisNO);
      SystemLogManager::getInstance().log(SystemLogManager::LogType::Operation, std::string(CT2A(cstrMessage)));
   }
   else {
      cstrMessage.Format(_T("保存轴 [%d] 细部参数失败!"), m_nAxisNO);
      SystemLogManager::getInstance().log(SystemLogManager::LogType::Error, std::string(CT2A(cstrMessage)));
   }
   AfxMessageBox(cstrMessage);
}
void CAxisDetailSettingsDlg::OnBnClickedButtonSetAxisPositioningPoints()
{
   // TODO: 在此添加控件通知处理程序代码
   CString strPosCount;
   GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->GetWindowText(strPosCount);
   if (strPosCount.IsEmpty()) {
      AfxMessageBox(_T("请输入定位点数!"));
      return;
   }
   RecipeManager& recipeManager = RecipeManager::getInstance();
   AxisInfo axisDetails = recipeManager.getAxis(m_nAxisNO);
   axisDetails.positioningPointCount = _ttoi(strPosCount);
   // 更新 RecipeManager 中的轴数据
   recipeManager.updateAxis(axisDetails);
   FillAnchorPontManager();
}