From 9198ac12e4e2ff64a2cf65c32d576f02d54c346a Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期六, 10 一月 2026 16:50:32 +0800
Subject: [PATCH] 1.S1F3_CurrentRecipe,S6F11_RecipeChange实现。

---
 SourceCode/Bond/EAPSimulator/Resource.h          |    6 +
 SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp |   52 +++++++++++++++++
 SourceCode/Bond/EAPSimulator/CHsmsActive.h       |    7 ++
 SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h   |    1 
 SourceCode/Bond/Servo/CEquipment.cpp             |   19 ++++++
 SourceCode/Bond/EAPSimulator/EAPSimulator.rc     |   20 +++---
 SourceCode/Bond/Servo/CMaster.cpp                |    5 +
 SourceCode/Bond/Servo/CMaster.h                  |    3 +
 SourceCode/Bond/Servo/Model.cpp                  |   37 ++++++++++++
 SourceCode/Bond/Servo/CEquipment.h               |    5 +
 SourceCode/Bond/x64/Debug/VariableList.txt       |    6 ++
 11 files changed, 149 insertions(+), 12 deletions(-)

diff --git a/SourceCode/Bond/EAPSimulator/CHsmsActive.h b/SourceCode/Bond/EAPSimulator/CHsmsActive.h
index 4566fa0..b8f3234 100644
--- a/SourceCode/Bond/EAPSimulator/CHsmsActive.h
+++ b/SourceCode/Bond/EAPSimulator/CHsmsActive.h
@@ -12,6 +12,13 @@
 #define SVID_CJobSpace            5001
 #define SVID_PJobSpace				5002
 #define SVID_PJobQueued				5003
+#define SVID_EQPPExecName           801
+#define SVID_Bonder1CurrentRecipe   8100
+#define SVID_Bonder2CurrentRecipe   8101
+#define SVID_VacuumBakeCurrentRecipe 8102
+#define SVID_BakeCoolingCurrentRecipe 8103
+#define SVID_MeasurementCurrentRecipe 8104
+#define SVID_EFEMCurrentRecipe      8105
 
 
 typedef std::function<void(void* pFrom, ACTIVESTATE state)> STATECHANGED;
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulator.rc b/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
index d1527d3..b577063 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulator.rc
@@ -54,10 +54,10 @@
     "\r\n"
     "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
     "LANGUAGE 4, 2\r\n"
-    "#include ""res\\EAPSimulator.rc2""  // 闈� Microsoft Visual C++ 缂栬緫鐨勮祫婧怽r\n"
-    "#include ""l.CHS\\afxres.rc""      // 鏍囧噯缁勪欢\r\n"
+    "#include ""res\\EAPSimulator.rc2""  // 闂�?Microsoft Visual C++ 缂傛牞绶惃鍕カ濠�?\n"
+    "#include ""l.CHS\\afxres.rc""      // 閺嶅洤鍣紒鍕\r\n"
     "#if !defined(_AFXDLL)\r\n"
-    "#include ""l.CHS\\afxribbon.rc""   // MFC 鍔熻兘鍖哄拰鎺у埗鏉¤祫婧怽r\n"
+    "#include ""l.CHS\\afxribbon.rc""   // MFC 閸旂喕鍏橀崠鍝勬嫲閹貉冨煑閺壜ょカ濠�?\n"
     "#endif\r\n"
     "#endif\r\n"
     "\0"
@@ -92,17 +92,17 @@
     DEFPUSHBUTTON   "纭畾",IDOK,113,41,50,14,WS_GROUP
 END
 
-IDD_EAPSIMULATOR_DIALOG DIALOGEX 0, 0, 469, 275
+IDD_EAPSIMULATOR_DIALOG DIALOGEX 0, 0, 469, 292
 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
 EXSTYLE WS_EX_APPWINDOW
 CAPTION "EAPSimulator"
 FONT 9, "MS Shell Dlg", 0, 0, 0x1
 BEGIN
-    DEFPUSHBUTTON   "纭畾",IDOK,246,254,50,14,NOT WS_VISIBLE
-    PUSHBUTTON      "鍙栨秷",IDCANCEL,412,254,50,14,NOT WS_VISIBLE
-    EDITTEXT        IDC_EDIT_LOG,7,190,455,78,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL
-    LTEXT           "鏃ュ織锛�",IDC_STATIC,7,181,24,8
-    GROUPBOX        "鍔熻兘",IDC_STATIC,7,7,455,164
+    DEFPUSHBUTTON   "纭畾",IDOK,246,271,50,14,NOT WS_VISIBLE
+    PUSHBUTTON      "鍙栨秷",IDCANCEL,412,271,50,14,NOT WS_VISIBLE
+    EDITTEXT        IDC_EDIT_LOG,7,218,455,67,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL
+    LTEXT           "鏃ュ織锛�",IDC_STATIC,7,203,24,8
+    GROUPBOX        "鍔熻兘",IDC_STATIC,7,7,455,190
     LTEXT           "IP:",IDC_STATIC,24,20,11,8
     EDITTEXT        IDC_EDIT_IP,39,17,94,14,ES_AUTOHSCROLL
     LTEXT           "Port:",IDC_STATIC,141,20,17,8
@@ -297,7 +297,7 @@
         LEFTMARGIN, 7
         RIGHTMARGIN, 462
         TOPMARGIN, 7
-        BOTTOMMARGIN, 268
+        BOTTOMMARGIN, 285
     END
 
     IDD_DIALOG_TERMINAL_DISPLAY, DIALOG
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
index 0b54f77..90c57ae 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
@@ -106,6 +106,7 @@
 	ON_BN_CLICKED(IDC_BUTTON_QUERY_PROCESS_STATE, &CEAPSimulatorDlg::OnBnClickedButtonQueryProcessState)
 	ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_SVID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllSvid)
 	ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_CEID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllCeid)
+	ON_BN_CLICKED(IDC_BUTTON_QUERY_CURRENT_RECIPE, &CEAPSimulatorDlg::OnBnClickedButtonQueryCurrentRecipe)
 END_MESSAGE_MAP()
 
 
@@ -272,6 +273,34 @@
 			WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
 			rc.left, rc.top, rc.Width(), rc.Height(),
 			m_hWnd, (HMENU)IDC_BUTTON_QUERY_ALL_CEID, AfxGetInstanceHandle(), nullptr);
+		if (hBtn != nullptr) {
+			::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
+		}
+	}
+	// S1F3 CurrentRecipe (EQ specific) combo + button
+	{
+		CRect rcCombo(14, 168, 14 + 120, 168 + 120); // dropdown height arbitrary
+		MapDialogRect(&rcCombo);
+		HWND hCombo = ::CreateWindow(_T("COMBOBOX"), _T(""),
+			WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL,
+			rcCombo.left, rcCombo.top, rcCombo.Width(), rcCombo.Height(),
+			m_hWnd, (HMENU)IDC_COMBO_EQ_FOR_RECIPE, AfxGetInstanceHandle(), nullptr);
+		if (hCombo != nullptr) {
+			::SendMessage(hCombo, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
+			// 绠�鍗曞~鍏呰澶囧垪琛紙鍙寜闇�璋冩暣锛�
+			std::vector<CString> eqs = { _T("Bonder1"), _T("Bonder2"), _T("EFEM"), _T("VacuumBake"), _T("BakeCooling"), _T("Measurement") };
+			for (const auto& eq : eqs) {
+				::SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)eq);
+			}
+			::SendMessage(hCombo, CB_SETCURSEL, 0, 0);
+		}
+
+		CRect rcBtn(140, 168, 14 + 140 + 140, 168 + 14);
+		MapDialogRect(&rcBtn);
+		HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F3_CurrentRecipe"),
+			WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+			rcBtn.left, rcBtn.top, rcBtn.Width(), rcBtn.Height(),
+			m_hWnd, (HMENU)IDC_BUTTON_QUERY_CURRENT_RECIPE, AfxGetInstanceHandle(), nullptr);
 		if (hBtn != nullptr) {
 			::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE);
 		}
@@ -626,3 +655,26 @@
 {
 	theApp.m_model.m_pHsmsActive->hsmsQueryAllCollectionEvents();
 }
+
+void CEAPSimulatorDlg::OnBnClickedButtonQueryCurrentRecipe()
+{
+	CString sel;
+	CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_EQ_FOR_RECIPE);
+	if (pCombo != nullptr) {
+		int idx = pCombo->GetCurSel();
+		if (idx != CB_ERR) {
+			pCombo->GetLBText(idx, sel);
+		}
+	}
+	unsigned int svid = SVID_EQPPExecName; // 榛樿鍏ㄥ眬
+	CString upper = sel;
+	upper.MakeUpper();
+	if (upper.Find(_T("BONDER1")) != -1) svid = SVID_Bonder1CurrentRecipe;
+	else if (upper.Find(_T("BONDER2")) != -1) svid = SVID_Bonder2CurrentRecipe;
+	else if (upper.Find(_T("VACUUMBAKE")) != -1) svid = SVID_VacuumBakeCurrentRecipe;
+	else if (upper.Find(_T("BAKECOOLING")) != -1) svid = SVID_BakeCoolingCurrentRecipe;
+	else if (upper.Find(_T("MEASUREMENT")) != -1) svid = SVID_MeasurementCurrentRecipe;
+	else if (upper.Find(_T("EFEM")) != -1) svid = SVID_EFEMCurrentRecipe;
+
+	theApp.m_model.m_pHsmsActive->hsmsSelectedEquipmentStatusRequest(svid);
+}
diff --git a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
index 547f189..53604db 100644
--- a/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
+++ b/SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
@@ -72,4 +72,5 @@
 	afx_msg void OnBnClickedButtonQueryProcessState();
 	afx_msg void OnBnClickedButtonQueryAllSvid();
 	afx_msg void OnBnClickedButtonQueryAllCeid();
+	afx_msg void OnBnClickedButtonQueryCurrentRecipe();
 };
diff --git a/SourceCode/Bond/EAPSimulator/Resource.h b/SourceCode/Bond/EAPSimulator/Resource.h
index 76d0766..be43ee7 100644
--- a/SourceCode/Bond/EAPSimulator/Resource.h
+++ b/SourceCode/Bond/EAPSimulator/Resource.h
@@ -67,14 +67,16 @@
 #define IDC_BUTTON_QUERY_ALL_CEID       1049
 #define IDC_EDIT_DELETE_PPID            1050
 #define IDC_BUTTON_DELETE_PPID          1051
+#define IDC_COMBO_EQ_FOR_RECIPE         1052
+#define IDC_BUTTON_QUERY_CURRENT_RECIPE 1053
 
 // Next default values for new objects
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        144
+#define _APS_NEXT_RESOURCE_VALUE        145
 #define _APS_NEXT_COMMAND_VALUE         32771
-#define _APS_NEXT_CONTROL_VALUE         1052
+#define _APS_NEXT_CONTROL_VALUE         1054
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index 2cddb34..3de5521 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -208,6 +208,21 @@
 		return m_strDescription;
 	}
 
+	void CEquipment::setCurrentRecipe(const std::string& recipe)
+	{
+		Lock();
+		m_currentRecipe = recipe;
+		Unlock();
+	}
+
+	std::string CEquipment::getCurrentRecipe()
+	{
+		Lock();
+		std::string out = m_currentRecipe;
+		Unlock();
+		return out;
+	}
+
 	void CEquipment::setStation(int network, int station)
 	{
 		m_station.nNetNo = network;
@@ -1655,6 +1670,10 @@
 				m_strName.c_str(), nRet);
 		}
 
+		if (m_listener.onReceivedJob != nullptr) {
+			m_listener.onReceivedJob(this, port, pJobDataS);
+		}
+
 		return nRet;
 	}
 
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index 6f314c0..024b9e9 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -59,6 +59,7 @@
 	typedef std::function<void(void* pEiuipment, short scanMap, short downMap)> ONMAPMISMATCH;
 	typedef std::function<void(void* pEiuipment, short status, __int64 data)> ONPORTSTATUSCHANGED;
 	typedef std::function<void(void* pEiuipment, const std::vector<CParam>& params)> ONPROCESSDATAREPORT;
+	typedef std::function<void(void* pEiuipment, int port, CJobDataS* pJobDataS)> ONRECEIVEDJOB;
 	
 	typedef struct _EquipmentListener
 	{
@@ -75,6 +76,7 @@
 		ONVCREVENTREPORT	onSVDataReport;
 		ONVCREVENTREPORT	onPanelDataReport;
 		ONPROCESSDATAREPORT	onProcessDataReport;
+		ONRECEIVEDJOB		onReceivedJob;
 	} EquipmentListener;
 
 
@@ -101,6 +103,8 @@
 		std::string& getName();
 		void setDescription(const char* pszDescription);
 		std::string& getDescription();
+		void setCurrentRecipe(const std::string& recipe);
+		std::string getCurrentRecipe();
 		void setStation(int network, int station);
 		const StationIdentifier& getStation();
 		virtual void getAttributeVector(CAttributeVector& attrubutes);
@@ -284,6 +288,7 @@
 		int m_nID;
 		std::string m_strName;
 		std::string m_strDescription;
+		std::string m_currentRecipe;
 		CRITICAL_SECTION m_criticalSection;
 		StationIdentifier m_station;
 		MemoryBlock m_blockReadBit;
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 6df6ca1..fe03f97 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -1810,6 +1810,11 @@
 			}
 
 		};
+		listener.onReceivedJob = [&](void* pEquipment, int port, CJobDataS* pJobDataS) {
+			if (m_listener.onJobReceived != nullptr) {
+				m_listener.onJobReceived(this, (CEquipment*)pEquipment, port, pJobDataS);
+			}
+		};
 		pEquipment->setListener(listener);
 		pEquipment->setCcLink(&m_cclink);
 		m_listEquipment.push_back(pEquipment);
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index 02720ee..567a7b1 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/SourceCode/Bond/Servo/CMaster.h
@@ -16,6 +16,7 @@
 #include "ProcessJob.h"
 #include "CControlJob.h"
 #include "../DAQBridge/core/Collector.h"
+#include "CJobDataS.h"
 
 
 #define CTStep_Unknow                   0
@@ -61,6 +62,7 @@
     typedef std::function<void(void* pMaster, CEquipment* pEquipment, int slotNo, PROCESS_STATE prevState, PROCESS_STATE state)> ONPROCESSSTATECHANGED;
     typedef std::function<void(void* pMaster, CEquipment* pEquipment, const std::vector<CParam>& params)> ONPROCESSDATAREPORTEX;
     typedef std::function<void(void* pMaster, CEquipment* pEquipment, const std::vector<CParam>& params)> ONSVDATAREPORT;
+    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int port, CJobDataS* pJobDataS)> ONJOBRECEIVED;
     typedef std::function<void(void* pMaster, int round)> ONCTROUNDEND;
     typedef std::function<void(void* pMaster, void* pj)> ONPJSTART;
     typedef std::function<void(void* pMaster)> ONCONTROLJOBCHANGED;
@@ -77,6 +79,7 @@
         ONPROCESSSTATECHANGED   onProcessStateChanged;
         ONSVDATAREPORT          onSVDataReport;
         ONPROCESSDATAREPORTEX   onProcessDataReport;
+        ONJOBRECEIVED           onJobReceived;
         ONCTROUNDEND            onCTRoundEnd;
         ONPJSTART               onCjStart;
         ONPJSTART               onCjEnd;
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index 5087821..fb2cf9d 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/SourceCode/Bond/Servo/Model.cpp
@@ -10,6 +10,7 @@
 #include "RecipeManager.h"
 #include "GlassLogDb.h"
 #include "CParam.h"
+#include "CJobDataS.h"
 #include <algorithm>
 #include <iomanip>
 #include <sstream>
@@ -510,6 +511,42 @@
 		notifyPtrAndInt(RX_CODE_EQ_ROBOT_TASK, pTask, nullptr, code);
 
 	};
+	masterListener.onJobReceived = [&](void* pMaster, SERVO::CEquipment* pEquipment, int port, SERVO::CJobDataS* pJobDataS) {
+		(void)pMaster;
+		(void)port;
+		if (pEquipment == nullptr || pJobDataS == nullptr) return;
+		const int eqId = pEquipment->getID();
+		const int recipeId = pJobDataS->getMasterRecipe();
+		std::string recipe = RecipeManager::getInstance().getPPIDById(recipeId);
+		if (recipe.empty()) {
+			recipe = std::to_string(recipeId);
+		}
+		const std::string prev = pEquipment->getCurrentRecipe();
+		if (recipe.empty() || recipe == prev) {
+			pEquipment->setCurrentRecipe(recipe);
+			return;
+		}
+		pEquipment->setCurrentRecipe(recipe);
+		m_hsmsPassive.withVariableLock([&] {
+			m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str());
+			m_hsmsPassive.setVariableValue("EQPPExecName", recipe.c_str());
+			m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str());
+			const char* recipeVid = nullptr;
+			switch (eqId) {
+			case EQ_ID_Bonder1: recipeVid = "Bonder1CurrentRecipe"; break;
+			case EQ_ID_Bonder2: recipeVid = "Bonder2CurrentRecipe"; break;
+			case EQ_ID_VACUUMBAKE: recipeVid = "VacuumBakeCurrentRecipe"; break;
+			case EQ_ID_BAKE_COOLING: recipeVid = "BakeCoolingCurrentRecipe"; break;
+			case EQ_ID_MEASUREMENT: recipeVid = "MeasurementCurrentRecipe"; break;
+			case EQ_ID_EFEM: recipeVid = "EFEMCurrentRecipe"; break;
+			default: break;
+			}
+			if (recipeVid != nullptr) {
+				m_hsmsPassive.setVariableValue(recipeVid, recipe.c_str());
+			}
+			m_hsmsPassive.requestEventReportSend("RecipeChanged");
+		});
+	};
 	masterListener.onLoadPortStatusChanged = [&] (void* pMaster, SERVO::CEquipment* pEquipment, short status, __int64 data) {
 		LOGE("<CModel>onLoadPortStatusChanged. status = %d", status);
 		static std::map<int, short> s_prevPortStatus;
diff --git a/SourceCode/Bond/x64/Debug/VariableList.txt b/SourceCode/Bond/x64/Debug/VariableList.txt
index c146e6a..2f945a2 100644
--- a/SourceCode/Bond/x64/Debug/VariableList.txt
+++ b/SourceCode/Bond/x64/Debug/VariableList.txt
@@ -8,6 +8,12 @@
 701,PreviousProcessState,U1,
 800,EFEMPPExecName,A20,
 801,EQPPExecName,A20,
+8100,Bonder1CurrentRecipe,A50,
+8101,Bonder2CurrentRecipe,A50,
+8102,VacuumBakeCurrentRecipe,A50,
+8103,BakeCoolingCurrentRecipe,A50,
+8104,MeasurementCurrentRecipe,A50,
+8105,EFEMCurrentRecipe,A50,
 2000,RbRAxisTorque,I2,鏈哄櫒浜篟杞存壄鐭�
 2001,RbLAxisTorque,U1,鏈哄櫒浜篖杞存壄鐭�
 2002,RbZAxisTorque,U1,鏈哄櫒浜篫杞存壄鐭�

--
Gitblit v1.9.3