| | |
| | | #include "AxisDetailSettingsDlg.h" |
| | | #include "ToolUnits.h" |
| | | #include <cctype> |
| | | #include <regex> |
| | | |
| | | |
| | | #define COLOR_GREEN_ON RGB(0, 255, 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 |
| | | |
| | |
| | | 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_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) |
| | |
| | | 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); |
| | |
| | | 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) |
| | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | // 判断输入的值是否在合法范围内 |
| | | 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; |
| | |
| | | |
| | | // 获取界面上的修改参数 |
| | | 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); |
| | | |
| | | // 更新定位点数据 |
| | |
| | | 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() |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | |
| | | 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); |
| | |
| | | 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); |
| | |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup2() |
| | | { |
| | | // TODO: 在此添加控件通知处理程序代码 |
| | | SwitchToPage(2); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup3() |
| | | { |
| | | // TODO: 在此添加控件通知处理程序代码 |
| | | SwitchToPage(3); |
| | | } |
| | | |
| | |
| | | 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) { |
| | |
| | | |
| | | ReadPLCDataToUI(nAxisId); |
| | | } |
| | | else if (TIMER_HIDE_TIP == nIDEvent) { |
| | | KillTimer(TIMER_HIDE_TIP); |
| | | HideTip(); |
| | | } |
| | | |
| | | CBaseDlg::OnTimer(nIDEvent); |
| | | } |
| | |
| | | |
| | | 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); |
| | | } |
| | | |
| | | bool CAxisSettingsDlg::IsFloatInRange(const std::string& strInput, double fLowerBound, double fUpperBound) |
| | | { |
| | | // 是否为合法浮点数 |
| | | 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; |
| | | } |
| | | } |