// AxisDetailSettingsDlg.cpp: 实现文件 // #include "stdafx.h" #include "BoounionPLC.h" #include "AxisDetailSettingsDlg.h" #include "NewCellTypes/GridCellCheck.h" // CAxisDetailSettingsDlg 对话框 IMPLEMENT_DYNAMIC(CAxisDetailSettingsDlg, CBaseDlg) CAxisDetailSettingsDlg::CAxisDetailSettingsDlg(AxisManager* pAxisManager, int nAxisNO, CWnd* pParent /*=nullptr*/) : CBaseDlg(IDD_DIALOG_AXIS_DETAIL_SETTINGS, pParent) { CPLC* pPLC = theApp.m_model.getCurrentPlc(); if (pPLC != nullptr && pAxisManager != nullptr) { m_pPLC = pPLC; m_pAxisManager = pAxisManager; } else { m_pPLC = nullptr; m_pAxisManager = nullptr; } m_nAxisNO = nAxisNO; } CAxisDetailSettingsDlg::~CAxisDetailSettingsDlg() { } 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() { int nRowIndex = 1; auto axisDetails = m_pAxisManager->GetAxis(m_nAxisNO); 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(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(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() { // 获取轴数据 auto axisDetails = m_pAxisManager->GetAxis(m_nAxisNO); auto formatDouble = [](double value) -> CString { CString str; str.Format(_T("%.3f"), value); return str; }; auto formatInt = [](int value) -> CString { CString str; str.Format(_T("%d"), value); return str; }; m_staticAxisNO.SetWindowText(CString(axisDetails.number.c_str())); // 轴编号 m_staticAxisDescription.SetWindowText(CString(axisDetails.description.c_str())); // 轴描述 m_staticStartAddress.SetWindowText(CString(axisDetails.startAddress.c_str())); // 起始地址 // 定位点数 GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->SetWindowText(formatInt(axisDetails.positioningPointCount)); // 微动量 GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM_MIN)->SetWindowText(formatDouble(axisDetails.jogDistance.minValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM)->SetWindowText(formatDouble(axisDetails.jogDistance.currentValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM_MAX)->SetWindowText(formatDouble(axisDetails.jogDistance.maxValue)); // 手动速度 GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS_MIN)->SetWindowText(formatDouble(axisDetails.manualSpeed.minValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS)->SetWindowText(formatDouble(axisDetails.manualSpeed.currentValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS_MAX)->SetWindowText(formatDouble(axisDetails.manualSpeed.maxValue)); // 自动速度 GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED_MIN)->SetWindowText(formatDouble(axisDetails.autoSpeed.minValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED)->SetWindowText(formatDouble(axisDetails.autoSpeed.currentValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED_MAX)->SetWindowText(formatDouble(axisDetails.autoSpeed.maxValue)); // 加速时间 GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME_MIN)->SetWindowText(formatDouble(axisDetails.accelerationTime.minValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME)->SetWindowText(formatDouble(axisDetails.accelerationTime.currentValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME_MAX)->SetWindowText(formatDouble(axisDetails.accelerationTime.maxValue)); // 减速时间 GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MIN)->SetWindowText(formatDouble(axisDetails.decelerationTime.minValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME)->SetWindowText(formatDouble(axisDetails.decelerationTime.currentValue)); GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MAX)->SetWindowText(formatDouble(axisDetails.decelerationTime.maxValue)); } bool CAxisDetailSettingsDlg::ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr) { if (address.GetLength() < 2) { return false; } // 提取组件类型(第一个字符) TCHAR componentChar = address[0]; if (address.Left(2) == _T("ZR")) { component = MC::SOFT_COMPONENT::ZR; // 提取数字部分(去除ZR前缀) CString numericAddress = address.Mid(2); addr = _ttoi(numericAddress); return addr != 0 || numericAddress.CompareNoCase(_T("0")) == 0; // 如果是 "0",也认为有效 } // 对于其他组件,按照常规规则处理 CString hexAddress = address.Mid(1); switch (componentChar) { case 'D': component = MC::SOFT_COMPONENT::D; addr = _ttoi(hexAddress); break; case 'M': component = MC::SOFT_COMPONENT::M; addr = _tcstoul(hexAddress, nullptr, 16); break; case 'X': component = MC::SOFT_COMPONENT::X; addr = _tcstoul(hexAddress, nullptr, 16); break; case 'Y': component = MC::SOFT_COMPONENT::Y; addr = _tcstoul(hexAddress, nullptr, 16); break; case 'W': component = MC::SOFT_COMPONENT::W; addr = _tcstoul(hexAddress, nullptr, 16); break; case 'L': component = MC::SOFT_COMPONENT::L; addr = _tcstoul(hexAddress, nullptr, 16); break; case 'S': component = MC::SOFT_COMPONENT::S; addr = _tcstoul(hexAddress, nullptr, 16); break; case 'B': component = MC::SOFT_COMPONENT::B; addr = _tcstoul(hexAddress, nullptr, 16); break; case 'F': component = MC::SOFT_COMPONENT::F; addr = _tcstoul(hexAddress, nullptr, 16); break; default: return false; } // 检查地址是否有效 if (addr == 0 && hexAddress.CompareNoCase(_T("0")) != 0) { return false; } return true; } void CAxisDetailSettingsDlg::WriteAxisDataToPLC(int nAxisId) { // 获取轴数据 AxisInfo axisData = m_pAxisManager->GetAxis(nAxisId); MC::SOFT_COMPONENT enComponent; int nStartAddress, nSize; if (!ParsePLCAddress(CString(axisData.startAddress.c_str()), enComponent, nStartAddress)) { AfxMessageBox(_T("无效的起始地址!")); } // 写入微动量 m_pPLC->writeWord(enComponent, nStartAddress + 81, (int)(axisData.jogDistance.currentValue * 1000.0), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 微动量, 地址: %d, 值: %lu\n", addr, value); } else { TRACE("\n写入失败: 微动量, 地址: %d, 错误码: %d\n", addr, flag); } }); // 写入定位点数 m_pPLC->writeWord(enComponent, nStartAddress + 99, (int)(axisData.positioningPointCount), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 定位点数, 地址: %d, 值: %lu\n", addr, value); } else { TRACE("\n写入失败: 定位点数, 地址: %d, 错误码: %d\n", addr, flag); } }); // 写入手动速度 m_pPLC->writeDWord(enComponent, nStartAddress + 82, (int)(axisData.manualSpeed.currentValue * 1000), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 手动速度, 地址: %d, 值: %lu\n", addr, value); } else { TRACE("\n写入失败: 手动速度, 地址: %d, 错误码: %d\n", addr, flag); } }); // 写入最大手动速度 m_pPLC->writeDWord(enComponent, nStartAddress + 72, (int)(axisData.manualSpeed.maxValue * 1000), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 最大手动速度, 地址: %d, 值: %lu\n", addr, value); } else { TRACE("\n写入失败: 最大手动速度, 地址: %d, 错误码: %d\n", addr, flag); } }); // 写入自动速度 m_pPLC->writeDWord(enComponent, nStartAddress + 84, (int)(axisData.autoSpeed.currentValue * 1000), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 自动速度, 地址: %d, 值: %lu\n", addr, value); } else { TRACE("\n写入失败: 自动速度, 地址: %d, 错误码: %d\n", addr, flag); } }); // 写入最大自动速度 m_pPLC->writeDWord(enComponent, nStartAddress + 60, (int)(axisData.autoSpeed.maxValue * 1000), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 最大自动速度, 地址: %d, 值: %lu\n", addr, value); } else { TRACE("\n写入失败: 最大自动速度, 地址: %d, 错误码: %d\n", addr, flag); } }); // 写入加速时间 m_pPLC->writeDWord(enComponent, nStartAddress + 62, (int)(axisData.accelerationTime.currentValue * 1000), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 加速时间, 地址: %d, 值: %lu\n", addr, value); } else { TRACE("\n写入失败: 加速时间, 地址: %d, 错误码: %d\n", addr, flag); } }); // 写入减速时间 m_pPLC->writeDWord(enComponent, nStartAddress + 64, (int)(axisData.decelerationTime.currentValue * 1000), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 减速时间, 地址: %d, 值: %lu\n", addr, value); } else { TRACE("\n写入失败: 减速时间, 地址: %d, 错误码: %d\n", addr, flag); } }); // 写入定位点数据 { char szWrite[100] = { 0 }; auto writeIntToBuffer = [&](int value, int nWriteIndex) { if (nWriteIndex + 4 <= sizeof(szWrite)) { // 小端 szWrite[nWriteIndex] = static_cast(value & 0xFF); // 低字节 szWrite[nWriteIndex + 1] = static_cast((value >> 8) & 0xFF); // 次低字节 szWrite[nWriteIndex + 2] = static_cast((value >> 16) & 0xFF); // 次高字节 szWrite[nWriteIndex + 3] = static_cast((value >> 24) & 0xFF); // 高字节 } }; nSize = sizeof(szWrite); int nAddress = nStartAddress + 100; for (int i = 0; i < axisData.positions.size(); ++i) { const auto& position = axisData.positions[i]; writeIntToBuffer(static_cast(position.range.currentValue * 1000), (i * 4)); } m_pPLC->writeData(enComponent, nAddress, szWrite, nSize, [nAddress, &szWrite](IMcChannel* pChannel, int nAddr, DWORD nValue, int nFlag) { if (nFlag == 0) { TRACE("操作成功:地址=%d,值=%s\n", nAddress, szWrite); } else { TRACE("操作失败:地址=%d,错误码=%d\n", nAddress, nFlag); } }); } // 写入定位点上下限 { char szWrite[200] = { 0 }; auto writeIntToBuffer = [&](int value, int nWriteIndex) { if (nWriteIndex + 4 <= sizeof(szWrite)) { // 小端 szWrite[nWriteIndex] = static_cast(value & 0xFF); // 低字节 szWrite[nWriteIndex + 1] = static_cast((value >> 8) & 0xFF); // 次低字节 szWrite[nWriteIndex + 2] = static_cast((value >> 16) & 0xFF); // 次高字节 szWrite[nWriteIndex + 3] = static_cast((value >> 24) & 0xFF); // 高字节 } }; nSize = sizeof(szWrite); int nAddress = nStartAddress + 200; int nIndex = 0; for (int i = 0; i < axisData.positions.size(); ++i) { const auto& position = axisData.positions[i]; writeIntToBuffer(static_cast(position.range.minValue * 1000), (nIndex * 4)); writeIntToBuffer(static_cast(position.range.maxValue * 1000), ((nIndex + 1) * 4)); nIndex += 2; } m_pPLC->writeData(enComponent, nAddress, szWrite, nSize, [nAddress, &szWrite](IMcChannel* pChannel, int nAddr, DWORD nValue, int nFlag) { if (nFlag == 0) { TRACE("操作成功:地址=%d,值=%s\n", nAddress, szWrite); } else { TRACE("操作失败:地址=%d,错误码=%d\n", nAddress, nFlag); } }); } } void CAxisDetailSettingsDlg::DoDataExchange(CDataExchange* pDX) { CBaseDlg::DoDataExchange(pDX); 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_grid); } BEGIN_MESSAGE_MAP(CAxisDetailSettingsDlg, CBaseDlg) 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() // CAxisDetailSettingsDlg 消息处理程序 BOOL CAxisDetailSettingsDlg::OnInitDialog() { CBaseDlg::OnInitDialog(); // TODO: 在此添加额外的初始化 if (m_pPLC == nullptr || !m_pPLC->isConnected()) { AfxMessageBox(_T("PLC 未连接!")); return FALSE; } if (m_pAxisManager == nullptr) { AfxMessageBox(_T("轴管理器未加载!")); return FALSE; } CString strTitle; strTitle.Format(_T("轴细部设定(PLC: %s)"), m_pPLC->getName().c_str()); SetWindowText(strTitle); // 不可编辑 GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS_MIN)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED_MIN)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME_MIN)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME_MAX)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MIN)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MAX)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM_MIN)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM_MAX)->EnableWindow(FALSE); // 获取轴数据 auto axisDetails = m_pAxisManager->GetAxis(m_nAxisNO); if (axisDetails.id == -1) { CString strMsg; strMsg.Format(_T("轴 [%d] 不存在!"), m_nAxisNO); AfxMessageBox(strMsg); return FALSE; } 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(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: 在此添加控件通知处理程序代码 // 获取轴数据 auto& axisDetails = m_pAxisManager->GetAxis(m_nAxisNO); // 轴编号、描述和起始地址 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 strPosCount; GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->GetWindowText(strPosCount); axisDetails.positioningPointCount = _ttoi(strPosCount); // 微动量 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)); } m_pAxisManager->UpdateAxis(axisDetails); // 保存轴数据到文件 CString cstrMessage; if (m_pAxisManager->SaveAxis(m_pPLC->getName())) { WriteAxisDataToPLC(m_nAxisNO); cstrMessage.Format(_T("保存轴 [%d] 细部参数成功!"), m_nAxisNO); } else { cstrMessage.Format(_T("保存轴 [%d] 细部参数失败!"), m_nAxisNO); } AfxMessageBox(cstrMessage); } void CAxisDetailSettingsDlg::OnBnClickedButtonSetAxisPositioningPoints() { // TODO: 在此添加控件通知处理程序代码 CString strPosCount; GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->GetWindowText(strPosCount); if (strPosCount.IsEmpty()) { AfxMessageBox(_T("请输入定位点数!")); return; } short nCount = _ttoi(strPosCount); if (nCount < 1 || nCount > 25) { AfxMessageBox(_T("范围在1-25之间!")); return; } AxisInfo axisDetails = m_pAxisManager->GetAxis(m_nAxisNO); axisDetails.positioningPointCount = _ttoi(strPosCount); // 更新 AxisManager 中的轴数据 m_pAxisManager->UpdateAxis(axisDetails); FillAnchorPontManager(); }