// AxisSettingsDlg.cpp: 实现文件 // #include "stdafx.h" #include "BoounionPLC.h" #include "afxdialogex.h" #include "AxisSettingsDlg.h" #include "AxisDetailSettingsDlg.h" #include "ToolUnits.h" #include #define COLOR_GREEN_ON RGB(0, 255, 0) // 正常状态绿色 #define COLOR_GREEN_OFF RGB(0, 180, 0) // 偏绿状态 #define COLOR_RED RGB(255, 0, 0) // 错误状态红色 #define TIMER_INIT 1 #define TIMER_READ_PLC_DATA 2 #define TIMER_HIDE_TIP 3 #define ID_MSG_UPDATA_DATA_TO_UI WM_USER + 101 // CAxisSettingsDlg 对话框 IMPLEMENT_DYNAMIC(CAxisSettingsDlg, CBaseDlg) CAxisSettingsDlg::CAxisSettingsDlg(CWnd* pParent /*=nullptr*/) : CBaseDlg(IDD_DIALOG_AXIS_SETTINGS, pParent) { CPLC* pPLC = theApp.m_model.getCurrentPlc(); if (pPLC != nullptr) { m_pPLC = pPLC; m_pAxisManager = new AxisManager(); m_pAxisManager->LoadAxis(pPLC->getName()); } m_bSEV = FALSE; m_fCurPos = 0.0; m_fManualSpeed = 0.0; m_fAutoSpeed = 0.0; m_fPrm = 0.0; m_nLoad = 0; m_nErrCode = 0; m_nAlarmCode = 0; m_bFLS = FALSE; m_bDOG = FALSE; m_bRLS = FALSE; m_bReady = FALSE; m_bBusy = FALSE; m_bErr = FALSE; for (int i = 0; i < BTN_MAX; i++) { 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(); } m_nBtnsFlashState6 = 0; m_nBtnsFlashState8 = 0; m_crTipBack = RGB(255, 127, 39); m_crTipText = RGB(228, 228, 228); m_hbrTip = CreateSolidBrush(m_crTipBack); m_hTipFont = nullptr; } CAxisSettingsDlg::~CAxisSettingsDlg() { 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++) { delete m_pBlLabels[i]; } if (m_pAxisManager != nullptr) { delete m_pAxisManager; m_pAxisManager = nullptr; } ::DeleteObject(m_hbrTip); if (m_hTipFont != nullptr) { ::DeleteObject(m_hTipFont); } } BOOL CAxisSettingsDlg::PreAdjustControl(CWnd* pWnd) { int nCtrlID = pWnd->GetDlgCtrlID(); if (nCtrlID == IDC_LABEL_TIP) return FALSE; return TRUE; } void CAxisSettingsDlg::DoDataExchange(CDataExchange* pDX) { CBaseDlg::DoDataExchange(pDX); DDX_Control(pDX, IDC_COMBO_AXIS_NAME, m_comboAxisNO); 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); } UINT CAxisSettingsDlg::FindIDByName(const CString& strControlID) { // 将资源文件中定义的控件名称和 ID 加载到一个映射中 static const std::map controlIdMap = { {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP1", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP1}, {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP2", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP2}, {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP3", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP3}, {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP4", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP4}, {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP5", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP5}, {"IDC_EDIT_AXIS_ANCHOR_POINT1", IDC_EDIT_AXIS_ANCHOR_POINT1}, {"IDC_EDIT_AXIS_ANCHOR_POINT2", IDC_EDIT_AXIS_ANCHOR_POINT2}, {"IDC_EDIT_AXIS_ANCHOR_POINT3", IDC_EDIT_AXIS_ANCHOR_POINT3}, {"IDC_EDIT_AXIS_ANCHOR_POINT4", IDC_EDIT_AXIS_ANCHOR_POINT4}, {"IDC_EDIT_AXIS_ANCHOR_POINT5", IDC_EDIT_AXIS_ANCHOR_POINT5} // 可以继续添加其他控件名称和 ID }; // 查找控件名称是否在映射中 auto it = controlIdMap.find(strControlID); if (it != controlIdMap.end()) { return it->second; } return 0; } void CAxisSettingsDlg::AdjustLabelFont(CBLLabel& label) { if (label.m_hWnd == nullptr) { return; } // 获取控件的矩形区域 CRect rect; label.GetClientRect(&rect); // 动态计算字体大小,基于控件的高度 int fontSize = rect.Height() / 2; // 控件高度的一半作为字体大小 if (fontSize < 8) fontSize = 8; // 最小字体大小 if (fontSize > 20) fontSize = 20; // 最大字体大小 // 设置字体大小 label.SetFontSize(fontSize); // 刷新控件显示 label.Invalidate(); label.UpdateWindow(); } void CAxisSettingsDlg::SetLabelColor(CBLLabel& label, COLORREF color) { label.SetBkColor(color); label.Invalidate(); // 标记区域无效 label.UpdateWindow(); // 立即刷新 } void CAxisSettingsDlg::SetLabelColorBasedOnState(CBLLabel& label, BOOL bState, COLORREF colorTrue, COLORREF colorFalse) { SetLabelColor(label, bState ? colorTrue : colorFalse); } void CAxisSettingsDlg::UpdateLabels() { SetLabelColorBasedOnState(*m_pBlLabels[LABEL_FLS], m_bFLS, COLOR_GREEN_ON, COLOR_GREEN_OFF); SetLabelColorBasedOnState(*m_pBlLabels[LABEL_DOG], m_bDOG, COLOR_GREEN_ON, COLOR_GREEN_OFF); SetLabelColorBasedOnState(*m_pBlLabels[LABEL_RLS], m_bRLS, COLOR_GREEN_ON, COLOR_GREEN_OFF); SetLabelColorBasedOnState(*m_pBlLabels[LABEL_READY], m_bReady, COLOR_GREEN_ON, COLOR_GREEN_OFF); SetLabelColorBasedOnState(*m_pBlLabels[LABEL_BUSY], m_bBusy, COLOR_GREEN_ON, COLOR_GREEN_OFF); 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) { BOOL bSelect = (i + 1 == m_currentPage); m_pBlBtns[i]->SetFaceColor(bSelect ? BTN_PAGE_FACE_SELECT_COLOR: BTN_PAGE_FACE_NORMAL_COLOR); m_pBlBtns[i]->SetTextColor(bSelect ? BTN_PAGE_TEXT_SELECT_COLOR : BTN_PAGE_TEXT_NORMAL_COLOR); } } void CAxisSettingsDlg::HideEditCursor(int nCtrlID) { CEdit* pEdit = (CEdit*)GetDlgItem(nCtrlID); if (pEdit && pEdit->GetSafeHwnd()) { pEdit->EnableWindow(FALSE); // 禁用控件 pEdit->SetReadOnly(TRUE); // 设置为只读 pEdit->HideCaret(); // 隐藏光标 } } int CAxisSettingsDlg::GetCurrentSelectedAxisID() { int currentIndex = m_comboAxisNO.GetCurSel(); if (currentIndex == CB_ERR) { return -1; } CString strAxisIDStr; m_comboAxisNO.GetLBText(currentIndex, strAxisIDStr); return _ttoi(strAxisIDStr); } void CAxisSettingsDlg::InitializeAxisIDCombo() { // 获取所有轴的编号 auto axisNumbers = m_pAxisManager->GetAllAxisID(); if (axisNumbers.empty()) { AfxMessageBox(_T("没有找到轴信息!")); return; } // 清空下拉框 m_comboAxisNO.ResetContent(); // 填充数据到下拉框 for (const auto& axisID : axisNumbers) { CString axisCString; axisCString.Format(_T("%d"), axisID); m_comboAxisNO.AddString(axisCString); } // 默认选择第一项 if (m_comboAxisNO.GetCount() > 0) { m_comboAxisNO.SetCurSel(0); } } void CAxisSettingsDlg::RefreshAxisDetails(int nAxisId) { // 获取轴数据 auto axisDetails = m_pAxisManager->GetAxis(nAxisId); auto formatDouble = [](double value) -> CString { CString str; str.Format(_T("%.3f"), 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())); // 起始地址 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("减速时间")); } void CAxisSettingsDlg::RefreshPositionDetails(int nAxisId, int pageNumber) { // 每页显示的定位点数量 const int pageSize = AXIS_PAGE_SIZE; // 获取定位点数据 auto positions = m_pAxisManager->GetPositions(nAxisId, pageNumber, pageSize); // 刷新 UI for (int i = 0; i < pageSize; ++i) { CString descriptionCtrlName, positionCtrlName; descriptionCtrlName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP%d"), i + 1); positionCtrlName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT%d"), i + 1); UINT descriptionCtrlId = FindIDByName(descriptionCtrlName); UINT positionCtrlId = FindIDByName(positionCtrlName); CWnd* pDescriptionCtrl = GetDlgItem(descriptionCtrlId); CWnd* pPositionCtrl = GetDlgItem(positionCtrlId); if (i < positions.size()) { const PositionRange& position = positions[i]; // 显示定位点的描述 CString description = CString(position.description.c_str()); if (pDescriptionCtrl) pDescriptionCtrl->SetWindowText(description); // 显示定位点的当前位置 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); } } } else { // 清空控件内容 if (pDescriptionCtrl) { pDescriptionCtrl->SetWindowText(_T("")); pDescriptionCtrl->EnableWindow(FALSE); } if (pPositionCtrl) { pPositionCtrl->SetWindowText(_T("")); pPositionCtrl->EnableWindow(FALSE); } } } } void CAxisSettingsDlg::UpdatePositionRange(PositionRange& position, int pageNumber, int pageSize, int currentIndex) { // 获取当前输入框中的文本 CString strText; GetDlgItem(IDC_EDIT_AXIS_CURR_POS)->GetWindowText(strText); if (strText.IsEmpty()) { return; } CString descriptionCtrlName, positionCtrlName; descriptionCtrlName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP%d"), currentIndex + 1); positionCtrlName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT%d"), currentIndex + 1); UINT descriptionCtrlId = FindIDByName(descriptionCtrlName); UINT positionCtrlId = FindIDByName(positionCtrlName); CWnd* pDescriptionCtrl = GetDlgItem(descriptionCtrlId); CWnd* pPositionCtrl = GetDlgItem(positionCtrlId); if (pDescriptionCtrl == nullptr || pPositionCtrl == nullptr) { return; } double enteredValue = _ttof(strText); double minValue = position.range.minValue; double maxValue = position.range.maxValue; // 判断输入的值是否在合法范围内 if (enteredValue < minValue || enteredValue > maxValue) { CString strError; strError.Format(_T("定位点的值必须在 %f 和 %f 之间!"), minValue, maxValue); pDescriptionCtrl->SetWindowText(strError); } else { position.range.currentValue = enteredValue; pDescriptionCtrl->SetWindowText(CString(position.description.c_str())); pPositionCtrl->SetWindowText(strText); } } void CAxisSettingsDlg::UpdateAxisSelection(int offset) { int currentIndex = m_comboAxisNO.GetCurSel(); if (currentIndex == CB_ERR) { AfxMessageBox(_T("请选择一个有效的轴编号!")); return; } int newIndex = currentIndex + offset; if (newIndex < 0 || newIndex >= m_comboAxisNO.GetCount()) { CString error; error.Format(_T("已经到达%s一个轴!"), offset < 0 ? _T("上") : _T("下")); AfxMessageBox(error); return; } m_comboAxisNO.SetCurSel(newIndex); RefreshAxisDetails(newIndex + 1); RefreshPositionDetails(newIndex + 1, m_currentPage); UpdatePageButtonStates(); } void CAxisSettingsDlg::UpdateDataFromUI(int nAxisId) { const int pageSize = AXIS_PAGE_SIZE; // 每页显示 5 个定位点 auto axisData = m_pAxisManager->GetAxis(nAxisId); // 获取界面上的修改参数 CString text; m_pRegexEdit[EDIT_MANUAL_SPEED]->GetWindowText(text); axisData.manualSpeed.currentValue = _ttof(text); m_pRegexEdit[EDIT_AUTO_SPEED]->GetWindowText(text); axisData.autoSpeed.currentValue = _ttof(text); m_pRegexEdit[EDIT_ACCE_TIME]->GetWindowText(text); axisData.accelerationTime.currentValue = _ttof(text); m_pRegexEdit[EDIT_DECE_TIME]->GetWindowText(text); axisData.decelerationTime.currentValue = _ttof(text); m_pRegexEdit[EDIT_MICROMENTUM]->GetWindowText(text); axisData.jogDistance.currentValue = _ttof(text); // 更新定位点数据 for (int i = 0; i < pageSize; ++i) { int index = (m_currentPage - 1) * pageSize + i; if (index < axisData.positions.size()) { // 构建控件名称 CString descriptionName, positionName; descriptionName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP%d"), i + 1); positionName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT%d"), i + 1); // 获取控件 CEdit* pDescriptionEdit = (CEdit*)GetDlgItem(FindIDByName(descriptionName)); CEdit* pPositionEdit = (CEdit*)GetDlgItem(FindIDByName(positionName)); if (pDescriptionEdit && pPositionEdit) { CString description, positionValue; // 获取控件中的文本 pDescriptionEdit->GetWindowText(description); pPositionEdit->GetWindowText(positionValue); // 更新 AxisManager 中的数据 axisData.positions[index].description = CT2A(description); axisData.positions[index].range.currentValue = _ttof(positionValue); } } } // 保存 AxisManager m_pAxisManager->UpdateAxis(axisData); } void CAxisSettingsDlg::SwitchToPage(int targetPage) { try { // 如果当前页面已经是目标页面,直接返回 if (m_currentPage == targetPage) { return; } // 获取当前选中的轴 ID int axisId = GetCurrentSelectedAxisID(); if (axisId == -1) { AfxMessageBox(_T("请选择一个有效的轴编号!")); return; } // 更新 UI 数据到内存 UpdateDataFromUI(axisId); // 切换页面 m_currentPage = targetPage; RefreshPositionDetails(axisId, targetPage); UpdatePageButtonStates(); } catch (const std::exception& ex) { CString errorMsg; errorMsg.Format(_T("刷新定位组%d失败:%s"), targetPage, CString(ex.what())); AfxMessageBox(errorMsg, MB_ICONERROR); } } bool CAxisSettingsDlg::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 CAxisSettingsDlg::WriteAxisDataToPLC(int nAxisId) { // 从 AxisManager 获取轴数据 auto axisData = m_pAxisManager->GetAxis(nAxisId); int startAddress; MC::SOFT_COMPONENT component; if (!ParsePLCAddress(CString(axisData.startAddress.c_str()), component, startAddress)) { AfxMessageBox(_T("无效的起始地址!")); } // 写入手动速度 m_pPLC->writeDWord(component, startAddress + 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(component, startAddress + 84, (int)(axisData.autoSpeed.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->writeDWord(component, startAddress + 62, (int)(axisData.accelerationTime.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->writeDWord(component, startAddress + 64, (int)(axisData.decelerationTime.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(component, startAddress + 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); } }); // 写入定位点数据 int positionStartAddress = startAddress + 100; for (int i = 0; i < axisData.positions.size(); ++i) { const auto& position = axisData.positions[i]; unsigned int positionAddress = positionStartAddress + (i * 2); double valueToWrite = position.range.currentValue; m_pPLC->writeDWord(component, positionAddress, (int)(valueToWrite * 1000), [i, positionAddress](IMcChannel* pChannel, int addr, DWORD value, int flag) { if (flag == 0) { TRACE("\n写入成功: 定位点 %d, 地址: %d, 值: %lu\n", i + 1, positionAddress, value); } else { TRACE("\n写入失败: 定位点 %d, 地址: %d, 错误码: %d\n", i + 1, positionAddress, flag); } }); } } void CAxisSettingsDlg::HandleAxisOperation(AxisOperationType eOpType, bool bPressed) { int nAxisId = GetCurrentSelectedAxisID(); if (nAxisId == -1) { AfxMessageBox(_T("未选择有效的轴编号!")); return; } // 获取轴数据 auto axisData = m_pAxisManager->GetAxis(nAxisId); int startAddress; MC::SOFT_COMPONENT component; if (!ParsePLCAddress(CString(axisData.startAddress.c_str()), component, startAddress)) { AfxMessageBox(_T("无效的起始地址!")); } // 根据操作类型计算目标地址 int bitIndex = 0; char szWrite[4] = { 0x0, 0x0, 0x0, 0x0 }; switch (eOpType) { case AxisOperationType::OPR: startAddress += 0; // OPR 信号地址 0,闪动信息06.0 szWrite[0] = bPressed ? 0x1 : 0; break; case AxisOperationType::JOG_ADD: startAddress += 01; // JOG+ 信号地址 c szWrite[1] = bPressed ? 0x10 : 0; break; case AxisOperationType::JOG_SUB: startAddress += 01; // JOG- 信号地址 d szWrite[1] = bPressed ? 0x20 : 0; break; case AxisOperationType::STOP: startAddress += 05; // STOP 信号地址 5.e szWrite[1] = bPressed ? 0x40 : 0; break; case AxisOperationType::SEV_ON: startAddress += 01; // SEV_ON 信号地址 1.a szWrite[1] = bPressed ? 0x04 : 0; break; case AxisOperationType::POSITION_1: case AxisOperationType::POSITION_2: case AxisOperationType::POSITION_3: case AxisOperationType::POSITION_4: case AxisOperationType::POSITION_5: startAddress += ((m_currentPage - 1) * 5 + ((int)eOpType - (int)AxisOperationType::POSITION_1 + 1)) / 16; bitIndex = ((m_currentPage-1) * 5 + ((int)eOpType - (int)AxisOperationType::POSITION_1 + 1)) % 16; if(bPressed) CToolUnits::setBit(szWrite, bitIndex); break; default: AfxMessageBox(_T("未知操作类型!")); return; } // 向 PLC 写入信号 m_pPLC->writeData(component, startAddress, szWrite, 2, [eOpType, startAddress, bPressed](IMcChannel* pChannel, int nAddr, DWORD nValue, int nFlag) { if (nFlag == 0) { TRACE("操作成功:类型=%d,地址=%d,值=%d\n", static_cast(eOpType), nAddr, bPressed); } else { TRACE("操作失败:类型=%d,地址=%d,错误码=%d\n", static_cast(eOpType), nAddr, nFlag); } }); } void CAxisSettingsDlg::ReadPLCDataToUI(int nAxisId) { AxisInfo axisData = m_pAxisManager->GetAxis(nAxisId); MC::SOFT_COMPONENT component; int startAddress, endAddress, readSize; if (!ParsePLCAddress(CString(axisData.startAddress.c_str()), component, startAddress)) { AfxMessageBox(_T("无效的起始地址!")); } endAddress = startAddress + 300; readSize = (endAddress - startAddress + 1) * 2; auto funOnReadData = [this, nAxisId, startAddress, readSize](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void { if (nDataSize == readSize && flag == 0 && ::IsWindow(m_hWnd)) { m_fCurPos = CToolUnits::toInt32(&pData[20 * 2]) * 0.001; m_fManualSpeed = CToolUnits::toInt32(&pData[82 * 2]) * 0.001; m_fAutoSpeed = CToolUnits::toInt32(&pData[84 * 2]) * 0.001; m_fPrm = CToolUnits::toInt32(&pData[50 * 2]) * 0.1; m_nLoad = CToolUnits::toInt16(&pData[54 * 2]); m_nErrCode = CToolUnits::toInt16(&pData[26 * 2]); m_nAlarmCode = CToolUnits::toInt16(&pData[27 * 2]); m_bSEV = CToolUnits::getBit(pData[1 * 2 + 1], 0xa - 8); m_bFLS = CToolUnits::getBit(pData[10 * 2], 1); m_bDOG = CToolUnits::getBit(pData[10 * 2], 6); m_bRLS = CToolUnits::getBit(pData[10 * 2], 0); m_bReady = CToolUnits::getBit(pData[10 * 2 + 1], 0xA - 8); m_bBusy = CToolUnits::getBit(pData[10 * 2 + 1], 0xB - 8); m_bErr = CToolUnits::getBit(pData[10 * 2 + 1], 0xF - 8); // 记录按钮刷新状态 // 6,7,8,9为原点和25个点位状态和完成状态 // ZR 06.0 和 08.0 // 回原点运动中,ZR06.0在0和1中切换,回原点完成, 08.0为1 // 修改ZR06.0闪烁为1,停止闪烁是0 // 定位1 // ZR 06.1 和 08.1 // ... int b = 6 * 2; m_nBtnsFlashState6 = ((BYTE)pData[b] | (BYTE)pData[b + 1] << 8); m_nBtnsFlashState6 |= ((BYTE)pData[b + 2] << 16 | (BYTE)pData[b + 3] << 24); m_nBtnsFlashState8 = ((BYTE)pData[b + 4] | (BYTE)pData[b + 5] << 8); m_nBtnsFlashState8 |= ((BYTE)pData[b + 6] << 16 | (BYTE)pData[b + 7] << 24); // 读取定位点数据 AxisInfo axisInfo = m_pAxisManager->GetAxis(nAxisId); for (int i = 0; i < axisInfo.positions.size(); ++i) { if (axisInfo.positions[i].isEnable == FALSE) { unsigned int positionAddress = 100 + (i * 2); axisInfo.positions[i].range.currentValue = CToolUnits::toInt32(&pData[positionAddress * 2]) * 0.001; } } m_pAxisManager->UpdateAxis(axisInfo); PostMessage(ID_MSG_UPDATA_DATA_TO_UI); } }; m_pPLC->readData(component, startAddress, readSize, funOnReadData); } BEGIN_MESSAGE_MAP(CAxisSettingsDlg, CBaseDlg) ON_BN_CLICKED(IDC_BUTTON_AXIS_LAST, &CAxisSettingsDlg::OnBnClickedButtonAxisLast) ON_BN_CLICKED(IDC_BUTTON_AXIS_NEXT, &CAxisSettingsDlg::OnBnClickedButtonAxisNext) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP1, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup1) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP2, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup2) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP3, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup3) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP4, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup4) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP5, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup5) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT1, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint1) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT2, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint2) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT3, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint3) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT4, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint4) ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT5, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint5) ON_BN_CLICKED(IDC_BUTTON_AXIS_TEST_OPR, &CAxisSettingsDlg::OnBnClickedButtonAxisTestOpr) ON_BN_CLICKED(IDC_BUTTON_AXIS_TEST_STOP, &CAxisSettingsDlg::OnBnClickedButtonAxisTestStop) ON_BN_CLICKED(IDC_BUTTON_AXIS_SEV, &CAxisSettingsDlg::OnBnClickedButtonAxisSev) ON_CBN_SELCHANGE(IDC_COMBO_AXIS_NAME, &CAxisSettingsDlg::OnSelchangeComboAxisName) ON_BN_CLICKED(IDC_BUTTON_AXIS_SAVE, &CAxisSettingsDlg::OnBnClickedButtonAxisSave) 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_WM_SIZE() ON_WM_TIMER() ON_WM_CLOSE() ON_WM_CTLCOLOR() ON_EN_KILLFOCUS(IDC_EDIT_AXIS_MODITFY_MICROMENTUM, &CAxisSettingsDlg::OnEnKillfocusEditAxisModitfyMicromentum) END_MESSAGE_MAP() // CAxisSettingsDlg 消息处理程序 BOOL CAxisSettingsDlg::OnInitDialog() { CBaseDlg::OnInitDialog(); // TODO: 在此添加额外的初始化 if (m_pPLC == nullptr || !m_pPLC->isConnected()) { AfxMessageBox(_T("PLC 未连接!")); return FALSE; } CString strTitle; strTitle.Format(_T("轴设定页面(PLC: %s)"), m_pPLC->getName().c_str()); SetWindowText(strTitle); // 隐藏光标 HideEditCursor(IDC_EDIT_AXIS_CURR_POS); HideEditCursor(IDC_EDIT_AXIS_CURR_MANUAL_SPEED); HideEditCursor(IDC_EDIT_AXIS_CURR_AUTO_SPEED); HideEditCursor(IDC_EDIT_AXIS_CURR_ROTA_SPEED); HideEditCursor(IDC_EDIT_AXIS_CURR_LOAD); HideEditCursor(IDC_EDIT_AXIS_CURR_ERROR_NUMBER); HideEditCursor(IDC_EDIT_AXIS_CURR_ALARM_NUMBER); // 设置测试状态 m_pBlLabels[LABEL_FLS]->SubclassDlgItem(IDC_STATIC_AXIS_TEST_FLS, this); m_pBlLabels[LABEL_DOG]->SubclassDlgItem(IDC_STATIC_AXIS_TEST_DOG, this); m_pBlLabels[LABEL_RLS]->SubclassDlgItem(IDC_STATIC_AXIS_TEST_RLS, this); m_pBlLabels[LABEL_READY]->SubclassDlgItem(IDC_STATIC_AXIS_TEST_READY, this); m_pBlLabels[LABEL_BUSY]->SubclassDlgItem(IDC_STATIC_AXIS_TEST_BUSY, this); m_pBlLabels[LABEL_ERR]->SubclassDlgItem(IDC_STATIC_AXIS_TEST_ERR, this); for (auto pLabel : m_pBlLabels) { pLabel->SetBkColor(RGB(0, 180, 0)); pLabel->SetRoundedCorners(TRUE, 10); pLabel->DisableBorder(); pLabel->SetTextColor(RGB(0, 0, 0)); pLabel->SetAlignment(AlignCenter); pLabel->SetDynamicFont(TRUE); 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); m_pBlBtns[BTN_PAGE2]->SubclassDlgItem(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP2, this); m_pBlBtns[BTN_PAGE3]->SubclassDlgItem(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP3, this); m_pBlBtns[BTN_PAGE4]->SubclassDlgItem(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP4, this); m_pBlBtns[BTN_PAGE5]->SubclassDlgItem(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP5, this); m_pBlBtns[BTN_JOG_ADD]->SubclassDlgItem(IDC_BUTTON_AXIS_TEST_JOG_ADD, this); m_pBlBtns[BTN_JOG_ADD]->SetFrameColor(BS_NORMAL, BTN_JOG_FRAME_NORMAL); m_pBlBtns[BTN_JOG_ADD]->SetFrameColor(BS_HOVER, BTN_JOG_FRAME_HOVER); m_pBlBtns[BTN_JOG_ADD]->SetFrameColor(BS_PRESS, BTN_JOG_FRAME_PRESS); m_pBlBtns[BTN_JOG_ADD]->SetBkgndColor(BS_NORMAL, BTN_JOG_BKGND_NORMAL); m_pBlBtns[BTN_JOG_ADD]->SetBkgndColor(BS_HOVER, BTN_JOG_BKGND_HOVER); m_pBlBtns[BTN_JOG_ADD]->SetBkgndColor(BS_PRESS, BTN_JOG_BKGND_PRESS); m_pBlBtns[BTN_JOG_SUB]->SubclassDlgItem(IDC_BUTTON_AXIS_TEST_JOG_SUB, this); m_pBlBtns[BTN_JOG_SUB]->SetFrameColor(BS_NORMAL, BTN_JOG_FRAME_NORMAL); m_pBlBtns[BTN_JOG_SUB]->SetFrameColor(BS_HOVER, BTN_JOG_FRAME_HOVER); m_pBlBtns[BTN_JOG_SUB]->SetFrameColor(BS_PRESS, BTN_JOG_FRAME_PRESS); m_pBlBtns[BTN_JOG_SUB]->SetBkgndColor(BS_NORMAL, BTN_JOG_BKGND_NORMAL); m_pBlBtns[BTN_JOG_SUB]->SetBkgndColor(BS_HOVER, BTN_JOG_BKGND_HOVER); m_pBlBtns[BTN_JOG_SUB]->SetBkgndColor(BS_PRESS, BTN_JOG_BKGND_PRESS); m_pBlBtns[BTN_JOG_SEV]->SubclassDlgItem(IDC_BUTTON_AXIS_SEV, this); m_pBlBtns[BTN_JOG_SEV]->SetFrameColor(BS_NORMAL, BTN_SEV_FRAME_NORMAL); m_pBlBtns[BTN_JOG_SEV]->SetFrameColor(BS_HOVER, BTN_SEV_FRAME_HOVER); m_pBlBtns[BTN_JOG_SEV]->SetFrameColor(BS_PRESS, BTN_SEV_FRAME_PRESS); m_pBlBtns[BTN_JOG_SEV]->SetBkgndColor(BS_NORMAL, BTN_SEV_BKGND_NORMAL); m_pBlBtns[BTN_JOG_SEV]->SetBkgndColor(BS_HOVER, BTN_SEV_BKGND_HOVER); m_pBlBtns[BTN_JOG_SEV]->SetBkgndColor(BS_PRESS, BTN_SEV_BKGND_PRESS); m_pBlBtns[BTN_JOG_STOP]->SubclassDlgItem(IDC_BUTTON_AXIS_TEST_STOP, this); m_pBlBtns[BTN_JOG_STOP]->SetFrameColor(BS_NORMAL, BTN_STOP_FRAME_NORMAL); m_pBlBtns[BTN_JOG_STOP]->SetFrameColor(BS_HOVER, BTN_STOP_FRAME_HOVER); m_pBlBtns[BTN_JOG_STOP]->SetFrameColor(BS_PRESS, BTN_STOP_FRAME_PRESS); m_pBlBtns[BTN_JOG_STOP]->SetBkgndColor(BS_NORMAL, BTN_STOP_BKGND_NORMAL); m_pBlBtns[BTN_JOG_STOP]->SetBkgndColor(BS_HOVER, BTN_STOP_BKGND_HOVER); m_pBlBtns[BTN_JOG_STOP]->SetBkgndColor(BS_PRESS, BTN_STOP_BKGND_PRESS); m_pBlBtns[BTN_JOG_OPR]->SubclassDlgItem(IDC_BUTTON_AXIS_TEST_OPR, this); m_pBlBtns[BTN_JOG_OPR]->SetFrameColor(BS_NORMAL, BTN_OPR_FRAME_NORMAL); m_pBlBtns[BTN_JOG_OPR]->SetFrameColor(BS_HOVER, BTN_OPR_FRAME_HOVER); m_pBlBtns[BTN_JOG_OPR]->SetFrameColor(BS_PRESS, BTN_OPR_FRAME_PRESS); m_pBlBtns[BTN_JOG_OPR]->SetBkgndColor(BS_NORMAL, BTN_OPR_BKGND_NORMAL); m_pBlBtns[BTN_JOG_OPR]->SetBkgndColor(BS_HOVER, BTN_OPR_BKGND_HOVER); m_pBlBtns[BTN_JOG_OPR]->SetBkgndColor(BS_PRESS, BTN_OPR_BKGND_PRESS); static UINT btnPointIds[] = { IDC_BUTTON_AXIS_ANCHOR_POINT1, IDC_BUTTON_AXIS_ANCHOR_POINT2, IDC_BUTTON_AXIS_ANCHOR_POINT3, IDC_BUTTON_AXIS_ANCHOR_POINT4, IDC_BUTTON_AXIS_ANCHOR_POINT5}; for (int i = 0; i < 5; i++) { m_pBlBtns[BTN_POINT1 + i]->SubclassDlgItem(btnPointIds[i], this); m_pBlBtns[BTN_POINT1 + i]->SetFrameColor(BS_NORMAL, BTN_POINT_FRAME_NORMAL); m_pBlBtns[BTN_POINT1 + i]->SetFrameColor(BS_HOVER, BTN_POINT_FRAME_HOVER); m_pBlBtns[BTN_POINT1 + i]->SetFrameColor(BS_PRESS, BTN_POINT_FRAME_PRESS); m_pBlBtns[BTN_POINT1 + i]->SetBkgndColor(BS_NORMAL, BTN_POINT_BKGND_NORMAL); m_pBlBtns[BTN_POINT1 + i]->SetBkgndColor(BS_HOVER, BTN_POINT_BKGND_HOVER); m_pBlBtns[BTN_POINT1 + i]->SetBkgndColor(BS_PRESS, BTN_POINT_BKGND_PRESS); } // 初始化当前页面为第一页 m_currentPage = 1; UpdatePageButtonStates(); InitializeAxisIDCombo(); RefreshAxisDetails(1); RefreshPositionDetails(1, m_currentPage); SetTimer(TIMER_READ_PLC_DATA, 500, nullptr); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } BOOL CAxisSettingsDlg::PreTranslateMessage(MSG* pMsg) { // TODO: 在此添加专用代码和/或调用基类 CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd); if (pWnd) { if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) { // 阻止回车键默认处理,防止对话框关闭 return TRUE; } // 判断鼠标是否进入指定控件区域 if (pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP1)->m_hWnd || pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP2)->m_hWnd || pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP3)->m_hWnd || pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP4)->m_hWnd || pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP5)->m_hWnd) { int currentIndex = -1; // 根据控件ID确定 currentIndex if (pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP1)->m_hWnd) { currentIndex = 0; } else if (pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP2)->m_hWnd) { currentIndex = 1; } else if (pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP3)->m_hWnd) { currentIndex = 2; } else if (pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP4)->m_hWnd) { currentIndex = 3; } else if (pWnd->GetSafeHwnd() == GetDlgItem(IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP5)->m_hWnd) { currentIndex = 4; } if (currentIndex == -1) { return CBaseDlg::PreTranslateMessage(pMsg); } CString descriptionCtrlName, positionCtrlName; descriptionCtrlName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP%d"), currentIndex + 1); positionCtrlName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT%d"), currentIndex + 1); UINT descriptionCtrlId = FindIDByName(descriptionCtrlName); UINT positionCtrlId = FindIDByName(positionCtrlName); CWnd* pDescriptionCtrl = GetDlgItem(descriptionCtrlId); CWnd* pPositionCtrl = GetDlgItem(positionCtrlId); if (pDescriptionCtrl == nullptr || pPositionCtrl == nullptr) { return CBaseDlg::PreTranslateMessage(pMsg); } PositionRange& position = m_pAxisManager->GetPositionByIndex(GetCurrentSelectedAxisID(), m_currentPage, AXIS_PAGE_SIZE, currentIndex); if (pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK) { // 处理鼠标点击事件 // 设置鼠标为箭头光标 ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); CString strText; GetDlgItem(IDC_EDIT_AXIS_CURR_POS)->GetWindowText(strText); if (strText.IsEmpty()) { return CBaseDlg::PreTranslateMessage(pMsg);; } double enteredValue = _ttof(strText); double minValue = position.range.minValue; double maxValue = position.range.maxValue; // 判断输入的值是否在合法范围内 if (enteredValue < minValue || enteredValue > maxValue) { CString strError; strError.Format(_T("定位点的值必须在 %f 和 %f 之间!"), minValue, maxValue); pDescriptionCtrl->SetWindowText(strError); } else { position.range.currentValue = enteredValue; pPositionCtrl->SetWindowText(strText); } } else if (pMsg->message == WM_LBUTTONUP) { // 处理鼠标抬起事件 // 设置鼠标为手形光标 ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HAND)); CString strText; strText.Format(_T("%s"), position.description.c_str()); pDescriptionCtrl->SetWindowText(strText); } else if (pMsg->message == WM_MOUSEMOVE) { // 处理鼠标移动事件 ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HAND)); } } if (pMsg->message == WM_LBUTTONDOWN) { if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_AXIS_TEST_JOG_ADD)->m_hWnd) { TRACE("JOG+ 按钮按下\n"); HandleAxisOperation(AxisOperationType::JOG_ADD, true); } else if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_AXIS_TEST_JOG_SUB)->m_hWnd) { TRACE("JOG- 按钮按下\n"); // 启动定时器连续发送信号 HandleAxisOperation(AxisOperationType::JOG_SUB, true); } } else if (pMsg->message == WM_LBUTTONUP) { if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_AXIS_TEST_JOG_ADD)->m_hWnd) { TRACE("JOG+ 按钮松开\n"); HandleAxisOperation(AxisOperationType::JOG_ADD, false); } else if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_AXIS_TEST_JOG_SUB)->m_hWnd) { TRACE("JOG- 按钮松开\n"); HandleAxisOperation(AxisOperationType::JOG_SUB, false); } } } return CBaseDlg::PreTranslateMessage(pMsg); } void CAxisSettingsDlg::OnSize(UINT nType, int cx, int cy) { CBaseDlg::OnSize(nType, cx, cy); if (GetDlgItem(IDC_LABEL_TIP) == nullptr) return; // TODO: 在此处添加消息处理程序代码 CWnd* pItem; CRect rcClient; GetClientRect(&rcClient); pItem = GetDlgItem(IDC_LABEL_TIP); pItem->MoveWindow(0, 0, rcClient.Width(), 36); // 动态调整各个 CBLLabel 的字体大小 for (auto pLabel : m_pBlLabels) { AdjustLabelFont(*pLabel); } // 调整下拉框高度 CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_AXIS_NAME); CButton* pButtonLeft = (CButton*)GetDlgItem(IDC_BUTTON_AXIS_LAST); CButton* pButtonRight = (CButton*)GetDlgItem(IDC_BUTTON_AXIS_NEXT); if (pComboBox && pButtonLeft && pButtonRight) { CRect rectButton; pButtonLeft->GetWindowRect(&rectButton); // 获取按钮尺寸 ScreenToClient(&rectButton); // 转换为客户端坐标 CRect rectComboBox; pComboBox->GetWindowRect(&rectComboBox); ScreenToClient(&rectComboBox); // 调整下拉框高度 int heightAdjustment = 2; rectComboBox.top = rectButton.top; rectComboBox.bottom = rectButton.bottom + heightAdjustment; pComboBox->MoveWindow(&rectComboBox); pComboBox->SetItemHeight(-1, rectButton.Height() - 6); } } void CAxisSettingsDlg::OnBnClickedButtonAxisLast() { // TODO: 在此添加控件通知处理程序代码 UpdateAxisSelection(-1); } void CAxisSettingsDlg::OnBnClickedButtonAxisNext() { // TODO: 在此添加控件通知处理程序代码 UpdateAxisSelection(1); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup1() { // TODO: 在此添加控件通知处理程序代码 SwitchToPage(1); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup2() { SwitchToPage(2); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup3() { SwitchToPage(3); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup4() { // TODO: 在此添加控件通知处理程序代码 SwitchToPage(4); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup5() { // TODO: 在此添加控件通知处理程序代码 SwitchToPage(5); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint1() { // TODO: 在此添加控件通知处理程序代码 HandleAxisOperation(AxisOperationType::POSITION_1, true); Sleep(200); HandleAxisOperation(AxisOperationType::POSITION_1, false); m_pBlBtns[BTN_POINT1]->Flash(500); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint2() { // TODO: 在此添加控件通知处理程序代码 HandleAxisOperation(AxisOperationType::POSITION_2, true); Sleep(200); HandleAxisOperation(AxisOperationType::POSITION_2, false); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint3() { // TODO: 在此添加控件通知处理程序代码 HandleAxisOperation(AxisOperationType::POSITION_3, true); Sleep(200); HandleAxisOperation(AxisOperationType::POSITION_3, false); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint4() { // TODO: 在此添加控件通知处理程序代码 HandleAxisOperation(AxisOperationType::POSITION_4, true); Sleep(200); HandleAxisOperation(AxisOperationType::POSITION_4, false); } void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint5() { // TODO: 在此添加控件通知处理程序代码 HandleAxisOperation(AxisOperationType::POSITION_5, true); Sleep(200); HandleAxisOperation(AxisOperationType::POSITION_5, false); } void CAxisSettingsDlg::OnBnClickedButtonAxisTestOpr() { // TODO: 在此添加控件通知处理程序代码 HandleAxisOperation(AxisOperationType::OPR, true); Sleep(200); HandleAxisOperation(AxisOperationType::OPR, false); } void CAxisSettingsDlg::OnBnClickedButtonAxisTestStop() { // TODO: 在此添加控件通知处理程序代码 HandleAxisOperation(AxisOperationType::STOP, true); Sleep(200); HandleAxisOperation(AxisOperationType::STOP, false); m_pBlBtns[BTN_JOG_OPR]->StopFlash(); m_pBlBtns[BTN_POINT1]->StopFlash(); m_pBlBtns[BTN_POINT2]->StopFlash(); m_pBlBtns[BTN_POINT3]->StopFlash(); m_pBlBtns[BTN_POINT3]->StopFlash(); m_pBlBtns[BTN_POINT4]->StopFlash(); } void CAxisSettingsDlg::OnBnClickedButtonAxisSev() { // TODO: 在此添加控件通知处理程序代码 HandleAxisOperation(AxisOperationType::SEV_ON, !m_bSEV); } void CAxisSettingsDlg::OnSelchangeComboAxisName() { // TODO: 在此添加控件通知处理程序代码 int axisId = GetCurrentSelectedAxisID(); if (axisId == -1) { AfxMessageBox(_T("请选择一个有效的轴编号!")); return; } RefreshAxisDetails(axisId); RefreshPositionDetails(axisId, m_currentPage); UpdatePageButtonStates(); } void CAxisSettingsDlg::OnBnClickedButtonAxisSave() { // TODO: 在此添加控件通知处理程序代码 int axisId = GetCurrentSelectedAxisID(); if (axisId == -1) { AfxMessageBox(_T("请选择一个有效的轴编号!")); return; } CString cstrMessage; cstrMessage.Format(_T("是否保存轴 [%d] 参数?"), axisId); int ret = AfxMessageBox(_T(cstrMessage), MB_OKCANCEL | MB_ICONEXCLAMATION); if (ret != IDOK) { return; } UpdateDataFromUI(axisId); if (m_pAxisManager->SaveAxis(m_pPLC->getName())) { WriteAxisDataToPLC(axisId); cstrMessage.Format(_T("保存轴 [%d] 参数成功!"), axisId); } else { cstrMessage.Format(_T("保存轴 [%d] 参数失败!"), axisId); } AfxMessageBox(cstrMessage); } void CAxisSettingsDlg::OnBnClickedButtonAxisUpdateUi() { // TODO: 在此添加控件通知处理程序代码 int axisId = GetCurrentSelectedAxisID(); if (axisId == -1) { AfxMessageBox(_T("请选择一个有效的轴编号!")); return; } RefreshAxisDetails(axisId); RefreshPositionDetails(axisId, m_currentPage); } void CAxisSettingsDlg::OnBnClickedButtonAxisDetailSettings() { // TODO: 在此添加控件通知处理程序代码 int nAxisId = GetCurrentSelectedAxisID(); if (nAxisId == -1) { AfxMessageBox(_T("请选择一个有效的轴编号!")); return; } CAxisDetailSettingsDlg dlg(m_pAxisManager, nAxisId, this); dlg.DoModal(); RefreshAxisDetails(nAxisId); RefreshPositionDetails(nAxisId, m_currentPage); } LRESULT CAxisSettingsDlg::OnUpdateDataToUI(WPARAM wParam, LPARAM lParam) { CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_POS, m_fCurPos); CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_MANUAL_SPEED, m_fManualSpeed); CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_AUTO_SPEED, m_fAutoSpeed); CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_ROTA_SPEED, m_fPrm); SetDlgItemInt(IDC_EDIT_AXIS_CURR_LOAD, m_nLoad); SetDlgItemInt(IDC_EDIT_AXIS_CURR_ERROR_NUMBER, m_nErrCode); SetDlgItemInt(IDC_EDIT_AXIS_CURR_ALARM_NUMBER, m_nAlarmCode); // 更新Labels状态 UpdateLabels(); // 更新不可写的定位点数据 for (int i = 0; i < AXIS_PAGE_SIZE; ++i) { PositionRange position = m_pAxisManager->GetPositionByIndex(GetCurrentSelectedAxisID(), m_currentPage, AXIS_PAGE_SIZE, 0); if (position.isEnable) { continue; } CString positionName; positionName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT%d"), i + 1); CEdit* pPositionEdit = (CEdit*)GetDlgItem(FindIDByName(positionName)); if (pPositionEdit) { CString positionValue; positionValue.Format(_T("%.3f"), position.range.currentValue); pPositionEdit->GetWindowText(positionValue); } } // ZR 06.0 和 08.0 // 回原点运动中,ZR06.0在0和1中切换,回原点完成, 08.0为1 // 修改ZR06.0闪烁为1,停止闪烁是0 // OPR按钮是否要闪烁或停止闪烁 // 06.0和08.0 if (m_nBtnsFlashState6 & 0x01) { // 06.0 if (!m_pBlBtns[BTN_JOG_OPR]->IsFlash()) { m_pBlBtns[BTN_JOG_OPR]->Flash(500); } } else { if (m_pBlBtns[BTN_JOG_OPR]->IsFlash()) { m_pBlBtns[BTN_JOG_OPR]->StopFlash(); } } if (m_nBtnsFlashState8 & 0x01) { // 完成信号 if (m_pBlBtns[BTN_JOG_OPR]->IsFlash()) { m_pBlBtns[BTN_JOG_OPR]->StopFlash(); } m_pBlBtns[BTN_JOG_OPR]->SetBkgndColor(BS_NORMAL, BTN_OPR_BKGND_TEST); m_pBlBtns[BTN_JOG_OPR]->Invalidate(); } else { m_pBlBtns[BTN_JOG_OPR]->SetBkgndColor(BS_NORMAL, BTN_OPR_BKGND_NORMAL); m_pBlBtns[BTN_JOG_OPR]->Invalidate(); } int v = 0x02; if (m_currentPage > 1) { v = v << (5 * (m_currentPage - 1)); } if (m_nBtnsFlashState6 & v) { if (!m_pBlBtns[BTN_POINT1]->IsFlash()) { m_pBlBtns[BTN_POINT1]->Flash(500); } } else if (m_nBtnsFlashState8 & v) { if (m_pBlBtns[BTN_POINT1]->IsFlash()) { m_pBlBtns[BTN_POINT1]->StopFlash(); } } // 设置使能按钮状态 if (m_bSEV) { m_pBlBtns[BTN_JOG_SEV]->SetWindowText(_T("Sev-OFF")); m_pBlBtns[BTN_JOG_SEV]->SetBkgndColor(BS_NORMAL, BTN_SEV_BKGND_PRESS); } else { m_pBlBtns[BTN_JOG_SEV]->SetWindowText(_T("Sev-ON")); m_pBlBtns[BTN_JOG_SEV]->SetBkgndColor(BS_NORMAL, BTN_SEV_BKGND_NORMAL); } if (m_nBtnsFlashState6 & (v << 1)) { if (!m_pBlBtns[BTN_POINT2]->IsFlash()) { m_pBlBtns[BTN_POINT2]->Flash(500); } } else if (m_nBtnsFlashState8 & (v << 1)) { if (m_pBlBtns[BTN_POINT2]->IsFlash()) { m_pBlBtns[BTN_POINT2]->StopFlash(); } } if (m_nBtnsFlashState6 & (v << 2)) { if (!m_pBlBtns[BTN_POINT3]->IsFlash()) { m_pBlBtns[BTN_POINT3]->Flash(500); } } else if (m_nBtnsFlashState8 & (v << 2)) { if (m_pBlBtns[BTN_POINT3]->IsFlash()) { m_pBlBtns[BTN_POINT3]->StopFlash(); } } if (m_nBtnsFlashState6 & (v << 3)) { if (!m_pBlBtns[BTN_POINT4]->IsFlash()) { m_pBlBtns[BTN_POINT4]->Flash(500); } } else if (m_nBtnsFlashState8 & (v << 3)) { if (m_pBlBtns[BTN_POINT4]->IsFlash()) { m_pBlBtns[BTN_POINT4]->StopFlash(); } } if (m_nBtnsFlashState6 & (v << 4)) { if (!m_pBlBtns[BTN_POINT5]->IsFlash()) { m_pBlBtns[BTN_POINT5]->Flash(500); } } else if (m_nBtnsFlashState8 & (v << 4)) { if (m_pBlBtns[BTN_POINT5]->IsFlash()) { m_pBlBtns[BTN_POINT5]->StopFlash(); } } return 0; } void CAxisSettingsDlg::OnTimer(UINT_PTR nIDEvent) { if (TIMER_READ_PLC_DATA == nIDEvent) { ASSERT(m_pPLC); int nAxisId = GetCurrentSelectedAxisID(); if (nAxisId == -1) { return; } ReadPLCDataToUI(nAxisId); } else if (TIMER_HIDE_TIP == nIDEvent) { KillTimer(TIMER_HIDE_TIP); HideTip(); } CBaseDlg::OnTimer(nIDEvent); } void CAxisSettingsDlg::OnClose() { // TODO: 在此添加消息处理程序代码和/或调用默认值 KillTimer(TIMER_READ_PLC_DATA); CBaseDlg::OnClose(); } HBRUSH CAxisSettingsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CBaseDlg::OnCtlColor(pDC, pWnd, nCtlColor); int nCtrlID = pWnd->GetDlgCtrlID(); if (nCtrlID == IDC_LABEL_TIP) { pDC->SetTextColor(m_crTipText); pDC->SetBkColor(m_crTipBack); if (m_hTipFont == nullptr) { HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT); CFont* pFont = CFont::FromHandle(hFontDefault); LOGFONT lf; pFont->GetLogFont(&lf); lf.lfHeight -= 8; m_hTipFont = ::CreateFontIndirect(&lf); ::SelectObject(pDC->m_hDC, m_hTipFont); } return m_hbrTip; } return hbr; } void CAxisSettingsDlg::ShowTipText(const char* pszText, float sec) { CString strText; strText.Format(_T(" * %s"), pszText); SetDlgItemText(IDC_LABEL_TIP, strText); GetDlgItem(IDC_LABEL_TIP)->ShowWindow(SW_SHOW); SetTimer(TIMER_HIDE_TIP, (int)(sec * 1000.0), nullptr); } void CAxisSettingsDlg::HideTip() { GetDlgItem(IDC_LABEL_TIP)->ShowWindow(SW_HIDE); } void CAxisSettingsDlg::OnEnKillfocusEditAxisModitfyMicromentum() { 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); } }