From 19261d011387ec57d646decc945aadaf8913eeab Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期一, 10 三月 2025 09:05:54 +0800
Subject: [PATCH] Merge branch 'clh'
---
SourceCode/Bond/Servo/CReadStep.h | 35
SourceCode/Bond/Servo/CPanelEquipment.cpp | 175 ++
SourceCode/Bond/Servo/CPanelAttributes.cpp | 192 ++
SourceCode/Bond/Servo/ServoGraph.cpp | 18
SourceCode/Bond/Servo/ToolUnits.cpp | 5
SourceCode/Bond/Servo/Servo.rc | 0
SourceCode/Bond/Servo/ApredTreeCtrl2.h | 53
SourceCode/Bond/Servo/ServoDlg.h | 10
SourceCode/Bond/Servo/AlarmDlg.h | 1
SourceCode/Bond/Servo/CEqStatusStep.h | 6
SourceCode/Bond/Servo/HorizontalLine.cpp | 209 ++
SourceCode/Bond/Servo/CPanelMaster.h | 47
SourceCode/Bond/Servo/CWriteStep.cpp | 197 ++
SourceCode/Bond/Servo/CEqCimModeChangeStep.h | 23
SourceCode/Bond/Servo/CPanelAttributes.h | 41
SourceCode/Bond/Servo/CAttribute.cpp | 36
SourceCode/Bond/Servo/ApredTreeCtrl2.cpp | 379 +++++
SourceCode/Bond/Servo/CEqModeStep.cpp | 24
SourceCode/Bond/Servo/Servo.vcxproj.filters | 22
SourceCode/Bond/Servo/CEqStatusStep.cpp | 34
SourceCode/Bond/Servo/CEquipment.h | 6
SourceCode/Bond/Servo/Servo.vcxproj | 22
.gitignore | 1
SourceCode/Bond/Servo/resource.h | 0
SourceCode/Bond/Servo/Servo.vcxproj.user | 2
SourceCode/Bond/Servo/HorizontalLine.h | 87 +
SourceCode/Bond/Servo/Servo.cpp | 3
SourceCode/Bond/Servo/CPanelMaster.cpp | 207 ++
SourceCode/Bond/Servo/CEqModeStep.h | 6
SourceCode/Bond/Servo/CMaster.h | 1
SourceCode/Bond/Servo/VerticalLine.h | 95 +
SourceCode/Bond/Servo/CEqAlarmStep.h | 37
SourceCode/Bond/Servo/CStep.h | 22
SourceCode/Bond/Servo/AlarmDlg.cpp | 16
SourceCode/Bond/Servo/AlarmManager.h | 28
SourceCode/Bond/Servo/CEquipment.cpp | 25
SourceCode/Bond/Servo/Model.h | 1
SourceCode/Bond/Servo/CMaster.cpp | 44
SourceCode/Bond/x64/Debug/Res/panel_close_24_b.ico | 0
SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp | 45
SourceCode/Bond/Servo/CStep.cpp | 166 --
SourceCode/Bond/Servo/ToolUnits.h | 1
SourceCode/Bond/Servo/CReadStep.cpp | 187 ++
SourceCode/Bond/Servo/CWriteStep.h | 38
SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h | 412 ++--
SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp | 442 +++---
SourceCode/Bond/Servo/CEqAlarmStep.cpp | 55
SourceCode/Bond/x64/Debug/Res/panel_close_24_a.ico | 0
SourceCode/Bond/Servo/CPanelEquipment.h | 42
SourceCode/Bond/Servo/Model.cpp | 52
SourceCode/Bond/Servo/ServoDlg.cpp | 141 +
SourceCode/Bond/Servo/VerticalLine.cpp | 316 ++++
SourceCode/Bond/Servo/CEqProcessStep.cpp | 160 ++
SourceCode/Bond/Servo/CAttributeVector.h | 24
SourceCode/Bond/Servo/CAttribute.h | 23
SourceCode/Bond/Servo/CAttributeVector.cpp | 47
SourceCode/Bond/Servo/ServoGraph.h | 4
SourceCode/Bond/Servo/CEqProcessStep.h | 37
SourceCode/Bond/Servo/Common.h | 39
59 files changed, 3,658 insertions(+), 683 deletions(-)
diff --git a/.gitignore b/.gitignore
index 1277413..99779f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,3 +48,4 @@
*.iom
SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj.user
SourceCode/Bond/x64/Debug/ServoConfiguration.ini
+*.iobj
diff --git a/SourceCode/Bond/Servo/AlarmDlg.cpp b/SourceCode/Bond/Servo/AlarmDlg.cpp
index 6fc3e88..66c14dd 100644
--- a/SourceCode/Bond/Servo/AlarmDlg.cpp
+++ b/SourceCode/Bond/Servo/AlarmDlg.cpp
@@ -5,6 +5,7 @@
#include "Servo.h"
#include "afxdialogex.h"
#include "AlarmDlg.h"
+#include "AlarmManager.h"
#include "Common.h"
#include <iomanip>
@@ -84,13 +85,14 @@
bool result = alarmManager.addAlarm(alarmData, alarmEventId);
if (result) {
LOGI("<CAlarmDlg> Alarm added successfully!");
- }
+ }
else {
LOGI("<CAlarmDlg> Failed to add alarm.");
- }
- }
}
}
+ }
+ }
+
pAny->release();
}, [&]() -> void {
@@ -277,7 +279,6 @@
pListCtrl->SetColumnWidth(7, LVSCW_AUTOSIZE_USEHEADER);
// 璁$畻鎬婚〉鏁�
- int totalRecords = AlarmManager::getInstance().getTotalAlarmCount("", "", m_strDeviceName, m_strUnitName, m_strKeyword, m_szTimeStart, m_szTimeEnd);
m_nTotalPages = (totalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
m_nCurPage = 1;
@@ -286,6 +287,11 @@
return TRUE; // return TRUE unless you set the focus to a control
// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+BOOL CAlarmDlg::DestroyWindow()
+{
+ return CDialogEx::DestroyWindow();
}
HBRUSH CAlarmDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
@@ -471,4 +477,4 @@
// 鐐瑰嚮涓嬩竴椤�
m_nCurPage++;
UpdatePageData(); // 璋冪敤鍒嗛〉鏇存柊鍑芥暟
-}
\ No newline at end of file
+}
diff --git a/SourceCode/Bond/Servo/AlarmDlg.h b/SourceCode/Bond/Servo/AlarmDlg.h
index 3fbf26d..6755277 100644
--- a/SourceCode/Bond/Servo/AlarmDlg.h
+++ b/SourceCode/Bond/Servo/AlarmDlg.h
@@ -57,6 +57,7 @@
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 鏀寔
virtual BOOL OnInitDialog();
+ virtual BOOL DestroyWindow();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnDestroy();
afx_msg void OnClose();
diff --git a/SourceCode/Bond/Servo/AlarmManager.h b/SourceCode/Bond/Servo/AlarmManager.h
index f99aafe..1c41797 100644
--- a/SourceCode/Bond/Servo/AlarmManager.h
+++ b/SourceCode/Bond/Servo/AlarmManager.h
@@ -262,6 +262,34 @@
*/
std::vector<AlarmInfo> getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const;
+ /**
+ * 读取报警文件
+ * @param filename 文件名
+ * @return 成功返回true,失败返回false
+ */
+ bool readAlarmFile(const std::string& filename);
+
+ /**
+ * 保存报警文件
+ * @param filename 文件名
+ * @return 成功返回true,失败返回false
+ */
+ bool saveAlarmFile(const std::string& filename);
+
+ /**
+ * 通过报警ID查询报警信息
+ * @param nAlarmID 报警ID
+ * @return 报警信息的指针
+ */
+ const AlarmInfo* getAlarmInfoByID(int nAlarmID) const;
+
+ /**
+ * 通过多个报警ID查询对应的报警信息
+ * @param alarmIDs 多个报警ID
+ * @return 返回多个报警信息
+ */
+ std::vector<AlarmInfo> getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const;
+
private:
AlarmManager();
~AlarmManager();
diff --git a/SourceCode/Bond/Servo/ApredTreeCtrl2.cpp b/SourceCode/Bond/Servo/ApredTreeCtrl2.cpp
new file mode 100644
index 0000000..92956c6
--- /dev/null
+++ b/SourceCode/Bond/Servo/ApredTreeCtrl2.cpp
@@ -0,0 +1,379 @@
+#include "stdafx.h"
+#include "ApredTreeCtrl2.h"
+
+
+#define ROFFSET 7
+#define WIDE 10
+#define WIDE2 5
+#define EXPANDED_WIDE 8
+
+#define BADGE_HIDE 0
+#define BADGE_DOT 1
+#define BADGE_NUMBER 2
+#define BADGE_DOT_WIDTH 12
+#define BADGE_NUMBER_WIDTH 20
+
+
+IMPLEMENT_DYNAMIC(CApredTreeCtrl2, CTreeCtrl)
+
+CApredTreeCtrl2::CApredTreeCtrl2()
+{
+ m_hBrushItem[0] = NULL;
+ m_hBrushItem[1] = NULL;
+ m_hBrushItem[2] = NULL;
+ m_crItemBk[0] = GetSysColor(COLOR_WINDOW);
+ m_crItemBk[1] = GetSysColor(COLOR_HIGHLIGHT);
+ m_crItemBk[2] = RGB(204, 206, 219);
+ m_crItemBtn[0] = RGB(30, 30, 30);
+ m_crItemBtn[1] = RGB(255, 255, 255);
+ m_crItemBtn[2] = RGB(255, 255, 255);
+}
+
+CApredTreeCtrl2::~CApredTreeCtrl2()
+{
+ if (m_hBrushItem[0] != NULL) {
+ ::DeleteObject(m_hBrushItem[0]);
+ }
+ if (m_hBrushItem[1] != NULL) {
+ ::DeleteObject(m_hBrushItem[1]);
+ }
+ if (m_hBrushItem[2] != NULL) {
+ ::DeleteObject(m_hBrushItem[2]);
+ }
+}
+
+BEGIN_MESSAGE_MAP(CApredTreeCtrl2, CTreeCtrl)
+ ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CApredTreeCtrl2::OnNMCustomdraw)
+END_MESSAGE_MAP()
+
+
+void CApredTreeCtrl2::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
+ LPNMTVCUSTOMDRAW lpnmcd = (LPNMTVCUSTOMDRAW)pNMCD;
+ HTREEITEM hItem;
+ UINT unt;
+ *pResult = 0;
+
+
+ switch (lpnmcd->nmcd.dwDrawStage)
+ {
+ case CDDS_PREPAINT:
+ *pResult = CDRF_NOTIFYITEMDRAW;
+ m_items.clear();
+ break;
+
+ case CDDS_ITEMPREPAINT:
+ m_items[(HTREEITEM)lpnmcd->nmcd.dwItemSpec] = lpnmcd->iLevel;
+ hItem = (HTREEITEM)lpnmcd->nmcd.dwItemSpec;
+ if (hItem != NULL) {
+ if ( (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED)== TVIS_SELECTED) {
+ if (GetFocus() != this) {
+ lpnmcd->clrTextBk = RGB(204, 206, 219);
+ }
+ }
+ }
+ *pResult = CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT; // 订阅绘制结束通知
+
+ break;
+
+
+ case CDDS_ITEMPOSTPAINT: // 项绘制结束通知
+ unt = GetIndent();
+ hItem = (HTREEITEM)lpnmcd->nmcd.dwItemSpec;
+ auto iter = m_items.find(hItem);
+ if (iter != m_items.end()) {
+ CRect button_rect = pNMCD->rc;
+ button_rect.right = button_rect.left + unt + 5;
+ int off = unt * iter->second;
+ button_rect.OffsetRect(off, 0);
+ DrawItemButton(hItem, pNMCD->hdc, &button_rect);
+
+ // 是否有小圆点
+ CRect rcItem = pNMCD->rc;
+ Gdiplus::Graphics graphics(pNMCD->hdc);
+ graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+ if (m_badges.find(hItem) != m_badges.end()) {
+ BADGE& badge = m_badges[hItem];
+ if (badge.type == BADGE_DOT) {
+ Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(badge.badgeBackground), GetGValue(badge.badgeBackground), GetBValue(badge.badgeBackground)));
+ int x = rcItem.right - 18 - BADGE_DOT_WIDTH;
+ int y = rcItem.top + (rcItem.Height() - BADGE_DOT_WIDTH) / 2;
+ graphics.FillEllipse(&brush, x, y, BADGE_DOT_WIDTH, BADGE_DOT_WIDTH);
+ }
+ else if (badge.type == BADGE_NUMBER) {
+ Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(badge.badgeBackground), GetGValue(badge.badgeBackground), GetBValue(badge.badgeBackground)));
+ int x = rcItem.right - 18 - BADGE_NUMBER_WIDTH;
+ int y = rcItem.top + (rcItem.Height() - BADGE_NUMBER_WIDTH) / 2;
+ graphics.FillEllipse(&brush, x, y, BADGE_NUMBER_WIDTH, BADGE_NUMBER_WIDTH);
+ RECT rcBadge;
+ rcBadge.left = x;
+ rcBadge.right = rcBadge.left + BADGE_NUMBER_WIDTH;
+ rcBadge.top = y;
+ rcBadge.bottom = rcBadge.top + BADGE_NUMBER_WIDTH;
+ ::SetTextColor(pNMCD->hdc, badge.badgeForeground);
+ char szBuffer[32];
+ sprintf_s(szBuffer, 32, "%d%s", min(badge.number, 9), badge.number > 9 ? "+" : "");
+ DrawText(pNMCD->hdc, szBuffer, (int)strlen(szBuffer), &rcBadge, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ }
+ }
+
+ *pResult = CDRF_SKIPDEFAULT;
+ }
+
+ break;
+ }
+}
+
+void CApredTreeCtrl2::DrawItemButton(HTREEITEM hItem, HDC hDC, CRect* pRect)
+{
+ if (!ItemHasChildren(hItem)) {
+ return;
+ }
+
+
+ // 按钮要刷一下
+ ::FillRect(hDC, pRect, GetItemBkBrush(hItem));
+ if ((GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED) == TVIS_EXPANDED) {
+ int nBottomOffset = (pRect->Height() - EXPANDED_WIDE) / 2;
+ POINT pt[3];
+ pt[0].x = pRect->right - ROFFSET - EXPANDED_WIDE;
+ pt[0].y = pRect->bottom - nBottomOffset;
+ pt[1].x = pRect->right - ROFFSET;
+ pt[1].y = pRect->bottom - nBottomOffset;
+ pt[2].x = pRect->right - ROFFSET;
+ pt[2].y = pRect->bottom - nBottomOffset - EXPANDED_WIDE;
+
+ HBRUSH hBrush = GetItemBtnBrush(hItem);
+ HPEN hPen = GetItemBtnPen(hItem);
+ HBRUSH hOldBrush = (HBRUSH)::SelectObject(hDC, hBrush);
+ HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
+ ::Polygon(hDC, pt, 3);
+ ::SelectObject(hDC, hOldBrush);
+ ::SelectObject(hDC, hOldPen);
+ ::DeleteObject(hBrush);
+ ::DeleteObject(hPen);
+ }
+ else {
+ int nBottomOffset = (pRect->Height() - WIDE) / 2;
+ POINT pt[3];
+ pt[0].x = pRect->right - ROFFSET - WIDE2;
+ pt[0].y = pRect->bottom - nBottomOffset - WIDE;
+ pt[1].x = pRect->right - ROFFSET - WIDE2;
+ pt[1].y = pRect->bottom - nBottomOffset;
+ pt[2].x = pRect->right - ROFFSET;
+ pt[2].y = pRect->bottom - nBottomOffset - WIDE2;
+
+ HBRUSH hBrush = GetItemBtnBrush(hItem);
+ HPEN hPen = GetItemBtnPen(hItem);
+ HBRUSH hOldBrush = (HBRUSH)::SelectObject(hDC, hBrush);
+ HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
+ ::Polygon(hDC, pt, 3);
+ ::SelectObject(hDC, hOldBrush);
+ ::SelectObject(hDC, hOldPen);
+ ::DeleteObject(hBrush);
+ ::DeleteObject(hPen);
+ }
+}
+
+COLORREF CApredTreeCtrl2::SetBkColor(COLORREF crColor)
+{
+ if (m_hBrushItem[0] != NULL) {
+ ::DeleteObject(m_hBrushItem[0]);
+ }
+ m_hBrushItem[0] = CreateSolidBrush(crColor);
+
+ return CTreeCtrl::SetBkColor(crColor);
+}
+
+int CApredTreeCtrl2::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ m_crItemBk[0] = GetBkColor();
+ m_crItemBk[1] = GetSysColor(COLOR_HIGHLIGHT);
+ m_hBrushItem[0] = CreateSolidBrush(m_crItemBk[0]);
+ m_hBrushItem[1] = CreateSolidBrush(m_crItemBk[1]);
+ m_hBrushItem[2] = CreateSolidBrush(m_crItemBk[2]);
+
+ return 0;
+}
+
+HBRUSH CApredTreeCtrl2::GetItemBkBrush(HTREEITEM hItem)
+{
+ BOOL bSelected = (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED) == TVIS_SELECTED;
+ BOOL bHilited = (GetItemState(hItem, TVIS_DROPHILITED) & TVIS_DROPHILITED) == TVIS_DROPHILITED;;
+ HTREEITEM hClickedItem = GetDropHilightItem();
+
+
+ if (bHilited) {
+ return m_hBrushItem[1];
+ }
+
+ if (!bSelected) {
+ return m_hBrushItem[0];
+ }
+
+ if (GetFocus() == this) {
+ if (hClickedItem == NULL) {
+ return m_hBrushItem[1];
+ }
+ else {
+ return m_hBrushItem[0];
+ }
+ }
+
+
+ return m_hBrushItem[2];
+}
+
+HBRUSH CApredTreeCtrl2::GetItemBtnBrush(HTREEITEM hItem)
+{
+ BOOL bExpanded = (GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED) == TVIS_EXPANDED;
+ BOOL bSelected = (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED) == TVIS_SELECTED;
+ BOOL bHilited = (GetItemState(hItem, TVIS_DROPHILITED) & TVIS_DROPHILITED) == TVIS_DROPHILITED;;
+ HTREEITEM hClickedItem = GetDropHilightItem();
+
+
+ // 展开时实心三角
+ if (bExpanded) {
+ if (bHilited) {
+ return CreateSolidBrush(m_crItemBtn[1]);
+ }
+
+ if (!bSelected) {
+ return CreateSolidBrush(m_crItemBtn[0]);
+ }
+
+ if (GetFocus() == this && hClickedItem == NULL) {
+ return CreateSolidBrush(m_crItemBtn[1]);
+ }
+
+ return CreateSolidBrush(m_crItemBtn[0]);
+ }
+ else {
+ // 收起时空心三角
+ if (bHilited) {
+ return CreateSolidBrush(m_crItemBk[1]);
+ }
+
+ if (!bSelected) {
+ return CreateSolidBrush(m_crItemBk[0]);
+ }
+
+ if (GetFocus() == this && hClickedItem == NULL) {
+ return CreateSolidBrush(m_crItemBk[1]);
+ }
+
+ return CreateSolidBrush(m_crItemBk[2]);
+ }
+}
+
+HPEN CApredTreeCtrl2::GetItemBtnPen(HTREEITEM hItem)
+{
+ BOOL bExpanded = (GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED) == TVIS_EXPANDED;
+ BOOL bSelected = (GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED) == TVIS_SELECTED;
+ BOOL bHilited = (GetItemState(hItem, TVIS_DROPHILITED) & TVIS_DROPHILITED) == TVIS_DROPHILITED;;
+ HTREEITEM hClickedItem = GetDropHilightItem();
+
+
+ // 展开时实心三角
+ if (bExpanded) {
+ if (bHilited) {
+ return CreatePen(PS_SOLID, 1, m_crItemBtn[1]);
+ }
+
+ if (!bSelected) {
+ return CreatePen(PS_SOLID, 1, m_crItemBtn[0]);
+ }
+
+ if (GetFocus() == this && hClickedItem == NULL) {
+ return CreatePen(PS_SOLID, 1, m_crItemBtn[1]);
+ }
+
+ return CreatePen(PS_SOLID, 1, m_crItemBtn[0]);
+ }
+ else {
+ // 收起时空心三角
+ if (bHilited) {
+ return CreatePen(PS_SOLID, 1, m_crItemBtn[1]);
+ }
+
+ if (!bSelected) {
+ return CreatePen(PS_SOLID, 1, m_crItemBtn[0]);
+ }
+
+ if (GetFocus() == this && hClickedItem == NULL) {
+ return CreatePen(PS_SOLID, 1, m_crItemBtn[1]);
+ }
+
+ return CreatePen(PS_SOLID, 1, m_crItemBtn[0]);
+ }
+}
+
+void CApredTreeCtrl2::PreSubclassWindow()
+{
+ m_crItemBk[0] = GetBkColor();
+ m_crItemBk[1] = GetSysColor(COLOR_HIGHLIGHT);
+ m_hBrushItem[0] = CreateSolidBrush(m_crItemBk[0]);
+ m_hBrushItem[1] = CreateSolidBrush(m_crItemBk[1]);
+ m_hBrushItem[2] = CreateSolidBrush(m_crItemBk[2]);
+
+ CTreeCtrl::PreSubclassWindow();
+}
+
+void CApredTreeCtrl2::SetItemBadge(HTREEITEM hItem, COLORREF badgeBackground, COLORREF badgeForeground)
+{
+ if (m_badges.find(hItem) == m_badges.end()) {
+ BADGE badge;
+ badge.badgeBackground = badgeBackground;
+ badge.badgeForeground = badgeForeground;
+ badge.type = BADGE_HIDE;
+ m_badges[hItem] = badge;
+ }
+ else {
+ BADGE& badge = m_badges[hItem];
+ badge.badgeBackground = badgeBackground;
+ badge.badgeForeground = badgeForeground;
+ badge.type = BADGE_HIDE;
+ }
+}
+
+void CApredTreeCtrl2::ShowItemBadgeNumber(HTREEITEM hItem, int number)
+{
+ if (m_badges.find(hItem) == m_badges.end()) {
+ return;
+ }
+
+ BADGE& badge = m_badges[hItem];
+ badge.type = BADGE_NUMBER;
+ badge.number = number;
+ InvalidateRect(NULL, TRUE);
+}
+
+void CApredTreeCtrl2::ShowItemBadgeDotMode(HTREEITEM hItem)
+{
+ if (m_badges.find(hItem) == m_badges.end()) {
+ return;
+ }
+
+ BADGE& badge = m_badges[hItem];
+ if (badge.type != BADGE_DOT) {
+ badge.type = BADGE_DOT;
+ InvalidateRect(NULL, TRUE);
+ }
+}
+
+void CApredTreeCtrl2::HideItemBadge(HTREEITEM hItem)
+{
+ if (m_badges.find(hItem) == m_badges.end()) {
+ return;
+ }
+
+ BADGE& badge = m_badges[hItem];
+ if (badge.type != BADGE_HIDE) {
+ badge.type = BADGE_HIDE;
+ InvalidateRect(NULL, TRUE);
+ }
+}
diff --git a/SourceCode/Bond/Servo/ApredTreeCtrl2.h b/SourceCode/Bond/Servo/ApredTreeCtrl2.h
new file mode 100644
index 0000000..68f5310
--- /dev/null
+++ b/SourceCode/Bond/Servo/ApredTreeCtrl2.h
@@ -0,0 +1,53 @@
+#pragma once
+#include <afxcmn.h>
+#include <map>
+
+class CApredTreeCtrl2 :
+ public CTreeCtrl
+{
+public:
+ typedef struct tagBADGE
+ {
+ HTREEITEM hTreeItem;
+ COLORREF badgeBackground;
+ COLORREF badgeForeground;
+ int type; /* 0: 无,不显示*/
+ int number;
+ } BADGE;
+
+
+ DECLARE_DYNAMIC(CApredTreeCtrl2)
+
+public:
+ CApredTreeCtrl2();
+ virtual ~CApredTreeCtrl2();
+
+
+public:
+ virtual COLORREF SetBkColor(COLORREF crColor);
+ void SetItemBadge(HTREEITEM hItem, COLORREF badgeBackground, COLORREF badgeForeground);
+ void ShowItemBadgeNumber(HTREEITEM hItem, int number);
+ void ShowItemBadgeDotMode(HTREEITEM hItem);
+ void HideItemBadge(HTREEITEM hItem);
+
+private:
+ HBRUSH GetItemBkBrush(HTREEITEM hItem);
+ HBRUSH GetItemBtnBrush(HTREEITEM hItem);
+ HPEN GetItemBtnPen(HTREEITEM hItem);
+ void DrawItemButton(HTREEITEM hItem, HDC hDC, CRect* pRect);
+
+
+private:
+ std::map<HTREEITEM, BADGE> m_badges;
+ std::map<HTREEITEM, int> m_items;
+ HBRUSH m_hBrushItem[3];
+ COLORREF m_crItemBk[3];
+ COLORREF m_crItemBtn[3];
+
+public:
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ virtual void PreSubclassWindow();
+};
+
diff --git a/SourceCode/Bond/Servo/CAttribute.cpp b/SourceCode/Bond/Servo/CAttribute.cpp
new file mode 100644
index 0000000..468ebf2
--- /dev/null
+++ b/SourceCode/Bond/Servo/CAttribute.cpp
@@ -0,0 +1,36 @@
+#include "stdafx.h"
+#include "CAttribute.h"
+
+namespace SERVO {
+ CAttribute::CAttribute()
+ {
+
+ }
+
+ CAttribute::CAttribute(const char* pszName, const char* pszValue, const char* pszDescription)
+ {
+ m_strName = pszName;
+ m_strValue = pszValue;
+ m_strDescription = pszDescription;
+ }
+
+ CAttribute::~CAttribute()
+ {
+
+ }
+
+ std::string& CAttribute::getName()
+ {
+ return m_strName;
+ }
+
+ std::string& CAttribute::getValue()
+ {
+ return m_strValue;
+ }
+
+ std::string& CAttribute::getDescription()
+ {
+ return m_strDescription;
+ }
+}
diff --git a/SourceCode/Bond/Servo/CAttribute.h b/SourceCode/Bond/Servo/CAttribute.h
new file mode 100644
index 0000000..5c96b72
--- /dev/null
+++ b/SourceCode/Bond/Servo/CAttribute.h
@@ -0,0 +1,23 @@
+#pragma once
+
+
+namespace SERVO {
+ class CAttribute
+ {
+ public:
+ CAttribute();
+ CAttribute(const char* pszName, const char* pszValue, const char* pszDescription);
+ ~CAttribute();
+
+ public:
+ std::string& getName();
+ std::string& getValue();
+ std::string& getDescription();
+
+ private:
+ std::string m_strName;
+ std::string m_strValue;
+ std::string m_strDescription;
+ };
+}
+
diff --git a/SourceCode/Bond/Servo/CAttributeVector.cpp b/SourceCode/Bond/Servo/CAttributeVector.cpp
new file mode 100644
index 0000000..6d9213a
--- /dev/null
+++ b/SourceCode/Bond/Servo/CAttributeVector.cpp
@@ -0,0 +1,47 @@
+#include "stdafx.h"
+#include "CAttributeVector.h"
+
+
+namespace SERVO {
+ CAttributeVector::CAttributeVector()
+ {
+
+ }
+
+ CAttributeVector::~CAttributeVector()
+ {
+ for (auto item : m_attributes) {
+ delete item;
+ }
+ m_attributes.clear();
+ }
+
+ void CAttributeVector::addAttribute(CAttribute* pAttribute)
+ {
+ m_attributes.push_back(pAttribute);
+ }
+
+ unsigned int CAttributeVector::size()
+ {
+ return m_attributes.size();
+ }
+
+ void CAttributeVector::clear()
+ {
+ for (auto item : m_attributes) {
+ delete item;
+ }
+ m_attributes.clear();
+ }
+
+ bool CAttributeVector::empty()
+ {
+ return m_attributes.empty();
+ }
+
+ CAttribute* CAttributeVector::getAttribute(unsigned int index)
+ {
+ ASSERT(index < m_attributes.size());
+ return m_attributes[index];
+ }
+}
diff --git a/SourceCode/Bond/Servo/CAttributeVector.h b/SourceCode/Bond/Servo/CAttributeVector.h
new file mode 100644
index 0000000..c3b9b34
--- /dev/null
+++ b/SourceCode/Bond/Servo/CAttributeVector.h
@@ -0,0 +1,24 @@
+#pragma once
+#include <vector>
+#include "CAttribute.h"
+
+
+namespace SERVO {
+ class CAttributeVector
+ {
+ public:
+ CAttributeVector();
+ ~CAttributeVector();
+
+ public:
+ void addAttribute(CAttribute* pAttribute);
+ void clear();
+ unsigned int size();
+ bool empty();
+ CAttribute* getAttribute(unsigned int index);
+
+ private:
+ std::vector<CAttribute*> m_attributes;
+ };
+}
+
diff --git a/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp b/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp
index 61f9245..141634c 100644
--- a/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp
+++ b/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp
@@ -23,9 +23,9 @@
#define LOG_DEBUG(msg)
#endif
-// 鍒濆鍖栭潤鎬佹垚鍛樺彉閲�
+// 初始化静态成员变量
std::unordered_map<int, std::string> CPerformanceMelsec::m_mapError = {
- // 鏉垮潡SDK閿欒鐮�
+ // 板块SDK错误码
{0, "No error, communication successful."},
{1, "Driver not started. The driver is not running."},
{2, "Timeout error (board response error). Request not completed within timeout."},
@@ -118,7 +118,7 @@
{-28634, "Hardware self-diagnosis error."},
{-28636, "Hardware self-diagnosis error."},
- // 鑷畾涔夐敊璇爜
+ // 自定义错误码
{ERROR_CODE_UNKNOWN, "Error: Unknown error code."},
{ERROR_CODE_NOT_CONNECTED, "Error: Not connected to the device."},
{ERROR_CODE_INVALID_PARAM, "Error: Invalid parameter."},
@@ -137,26 +137,26 @@
m_bConnected.store(false);
}
-// 鏋愭瀯鍑芥暟
+// 析构函数
CPerformanceMelsec::~CPerformanceMelsec() {
Disconnect();
}
-// 鑾峰彇鏈�杩戠殑閿欒淇℃伅
+// 获取最近的错误信息
std::string CPerformanceMelsec::GetLastError() const {
return m_strLastError;
}
-// 淇濆瓨閿欒淇℃伅
+// 保存错误信息
bool CPerformanceMelsec::SaveErrorInfoToFile(const std::string& filename) {
- // 鎵撳紑鏂囦欢
+ // 打开文件
std::ofstream file(filename);
if (!file.is_open()) {
std::cerr << "Failed to open file for saving: " << filename << std::endl;
return false;
}
- // 閬嶅巻闈欐�佹垚鍛樺彉閲� m_mapError 骞跺皢姣忎釜閿欒淇℃伅鍐欏叆鏂囦欢
+ // 遍历静态成员变量 m_mapError 并将每个错误信息写入文件
for (const auto& entry : m_mapError) {
const int nCode = entry.first;
const std::string& strMessage = entry.second;
@@ -167,7 +167,7 @@
return true;
}
-// 鍔犺浇閿欒淇℃伅
+// 加载错误信息
bool CPerformanceMelsec::LoadErrorInfoFromFile(const std::string& filename) {
std::ifstream inFile(filename);
if (!inFile.is_open()) {
@@ -183,7 +183,7 @@
std::string strToken;
std::string strMessage;
- // 浣跨敤鍒嗛殧绗� "|" 瑙f瀽姣忎竴琛�
+ // 使用分隔符 "|" 解析每一行
if (std::getline(iss, strToken, '|')) {
nCode = std::stoi(strToken);
}
@@ -200,7 +200,7 @@
return true;
}
-// 杩炴帴鍒癙LC
+// 连接到PLC
int CPerformanceMelsec::Connect(const short nChannel, const short nMode) {
std::lock_guard<std::mutex> lock(m_mtx);
@@ -214,7 +214,7 @@
return ERROR_CODE_INVALID_PARAM;
}
- // 杩炴帴PLC锛屾樉寮忕被鍨嬭浆鎹互鍖归厤 mdOpen 鐨勭鍚�
+ // 连接PLC,显式类型转换以匹配 mdOpen 的签名
const short nRet = mdOpen(nChannel, nMode, &m_nPath);
if (nRet == 0) {
m_bConnected.store(true);
@@ -228,7 +228,7 @@
return nRet;
}
-// 鏂紑杩炴帴
+// 断开连接
int CPerformanceMelsec::Disconnect() {
std::lock_guard<std::mutex> lock(m_mtx);
@@ -245,7 +245,7 @@
return nRet;
}
-// 鍙紪绋嬫帶鍒跺櫒杞厓浠朵俊鎭〃鐨勫垵濮嬪寲
+// 可编程控制器软元件信息表的初始化
int CPerformanceMelsec::InitializeController() {
std::lock_guard<std::mutex> lock(m_mtx);
@@ -263,14 +263,14 @@
return nRet;
}
-// 鑾峰彇鐗堟湰淇℃伅
+// 获取版本信息
int CPerformanceMelsec::GetBoardVersion(BoardVersion& version) {
if (!m_bConnected.load()) {
UpdateLastError(ERROR_CODE_NOT_CONNECTED);
return ERROR_CODE_NOT_CONNECTED;
}
- // 鑾峰彇鐗堟湰淇℃伅
+ // 获取版本信息
short buf[32] = { 0 };
const short nRet = mdBdVerRead(m_nPath, buf);
if (nRet != 0) {
@@ -279,7 +279,7 @@
return nRet;
}
- // 濉厖鐗堟湰淇℃伅鍒扮粨鏋勪綋
+ // 填充版本信息到结构体
version.fixedValue[0] = static_cast<char>(buf[0] & 0xFF);
version.fixedValue[1] = static_cast<char>((buf[0] >> 8) & 0xFF);
@@ -310,16 +310,16 @@
return nRet;
}
-// 璇诲彇鐩爣绔欑偣CPU绫诲瀷
+// 读取目标站点CPU类型
int CPerformanceMelsec::ReadCPUCode(const StationIdentifier& station, short& nCPUCode) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
int nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 纭繚绾跨▼瀹夊叏鐨勬渶灏忛攣瀹氳寖鍥�
+ // 确保线程安全的最小锁定范围
{
nCPUCode = 0;
std::lock_guard<std::mutex> lock(m_mtx);
@@ -334,15 +334,15 @@
return nRet;
}
-// 鏉挎ā寮忚缃�
+// 板模式设置
int CPerformanceMelsec::SetBoardMode(const short nMode) {
- // 妫�鏌ユ槸鍚﹀凡缁忚繛鎺�
+ // 检查是否已经连接
if (!m_bConnected.load()) {
UpdateLastError(ERROR_CODE_NOT_CONNECTED);
return ERROR_CODE_NOT_CONNECTED;
}
- // 纭繚绾跨▼瀹夊叏鐨勬渶灏忛攣瀹氳寖鍥�
+ // 确保线程安全的最小锁定范围
short nRet = 0;
{
std::lock_guard<std::mutex> lock(m_mtx);
@@ -357,9 +357,9 @@
return nRet;
}
-// 鑾峰彇鏉挎ā寮�
+// 获取板模式
int CPerformanceMelsec::GetBoardMode(short& nMode) {
- // 妫�鏌ユ槸鍚﹀凡缁忚繛鎺�
+ // 检查是否已经连接
if (!m_bConnected.load()) {
UpdateLastError(ERROR_CODE_NOT_CONNECTED);
return ERROR_CODE_NOT_CONNECTED;
@@ -381,7 +381,7 @@
return 0;
}
-// 鏉垮浣�
+// 板复位
int CPerformanceMelsec::BoardReset() {
std::lock_guard<std::mutex> lock(m_mtx);
if (!m_bConnected.load()) {
@@ -398,7 +398,7 @@
return nRet;
}
-// 鏉縇ED璇诲彇
+// 板LED读取
int CPerformanceMelsec::ReadBoardLed(std::vector<short>& vecLedBuffer) {
std::lock_guard<std::mutex> lock(m_mtx);
if (!m_bConnected.load()) {
@@ -406,11 +406,11 @@
return ERROR_CODE_NOT_CONNECTED;
}
- // 娓呯┖ LED 缂撳啿鍖�
+ // 清空 LED 缓冲区
vecLedBuffer.clear();
vecLedBuffer.resize(16, 0);
- // 璋冪敤 SDK 鍑芥暟璇诲彇 LED 鏁版嵁
+ // 调用 SDK 函数读取 LED 数据
const short nRet = mdBdLedRead(m_nPath, vecLedBuffer.data());
if (nRet != 0) {
UpdateLastError(ERROR_CODE_NOT_CONNECTED);
@@ -421,7 +421,7 @@
return nRet;
}
-// 鑾峰彇鏉跨姸鎬�
+// 获取板状态
int CPerformanceMelsec::GetBoardStatus(BoardStatus& status) {
std::lock_guard<std::mutex> lock(m_mtx);
if (!m_bConnected) {
@@ -436,25 +436,25 @@
LOG_ERROR(m_strLastError);
}
- // 灏� buf 鏄犲皠鍒扮粨鏋勪綋
+ // 将 buf 映射到结构体
status = BoardStatus::fromBuffer(buf);
return 0;
}
-// 閫氱敤璇绘暟鎹�
+// 通用读数据
int CPerformanceMelsec::ReadData(const StationIdentifier& station, const short nDevType, const short nDevNo, short nSize, std::vector<short>& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
int nRet = ValidateStationAndSize(station, nSize);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 鍒濆鍖栬鍙栫紦鍐插尯
+ // 初始化读取缓冲区
vecData.clear();
vecData.resize(nSize, 0);
- // 纭繚绾跨▼瀹夊叏鐨勬渶灏忛攣瀹氳寖鍥�
+ // 确保线程安全的最小锁定范围
{
std::lock_guard<std::mutex> lock(m_mtx);
short* pData = vecData.data();
@@ -468,15 +468,15 @@
}
if (nRet != 0) {
- vecData.clear(); // 濡傛灉璇诲彇澶辫触锛屾竻绌虹紦鍐插尯
+ vecData.clear(); // 如果读取失败,清空缓冲区
}
return nRet;
}
-// 璇诲彇浣嶆暟鎹�
+// 读取位数据
int CPerformanceMelsec::ReadBitData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const short nBitCount, BitContainer& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
int nRet = ValidateStationAndSize(station, nBitCount);
if (nRet != 0) {
UpdateLastError(nRet);
@@ -490,7 +490,7 @@
}
const short nDevType = CalculateDeviceType(station, enDevType);
- const auto nSize = static_cast<short>((static_cast<int>(nBitCount) + 15) / 16); // 璁$畻闇�瑕佽鍙栫殑瀛楁暟閲忥紙鍚戜笂鍙栨暣锛�
+ const auto nSize = static_cast<short>((static_cast<int>(nBitCount) + 15) / 16); // 计算需要读取的字数量(向上取整)
std::vector<short> vecTempBuffer(nSize, 0);
nRet = ReadData(station, nDevType, nDevNo, nSize, vecTempBuffer);
@@ -498,15 +498,15 @@
if (nRet == 0) {
vecData.clear();
- // 灏嗗瓧鏁版嵁瑙f瀽涓轰綅鏁版嵁
+ // 将字数据解析为位数据
for (short nIdx = 0; nIdx < nSize; ++nIdx) {
const short nCurrentValue = vecTempBuffer[nIdx];
- // 閬嶅巻褰撳墠 short 涓殑姣忎竴浣�
+ // 遍历当前 short 中的每一位
for (int bitIdx = 0; bitIdx < 16; ++bitIdx) {
bool bBit = (nCurrentValue & (1 << bitIdx)) != 0;
vecData.push_back(bBit);
if (vecData.size() >= nBitCount) {
- return nRet; // 濡傛灉宸茬粡璇诲彇瀹屾墍闇�鐨勪綅鏁帮紝鎻愬墠閫�鍑�
+ return nRet; // 如果已经读取完所需的位数,提前退出
}
}
}
@@ -515,9 +515,9 @@
return nRet;
}
-// 璇诲彇瀛楁暟鎹�
+// 读取字数据
int CPerformanceMelsec::ReadWordData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const short nWordCount, WordContainer& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
int nRet = ValidateStationAndSize(station, nWordCount);
if (nRet != 0) {
UpdateLastError(nRet);
@@ -536,44 +536,44 @@
return nRet;
}
-// 璇诲彇鍙屽瓧鏁版嵁
+// 读取双字数据
int CPerformanceMelsec::ReadDWordData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const short nDWordCount, DWordContainer& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
int nRet = ValidateStationAndSize(station, nDWordCount);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- const auto nSize = static_cast<short>(nDWordCount * 2); // 姣忎釜鍙屽瓧鍗犱袱涓瓧锛堟瘡涓弻瀛楀崰 4 瀛楄妭锛�
+ const auto nSize = static_cast<short>(nDWordCount * 2); // 每个双字占两个字(每个双字占 4 字节)
const short nDevType = CalculateDeviceType(station, enDevType);
std::vector<short> vecTempBuffer(nSize, 0);
nRet = ReadData(station, nDevType, nDevNo, nSize, vecTempBuffer);
if (nRet == 0) {
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
ConvertShortToUint32(vecTempBuffer, vecData);
}
return nRet;
}
-// 閫氱敤鍐欐暟鎹�
+// 通用写数据
int CPerformanceMelsec::WriteData(const StationIdentifier& station, const short nDevType, const short nDevNo, short nSize, short* pData) {
- // 楠岃瘉绔欑偣鍙傛暟
+ // 验证站点参数
int nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 鏁版嵁鏈夋晥鎬�
+ // 数据有效性
if (nSize < 0 || pData == nullptr) {
UpdateLastError(ERROR_CODE_INVALID_PARAM);
return ERROR_CODE_INVALID_PARAM;
}
- // 纭繚绾跨▼瀹夊叏鐨勬渶灏忛攣瀹氳寖鍥�
+ // 确保线程安全的最小锁定范围
{
std::lock_guard<std::mutex> lock(m_mtx);
nSize *= sizeof(short);
@@ -588,9 +588,9 @@
return nRet;
}
-// 鍐欎綅鏁版嵁
+// 写位数据
int CPerformanceMelsec::WriteBitData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const BitContainer& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
int nRet = ValidateStationAndData(station, vecData);
if (nRet != 0) {
UpdateLastError(nRet);
@@ -604,16 +604,16 @@
}
const short nDevType = CalculateDeviceType(station, enDevType);
- const auto nSize = static_cast<short>((static_cast<int>(vecData.size()) + 15) / 16); // 璁$畻闇�瑕佸啓鍏ョ殑瀛楁暟閲忥紙鍚戜笂鍙栨暣锛�
+ const auto nSize = static_cast<short>((static_cast<int>(vecData.size()) + 15) / 16); // 计算需要写入的字数量(向上取整)
- // 鍑嗗涓存椂缂撳啿鍖烘潵瀛樺偍杞崲鍚庣殑 16 浣嶆暟鎹�
+ // 准备临时缓冲区来存储转换后的 16 位数据
std::vector<short> vecTempBuffer(nSize, 0);
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
- // 灏嗕綅鏁版嵁鎸夊瓧鎵撳寘鍒颁复鏃剁紦鍐插尯
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
+ // 将位数据按字打包到临时缓冲区
for (int i = 0; i < vecData.size(); ++i) {
if (vecData[i]) {
- // 浣跨敤 & 0xFFFF 淇濊瘉涓嶄細瓒呰繃 16 浣嶏紝闃叉婧㈠嚭
+ // 使用 & 0xFFFF 保证不会超过 16 位,防止溢出
vecTempBuffer[i / 16] |= static_cast<short>((1 << (i % 16)) & 0xFFFF);
}
}
@@ -622,16 +622,16 @@
return WriteData(station, nDevType, nDevNo, nSize, vecTempBuffer.data());
}
-// 鍐欏瓧鏁版嵁
+// 写字数据
int CPerformanceMelsec::WriteWordData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const WordContainer& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
const int nRet = ValidateStationAndData(station, vecData);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 璁$畻闇�瑕佸啓鍏ョ殑瀛楄妭鏁帮紙姣忎釜瀛楀崰 2 瀛楄妭锛�
+ // 计算需要写入的字节数(每个字占 2 字节)
const short nDevType = CalculateDeviceType(station, enDevType);
const auto nSize = static_cast<short>(vecData.size());
const auto pData = const_cast<short*>(reinterpret_cast<const short*>(vecData.data()));
@@ -639,30 +639,30 @@
return WriteData(station, nDevType, nDevNo, nSize, pData);
}
-// 鍐欏弻瀛楁暟鎹�
+// 写双字数据
int CPerformanceMelsec::WriteDWordData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const DWordContainer& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
const int nRet = ValidateStationAndData(station, vecData);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 璁$畻闇�瑕佸啓鍏ョ殑瀛楄妭鏁帮紙姣忎釜鍙屽瓧鍗� 4 瀛楄妭锛�
+ // 计算需要写入的字节数(每个双字占 4 字节)
const short nDevType = CalculateDeviceType(station, enDevType);
const auto nSize = static_cast<short>(vecData.size() * sizeof(short));
std::vector<short> vecBuffer(nSize, 0);
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
ConvertUint32ToShort(vecData, vecBuffer);
}
return WriteData(station, nDevType, nDevNo, nSize, vecBuffer.data());
}
-// 鎵╁睍璇绘暟鎹�
+// 扩展读数据
long CPerformanceMelsec::ReadDataEx(const StationIdentifier& station, long nDevType, long nDevNo, long nSize, std::vector<char>& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜岃鍙栧ぇ灏忔槸鍚︽湁鏁�
+ // 验证站点参数和读取大小是否有效
long nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
@@ -678,7 +678,7 @@
std::vector<short> vecBuffer(nSize / 2, 0);
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
nRet = mdReceiveEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo, &nSize, vecBuffer.data());
}
@@ -687,7 +687,7 @@
LOG_ERROR(m_strLastError);
}
else {
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
vecData.resize(nSize);
ConvertShortToChar(vecBuffer, vecData);
}
@@ -695,27 +695,27 @@
return 0;
}
-// 鎵╁睍鍐欐暟鎹�
+// 扩展写数据
long CPerformanceMelsec::WriteDataEx(const StationIdentifier& station, long nDevType, long nDevNo, const std::vector<char>& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
long nRet = ValidateStationAndData(station, vecData);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 灏� vecData 杞崲涓� short 绫诲瀷鐨勭紦鍐插尯
+ // 将 vecData 转换为 short 类型的缓冲区
long nSize = static_cast<long>(vecData.size());
nSize = nSize % 2 != 0 ? nSize + 1 : nSize;
std::vector<short> vecBuffer(nSize / 2, 0);
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
ConvertCharToShort(vecData, vecBuffer);
nRet = mdSendEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo, &nSize, vecBuffer.data());
}
- // 閿欒澶勭悊鍜屾棩蹇楄褰�
+ // 错误处理和日志记录
if (nRet != 0) {
UpdateLastError(nRet);
LOG_ERROR(m_strLastError);
@@ -724,7 +724,7 @@
return nRet;
}
-// 鎵╁睍杞厓浠堕殢鏈鸿鍙�
+// 扩展软元件随机读取
long CPerformanceMelsec::ReadRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, std::vector<char>& vecData) {
if (vecSoftElements.empty()) {
UpdateLastError(ERROR_INVALID_PARAMETER);
@@ -732,48 +732,48 @@
return ERROR_INVALID_PARAMETER;
}
- // 鍑嗗 dev 鏁版嵁
- std::vector<short> devBuffer(vecSoftElements.size() * 3 + 1, 0); // 姣忎釜杞厓浠堕渶瑕� 3 涓� short锛屽鍔犱竴涓鏁板櫒
- devBuffer[0] = static_cast<short>(vecSoftElements.size()); // 绗竴涓厓绱犳槸杞厓浠舵暟閲�
+ // 准备 dev 数据
+ std::vector<short> devBuffer(vecSoftElements.size() * 3 + 1, 0); // 每个软元件需要 3 个 short,外加一个计数器
+ devBuffer[0] = static_cast<short>(vecSoftElements.size()); // 第一个元素是软元件数量
for (size_t i = 0; i < vecSoftElements.size(); ++i) {
const SoftElement& element = vecSoftElements[i];
- devBuffer[i * 3 + 1] = element.nType; // 杞厓浠剁被鍨�
- devBuffer[i * 3 + 2] = static_cast<short>(element.nStartNo); // 璧峰杞厓浠剁紪鍙�
- devBuffer[i * 3 + 3] = element.nElementCount; // 鐐规暟
+ devBuffer[i * 3 + 1] = element.nType; // 软元件类型
+ devBuffer[i * 3 + 2] = static_cast<short>(element.nStartNo); // 起始软元件编号
+ devBuffer[i * 3 + 3] = element.nElementCount; // 点数
}
- // 璁$畻璇诲彇鏁版嵁鎵�闇�缂撳啿鍖哄ぇ灏�
+ // 计算读取数据所需缓冲区大小
long nBufferSize = 0;
for (const auto& element : vecSoftElements) {
- nBufferSize += element.nElementCount * 2; // 姣忎釜鐐瑰崰鐢� 2 涓瓧鑺�
+ nBufferSize += element.nElementCount * 2; // 每个点占用 2 个字节
}
- // 閿佷繚鎶ゅ強璋冪敤 mdRandREx
+ // 锁保护及调用 mdRandREx
long nRet = 0;
std::vector<short> vecBuffer(nBufferSize / 2, 0);
{
- std::lock_guard<std::mutex> lock(m_mtx); // 纭繚绾跨▼瀹夊叏
+ std::lock_guard<std::mutex> lock(m_mtx); // 确保线程安全
nRet = mdRandREx(m_nPath, station.nNetNo, station.nStNo, devBuffer.data(), vecBuffer.data(), nBufferSize);
}
- // 閿欒澶勭悊鍜屾棩蹇楄褰�
+ // 错误处理和日志记录
if (nRet != 0) {
UpdateLastError(nRet);
LOG_ERROR(m_strLastError);
return nRet;
}
- // 灏嗚鍙栧埌鐨� short 鏁版嵁杞崲涓� char 鏁版嵁
+ // 将读取到的 short 数据转换为 char 数据
vecData.resize(nBufferSize);
for (size_t i = 0; i < vecBuffer.size(); ++i) {
- vecData[i * 2] = static_cast<char>(vecBuffer[i] & 0xFF); // 浣庡瓧鑺�
- vecData[i * 2 + 1] = static_cast<char>((vecBuffer[i] >> 8) & 0xFF); // 楂樺瓧鑺�
+ vecData[i * 2] = static_cast<char>(vecBuffer[i] & 0xFF); // 低字节
+ vecData[i * 2 + 1] = static_cast<char>((vecBuffer[i] >> 8) & 0xFF); // 高字节
}
return nRet;
}
-// 鎵╁睍杞厓浠堕殢鏈哄啓鍏ワ紙鏀寔澶氫釜杞厓浠讹級
+// 扩展软元件随机写入(支持多个软元件)
long CPerformanceMelsec::WriteRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, const std::vector<char>& vecData) {
if (vecSoftElements.empty() || vecData.empty()) {
UpdateLastError(ERROR_INVALID_PARAMETER);
@@ -781,26 +781,26 @@
return ERROR_INVALID_PARAMETER;
}
- // 鍑嗗 dev 鏁版嵁
- std::vector<long> devBuffer(vecSoftElements.size() * 3 + 1, 0); // 姣忎釜杞厓浠堕渶瑕� 3 涓� long锛屽鍔犱竴涓鏁板櫒
- devBuffer[0] = static_cast<long>(vecSoftElements.size()); // 绗竴涓厓绱犳槸杞厓浠舵暟閲�
+ // 准备 dev 数据
+ std::vector<long> devBuffer(vecSoftElements.size() * 3 + 1, 0); // 每个软元件需要 3 个 long,外加一个计数器
+ devBuffer[0] = static_cast<long>(vecSoftElements.size()); // 第一个元素是软元件数量
for (size_t i = 0; i < vecSoftElements.size(); ++i) {
const SoftElement& element = vecSoftElements[i];
- devBuffer[i * 3 + 1] = static_cast<long>(element.nType); // 杞厓浠剁被鍨�
- devBuffer[i * 3 + 2] = element.nStartNo; // 璧峰杞厓浠剁紪鍙凤紙宸茬粡鏄� long 绫诲瀷锛屾棤闇�杞崲锛�
- devBuffer[i * 3 + 3] = static_cast<long>(element.nElementCount); // 鐐规暟
+ devBuffer[i * 3 + 1] = static_cast<long>(element.nType); // 软元件类型
+ devBuffer[i * 3 + 2] = element.nStartNo; // 起始软元件编号(已经是 long 类型,无需转换)
+ devBuffer[i * 3 + 3] = static_cast<long>(element.nElementCount); // 点数
}
- // 閿佷繚鎶ゅ強璋冪敤 mdRandWEx
+ // 锁保护及调用 mdRandWEx
long nRet = 0;
std::vector<short> vecBuffer(vecData.size() / 2, 0);
{
- std::lock_guard<std::mutex> lock(m_mtx); // 纭繚绾跨▼瀹夊叏
+ std::lock_guard<std::mutex> lock(m_mtx); // 确保线程安全
ConvertCharToShort(vecData, vecBuffer);
nRet = mdRandWEx(m_nPath, station.nNetNo, station.nStNo, devBuffer.data(), vecBuffer.data(), static_cast<long>(vecBuffer.size()));
}
- // 閿欒澶勭悊鍜屾棩蹇楄褰�
+ // 错误处理和日志记录
if (nRet != 0) {
UpdateLastError(nRet);
LOG_ERROR(m_strLastError);
@@ -809,9 +809,9 @@
return nRet;
}
-// 杩滅▼璁惧绔�/杩滅▼绔欑殑缂撳啿瀛樺偍鍣ㄨ鍙�
+// 远程设备站/远程站的缓冲存储器读取
long CPerformanceMelsec::ReadRemoteBuffer(const StationIdentifier& station, long nOffset, long nSize, std::vector<char>& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
int nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
@@ -826,37 +826,37 @@
long nActualSize = (nSize + 1) / 2;
std::vector<short> vecBuffer(nActualSize, 0);
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
nRet = mdRemBufReadEx(m_nPath, station.nNetNo, station.nStNo, nOffset, &nActualSize, vecBuffer.data());
}
if (nRet != 0) {
- UpdateLastError(nRet); // 鏇存柊閿欒鐮�
+ UpdateLastError(nRet); // 更新错误码
LOG_ERROR(m_strLastError);
}
else {
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
ConvertShortToChar(vecBuffer, vecData);
}
return nRet;
}
-// 杩滅▼璁惧绔�/杩滅▼绔欑殑缂撳啿瀛樺偍鍣ㄥ啓鍏�
+// 远程设备站/远程站的缓冲存储器写入
long CPerformanceMelsec::WriteRemoteBuffer(const StationIdentifier& station, long nOffset, const std::vector<char>& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
long nRet = ValidateStationAndData(station, vecData);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 灏� vecData 杞崲涓� short 绫诲瀷鐨勭紦鍐插尯
+ // 将 vecData 转换为 short 类型的缓冲区
long nSize = static_cast<long>(vecData.size());
std::vector<short> vecBuffer((nSize + 1) / 2, 0);
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
ConvertCharToShort(vecData, vecBuffer);
nRet = mdRemBufWriteEx(m_nPath, station.nNetNo, station.nStNo, nOffset, &nSize, vecBuffer.data());
}
@@ -869,7 +869,7 @@
return nRet;
}
-// 杩滅▼绔欑殑缂撳啿瀛樺偍鍣ㄨ鍙� 瀵硅薄绔橧P鍦板潃鎸囧畾
+// 远程站的缓冲存储器读取 对象站IP地址指定
long CPerformanceMelsec::ReadRemoteBufferByIp(const std::string& strIP, long nOffset, long nSize, std::vector<char>& vecData) {
uint32_t nAddress = 0;
if (nSize < 0 || !ConvertIpStringToUint32(strIP, nAddress)) {
@@ -877,14 +877,14 @@
return ERROR_CODE_INVALID_PARAM;
}
- // 灏嗙紦鍐插尯澶у皬璋冩暣涓� nSize
+ // 将缓冲区大小调整为 nSize
vecData.resize(nSize, 0);
- std::vector<short> vecBuffer((nSize + 1) / 2, 0); // 杞崲涓� short 绫诲瀷
+ std::vector<short> vecBuffer((nSize + 1) / 2, 0); // 转换为 short 类型
- // 璋冪敤搴曞眰 SDK
+ // 调用底层 SDK
long nRet = 0;
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
nRet = mdRemBufReadIPEx(m_nPath, static_cast<long>(nAddress), nOffset, &nSize, vecBuffer.data());
}
@@ -893,14 +893,14 @@
LOG_ERROR(m_strLastError);
}
else {
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏淇濇姢
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
ConvertShortToChar(vecBuffer, vecData);
}
return nRet;
}
-// 杩滅▼绔欑殑缂撳啿瀛樺偍鍣ㄥ啓鍏� 瀵硅薄绔橧P鍦板潃鎸囧畾
+// 远程站的缓冲存储器写入 对象站IP地址指定
long CPerformanceMelsec::WriteRemoteBufferByIp(const std::string& strIP, long nOffset, const std::vector<char>& vecData) {
uint32_t nAddress = 0;
if (vecData.empty() || !ConvertIpStringToUint32(strIP, nAddress)) {
@@ -908,13 +908,13 @@
return ERROR_CODE_INVALID_PARAM;
}
- // 杞崲 vecData 涓� short 绫诲瀷鐨勭紦鍐插尯
+ // 转换 vecData 为 short 类型的缓冲区
long nSize = static_cast<long>(vecData.size());
std::vector<short> vecBuffer((nSize + 1) / 2, 0);
long nRet = 0;
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全
ConvertCharToShort(vecData, vecBuffer);
nRet = mdRemBufWriteIPEx(m_nPath, static_cast<long>(nAddress), nOffset, &nSize, vecBuffer.data());
}
@@ -927,18 +927,18 @@
return nRet;
}
-// 璁剧疆(ON)瀵硅薄绔欑殑鎸囧畾浣嶈蒋鍏冧欢
+// 设置(ON)对象站的指定位软元件
int CPerformanceMelsec::SetBitDevice(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo) {
- // 楠岃瘉绔欑偣鍙傛暟
+ // 验证站点参数
int nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 纭繚绾跨▼瀹夊叏鐨勬渶灏忛攣瀹氳寖鍥�
+ // 确保线程安全的最小锁定范围
{
- std::lock_guard<std::mutex> lock(m_mtx); // 绾跨▼瀹夊叏
+ std::lock_guard<std::mutex> lock(m_mtx); // 线程安全
const short nDevType = CalculateDeviceType(station, enDevType);
nRet = mdDevSet(m_nPath, CombineStation(station), nDevType, nDevNo);
}
@@ -951,16 +951,16 @@
return nRet;
}
-// 澶嶄綅(OFF)瀵硅薄绔欑殑鎸囧畾浣嶈蒋鍏冧欢
+// 复位(OFF)对象站的指定位软元件
int CPerformanceMelsec::ResetBitDevice(const StationIdentifier& station, const DeviceType enDevType, const short enDevNo) {
- // 楠岃瘉绔欑偣鍙傛暟
+ // 验证站点参数
int nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 纭繚绾跨▼瀹夊叏鐨勬渶灏忛攣瀹氳寖鍥�
+ // 确保线程安全的最小锁定范围
{
std::lock_guard<std::mutex> lock(m_mtx);
const short nDevType = CalculateDeviceType(station, enDevType);
@@ -975,11 +975,11 @@
return nRet;
}
-// 鎵╁睍浣嶈蒋鍏冧欢璁剧疆
+// 扩展位软元件设置
long CPerformanceMelsec::SetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo) {
std::lock_guard<std::mutex> lock(m_mtx);
- // 妫�鏌ュ弬鏁版湁鏁堟��
+ // 检查参数有效性
long nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
@@ -995,11 +995,11 @@
return nRet;
}
-// 鎵╁睍浣嶈蒋鍏冧欢澶嶄綅
+// 扩展位软元件复位
long CPerformanceMelsec::ResetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo) {
std::lock_guard<std::mutex> lock(m_mtx);
- // 妫�鏌ュ弬鏁版湁鏁堟��
+ // 检查参数有效性
long nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
@@ -1015,23 +1015,23 @@
return nRet;
}
-// 鎵ц瀵硅薄绔欑殑CPU
+// 执行对象站的CPU
int CPerformanceMelsec::ControlCPU(const StationIdentifier& station, ControlCode enControlCode) {
- // 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+ // 验证站点参数和数据有效性
int nRet = ValidateStation(station);
if (nRet != 0) {
UpdateLastError(nRet);
return nRet;
}
- // 楠岃瘉鎺у埗鐮佹槸鍚﹀悎娉�
+ // 验证控制码是否合法
const auto nControlCode = static_cast<short>(enControlCode);
if (nControlCode < 0 || nControlCode > 2) {
- UpdateLastError(ERROR_CODE_INVALID_PARAM); // 鍙傛暟閿欒
+ UpdateLastError(ERROR_CODE_INVALID_PARAM); // 参数错误
return ERROR_CODE_INVALID_PARAM;
}
- // 纭繚绾跨▼瀹夊叏鐨勬渶灏忛攣瀹氳寖鍥�
+ // 确保线程安全的最小锁定范围
{
std::lock_guard<std::mutex> lock(m_mtx);
nRet = mdControl(m_nPath, CombineStation(station), nControlCode);
@@ -1045,7 +1045,7 @@
return nRet;
}
-// 浜嬩欢绛夊緟
+// 事件等待
int CPerformanceMelsec::WaitForBoardEvent(std::vector<short> vecEventNumbers, const int nTimeoutMs, EventDetails& details) {
std::lock_guard<std::mutex> lock(m_mtx);
@@ -1059,12 +1059,12 @@
return ERROR_CODE_INVALID_PARAM;
}
- // 绗� 0 涓厓绱犲瓨鍌ㄦ暟閲忥紝鏈�澶ф敮鎸� 64 涓簨浠�
+ // 第 0 个元素存储数量,最大支持 64 个事件
std::array<short, 65> eventno = { 0 };
eventno[0] = static_cast<short>(vecEventNumbers.size());
std::copy(vecEventNumbers.begin(), vecEventNumbers.end(), eventno.begin() + 1);
- // 鍒濆鍖栬緭鍑哄弬鏁�
+ // 初始化输出参数
details.nEventNo = 0;
details.details.fill(0);
@@ -1077,100 +1077,100 @@
return nRet;
}
-//============================================杈呭姪鍑芥暟=======================================================
-// 鏇存柊鏈�杩戠殑閿欒淇℃伅
+//============================================辅助函数=======================================================
+// 更新最近的错误信息
void CPerformanceMelsec::UpdateLastError(const int nCode) {
if (nCode == 0) {
return;
}
- // 妫�鏌ラ敊璇爜鏄惁瀛樺湪浜庢槧灏勮〃涓�
+ // 检查错误码是否存在于映射表中
const auto it = m_mapError.find(nCode);
if (it != m_mapError.end()) {
- // 濡傛灉鎵惧埌锛岀洿鎺ヨ繑鍥炲搴旇瑷�鐨勯敊璇俊鎭�
+ // 如果找到,直接返回对应语言的错误信息
m_strLastError = it->second;
}
else {
- // 濡傛灉鏈壘鍒帮紝澶勭悊鐗规畩鑼冨洿
+ // 如果未找到,处理特殊范围
m_strLastError = "Unknown error.";
if (nCode == -28611 || nCode == -28612) {
- // 绯荤粺鍑洪敊
+ // 系统出错
m_strLastError = "System error.";
}
if (nCode >= -20480 && nCode <= -16384) {
- // CC-Link 绯荤粺妫�娴嬪嚭鐨勯敊璇�
+ // CC-Link 系统检测出的错误
m_strLastError = "Error detected in the CC-Link system.";
}
if (nCode >= -12288 && nCode <= -8193) {
- // CC-Link IE TSN 绯荤粺妫�娴嬪嚭鐨勯敊璇�
+ // CC-Link IE TSN 系统检测出的错误
m_strLastError = "Error detected in the CC-Link IE TSN system.";
}
if (nCode >= -8192 && nCode <= -4097) {
- // CC-Link IE 鎺у埗缃戠粶绯荤粺妫�娴嬪嚭鐨勯敊璇�
+ // CC-Link IE 控制网络系统检测出的错误
m_strLastError = "Error detected in the CC-Link IE control network system.";
}
if (nCode >= -4096 && nCode <= -257) {
- // MELSECNET/10 鎴� MELSECNET/缃戠粶绯荤粺閿欒鑼冨洿
+ // MELSECNET/10 或 MELSECNET/网络系统错误范围
m_strLastError = "Errors detected in MELSECNET/10 or MELSECNET/network system.";
}
if (nCode >= 4096 && nCode <= 16383) {
- // MELSEC 鏁版嵁閾炬帴搴撹寖鍥�
+ // MELSEC 数据链接库范围
m_strLastError = "Internal error detected by MELSEC Data Link Library.";
}
if (nCode == 18944 || nCode == 18945) {
- // 閾炬帴鍏宠仈鍑洪敊
+ // 链接关联出错
m_strLastError = "Link association error: Network does not exist, unsupported CPU, or incorrect network No./station number.";
}
if (nCode >= 16384 && nCode <= 20479) {
- // PLC CPU 妫�娴嬭寖鍥�
+ // PLC CPU 检测范围
m_strLastError = "Errors detected by the programmable controller CPU in the target station.";
}
if (nCode >= 28416 && nCode <= 28671) {
- // 鍐椾綑鍔熻兘妯″潡鑼冨洿
+ // 冗余功能模块范围
m_strLastError = "Error detected in the redundancy module of the target station.";
}
}
}
-// 妫�鏌ヨ繛鎺ョ姸鎬佸拰绔欑偣鍙傛暟鏈夋晥鎬�
+// 检查连接状态和站点参数有效性
int CPerformanceMelsec::ValidateStation(const StationIdentifier& station) const {
- // 妫�鏌ユ槸鍚﹀凡杩炴帴
+ // 检查是否已连接
if (!m_bConnected.load()) {
return ERROR_CODE_NOT_CONNECTED;
}
- // 妫�鏌ョ綉缁滃彿鍜岀珯鐐瑰彿鑼冨洿
+ // 检查网络号和站点号范围
if (station.nNetNo < 0 || station.nNetNo > 239 || station.nStNo < 0 || station.nStNo > 255) {
return ERROR_CODE_INVALID_PARAM;
}
- return 0; // 鍙傛暟鏈夋晥
+ return 0; // 参数有效
}
-// 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+// 验证站点参数和数据有效性
int CPerformanceMelsec::ValidateStationAndSize(const StationIdentifier& station, const short nCount) const {
- // 楠岃瘉绔欑偣鍙傛暟
+ // 验证站点参数
const int nRet = ValidateStation(station);
if (nRet != 0) {
- return nRet; // 濡傛灉绔欑偣楠岃瘉澶辫触锛岃繑鍥炲搴旈敊璇爜
+ return nRet; // 如果站点验证失败,返回对应错误码
}
if (nCount <= 0) {
return ERROR_CODE_INVALID_PARAM;
}
- return 0; // 楠岃瘉閫氳繃
+ return 0; // 验证通过
}
-// IP瀛楃涓茶浆uint32_t
+// IP字符串转uint32_t
bool CPerformanceMelsec::ConvertIpStringToUint32(const std::string& strIP, uint32_t& nIP) {
nIP = 0;
std::stringstream ss(strIP);
@@ -1189,30 +1189,30 @@
return true;
}
-//============================================闈欐�佽緟鍔╁嚱鏁�====================================================
-// 寤舵椂锛屽苟涓旇浆鍙戠獥鍙f秷鎭�
+//============================================静态辅助函数====================================================
+// 延时,并且转发窗口消息
void CPerformanceMelsec::Delay(const unsigned int nDelayMs) {
MSG message;
- // 濡傛灉寤惰繜鏃堕棿涓� 0锛屼粎澶勭悊涓�娆℃秷鎭槦鍒�
+ // 如果延迟时间为 0,仅处理一次消息队列
if (nDelayMs == 0) {
- // 闈為樆濉炵殑妫�鏌ユ秷鎭槦鍒�
+ // 非阻塞的检查消息队列
if (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) {
- TranslateMessage(&message); // 灏嗘秷鎭浆鍖栦负鏈夋晥鐨勭獥鍙f秷鎭�
- DispatchMessage(&message); // 娲惧彂娑堟伅缁欑浉搴旂殑绐楀彛杩囩▼
+ TranslateMessage(&message); // 将消息转化为有效的窗口消息
+ DispatchMessage(&message); // 派发消息给相应的窗口过程
}
return;
}
DWORD finish;
- const DWORD start = GetTickCount(); // 鑾峰彇褰撳墠鐨勬椂闂存埑锛堜粠绯荤粺鍚姩浠ユ潵鐨勬绉掓暟锛�
+ const DWORD start = GetTickCount(); // 获取当前的时间戳(从系统启动以来的毫秒数)
do {
if (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) {
- TranslateMessage(&message); // 杞崲娑堟伅
- DispatchMessage(&message); // 澶勭悊娑堟伅
+ TranslateMessage(&message); // 转换消息
+ DispatchMessage(&message); // 处理消息
}
- Sleep(1); // 鏆傚仠 1 姣锛岄槻姝㈣繃搴﹀崰鐢� CPU
- finish = GetTickCount(); // 鑾峰彇褰撳墠鐨勬椂闂存埑
- } while ((finish - start) < nDelayMs); // 寰幆鐩村埌缁忚繃鐨勬椂闂村ぇ浜庢寚瀹氱殑寤惰繜鏃堕棿
+ Sleep(1); // 暂停 1 毫秒,防止过度占用 CPU
+ finish = GetTickCount(); // 获取当前的时间戳
+ } while ((finish - start) < nDelayMs); // 循环直到经过的时间大于指定的延迟时间
}
BoardType CPerformanceMelsec::FindBoardTypeByChannel(const int nChannel) {
@@ -1234,136 +1234,136 @@
return BoardType::UNKNOWN;
}
-// 鍚堝苟缃戠粶鍙峰拰绔欑偣鍙�
+// 合并网络号和站点号
short CPerformanceMelsec::CombineStation(const StationIdentifier& station) {
return static_cast<short>(station.nStNo | ((station.nNetNo << 8) & 0xFF00));
}
-// 璁$畻杞厓浠剁被鍨�
+// 计算软元件类型
short CPerformanceMelsec::CalculateDeviceType(const StationIdentifier& station, DeviceType enDevType) {
int nDevType = static_cast<int>(enDevType);
- // 鏍规嵁杞厓浠剁被鍨嬬殑鐗瑰畾瑙勫垯杩涜璁$畻
+ // 根据软元件类型的特定规则进行计算
if (enDevType == DeviceType::LX || enDevType == DeviceType::LY ||
enDevType == DeviceType::LB || enDevType == DeviceType::LW ||
enDevType == DeviceType::LSB || enDevType == DeviceType::LSW) {
- // 缃戠粶鍙峰姞鍋忕Щ
+ // 网络号加偏移
nDevType += station.nNetNo;
}
else if (enDevType == DeviceType::ER) {
- // 鏂囦欢瀵勫瓨鍣ㄧ殑鍧楀彿鍔犲亸绉�
+ // 文件寄存器的块号加偏移
nDevType += 0;
}
else if (enDevType == DeviceType::SPG) {
- // 璧峰 I/O No. 梅 16 鐨勫��
+ // 起始 I/O No. ÷ 16 的值
nDevType += 0 / 16;
}
return static_cast<short>(nDevType);
}
-// std::vector<char>杞崲涓簊td::vector<short>
+// std::vector<char>转换为std::vector<short>
void CPerformanceMelsec::ConvertCharToShort(const std::vector<char>& vecChar, std::vector<short>& vecShort) {
- vecShort.resize((vecChar.size() + 1) / 2, 0); // 璋冩暣 short 瀹瑰櫒澶у皬
+ vecShort.resize((vecChar.size() + 1) / 2, 0); // 调整 short 容器大小
for (size_t i = 0; i < vecChar.size(); i++) {
if (i % 2 == 0) {
- vecShort[i / 2] = static_cast<unsigned char>(vecChar[i]); // 浣庡瓧鑺�
+ vecShort[i / 2] = static_cast<unsigned char>(vecChar[i]); // 低字节
}
else {
- vecShort[i / 2] |= static_cast<unsigned char>(vecChar[i]) << 8; // 楂樺瓧鑺�
+ vecShort[i / 2] |= static_cast<unsigned char>(vecChar[i]) << 8; // 高字节
}
}
}
-// std::vector<short>杞崲涓簊td::vector<char>
+// std::vector<short>转换为std::vector<char>
void CPerformanceMelsec::ConvertShortToChar(const std::vector<short>& vecShort, std::vector<char>& vecChar) {
- vecChar.resize(vecShort.size() * 2); // 璋冩暣 char 瀹瑰櫒澶у皬
+ vecChar.resize(vecShort.size() * 2); // 调整 char 容器大小
for (size_t i = 0; i < vecShort.size(); i++) {
- vecChar[i * 2] = static_cast<char>(vecShort[i] & 0xFF); // 浣庡瓧鑺�
- vecChar[i * 2 + 1] = static_cast<char>((vecShort[i] >> 8) & 0xFF); // 楂樺瓧鑺�
+ vecChar[i * 2] = static_cast<char>(vecShort[i] & 0xFF); // 低字节
+ vecChar[i * 2 + 1] = static_cast<char>((vecShort[i] >> 8) & 0xFF); // 高字节
}
}
-// std::vector<uint8_t>杞崲涓簊td::vector<short>
+// std::vector<uint8_t>转换为std::vector<short>
void CPerformanceMelsec::ConvertUint8ToShort(const std::vector<uint8_t>& vecUint8, std::vector<short>& vecShort) {
- vecShort.resize((vecUint8.size() + 1) / 2, 0); // 璋冩暣 short 瀹瑰櫒澶у皬
+ vecShort.resize((vecUint8.size() + 1) / 2, 0); // 调整 short 容器大小
for (size_t i = 0; i < vecUint8.size(); i++) {
if (i % 2 == 0) {
- vecShort[i / 2] = static_cast<short>(vecUint8[i]); // 浣庡瓧鑺�
+ vecShort[i / 2] = static_cast<short>(vecUint8[i]); // 低字节
}
else {
- vecShort[i / 2] |= static_cast<short>(vecUint8[i] << 8); // 楂樺瓧鑺�
+ vecShort[i / 2] |= static_cast<short>(vecUint8[i] << 8); // 高字节
}
}
}
-// std::vector<short>杞崲涓簊td::vector<uint8_t>
+// std::vector<short>转换为std::vector<uint8_t>
void CPerformanceMelsec::ConvertShortToUint8(const std::vector<short>& vecShort, std::vector<uint8_t>& vecUint8) {
- vecUint8.resize(vecShort.size() * 2); // 璋冩暣 uint8_t 瀹瑰櫒澶у皬
+ vecUint8.resize(vecShort.size() * 2); // 调整 uint8_t 容器大小
for (size_t i = 0; i < vecShort.size(); i++) {
- vecUint8[i * 2] = static_cast<uint8_t>(vecShort[i] & 0xFF); // 浣庡瓧鑺�
- vecUint8[i * 2 + 1] = static_cast<uint8_t>((vecShort[i] >> 8) & 0xFF); // 楂樺瓧鑺�
+ vecUint8[i * 2] = static_cast<uint8_t>(vecShort[i] & 0xFF); // 低字节
+ vecUint8[i * 2 + 1] = static_cast<uint8_t>((vecShort[i] >> 8) & 0xFF); // 高字节
}
}
-// std::vector<uint32_t>杞崲涓簊td::vector<short>
+// std::vector<uint32_t>转换为std::vector<short>
void CPerformanceMelsec::ConvertUint32ToShort(const std::vector<uint32_t>& vecUint32, std::vector<short>& vecShort) {
- vecShort.resize(vecUint32.size() * 2); // 姣忎釜 uint32_t 杞崲涓轰袱涓� short
+ vecShort.resize(vecUint32.size() * 2); // 每个 uint32_t 转换为两个 short
for (size_t i = 0; i < vecUint32.size(); i++) {
- vecShort[i * 2] = static_cast<short>(vecUint32[i] & 0xFFFF); // 浣�16浣�
- vecShort[i * 2 + 1] = static_cast<short>((vecUint32[i] >> 16) & 0xFFFF); // 楂�16浣�
+ vecShort[i * 2] = static_cast<short>(vecUint32[i] & 0xFFFF); // 低16位
+ vecShort[i * 2 + 1] = static_cast<short>((vecUint32[i] >> 16) & 0xFFFF); // 高16位
}
}
-// std::vector<short>杞崲涓簊td::vector<uint32_t>
+// std::vector<short>转换为std::vector<uint32_t>
void CPerformanceMelsec::ConvertShortToUint32(const std::vector<short>& vecShort, std::vector<uint32_t>& vecUint32) {
- vecUint32.resize((vecShort.size() + 1) / 2, 0); // 姣忎袱涓� short 鍚堝苟涓轰竴涓� uint32_t
+ vecUint32.resize((vecShort.size() + 1) / 2, 0); // 每两个 short 合并为一个 uint32_t
for (size_t i = 0; i < vecUint32.size(); i++) {
- vecUint32[i] = (static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2 + 1])) << 16) | // 楂�16浣�
- static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2])); // 浣�16浣�
+ vecUint32[i] = (static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2 + 1])) << 16) | // 高16位
+ static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2])); // 低16位
}
}
-//============================================妯℃澘杈呭姪鍑芥暟====================================================
-// 楠岃瘉绔欑偣鍙傛暟鍜屾暟鎹湁鏁堟��
+//============================================模板辅助函数====================================================
+// 验证站点参数和数据有效性
template <typename T>
int CPerformanceMelsec::ValidateStationAndData(const StationIdentifier& station, const std::vector<T>& vecData) {
- // 楠岃瘉绔欑偣鍙傛暟
+ // 验证站点参数
const int nRet = ValidateStation(station);
if (nRet != 0) {
- return nRet; // 濡傛灉绔欑偣楠岃瘉澶辫触锛岃繑鍥炲搴旈敊璇爜
+ return nRet; // 如果站点验证失败,返回对应错误码
}
- // 楠岃瘉鏁版嵁鏄惁涓虹┖
+ // 验证数据是否为空
if (vecData.empty()) {
return ERROR_CODE_INVALID_PARAM;
}
- return 0; // 楠岃瘉閫氳繃
+ return 0; // 验证通过
}
-// 鐢变綆杞珮瀹瑰櫒鐨勬ā鏉匡紙鏁村瀷锛�
+// 由低转高容器的模板(整型)
template <typename T, typename U>
void CPerformanceMelsec::ConvertLowToHigh(const std::vector<T>& vecLow, std::vector<U>& vecHigh) {
static_assert(std::is_integral<T>::value && std::is_integral<U>::value, "T and U must be integral types");
- // 鑷姩璁$畻 nGroupSize
+ // 自动计算 nGroupSize
constexpr size_t nGroupSize = sizeof(U) / sizeof(T);
- // 濡傛灉 T 鍜� U 鐨勫ぇ灏忕浉绛夛紝鐩存帴杞崲
+ // 如果 T 和 U 的大小相等,直接转换
if (sizeof(T) == sizeof(U)) {
vecHigh.assign(vecLow.begin(), vecLow.end());
return;
}
- // 濡傛灉 U 鐨勫ぇ灏忔槸 T 鐨勫�嶆暟锛屾甯哥粍鍚�
+ // 如果 U 的大小是 T 的倍数,正常组合
static_assert(sizeof(U) > sizeof(T), "Size of U must be greater than or equal to size of T");
- // 璁$畻瀹屾暣缁勭殑鏁伴噺
- size_t nHighSize = (vecLow.size() + nGroupSize - 1) / nGroupSize; // 鍚戜笂鍙栨暣
+ // 计算完整组的数量
+ size_t nHighSize = (vecLow.size() + nGroupSize - 1) / nGroupSize; // 向上取整
vecHigh.resize(nHighSize, 0);
- // 鍚堝苟浣庝綅鏁版嵁鍒伴珮浣嶆暟鎹�
+ // 合并低位数据到高位数据
for (size_t i = 0; i < vecLow.size(); i++) {
vecHigh[i / nGroupSize] |= (static_cast<U>(vecLow[i]) << ((i % nGroupSize) * CHAR_BIT * sizeof(T)));
}
@@ -1371,27 +1371,27 @@
return vecHigh;
}
-// 鐢遍珮杞綆瀹瑰櫒鐨勬ā鏉匡紙鏁村瀷锛�
+// 由高转低容器的模板(整型)
template <typename T, typename U>
void CPerformanceMelsec::ConvertHighToLow(const std::vector<T>& vecHigh, std::vector<U>& vecLow) {
static_assert(std::is_integral<T>::value && std::is_integral<U>::value, "T and U must be integral types");
- // 鑷姩璁$畻 nGroupSize
+ // 自动计算 nGroupSize
constexpr size_t nGroupSize = sizeof(T) / sizeof(U);
- // 濡傛灉 T 鍜� U 鐨勫ぇ灏忕浉绛夛紝鐩存帴杞崲
+ // 如果 T 和 U 的大小相等,直接转换
if (sizeof(T) == sizeof(U)) {
vecLow.assign(vecHigh.begin(), vecHigh.end());
return;
}
- // 濡傛灉 T 鐨勫ぇ灏忔槸 U 鐨勫�嶆暟锛屾甯稿垎瑙�
+ // 如果 T 的大小是 U 的倍数,正常分解
static_assert(sizeof(T) > sizeof(U), "Size of T must be greater than or equal to size of U");
- size_t nLowSize = vecHigh.size() * nGroupSize; // 浣庡鍣ㄧ殑澶у皬
+ size_t nLowSize = vecHigh.size() * nGroupSize; // 低容器的大小
vecLow.resize(nLowSize, 0);
- // 鍒嗚В楂樹綅鏁版嵁鍒颁綆浣嶆暟鎹�
+ // 分解高位数据到低位数据
for (size_t i = 0; i < vecHigh.size(); i++) {
for (size_t j = 0; j < nGroupSize; j++) {
vecLow[i * nGroupSize + j] = static_cast<U>((vecHigh[i] >> (j * CHAR_BIT * sizeof(U))) & ((1ULL << (CHAR_BIT * sizeof(U))) - 1));
diff --git a/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h b/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h
index 07a4b32..a6020c4 100644
--- a/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h
+++ b/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h
@@ -10,151 +10,151 @@
#include <sstream>
#include <unordered_map>
-// 杩炴帴鍙傛暟
-#define PLC_MAX_RETRY 3 // 鏈�澶ч噸璇曟鏁帮細鍦ㄤ笌PLC閫氫俊鏃讹紝濡傛灉鍙戠敓閫氫俊閿欒锛屽皢鏈�澶氶噸璇�3娆�
-#define PLC_TIMEOUT 500 // 瓒呮椂鏃堕棿锛堟绉掞級锛氭瘡娆¢�氫俊鎿嶄綔鐨勮秴鏃剁瓑寰呮椂闂翠负500姣
+// 连接参数
+#define PLC_MAX_RETRY 3 // 最大重试次数:在与PLC通信时,如果发生通信错误,将最多重试3次
+#define PLC_TIMEOUT 500 // 超时时间(毫秒):每次通信操作的超时等待时间为500毫秒
/*
- * 缃戠粶閫氶亾锛氭寚瀹氶�氫俊鎵�浣跨敤鐨勭綉缁滈�氶亾鍙凤紝閫氬父鍦ㄥ閫氶亾閫氫俊涓缃�
- * 51 鍒� 54 鏄� MELSECNET/H 鐨� 1-4 閫氶亾
- * 81 鍒� 84 鏄� CC-Link 鐨� 1-4 閫氶亾
- * 151 鍒� 154 鏄� CC-Link IE 鎺у埗鍣ㄧ綉缁滅殑 1-4 閫氶亾
- * 181 鍒� 184 鏄� CC-Link IE 鐜板満缃戠粶鐨� 1-4 閫氶亾
- * 281 鍒� 284 鏄� CC-Link IE TSN 缃戠粶鐨� 1-4 閫氶亾
+ * 网络通道:指定通信所使用的网络通道号,通常在多通道通信中设置
+ * 51 到 54 是 MELSECNET/H 的 1-4 通道
+ * 81 到 84 是 CC-Link 的 1-4 通道
+ * 151 到 154 是 CC-Link IE 控制器网络的 1-4 通道
+ * 181 到 184 是 CC-Link IE 现场网络的 1-4 通道
+ * 281 到 284 是 CC-Link IE TSN 网络的 1-4 通道
**/
-#define MELSECNET_CHANNEL(x) (50 + (x)) // x 鑼冨洿锛�1~4
-#define CC_LINK_CHANNEL(x) (80 + (x)) // x 鑼冨洿锛�1~4
-#define CC_LINK_IE_CONTROL_CHANNEL(x) (150 + (x)) // x 鑼冨洿锛�1~4
-#define CC_LINK_IE_FIELD_CHANNEL(x) (180 + (x)) // x 鑼冨洿锛�1~4
-#define CC_LINK_IE_TSN_CHANNEL(x) (280 + (x)) // x 鑼冨洿锛�1~4
+#define MELSECNET_CHANNEL(x) (50 + (x)) // x 范围:1~4
+#define CC_LINK_CHANNEL(x) (80 + (x)) // x 范围:1~4
+#define CC_LINK_IE_CONTROL_CHANNEL(x) (150 + (x)) // x 范围:1~4
+#define CC_LINK_IE_FIELD_CHANNEL(x) (180 + (x)) // x 范围:1~4
+#define CC_LINK_IE_TSN_CHANNEL(x) (280 + (x)) // x 范围:1~4
- // 鑷畾涔夐敊璇爜
-#define ERROR_CODE_UNKNOWN 0x00010000 // 鏈煡
-#define ERROR_CODE_NOT_CONNECTED 0x00020000 // 鏈繛鎺�
-#define ERROR_CODE_INVALID_PARAM 0x00030000 // 鍙傛暟鏃犳晥
-#define ERROR_CODE_INVALID_DATA 0x00040000 // 鏁版嵁鏃犳晥
-#define ERROR_CODE_STATION_OUT_OF_RANGE 0x00050000 // 绔欏彿瓒呭嚭鑼冨洿
-#define ERROR_CODE_GROUP_OUT_OF_RANGE 0x00060000 // 缁勫彿瓒呭嚭鑼冨洿
-#define ERROR_CODE_NETWORK_OUT_OF_RANGE 0x00070000 // 缃戠粶鍙疯秴鍑鸿寖鍥�
+ // 自定义错误码
+#define ERROR_CODE_UNKNOWN 0x00010000 // 未知
+#define ERROR_CODE_NOT_CONNECTED 0x00020000 // 未连接
+#define ERROR_CODE_INVALID_PARAM 0x00030000 // 参数无效
+#define ERROR_CODE_INVALID_DATA 0x00040000 // 数据无效
+#define ERROR_CODE_STATION_OUT_OF_RANGE 0x00050000 // 站号超出范围
+#define ERROR_CODE_GROUP_OUT_OF_RANGE 0x00060000 // 组号超出范围
+#define ERROR_CODE_NETWORK_OUT_OF_RANGE 0x00070000 // 网络号超出范围
-// 鏉垮潡绫诲瀷
+// 板块类型
enum class BoardType {
- UNKNOWN = -1, // 鏈煡绫诲瀷
+ UNKNOWN = -1, // 未知类型
MELSECNET_H = MELSECNET_CHANNEL(1), // MELSECNET/H
CC_LINK_VER_2 = CC_LINK_CHANNEL(1), // CC-Link Ver. 2
- CC_LINK_IE_CONTROL = CC_LINK_IE_CONTROL_CHANNEL(1), // CC-Link IE 鎺у埗缃戠粶
- CC_LINK_IE_FIELD = CC_LINK_IE_FIELD_CHANNEL(1), // CC-Link IE 鐜板満缃戠粶
+ CC_LINK_IE_CONTROL = CC_LINK_IE_CONTROL_CHANNEL(1), // CC-Link IE 控制网络
+ CC_LINK_IE_FIELD = CC_LINK_IE_FIELD_CHANNEL(1), // CC-Link IE 现场网络
CC_LINK_IE_TSN = CC_LINK_IE_TSN_CHANNEL(1) // CC-Link IE TSN
};
-// 杞厓浠剁被鍨嬫灇涓�
+// 软元件类型枚举
enum class DeviceType {
/*
- * ER銆丩X銆丩Y銆丩B銆丩W銆丩SB銆丩SW鍜孲PG杞厓浠堕兘鏄寖鍥村瀷
- * ER锛欴evER0锝�256
- * LX锛欴evLX1锝�255锛孌evLX(x) (DevX*1000+(x))
- * LY锛欴evLY1锝�255锛孌evLY(x) (DevY*1000+(x))
- * LB锛欴evLB1锝�255锛孌evLB(x) (DevB*1000+(x))
- * LW锛欴evLW1锝�255锛孌evLW(x) (DevW*1000+(x))
- * LSB锛欴evLSB1锝�255锛孌evLSB(x) (DevQSB*1000+(x))
- * LSW锛欴evLSW1锝�255锛孌evLSW(x) (DevQSW*1000+(x))
- * SPG锛欴evSPG0锝�255锛孌evSPG(x) (29*1000+(x))
- * 鎵╁睍鏂囦欢瀵勫瓨鍣ㄤ唬鐮佹寚瀹�(10杩涘埗鏁�)鐨勫悗3浣嶆暟鍙婅蒋鍏冧欢鍚嶆寚瀹氱殑鏁板�间腑锛屽簲鎸囧畾鍧桸o.(0锝�256)
- * 閾炬帴鐩存帴杞厓浠朵唬鐮佹寚瀹�(10杩涘埗鏁�)鐨勫悗3浣嶆暟鍙婅蒋鍏冧欢鍚嶆寚瀹氱殑鏁板�间腑锛屽簲鎸囧畾缃戠粶No.(1锝�255)
- * 鏅鸿兘鍔熻兘妯″潡杞厓浠朵唬鐮佹寚瀹�(10杩涘埗鏁�)鐨勫悗3浣嶆暟鍙婅蒋鍏冧欢鍚嶆寚瀹氱殑鏁板�间腑锛屽簲鎸囧畾(璧峰I/ONo.梅16)鐨勫��
- * 鎵╁睍鏂囦欢瀵勫瓨鍣ㄥ拰閾炬帴鐩存帴杞厓浠跺湪闅忔満璇诲彇(mdRandR銆乵dRandREx)鍑芥暟涓紝鍗充娇鎸囧畾瀹為檯涓嶅瓨鍦ㄧ殑杞厓浠朵篃鏈夊彲鑳芥甯哥粨鏉�
- * MAIL鍜孧AILMC鍦⊿END鍔熻兘鍙奟ECV鍔熻兘涓紝涓庤蒋鍏冧欢璁块棶涓�鏍凤紝鎸囧畾鍚勫姛鑳藉搴旂殑杞厓浠剁被鍨嬶紝杩涜鏁版嵁鐨勫彂閫�(mdSend銆乵dSendEx)鎴栨暟鎹殑璇诲彇(mdReceive銆乵dReceiveEx)
+ * ER、LX、LY、LB、LW、LSB、LSW和SPG软元件都是范围型
+ * ER:DevER0~256
+ * LX:DevLX1~255,DevLX(x) (DevX*1000+(x))
+ * LY:DevLY1~255,DevLY(x) (DevY*1000+(x))
+ * LB:DevLB1~255,DevLB(x) (DevB*1000+(x))
+ * LW:DevLW1~255,DevLW(x) (DevW*1000+(x))
+ * LSB:DevLSB1~255,DevLSB(x) (DevQSB*1000+(x))
+ * LSW:DevLSW1~255,DevLSW(x) (DevQSW*1000+(x))
+ * SPG:DevSPG0~255,DevSPG(x) (29*1000+(x))
+ * 扩展文件寄存器代码指定(10进制数)的后3位数及软元件名指定的数值中,应指定块No.(0~256)
+ * 链接直接软元件代码指定(10进制数)的后3位数及软元件名指定的数值中,应指定网络No.(1~255)
+ * 智能功能模块软元件代码指定(10进制数)的后3位数及软元件名指定的数值中,应指定(起始I/ONo.÷16)的值
+ * 扩展文件寄存器和链接直接软元件在随机读取(mdRandR、mdRandREx)函数中,即使指定实际不存在的软元件也有可能正常结束
+ * MAIL和MAILMC在SEND功能及RECV功能中,与软元件访问一样,指定各功能对应的软元件类型,进行数据的发送(mdSend、mdSendEx)或数据的读取(mdReceive、mdReceiveEx)
**/
- X = 0x0001, // 杈撳叆 (浣�)
- Y = 0x0002, // 杈撳嚭 (浣�)
- L = 0x0003, // 閿佸瓨缁х數鍣� (浣�)
- M = 0x0004, // 鍐呴儴缁х數鍣� (浣�)
- SM = 0x0005, // 鐗规畩缁х數鍣� (浣�)
- F = 0x0006, // 鎶ヨ鍣� (浣�)
- TT = 0x0007, // 瀹氭椂鍣� (瑙︾偣) (浣�)
- TC = 0x0008, // 璁℃暟鍣� (绾垮湀) (浣�)
- CT = 0x0009, // 璁℃暟鍣� (瑙︾偣) (浣�)
- CC = 0x000A, // 璁℃暟鍣� (绾垮湀) (瀛�)
- TN = 0x000B, // 瀹氭椂鍣� (褰撳墠鍊�) (瀛�)
- CN = 0x000C, // 璁℃暟鍣� (褰撳墠鍊�) (瀛�)
- D = 0x000D, // 鏁版嵁瀵勫瓨鍣� (瀛�)
- SD = 0x000E, // 鐗规畩瀵勫瓨鍣� (瀛�)
- TM = 0x000F, // 瀹氭椂鍣� (璁剧疆鍊间富) (瀛�)
- TS = 0x0010, // 瀹氭椂鍣� (璁剧疆鍊间富1) (瀛�)
- TS2 = 0x3E82, // 瀹氭椂鍣� (璁剧疆鍊间富2) (瀛�)
- TS3 = 0x3E83, // 瀹氭椂鍣� (璁剧疆鍊间富3) (瀛�)
- CM = 0x0011, // 璁℃暟鍣� (璁剧疆鍊间富) (瀛�)
- CS = 0x0012, // 璁℃暟鍣� (璁剧疆鍊间富1) (瀛�)
- CS2 = 0x4652, // 璁℃暟鍣� (璁剧疆鍊间富2) (瀛�)
- CS3 = 0x4653, // 璁℃暟鍣� (璁剧疆鍊间富3) (瀛�)
- A = 0x0013, // 绱姞鍣� (瀛�)
- Z = 0x0014, // 鍙樺潃瀵勫瓨鍣� (瀛�)
- V = 0x0015, // 鍙樺潃瀵勫瓨鍣� (瀛�)
- R = 0x0016, // 鏂囦欢瀵勫瓨鍣� (鍧楀垏鎹㈡柟寮�) (瀛�)
- ER = 0x55F0, // 鎵╁睍鏂囦欢瀵勫瓨鍣� (鍧楀垏鎹㈡柟寮�) (0x55F0锝�0x56F0) (瀛�) (鍦ㄩ殢鏈鸿鍙�(mdRandR銆乵dRandREx)鍑芥暟涓紝鍗充娇鎸囧畾瀹為檯涓嶅瓨鍦ㄧ殑杞厓浠朵篃鏈夊彲鑳芥甯哥粨鏉熴��(璇诲彇鏁版嵁涓嶆纭��))
- ZR = 0x00DC, // 鏂囦欢瀵勫瓨鍣� (杩炲彿璁块棶鏂瑰紡) (瀛�)
- B = 0x0017, // 閾炬帴缁х數鍣� (浣�)
- W = 0x0018, // 閾炬帴瀵勫瓨鍣� (瀛�)
- QSB = 0x0019, // 閾炬帴鐗规畩缁х數鍣� (浣�)
- STT = 0x001A, // 绱瀹氭椂鍣� (瑙︾偣) (浣�)
- STC = 0x001B, // 绱瀹氭椂鍣� (绾垮湀) (浣�)
- QSW = 0x001C, // 閾炬帴鐗规畩瀵勫瓨鍣� (瀛�)
- QV = 0x001E, // 鍙樺潃缁х數鍣� (浣�)
- MRB = 0x0021, // 闅忔満璁块棶缂撳啿 (瀛�)
- STN = 0x0023, // 绱瀹氭椂鍣� (褰撳墠鍊�) (瀛�)
- LZ = 0x0026, // 瓒呴暱鍙樺潃瀵勫瓨鍣� (鍙屽瓧)
- RD = 0x0027, // 鍒锋柊鏁版嵁瀵勫瓨鍣� (瀛�)
- LTT = 0x0029, // 瓒呴暱瀹氭椂鍣� (瑙︾偣) (浣�)
- LTC = 0x002A, // 瓒呴暱瀹氭椂鍣� (绾垮湀) (浣�)
- LTN = 0x002B, // 瓒呴暱瀹氭椂鍣� (褰撳墠鍊�) (鍙屽瓧)
- LCT = 0x002C, // 瓒呴暱璁℃暟鍣� (瑙︾偣) (浣�)
- LCC = 0x002D, // 瓒呴暱璁℃暟鍣� (绾垮湀) (浣�)
- LCN = 0x002E, // 瓒呴暱璁℃暟鍣� (褰撳墠鍊�) (鍙屽瓧)
- LSTT = 0x002F, // 瓒呴暱绱瀹氭椂鍣� (瑙︾偣) (浣�)
- LSTC = 0x0030, // 瓒呴暱绱瀹氭椂鍣� (绾垮湀) (浣�)
- LSTN = 0x0031, // 瓒呴暱绱瀹氭椂鍣� (褰撳墠鍊�) (鍙屽瓧)
- SPB = 0x0032, // 缂撳啿瀛樺偍鍣� (瀛�)
- MAIL = 0x0065, // 鐗规畩杞厓浠剁被鍨嬶細閭欢绫诲瀷 (10杩涘埗 101)
- MAILMC = 0x0066, // 鐗规畩杞厓浠剁被鍨嬶細鏃犵‘璁ら偖浠� (10杩涘埗 102)
- LX = 0x03E8, // 閾炬帴鐩存帴杞厓浠� (閾炬帴杈撳叆) (0x03E9锝�0x04E7) (浣�)
- LY = 0x07D0, // 閾炬帴鐩存帴杞厓浠� (閾炬帴杈撳嚭) (0x07D1锝�0x08CF) (浣�)
- LB = 0x59D8, // 閾炬帴鐩存帴杞厓浠� (閾炬帴缁х數鍣�) (0x59D9锝�0x5AD7) (浣�)
- LW = 0x5DC0, // 閾炬帴鐩存帴杞厓浠� (閾炬帴瀵勫瓨鍣�) (0x5DC1锝�0x5EBF) (瀛�)
- LSB = 0x61A8, // 閾炬帴鐩存帴杞厓浠� (閾炬帴鐗规畩缁х數鍣�) (0x61A9锝�0x62A7) (浣�)
- LSW = 0x6D60, // 閾炬帴鐩存帴杞厓浠� (閾炬帴鐗规畩瀵勫瓨鍣�) (0x6D61锝�0x6E5F) (瀛�)
- SPG = 0x7147, // 鏅鸿兘鍔熻兘妯″潡杞厓浠� (0x7148锝�0x7247) (瀛�)
+ X = 0x0001, // 输入 (位)
+ Y = 0x0002, // 输出 (位)
+ L = 0x0003, // 锁存继电器 (位)
+ M = 0x0004, // 内部继电器 (位)
+ SM = 0x0005, // 特殊继电器 (位)
+ F = 0x0006, // 报警器 (位)
+ TT = 0x0007, // 定时器 (触点) (位)
+ TC = 0x0008, // 计数器 (线圈) (位)
+ CT = 0x0009, // 计数器 (触点) (位)
+ CC = 0x000A, // 计数器 (线圈) (字)
+ TN = 0x000B, // 定时器 (当前值) (字)
+ CN = 0x000C, // 计数器 (当前值) (字)
+ D = 0x000D, // 数据寄存器 (字)
+ SD = 0x000E, // 特殊寄存器 (字)
+ TM = 0x000F, // 定时器 (设置值主) (字)
+ TS = 0x0010, // 定时器 (设置值主1) (字)
+ TS2 = 0x3E82, // 定时器 (设置值主2) (字)
+ TS3 = 0x3E83, // 定时器 (设置值主3) (字)
+ CM = 0x0011, // 计数器 (设置值主) (字)
+ CS = 0x0012, // 计数器 (设置值主1) (字)
+ CS2 = 0x4652, // 计数器 (设置值主2) (字)
+ CS3 = 0x4653, // 计数器 (设置值主3) (字)
+ A = 0x0013, // 累加器 (字)
+ Z = 0x0014, // 变址寄存器 (字)
+ V = 0x0015, // 变址寄存器 (字)
+ R = 0x0016, // 文件寄存器 (块切换方式) (字)
+ ER = 0x55F0, // 扩展文件寄存器 (块切换方式) (0x55F0~0x56F0) (字) (在随机读取(mdRandR、mdRandREx)函数中,即使指定实际不存在的软元件也有可能正常结束。(读取数据不正确。))
+ ZR = 0x00DC, // 文件寄存器 (连号访问方式) (字)
+ B = 0x0017, // 链接继电器 (位)
+ W = 0x0018, // 链接寄存器 (字)
+ QSB = 0x0019, // 链接特殊继电器 (位)
+ STT = 0x001A, // 累计定时器 (触点) (位)
+ STC = 0x001B, // 累计定时器 (线圈) (位)
+ QSW = 0x001C, // 链接特殊寄存器 (字)
+ QV = 0x001E, // 变址继电器 (位)
+ MRB = 0x0021, // 随机访问缓冲 (字)
+ STN = 0x0023, // 累计定时器 (当前值) (字)
+ LZ = 0x0026, // 超长变址寄存器 (双字)
+ RD = 0x0027, // 刷新数据寄存器 (字)
+ LTT = 0x0029, // 超长定时器 (触点) (位)
+ LTC = 0x002A, // 超长定时器 (线圈) (位)
+ LTN = 0x002B, // 超长定时器 (当前值) (双字)
+ LCT = 0x002C, // 超长计数器 (触点) (位)
+ LCC = 0x002D, // 超长计数器 (线圈) (位)
+ LCN = 0x002E, // 超长计数器 (当前值) (双字)
+ LSTT = 0x002F, // 超长累计定时器 (触点) (位)
+ LSTC = 0x0030, // 超长累计定时器 (线圈) (位)
+ LSTN = 0x0031, // 超长累计定时器 (当前值) (双字)
+ SPB = 0x0032, // 缓冲存储器 (字)
+ MAIL = 0x0065, // 特殊软元件类型:邮件类型 (10进制 101)
+ MAILMC = 0x0066, // 特殊软元件类型:无确认邮件 (10进制 102)
+ LX = 0x03E8, // 链接直接软元件 (链接输入) (0x03E9~0x04E7) (位)
+ LY = 0x07D0, // 链接直接软元件 (链接输出) (0x07D1~0x08CF) (位)
+ LB = 0x59D8, // 链接直接软元件 (链接继电器) (0x59D9~0x5AD7) (位)
+ LW = 0x5DC0, // 链接直接软元件 (链接寄存器) (0x5DC1~0x5EBF) (字)
+ LSB = 0x61A8, // 链接直接软元件 (链接特殊继电器) (0x61A9~0x62A7) (位)
+ LSW = 0x6D60, // 链接直接软元件 (链接特殊寄存器) (0x6D61~0x6E5F) (字)
+ SPG = 0x7147, // 智能功能模块软元件 (0x7148~0x7247) (字)
};
-// 鏁版嵁绫诲瀷
+// 数据类型
enum class DataType {
- BIT = 1, // 浣� (1浣�)
- WORD = 2, // 瀛� (16浣�)
- DWORD = 4 // 鍙屽瓧 (32浣�)
+ BIT = 1, // 位 (1位)
+ WORD = 2, // 字 (16位)
+ DWORD = 4 // 双字 (32位)
};
-// 鎺у埗浠g爜
+// 控制代码
enum class ControlCode {
- RUN = 0, // 杩滅▼ RUN
- STOP = 1, // 杩滅▼ STOP
- PAUSE = 2 // 杩滅▼ PAUSE
+ RUN = 0, // 远程 RUN
+ STOP = 1, // 远程 STOP
+ PAUSE = 2 // 远程 PAUSE
};
-// 鐗堟湰淇℃伅
+// 版本信息
struct BoardVersion {
- char fixedValue[2]; // 鍥哄畾鍊�
- char checksum[2]; // 鏍¢獙鍜�
- char swVersion[2]; // 杞欢鐗堟湰
- char date[6]; // 鏃ユ湡 (鏍煎紡 YYMMDD)
- uint32_t reserved; // 淇濈暀鍖哄煙 (4 瀛楄妭)
- char swModel[16]; // 杞欢鍨嬪彿
- char hwModel[16]; // 纭欢鍨嬪彿
- char twoPortMemory[2]; // 涓ょ鍙e瓨鍌ㄥ櫒鍗犵敤瀹归噺
- char twoPortAttribute[2]; // 涓ょ鍙e睘鎬�
- char availableBias[2]; // 鍙娇鐢ㄥ亸缃�
- char moduleType[10]; // 鏈哄瀷绫诲瀷
+ char fixedValue[2]; // 固定值
+ char checksum[2]; // 校验和
+ char swVersion[2]; // 软件版本
+ char date[6]; // 日期 (格式 YYMMDD)
+ uint32_t reserved; // 保留区域 (4 字节)
+ char swModel[16]; // 软件型号
+ char hwModel[16]; // 硬件型号
+ char twoPortMemory[2]; // 两端口存储器占用容量
+ char twoPortAttribute[2]; // 两端口属性
+ char availableBias[2]; // 可使用偏置
+ char moduleType[10]; // 机型类型
- // 杈撳嚭缁撴瀯浣撳唴瀹逛负瀛楃涓� (渚夸簬璋冭瘯)
+ // 输出结构体内容为字符串 (便于调试)
std::string toString() const {
std::ostringstream oss;
oss << "Fixed Value: " << fixedValue[0] << fixedValue[1] << "\n"
@@ -172,18 +172,18 @@
}
};
-// 绔欑偣鏍囪瘑绗︼紝榛樿浣跨敤鏈珯
+// 站点标识符,默认使用本站
struct StationIdentifier {
/*
* [Network No.]
- * 0 琛ㄧず鏈珯
- * 1~239 琛ㄧず鏅�氱綉缁滃彿
+ * 0 表示本站
+ * 1~239 表示普通网络号
**/
/*
* [Station No.]
- * MELSECNET/H锛�1~64 琛ㄧず鍏朵粬绔欑偣锛�255 琛ㄧず鏈珯
- * CC-Link 绯诲垪缃戠粶鐨勮寖鍥寸被浼硷紝鍖哄埆鍦ㄤ簬绔欏彿鐨勫彇鍊艰寖鍥�
+ * MELSECNET/H:1~64 表示其他站点,255 表示本站
+ * CC-Link 系列网络的范围类似,区别在于站号的取值范围
* MELSECNET/H : 1~64(Other stations),255(Own station)
* CC-Link : 0~63(Other stations),255(Own station)
* CC-Link IE Controller : 1~120(Other stations),255(Own station)
@@ -192,15 +192,15 @@
**/
/*
- * 楂� 8 浣嶏紙缃戠粶鍙凤級锛� 鎸囧畾璁惧鎵�灞炵殑缃戠粶
- * 浣� 8 浣嶏紙绔欑偣鍙凤級锛� 鎸囧畾璁惧鍦ㄧ綉缁滀腑鐨勭紪鍙�
- * 鐢ㄤ竴涓弬鏁颁紶閫掕澶囩殑缃戠粶鍙峰拰绔欑偣鍙锋椂: nSt = station.nStNo | ((station.nNetNo << 8) & 0xFF00);
+ * 高 8 位(网络号): 指定设备所属的网络
+ * 低 8 位(站点号): 指定设备在网络中的编号
+ * 用一个参数传递设备的网络号和站点号时: nSt = station.nStNo | ((station.nNetNo << 8) & 0xFF00);
**/
- short nNetNo = 0; // 缃戠粶缂栧彿锛歅LC鎵�杩炴帴鐨勭綉缁滅紪鍙凤紝0琛ㄧず榛樿缃戠粶
- short nStNo = 255; // 绔欑偣缂栧彿锛氭寚瀹氫笌PLC杩炴帴鐨勭珯鐐圭紪鍙凤紝255閫氬父琛ㄧず骞挎挱鎴栨墍鏈夌珯鐐�
+ short nNetNo = 0; // 网络编号:PLC所连接的网络编号,0表示默认网络
+ short nStNo = 255; // 站点编号:指定与PLC连接的站点编号,255通常表示广播或所有站点
- // 鑷畾涔夋瀯閫犲嚱鏁帮紝瑕嗙洊榛樿鍊�
+ // 自定义构造函数,覆盖默认值
explicit StationIdentifier(const short net, const short st) : nNetNo(net), nStNo(st) {}
StationIdentifier()
@@ -209,24 +209,24 @@
nStNo = 255;
}
- // 灏嗏�滅綉缁滃彿鈥濆拰鈥滅珯鐐瑰彿鈥濈粍鍚堟垚涓�涓渶缁堢紪鐮�
+ // 将“网络号”和“站点号”组合成一个最终编码
short StationIdentifier::toNetworkStationCode() const {
return static_cast<short>(nStNo | ((nNetNo << 8) & 0xFF00));
}
- // 閲嶈浇 < 杩愮畻绗︼紙鐢ㄤ簬鎺掑簭鎴栨瘮杈冿紝閫氬父鐢ㄤ簬 map 鎴� set 涓綔涓� key锛�
+ // 重载 < 运算符(用于排序或比较,通常用于 map 或 set 中作为 key)
bool operator<(const StationIdentifier& other) const {
return std::tie(nNetNo, nStNo) <
std::tie(other.nNetNo, other.nStNo);
}
- // 閲嶈浇 == 杩愮畻绗︼紙鐢ㄤ簬鐩哥瓑姣旇緝锛�
+ // 重载 == 运算符(用于相等比较)
bool operator==(const StationIdentifier& other) const {
return std::tie(nNetNo, nStNo) ==
std::tie(other.nNetNo, other.nStNo);
}
- // 閲嶈浇 = 杩愮畻绗︼紙鐢ㄤ簬璧嬪�硷級
+ // 重载 = 运算符(用于赋值)
StationIdentifier& operator=(const StationIdentifier& other) {
if (this != &other) {
nNetNo = other.nNetNo;
@@ -236,16 +236,16 @@
}
};
-// 鏉跨姸鎬�
+// 板状态
struct BoardStatus {
- short nStationValue = 0; // 绔欏彿鐨勮澶囧�� (buf[0])
- short nGroupValue = 0; // 缁� No. 鐨勮澶囧�� (buf[1])
- short nNetworkValue = 0; // 缃戠粶 No. 鐨勮澶囧�� (buf[2])
- short nReserved1 = 0; // 淇濈暀瀛楁 (buf[3])
- short nReserved2 = 0; // 淇濈暀瀛楁 (buf[4])
- short nReserved3 = 0; // 淇濈暀瀛楁 (buf[5])
+ short nStationValue = 0; // 站号的设备值 (buf[0])
+ short nGroupValue = 0; // 组 No. 的设备值 (buf[1])
+ short nNetworkValue = 0; // 网络 No. 的设备值 (buf[2])
+ short nReserved1 = 0; // 保留字段 (buf[3])
+ short nReserved2 = 0; // 保留字段 (buf[4])
+ short nReserved3 = 0; // 保留字段 (buf[5])
- // 灏嗘暟缁勬槧灏勫埌缁撴瀯浣�
+ // 将数组映射到结构体
static BoardStatus fromBuffer(const short buf[6]) {
return {
buf[0],
@@ -257,7 +257,7 @@
};
}
- // 灏嗙粨鏋勪綋鍐呭鏄犲皠鍒版暟缁�
+ // 将结构体内容映射到数组
void toBuffer(short buf[6]) const {
buf[0] = nStationValue;
buf[1] = nGroupValue;
@@ -267,7 +267,7 @@
buf[5] = nReserved3;
}
- // 璋冭瘯杈撳嚭
+ // 调试输出
std::string toString() const {
std::ostringstream oss;
oss << "Station Value: " << nStationValue << "\n"
@@ -280,12 +280,12 @@
}
};
-// 浜嬩欢璇︽儏
+// 事件详情
struct EventDetails {
- short nEventNo; // 鍙戠敓鐨勪簨浠跺彿
- std::array<short, 4> details; // 瀛樺偍浜嬩欢璇︽儏淇℃伅
+ short nEventNo; // 发生的事件号
+ std::array<short, 4> details; // 存储事件详情信息
- // 瑙f瀽浜嬩欢璇︽儏锛岃繑鍥炴牸寮忓寲瀛楃涓�
+ // 解析事件详情,返回格式化字符串
std::string toString() const {
std::ostringstream oss;
oss << "Details[0]: " << details[0] << ", "
@@ -296,33 +296,33 @@
}
};
-// SoftElement 缁撴瀯浣撳畾涔�
+// SoftElement 结构体定义
struct SoftElement {
- short nType; // 杞厓浠剁被鍨�
- short nElementCount; // 鐐规暟
- long nStartNo; // 璧峰杞厓浠剁紪鍙�
+ short nType; // 软元件类型
+ short nElementCount; // 点数
+ long nStartNo; // 起始软元件编号
};
-// 閿欒淇℃伅
+// 错误信息
struct ErrorInfo {
- int nErrorCode = 0; // 閿欒鐮�
- std::string strErrorMessageCn; // 涓枃鎻忚堪
- std::string strErrorMessageEn; // 鑻辨枃鎻忚堪
+ int nErrorCode = 0; // 错误码
+ std::string strErrorMessageCn; // 中文描述
+ std::string strErrorMessageEn; // 英文描述
- // 灏嗙粨鏋勪綋搴忓垪鍖栦负瀛楃涓�
+ // 将结构体序列化为字符串
std::string toString() const {
std::ostringstream oss;
oss << nErrorCode << "|" << strErrorMessageCn << "|" << strErrorMessageEn;
return oss.str();
}
- // 浠庡瓧绗︿覆鍙嶅簭鍒楀寲涓虹粨鏋勪綋
+ // 从字符串反序列化为结构体
static ErrorInfo fromString(const std::string& line) {
ErrorInfo info;
std::istringstream iss(line);
std::string token;
- // 浣跨敤鍒嗛殧绗� "|" 瑙f瀽瀛楃涓�
+ // 使用分隔符 "|" 解析字符串
std::getline(iss, token, '|');
info.nErrorCode = std::stoi(token);
@@ -336,47 +336,47 @@
}
};
-using BitContainer = std::vector<bool>; // 姣忎釜鍏冪礌瀛樺偍 1 浣�
-using WordContainer = std::vector<uint16_t>; // 姣忎釜鍏冪礌瀛樺偍 16 浣�
-using DWordContainer = std::vector<uint32_t>; // 姣忎釜鍏冪礌瀛樺偍 32 浣�
+using BitContainer = std::vector<bool>; // 每个元素存储 1 位
+using WordContainer = std::vector<uint16_t>; // 每个元素存储 16 位
+using DWordContainer = std::vector<uint32_t>; // 每个元素存储 32 位
-// CPerformanceMelsec 绫诲0鏄�
+// CPerformanceMelsec 类声明
class CPerformanceMelsec {
public:
- // 鑾峰彇鏈�杩戠殑閿欒淇℃伅
+ // 获取最近的错误信息
std::string GetLastError() const;
- // 閿欒淇℃伅鍔犺浇涓庝繚瀛樻帴鍙�
- static bool LoadErrorInfoFromFile(const std::string& filename); // 浠庢枃浠跺姞杞介敊璇俊鎭�
- static bool SaveErrorInfoToFile(const std::string& filename); // 淇濆瓨閿欒淇℃伅鍒版枃浠�
+ // 错误信息加载与保存接口
+ static bool LoadErrorInfoFromFile(const std::string& filename); // 从文件加载错误信息
+ static bool SaveErrorInfoToFile(const std::string& filename); // 保存错误信息到文件
- // 杩炴帴/鏂紑
+ // 连接/断开
int Connect(short nChannel, short nMode = -1);
int Disconnect();
- // 鍒濆鍖栧彲缂栫▼鎺у埗鍣ㄨ蒋鍏冧欢淇℃伅琛�
+ // 初始化可编程控制器软元件信息表
int InitializeController();
- // 鑾峰彇鐗堟湰淇℃伅
+ // 获取版本信息
int GetBoardVersion(BoardVersion& version);
- // 鏉垮浣�
+ // 板复位
int BoardReset();
- // 鏉縇ED璇诲彇
+ // 板LED读取
int ReadBoardLed(std::vector<short>& vecLedBuffer);
- // 璇诲彇鐩爣绔欑偣CPU绫诲瀷
+ // 读取目标站点CPU类型
int ReadCPUCode(const StationIdentifier& station, short& nCPUCode);
- // 鏉挎ā寮忚幏鍙�/璁剧疆
+ // 板模式获取/设置
int SetBoardMode(short nMode);
int GetBoardMode(short& nMode);
- // 鑾峰彇鏉跨姸鎬�
+ // 获取板状态
int GetBoardStatus(BoardStatus& status);
- // 璇诲啓鏁版嵁
+ // 读写数据
int ReadData(const StationIdentifier& station, short nDevType, short nDevNo, short nSize, std::vector<short>& vecData);
int ReadBitData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, short nBitCount, BitContainer& vecData);
int ReadWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, short nWordCount, WordContainer& vecData);
@@ -386,60 +386,60 @@
int WriteWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, const WordContainer& vecData);
int WriteDWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, const DWordContainer& vecData);
- // 鎵╁睍璇诲啓鏁版嵁
+ // 扩展读写数据
long ReadDataEx(const StationIdentifier& station, long nDevType, long nDevNo, long nSize, std::vector<char>& vecData);
long WriteDataEx(const StationIdentifier& station, long nDevType, long nDevNo, const std::vector<char>& vecData);
- // 鎵╁睍杞厓浠堕殢鏈鸿鍐欙紙鏀寔澶氫釜杞厓浠讹級
+ // 扩展软元件随机读写(支持多个软元件)
long ReadRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, std::vector<char>& vecData);
long WriteRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, const std::vector<char>& vecData);
- // 杩滅▼璁惧绔�/杩滅▼绔欑殑缂撳啿瀛樺偍鍣ㄨ鍐�
+ // 远程设备站/远程站的缓冲存储器读写
long ReadRemoteBuffer(const StationIdentifier& station, long nOffset, long nSize, std::vector<char>& vecData);
long WriteRemoteBuffer(const StationIdentifier& station, long nOffset, const std::vector<char>& vecData);
long ReadRemoteBufferByIp(const std::string& strIP, long nOffset, long nSize, std::vector<char>& vecData);
long WriteRemoteBufferByIp(const std::string& strIP, long nOffset, const std::vector<char>& vecData);
- // 璁剧疆/澶嶄綅瀵硅薄绔欑殑鎸囧畾浣嶈蒋鍏冧欢
+ // 设置/复位对象站的指定位软元件
int SetBitDevice(const StationIdentifier& station, DeviceType enDevType, short nDevNo);
int ResetBitDevice(const StationIdentifier& station, DeviceType enDevType, short enDevNo);
- // 鎵╁睍璁剧疆/澶嶄綅瀵硅薄绔欑殑鎸囧畾浣嶈蒋鍏冧欢
+ // 扩展设置/复位对象站的指定位软元件
long SetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo);
long ResetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo);
- // 鎵ц瀵硅薄绔欑殑CPU
+ // 执行对象站的CPU
int ControlCPU(const StationIdentifier& station, ControlCode enControlCode);
- // 浜嬩欢绛夊緟锛寁ecEventNumbers[0, 64]锛宯TimeoutMs[-1, 2147483647]
- // 鍚屾椂鍙戠敓浜嗗涓簨浠剁殑鎯呭喌涓嬶紝棣栧厛妫�娴嬪嚭鍏朵腑涓�涓簨浠躲�� 鍐嶆鎵ц浜嗘湰鍑芥暟鐨勬儏鍐典笅妫�娴嬪嚭鍏跺畠浜嬩欢銆�
+ // 事件等待,vecEventNumbers[0, 64],nTimeoutMs[-1, 2147483647]
+ // 同时发生了多个事件的情况下,首先检测出其中一个事件。 再次执行了本函数的情况下检测出其它事件。
int WaitForBoardEvent(std::vector<short> vecEventNumbers, int nTimeoutMs, EventDetails& details);
private:
- // 閿佸畾涓庤В閿侊紙澶氱嚎绋嬪悓姝ヤ繚鎶わ級
+ // 锁定与解锁(多线程同步保护)
void Lock() { m_mtx.lock(); }
void Unlock() { m_mtx.unlock(); }
protected:
- // 鏋勯�犲嚱鏁�/鏋愭瀯鍑芥暟
+ // 构造函数/析构函数
explicit CPerformanceMelsec(BoardType enBoardType);
virtual ~CPerformanceMelsec();
- // 杈呭姪鍑芥暟
- void UpdateLastError(int nCode); // 鏇存柊鏈�杩戠殑閿欒淇℃伅
- int ValidateStation(const StationIdentifier& station) const; // 妫�鏌ヨ繛鎺ョ姸鎬佸拰绔欑偣鍙傛暟鏈夋晥鎬�
+ // 辅助函数
+ void UpdateLastError(int nCode); // 更新最近的错误信息
+ int ValidateStation(const StationIdentifier& station) const; // 检查连接状态和站点参数有效性
int ValidateStationAndSize(const StationIdentifier& station, short nCount) const;
- // 闈欐�佽緟鍔╁嚱鏁�
- static void Delay(unsigned int nDelayMs); // 寤舵椂锛屽苟涓旇浆鍙戠獥鍙f秷鎭�
- static BoardType FindBoardTypeByChannel(int nChannel); // 鏌ユ壘鏉垮潡绫诲瀷
- static short CombineStation(const StationIdentifier& station); // 鍚堝苟缃戠粶鍙峰拰绔欑偣鍙�
- static short CalculateDeviceType(const StationIdentifier& station, DeviceType enDevType); // 璁$畻杞厓浠剁被鍨�
+ // 静态辅助函数
+ static void Delay(unsigned int nDelayMs); // 延时,并且转发窗口消息
+ static BoardType FindBoardTypeByChannel(int nChannel); // 查找板块类型
+ static short CombineStation(const StationIdentifier& station); // 合并网络号和站点号
+ static short CalculateDeviceType(const StationIdentifier& station, DeviceType enDevType); // 计算软元件类型
- // IP杞崲
+ // IP转换
static bool ConvertIpStringToUint32(const std::string& strIP, uint32_t& nIP);
- // 瀹瑰櫒杞崲
+ // 容器转换
static void ConvertCharToShort(const std::vector<char>& vecChar, std::vector<short>& vecShort);
static void ConvertShortToChar(const std::vector<short>& vecShort, std::vector<char>& vecChar);
static void ConvertUint8ToShort(const std::vector<uint8_t>& vecUint8, std::vector<short>& vecShort);
@@ -447,7 +447,7 @@
static void ConvertUint32ToShort(const std::vector<uint32_t>& vecUint32, std::vector<short>& vecShort);
static void ConvertShortToUint32(const std::vector<short>& vecShort, std::vector<uint32_t>& vecUint32);
- // 妯℃澘杈呭姪鍑芥暟
+ // 模板辅助函数
template <typename T>
int ValidateStationAndData(const StationIdentifier& station, const std::vector<T>& vecData);
@@ -457,15 +457,15 @@
template <typename T, typename U>
void ConvertHighToLow(const std::vector<T>& vecHigh, std::vector<U>& vecLow);
- // 鎴愬憳鍙橀噺
- std::mutex m_mtx; // 浜掓枼閿佷繚鎶�
- BoardType m_enBoardType; // 鏉垮潡绫诲瀷
- long m_nPath; // 閫氫俊璺緞
- std::atomic<bool> m_bConnected; // 鏄惁宸茶繛鎺�
- std::string m_strLastError; // 鏈�杩戜竴娆¢敊璇俊鎭�
+ // 成员变量
+ std::mutex m_mtx; // 互斥锁保护
+ BoardType m_enBoardType; // 板块类型
+ long m_nPath; // 通信路径
+ std::atomic<bool> m_bConnected; // 是否已连接
+ std::string m_strLastError; // 最近一次错误信息
- // 闈欐�佹垚鍛樺彉閲�
- static std::unordered_map<int, std::string> m_mapError; // 閿欒鐮佹槧灏勮〃
+ // 静态成员变量
+ static std::unordered_map<int, std::string> m_mapError; // 错误码映射表
};
#endif // PERFORMANCE_MELSEC_H
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/CEqAlarmStep.cpp b/SourceCode/Bond/Servo/CEqAlarmStep.cpp
index 0b42394..67247eb 100644
--- a/SourceCode/Bond/Servo/CEqAlarmStep.cpp
+++ b/SourceCode/Bond/Servo/CEqAlarmStep.cpp
@@ -5,7 +5,7 @@
namespace SERVO {
- CEqAlarmStep::CEqAlarmStep() : CStep()
+ CEqAlarmStep::CEqAlarmStep() : CReadStep()
{
m_nAlarmDev = 0;
m_nAlarmState = 0;
@@ -19,9 +19,30 @@
{
}
+
+ void CEqAlarmStep::getAttributeVector(CAttributeVector& attrubutes)
+ {
+ CReadStep::getAttributeVector(attrubutes);
+
+ attrubutes.addAttribute(new CAttribute("Alarm State",
+ std::to_string(m_nAlarmState).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Unit ID",
+ std::to_string(m_nUnitId).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Alarm Level",
+ std::to_string(m_nAlarmLevel).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Alarm Code",
+ std::to_string(m_nAlarmCode).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Alarm ID",
+ std::to_string(m_nAlarmId).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Text",
+ m_strText.c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Description",
+ m_strDescription.c_str(), ""));
+ }
+
int CEqAlarmStep::onReadData()
{
- CStep::onReadData();
+ CReadStep::onReadData();
char szBuffer[64];
int nRet = m_pCclink->ReadData2(m_station, DeviceType::W,
@@ -45,7 +66,7 @@
int CEqAlarmStep::onComplete()
{
- CStep::onComplete();
+ CReadStep::onComplete();
LOGI("<CEqAlarmStep> onComplete.");
return 0;
@@ -53,7 +74,7 @@
int CEqAlarmStep::onTimeout()
{
- CStep::onTimeout();
+ CReadStep::onTimeout();
LOGI("<CEqAlarmStep> onTimeout.");
return 0;
@@ -122,12 +143,28 @@
m_strText = strText;
}
- // 获取和设置 Description
- std::string CEqAlarmStep::getDescription() const {
- return m_strDescription;
+ int CEqAlarmStep::getAlarmState()
+ {
+ return m_nAlarmState;
}
- void CEqAlarmStep::setDescription(const std::string& strDescription) {
- m_strDescription = strDescription;
+ int CEqAlarmStep::getUnitId()
+ {
+ return m_nUnitId;
+ }
+
+ int CEqAlarmStep::getAlarmLevel()
+ {
+ return m_nAlarmLevel;
+ }
+
+ int CEqAlarmStep::getAlarmCode()
+ {
+ return m_nAlarmCode;
+ }
+
+ int CEqAlarmStep::getAlarmId()
+ {
+ return m_nAlarmId;
}
}
diff --git a/SourceCode/Bond/Servo/CEqAlarmStep.h b/SourceCode/Bond/Servo/CEqAlarmStep.h
index 98cc3bc..7c33958 100644
--- a/SourceCode/Bond/Servo/CEqAlarmStep.h
+++ b/SourceCode/Bond/Servo/CEqAlarmStep.h
@@ -1,44 +1,25 @@
#pragma once
-#include "CStep.h"
+#include "CReadStep.h"
namespace SERVO {
- class CEqAlarmStep : public CStep
+ class CEqAlarmStep : public CReadStep
{
public:
CEqAlarmStep();
~CEqAlarmStep();
public:
+ virtual void getAttributeVector(CAttributeVector& attrubutes);
virtual int onReadData();
virtual int onComplete();
virtual int onTimeout();
-
- // Getter 和 Setter 声明
- int getAlarmDev() const;
- void setAlarmDev(int nAlarmDev);
-
- int getAlarmState() const;
- void setAlarmState(int nAlarmState);
-
- int getUnitId() const;
- void setUnitId(int nUnitId);
-
- int getAlarmLevel() const;
- void setAlarmLevel(int nAlarmLevel);
-
- int getAlarmCode() const;
- void setAlarmCode(int nAlarmCode);
-
- int getAlarmId() const;
- void setAlarmId(int nAlarmId);
-
- std::string getText() const;
- void setText(const std::string& strText);
-
- std::string getDescription() const;
- void setDescription(const std::string& strDescription);
-
+ void setAlarmDev(int nDev);
+ int getAlarmState();
+ int getUnitId();
+ int getAlarmLevel();
+ int getAlarmCode();
+ int getAlarmId();
private:
int m_nAlarmDev;
diff --git a/SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp b/SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp
new file mode 100644
index 0000000..9e2d40c
--- /dev/null
+++ b/SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp
@@ -0,0 +1,45 @@
+#include "stdafx.h"
+#include "CEqCimModeChangeStep.h"
+
+
+namespace SERVO {
+ CEqCimModeChangeStep::CEqCimModeChangeStep() : CWriteStep()
+ {
+ m_nCimModeDev = 0;
+ }
+
+ CEqCimModeChangeStep::~CEqCimModeChangeStep()
+ {
+
+ }
+
+ void CEqCimModeChangeStep::setCimModeDev(int nDev)
+ {
+ m_nCimModeDev = nDev;
+ }
+
+ int CEqCimModeChangeStep::cimOn()
+ {
+ short mode = 1;
+ return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
+ }
+
+ int CEqCimModeChangeStep::cimOff()
+ {
+ short mode = 2;
+ return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
+ }
+
+ int CEqCimModeChangeStep::setCimMode(short mode)
+ {
+ return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
+ }
+
+ void CEqCimModeChangeStep::getAttributeVector(CAttributeVector& attrubutes)
+ {
+ CWriteStep::getAttributeVector(attrubutes);
+
+ attrubutes.addAttribute(new CAttribute("Cim Mode Dev",
+ std::to_string(m_nCimModeDev).c_str(), ""));
+ }
+}
diff --git a/SourceCode/Bond/Servo/CEqCimModeChangeStep.h b/SourceCode/Bond/Servo/CEqCimModeChangeStep.h
new file mode 100644
index 0000000..22afc6a
--- /dev/null
+++ b/SourceCode/Bond/Servo/CEqCimModeChangeStep.h
@@ -0,0 +1,23 @@
+#pragma once
+#include "CWriteStep.h"
+
+
+namespace SERVO {
+ class CEqCimModeChangeStep : public CWriteStep
+ {
+ public:
+ CEqCimModeChangeStep();
+ ~CEqCimModeChangeStep();
+
+ public:
+ void setCimModeDev(int nDev);
+ int cimOn();
+ int cimOff();
+ int setCimMode(short mode);
+ void getAttributeVector(CAttributeVector& attrubutes);
+
+ private:
+ int m_nCimModeDev;
+ };
+}
+
diff --git a/SourceCode/Bond/Servo/CEqModeStep.cpp b/SourceCode/Bond/Servo/CEqModeStep.cpp
index 888117b..3b416b2 100644
--- a/SourceCode/Bond/Servo/CEqModeStep.cpp
+++ b/SourceCode/Bond/Servo/CEqModeStep.cpp
@@ -4,7 +4,7 @@
namespace SERVO {
- CEqModeStep::CEqModeStep() : CStep()
+ CEqModeStep::CEqModeStep() : CReadStep()
{
m_nModeDev = 0;
m_nMode = 0;
@@ -15,9 +15,20 @@
}
+ void CEqModeStep::getAttributeVector(CAttributeVector& attrubutes)
+ {
+ CReadStep::getAttributeVector(attrubutes);
+
+ std::string strTemp;
+ attrubutes.addAttribute(new CAttribute("Mode",
+ std::to_string(m_nMode).c_str(), getModeDescription(strTemp).c_str()));
+ attrubutes.addAttribute(new CAttribute("Mode Dev",
+ std::to_string(m_nModeDev).c_str(), ""));
+ }
+
int CEqModeStep::onReadData()
{
- CStep::onReadData();
+ CReadStep::onReadData();
DWordContainer dc;
if (0 != m_pCclink->ReadDWordData(m_station, DeviceType::W, m_nModeDev, 1, dc)) {
@@ -37,7 +48,7 @@
int CEqModeStep::onComplete()
{
- CStep::onComplete();
+ CReadStep::onComplete();
LOGI("<CEqModeStep> onComplete.");
return 0;
@@ -45,7 +56,7 @@
int CEqModeStep::onTimeout()
{
- CStep::onTimeout();
+ CReadStep::onTimeout();
LOGI("<CEqModeStep> onTimeout.");
return 0;
@@ -56,6 +67,11 @@
m_nModeDev = nDev;
}
+ int CEqModeStep::getMode()
+ {
+ return m_nMode;
+ }
+
/*
0: No Equipment Mode exist
1: Normal Mode
diff --git a/SourceCode/Bond/Servo/CEqModeStep.h b/SourceCode/Bond/Servo/CEqModeStep.h
index c91c5fa..1bc611d 100644
--- a/SourceCode/Bond/Servo/CEqModeStep.h
+++ b/SourceCode/Bond/Servo/CEqModeStep.h
@@ -1,19 +1,21 @@
#pragma once
-#include "CStep.h"
+#include "CReadStep.h"
namespace SERVO {
- class CEqModeStep : public CStep
+ class CEqModeStep : public CReadStep
{
public:
CEqModeStep();
~CEqModeStep();
public:
+ virtual void getAttributeVector(CAttributeVector& attrubutes);
virtual int onReadData();
virtual int onComplete();
virtual int onTimeout();
void setModeDev(int nDev);
+ int getMode();
std::string& getModeDescription(std::string& strDescription);
private:
diff --git a/SourceCode/Bond/Servo/CEqProcessStep.cpp b/SourceCode/Bond/Servo/CEqProcessStep.cpp
new file mode 100644
index 0000000..f566e43
--- /dev/null
+++ b/SourceCode/Bond/Servo/CEqProcessStep.cpp
@@ -0,0 +1,160 @@
+#include "stdafx.h"
+#include "Common.h"
+#include "CEqProcessStep.h"
+#include "Log.h"
+#include "ToolUnits.h"
+
+
+namespace SERVO {
+ CEqProcessStep::CEqProcessStep() : CReadStep()
+ {
+ m_nProcessDev = 0;
+ m_nTotalParameter = 0;
+ }
+
+ CEqProcessStep::~CEqProcessStep()
+ {
+
+ }
+
+ void CEqProcessStep::getAttributeVector(CAttributeVector& attrubutes)
+ {
+ CReadStep::getAttributeVector(attrubutes);
+
+ attrubutes.addAttribute(new CAttribute("Glass ID",
+ m_strGlassId.c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Start Time",
+ m_strStartTime.c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("End Time",
+ m_strEndTime.c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Total Parameter",
+ std::to_string(m_nTotalParameter).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Total Group",
+ std::to_string(m_nTotalGroup).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Current Group",
+ std::to_string(m_nCurrentGroup).c_str(), ""));
+
+ char szName[256];
+ int index = 0;
+ for (auto item : m_params) {
+ sprintf_s(szName, 256, "Parameter %d", ++index);
+ attrubutes.addAttribute(new CAttribute(szName,
+ item.c_str(), ""));
+ }
+ }
+
+#define PROGRESS_BUF_SIZE (1024 + 64)
+ int CEqProcessStep::onReadData()
+ {
+ CReadStep::onReadData();
+
+ // W1864 ~ W1A74, 529个word, 1058 bytes
+ char szBuffer[PROGRESS_BUF_SIZE];
+ int nRet = m_pCclink->ReadData2(m_station, DeviceType::W,
+ m_nProcessDev, PROGRESS_BUF_SIZE, szBuffer);
+ if (0 != nRet) {
+ return -1;
+ }
+
+ // 解释数据
+ // Glass ID(1864~186D)
+ int index = 0;
+ convertString(&szBuffer[index], (0x186d - 0x1864 + 1) * 2, m_strStartTime);
+ index += (0x186d - 0x1864 + 1) * 2;
+
+ // Process Start Time(186e~1875)
+ convertString(&szBuffer[index], (0x1875 - 0x186e + 1) * 2, m_strStartTime);
+ index += (0x1875 - 0x186e + 1) * 2;
+
+ // Process End Time(1876~187d)
+ convertString(&szBuffer[index], (0x187d - 0x1876 + 1) * 2, m_strEndTime);
+ index += (0x187d - 0x1876 + 1) * 2;
+
+ // parameter count
+ m_nTotalParameter = (unsigned int)CToolUnits::toInt16(&szBuffer[index]);
+ index += 2;
+
+ // total group
+ m_nTotalGroup = (unsigned int)CToolUnits::toInt16(&szBuffer[index]);
+ index += 2;
+
+ // current group
+ m_nCurrentGroup = (unsigned int)CToolUnits::toInt16(&szBuffer[index]);
+ index += 2;
+
+ // param list(0x1881~0x1a74), 共1000 bytes, 20个字符为一个参数, 50组
+ // 最后一group可能不满足50, 以m_nTotalParameter为依据
+ int size = (m_nCurrentGroup == m_nTotalGroup) ? m_nTotalParameter % 50 : 50;
+ for (int i = 0; i < size; i++) {
+ std::string strParam;
+ convertString(&szBuffer[index], 20, strParam);
+ if (!strParam.empty()) {
+ m_params.push_back(strParam);
+ }
+ index += 20;
+ }
+
+ if (m_nCurrentGroup == m_nTotalGroup && m_listener.onEvent != nullptr) {
+ m_listener.onEvent(this, STEP_EVENT_PROCESS_DATA, nullptr);
+ }
+
+
+ LOGI("<CEqProcessStep> Process Data<GlassId:%s>\n",
+ m_strGlassId.c_str());
+
+ return 0;
+ }
+
+ int CEqProcessStep::onComplete()
+ {
+ CReadStep::onComplete();
+ LOGI("<CEqProcessStep> onComplete.");
+
+ return 0;
+ }
+
+ int CEqProcessStep::onTimeout()
+ {
+ CReadStep::onTimeout();
+ LOGI("<CEqProcessStep> onTimeout.");
+
+ return 0;
+ }
+
+ void CEqProcessStep::setProcessDev(int nDev)
+ {
+ m_nProcessDev = nDev;
+ }
+
+ std::string& CEqProcessStep::getGlassId()
+ {
+ return m_strGlassId;
+ }
+
+ std::string& CEqProcessStep::getStartTime()
+ {
+ return m_strStartTime;
+ }
+
+ std::string& CEqProcessStep::getEndTime()
+ {
+ return m_strEndTime;
+ }
+
+ unsigned int CEqProcessStep::getTotalParameter()
+ {
+ return m_nTotalParameter;
+ }
+
+ const std::list<std::string> CEqProcessStep::getParameters()
+ {
+ return m_params;
+ }
+
+ void CEqProcessStep::getParameters(std::list<std::string>& list)
+ {
+ Lock();
+ std::copy(m_params.begin(), m_params.end(), std::back_inserter(list));
+ Unlock();
+ }
+}
diff --git a/SourceCode/Bond/Servo/CEqProcessStep.h b/SourceCode/Bond/Servo/CEqProcessStep.h
new file mode 100644
index 0000000..d16a5a0
--- /dev/null
+++ b/SourceCode/Bond/Servo/CEqProcessStep.h
@@ -0,0 +1,37 @@
+#pragma once
+#include "CReadStep.h"
+#include <list>
+
+
+namespace SERVO {
+ class CEqProcessStep : public CReadStep
+ {
+ public:
+ CEqProcessStep();
+ ~CEqProcessStep();
+
+ public:
+ void getAttributeVector(CAttributeVector& attrubutes);
+ virtual int onReadData();
+ virtual int onComplete();
+ virtual int onTimeout();
+ void setProcessDev(int nDev);
+ std::string& getGlassId();
+ std::string& getStartTime();
+ std::string& getEndTime();
+ unsigned int getTotalParameter();
+ const std::list<std::string> getParameters();
+ void getParameters(std::list<std::string>& list);
+
+ private:
+ int m_nProcessDev;
+ std::string m_strGlassId;
+ std::string m_strStartTime;
+ std::string m_strEndTime;
+ unsigned int m_nTotalParameter;
+ unsigned int m_nTotalGroup;
+ unsigned int m_nCurrentGroup;
+ std::list<std::string> m_params;
+ };
+}
+
diff --git a/SourceCode/Bond/Servo/CEqStatusStep.cpp b/SourceCode/Bond/Servo/CEqStatusStep.cpp
index 9df8a03..b525e6f 100644
--- a/SourceCode/Bond/Servo/CEqStatusStep.cpp
+++ b/SourceCode/Bond/Servo/CEqStatusStep.cpp
@@ -5,7 +5,7 @@
namespace SERVO {
- CEqStatusStep::CEqStatusStep() : CStep()
+ CEqStatusStep::CEqStatusStep() : CReadStep()
{
m_nStatusDev = 0;
for (int i = 0; i < STATUS_MAX; i++) {
@@ -21,9 +21,35 @@
}
+ void CEqStatusStep::getAttributeVector(CAttributeVector& attrubutes)
+ {
+ CReadStep::getAttributeVector(attrubutes);
+
+ char szName[256];
+ for (int i = 0; i < STATUS_MAX; i++) {
+ sprintf_s(szName, 256, "Status %d", i + 1);
+ attrubutes.addAttribute(new CAttribute(szName,
+ std::to_string(m_nStatus[i]).c_str(), ""));
+ sprintf_s(szName, 256, "Reason Code %d", i + 1);
+ attrubutes.addAttribute(new CAttribute(szName,
+ std::to_string(m_nReasonCode[i]).c_str(), ""));
+ }
+
+ attrubutes.addAttribute(new CAttribute("Status Dev",
+ std::to_string(m_nStatusDev).c_str(), ""));
+ }
+
+ int CEqStatusStep::getStatus(unsigned int uint)
+ {
+ if (uint < STATUS_MAX) {
+ return m_nStatus[uint];
+ }
+
+ return -1;
+ }
int CEqStatusStep::onReadData()
{
- CStep::onReadData();
+ CReadStep::onReadData();
char szBuffer[64];
int nRet = m_pCclink->ReadData2(m_station, DeviceType::W,
@@ -56,7 +82,7 @@
int CEqStatusStep::onComplete()
{
- CStep::onComplete();
+ CReadStep::onComplete();
LOGI("<CEqStatusStep> onComplete.");
return 0;
@@ -64,7 +90,7 @@
int CEqStatusStep::onTimeout()
{
- CStep::onTimeout();
+ CReadStep::onTimeout();
LOGI("<CEqStatusStep> onTimeout.");
return 0;
diff --git a/SourceCode/Bond/Servo/CEqStatusStep.h b/SourceCode/Bond/Servo/CEqStatusStep.h
index 09fc8f4..f99e813 100644
--- a/SourceCode/Bond/Servo/CEqStatusStep.h
+++ b/SourceCode/Bond/Servo/CEqStatusStep.h
@@ -1,22 +1,24 @@
#pragma once
-#include "CStep.h"
+#include "CReadStep.h"
namespace SERVO {
#define UNIT_MAX 6
#define STATUS_MAX (UNIT_MAX + 1)
- class CEqStatusStep : public CStep
+ class CEqStatusStep : public CReadStep
{
public:
CEqStatusStep();
~CEqStatusStep();
public:
+ virtual void getAttributeVector(CAttributeVector& attrubutes);
virtual int onReadData();
virtual int onComplete();
virtual int onTimeout();
void setStatusDev(int nDev);
+ int getStatus(unsigned int uint);
std::string& getStatusDescription(unsigned int unid, std::string& strDescription);
private:
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index 2c6b8e6..3fa85bb 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -16,6 +16,7 @@
m_bAutoRecipeChange = FALSE;
m_bVCREnable[0] = FALSE;
m_pCclink = nullptr;
+ m_nBaseAlarmId = 0;
InitializeCriticalSection(&m_criticalSection);
}
@@ -40,6 +41,16 @@
m_pCclink = pCcLink;
}
+ void CEquipment::setBaseAlarmId(int nBaseId)
+ {
+ m_nBaseAlarmId = nBaseId;
+ }
+
+ int CEquipment::getBaseAlarmId()
+ {
+ return m_nBaseAlarmId;
+ }
+
void CEquipment::getProperties(std::vector<std::pair<std::string, std::string>>& container)
{
container.clear();
@@ -47,6 +58,11 @@
container.push_back(std::make_pair("DeviceName", "ServoMotor"));
container.push_back(std::make_pair("SerialNumber", "123456789"));
container.push_back(std::make_pair("Version", "1.0"));
+ }
+
+ std::map<unsigned int, CStep*>& CEquipment::getSteps()
+ {
+ return m_mapStep;
}
CStep* CEquipment::getStep(unsigned int addr)
@@ -251,9 +267,16 @@
bFlag = isBitOn(pszData, size, index);
pStep = getStep(index);
if (pStep != nullptr) {
- pStep->onSignal(bFlag);
+ ((CReadStep*)pStep)->onReadSignal(bFlag);
}
}
+
+ index = 0x350;
+ bFlag = isBitOn(pszData, size, index);
+ pStep = getStep(index);
+ if (pStep != nullptr) {
+ ((CWriteStep*)pStep)->onRecvSignal(bFlag);
+ }
}
BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index)
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index 2bdbc4d..c13e71e 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -4,6 +4,8 @@
#include "CEqModeStep.h"
#include "CEqStatusStep.h"
#include "CEqAlarmStep.h"
+#include "CEqProcessStep.h"
+#include "CEqCimModeChangeStep.h"
#include <map>
@@ -46,6 +48,8 @@
virtual const char* getClassName() = 0;
virtual void setListener(EquipmentListener listener);
void setCcLink(CCCLinkIEControl* pCcLink);
+ void setBaseAlarmId(int nBaseId);
+ int getBaseAlarmId();
void setID(int nID);
int getID();
void setName(const char* pszName);
@@ -61,6 +65,7 @@
void getProperties(std::vector<std::pair<std::string, std::string>>& container);
int addStep(unsigned int addr, CStep* pStep);
CStep* getStep(unsigned int addr);
+ std::map<unsigned int, CStep*>& getSteps();
virtual void init();
virtual void term();
virtual void onTimer(UINT nTimerid);
@@ -110,6 +115,7 @@
private:
CCCLinkIEControl* m_pCclink;
std::map<unsigned int, CStep*> m_mapStep;
+ int m_nBaseAlarmId;
};
}
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 82d77ca..7040c70 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -74,7 +74,7 @@
// 初始化添加各子设备
addEFEM(listener);
- /*
+
{
CBonder* pBonder = new CBonder();
pBonder->setName("Bonder 1");
@@ -84,7 +84,7 @@
addEquipment(pBonder);
LOGE("已添加“Bonder 1”.");
}
- */
+
// 定时器
g_pMaster = this;
@@ -127,6 +127,11 @@
return 0;
}
+ std::list<CEquipment*>& CMaster::getEquipmentList()
+ {
+ return m_listEquipment;
+ }
+
CEquipment* CMaster::getEquipment(int id)
{
for (auto item : m_listEquipment) {
@@ -140,6 +145,7 @@
{
CEFEM* pEquipment = new CEFEM();
pEquipment->setID(EQ_ID_EFEM);
+ pEquipment->setBaseAlarmId(BASE_ALARM_EFEM);
pEquipment->setName("EFEM(ROBOT)");
pEquipment->setDescription("EFEM(ROBOT).");
pEquipment->setReadBitBlock(0x4000, 0x45ff);
@@ -150,7 +156,7 @@
// 添加 step
{
CEqModeStep* pStep = new CEqModeStep();
- pStep->setName("EQMode");
+ pStep->setName(STEP_MODE);
pStep->setListener(listener);
pStep->setWriteSignalDev(0x30);
pStep->setModeDev(0x4a8c);
@@ -160,7 +166,7 @@
}
{
CEqStatusStep* pStep = new CEqStatusStep();
- pStep->setName("EQStatus");
+ pStep->setName(STEP_STATUS);
pStep->setListener(listener);
pStep->setWriteSignalDev(0x31);
pStep->setStatusDev(0x4a68);
@@ -170,7 +176,7 @@
}
{
CEqAlarmStep* pStep = new CEqAlarmStep();
- pStep->setName("EQAlarm1");
+ pStep->setName(STEP_ALARM_BLOCK1);
pStep->setListener(listener);
pStep->setWriteSignalDev(0x32);
pStep->setAlarmDev(0x4c1d);
@@ -180,7 +186,7 @@
}
{
CEqAlarmStep* pStep = new CEqAlarmStep();
- pStep->setName("EQAlarm2");
+ pStep->setName(STEP_ALARM_BLOCK2);
pStep->setListener(listener);
pStep->setWriteSignalDev(0x33);
pStep->setAlarmDev(0x4c4a);
@@ -190,7 +196,7 @@
}
{
CEqAlarmStep* pStep = new CEqAlarmStep();
- pStep->setName("EQAlarm3");
+ pStep->setName(STEP_ALARM_BLOCK3);
pStep->setListener(listener);
pStep->setWriteSignalDev(0x34);
pStep->setAlarmDev(0x4c77);
@@ -200,7 +206,7 @@
}
{
CEqAlarmStep* pStep = new CEqAlarmStep();
- pStep->setName("EQAlarm4");
+ pStep->setName(STEP_ALARM_BLOCK4);
pStep->setListener(listener);
pStep->setWriteSignalDev(0x35);
pStep->setAlarmDev(0x4ca4);
@@ -210,7 +216,7 @@
}
{
CEqAlarmStep* pStep = new CEqAlarmStep();
- pStep->setName("EQAlarm5");
+ pStep->setName(STEP_ALARM_BLOCK5);
pStep->setListener(listener);
pStep->setWriteSignalDev(0x36);
pStep->setAlarmDev(0x4cd1);
@@ -218,6 +224,26 @@
delete pStep;
}
}
+ {
+ CEqProcessStep* pStep = new CEqProcessStep();
+ pStep->setName(STEP_PROCESS);
+ pStep->setListener(listener);
+ pStep->setWriteSignalDev(0x37);
+ pStep->setProcessDev(0x1864);
+ if (pEquipment->addStep(0x367, pStep) != 0) {
+ delete pStep;
+ }
+ }
+ {
+ CEqCimModeChangeStep* pStep = new CEqCimModeChangeStep();
+ pStep->setName(STEP_CIM_MODE_CHANGE);
+ pStep->setListener(listener);
+ pStep->setWriteSignalDev(0x50);
+ pStep->setCimModeDev(0x15);
+ if (pEquipment->addStep(0x350, pStep) != 0) {
+ delete pStep;
+ }
+ }
pEquipment->init();
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index 73ae99b..0fefda3 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/SourceCode/Bond/Servo/CMaster.h
@@ -28,6 +28,7 @@
int init();
int term();
void onTimer(UINT nTimerid);
+ std::list<CEquipment*>& getEquipmentList();
CEquipment* getEquipment(int id);
private:
diff --git a/SourceCode/Bond/Servo/CPanelAttributes.cpp b/SourceCode/Bond/Servo/CPanelAttributes.cpp
new file mode 100644
index 0000000..fb2200b
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPanelAttributes.cpp
@@ -0,0 +1,192 @@
+锘�// CPanelAttributes.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "Servo.h"
+#include "CPanelAttributes.h"
+#include "afxdialogex.h"
+#include "common.h"
+#include "VerticalLine.h"
+
+
+// CPanelAttributes 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CPanelAttributes, CDialogEx)
+
+CPanelAttributes::CPanelAttributes(CWnd* pParent /*=nullptr*/)
+ : CDialogEx(IDD_PANEL_ATTRIBUTES, pParent)
+{
+ m_crBkgnd = PANEL_ATTRIBUTES_BACKGROUND_COLOR;
+ m_hbrBkgnd = nullptr;
+ m_nPanelWidth = 188;
+}
+
+CPanelAttributes::~CPanelAttributes()
+{
+}
+
+void CPanelAttributes::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_MFCPROPERTYGRID1, m_gridCtrl);
+}
+
+
+BEGIN_MESSAGE_MAP(CPanelAttributes, CDialogEx)
+ ON_WM_CTLCOLOR()
+ ON_WM_DESTROY()
+ ON_WM_SIZE()
+ ON_NOTIFY(BYVERTICALLINE_MOVEX, IDC_LINE1, &CPanelAttributes::OnVLineMoveX)
+ ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CPanelAttributes::OnBnClickedButtonClose)
+END_MESSAGE_MAP()
+
+
+// CPanelAttributes 娑堟伅澶勭悊绋嬪簭
+
+
+int CPanelAttributes::getPanelWidth()
+{
+ return m_nPanelWidth;
+}
+
+void CPanelAttributes::loadDataFromStep(SERVO::CStep* pStep)
+{
+ // 鍏堟竻绌烘墍鏈�
+ m_gridCtrl.RemoveAll();
+
+
+ // 鍔犺浇鏁版嵁
+ SetDlgItemText(IDC_LABEL_TITLE, pStep->getName().c_str());
+ SERVO::CAttributeVector attrubutes;
+ pStep->getAttributeVector(attrubutes);
+ unsigned int nSize = attrubutes.size();
+ for (unsigned int i = 0; i < nSize; i++) {
+ SERVO::CAttribute* pAttribute = attrubutes.getAttribute(i);
+ CMFCPropertyGridProperty* pProperty = new CMFCPropertyGridProperty(
+ pAttribute->getName().c_str(),
+ pAttribute->getValue().c_str(),
+ pAttribute->getDescription().c_str());
+ pProperty->AllowEdit(TRUE);
+ m_gridCtrl.AddProperty(pProperty);
+ }
+}
+
+BOOL CPanelAttributes::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+
+ // 鍏抽棴鎸夐挳
+ CString strIcon1;
+ strIcon1.Format(_T("%s\\Res\\panel_close_24_b.ico"), theApp.m_strAppDir);
+ HICON hIcon1 = (HICON)::LoadImage(AfxGetInstanceHandle(),
+ strIcon1, IMAGE_ICON, 24, 24,
+ LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+ m_btnClose.SubclassDlgItem(IDC_BUTTON_CLOSE, this);
+ m_btnClose.SetIcon(hIcon1, hIcon1, 24);
+ m_btnClose.SetFaceColor(m_crBkgnd);
+ m_btnClose.SetFrameColor(m_crBkgnd);
+ m_btnClose.SetFrameColor(BS_HOVER, RGB(218, 218, 218));
+ m_btnClose.SetFrameColor(BS_PRESS, RGB(168, 168, 168));
+
+ CVerticalLine* pLine1 = CVerticalLine::Hook(GetDlgItem(IDC_LINE1)->GetSafeHwnd());
+ pLine1->SetBkgndColor(RGB(225, 225, 225));
+ pLine1->SetLineColor(RGB(198, 198, 198));
+ pLine1->EnableResize();
+
+
+ // 璇诲彇闈㈡澘瀹�
+ CString strIniFile;
+ strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile);
+ m_nPanelWidth = GetPrivateProfileInt(_T("App"), _T("AttributesPanelWidth"),
+ int((double)GetSystemMetrics(SM_CXSCREEN) * 0.25), (LPTSTR)(LPCTSTR)strIniFile);
+
+
+
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+
+HBRUSH CPanelAttributes::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+ HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+ if (nCtlColor == CTLCOLOR_STATIC) {
+ pDC->SetBkColor(m_crBkgnd);
+ pDC->SetTextColor(RGB(0, 0, 0));
+ }
+
+ if (m_hbrBkgnd == nullptr) {
+ m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+ }
+
+ return m_hbrBkgnd;
+}
+
+void CPanelAttributes::OnDestroy()
+{
+ CDialogEx::OnDestroy();
+
+ if (m_hbrBkgnd != nullptr) {
+ ::DeleteObject(m_hbrBkgnd);
+ }
+}
+
+void CPanelAttributes::OnSize(UINT nType, int cx, int cy)
+{
+ CDialogEx::OnSize(nType, cx, cy);
+ if (GetDlgItem(IDC_LINE1) == nullptr) return;
+
+ CWnd* pItem;
+ CRect rcClient, rcItem;
+
+ GetClientRect(&rcClient);
+ pItem = GetDlgItem(IDC_LINE1);
+ pItem->MoveWindow(rcClient.right - 3, 0, 3, rcClient.Height());
+
+ int x2 = rcClient.right - 6;
+ int y = 3;
+ pItem = GetDlgItem(IDC_BUTTON_CLOSE);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(x2 - rcItem.Width(), y, rcItem.Width(), rcItem.Height());
+ x2 -= rcItem.Width();
+ x2 -= 3;
+
+ pItem = GetDlgItem(IDC_LABEL_TITLE);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(5, y, x2 - 5, rcItem.Height());
+ y += rcItem.Height();
+ y += 8;
+
+
+ GetDlgItem(IDC_MFCPROPERTYGRID1)->MoveWindow(5, y, rcClient.Width() - 13, rcClient.Height() - 3 - y);
+}
+
+#define ATTRIBUTES_PANEL_MIN_WIDTH 88
+#define ATTRIBUTES_PANEL_MAX_WIDTH 588
+void CPanelAttributes::OnVLineMoveX(NMHDR* nmhdr, LRESULT* result)
+{
+ BYVERTICALLINE_NMHDR* pNmhdrex = (BYVERTICALLINE_NMHDR*)nmhdr;
+ int x = pNmhdrex->dwData;
+ m_nPanelWidth += x;
+ m_nPanelWidth = max(m_nPanelWidth, ATTRIBUTES_PANEL_MIN_WIDTH);
+ m_nPanelWidth = min(m_nPanelWidth, ATTRIBUTES_PANEL_MAX_WIDTH);
+ GetParent()->SendMessage(ID_MSG_PANEL_RESIZE, m_nPanelWidth, 0);
+
+ CString strIniFile, strValue;
+ strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile);
+ strValue.Format(_T("%d"), m_nPanelWidth);
+ WritePrivateProfileString(_T("App"), _T("AttributesPanelWidth"),
+ (LPTSTR)(LPCTSTR)strValue, (LPTSTR)(LPCTSTR)strIniFile);
+ OnSize(0, 0, 0);
+
+ *result = 0;
+}
+
+void CPanelAttributes::OnBnClickedButtonClose()
+{
+ ShowWindow(SW_HIDE);
+ GetParent()->SendMessage(ID_MSG_PANEL_RESIZE, m_nPanelWidth, 0);
+}
diff --git a/SourceCode/Bond/Servo/CPanelAttributes.h b/SourceCode/Bond/Servo/CPanelAttributes.h
new file mode 100644
index 0000000..5c00465
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPanelAttributes.h
@@ -0,0 +1,41 @@
+锘�#pragma once
+#include "BlButton.h"
+
+
+
+// CPanelAttributes 瀵硅瘽妗�
+
+class CPanelAttributes : public CDialogEx
+{
+ DECLARE_DYNAMIC(CPanelAttributes)
+
+public:
+ CPanelAttributes(CWnd* pParent = nullptr); // 鏍囧噯鏋勯�犲嚱鏁�
+ virtual ~CPanelAttributes();
+ int getPanelWidth();
+ void loadDataFromStep(SERVO::CStep* pStep);
+
+private:
+ COLORREF m_crBkgnd;
+ HBRUSH m_hbrBkgnd;
+ int m_nPanelWidth;
+ CMFCPropertyGridCtrl m_gridCtrl;
+ CBlButton m_btnClose;
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_PANEL_ATTRIBUTES };
+#endif
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 鏀寔
+
+ DECLARE_MESSAGE_MAP()
+public:
+ virtual BOOL OnInitDialog();
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+ afx_msg void OnDestroy();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnVLineMoveX(NMHDR* nmhdr, LRESULT* result);
+ afx_msg void OnBnClickedButtonClose();
+};
diff --git a/SourceCode/Bond/Servo/CPanelEquipment.cpp b/SourceCode/Bond/Servo/CPanelEquipment.cpp
new file mode 100644
index 0000000..533e77f
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPanelEquipment.cpp
@@ -0,0 +1,175 @@
+锘�// CPanelEquipment.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "Servo.h"
+#include "CPanelEquipment.h"
+#include "afxdialogex.h"
+#include "Common.h"
+#include "VerticalLine.h"
+
+
+// CPanelEquipment 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CPanelEquipment, CDialogEx)
+
+CPanelEquipment::CPanelEquipment(CWnd* pParent /*=nullptr*/)
+ : CDialogEx(IDD_PANEL_EQUIPMENT, pParent)
+{
+ m_crBkgnd = PANEL_EQUIPMENT_BACKGROUND_COLOR;
+ m_hbrBkgnd = nullptr;
+ m_nPanelWidth = 188;
+ m_pEquipment = nullptr;
+}
+
+CPanelEquipment::~CPanelEquipment()
+{
+}
+
+void CPanelEquipment::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CPanelEquipment, CDialogEx)
+ ON_WM_CTLCOLOR()
+ ON_WM_DESTROY()
+ ON_WM_SIZE()
+ ON_NOTIFY(BYVERTICALLINE_MOVEX, IDC_LINE1, &CPanelEquipment::OnVLineMoveX)
+ ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CPanelEquipment::OnBnClickedButtonClose)
+END_MESSAGE_MAP()
+
+
+// CPanelEquipment 娑堟伅澶勭悊绋嬪簭
+
+
+int CPanelEquipment::getPanelWidth()
+{
+ return m_nPanelWidth;
+}
+
+void CPanelEquipment::SetEquipment(SERVO::CEquipment* pEquipment)
+{
+ m_pEquipment = pEquipment;
+ ASSERT(m_pEquipment);
+
+ if (::IsWindow(m_hWnd)) {
+ SetDlgItemText(IDC_LABEL_TITLE, m_pEquipment->getName().c_str());
+ }
+}
+
+BOOL CPanelEquipment::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ // 鍏抽棴鎸夐挳
+ CString strIcon1;
+ strIcon1.Format(_T("%s\\Res\\panel_close_24_b.ico"), theApp.m_strAppDir);
+ HICON hIcon1 = (HICON)::LoadImage(AfxGetInstanceHandle(),
+ strIcon1, IMAGE_ICON, 24, 24,
+ LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+ m_btnClose.SubclassDlgItem(IDC_BUTTON_CLOSE, this);
+ m_btnClose.SetIcon(hIcon1, hIcon1, 24);
+ m_btnClose.SetFaceColor(m_crBkgnd);
+ m_btnClose.SetFrameColor(m_crBkgnd);
+ m_btnClose.SetFrameColor(BS_HOVER, RGB(218, 218, 218));
+ m_btnClose.SetFrameColor(BS_PRESS, RGB(168, 168, 168));
+
+ CVerticalLine* pLine1 = CVerticalLine::Hook(GetDlgItem(IDC_LINE1)->GetSafeHwnd());
+ pLine1->SetBkgndColor(RGB(225, 225, 225));
+ pLine1->SetLineColor(RGB(198, 198, 198));
+ pLine1->EnableResize();
+
+
+ // 璇诲彇闈㈡澘瀹�
+ CString strIniFile;
+ strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile);
+ m_nPanelWidth = GetPrivateProfileInt(_T("App"), _T("EquipmentPanelWidth"),
+ int((double)GetSystemMetrics(SM_CXSCREEN) * 0.25), (LPTSTR)(LPCTSTR)strIniFile);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+
+HBRUSH CPanelEquipment::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+ HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+ if (nCtlColor == CTLCOLOR_STATIC) {
+ pDC->SetBkColor(m_crBkgnd);
+ pDC->SetTextColor(RGB(0, 0, 0));
+ }
+
+ if (m_hbrBkgnd == nullptr) {
+ m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+ }
+
+ return m_hbrBkgnd;
+}
+
+
+void CPanelEquipment::OnDestroy()
+{
+ CDialogEx::OnDestroy();
+
+ if (m_hbrBkgnd != nullptr) {
+ ::DeleteObject(m_hbrBkgnd);
+ }
+}
+
+
+void CPanelEquipment::OnSize(UINT nType, int cx, int cy)
+{
+ CDialogEx::OnSize(nType, cx, cy);
+ if (GetDlgItem(IDC_LINE1) == nullptr) return;
+
+ CWnd* pItem;
+ CRect rcClient, rcItem;
+
+ GetClientRect(&rcClient);
+ pItem = GetDlgItem(IDC_LINE1);
+ pItem->MoveWindow(rcClient.right - 3, 0, 3, rcClient.Height());
+
+ int x2 = rcClient.right - 6;
+ int y = 3;
+ pItem = GetDlgItem(IDC_BUTTON_CLOSE);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(x2 - rcItem.Width(), y, rcItem.Width(), rcItem.Height());
+ x2 -= rcItem.Width();
+ x2 -= 3;
+
+ pItem = GetDlgItem(IDC_LABEL_TITLE);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(5, y, x2 - 5, rcItem.Height());
+ y += rcItem.Height();
+ y += 8;
+}
+
+#define EQUIPMENT_PANEL_MIN_WIDTH 88
+#define EQUIPMENT_PANEL_MAX_WIDTH 588
+void CPanelEquipment::OnVLineMoveX(NMHDR* nmhdr, LRESULT* result)
+{
+ BYVERTICALLINE_NMHDR* pNmhdrex = (BYVERTICALLINE_NMHDR*)nmhdr;
+ int x = pNmhdrex->dwData;
+ m_nPanelWidth += x;
+ m_nPanelWidth = max(m_nPanelWidth, EQUIPMENT_PANEL_MIN_WIDTH);
+ m_nPanelWidth = min(m_nPanelWidth, EQUIPMENT_PANEL_MAX_WIDTH);
+ GetParent()->SendMessage(ID_MSG_PANEL_RESIZE, m_nPanelWidth, 0);
+
+ CString strIniFile, strValue;
+ strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile);
+ strValue.Format(_T("%d"), m_nPanelWidth);
+ WritePrivateProfileString(_T("App"), _T("EquipmentPanelWidth"),
+ (LPTSTR)(LPCTSTR)strValue, (LPTSTR)(LPCTSTR)strIniFile);
+ OnSize(0, 0, 0);
+
+ *result = 0;
+}
+
+void CPanelEquipment::OnBnClickedButtonClose()
+{
+ ShowWindow(SW_HIDE);
+ GetParent()->SendMessage(ID_MSG_PANEL_RESIZE, m_nPanelWidth, 0);
+}
diff --git a/SourceCode/Bond/Servo/CPanelEquipment.h b/SourceCode/Bond/Servo/CPanelEquipment.h
new file mode 100644
index 0000000..460e858
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPanelEquipment.h
@@ -0,0 +1,42 @@
+锘�#pragma once
+#include "BlButton.h"
+#include "CEquipment.h"
+
+
+// CPanelEquipment 瀵硅瘽妗�
+
+class CPanelEquipment : public CDialogEx
+{
+ DECLARE_DYNAMIC(CPanelEquipment)
+
+public:
+ CPanelEquipment(CWnd* pParent = nullptr); // 鏍囧噯鏋勯�犲嚱鏁�
+ virtual ~CPanelEquipment();
+ int getPanelWidth();
+ void SetEquipment(SERVO::CEquipment* pEquipment);
+
+private:
+ COLORREF m_crBkgnd;
+ HBRUSH m_hbrBkgnd;
+ int m_nPanelWidth;
+ CBlButton m_btnClose;
+ SERVO::CEquipment* m_pEquipment;
+
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_PANEL_EQUIPMENT };
+#endif
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 鏀寔
+
+ DECLARE_MESSAGE_MAP()
+public:
+ virtual BOOL OnInitDialog();
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+ afx_msg void OnDestroy();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnVLineMoveX(NMHDR* nmhdr, LRESULT* result);
+ afx_msg void OnBnClickedButtonClose();
+};
diff --git a/SourceCode/Bond/Servo/CPanelMaster.cpp b/SourceCode/Bond/Servo/CPanelMaster.cpp
new file mode 100644
index 0000000..014819d
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPanelMaster.cpp
@@ -0,0 +1,207 @@
+锘�// CPanelMaster.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "Servo.h"
+#include "CPanelMaster.h"
+#include "afxdialogex.h"
+#include "Common.h"
+#include "VerticalLine.h"
+
+
+// CPanelMaster 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CPanelMaster, CDialogEx)
+
+CPanelMaster::CPanelMaster(CWnd* pParent /*=nullptr*/)
+ : CDialogEx(IDD_PANEL_MASTER, pParent)
+{
+ m_crBkgnd = PANEL_MASTER_BACKGROUND_COLOR;
+ m_hbrBkgnd = nullptr;
+ m_nPanelWidth = 388;
+}
+
+CPanelMaster::~CPanelMaster()
+{
+}
+
+void CPanelMaster::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_TREE1, m_treeCtrl);
+}
+
+
+BEGIN_MESSAGE_MAP(CPanelMaster, CDialogEx)
+ ON_WM_CTLCOLOR()
+ ON_WM_DESTROY()
+ ON_WM_SIZE()
+ ON_NOTIFY(BYVERTICALLINE_MOVEX, IDC_LINE1, &CPanelMaster::OnVLineMoveX)
+ ON_WM_TIMER()
+ ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &CPanelMaster::OnTvnSelchangedTree1)
+END_MESSAGE_MAP()
+
+
+// CPanelMaster 娑堟伅澶勭悊绋嬪簭
+
+
+int CPanelMaster::getPanelWidth()
+{
+ return m_nPanelWidth;
+}
+
+BOOL CPanelMaster::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+
+ CVerticalLine* pLine1 = CVerticalLine::Hook(GetDlgItem(IDC_LINE1)->GetSafeHwnd());
+ pLine1->SetBkgndColor(RGB(225, 225, 225));
+ pLine1->SetLineColor(RGB(198, 198, 198));
+ pLine1->EnableResize();
+
+
+ // 璇诲彇闈㈡澘瀹�
+ CString strIniFile;
+ strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile);
+ m_nPanelWidth = GetPrivateProfileInt(_T("App"), _T("MasterPanelWidth"),
+ int((double)GetSystemMetrics(SM_CXSCREEN) * 0.25), (LPTSTR)(LPCTSTR)strIniFile);
+
+
+ // treectrl
+ m_treeCtrl.SetBkColor(PANEL_MASTER_BACKGROUND_COLOR);
+ m_treeCtrl.SetItemHeight(28);
+ SetTimer(1, 2000, nullptr);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+HBRUSH CPanelMaster::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+ HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+ if (nCtlColor == CTLCOLOR_STATIC) {
+ pDC->SetBkColor(m_crBkgnd);
+ pDC->SetTextColor(RGB(0, 0, 0));
+ }
+
+ if (m_hbrBkgnd == nullptr) {
+ m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+ }
+
+ return m_hbrBkgnd;
+}
+
+void CPanelMaster::OnDestroy()
+{
+ CDialogEx::OnDestroy();
+
+ if (m_hbrBkgnd != nullptr) {
+ ::DeleteObject(m_hbrBkgnd);
+ }
+}
+
+void CPanelMaster::OnSize(UINT nType, int cx, int cy)
+{
+ CDialogEx::OnSize(nType, cx, cy);
+ if (GetDlgItem(IDC_LINE1) == nullptr) return;
+
+ CWnd* pItem;
+ CRect rcClient;
+
+ GetClientRect(&rcClient);
+ pItem = GetDlgItem(IDC_LINE1);
+ pItem->MoveWindow(rcClient.right - 3, 0, 3, rcClient.Height());
+
+ m_treeCtrl.MoveWindow(5, 5, rcClient.Width() - 13, rcClient.Height() - 10);
+}
+
+
+#define MASTER_PANEL_MIN_WIDTH 88
+#define MASTER_PANEL_MAX_WIDTH 588
+void CPanelMaster::OnVLineMoveX(NMHDR* nmhdr, LRESULT* result)
+{
+ BYVERTICALLINE_NMHDR* pNmhdrex = (BYVERTICALLINE_NMHDR*)nmhdr;
+ int x = pNmhdrex->dwData;
+ m_nPanelWidth += x;
+ m_nPanelWidth = max(m_nPanelWidth, MASTER_PANEL_MIN_WIDTH);
+ m_nPanelWidth = min(m_nPanelWidth, MASTER_PANEL_MAX_WIDTH);
+ GetParent()->SendMessage(ID_MSG_PANEL_RESIZE, m_nPanelWidth, 0);
+
+ CString strIniFile, strValue;
+ strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile);
+ strValue.Format(_T("%d"), m_nPanelWidth);
+ WritePrivateProfileString(_T("App"), _T("MasterPanelWidth"),
+ (LPTSTR)(LPCTSTR)strValue, (LPTSTR)(LPCTSTR)strIniFile);
+ OnSize(0, 0, 0);
+
+ * result = 0;
+}
+
+void CPanelMaster::OnTimer(UINT_PTR nIDEvent)
+{
+ if (1 == nIDEvent) {
+ KillTimer(1);
+ loadEquipmentList();
+ }
+
+ CDialogEx::OnTimer(nIDEvent);
+}
+
+void CPanelMaster::loadEquipmentList()
+{
+ HTREEITEM hItemMaster = m_treeCtrl.InsertItem("Master");
+
+ std::list<SERVO::CEquipment*>& eqs = theApp.m_model.m_master.getEquipmentList();
+ for (auto item : eqs) {
+ HTREEITEM hItemEq = m_treeCtrl.InsertItem(item->getName().c_str(), hItemMaster);
+ m_treeCtrl.SetItemData(hItemEq, (DWORD_PTR)item);
+ loadSteps(item, hItemEq);
+ m_treeCtrl.Expand(hItemEq, TVE_EXPAND);
+ }
+
+
+ m_treeCtrl.Expand(hItemMaster, TVE_EXPAND);
+}
+
+void CPanelMaster::loadSteps(SERVO::CEquipment* pEquipment, HTREEITEM hItemEq)
+{
+ std::map<unsigned int, SERVO::CStep*>& steps = pEquipment->getSteps();
+
+ for (auto item : steps) {
+ HTREEITEM hStep = m_treeCtrl.InsertItem(item.second->getName().c_str(), hItemEq);
+ m_treeCtrl.SetItemData(hStep, (DWORD_PTR)item.second);
+ }
+}
+
+void CPanelMaster::OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
+ HTREEITEM hItem = pNMTreeView->itemNew.hItem;
+ int nLevel = GetTreeItemLevel(hItem);
+ if (nLevel == 2) {
+ SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)m_treeCtrl.GetItemData(hItem);
+ theApp.m_model.notifyPtr(RX_CODE_SELECT_EQUIPMENT, pEquipment);
+ }
+ else if (nLevel == 3) {
+ SERVO::CStep* pStep = (SERVO::CStep*)m_treeCtrl.GetItemData(hItem);
+ theApp.m_model.notifyPtr(RX_CODE_SELECT_STEP, pStep);
+ }
+
+
+
+ *pResult = 0;
+}
+
+int CPanelMaster::GetTreeItemLevel(HTREEITEM hItem)
+{
+ int nLevel = 0;
+ HTREEITEM hTemp = hItem;
+ while (hTemp != nullptr) {
+ hTemp = m_treeCtrl.GetParentItem(hTemp);
+ nLevel++;
+ }
+
+ return nLevel;
+}
diff --git a/SourceCode/Bond/Servo/CPanelMaster.h b/SourceCode/Bond/Servo/CPanelMaster.h
new file mode 100644
index 0000000..bea8068
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPanelMaster.h
@@ -0,0 +1,47 @@
+锘�#pragma once
+#include "ApredTreeCtrl2.h"
+
+
+// CPanelMaster 瀵硅瘽妗�
+
+class CPanelMaster : public CDialogEx
+{
+ DECLARE_DYNAMIC(CPanelMaster)
+
+public:
+ CPanelMaster(CWnd* pParent = nullptr); // 鏍囧噯鏋勯�犲嚱鏁�
+ virtual ~CPanelMaster();
+ int getPanelWidth();
+ void loadEquipmentList();
+ void loadSteps(SERVO::CEquipment* pEquipment, HTREEITEM hItemEq);
+
+
+private:
+ int GetTreeItemLevel(HTREEITEM hItem);
+
+
+private:
+ COLORREF m_crBkgnd;
+ HBRUSH m_hbrBkgnd;
+ CApredTreeCtrl2 m_treeCtrl;
+ int m_nPanelWidth;
+
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_PANEL_MASTER };
+#endif
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 鏀寔
+
+ DECLARE_MESSAGE_MAP()
+public:
+ virtual BOOL OnInitDialog();
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+ afx_msg void OnDestroy();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnVLineMoveX(NMHDR* nmhdr, LRESULT* result);
+ afx_msg void OnTimer(UINT_PTR nIDEvent);
+ afx_msg void OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult);
+};
diff --git a/SourceCode/Bond/Servo/CReadStep.cpp b/SourceCode/Bond/Servo/CReadStep.cpp
new file mode 100644
index 0000000..0a2474f
--- /dev/null
+++ b/SourceCode/Bond/Servo/CReadStep.cpp
@@ -0,0 +1,187 @@
+#include "stdafx.h"
+#include "CReadStep.h"
+#include "Common.h"
+
+
+namespace SERVO {
+#define TIMEOUT 15
+
+ unsigned __stdcall ReadStepWorkThreadFunction(LPVOID lpParam)
+ {
+ CReadStep* pStep = (CReadStep*)lpParam;
+ return pStep->WorkingProc();
+ }
+
+ CReadStep::CReadStep() : CStep()
+ {
+ m_nWordThreadAddr = 0;
+ m_hWorkStop = nullptr;
+ m_hWorkThreadHandle = nullptr;
+ m_hReadSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_hReadSignalOff = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_nCurStep = 0;
+ }
+
+ CReadStep::~CReadStep()
+ {
+ ASSERT(m_hReadSignalOn);
+ CloseHandle(m_hReadSignalOn);
+ m_hReadSignalOn = nullptr;
+
+ ASSERT(m_hReadSignalOff);
+ CloseHandle(m_hReadSignalOff);
+ m_hReadSignalOff = nullptr;
+ }
+
+ void CReadStep::setWriteSignalDev(int dev)
+ {
+ m_nWriteSignalDev = dev;
+ }
+
+ void CReadStep::onReadSignal(BOOL bSignal)
+ {
+ Lock();
+ if (m_nCurStep == 0 && bSignal) {
+ SetEvent(m_hReadSignalOn);
+ }
+ else if (m_nCurStep == 3 && !bSignal) {
+ SetEvent(m_hReadSignalOff);
+ }
+
+ Unlock();
+ }
+
+ int CReadStep::onReadData()
+ {
+ return 0;
+ }
+
+ unsigned CReadStep::WorkingProc()
+ {
+ HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ BOOL bReadOk = FALSE;
+
+ int nBeginAddr = 0x0;
+ while (1) {
+ RESET:
+ resetStep();
+
+ // 待退出信号或时间到
+ HANDLE hEvents[] = { m_hWorkStop, m_hReadSignalOn };
+ int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
+ if (nRet == WAIT_OBJECT_0) {
+ ResetEvent(m_hWorkStop);
+ break;
+ }
+
+ else if (nRet == WAIT_OBJECT_0 + 1) {
+ ResetEvent(m_hReadSignalOn);
+
+ // 1.读取数据
+ nextStep();
+ ASSERT(m_pCclink);
+ if (0 == onReadData()) {
+ if (m_listener.onEvent != nullptr) {
+ m_listener.onEvent(this, STEP_EVENT_READDATA, nullptr);
+ }
+ }
+
+ // 2.给对方写ON
+ nextStep();
+ m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+
+
+ // 3.等待对方OFF
+ nextStep();
+ int nStep3Ret = ::WaitForSingleObject(m_hReadSignalOff, TIMEOUT * 1000);
+ if (nStep3Ret == WAIT_TIMEOUT) {
+ m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+ onTimeout();
+ goto RESET;
+ }
+ ResetEvent(m_hReadSignalOff);
+
+
+ // 4.给对方写OFF
+ nextStep();
+ m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+
+
+ // 6.完成
+ nextStep();
+ if (0 == onComplete()) {
+ if (m_listener.onEvent != nullptr) {
+ m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
+ }
+ }
+ }
+ }
+
+ if (hEvent != nullptr) {
+ CloseHandle(hEvent);
+ }
+
+ // _endthreadex(0);
+ TRACE("CStep::WorkingProc 线程退出\n");
+ return 0;
+ }
+
+ void CReadStep::getAttributeVector(CAttributeVector& attrubutes)
+ {
+ CStep::getAttributeVector(attrubutes);
+ attrubutes.addAttribute(new CAttribute("Current Step",
+ std::to_string(m_nCurStep).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Signal Dev",
+ std::to_string(m_nWriteSignalDev).c_str(), ""));
+ }
+
+ void CReadStep::init()
+ {
+ CStep::init();
+
+ if (m_hWorkStop != nullptr) return;
+ m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadStepWorkThreadFunction, this,
+ 0, &m_nWordThreadAddr);
+ }
+
+ void CReadStep::term()
+ {
+ CStep::term();
+
+ ASSERT(m_hWorkStop);
+ SetEvent(m_hWorkStop);
+ if (m_hWorkThreadHandle != NULL) {
+ WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
+ CloseHandle(m_hWorkThreadHandle);
+ m_hWorkThreadHandle = NULL;
+ }
+ CloseHandle(m_hWorkStop);
+ m_hWorkStop = NULL;
+ }
+
+ void CReadStep::resetStep()
+ {
+ Lock();
+ m_nCurStep = 0;
+ Unlock();
+ }
+
+ void CReadStep::nextStep()
+ {
+ Lock();
+ m_nCurStep++;
+ Unlock();
+ }
+
+
+ int CReadStep::onComplete()
+ {
+ return 0;
+ }
+
+ int CReadStep::onTimeout()
+ {
+ return 0;
+ }
+}
diff --git a/SourceCode/Bond/Servo/CReadStep.h b/SourceCode/Bond/Servo/CReadStep.h
new file mode 100644
index 0000000..2b0df3b
--- /dev/null
+++ b/SourceCode/Bond/Servo/CReadStep.h
@@ -0,0 +1,35 @@
+#pragma once
+#include "CStep.h"
+
+
+namespace SERVO {
+ class CReadStep : public CStep
+ {
+ public:
+ CReadStep();
+ virtual ~CReadStep();
+
+ public:
+ unsigned WorkingProc();
+ virtual void setWriteSignalDev(int dev);
+ virtual void onReadSignal(BOOL bSignal);
+ virtual int onReadData();
+ virtual void init();
+ virtual void term();
+ virtual void getAttributeVector(CAttributeVector& attrubutes);
+ virtual int onComplete();
+ virtual int onTimeout();
+ inline void nextStep();
+ inline void resetStep();
+
+ protected:
+ HANDLE m_hWorkThreadHandle;
+ unsigned m_nWordThreadAddr;
+ HANDLE m_hWorkStop;
+ HANDLE m_hReadSignalOn;
+ HANDLE m_hReadSignalOff;
+ int m_nCurStep;
+ int m_nWriteSignalDev; // 对方BIT地址
+ };
+}
+
diff --git a/SourceCode/Bond/Servo/CStep.cpp b/SourceCode/Bond/Servo/CStep.cpp
index 2e43de3..dbbf161 100644
--- a/SourceCode/Bond/Servo/CStep.cpp
+++ b/SourceCode/Bond/Servo/CStep.cpp
@@ -3,38 +3,16 @@
namespace SERVO {
-#define TIMEOUT 15
-
- unsigned __stdcall StepWorkThreadFunction(LPVOID lpParam)
- {
- CStep* pStep = (CStep*)lpParam;
- return pStep->WorkingProc();
- }
CStep::CStep()
{
m_listener = {nullptr};
- m_nWordThreadAddr = 0;
- m_hWorkStop = nullptr;
- m_hWorkThreadHandle = nullptr;
- m_hSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- m_hSignalOff = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- m_nCurStep = 0;
m_pCclink = nullptr;
- m_nWriteSignalDev = 0;
InitializeCriticalSection(&m_criticalSection);
}
CStep::~CStep()
{
- ASSERT(m_hSignalOn);
- CloseHandle(m_hSignalOn);
- m_hSignalOn = nullptr;
-
- ASSERT(m_hSignalOff);
- CloseHandle(m_hSignalOff);
- m_hSignalOff = nullptr;
-
DeleteCriticalSection(&m_criticalSection);
}
@@ -68,142 +46,36 @@
return m_strName;
}
- void CStep::setWriteSignalDev(int dev)
+ void CStep::getAttributeVector(CAttributeVector& attrubutes)
{
- m_nWriteSignalDev = dev;
+ attrubutes.clear();
+ attrubutes.addAttribute(new CAttribute("Network",
+ std::to_string(m_station.nNetNo).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Station",
+ std::to_string(m_station.nStNo).c_str(), ""));
}
void CStep::init()
{
- if (m_hWorkStop != nullptr) return;
- m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::StepWorkThreadFunction, this,
- 0, &m_nWordThreadAddr);
+
}
void CStep::term()
{
- ASSERT(m_hWorkStop);
- SetEvent(m_hWorkStop);
- if (m_hWorkThreadHandle != NULL) {
- WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
- CloseHandle(m_hWorkThreadHandle);
- m_hWorkThreadHandle = NULL;
+
+ }
+
+ void CStep::convertString(const char* pszBuffer, int size, std::string& strOut)
+ {
+ strOut.clear();
+ int nLength = 0;
+ for (int i = 0; i < size; i++) {
+ if (pszBuffer[i] == '\0') break;
+ nLength++;
}
- CloseHandle(m_hWorkStop);
- m_hWorkStop = NULL;
- }
-
- unsigned CStep::WorkingProc()
- {
- HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- BOOL bReadOk = FALSE;
-
- int nBeginAddr = 0x0;
- while (1) {
-RESET:
- resetStep();
-
- // 待退出信号或时间到
- HANDLE hEvents[] = { m_hWorkStop, m_hSignalOn };
- int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
- if (nRet == WAIT_OBJECT_0) {
- ResetEvent(m_hWorkStop);
- break;
- }
-
- else if (nRet == WAIT_OBJECT_0 + 1) {
- ResetEvent(m_hSignalOn);
-
- // 1.读取数据
- nextStep();
- ASSERT(m_pCclink);
- if (0 == onReadData()) {
- if (m_listener.onEvent != nullptr) {
- m_listener.onEvent(this, STEP_EVENT_READDATA, nullptr);
- }
- }
-
- // 2.给对方写ON
- nextStep();
- m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
-
-
- // 3.等待对方OFF
- nextStep();
- int nStep3Ret = ::WaitForSingleObject(m_hSignalOff, TIMEOUT * 1000);
- if (nStep3Ret == WAIT_TIMEOUT) {
- m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
- onTimeout();
- goto RESET;
- }
- ResetEvent(m_hSignalOff);
-
-
- // 4.给对方写OFF
- nextStep();
- m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
-
-
- // 6.完成
- nextStep();
- if (0 == onComplete()) {
- if (m_listener.onEvent != nullptr) {
- m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
- }
- }
- }
+ if (nLength > 0) {
+ strOut = std::string(pszBuffer, nLength);
}
-
- if (hEvent != nullptr) {
- CloseHandle(hEvent);
- }
-
- // _endthreadex(0);
- TRACE("CStep::WorkingProc 线程退出\n");
- return 0;
- }
-
- void CStep::onSignal(BOOL bSignal)
- {
- Lock();
- if (m_nCurStep == 0 && bSignal) {
- SetEvent(m_hSignalOn);
- }
- else if (m_nCurStep == 3 && !bSignal) {
- SetEvent(m_hSignalOff);
- }
-
- Unlock();
- }
-
- int CStep::onReadData()
- {
- return 0;
- }
-
- int CStep::onComplete()
- {
- return 0;
- }
-
- int CStep::onTimeout()
- {
- return 0;
- }
-
- void CStep::resetStep()
- {
- Lock();
- m_nCurStep = 0;
- Unlock();
- }
-
- void CStep::nextStep()
- {
- Lock();
- m_nCurStep++;
- Unlock();
}
}
diff --git a/SourceCode/Bond/Servo/CStep.h b/SourceCode/Bond/Servo/CStep.h
index 628f116..04aa2c1 100644
--- a/SourceCode/Bond/Servo/CStep.h
+++ b/SourceCode/Bond/Servo/CStep.h
@@ -1,5 +1,6 @@
#pragma once
#include "CCLinkIEControl.h"
+#include "CAttributeVector.h"
namespace SERVO {
@@ -20,26 +21,21 @@
virtual ~CStep();
public:
- unsigned WorkingProc();
void setListener(StepListener listener);
void setCcLink(CCCLinkIEControl* pCcLink);
void setEquipment(CEquipment* pEquipment);
CEquipment* getEquipment();
void setName(const char* pszName);
std::string& getName();
- virtual void setWriteSignalDev(int dev);
+ virtual void getAttributeVector(CAttributeVector& attrubutes);
virtual void init();
- virtual void CStep::term();
- virtual void onSignal(BOOL bSignal);
- virtual int onReadData();
- virtual int onComplete();
- virtual int onTimeout();
+ virtual void term();
+
protected:
inline void Lock() { EnterCriticalSection(&m_criticalSection); }
inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
- inline void nextStep();
- inline void resetStep();
+ void convertString(const char* pszBuffer, int size, std::string& strOut);
protected:
StepListener m_listener;
@@ -48,14 +44,6 @@
CEquipment* m_pEquipment;
CCCLinkIEControl* m_pCclink;
CRITICAL_SECTION m_criticalSection;
- std::string strName;
- HANDLE m_hWorkThreadHandle;
- unsigned m_nWordThreadAddr;
- HANDLE m_hWorkStop;
- HANDLE m_hSignalOn;
- HANDLE m_hSignalOff;
- int m_nCurStep;
- int m_nWriteSignalDev; // 对方BIT地址
};
}
diff --git a/SourceCode/Bond/Servo/CWriteStep.cpp b/SourceCode/Bond/Servo/CWriteStep.cpp
new file mode 100644
index 0000000..15f6a2a
--- /dev/null
+++ b/SourceCode/Bond/Servo/CWriteStep.cpp
@@ -0,0 +1,197 @@
+#include "stdafx.h"
+#include "CWriteStep.h"
+#include "Common.h"
+
+
+namespace SERVO {
+#define TIMEOUT 15
+
+ unsigned __stdcall WriteStepWorkThreadFunction(LPVOID lpParam)
+ {
+ CWriteStep* pStep = (CWriteStep*)lpParam;
+ return pStep->WorkingProc();
+ }
+
+ CWriteStep::CWriteStep() : CStep()
+ {
+ m_nWordThreadAddr = 0;
+ m_hWorkStop = nullptr;
+ m_hWorkThreadHandle = nullptr;
+ m_nCurStep = 0;
+ m_nWriteSignalDev = 0;
+ m_nWriteDataSize = 0;
+ m_nWriteDevNo = 0;
+ m_hWriteSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_hRecvSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ }
+
+ CWriteStep::~CWriteStep()
+ {
+ ASSERT(m_hWriteSignalOn);
+ CloseHandle(m_hWriteSignalOn);
+ m_hWriteSignalOn = nullptr;
+
+ ASSERT(m_hRecvSignalOn);
+ CloseHandle(m_hRecvSignalOn);
+ m_hRecvSignalOn = nullptr;
+ }
+
+ int CWriteStep::writeData(short devno, const char* pszData, int size)
+ {
+ if (size > 1024) return -1;
+ if (m_nCurStep != 0) return -2;
+
+ memcpy(m_szBuffer, pszData, size);
+ m_nWriteDataSize = size;
+ m_nWriteDevNo = devno;
+ SetEvent(m_hWriteSignalOn);
+
+ return 0;
+ }
+
+ void CWriteStep::setWriteSignalDev(int dev)
+ {
+ m_nWriteSignalDev = dev;
+ }
+
+ void CWriteStep::onRecvSignal(BOOL bSignal)
+ {
+ Lock();
+ if (m_nCurStep == 3 && bSignal) {
+ SetEvent(m_hRecvSignalOn);
+ }
+
+ Unlock();
+ }
+
+ unsigned CWriteStep::WorkingProc()
+ {
+ HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ BOOL bReadOk = FALSE;
+
+ int nBeginAddr = 0x0;
+ while (1) {
+ RESET:
+ resetStep();
+
+ // 待退出信号或时间到
+ HANDLE hEvents[] = { m_hWorkStop, m_hWriteSignalOn };
+ int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
+ if (nRet == WAIT_OBJECT_0) {
+ ResetEvent(m_hWorkStop);
+ break;
+ }
+
+ else if (nRet == WAIT_OBJECT_0 + 1) {
+ ResetEvent(m_hWriteSignalOn);
+
+ // 1.写数据
+ nextStep();
+ ASSERT(m_pCclink);
+ int nRet = m_pCclink->WriteData(m_station, (short)DeviceType::W,
+ m_nWriteDevNo, m_nWriteDataSize, (short*)m_szBuffer);
+ if (0 != nRet) {
+ onTimeout();
+ goto RESET;
+ }
+
+
+ // 2.给对方写ON
+ nextStep();
+ m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+
+
+ // 3.等待对方ON
+ nextStep();
+ int nStep3Ret = ::WaitForSingleObject(m_hRecvSignalOn, TIMEOUT * 1000);
+ if (nStep3Ret == WAIT_TIMEOUT) {
+ m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+ onTimeout();
+ goto RESET;
+ }
+ ResetEvent(m_hRecvSignalOn);
+
+
+ // 4.写OFF
+ nextStep();
+ m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+
+
+ // 6.完成
+ nextStep();
+ if (0 == onComplete()) {
+ if (m_listener.onEvent != nullptr) {
+ m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
+ }
+ }
+ }
+ }
+
+ if (hEvent != nullptr) {
+ CloseHandle(hEvent);
+ }
+
+ // _endthreadex(0);
+ TRACE("CStep::WorkingProc 线程退出\n");
+ return 0;
+ }
+
+ void CWriteStep::getAttributeVector(CAttributeVector& attrubutes)
+ {
+ CStep::getAttributeVector(attrubutes);
+
+ attrubutes.addAttribute(new CAttribute("Current Step",
+ std::to_string(m_nCurStep).c_str(), ""));
+ attrubutes.addAttribute(new CAttribute("Signal Dev",
+ std::to_string(m_nWriteSignalDev).c_str(), ""));
+ }
+
+ void CWriteStep::init()
+ {
+ CStep::init();
+
+ if (m_hWorkStop != nullptr) return;
+ m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::WriteStepWorkThreadFunction, this,
+ 0, &m_nWordThreadAddr);
+ }
+
+ void CWriteStep::term()
+ {
+ CStep::term();
+
+ ASSERT(m_hWorkStop);
+ SetEvent(m_hWorkStop);
+ if (m_hWorkThreadHandle != NULL) {
+ WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
+ CloseHandle(m_hWorkThreadHandle);
+ m_hWorkThreadHandle = NULL;
+ }
+ CloseHandle(m_hWorkStop);
+ m_hWorkStop = NULL;
+ }
+
+ void CWriteStep::resetStep()
+ {
+ Lock();
+ m_nCurStep = 0;
+ Unlock();
+ }
+
+ void CWriteStep::nextStep()
+ {
+ Lock();
+ m_nCurStep++;
+ Unlock();
+ }
+
+ int CWriteStep::onComplete()
+ {
+ return 0;
+ }
+
+ int CWriteStep::onTimeout()
+ {
+ return 0;
+ }
+}
diff --git a/SourceCode/Bond/Servo/CWriteStep.h b/SourceCode/Bond/Servo/CWriteStep.h
new file mode 100644
index 0000000..6bb6b30
--- /dev/null
+++ b/SourceCode/Bond/Servo/CWriteStep.h
@@ -0,0 +1,38 @@
+#pragma once
+#include "CStep.h"
+
+
+namespace SERVO {
+ class CWriteStep : public CStep
+ {
+ public:
+ CWriteStep();
+ virtual ~CWriteStep();
+
+ public:
+ unsigned WorkingProc();
+ virtual void setWriteSignalDev(int dev);
+ virtual void onRecvSignal(BOOL bSignal);
+ int writeData(short devno, const char* pszData, int size);
+ virtual void init();
+ virtual void term();
+ virtual void getAttributeVector(CAttributeVector& attrubutes);
+ virtual int onComplete();
+ virtual int onTimeout();
+ inline void nextStep();
+ inline void resetStep();
+
+ protected:
+ HANDLE m_hWorkThreadHandle;
+ unsigned m_nWordThreadAddr;
+ HANDLE m_hWorkStop;
+ HANDLE m_hWriteSignalOn;
+ HANDLE m_hRecvSignalOn;
+ int m_nCurStep;
+ int m_nWriteSignalDev; // 对方BIT地址
+ char m_szBuffer[1024];
+ int m_nWriteDataSize;
+ int m_nWriteDevNo;
+ };
+}
+
diff --git a/SourceCode/Bond/Servo/Common.h b/SourceCode/Bond/Servo/Common.h
index 7aeb6aa..92d40c2 100644
--- a/SourceCode/Bond/Servo/Common.h
+++ b/SourceCode/Bond/Servo/Common.h
@@ -9,14 +9,19 @@
#define RX_HSMS_TERMINAL_TEXT 1003
#define RX_CODE_EQ_ALIVE 1004
#define RX_CODE_STEP_EVENT_READDATA 1005
+#define RX_CODE_SELECT_EQUIPMENT 1006
+#define RX_CODE_SELECT_STEP 1007
/* Channel Name */
#define MC_CHANNEL1_NAME "McChannel1"
/* 颜色 */
-#define APPDLG_BACKGROUND_COLOR RGB(255, 255, 255)
-#define LOGDLG_BACKGROUND_COLOR RGB(255, 255, 255)
+#define APPDLG_BACKGROUND_COLOR RGB(255, 255, 255)
+#define LOGDLG_BACKGROUND_COLOR RGB(255, 255, 255)
+#define PANEL_MASTER_BACKGROUND_COLOR RGB(255, 255, 255)
+#define PANEL_ATTRIBUTES_BACKGROUND_COLOR RGB(255, 255, 255)
+#define PANEL_EQUIPMENT_BACKGROUND_COLOR RGB(255, 255, 255)
/* LOG BTN */
@@ -38,4 +43,32 @@
/* Equipment ID */
#define EQ_ID_EFEM 1
#define EQ_ID_Bonder1 2
-#define EQ_ID_Bonder2 3
\ No newline at end of file
+#define EQ_ID_Bonder2 3
+
+
+/* step name */
+#define STEP_MODE _T("EQMode")
+#define STEP_STATUS _T("EQStatus")
+#define STEP_ALARM_START _T("EQAlarm")
+#define STEP_ALARM_BLOCK1 _T("EQAlarm1")
+#define STEP_ALARM_BLOCK2 _T("EQAlarm2")
+#define STEP_ALARM_BLOCK3 _T("EQAlarm3")
+#define STEP_ALARM_BLOCK4 _T("EQAlarm4")
+#define STEP_ALARM_BLOCK5 _T("EQAlarm5")
+#define STEP_PROCESS _T("EQProcess")
+#define STEP_CIM_MODE_CHANGE _T("EQCimModeChange")
+
+
+#define BASE_ALARM_EFEM 10000
+#define BASE_ALARM_BONDER1 20000
+#define BASE_ALARM_BONDER2 30000
+
+
+/* step event */
+#define STEP_EVENT_READDATA 0x01
+#define STEP_EVENT_COMPLETE 0x02
+#define STEP_EVENT_PROCESS_DATA 0x1001
+
+
+/* 自定义消息 */
+#define ID_MSG_PANEL_RESIZE WM_USER + 1998
diff --git a/SourceCode/Bond/Servo/HorizontalLine.cpp b/SourceCode/Bond/Servo/HorizontalLine.cpp
new file mode 100644
index 0000000..fc48b76
--- /dev/null
+++ b/SourceCode/Bond/Servo/HorizontalLine.cpp
@@ -0,0 +1,209 @@
+// HorizontalLine.cpp: implementation of the CHorizontalLine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "HorizontalLine.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CHorizontalLine::CHorizontalLine()
+{
+ m_hWnd = NULL;
+ m_crBkgnd = RGB(255, 255, 255);
+ m_crLineColor = RGB(222, 222, 222);
+}
+
+CHorizontalLine::~CHorizontalLine()
+{
+}
+
+BOOL CHorizontalLine::RegisterWndClass()
+{
+ WNDCLASS wc;
+ wc.lpszClassName = BYHORIZONTALLINE_CLASS;
+ wc.hInstance = AfxGetInstanceHandle();
+ wc.lpfnWndProc = WindowProc;
+ wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+ wc.hIcon = 0;
+ wc.lpszMenuName = NULL;
+ wc.hbrBackground = NULL;
+ wc.style = CS_GLOBALCLASS|CS_DBLCLKS;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+
+ // 注册自定义类
+ return (::RegisterClass(&wc) != 0);
+}
+
+CHorizontalLine* CHorizontalLine::Hook(HWND hWnd)
+{
+ CHorizontalLine* pHorizontalLine = (CHorizontalLine*)GetProp(hWnd, BYSTAG_HORIZONTALLINE);
+ if(pHorizontalLine == NULL)
+ {
+ pHorizontalLine = new CHorizontalLine;
+ pHorizontalLine->m_hWnd = hWnd;
+
+ SetProp(hWnd, BYSTAG_HORIZONTALLINE, (HANDLE)pHorizontalLine);
+ }
+
+ return pHorizontalLine;
+}
+
+void CHorizontalLine::Release()
+{
+ // delete
+ delete this;
+}
+
+void CHorizontalLine::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/)
+{
+ HWND hParent;
+ hParent = GetParent(m_hWnd);
+ if(hParent != NULL) {
+ BYHORIZONTALLINE_NMHDR iii_nmhdr;
+ iii_nmhdr.nmhdr.hwndFrom = m_hWnd;
+ iii_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+ iii_nmhdr.nmhdr.code = nCode;
+ iii_nmhdr.dwData = dwData;
+ iii_nmhdr.dwData1 = dwData1;
+ iii_nmhdr.dwData2 = dwData2;
+ SendMessage(hParent, WM_NOTIFY, (WPARAM)iii_nmhdr.nmhdr.idFrom, (LPARAM)&iii_nmhdr);
+ }
+}
+
+////////////////////////////////
+// 拦截窗口消息函数
+LRESULT CALLBACK CHorizontalLine::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CHorizontalLine* pHorizontalLine = (CHorizontalLine *)GetProp(hWnd, BYSTAG_HORIZONTALLINE);
+ if(pHorizontalLine == NULL && uMsg != WM_NCCREATE)
+ {
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+
+
+ // 如果Hook则响应消息
+ ASSERT(hWnd);
+ switch(uMsg)
+ {
+ case WM_NCCREATE:
+ return OnNcCreate(hWnd, wParam, lParam);
+
+ case WM_DESTROY:
+ return pHorizontalLine->OnDestroy(wParam, lParam);
+
+ case WM_PAINT:
+ return pHorizontalLine->OnPaint(wParam, lParam);
+
+ case WM_TIMER:
+ return pHorizontalLine->OnTimer(wParam, lParam);
+
+ case WM_GETDLGCODE:
+ return DLGC_WANTALLKEYS;
+
+ default:
+ break;
+ }
+
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_NCCREATE
+// 窗口创建前的初始化工作
+LRESULT CHorizontalLine::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ CHorizontalLine* pHorizontalLine = (CHorizontalLine *)GetProp(hWnd, BYSTAG_HORIZONTALLINE);
+ ASSERT(pHorizontalLine == NULL);
+
+ Hook(hWnd);
+ return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_DESTROY
+LRESULT CHorizontalLine::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+ Release();
+ return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_TIMER
+LRESULT CHorizontalLine::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+ return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+
+///////////////////////////////
+// WM_PAINT
+LRESULT CHorizontalLine::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+ HDC hDC, hMemDC;
+ HBITMAP hBitmap;
+ RECT rcClient;
+ CString strText;
+ HFONT hFont;
+ HBRUSH hBrushBK;
+
+
+ // BeginPaint
+ PAINTSTRUCT ps;
+ hDC = BeginPaint(m_hWnd, &ps);
+ GetClientRect(m_hWnd, &rcClient);
+
+ hMemDC = ::CreateCompatibleDC(hDC);
+ hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right-rcClient.left,
+ rcClient.bottom-rcClient.top);
+ ::SelectObject(hMemDC, hBitmap);
+
+ hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+ ::SelectObject(hMemDC, hFont);
+
+
+ // 背景颜色
+ hBrushBK = CreateSolidBrush( m_crBkgnd );
+ ::FillRect(hMemDC, &rcClient, hBrushBK);
+ DeleteObject(hBrushBK);
+
+
+ // 画线
+ HPEN hPen = CreatePen(PS_SOLID, 1, m_crLineColor);
+ HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPen);
+ ::MoveToEx(hMemDC, 0, 0, NULL);
+ LineTo(hMemDC, rcClient.right, 0);
+ ::SelectObject(hMemDC, hOldPen);
+
+
+ // EndPaint
+ ::BitBlt(hDC, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
+ hMemDC, 0, 0, SRCCOPY);
+ EndPaint(m_hWnd, &ps);
+ ::DeleteObject(hBitmap);
+ ::DeleteDC(hMemDC);
+
+
+ return 1;
+}
+
+void CHorizontalLine::SetBkgndColor(COLORREF cr)
+{
+ m_crBkgnd = cr;
+}
+
+void CHorizontalLine::SetLineColor(COLORREF cr)
+{
+ m_crLineColor = cr;
+}
+
+
diff --git a/SourceCode/Bond/Servo/HorizontalLine.h b/SourceCode/Bond/Servo/HorizontalLine.h
new file mode 100644
index 0000000..f5b3647
--- /dev/null
+++ b/SourceCode/Bond/Servo/HorizontalLine.h
@@ -0,0 +1,87 @@
+// HorizontalLine.h: interface for the CHorizontalLine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_HORIZONTALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
+#define AFX_HORIZONTALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_
+
+
+#pragma comment(lib, "Msimg32.lib") // TransparentBlt
+
+
+
+//====== HorizontalLine =====================================================
+
+#ifndef NOHORIZONTALLINE
+
+#ifdef _WIN32
+
+#define BYHORIZONTALLINE_CLASSA "BYHorizontalLine"
+#define BYHORIZONTALLINE_CLASSW L"BYHorizontalLine"
+
+#ifdef UNICODE
+#define BYHORIZONTALLINE_CLASS BYHORIZONTALLINE_CLASSW
+#else
+#define BYHORIZONTALLINE_CLASS BYHORIZONTALLINE_CLASSA
+#endif
+
+#else
+#define BYHORIZONTALLINE_CLASS "BYHorizontalLine"
+#endif
+
+
+#define BYSTAG_HORIZONTALLINE _T("ISHORIZONTALLINE")
+
+
+//====== WM_NOTIFY codes (NMHDR.code values) ==================================
+#define BYHORIZONTALLINE_FIRST (0U-590U) //
+#define BYHORIZONTALLINE_LAST (0U-550U)
+#define BYHORIZONTALLINE_ (BYHORIZONTALLINE_FIRST - 1)
+
+
+typedef struct tagBYHORIZONTALLINE_NMHDR
+{
+ NMHDR nmhdr;
+ DWORD dwData;
+ DWORD dwData1;
+ DWORD dwData2;
+} BYHORIZONTALLINE_NMHDR;
+
+
+
+#endif
+
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+class CHorizontalLine
+{
+public:
+ CHorizontalLine();
+ virtual ~CHorizontalLine();
+
+public:
+ static BOOL RegisterWndClass();
+ static CHorizontalLine* Hook(HWND hWnd);
+ void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0);
+ void Release();
+ void SetBkgndColor(COLORREF cr);
+ void SetLineColor(COLORREF cr);
+ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
+ LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
+ LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
+ LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+
+private:
+ HWND m_hWnd;
+ COLORREF m_crBkgnd;
+ COLORREF m_crLineColor;
+};
+
+#endif // !defined(AFX_HORIZONTALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index 38ad39f..729bf8d 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/SourceCode/Bond/Servo/Model.cpp
@@ -2,6 +2,9 @@
#include "Model.h"
#include "Log.h"
#include "Common.h"
+#include "ToolUnits.h"
+#include "CEqAlarmStep.h"
+#include "AlarmManager.h"
CModel::CModel()
@@ -108,10 +111,54 @@
pStep->getName().c_str(), pData);
notifyPtr(RX_CODE_STEP_EVENT_READDATA, pStep);
+ // 处理警告信息
+ if (isAlarmStep(pStep)) {
+ // 保存到数据库
+ AlarmManager& alarmManager = AlarmManager::getInstance();
+ std::string strAlarmText;
+ SERVO::CEquipment* pEquipment = pStep->getEquipment();
+ SERVO::CEqAlarmStep* pEqAlarmStep = (SERVO::CEqAlarmStep*)pStep;
+ const AlarmInfo* pAlarmInfo = alarmManager.getAlarmInfoByID(pEqAlarmStep->getAlarmId());
+ if (pAlarmInfo != nullptr) {
+ strAlarmText = pAlarmInfo->strAlarmText;
+ }
+ int state = pEqAlarmStep->getAlarmState();
+ if (state == 1) {
+ LOGE("<CAlarmDlg> 发生警告");
+ std::string startTime = CToolUnits::timeToString2(CToolUnits::getTimestamp());
+ std::string endTime = "";
+ bool result = alarmManager.addAlarm(std::to_string(pEqAlarmStep->getAlarmId()),
+ pEquipment->getName(), strAlarmText, startTime, endTime);
+ if (result) {
+ LOGI("<CAlarmDlg> Alarm added successfully!");
+ }
+ else {
+ LOGE("<CAlarmDlg> Failed to add alarm.");
+ }
+ }
+ else {
+ LOGE("<CAlarmDlg> i消除警告");
+ //alarmManager.updateAlarmEndTime(std::to_string(pEqAlarmStep->getAlarmId()),
+ // pEquipment->getName());
+ }
+
+ m_hsmsPassive.requestAlarmReport(pEqAlarmStep->getAlarmState(),
+ pEquipment->getBaseAlarmId() + pEqAlarmStep->getAlarmId(),
+ strAlarmText.c_str());
+ }
}
};
m_master.setListener(masterListener);
+
+
+ // 加载警告信息
+ AlarmManager& alarmManager = AlarmManager::getInstance();
+ char szBuffer[MAX_PATH];
+ sprintf_s(szBuffer, MAX_PATH, "%s\\AlarmList.csv", (LPTSTR)(LPCTSTR)m_strWorkDir);
+ alarmManager.readAlarmFile(szBuffer);
+
+
return 0;
}
@@ -329,3 +376,8 @@
return 0;
}
+
+bool CModel::isAlarmStep(SERVO::CStep* pStep)
+{
+ return CToolUnits::startsWith(pStep->getName(), STEP_ALARM_START);
+}
diff --git a/SourceCode/Bond/Servo/Model.h b/SourceCode/Bond/Servo/Model.h
index 6e2655c..3b92364 100644
--- a/SourceCode/Bond/Servo/Model.h
+++ b/SourceCode/Bond/Servo/Model.h
@@ -14,6 +14,7 @@
void setWorkDir(const char* pszWorkDir);
int init();
int term();
+ bool isAlarmStep(SERVO::CStep* pStep);
public:
int notify(int code);
diff --git a/SourceCode/Bond/Servo/Servo.cpp b/SourceCode/Bond/Servo/Servo.cpp
index 4b49603..4a492c8 100644
--- a/SourceCode/Bond/Servo/Servo.cpp
+++ b/SourceCode/Bond/Servo/Servo.cpp
@@ -8,6 +8,8 @@
#include "ServoGraph.h"
#include "AlarmManager.h"
#include "SECSRuntimeManager.h"
+#include "VerticalLine.h"
+
// 声明全局变量,用于管理 GDI+ 初始化
ULONG_PTR g_diplusToken;
@@ -92,6 +94,7 @@
// 注册控件
CServoGraph::RegisterWndClass();
+ CVerticalLine::RegisterWndClass();
// 初始化Rx库
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 228ffdd..d4dd065 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
Binary files differ
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index 1e7a588..15c767a 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -197,14 +197,24 @@
<ItemGroup>
<ClInclude Include="AlarmDlg.h" />
<ClInclude Include="AlarmManager.h" />
+ <ClInclude Include="ApredTreeCtrl2.h" />
<ClInclude Include="BlButton.h" />
+ <ClInclude Include="CAttribute.h" />
+ <ClInclude Include="CAttributeVector.h" />
<ClInclude Include="CBonder.h" />
<ClInclude Include="CCLinkPerformance\CCLinkIEControl.h" />
<ClInclude Include="CCLinkPerformance\PerformanceMelsec.h" />
<ClInclude Include="CEqAlarmStep.h" />
+ <ClInclude Include="CEqCimModeChangeStep.h" />
<ClInclude Include="CEqModeStep.h" />
+ <ClInclude Include="CEqProcessStep.h" />
<ClInclude Include="CEqStatusStep.h" />
+ <ClInclude Include="CPanelAttributes.h" />
+ <ClInclude Include="CPanelEquipment.h" />
+ <ClInclude Include="CPanelMaster.h" />
+ <ClInclude Include="CReadStep.h" />
<ClInclude Include="CStep.h" />
+ <ClInclude Include="CWriteStep.h" />
<ClInclude Include="DevicePropertyDlg.h" />
<ClInclude Include="CEFEM.h" />
<ClInclude Include="CEquipment.h" />
@@ -228,18 +238,29 @@
<ClInclude Include="targetver.h" />
<ClInclude Include="TerminalDisplayDlg.h" />
<ClInclude Include="ToolUnits.h" />
+ <ClInclude Include="VerticalLine.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="AlarmDlg.cpp" />
<ClCompile Include="AlarmManager.cpp" />
+ <ClCompile Include="ApredTreeCtrl2.cpp" />
<ClCompile Include="BlButton.cpp" />
+ <ClCompile Include="CAttribute.cpp" />
+ <ClCompile Include="CAttributeVector.cpp" />
<ClCompile Include="CBonder.cpp" />
<ClCompile Include="CCLinkPerformance\CCLinkIEControl.cpp" />
<ClCompile Include="CCLinkPerformance\PerformanceMelsec.cpp" />
<ClCompile Include="CEqAlarmStep.cpp" />
+ <ClCompile Include="CEqCimModeChangeStep.cpp" />
<ClCompile Include="CEqModeStep.cpp" />
+ <ClCompile Include="CEqProcessStep.cpp" />
<ClCompile Include="CEqStatusStep.cpp" />
+ <ClCompile Include="CPanelAttributes.cpp" />
+ <ClCompile Include="CPanelEquipment.cpp" />
+ <ClCompile Include="CPanelMaster.cpp" />
+ <ClCompile Include="CReadStep.cpp" />
<ClCompile Include="CStep.cpp" />
+ <ClCompile Include="CWriteStep.cpp" />
<ClCompile Include="DevicePropertyDlg.cpp" />
<ClCompile Include="CEFEM.cpp" />
<ClCompile Include="CEquipment.cpp" />
@@ -265,6 +286,7 @@
</ClCompile>
<ClCompile Include="TerminalDisplayDlg.cpp" />
<ClCompile Include="ToolUnits.cpp" />
+ <ClCompile Include="VerticalLine.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Servo.rc" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index 06cd13e..c1113c1 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -41,6 +41,17 @@
<ClCompile Include="CEqStatusStep.cpp" />
<ClCompile Include="CEqAlarmStep.cpp" />
<ClCompile Include="AlarmDlg.cpp" />
+ <ClCompile Include="CEqProcessStep.cpp" />
+ <ClCompile Include="CAttribute.cpp" />
+ <ClCompile Include="CAttributeVector.cpp" />
+ <ClCompile Include="CPanelMaster.cpp" />
+ <ClCompile Include="VerticalLine.cpp" />
+ <ClCompile Include="ApredTreeCtrl2.cpp" />
+ <ClCompile Include="CPanelAttributes.cpp" />
+ <ClCompile Include="CReadStep.cpp" />
+ <ClCompile Include="CWriteStep.cpp" />
+ <ClCompile Include="CEqCimModeChangeStep.cpp" />
+ <ClCompile Include="CPanelEquipment.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AlarmManager.h" />
@@ -80,6 +91,17 @@
<ClInclude Include="CEqStatusStep.h" />
<ClInclude Include="CEqAlarmStep.h" />
<ClInclude Include="AlarmDlg.h" />
+ <ClInclude Include="CEqProcessStep.h" />
+ <ClInclude Include="CAttribute.h" />
+ <ClInclude Include="CAttributeVector.h" />
+ <ClInclude Include="CPanelMaster.h" />
+ <ClInclude Include="VerticalLine.h" />
+ <ClInclude Include="ApredTreeCtrl2.h" />
+ <ClInclude Include="CPanelAttributes.h" />
+ <ClInclude Include="CReadStep.h" />
+ <ClInclude Include="CWriteStep.h" />
+ <ClInclude Include="CEqCimModeChangeStep.h" />
+ <ClInclude Include="CPanelEquipment.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Servo.rc" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.user b/SourceCode/Bond/Servo/Servo.vcxproj.user
index 3980fd1..86e9faf 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.user
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.user
@@ -7,6 +7,6 @@
<RemoteDebuggerCommand>D:\CLH\Servo\Servo.exe</RemoteDebuggerCommand>
<RemoteDebuggerWorkingDirectory>D:\CLH\Servo\</RemoteDebuggerWorkingDirectory>
<RemoteDebuggerServerName>Boounion-0106</RemoteDebuggerServerName>
- <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/ServoDlg.cpp b/SourceCode/Bond/Servo/ServoDlg.cpp
index bb7deba..90ee383 100644
--- a/SourceCode/Bond/Servo/ServoDlg.cpp
+++ b/SourceCode/Bond/Servo/ServoDlg.cpp
@@ -9,6 +9,7 @@
#include "Common.h"
#include "Log.h"
#include "SecsTestDlg.h"
+#include "AlarmDlg.h"
#include <chrono>
#include <thread>
#include <cmath>
@@ -90,6 +91,9 @@
m_pAlarmDlg = nullptr;
m_pTerminalDisplayDlg = nullptr;
m_pObserver = nullptr;
+ m_pPanelMaster = nullptr;
+ m_pPanelEquipment = nullptr;
+ m_pPanelAttributes = nullptr;
}
void CServoDlg::DoDataExchange(CDataExchange* pDX)
@@ -127,6 +131,9 @@
ON_WM_TIMER()
ON_WM_ERASEBKGND()
ON_BN_CLICKED(IDC_BUTTON_ALARM, &CServoDlg::OnBnClickedButtonAlarm)
+ ON_BN_CLICKED(IDC_BUTTON_ALARM, &CServoDlg::OnBnClickedButtonAlarm)
+ ON_NOTIFY(BYSERVOGRAPH_ITEM_CLICKED, IDC_SERVO_GRAPH1, &CServoDlg::OnGraphItemClicked)
+ ON_MESSAGE(ID_MSG_PANEL_RESIZE, OnPanelResize)
END_MESSAGE_MAP()
@@ -164,6 +171,35 @@
}
}
}
+ else if (RX_CODE_SELECT_EQUIPMENT == code) {
+ SERVO::CEquipment* pEquipment = nullptr;
+ if (pAny->getPtrValue("ptr", (void*&)pEquipment)) {
+ ASSERT(pEquipment);
+ ASSERT(m_pPanelEquipment);
+ ASSERT(m_pPanelAttributes);
+ m_pPanelEquipment->SetEquipment(pEquipment);
+ m_pPanelAttributes->ShowWindow(SW_HIDE);
+ if (!m_pPanelEquipment->IsWindowVisible()) {
+ m_pPanelEquipment->ShowWindow(SW_SHOW);
+ Resize();
+ }
+ }
+ }
+ else if (RX_CODE_SELECT_STEP == code) {
+ SERVO::CStep* pStep = nullptr;
+ if (pAny->getPtrValue("ptr", (void*&)pStep)) {
+ ASSERT(pStep);
+ ASSERT(m_pPanelEquipment);
+ ASSERT(m_pPanelAttributes);
+ m_pPanelEquipment->ShowWindow(SW_HIDE);
+ m_pPanelAttributes->loadDataFromStep(pStep);
+ if (!m_pPanelAttributes->IsWindowVisible()) {
+ m_pPanelAttributes->ShowWindow(SW_SHOW);
+ Resize();
+ }
+ }
+ }
+
pAny->release();
}, [&]() -> void {
// onComplete
@@ -278,6 +314,8 @@
m_pGraph->SetBoxText(INDICATE_ROBOT_ARM2, "6", "Robot");
+
+
// Vacuum bake
m_pGraph->AddIndicateBox(INDICATE_VACUUM_BAKE, 396, 516, 48, RGB(22, 22, 22),
RGB(255, 127, 39), RGB(0, 176, 80));
@@ -294,6 +332,17 @@
m_pGraph->AddIndicateBox(INDICATE_MEASUREMENT, 736, 516, 48, RGB(22, 22, 22),
RGB(255, 127, 39), RGB(0, 176, 80));
m_pGraph->SetBoxText(INDICATE_MEASUREMENT, "13", "Measurement");
+
+
+
+ m_pPanelMaster = new CPanelMaster();
+ m_pPanelMaster->Create(IDD_PANEL_MASTER, this);
+ m_pPanelMaster->ShowWindow(SW_SHOW);
+ m_pPanelEquipment = new CPanelEquipment();
+ m_pPanelEquipment->Create(IDD_PANEL_EQUIPMENT, this);
+ m_pPanelAttributes = new CPanelAttributes();
+ m_pPanelAttributes->Create(IDD_PANEL_ATTRIBUTES, this);
+
// 调整初始窗口位置
@@ -318,6 +367,13 @@
// 相当于延时调用master的初始化
theApp.m_model.m_master.init();
+
+
+ // 绑定数据
+ {
+ SERVO::CEquipment* pEquipment = theApp.m_model.m_master.getEquipment(EQ_ID_EFEM);
+ m_pGraph->SetIndicateBoxData(INDICATE_ROBOT_ARM1, pEquipment);
+ }
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
@@ -541,6 +597,24 @@
m_pTerminalDisplayDlg = nullptr;
}
+ if (m_pPanelMaster != nullptr) {
+ m_pPanelMaster->DestroyWindow();
+ delete m_pPanelMaster;
+ m_pPanelMaster = nullptr;
+ }
+
+ if (m_pPanelEquipment != nullptr) {
+ m_pPanelEquipment->DestroyWindow();
+ delete m_pPanelEquipment;
+ m_pPanelEquipment = nullptr;
+ }
+
+ if (m_pPanelAttributes != nullptr) {
+ m_pPanelAttributes->DestroyWindow();
+ delete m_pPanelAttributes;
+ m_pPanelAttributes = nullptr;
+ }
+
if (m_hbrBkgnd != nullptr) {
::DeleteObject(m_hbrBkgnd);
}
@@ -749,6 +823,25 @@
x = 0;
y = 0;
+ int nPanelWidth = 0;
+ if (m_pPanelMaster != nullptr) {
+ nPanelWidth = m_pPanelMaster->getPanelWidth();
+ m_pPanelMaster->MoveWindow(x, y, nPanelWidth, rcClient.Height());
+ x += nPanelWidth;
+ }
+
+ if (m_pPanelEquipment != nullptr && m_pPanelEquipment->IsWindowVisible()) {
+ nPanelWidth = m_pPanelEquipment->getPanelWidth();
+ m_pPanelEquipment->MoveWindow(x, y, nPanelWidth, rcClient.Height());
+ x += nPanelWidth;
+ }
+
+ if (m_pPanelAttributes != nullptr && m_pPanelAttributes->IsWindowVisible()) {
+ nPanelWidth = m_pPanelAttributes->getPanelWidth();
+ m_pPanelAttributes->MoveWindow(x, y, nPanelWidth, rcClient.Height());
+ x += nPanelWidth;
+ }
+
pItem = GetDlgItem(IDC_SERVO_GRAPH1);
pItem->GetClientRect(&rcItem);
pItem->MoveWindow(x, y, rcItem.Width(), rcItem.Height());
@@ -858,27 +951,29 @@
void CServoDlg::OnBnClickedButtonAlarm()
{
// TODO: 在此添加控件通知处理程序代码
- m_bShowAlarmWnd = !m_bShowAlarmWnd;
-
- // 如果要显示报警窗口,则隐藏日志窗口
- if (m_bShowAlarmWnd) {
- m_bShowLogWnd = false;
- if (m_pLogDlg != nullptr) {
- m_pLogDlg->ShowWindow(SW_HIDE);
- UpdateLogBtn();
- }
- }
-
- if (m_pAlarmDlg == nullptr) {
- m_pAlarmDlg = new CAlarmDlg();
- m_pAlarmDlg->Create(IDD_DIALOG_ALARM, this);
-
- CRect rcWnd;
- GetWindowRect(&rcWnd);
- m_pAlarmDlg->MoveWindow(rcWnd.left, rcWnd.bottom - 8, rcWnd.Width(), 200);
- }
- ASSERT(m_pAlarmDlg);
- m_pAlarmDlg->ShowWindow(m_bShowAlarmWnd ? SW_SHOW : SW_HIDE);
-
- UpdateAlarmBtn();
+ CAlarmDlg dlg;
+ dlg.DoModal();
}
+
+void CServoDlg::OnGraphItemClicked(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ BYSERVOGRAPH_NMHDR* pGraphNmhdr = reinterpret_cast<BYSERVOGRAPH_NMHDR*>(pNMHDR);
+ CString s; s.Format(_T("OnGraphItemClicked %d"), pGraphNmhdr->dwData);
+ SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)m_pGraph->GetIndicateBoxData(pGraphNmhdr->dwData);
+ if (pEquipment != nullptr) {
+ AfxMessageBox(pEquipment->getName().c_str());
+ }
+
+
+ *pResult = 0;
+}
+
+LRESULT CServoDlg::OnPanelResize(WPARAM wParam, LPARAM lParam)
+{
+ int width = wParam;
+ // m_pPanel->SetPanelWidth(width);
+ Resize();
+
+ return 0;
+}
+
diff --git a/SourceCode/Bond/Servo/ServoDlg.h b/SourceCode/Bond/Servo/ServoDlg.h
index dc5314e..39ae6d7 100644
--- a/SourceCode/Bond/Servo/ServoDlg.h
+++ b/SourceCode/Bond/Servo/ServoDlg.h
@@ -8,6 +8,10 @@
#include "LogDlg.h"
#include "AlarmDlg.h"
#include "TerminalDisplayDlg.h"
+#include "CPanelMaster.h"
+#include "CPanelEquipment.h"
+#include "CPanelAttributes.h"
+
enum DeviceStatus {
ONLINE, // 在线
@@ -64,7 +68,9 @@
HBRUSH m_hbrBkgnd;
CBlButton m_btnLog;
CBlButton m_btnAlarm;
-
+ CPanelMaster* m_pPanelMaster;
+ CPanelEquipment* m_pPanelEquipment;
+ CPanelAttributes* m_pPanelAttributes;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
@@ -97,4 +103,6 @@
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnBnClickedButtonAlarm();
+ afx_msg void OnGraphItemClicked(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg LRESULT OnPanelResize(WPARAM wParam, LPARAM lParam);
};
diff --git a/SourceCode/Bond/Servo/ServoGraph.cpp b/SourceCode/Bond/Servo/ServoGraph.cpp
index daf274a..63bfab7 100644
--- a/SourceCode/Bond/Servo/ServoGraph.cpp
+++ b/SourceCode/Bond/Servo/ServoGraph.cpp
@@ -693,4 +693,22 @@
graphics.DrawImage(&bitmap, item.x, item.y);
graphics.ResetTransform();
}
+}
+
+void CServoGraph::SetIndicateBoxData(int id, void* pData)
+{
+ INDICATEBOX* pib = GetIndicateBox(id);
+ if (pib != nullptr) {
+ pib->m_pData = pData;
+ }
+}
+
+void* CServoGraph::GetIndicateBoxData(int id)
+{
+ INDICATEBOX* pib = GetIndicateBox(id);
+ if (pib != nullptr) {
+ return pib->m_pData;
+ }
+
+ return nullptr;
}
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/ServoGraph.h b/SourceCode/Bond/Servo/ServoGraph.h
index d409660..3dc0518 100644
--- a/SourceCode/Bond/Servo/ServoGraph.h
+++ b/SourceCode/Bond/Servo/ServoGraph.h
@@ -94,6 +94,7 @@
this->box2BackgroundColor = RGB(0, 255, 255);;
this->box2FrameColor = RGB(255, 255, 0);;
this->bBox2Visible = FALSE;
+ this->m_pData = nullptr;
};
~INDICATEBOX() {};
@@ -110,6 +111,7 @@
COLORREF box2FrameColor;
BOOL bBox2Visible;
std::vector<void*> m_contexts;
+ void* m_pData;
};
class INDICATEBKGND
@@ -154,6 +156,8 @@
BOOL RemoveIndicateBoxAllContext(int id);
const std::vector<void*>& GetIndicateBoxContexts(int id);
bool IsIndicateBoxContextsEmpty(int id);
+ void SetIndicateBoxData(int id, void* pData);
+ void* GetIndicateBoxData(int id);
void ShowIndicateBoxInterior(int id, COLORREF color);
void HideIndicateBoxInterior(int id);
CServoGraph::INDICATEBOX* GetIndicateBox(int id);
diff --git a/SourceCode/Bond/Servo/ToolUnits.cpp b/SourceCode/Bond/Servo/ToolUnits.cpp
index 664f802..a3e1725 100644
--- a/SourceCode/Bond/Servo/ToolUnits.cpp
+++ b/SourceCode/Bond/Servo/ToolUnits.cpp
@@ -301,4 +301,9 @@
ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
return std::string(buffer);
+}
+
+bool CToolUnits::startsWith(const std::string& str, const std::string& prefix)
+{
+ return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0;
}
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/ToolUnits.h b/SourceCode/Bond/Servo/ToolUnits.h
index 9e8fdfb..d010744 100644
--- a/SourceCode/Bond/Servo/ToolUnits.h
+++ b/SourceCode/Bond/Servo/ToolUnits.h
@@ -28,5 +28,6 @@
static std::vector<CString> GetFileNamesInDirectory(const CString& strFolderPath, const CString& strExtension);
static std::string getRecipePath();
static std::string getCurrentTimeString();
+ static bool startsWith(const std::string& str, const std::string& prefix);
};
diff --git a/SourceCode/Bond/Servo/VerticalLine.cpp b/SourceCode/Bond/Servo/VerticalLine.cpp
new file mode 100644
index 0000000..319e508
--- /dev/null
+++ b/SourceCode/Bond/Servo/VerticalLine.cpp
@@ -0,0 +1,316 @@
+// VerticalLine.cpp: implementation of the CVerticalLine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "VerticalLine.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CVerticalLine::CVerticalLine()
+{
+ m_hWnd = NULL;
+ m_crBkgnd = RGB(255, 255, 255);
+ m_crLineColor = RGB(222, 222, 222);
+ m_bEnableResize = FALSE;
+}
+
+CVerticalLine::~CVerticalLine()
+{
+}
+
+BOOL CVerticalLine::RegisterWndClass()
+{
+ WNDCLASS wc;
+ wc.lpszClassName = BYVERTICALLINE_CLASS;
+ wc.hInstance = AfxGetInstanceHandle();
+ wc.lpfnWndProc = WindowProc;
+ wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+ wc.hIcon = 0;
+ wc.lpszMenuName = NULL;
+ wc.hbrBackground = NULL;
+ wc.style = CS_GLOBALCLASS|CS_DBLCLKS;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+
+ // 注册自定义类
+ return (::RegisterClass(&wc) != 0);
+}
+
+CVerticalLine* CVerticalLine::Hook(HWND hWnd)
+{
+ CVerticalLine* pVerticalLine = (CVerticalLine*)GetProp(hWnd, BYSTAG_VERTICALLINE);
+ if(pVerticalLine == NULL)
+ {
+ pVerticalLine = new CVerticalLine;
+ pVerticalLine->m_hWnd = hWnd;
+
+ SetProp(hWnd, BYSTAG_VERTICALLINE, (HANDLE)pVerticalLine);
+ }
+
+ return pVerticalLine;
+}
+
+void CVerticalLine::Release()
+{
+ // delete
+ delete this;
+}
+
+void CVerticalLine::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/)
+{
+ HWND hParent;
+ hParent = GetParent(m_hWnd);
+ if(hParent != NULL) {
+ BYVERTICALLINE_NMHDR iii_nmhdr;
+ iii_nmhdr.nmhdr.hwndFrom = m_hWnd;
+ iii_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+ iii_nmhdr.nmhdr.code = nCode;
+ iii_nmhdr.dwData = dwData;
+ iii_nmhdr.dwData1 = dwData1;
+ iii_nmhdr.dwData2 = dwData2;
+ SendMessage(hParent, WM_NOTIFY, (WPARAM)iii_nmhdr.nmhdr.idFrom, (LPARAM)&iii_nmhdr);
+ }
+}
+
+////////////////////////////////
+// 拦截窗口消息函数
+LRESULT CALLBACK CVerticalLine::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CVerticalLine* pVerticalLine = (CVerticalLine *)GetProp(hWnd, BYSTAG_VERTICALLINE);
+ if(pVerticalLine == NULL && uMsg != WM_NCCREATE)
+ {
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+
+
+ // 如果Hook则响应消息
+ ASSERT(hWnd);
+ switch(uMsg)
+ {
+ case WM_NCCREATE:
+ return OnNcCreate(hWnd, wParam, lParam);
+
+ case WM_DESTROY:
+ return pVerticalLine->OnDestroy(wParam, lParam);
+
+ case WM_PAINT:
+ return pVerticalLine->OnPaint(wParam, lParam);
+
+ case WM_TIMER:
+ return pVerticalLine->OnTimer(wParam, lParam);
+
+ case WM_SETCURSOR:
+ return pVerticalLine->OnSetCursor(wParam, lParam);
+
+ case WM_LBUTTONDOWN:
+ return pVerticalLine->OnLButtonDown(wParam, lParam);
+
+ case WM_GETDLGCODE:
+ return DLGC_WANTALLKEYS;
+
+ default:
+ break;
+ }
+
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_NCCREATE
+// 窗口创建前的初始化工作
+LRESULT CVerticalLine::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ CVerticalLine* pVerticalLine = (CVerticalLine *)GetProp(hWnd, BYSTAG_VERTICALLINE);
+ ASSERT(pVerticalLine == NULL);
+
+ Hook(hWnd);
+ return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_DESTROY
+LRESULT CVerticalLine::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+ Release();
+ return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_TIMER
+LRESULT CVerticalLine::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+ return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_SETCURSOR
+LRESULT CVerticalLine::OnSetCursor(WPARAM wParam, LPARAM lParam)
+{
+ if(m_bEnableResize) {
+ SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
+ return TRUE;
+ }
+
+ return ::DefWindowProc(m_hWnd, WM_SETCURSOR, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONDOWN
+ * 鼠标左键按下
+ */
+LRESULT CVerticalLine::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+{
+ if (!m_bEnableResize) {
+ return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+ }
+
+
+ POINT pt, ptNew;
+ pt.x = LOWORD(lParam);
+ pt.y = HIWORD(lParam);
+ int nMoveX = 0;
+
+
+ // 捕捉鼠标消息,检测是否拖动
+ RECT rcParent, rcWindows;
+ GetClientRect(m_hWnd, &rcWindows);
+ ::ClientToScreen(m_hWnd, (LPPOINT)&rcWindows);
+ ::ClientToScreen(m_hWnd, (LPPOINT)&rcWindows.right);
+ GetClientRect(GetParent(m_hWnd), &rcParent);
+ ::ClientToScreen(GetParent(m_hWnd), (LPPOINT)&rcParent);
+ HDC hDC = GetDC(GetDesktopWindow());
+ ::DrawFocusRect(hDC, &rcWindows);
+
+ if (::GetCapture() == NULL) {
+ SetCapture(m_hWnd);
+ ASSERT(m_hWnd == GetCapture());
+ AfxLockTempMaps();
+ for (;;) {
+ MSG msg;
+ VERIFY(::GetMessage(&msg, NULL, 0, 0));
+
+ if (GetCapture() != m_hWnd) break;
+
+ switch (msg.message)
+ {
+ case WM_MOUSEMOVE:
+ ptNew = msg.pt;
+ if (ptNew.x < rcParent.left) ptNew.x = rcParent.left;
+ ::DrawFocusRect(hDC, &rcWindows);
+ rcWindows.left = ptNew.x - 3;
+ rcWindows.right = ptNew.x + 3;
+ ::DrawFocusRect(hDC, &rcWindows);
+ ::ScreenToClient(m_hWnd, &ptNew);
+ break;
+
+ case WM_LBUTTONUP:
+ ptNew = msg.pt;
+ ::ScreenToClient(m_hWnd, &ptNew);
+ nMoveX = ptNew.x - pt.x;
+ goto ExitLoop;
+
+ case WM_KEYDOWN:
+ if (msg.wParam == VK_ESCAPE) {
+ goto ExitLoop;
+ }
+ break;
+
+ default:
+ DispatchMessage(&msg);
+ break;
+ }
+ }
+
+ ExitLoop:
+ ::DrawFocusRect(hDC, &rcWindows);
+ ReleaseDC(GetDesktopWindow(), hDC);
+ ReleaseCapture();
+ ::InvalidateRect(m_hWnd, NULL, TRUE);
+ Notify((int)BYVERTICALLINE_MOVEX, nMoveX);
+ AfxUnlockTempMaps(FALSE);
+ }
+
+
+ return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_PAINT
+LRESULT CVerticalLine::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+ HDC hDC, hMemDC;
+ HBITMAP hBitmap;
+ RECT rcClient;
+ CString strText;
+ HFONT hFont;
+ HBRUSH hBrushBK;
+
+
+ // BeginPaint
+ PAINTSTRUCT ps;
+ hDC = BeginPaint(m_hWnd, &ps);
+ GetClientRect(m_hWnd, &rcClient);
+
+ hMemDC = ::CreateCompatibleDC(hDC);
+ hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right-rcClient.left,
+ rcClient.bottom-rcClient.top);
+ ::SelectObject(hMemDC, hBitmap);
+
+ hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+ ::SelectObject(hMemDC, hFont);
+
+
+ // 背景颜色
+ hBrushBK = CreateSolidBrush( m_crBkgnd );
+ ::FillRect(hMemDC, &rcClient, hBrushBK);
+ DeleteObject(hBrushBK);
+
+
+ // 画线
+ HPEN hPen = CreatePen(PS_SOLID, 1, m_crLineColor);
+ HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPen);
+ ::MoveToEx(hMemDC, rcClient.right-1, 0, NULL);
+ LineTo(hMemDC, rcClient.right - 1, rcClient.bottom);
+ ::SelectObject(hMemDC, hOldPen);
+
+
+ // EndPaint
+ ::BitBlt(hDC, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
+ hMemDC, 0, 0, SRCCOPY);
+ EndPaint(m_hWnd, &ps);
+ ::DeleteObject(hBitmap);
+ ::DeleteDC(hMemDC);
+
+
+ return 1;
+}
+
+void CVerticalLine::SetBkgndColor(COLORREF cr)
+{
+ m_crBkgnd = cr;
+}
+
+void CVerticalLine::SetLineColor(COLORREF cr)
+{
+ m_crLineColor = cr;
+}
+
+void CVerticalLine::EnableResize()
+{
+ m_bEnableResize = TRUE;
+}
+
+void CVerticalLine::DisableResize()
+{
+ m_bEnableResize = FALSE;
+}
+
diff --git a/SourceCode/Bond/Servo/VerticalLine.h b/SourceCode/Bond/Servo/VerticalLine.h
new file mode 100644
index 0000000..d27f7b6
--- /dev/null
+++ b/SourceCode/Bond/Servo/VerticalLine.h
@@ -0,0 +1,95 @@
+// VerticalLine.h: interface for the CVerticalLine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_VERTICALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
+#define AFX_VERTICALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_
+
+
+#pragma comment(lib, "Msimg32.lib") // TransparentBlt
+
+
+
+//====== VerticalLine =====================================================
+
+#ifndef NOVERTICALLINE
+
+#ifdef _WIN32
+
+#define BYVERTICALLINE_CLASSA "BYVerticalLine"
+#define BYVERTICALLINE_CLASSW L"BYVerticalLine"
+
+#ifdef UNICODE
+#define BYVERTICALLINE_CLASS BYVERTICALLINE_CLASSW
+#else
+#define BYVERTICALLINE_CLASS BYVERTICALLINE_CLASSA
+#endif
+
+#else
+#define BYVERTICALLINE_CLASS "BYVerticalLine"
+#endif
+
+
+#define BYSTAG_VERTICALLINE _T("ISVERTICALLINE")
+
+
+//====== WM_NOTIFY codes (NMHDR.code values) ==================================
+#define BYVERTICALLINE_FIRST (0U-2330U) //
+#define BYVERTICALLINE_LAST (0U-2320U)
+#define BYVERTICALLINE_MOVEX (BYVERTICALLINE_FIRST - 1)
+
+
+typedef struct tagBYVERTICALLINE_NMHDR
+{
+ NMHDR nmhdr;
+ DWORD dwData;
+ DWORD dwData1;
+ DWORD dwData2;
+} BYVERTICALLINE_NMHDR;
+
+
+
+#endif
+
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+class CVerticalLine
+{
+public:
+ CVerticalLine();
+ virtual ~CVerticalLine();
+
+
+public:
+ void EnableResize();
+ void DisableResize();
+ static BOOL RegisterWndClass();
+ static CVerticalLine* Hook(HWND hWnd);
+ void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0);
+ void Release();
+ void SetBkgndColor(COLORREF cr);
+ void SetLineColor(COLORREF cr);
+ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
+ LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
+ LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
+ LRESULT OnSetCursor(WPARAM wParam, LPARAM lParam);
+ LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+ LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
+
+private:
+ HWND m_hWnd;
+ COLORREF m_crBkgnd;
+ COLORREF m_crLineColor;
+
+private:
+ BOOL m_bEnableResize;
+};
+
+#endif // !defined(AFX_VERTICALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 2afa563..f5ef8b0 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/panel_close_24_a.ico b/SourceCode/Bond/x64/Debug/Res/panel_close_24_a.ico
new file mode 100644
index 0000000..8950fff
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/panel_close_24_a.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/panel_close_24_b.ico b/SourceCode/Bond/x64/Debug/Res/panel_close_24_b.ico
new file mode 100644
index 0000000..5df3daa
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/panel_close_24_b.ico
Binary files differ
--
Gitblit v1.9.3