From 0fb528df2c1f05ef7d52827432bd934ce6f9d8cd Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期五, 12 九月 2025 09:46:59 +0800
Subject: [PATCH] Merge branch 'clh' into liuyang
---
SourceCode/Bond/Servo/CExpandableListCtrl.h | 19 ++
SourceCode/Bond/Servo/CPageGlassList.h | 1
SourceCode/Bond/Servo/CEquipment.cpp | 42 +++-
SourceCode/Bond/Servo/CServoUtilsTool.cpp | 4
SourceCode/Bond/Servo/CExpandableListCtrl.cpp | 63 ++++++
SourceCode/Bond/Servo/CMaster.cpp | 1
SourceCode/Bond/Servo/Model.cpp | 4
SourceCode/Bond/Servo/CPageGlassList.cpp | 349 ++++++++++++++++++++++++--------------
8 files changed, 336 insertions(+), 147 deletions(-)
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index f6858dd..f89dcf9 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -5,6 +5,7 @@
#include "CArm.h"
#include "CGlassPool.h"
#include "Servo.h"
+#include "GlassJson.h"
namespace SERVO {
@@ -335,11 +336,16 @@
for (int i = 0; i < SLOT_MAX; i++) {
m_slot[i].serialize(ar);
CGlass* pGlass = (CGlass *)m_slot[i].getContext();
- if (pGlass != nullptr) {
- pGlass->serialize(ar);
+ if (pGlass != nullptr) {
+ const std::string pretty = GlassJson::ToPrettyString(*pGlass);
+ CString strPretty = CString(pretty.c_str());
+ ar << strPretty;
+
CGlass* pBuddy = pGlass->getBuddy();
if (pBuddy != nullptr) {
- pBuddy->serialize(ar);
+ const std::string prettyBuddy = GlassJson::ToPrettyString(*pBuddy);
+ CString strPrettyBuddy = CString(prettyBuddy.c_str());
+ ar << strPrettyBuddy;
}
}
}
@@ -349,17 +355,29 @@
for (int i = 0; i < SLOT_MAX; i++) {
m_slot[i].serialize(ar);
if (m_slot[i].getTempContext() != nullptr) {
- CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
- pGlass->serialize(ar);
- m_slot[i].setContext(pGlass);
- if (pGlass->getBuddy() != nullptr) {
- CGlass* pBuddy = theApp.m_model.m_glassPool.allocaGlass();
- pBuddy->serialize(ar);
- pGlass->forceSetBuddy(pBuddy);
+ CString strPretty;
+ std::string pretty;
+ ar >> strPretty;
+ pretty = (LPTSTR)(LPCTSTR)strPretty;
+ if (!pretty.empty()) {
+ CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
+ GlassJson::FromString(pretty, *pGlass);
+ m_slot[i].setContext(pGlass);
+
+ if (!pGlass->getBuddyId().empty()) {
+ CGlass* pBuddy = theApp.m_model.m_glassPool.allocaGlass();
+ CString strPrettyBuddy;
+ std::string prettyBuddy;
+ ar >> strPrettyBuddy;
+ prettyBuddy = (LPTSTR)(LPCTSTR)strPrettyBuddy;
+ GlassJson::FromString(prettyBuddy, *pBuddy);
+ pGlass->forceSetBuddy(pBuddy);
+ }
}
+
}
}
-
+
// 梳理各玻璃之间的绑定关系
/*
Lock();
@@ -1568,7 +1586,9 @@
// 关联的Glass也要更新
CGlass* pBuddy = pGlass->getBuddy();
+ LOGI("<Equipment-%s>decodeProcessDataReport pBuddy=%x %s", getName().c_str(), pBuddy, pGlass->getID().c_str());
if (pBuddy != nullptr) {
+ LOGI("<Equipment-%s>decodeProcessDataReport addParams pBuddy=%x %s", getName().c_str(), pBuddy, pGlass->getID().c_str());
pBuddy->addParams(params);
}
diff --git a/SourceCode/Bond/Servo/CExpandableListCtrl.cpp b/SourceCode/Bond/Servo/CExpandableListCtrl.cpp
index 9022dce..ef21ed0 100644
--- a/SourceCode/Bond/Servo/CExpandableListCtrl.cpp
+++ b/SourceCode/Bond/Servo/CExpandableListCtrl.cpp
@@ -3,7 +3,11 @@
IMPLEMENT_DYNAMIC(CExpandableListCtrl, CListCtrl)
-CExpandableListCtrl::CExpandableListCtrl() {}
+CExpandableListCtrl::CExpandableListCtrl()
+{
+ m_popupCols = { };
+}
+
CExpandableListCtrl::~CExpandableListCtrl() {}
BEGIN_MESSAGE_MAP(CExpandableListCtrl, CListCtrl)
@@ -249,6 +253,38 @@
}
}
}
+
+ // 鈥斺�� 鑻ョ偣鍑诲埌闇�瑕佲�滃叏鏂囨樉绀衡�濈殑鍒楋紝鍒欏悜鐖剁獥鍙e彂閫佽嚜瀹氫箟閫氱煡 鈥斺�� //
+ if (!m_popupCols.empty()) {
+ LPNMITEMACTIVATE pia = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
+
+ // 鐢� SubItemHitTest 鏇寸簿鍑嗘嬁鍒板垪
+ LVHITTESTINFO ht{};
+ ht.pt = pia->ptAction;
+ int hit = SubItemHitTest(&ht);
+ if (hit >= 0 && ht.iItem >= 0 && ht.iSubItem >= 0) {
+ const int row = ht.iItem;
+ const int col = ht.iSubItem;
+
+ if (m_popupCols.count(col)) {
+ CString full = GetItemText(row, col);
+ if (!full.IsEmpty() && _IsCellTruncated(row, col, full)) {
+ NMC_ELC_SHOWFULLTEXT nm{};
+ nm.hdr.hwndFrom = m_hWnd;
+ nm.hdr.idFrom = GetDlgCtrlID();
+ nm.hdr.code = ELCN_SHOWFULLTEXT;
+ nm.iItem = row;
+ nm.iSubItem = col;
+ nm.text = full;
+
+ if (CWnd* pParent = GetParent()) {
+ pParent->SendMessage(WM_NOTIFY, nm.hdr.idFrom, reinterpret_cast<LPARAM>(&nm));
+ }
+ }
+ }
+ }
+ }
+
*pResult = 0;
}
@@ -441,4 +477,29 @@
Invalidate();
}
+void CExpandableListCtrl::SetPopupFullTextColumns(const std::vector<int>& cols)
+{
+ m_popupCols.clear();
+ for (int c : cols) m_popupCols.insert(c);
+}
+
+bool CExpandableListCtrl::_IsCellTruncated(int row, int col, const CString& text) const
+{
+ if (text.IsEmpty()) return false;
+
+ // 鍗曞厓鏍兼樉绀哄尯鍩熷搴�
+ CRect rcCell;
+ if (!const_cast<CExpandableListCtrl*>(this)->GetSubItemRect(row, col, LVIR_BOUNDS, rcCell))
+ return false;
+
+ // 鐢ㄦ帶浠跺瓧浣撴祴閲忔枃鏈儚绱犲
+ CClientDC dc(const_cast<CExpandableListCtrl*>(this));
+ CFont* pOld = dc.SelectObject(const_cast<CExpandableListCtrl*>(this)->GetFont());
+ CSize sz = dc.GetTextExtent(text);
+ dc.SelectObject(pOld);
+
+ const int kPadding = 8; // 棰勭暀涓�鐐硅竟璺�/鐪佺暐鍙蜂綑閲�
+ return sz.cx > (rcCell.Width() - kPadding);
+}
+
diff --git a/SourceCode/Bond/Servo/CExpandableListCtrl.h b/SourceCode/Bond/Servo/CExpandableListCtrl.h
index 95c013a..faf0692 100644
--- a/SourceCode/Bond/Servo/CExpandableListCtrl.h
+++ b/SourceCode/Bond/Servo/CExpandableListCtrl.h
@@ -2,6 +2,19 @@
#include <vector>
#include <memory>
#include <unordered_map>
+#include <set>
+
+
+// ===== 自定义通知:点击需要弹出全文的单元格 =====
+#ifndef ELCN_SHOWFULLTEXT
+#define ELCN_SHOWFULLTEXT (NM_FIRST - 201)
+struct NMC_ELC_SHOWFULLTEXT {
+ NMHDR hdr; // hwndFrom / idFrom / code = ELCN_SHOWFULLTEXT
+ int iItem; // 行
+ int iSubItem; // 列(0-based)
+ CString text; // 完整文本
+};
+#endif
class CExpandableListCtrl : public CListCtrl
{
@@ -46,6 +59,12 @@
// 清除树
void ClearTree();
+ // 设置哪些列需要“被截断则通知父窗口显示全文”(0-based列号)
+ void SetPopupFullTextColumns(const std::vector<int>& cols);
+
+ std::set<int> m_popupCols; // 需要通知的列集合
+ bool _IsCellTruncated(int row, int col, const CString& text) const;
+
protected:
virtual void PreSubclassWindow();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 9c22433..3b2d01f 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -774,6 +774,7 @@
continue;
}
+ pGlass->start();
pEFEM->setContext(m_pActiveRobotTask->getContext());
goto PORT_GET;
}
diff --git a/SourceCode/Bond/Servo/CPageGlassList.cpp b/SourceCode/Bond/Servo/CPageGlassList.cpp
index 98daad4..fdbdcd4 100644
--- a/SourceCode/Bond/Servo/CPageGlassList.cpp
+++ b/SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -98,7 +98,7 @@
}
// ====== 寮�鍏筹細1=鍚敤鍋囨暟鎹紙鍙浛鎹� DB 鏌ヨ锛夛紱0=鐢ㄧ湡瀹� DB ======
-#define USE_FAKE_DB_DEMO 1
+#define USE_FAKE_DB_DEMO 0
#if USE_FAKE_DB_DEMO
#include <ctime>
@@ -392,6 +392,7 @@
ON_BN_CLICKED(IDC_BUTTON_EXPORT, &CPageGlassList::OnBnClickedButtonExport)
ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CPageGlassList::OnBnClickedButtonPrevPage)
ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CPageGlassList::OnBnClickedButtonNextPage)
+ ON_NOTIFY(ELCN_SHOWFULLTEXT, IDC_LIST_ALARM, &CPageGlassList::OnShowFullText)
END_MESSAGE_MAP()
// ===== 绉佹湁灏忓伐鍏� =====
@@ -519,10 +520,10 @@
{
m_rebuilding = true;
- // 鏀惧湪浠讳綍娓呯┖/閲嶅缓鍔ㄤ綔涔嬪墠锛�
+ // 鏀惧湪浠讳綍娓呯┖/閲嶅缓鍔ㄤ綔涔嬪墠锛氳褰曞睍寮�鐨勭埗鑺傜偣 key锛圕lassID锛�
auto expandedKeys = SnapshotExpandedKeys(m_listCtrl);
- // 鈥斺�� 鍙屼繚闄╋細鍏堟竻鎺夊彲瑙侀」锛屽啀娓呮爲缁撴瀯 鈥斺��
+ // 鈥斺�� 鍙屼繚闄╋細鍏堟竻鎺夊彲瑙侀」锛屽啀娓呮爲缁撴瀯 鈥斺��
m_listCtrl.SetRedraw(FALSE);
m_listCtrl.DeleteAllItems();
m_listCtrl.SetRedraw(TRUE);
@@ -531,7 +532,7 @@
m_listCtrl.ClearTree();
const int colCount = m_listCtrl.GetHeaderCtrl() ? m_listCtrl.GetHeaderCtrl()->GetItemCount() : 0;
- if (colCount <= 0) return;
+ if (colCount <= 0) { m_rebuilding = false; return; }
// ==================== 1) WIP锛氫粎绗� 1 椤垫瀯寤猴紝涓旀斁鍦ㄦ渶椤堕儴 ====================
if (m_nCurPage == 1) {
@@ -550,9 +551,11 @@
SERVO::CGlass* b = g->getBuddy();
if (b) {
+ // 鎸変綘鐨勭害瀹氾細g 鏄埗锛宐uddy 鏄瓙
SERVO::CGlass* parent = g;
SERVO::CGlass* child = b;
+ // parent
std::vector<CString> pcols(colCount);
pcols[1] = _T("");
pcols[2] = std::to_string(parent->getCassetteSequenceNo()).c_str();
@@ -571,6 +574,7 @@
MaybeRestoreExpandByKey(nParent, expandedKeys);
m_listCtrl.SetNodeColor(nParent, kWipText, kWipParentBk); // 鐖讹細鍩虹缁�
+ // child
std::vector<CString> ccols(colCount);
ccols[1] = _T("");
ccols[2] = std::to_string(child->getCassetteSequenceNo()).c_str();
@@ -614,7 +618,7 @@
for (auto* item : tempGlasses) item->release();
}
- // ==================== 2) DB 褰撳墠椤碉紙鏃犺绗嚑椤甸兘鏋勫缓锛涙帓鍦� WIP 涔嬪悗锛� ====================
+ // ==================== 2) DB 褰撳墠椤碉紙涓ら樁娈垫瀯寤猴紝澶勭悊鍗曞悜 buddy锛� ====================
#if USE_FAKE_DB_DEMO
auto page = _make_page_fake(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1));
#else
@@ -622,99 +626,128 @@
auto page = db.queryPaged(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1));
#endif
+ // 寤虹储寮曪細classId -> index
std::unordered_map<std::string, size_t> idxById;
idxById.reserve(page.items.size());
- for (size_t i = 0; i < page.items.size(); ++i) idxById[page.items[i].classId] = i;
+ for (size_t i = 0; i < page.items.size(); ++i) {
+ idxById[page.items[i].classId] = i;
+ }
- std::unordered_set<std::string> usedDb;
+ // 宸叉秷璐癸紙宸叉彃鍏ヤ负鐖舵垨瀛愶級
+ std::unordered_set<std::string> consumed;
int zebra = 0;
+ auto zebraBk = [&](int z) -> COLORREF {
+ return (z % 2 == 0) ? RGB(255, 255, 255) : RGB(235, 235, 235);
+ };
+ // -------- Phase 1: 鍏堝鐞嗏�滄湁 buddyId 鐨勮褰曗�濓紙鑳介厤灏遍厤锛涘崟鍚戜篃閰嶏級 ----------
for (size_t i = 0; i < page.items.size(); ++i) {
const auto& r = page.items[i];
- if (usedDb.count(r.classId)) continue;
+ if (consumed.count(r.classId)) continue;
+ if (r.buddyId.empty()) continue;
- COLORREF bk = (zebra % 2 == 0) ? RGB(255, 255, 255) : RGB(235, 235, 235);
- bool paired = false;
+ COLORREF bk = zebraBk(zebra);
- if (!r.buddyId.empty()) {
- auto it = idxById.find(r.buddyId);
- if (it != idxById.end()) {
- const auto& br = page.items[it->second];
- if (!usedDb.count(br.classId)) {
- bool rIsParent = (r.classId <= br.classId);
- const auto& parentRec = rIsParent ? r : br;
- const auto& childRec = rIsParent ? br : r;
+ auto it = idxById.find(r.buddyId);
+ if (it != idxById.end()) {
+ const auto& br = page.items[it->second];
+ if (!consumed.count(br.classId)) {
+ // 鈥斺�� 浠モ�滄湁 buddyId 鐨勮繖鏉� r鈥濅负鐖讹紝buddy 浣滀负瀛愶紙鍗曞悜涔熻兘閰嶏級鈥斺��
+ std::vector<CString> pcols(colCount);
+ pcols[1] = std::to_string(r.id).c_str();
+ pcols[2] = std::to_string(r.cassetteSeqNo).c_str();
+ pcols[3] = std::to_string(r.jobSeqNo).c_str();
+ pcols[4] = r.classId.c_str();
+ pcols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
+ pcols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
+ pcols[7] = r.tStart.c_str();
+ pcols[8] = r.tEnd.c_str();
+ pcols[9] = r.buddyId.c_str();
+ pcols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
+ pcols[11] = r.path.c_str();
+ pcols[12] = r.params.c_str();
- std::vector<CString> pcols(colCount);
- pcols[1] = std::to_string(parentRec.id).c_str(); pcols[2] = std::to_string(parentRec.cassetteSeqNo).c_str();
- pcols[3] = std::to_string(parentRec.jobSeqNo).c_str(); pcols[4] = parentRec.classId.c_str();
- pcols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)parentRec.materialType).c_str();
- pcols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)parentRec.state).c_str();
- pcols[7] = parentRec.tStart.c_str(); pcols[8] = parentRec.tEnd.c_str(); pcols[9] = parentRec.buddyId.c_str();
- pcols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)parentRec.aoiResult).c_str();
- pcols[11] = parentRec.path.c_str(); pcols[12] = parentRec.params.c_str();
+ auto* nParent = m_listCtrl.InsertRoot(pcols);
+ MaybeRestoreExpandByKey(nParent, expandedKeys);
+ m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
- auto* nParent = m_listCtrl.InsertRoot(pcols);
- MaybeRestoreExpandByKey(nParent, expandedKeys);
- m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
+ std::vector<CString> ccols(colCount);
+ ccols[1] = std::to_string(br.id).c_str();
+ ccols[2] = std::to_string(br.cassetteSeqNo).c_str();
+ ccols[3] = std::to_string(br.jobSeqNo).c_str();
+ ccols[4] = br.classId.c_str();
+ ccols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)br.materialType).c_str();
+ ccols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)br.state).c_str();
+ ccols[7] = br.tStart.c_str();
+ ccols[8] = br.tEnd.c_str();
+ ccols[9] = br.buddyId.c_str();
+ ccols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)br.aoiResult).c_str();
+ ccols[11] = br.path.c_str();
+ ccols[12] = br.params.c_str();
- std::vector<CString> ccols(colCount);
- ccols[1] = std::to_string(childRec.id).c_str(); ccols[2] = std::to_string(childRec.cassetteSeqNo).c_str();
- ccols[3] = std::to_string(childRec.jobSeqNo).c_str(); ccols[4] = childRec.classId.c_str();
- ccols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)childRec.materialType).c_str();
- ccols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)childRec.state).c_str();
- ccols[7] = childRec.tStart.c_str(); ccols[8] = childRec.tEnd.c_str(); ccols[9] = childRec.buddyId.c_str();
- ccols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)childRec.aoiResult).c_str();
- ccols[11] = childRec.path.c_str(); ccols[12] = childRec.params.c_str();
+ auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
+ m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
- auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
- m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
-
- usedDb.insert(parentRec.classId);
- usedDb.insert(childRec.classId);
- paired = true;
- }
+ consumed.insert(r.classId);
+ consumed.insert(br.classId);
+ ++zebra;
+ continue;
}
}
- if (!paired && !r.buddyId.empty()) {
- std::vector<CString> pcols(colCount);
- pcols[1] = std::to_string(r.id).c_str(); pcols[2] = std::to_string(r.cassetteSeqNo).c_str();
- pcols[3] = std::to_string(r.jobSeqNo).c_str(); pcols[4] = r.classId.c_str();
- pcols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
- pcols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
- pcols[7] = r.tStart.c_str(); pcols[8] = r.tEnd.c_str(); pcols[9] = r.buddyId.c_str();
- pcols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
- pcols[11] = r.path.c_str(); pcols[12] = r.params.c_str();
+ // 鍚岄〉娌℃壘鍒� buddy锛堟垨宸茶娑堣垂锛夆啋 鎻掑崰浣嶅瓙琛�
+ std::vector<CString> pcols(colCount);
+ pcols[1] = std::to_string(r.id).c_str();
+ pcols[2] = std::to_string(r.cassetteSeqNo).c_str();
+ pcols[3] = std::to_string(r.jobSeqNo).c_str();
+ pcols[4] = r.classId.c_str();
+ pcols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
+ pcols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
+ pcols[7] = r.tStart.c_str();
+ pcols[8] = r.tEnd.c_str();
+ pcols[9] = r.buddyId.c_str();
+ pcols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
+ pcols[11] = r.path.c_str();
+ pcols[12] = r.params.c_str();
- auto* nParent = m_listCtrl.InsertRoot(pcols);
- MaybeRestoreExpandByKey(nParent, expandedKeys);
- m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
+ auto* nParent = m_listCtrl.InsertRoot(pcols);
+ MaybeRestoreExpandByKey(nParent, expandedKeys);
+ m_listCtrl.SetNodeColor(nParent, RGB(0, 0, 0), bk);
- std::vector<CString> ccols(colCount);
- ccols[4] = r.buddyId.c_str(); // 鍗犱綅瀛愯锛氭樉绀� buddy 鐨� classId
- auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
- m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
+ std::vector<CString> ccols(colCount); // 鍗犱綅鍙啓 ClassID
+ ccols[4] = r.buddyId.c_str();
+ auto* nChild = m_listCtrl.InsertChild(nParent, ccols);
+ m_listCtrl.SetNodeColor(nChild, RGB(0, 0, 0), bk);
- usedDb.insert(r.classId);
- paired = true;
- }
+ consumed.insert(r.classId);
+ ++zebra;
+ }
- if (!paired) {
- std::vector<CString> cols(colCount);
- cols[1] = std::to_string(r.id).c_str(); cols[2] = std::to_string(r.cassetteSeqNo).c_str();
- cols[3] = std::to_string(r.jobSeqNo).c_str(); cols[4] = r.classId.c_str();
- cols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
- cols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
- cols[7] = r.tStart.c_str(); cols[8] = r.tEnd.c_str(); cols[9] = r.buddyId.c_str();
- cols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
- cols[11] = r.path.c_str(); cols[12] = r.params.c_str();
+ // -------- Phase 2: 鍓╀綑鏈秷璐圭殑锛屼綔涓衡�滃崟鏉℃牴琛屸�� ----------
+ for (size_t i = 0; i < page.items.size(); ++i) {
+ const auto& r = page.items[i];
+ if (consumed.count(r.classId)) continue;
- auto* n = m_listCtrl.InsertRoot(cols);
- m_listCtrl.SetNodeColor(n, RGB(0, 0, 0), bk);
- usedDb.insert(r.classId);
- }
+ COLORREF bk = zebraBk(zebra);
+ std::vector<CString> cols(colCount);
+ cols[1] = std::to_string(r.id).c_str();
+ cols[2] = std::to_string(r.cassetteSeqNo).c_str();
+ cols[3] = std::to_string(r.jobSeqNo).c_str();
+ cols[4] = r.classId.c_str();
+ cols[5] = SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str();
+ cols[6] = SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str();
+ cols[7] = r.tStart.c_str();
+ cols[8] = r.tEnd.c_str();
+ cols[9] = r.buddyId.c_str();
+ cols[10] = SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str();
+ cols[11] = r.path.c_str();
+ cols[12] = r.params.c_str();
+
+ auto* n = m_listCtrl.InsertRoot(cols);
+ m_listCtrl.SetNodeColor(n, RGB(0, 0, 0), bk);
+
+ consumed.insert(r.classId);
++zebra;
}
@@ -726,6 +759,7 @@
m_rebuilding = false;
}
+
void CPageGlassList::UpdatePageControls()
{
@@ -789,6 +823,7 @@
}
// 浜屾鍏滃簳锛岄槻姝� ini 鍐欒繘浜� 0
if (m_listCtrl.GetColumnWidth(0) < 16) m_listCtrl.SetColumnWidth(0, 24);
+ m_listCtrl.SetPopupFullTextColumns({ 11, 12 });
Resize();
OnBnClickedButtonSearch(); // 瑙﹀彂涓�娆℃煡璇笌棣栧睆濉厖
@@ -961,19 +996,32 @@
}
}
+void CPageGlassList::OnShowFullText(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ auto* p = reinterpret_cast<NMC_ELC_SHOWFULLTEXT*>(pNMHDR);
+
+ // 杩欓噷鏆傛椂鐢ㄦ秷鎭鏄剧ず锛涘悗缁彲鎹㈡垚浣犵殑璇︽儏椤�
+ CString strNewMsg = p->text;
+ strNewMsg.Replace(_T(","), _T("\n"));
+ MessageBox(strNewMsg, _T("璇︾粏淇℃伅"), MB_OK | MB_ICONINFORMATION);
+ *pResult = 0;
+}
+
void CPageGlassList::UpdateWipData()
{
// 鍙湪绗� 1 椤靛埛鏂� WIP锛涘叾瀹冮〉涓嶅姩
if (m_nCurPage != 1) return;
+ // 鑻ュ垰濂藉湪 UpdatePageData() 閲嶅缓鏈熼棿锛岃烦杩囪繖杞閲忥紝閬垮厤浜掔浉骞叉壈
+ if (m_rebuilding) return;
const int colCount = m_listCtrl.GetHeaderCtrl() ? m_listCtrl.GetHeaderCtrl()->GetItemCount() : 0;
if (colCount <= 0) return;
// 1) 鏀堕泦褰撳墠鍙閲岀殑鈥淲IP 琛屸�濓紙绗�1鍒� id 涓虹┖锛�
- // a) wipRowById锛歝lassId -> (row, node*)锛屾敹闆嗏�滄牴+瀛愨�濈殑鍏ㄩ儴锛屼究浜庡垽鏂�渂uddy 鏄惁宸插湪鍙琛ㄤ腑鈥�
- // b) wipRootById锛歝lassId -> node*锛屼粎鏀堕泦鈥滄牴鑺傜偣鈥濓紝渚夸簬鍙鏍硅妭鐐硅ˉ瀛愰」
+ // a) wipRowById锛歝lassId -> (row, node*)锛屾敹闆嗘牴+瀛愶紝渚夸簬鍒ゆ柇鈥渂uddy 鏄惁宸插湪鍙琛ㄤ腑鈥�
+ // b) wipRootById锛歝lassId -> node*锛屼粎鏀堕泦鏍硅妭鐐癸紝渚夸簬鍙鈥滄牴鈥濊ˉ瀛愰」
std::unordered_map<std::string, std::pair<int, CExpandableListCtrl::Node*>> wipRowById;
- std::unordered_map<std::string, CExpandableListCtrl::Node*> wipRootById;
+ std::unordered_map<std::string, CExpandableListCtrl::Node*> wipRootById;
for (int row = 0; row < m_listCtrl.GetItemCount(); ++row) {
CString idDb = m_listCtrl.GetItemText(row, 1); // 绗�1鍒楁槸 DB id
if (!idDb.IsEmpty()) continue; // 鏈� id 鐨勬槸 DB 琛岋紝璺宠繃
@@ -995,26 +1043,7 @@
std::vector<SERVO::CGlass*> wipGlasses;
theApp.m_model.m_master.getWipGlasses(wipGlasses);
std::vector<SERVO::CGlass*> tempRetain = wipGlasses; // 绋嶅悗缁熶竴 release
- /*
- static int i = 0;
- i++;
- if (i == 8) {
- for (auto item : wipGlasses) {
- if (item->getBuddy() != nullptr) {
- item->setInspResult(EQ_ID_MEASUREMENT, 0, SERVO::InspResult::Fail);
- item->getBuddy()->setID("11111");
- }
- }
- }
- if (i == 16) {
- for (auto item : wipGlasses) {
- if (item->getBuddy() != nullptr) {
- item->setInspResult(EQ_ID_MEASUREMENT, 0, SERVO::InspResult::Pass);
- item->getBuddy()->setID("22222");
- }
- }
- }
- */
+
auto makeColsFromWip = [&](SERVO::CGlass* g) {
std::vector<CString> cols(colCount);
cols[1] = _T(""); // WIP 娌� DB id
@@ -1032,21 +1061,47 @@
return cols;
};
- bool needRebuildChildren = false; // 鏈鏄惁鏂板浜嗗瓙鑺傜偣锛堢粨鏋勫彉鍖栵級
- bool needRebuildAllForNewRoot = false;// 鏈鏄惁鍙戠幇浜嗏�滄柊澧炴牴鑺傜偣鈥濈殑闇�姹傦紙涓轰繚璇� WIP 鍦ㄩ《閮級
- std::vector<int> rowsToRedraw; // 浠呮枃鏈彉鍖栫殑琛�
+ // 2.1 鏋勫缓鈥滄渶鏂� WIP 閿泦鈥濓紙鍚� buddy锛屼笖鍛戒腑杩囨护锛夛紝鐢ㄤ簬妫�娴嬧�滅己澶�/鍒犻櫎鈥�
+ std::unordered_set<std::string> newWipKeys;
+ for (auto* g : wipGlasses) {
+ if (!GlassMatchesFilters(*g, m_filters)) continue;
+#ifdef _UNICODE
+ newWipKeys.insert(CT2A(CString(g->getID().c_str())));
+#else
+ newWipKeys.insert(g->getID());
+#endif
+ if (auto* b = g->getBuddy()) {
+ if (GlassMatchesFilters(*b, m_filters)) {
+#ifdef _UNICODE
+ newWipKeys.insert(CT2A(CString(b->getID().c_str())));
+#else
+ newWipKeys.insert(b->getID());
+#endif
+ }
+ }
+ }
+
+ bool needRebuildRemoval = false; // WIP 鍙樺皯/娓呯┖锛氶渶瑕佹暣椤甸噸寤�
+ bool needRebuildChildren = false; // 缁撴瀯鍙樺寲锛氭柊澧炲瓙
+ bool needRebuildAllForNewRoot = false; // 鏂板鏍癸紙淇濊瘉 WIP 浠嶅湪椤堕儴锛�
+ std::vector<int> rowsToRedraw; // 浠呮枃鏈彉鍖�
+
+ // 鍙闆嗕腑鏈変絾鏂版暟鎹噷娌℃湁 -> 瑙﹀彂鈥滃垹闄�/鍑忓皯鈥濈殑鏁撮〉閲嶅缓
+ for (const auto& kv : wipRowById) {
+ if (newWipKeys.find(kv.first) == newWipKeys.end()) { needRebuildRemoval = true; break; }
+ }
// UI 鐘舵�侊紙褰撻渶瑕侀噸寤烘椂浣跨敤锛�
std::vector<CExpandableListCtrl::Node*> savedSel;
CExpandableListCtrl::Node* savedTop = nullptr;
// 3) 閫愪釜澶勭悊 WIP锛氬凡瀛樺湪 -> 灏卞湴鏇存柊锛涘繀瑕佹椂鈥滃彧瀵规牴琛ュ瓙椤光��
- // 涓嶅瓨鍦� -> 瑙﹀彂鈥滃叏閲忛噸寤衡�濓紝浠ヤ繚璇佹柊 WIP 鏍硅鍑虹幇鍦ㄥ垪琛ㄩ《閮�
+ // 涓嶅瓨鍦� -> 浼樺厛鎸傚埌 buddy 瀹瑰櫒锛涘惁鍒欒Е鍙戞暣椤甸噸寤猴紙鏂版牴淇濇寔椤堕儴锛�
for (auto* g : wipGlasses) {
if (!GlassMatchesFilters(*g, m_filters)) continue;
#ifdef _UNICODE
- std::string cid = CT2A(g->getID().c_str());
+ std::string cid = CT2A(CString(g->getID().c_str()));
#else
std::string cid = g->getID();
#endif
@@ -1070,27 +1125,23 @@
// 鈥斺�� 椤哄甫鍒锋柊 buddy 瀛愯锛堝鏋滃畠宸插湪鍙琛ㄩ噷锛夆�斺��
if (SERVO::CGlass* b = g->getBuddy()) {
- CString buddyCidCs = b->getID().c_str();
#ifdef _UNICODE
- std::string bid = CT2A(buddyCidCs);
+ std::string bid = CT2A(CString(b->getID().c_str()));
#else
- std::string bid = buddyCidCs.GetString();
+ std::string bid = b->getID();
#endif
auto itChildAny = wipRowById.find(bid);
if (itChildAny != wipRowById.end()) {
int crow = itChildAny->second.first;
- // 鐢熸垚 buddy 鐨勫垪鏂囨湰骞朵竴娆℃�у啓鍥�
auto bcols = makeColsFromWip(b);
ApplyColsToRow(m_listCtrl, crow, bcols);
rowsToRedraw.push_back(crow);
}
- // 濡傛灉 buddy 琛屽綋鍓嶄笉瀛樺湪锛屽彲淇濈暀浣犲師鏉ョ殑鈥滃彧鍦ㄦ牴涓嬨�佷笖 buddy 涓嶅湪鍙琛ㄦ椂琛ュ瓙椤光�濈殑閫昏緫
}
// 鈥斺�� 鍙鈥滄牴鑺傜偣鈥濊ˉ瀛愰」锛屼笖浠呭綋 buddy 灏氭湭鍑虹幇鍦ㄥ彲瑙佽〃锛屼笖鏍逛笅涔熸病鏈夎 buddy 鈥斺��
SERVO::CGlass* b = g->getBuddy();
if (b) {
- // 褰撳墠鏍瑰鍣紵锛堝瓙鑺傜偣涓嶄綔涓哄鍣級
auto itRoot = wipRootById.find(cid);
if (itRoot != wipRootById.end()) {
CExpandableListCtrl::Node* container = itRoot->second;
@@ -1110,52 +1161,50 @@
bool buddyExistsAnywhere = (wipRowById.find(newBid) != wipRowById.end());
bool hasChildAlready = NodeHasChildWithClassId(container, newBuddyCid);
- // 鈥斺�� 鍏抽敭锛氬叧绯绘槸鍚﹀彂鐢熷彉鍖栵紵锛坥ldChildCid 涓� newBuddyCid 涓嶅悓锛�
+ // 鍏崇郴鏄惁鍙戠敓鍙樺寲锛燂紙oldChildCid 涓� newBuddyCid 涓嶅悓锛屾垨鏈夊瓙浣嗙幇鍦ㄦ病 buddy锛�
bool relationChanged =
- (!oldChildCid.IsEmpty() && newBuddyCid.IsEmpty()) || // 涔嬪墠鏈夊瓙锛岀幇鍦ㄦ病 buddy
- (oldChildCid.IsEmpty() && !newBuddyCid.IsEmpty()) || // 涔嬪墠娌″瓙锛岀幇鍦ㄦ湁 buddy
- (!oldChildCid.IsEmpty() && !newBuddyCid.IsEmpty() && oldChildCid.CompareNoCase(newBuddyCid) != 0); // 鏀� buddy
+ (!oldChildCid.IsEmpty() && newBuddyCid.IsEmpty()) ||
+ (oldChildCid.IsEmpty() && !newBuddyCid.IsEmpty()) ||
+ (!oldChildCid.IsEmpty() && !newBuddyCid.IsEmpty() &&
+ oldChildCid.CompareNoCase(newBuddyCid) != 0);
if (relationChanged) {
- // 鍏崇郴鍙樻洿璧扳�滅粨鏋勯噸寤衡�濓紝閬垮厤閲嶅鎴栧弽鍚戞寕杞�
- needRebuildAllForNewRoot = true;
+ needRebuildAllForNewRoot = true; // 閬垮厤閲嶅鎴栧弽鍚戞寕杞�
}
else {
- // 鍏崇郴鏈彉锛氳嫢 buddy 杩樹笉鍦ㄥ彲瑙佽〃涓斿鍣ㄤ笅涔熸病鏈夛紝鍒欒ˉ瀛�
+ // 鍏崇郴鏈彉锛氳嫢 buddy 涓嶅湪鍙琛ㄤ笖瀹瑰櫒涓嬩篃娌℃湁锛屽垯琛ュ瓙
if (!buddyExistsAnywhere && !hasChildAlready) {
if (!needRebuildChildren) { CaptureUiState(m_listCtrl, savedSel, savedTop); }
needRebuildChildren = true;
auto cols = makeColsFromWip(b);
auto* ch = m_listCtrl.InsertChild(container, cols);
- m_listCtrl.SetNodeColor(ch, kWipText, kWipChildBk); // 瀛愶細鏇存祬
- m_listCtrl.SetNodeColor(container, kWipText, kWipParentBk); // 鐖讹細鍩虹缁匡紙鍏滃簳绾犳锛�
+ m_listCtrl.SetNodeColor(ch, kWipText, kWipChildBk); // 瀛愶細娴呰壊
+ m_listCtrl.SetNodeColor(container, kWipText, kWipParentBk); // 鐖讹細鍩虹缁�
}
- // 鑻ュ凡鏈夊瓙锛氶『甯︽妸瀛愯鏂囨湰鍒锋柊涓�涓嬶紙姣斿 AOI 鏇存柊锛�
+ // 鑻ュ凡鏈夊瓙锛氬悓姝ュ埛鏂板瓙琛屾枃鏈笌棰滆壊
else if (hasChildAlready) {
- // 鎵惧埌瀵瑰簲瀛愬苟鏇存柊鏂囨湰/cols锛岄伩鍏嶅悗缁� Rebuild 鍊掑洖鏃у��
for (auto& ch : container->children) {
if (ch && ch->cols.size() > 4 && ch->cols[4].CompareNoCase(newBuddyCid) == 0) {
auto cols = makeColsFromWip(b);
- ch->cols = cols; // 搴曞眰鏁版嵁
+ ch->cols = cols; // 鏇存柊搴曞眰鏁版嵁
// 鍙琛屽埛鏂�
for (int r = 0; r < m_listCtrl.GetItemCount(); ++r) {
if (m_listCtrl.GetNodeByVisibleIndex(r) == ch.get()) {
- for (int c = 1; c < (int)cols.size(); ++c) {
+ for (int c = 1; c < (int)cols.size(); ++c)
m_listCtrl.SetItemText(r, c, cols[c]);
- m_listCtrl.SetNodeColor(ch.get(), kWipText, kWipChildBk); // 淇濊瘉瀛愯鏄祬鑹�
- m_listCtrl.SetNodeColor(container, kWipText, kWipParentBk); // 鐖朵繚鎸佸熀纭�缁�
- }
rowsToRedraw.push_back(r);
break;
}
}
+ m_listCtrl.SetNodeColor(ch.get(), kWipText, kWipChildBk);
+ m_listCtrl.SetNodeColor(container, kWipText, kWipParentBk);
break;
}
}
}
}
}
- // 褰撳墠鏄�滃瓙鑺傜偣鈥濈殑鎯呭喌锛氫竴寰嬩笉鎸傚瓙锛屼氦缁欓噸寤猴紙鑻ョ埗鍙樻洿锛�
+ // 鑻ュ綋鍓嶆槸鈥滃瓙鑺傜偣鈥濓紝涓嶅湪杩欓噷璋冩暣鐖跺瓙鍏崇郴锛涜鈥滃叧绯诲彉鍖栤�濊蛋鍏ㄩ噺閲嶅缓
}
else {
// 娌℃湁 buddy锛氬鏋滃鍣ㄤ笅鐜板湪鏈夊瓙锛屼篃绠楀叧绯诲彉鍖栵紝瑙﹀彂閲嶅缓
@@ -1168,17 +1217,51 @@
}
}
else {
- // (B) 涓嶅瓨鍦細鏂板鏍硅鈥斺�斾负淇濊瘉鈥淲IP 姘歌繙鍦ㄩ《閮ㄢ�濓紝瑙﹀彂鍏ㄩ噺閲嶅缓
- needRebuildAllForNewRoot = true;
+ // (B) 涓嶅瓨鍦細鏂板
+ // 鍏堝皾璇曗�滄寕鍒� buddy 鐨勫鍣ㄦ牴鈥濅笅闈紱
+ // 鑻� buddy 涓嶅湪褰撳墠鍙琛紝鍒欒Е鍙戝叏閲忛噸寤猴紙淇濊瘉 WIP 椤堕儴锛夈��
+ SERVO::CGlass* b = g->getBuddy();
+ CExpandableListCtrl::Node* container = nullptr;
+
+ if (b) {
+#ifdef _UNICODE
+ std::string bid = CT2A(CString(b->getID().c_str()));
+#else
+ std::string bid = b->getID();
+#endif
+ auto itB = wipRowById.find(bid);
+ if (itB != wipRowById.end()) {
+ CExpandableListCtrl::Node* buddyNode = itB->second.second;
+ container = buddyNode ? (buddyNode->parent ? buddyNode->parent : buddyNode) : nullptr;
+ }
+ }
+
+ if (container) {
+ // buddy 瀹瑰櫒瀛樺湪锛氭妸 g 浣滀负鈥滃瓙琛屸�濇寕涓婂幓锛堥伩鍏嶉噸澶嶏級
+ CString cidCs = g->getID().c_str();
+ if (!NodeHasChildWithClassId(container, cidCs)) {
+ if (!needRebuildChildren) { CaptureUiState(m_listCtrl, savedSel, savedTop); }
+ needRebuildChildren = true;
+
+ auto cols = makeColsFromWip(g);
+ auto* ch = m_listCtrl.InsertChild(container, cols);
+ // 瀛愶細鏇存祬锛涚埗锛氬熀纭�缁匡紙鍏滃簳锛�
+ m_listCtrl.SetNodeColor(ch, kWipText, kWipChildBk);
+ m_listCtrl.SetNodeColor(container, kWipText, kWipParentBk);
+ }
+ }
+ else {
+ // buddy 涓嶅湪鍙琛細涓轰簡淇濇寔鈥淲IP 姘歌繙鍦ㄩ《閮ㄢ�濓紝瑙﹀彂涓�娆″叏閲忛噸寤�
+ needRebuildAllForNewRoot = true;
+ }
}
}
- // 4) 搴旂敤 UI 鏇存柊
- if (needRebuildAllForNewRoot) {
- // 鐢� key锛圕lassID锛変繚瀛樺苟鎭㈠锛岄伩鍏� Node* 澶辨晥
+ // 4) 搴旂敤 UI 鏇存柊 鈥斺�� 鎶娾�滃垹闄�/鍑忓皯鈥濈殑鎯呭喌骞跺叆鍏ㄩ噺閲嶅缓鍒嗘敮
+ if (needRebuildAllForNewRoot || needRebuildRemoval) {
auto selKeys = SnapshotSelectedKeys(m_listCtrl);
auto topKey = SnapshotTopKey(m_listCtrl);
- UpdatePageData(); // 鍏ㄩ噺閲嶅缓锛圵IP 椤堕儴锛�
+ UpdatePageData(); // 鍏ㄩ噺閲嶅缓锛圵IP 椤堕儴 & 鍒犻櫎鏃犳晥椤癸級
RestoreSelectionByKeys(m_listCtrl, selKeys);
RestoreTopByKey(m_listCtrl, topKey);
}
diff --git a/SourceCode/Bond/Servo/CPageGlassList.h b/SourceCode/Bond/Servo/CPageGlassList.h
index 064072b..af56f30 100644
--- a/SourceCode/Bond/Servo/CPageGlassList.h
+++ b/SourceCode/Bond/Servo/CPageGlassList.h
@@ -74,5 +74,6 @@
afx_msg void OnBnClickedButtonExport();
afx_msg void OnBnClickedButtonPrevPage();
afx_msg void OnBnClickedButtonNextPage();
+ afx_msg void OnShowFullText(NMHDR* pNMHDR, LRESULT* pResult);
DECLARE_MESSAGE_MAP()
};
diff --git a/SourceCode/Bond/Servo/CServoUtilsTool.cpp b/SourceCode/Bond/Servo/CServoUtilsTool.cpp
index 8c29031..1bf444a 100644
--- a/SourceCode/Bond/Servo/CServoUtilsTool.cpp
+++ b/SourceCode/Bond/Servo/CServoUtilsTool.cpp
@@ -121,8 +121,8 @@
if (slot == 0) return "后烘烤A腔";
if (slot == 1) return "冷却A";
- if (slot == 0) return "后烘烤B腔";
- if (slot == 1) return "冷却B";
+ if (slot == 2) return "后烘烤B腔";
+ if (slot == 3) return "冷却B";
}
if (eqid == EQ_ID_MEASUREMENT) {
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index 6f2111e..b9c5505 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/SourceCode/Bond/Servo/Model.cpp
@@ -437,6 +437,10 @@
m_hsmsPassive.requestEventReportSend_Panel_End();
auto& db = GlassLogDb::Instance();
db.insertFromCGlass((*(SERVO::CGlass*)pPanel));
+ SERVO::CGlass* pBuddy = ((SERVO::CGlass*)pPanel)->getBuddy();
+ if (pBuddy != nullptr) {
+ db.insertFromCGlass(*pBuddy);
+ }
};
m_master.setListener(masterListener);
m_master.setContinuousTransferCount(m_configuration.getContinuousTransferCount());
--
Gitblit v1.9.3