From bb13ecc602edb0247f65a1362135e4ef70a5a79f Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期五, 06 六月 2025 13:50:15 +0800
Subject: [PATCH] Merge branch 'master' into clh
---
SourceCode/Bond/Servo/CRobotTask.h | 1
SourceCode/Bond/Servo/resource.h | 0
SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp | 2
SourceCode/Bond/Servo/CRobotTask.cpp | 12 ++
SourceCode/Bond/Servo/CRobotTaskDlg.h | 4
SourceCode/Bond/Servo/BlButton.cpp | 8
SourceCode/Bond/Servo/JobSlotGrid.h | 14 ++
SourceCode/Bond/Servo/CRobotTaskDlg.cpp | 97 +++++++++++++++++--
SourceCode/Bond/Servo/JobSlotGrid.cpp | 111 +++++++++++++++++++++-
9 files changed, 229 insertions(+), 20 deletions(-)
diff --git a/SourceCode/Bond/Servo/BlButton.cpp b/SourceCode/Bond/Servo/BlButton.cpp
index 5eb7694..2bddd2b 100644
--- a/SourceCode/Bond/Servo/BlButton.cpp
+++ b/SourceCode/Bond/Servo/BlButton.cpp
@@ -219,8 +219,7 @@
hFont = (HFONT)pFont->GetSafeHandle();
}
-
- ::SelectObject(hDC, hFont);
+ HFONT hOldFont = (HFONT)::SelectObject(hDC, hFont);
::SetBkMode(hDC, TRANSPARENT);
::SetTextColor(hDC, m_crText[state]);
@@ -237,6 +236,7 @@
}
DrawTextA(hDC, szText, (int)strlen(szText), &rcText, DT_VCENTER | DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
}
+ ::SelectObject(hDC, hOldFont);
// 是否有小圆点
@@ -283,8 +283,8 @@
::Polygon(hDC, pt, 3);
::SelectObject(hDC, hOldBrush);
::SelectObject(hDC, hOldPen);
- ::DeleteObject(hBrush);
- ::DeleteObject(hPen);
+ ::DeleteObject(hbrDrop); // 正确释放小三角使用的画刷
+ ::DeleteObject(hPenDrop); // 正确释放小三角的笔
}
}
diff --git a/SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp b/SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp
index ea62463..804335e 100644
--- a/SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp
+++ b/SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp
@@ -342,7 +342,7 @@
}
return 0;
- });
+ });
CString log;
if (ret == 0) {
diff --git a/SourceCode/Bond/Servo/CRobotTask.cpp b/SourceCode/Bond/Servo/CRobotTask.cpp
index 3112351..a33cc40 100644
--- a/SourceCode/Bond/Servo/CRobotTask.cpp
+++ b/SourceCode/Bond/Servo/CRobotTask.cpp
@@ -174,6 +174,18 @@
return m_robotCmdParam.putSlotNo;
}
+ CString CRobotTask::getStateString()
+ {
+ switch (m_state) {
+ case ROBOT_TASK_STATE::Ready: return _T("Ready");
+ case ROBOT_TASK_STATE::Running: return _T("Running");
+ case ROBOT_TASK_STATE::Error: return _T("Error");
+ case ROBOT_TASK_STATE::Abort: return _T("Abort");
+ case ROBOT_TASK_STATE::Completed: return _T("Completed");
+ default: return _T("Unknown");
+ }
+ }
+
void CRobotTask::fetchOut()
{
m_timeFetchOut = CToolUnits::getUnixTimestamp();;
diff --git a/SourceCode/Bond/Servo/CRobotTask.h b/SourceCode/Bond/Servo/CRobotTask.h
index f02d1ff..2cd8654 100644
--- a/SourceCode/Bond/Servo/CRobotTask.h
+++ b/SourceCode/Bond/Servo/CRobotTask.h
@@ -30,6 +30,7 @@
int getSrcSlot();
int getTarPosition();
int getTarSlot();
+ CString getStateString();
// 从源地拔片
void fetchOut();
diff --git a/SourceCode/Bond/Servo/CRobotTaskDlg.cpp b/SourceCode/Bond/Servo/CRobotTaskDlg.cpp
index 16fd9da..b354216 100644
--- a/SourceCode/Bond/Servo/CRobotTaskDlg.cpp
+++ b/SourceCode/Bond/Servo/CRobotTaskDlg.cpp
@@ -32,6 +32,7 @@
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_ACTIVATE()
+ ON_BN_CLICKED(IDC_BUTTON_ABORT_TASK, &CRobotTaskDlg::OnBnClickedAbortTask)
END_MESSAGE_MAP()
@@ -47,15 +48,47 @@
GetDlgItem(IDC_LABEL_NO_TASK)->ShowWindow(m_pRobotTask == nullptr ? SW_SHOW : SW_HIDE);
GetDlgItem(IDC_LABEL_GET_PUT)->ShowWindow(m_pRobotTask != nullptr ? SW_SHOW : SW_HIDE);
+ if (m_btnAbortTask.m_hWnd) {
+ m_btnAbortTask.ShowWindow(m_pRobotTask ? SW_SHOW : SW_HIDE);
+ }
if (m_pRobotTask != nullptr) {
- SERVO::CEquipment* pEq1, * pEq2;
- pEq1 = theApp.m_model.getMaster().getEquipment(m_pRobotTask->getSrcPosition());
- pEq2 = theApp.m_model.getMaster().getEquipment(m_pRobotTask->getTarPosition());
+ using namespace SERVO;
- CString strText;
- strText.Format(_T("%s --> %s"), pEq1->getName().c_str(), pEq2->getName().c_str());
- SetDlgItemText(IDC_LABEL_GET_PUT, strText);
+ CEquipment* pSrcEq = theApp.m_model.getMaster().getEquipment(pRobotTask->getSrcPosition());
+ CEquipment* pDstEq = theApp.m_model.getMaster().getEquipment(pRobotTask->getTarPosition());
+
+ ROBOT_CMD_PARAM& param = pRobotTask->getRobotCmdParam();
+
+ auto format_time = [](time_t t) -> CString {
+ if (t == 0) {
+ return _T("-");
+ }
+ CTime time(t);
+ return time.Format(_T("%Y-%m-%d %H:%M:%S"));
+ };
+
+ CString strDetail;
+ strDetail.Format(
+ _T("浠诲姟 ID: %s\r\n婧愪綅缃�: %s (P%d)\r\n鐩爣浣嶇疆: %s (P%d)\r\n")
+ _T("婧愭Ы浣�: Slot %d\r\n鐩爣妲戒綅: Slot %d\r\n鎵嬭噦缂栧彿: Arm %d\r\n浠诲姟鐘舵��: %s\r\n")
+ _T("鍒涘缓鏃堕棿: %s\r\n鍙栫墖鏃堕棿: %s\r\n鏀剧墖鏃堕棿: %s\r\n缁撴潫鏃堕棿: %s"),
+ pRobotTask->getId().c_str(),
+ pSrcEq ? pSrcEq->getName().c_str() : _T("鏈煡"),
+ param.getPosition,
+ pDstEq ? pDstEq->getName().c_str() : _T("鏈煡"),
+ param.putPosition,
+ param.getSlotNo,
+ param.putSlotNo,
+ param.armNo,
+ pRobotTask->getStateString(),
+ format_time(pRobotTask->getCreateTime()),
+ format_time(pRobotTask->getFetchoutTime()),
+ format_time(pRobotTask->getStoredTime()),
+ format_time(pRobotTask->getFinishTime())
+ );
+
+ SetDlgItemText(IDC_LABEL_GET_PUT, strDetail);
}
}
@@ -64,6 +97,20 @@
CDialogEx::OnInitDialog();
// TODO: 鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+ // 鍒涘缓鈥滃仠姝换鍔♀�濇寜閽�
+ m_btnAbortTask.Create(_T("鍋滄浠诲姟"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, CRect(0, 0, 100, 30), this, IDC_BUTTON_ABORT_TASK);
+
+ // 鍔ㄦ�佹寜閽垱寤哄悗璁剧疆瀛椾綋
+ if (m_fontButton.GetSafeHandle() == nullptr) {
+ m_fontButton.CreatePointFont(110, _T("寰蒋闆呴粦")); // 鎴� "Segoe UI"
+ }
+ m_btnAbortTask.SetFont(&m_fontButton);
+
+ // 璁剧疆 LABEL 鎺т欢鐨勫瓧浣�
+ if (m_fontDetail.GetSafeHandle() == nullptr) {
+ m_fontDetail.CreatePointFont(100, _T("寰蒋闆呴粦"));
+ }
+ GetDlgItem(IDC_LABEL_GET_PUT)->SetFont(&m_fontDetail);
return TRUE; // return TRUE unless you set the focus to a control
// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
@@ -86,6 +133,13 @@
CDialogEx::OnDestroy();
// TODO: 鍦ㄦ澶勬坊鍔犳秷鎭鐞嗙▼搴忎唬鐮�
+ if (m_fontButton.GetSafeHandle()) {
+ m_fontButton.DeleteObject();
+ }
+
+ if (m_fontDetail.GetSafeHandle()) {
+ m_fontDetail.DeleteObject();
+ }
}
void CRobotTaskDlg::OnSize(UINT nType, int cx, int cy)
@@ -116,9 +170,32 @@
(rcClient.Height() - rcItem.Height()) / 2, rcItem.Width(), rcItem.Height());
pItem = GetDlgItem(IDC_LABEL_GET_PUT);
- pItem->GetClientRect(&rcItem);
- pItem->MoveWindow(12,
- 12, rcItem.Width(), rcItem.Height());
+ if (pItem && pItem->m_hWnd) {
+ const int nLabelX = 12;
+ const int nLabelY = 12;
+ const int nLabelWidth = rcClient.Width() - 24;
+ const int nLabelHeight = rcClient.Height() - 24;
+
+ pItem->MoveWindow(nLabelX, nLabelY, nLabelWidth, nLabelHeight);
+ }
+
+ // 璁剧疆鈥滃仠姝换鍔♀�濇寜閽綅缃紙鍙充笅瑙掞級
+ if (m_btnAbortTask.m_hWnd != nullptr) {
+ const int nBtnWidth = 100;
+ const int nBtnHeight = 28;
+ const int nMargin = 12;
+
+ const int nPosX = rcClient.right - nBtnWidth - nMargin;
+ const int nPosY = rcClient.bottom - nBtnHeight - nMargin;
+
+ m_btnAbortTask.MoveWindow(nPosX, nPosY, nBtnWidth, nBtnHeight);
+ }
}
-
+void CRobotTaskDlg::OnBnClickedAbortTask()
+{
+ if (m_pRobotTask) {
+ m_pRobotTask->abort();
+ AfxMessageBox(_T("浠诲姟宸插仠姝€��"));
+ }
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/CRobotTaskDlg.h b/SourceCode/Bond/Servo/CRobotTaskDlg.h
index 8754432..9226dcb 100644
--- a/SourceCode/Bond/Servo/CRobotTaskDlg.h
+++ b/SourceCode/Bond/Servo/CRobotTaskDlg.h
@@ -21,6 +21,9 @@
private:
SERVO::CRobotTask* m_pRobotTask;
+ CButton m_btnAbortTask;
+ CFont m_fontButton;
+ CFont m_fontDetail;
// 瀵硅瘽妗嗘暟鎹�
@@ -38,4 +41,5 @@
afx_msg void OnDestroy();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
+ afx_msg void OnBnClickedAbortTask();
};
diff --git a/SourceCode/Bond/Servo/JobSlotGrid.cpp b/SourceCode/Bond/Servo/JobSlotGrid.cpp
index cf7df72..12a4c2f 100644
--- a/SourceCode/Bond/Servo/JobSlotGrid.cpp
+++ b/SourceCode/Bond/Servo/JobSlotGrid.cpp
@@ -10,6 +10,10 @@
BEGIN_MESSAGE_MAP(CJobSlotGrid, CWnd)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
+ ON_WM_MOUSEMOVE()
+ ON_WM_MOUSELEAVE()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
CJobSlotGrid::CJobSlotGrid() {
@@ -48,6 +52,7 @@
m_nRows = nRows;
m_nCols = nCols;
m_vSlotStatus.assign(nRows, std::vector<bool>(nCols, false));
+ m_vSlotClickable.assign(nRows, std::vector<bool>(nCols, false));
// 鍒濆鍖栨枃鏈暟缁�
m_vSlotText.assign(nRows, std::vector<CString>(nCols));
@@ -130,8 +135,88 @@
Invalidate();
}
+void CJobSlotGrid::SetSlotClickable(int nRow, int nCol, bool bClickable)
+{
+ if (nRow >= 0 && nRow < m_nRows && nCol >= 0 && nCol < m_nCols) {
+ m_vSlotClickable[nRow][nCol] = bClickable;
+ }
+}
+
+bool CJobSlotGrid::IsSlotClickable(int nRow, int nCol) const
+{
+ if (nRow >= 0 && nRow < m_nRows && nCol >= 0 && nCol < m_nCols) {
+ return m_vSlotClickable[nRow][nCol];
+ }
+ return false;
+}
+
+void CJobSlotGrid::SetSlotClickCallback(SlotClickCallback fnCallback)
+{
+ m_fnSlotClickCallback = fnCallback;
+}
+
BOOL CJobSlotGrid::OnEraseBkgnd(CDC* pDC) {
return TRUE;
+}
+
+void CJobSlotGrid::OnMouseMove(UINT nFlags, CPoint point)
+{
+ TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd };
+ ::TrackMouseEvent(&tme);
+
+ CRect rect;
+ GetClientRect(&rect);
+ int nCellWidth = rect.Width() / m_nCols;
+ int nCellHeight = rect.Height() / m_nRows;
+
+ int nCol = point.x / nCellWidth;
+ int nRow = point.y / nCellHeight;
+
+ if (nRow != m_ptHover.y || nCol != m_ptHover.x) {
+ m_ptHover = CPoint(nCol, nRow);
+ Invalidate();
+ }
+
+ CWnd::OnMouseMove(nFlags, point);
+}
+
+void CJobSlotGrid::OnMouseLeave()
+{
+ m_ptHover = CPoint(-1, -1);
+ Invalidate();
+
+ CWnd::OnMouseLeave();
+}
+
+void CJobSlotGrid::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ m_bLButtonDown = true;
+ Invalidate();
+
+ CWnd::OnLButtonDown(nFlags, point);
+}
+
+void CJobSlotGrid::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ m_bLButtonDown = false;
+ Invalidate();
+
+ // 淇濇寔鍘熸湁閫昏緫涓嶅彉
+ CRect rect;
+ GetClientRect(&rect);
+ int nCellWidth = rect.Width() / m_nCols;
+ int nCellHeight = rect.Height() / m_nRows;
+
+ int nCol = point.x / nCellWidth;
+ int nRow = point.y / nCellHeight;
+
+ if (IsSlotClickable(nRow, nCol)) {
+ if (m_fnSlotClickCallback) {
+ m_fnSlotClickCallback(nRow, nCol);
+ }
+ }
+
+ CWnd::OnLButtonUp(nFlags, point);
}
void CJobSlotGrid::OnPaint() {
@@ -152,14 +237,30 @@
for (int j = 0; j < m_nCols; ++j) {
CRect cellRect(j * nCellWidth, i * nCellHeight, (j + 1) * nCellWidth, (i + 1) * nCellHeight);
- // 鑳屾櫙
- CBrush* pBrush = m_vSlotStatus[i][j] ? &m_brushHasJob : &m_brushNoJob;
- pDC->FillRect(&cellRect, pBrush);
+ // 鍒ゆ柇鐘舵�侊細鎮仠 / 鎸変笅
+ bool bIsHover = (m_ptHover.x == j && m_ptHover.y == i);
+ bool bIsClicking = bIsHover && m_bLButtonDown;
+
+ // 閫夋嫨棰滆壊
+ COLORREF fillColor;
+ if (bIsClicking) {
+ fillColor = RGB(0, 120, 215); // 榧犳爣鎸変笅鑹�
+ }
+ else if (bIsHover) {
+ fillColor = RGB(200, 230, 255); // 鎮仠楂樹寒
+ }
+ else {
+ fillColor = m_vSlotStatus[i][j] ? m_colorHasJob : m_colorNoJob;
+ }
+
+ // 鐢昏儗鏅�
+ CBrush brush(fillColor);
+ pDC->FillRect(&cellRect, &brush);
// 杈规
pDC->DrawEdge(&cellRect, EDGE_SUNKEN, BF_RECT);
- // 鏂囧瓧锛堝眳涓級
+ // 鏂囨湰
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0, 0, 0));
pDC->DrawText(m_vSlotText[i][j], &cellRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
@@ -167,4 +268,4 @@
}
pDC->SelectObject(pOldFont);
-}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/JobSlotGrid.h b/SourceCode/Bond/Servo/JobSlotGrid.h
index f904aea..c00dea9 100644
--- a/SourceCode/Bond/Servo/JobSlotGrid.h
+++ b/SourceCode/Bond/Servo/JobSlotGrid.h
@@ -1,6 +1,9 @@
#pragma once
#include <afxwin.h>
#include <vector>
+#include <functional>
+
+using SlotClickCallback = std::function<void(int nRow, int nCol)>;
class CJobSlotGrid : public CWnd
{
@@ -16,15 +19,24 @@
void SetSlotText(int nRow, int nCol, const CString& strText);
void SetTextFont(const CString& strFontName, int nPointSize);
void ClearAll();
+ void SetSlotClickable(int nRow, int nCol, bool bClickable);
+ bool IsSlotClickable(int nRow, int nCol) const;
+ void SetSlotClickCallback(SlotClickCallback fnCallback);
protected:
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg void OnMouseLeave();
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
private:
int m_nRows;
int m_nCols;
+ bool m_bLButtonDown = false; // 鼠标是否按下
+ CPoint m_ptHover{ -1, -1 }; // 当前悬停的 cell 索引(row, col)
CFont m_fontText;
COLORREF m_colorHasJob;
COLORREF m_colorNoJob;
@@ -32,6 +44,8 @@
CBrush m_brushNoJob;
std::vector<std::vector<bool>> m_vSlotStatus;
std::vector<std::vector<CString>> m_vSlotText;
+ std::vector<std::vector<bool>> m_vSlotClickable;
+ SlotClickCallback m_fnSlotClickCallback;
void DrawGrid(CDC* pDC);
};
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 8baf4d6..1827348 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
Binary files differ
--
Gitblit v1.9.3