From 4ef35bf238fc6f7217e4b6de4aee37192ec503ec Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期三, 17 九月 2025 13:36:27 +0800
Subject: [PATCH] 1.自绘CListCtrl用于ProcessJob的Carrier选择
---
SourceCode/Bond/Servo/PortConfigurationDlg.cpp | 397 ++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 351 insertions(+), 46 deletions(-)
diff --git a/SourceCode/Bond/Servo/PortConfigurationDlg.cpp b/SourceCode/Bond/Servo/PortConfigurationDlg.cpp
index 79a1e11..62ad3a0 100644
--- a/SourceCode/Bond/Servo/PortConfigurationDlg.cpp
+++ b/SourceCode/Bond/Servo/PortConfigurationDlg.cpp
@@ -8,7 +8,10 @@
#include "NewCellTypes/GridCellCheck.h"
#include "NewCellTypes/GridCellCombo.h"
#include "NewCellTypes/GridCellNumeric.h"
+#include "RecipeManager.h"
+#include "ServoCommo.h"
+#define CHECKBOX_ALL_ID 0x1234
// CPortConfigurationDlg 瀵硅瘽妗�
@@ -17,11 +20,111 @@
CPortConfigurationDlg::CPortConfigurationDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIALOG_PORT_CONFIGURATION, pParent)
{
-
+ // 鍒濆鍖栨垚鍛樺彉閲�
+ m_pPort[0] = dynamic_cast<SERVO::CLoadPort*>(theApp.m_model.m_master.getEquipment(EQ_ID_LOADPORT1));
+ m_pPort[1] = dynamic_cast<SERVO::CLoadPort*>(theApp.m_model.m_master.getEquipment(EQ_ID_LOADPORT2));
+ m_pPort[2] = dynamic_cast<SERVO::CLoadPort*>(theApp.m_model.m_master.getEquipment(EQ_ID_LOADPORT3));
+ m_pPort[3] = dynamic_cast<SERVO::CLoadPort*>(theApp.m_model.m_master.getEquipment(EQ_ID_LOADPORT4));
+ m_nCurSelPort = -1;
+ m_pCheckBox = nullptr;
+ m_bCheckedAll = FALSE;
}
CPortConfigurationDlg::~CPortConfigurationDlg()
{
+}
+
+void CPortConfigurationDlg::setCurSelPort(int sel)
+{
+ m_nCurSelPort = sel;
+}
+
+int CPortConfigurationDlg::GetLoadPortEqID(const std::string& strPortName)
+{
+ if (strPortName == "Port 1") return EQ_ID_LOADPORT1;
+ if (strPortName == "Port 2") return EQ_ID_LOADPORT2;
+ if (strPortName == "Port 3") return EQ_ID_LOADPORT3;
+ if (strPortName == "Port 4") return EQ_ID_LOADPORT4;
+ return -1; // 鏈煡绔彛
+}
+
+void CPortConfigurationDlg::LoadPortConfigToUI(SERVO::CLoadPort* pPort)
+{
+ if (!pPort) {
+ return;
+ }
+
+ CStringArray permissions;
+ permissions.Add(_T("G1"));
+ permissions.Add(_T("G2"));
+
+ SetDlgItemText(IDC_EDIT_LOTID, "");
+ SetDlgItemText(IDC_EDIT_PRODUCTID, "");
+ SetDlgItemText(IDC_EDIT_OPERATIONID, "");
+ m_comboMaterialsType.SetCurSel(0);
+
+ bool bJobInfoSet = false;
+ for (int i = 0; i < SLOT_MAX; ++i) {
+ SERVO::CSlot* pSlot = pPort->getSlot(i);
+ if (!pSlot) {
+ continue;
+ }
+
+ // 璁剧疆 Panel ID 鍜屽嬀閫夋
+ SERVO::CGlass* pGlass = dynamic_cast<SERVO::CGlass*>(pSlot->getContext());
+ SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS();
+ int nRow = i + 1;
+ if (pGlass != nullptr && pJobDataS != nullptr) {
+ m_wndGrid.SetItemState(nRow, 0, GVIS_READONLY);
+ m_wndGrid.SetItemText(nRow, 0, pSlot->getName().c_str());
+ m_wndGrid.SetCellType(nRow, 1, RUNTIME_CLASS(CGridCellCheck));
+ CGridCellCheck* pCheck = dynamic_cast<CGridCellCheck*>(m_wndGrid.GetCell(nRow, 1));
+ ASSERT(pCheck);
+ pCheck->SetCheck(pGlass->isScheduledForProcessing());
+ pCheck->SetText(pGlass->getID().c_str());
+
+ if (m_wndGrid.SetCellType(nRow, 2, RUNTIME_CLASS(CGridCellCombo))) {
+ CGridCellCombo* pCell = static_cast<CGridCellCombo*>(m_wndGrid.GetCell(nRow, 2));
+ pCell->SetOptions(permissions);
+ pCell->SetStyle(CBS_DROPDOWNLIST);
+
+ int nMaterialsType = pJobDataS->getMaterialsType() - 1;
+ if (nMaterialsType < 0 || nMaterialsType > 2) {
+ nMaterialsType = 0;
+ }
+ m_wndGrid.SetItemText(nRow, 2, permissions.GetAt(nMaterialsType));
+ }
+ }
+ m_wndGrid.SetItemData(nRow, 0, (LPARAM)pGlass);
+
+ // 鍥炲~ Job 淇℃伅锛堝彧鍙栫涓�涓湁鏁� Glass锛�
+ if (!bJobInfoSet && pGlass) {
+ SERVO::CJobDataS* pJS = pGlass->getJobDataS();
+ if (pJS) {
+ int nRecipeID = pJobDataS->getMasterRecipe();
+ std::string strRecipeName = RecipeManager::getInstance().getPPIDById(nRecipeID);
+ SetDlgItemText(IDC_EDIT_LOTID, CString(pJS->getLotId().c_str()));
+ SetDlgItemText(IDC_EDIT_PRODUCTID, CString(pJS->getProductId().c_str()));
+ SetDlgItemText(IDC_EDIT_OPERATIONID, CString(pJS->getOperationId().c_str()));
+ m_comboMaterialsType.SetCurSel(pJS->getMaterialsType() - 1);
+
+ if (!strRecipeName.empty()) {
+ CString csRecipeName(strRecipeName.c_str());
+ int nIndex = m_comboRecipe.FindStringExact(-1, csRecipeName);
+ if (nIndex != CB_ERR) {
+ m_comboRecipe.SetCurSel(nIndex);
+ }
+ else {
+ AfxMessageBox(_T("褰撳墠閰嶆柟鍦ㄧ郴缁熶腑涓嶅瓨鍦紝璇烽噸鏂伴�夋嫨锛�"), MB_ICONWARNING);
+ m_comboRecipe.SetCurSel(0);
+ }
+ }
+
+ bJobInfoSet = true;
+ }
+ }
+ }
+ m_pCheckBox->SetCheck(IsCheckedAll() ? BST_CHECKED : BST_UNCHECKED);
}
void CPortConfigurationDlg::InitGrid()
@@ -32,7 +135,7 @@
const int nCols = 3;
const int nFixRows = 1;
- const int nRows = 9;
+ const int nRows = SLOT_MAX + 1; // 瀛樺湪琛ㄥご锛屾墍浠� +1
int nColIdx = 0;
m_wndGrid.DeleteAllItems();
@@ -53,19 +156,18 @@
// 璁剧疆鍒楀
m_wndGrid.SetColumnWidth(nColIdx, 50);
m_wndGrid.SetItemText(0, nColIdx++, _T("Slot ID"));
- m_wndGrid.SetColumnWidth(nColIdx, 150);
- m_wndGrid.SetItemText(0, nColIdx++, _T("EQ Recipe"));
- m_wndGrid.SetColumnWidth(nColIdx, 150);
- m_wndGrid.SetItemText(0, nColIdx++, _T("Panel ID"));
m_wndGrid.SetColumnWidth(nColIdx, 60);
- m_wndGrid.SetItemText(0, nColIdx++, _T("鍚敤"));
+ m_wndGrid.SetItemText(0, nColIdx++, _T("Glass ID"));
+ m_wndGrid.SetColumnWidth(nColIdx, 60);
+ m_wndGrid.SetItemText(0, nColIdx++, _T("鐗╂枡绫诲瀷"));
+
// 璁剧疆琛屼负鏍峰紡
m_wndGrid.SetFixedRowSelection(FALSE);
m_wndGrid.SetFixedColumnSelection(FALSE);
m_wndGrid.SetEditable(TRUE);
m_wndGrid.SetRowResize(FALSE);
- m_wndGrid.SetColumnResize(TRUE);
+ m_wndGrid.SetColumnResize(FALSE);
m_wndGrid.SetListMode(TRUE);
m_wndGrid.EnableSelection(TRUE);
m_wndGrid.SetSingleRowSelection(TRUE);
@@ -82,53 +184,35 @@
m_wndGrid.SetRowHeight(i, nEachRowHeight);
}
- FillGrid();
-}
-
-void CPortConfigurationDlg::FillGrid()
-{
- //CStringArray recipeOptions;
- //recipeOptions.Add(_T("Recipe A"));
- //recipeOptions.Add(_T("Recipe B"));
- //recipeOptions.Add(_T("Recipe C"));
-
- for (int i = 1; i < 9; ++i) {
- CString strIndex;
- strIndex.Format(_T("%d"), i);
- m_wndGrid.SetItemText(i, 0, strIndex);
- m_wndGrid.SetItemState(i, 0, GVIS_READONLY);
-
- // EQ Recipe - ComboBox
- //if (m_wndGrid.SetCellType(i, 1, RUNTIME_CLASS(CGridCellCombo))) {
- // CGridCellCombo* pCell = static_cast<CGridCellCombo*>(m_wndGrid.GetCell(i, 1));
- // pCell->SetOptions(recipeOptions);
- // pCell->SetStyle(CBS_DROPDOWNLIST);
- //}
- //m_wndGrid.SetItemText(i, 1, recipeOptions[0]);
-
- // Panel ID - 鍙紪杈�
- m_wndGrid.SetItemText(i, 1, _T(""));
-
- // Checkbox
- m_wndGrid.SetCellType(i, 2, RUNTIME_CLASS(CGridCellCheck));
- CGridCellCheck* pCheck = static_cast<CGridCellCheck*>(m_wndGrid.GetCell(i, 2));
- if (pCheck) {
- pCheck->SetCheck(FALSE);
- }
- }
-
- m_wndGrid.Invalidate();
- m_wndGrid.UpdateWindow();
+ CRect rect;
+ BOOL bOK = m_wndGrid.GetCellRect(0, 1, rect);
+ m_pCheckBox = new CCustomCheckBox();
+ m_pCheckBox->Create(_T("閫夋嫨鎵�鏈�"),
+ WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, // 鑷姩鍕鹃��
+ CRect(0, 0, 150, 32), &m_wndGrid, CHECKBOX_ALL_ID);
+ m_pCheckBox->SetFont(GetFont());
+ m_pCheckBox->MoveWindow(rect.left + 5, rect.top + 3, 150, rect.Height() - 6);
+ m_pCheckBox->SetBackgroundColor(g_nGridFixCellColor);
+ m_pCheckBox->SetNotifyHwnd(GetSafeHwnd());
}
void CPortConfigurationDlg::DoDataExchange(CDataExchange* pDX)
{
+ CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_GRID_PANEL_RECIPE, m_wndGrid);
- CDialogEx::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_COMBO_PORT, m_comboPort);
+ DDX_Control(pDX, IDC_COMBO_RECIPE, m_comboRecipe);
+ DDX_Control(pDX, IDC_COMBO_MATERIALS_TYPE, m_comboMaterialsType);
}
BEGIN_MESSAGE_MAP(CPortConfigurationDlg, CDialogEx)
+ ON_CBN_SELCHANGE(IDC_COMBO_PORT, &CPortConfigurationDlg::OnSelchangeComboPort)
+ ON_BN_CLICKED(IDC_BUTTON_APPLY, &CPortConfigurationDlg::OnBnClickedButtonApply)
+ ON_MESSAGE(WM_CHECKBOX_STATE_CHANGED, &CPortConfigurationDlg::OnCheckAllClicked)
+ ON_WM_DESTROY()
+ ON_BN_CLICKED(IDC_BUTTON_PROCESS_START, &CPortConfigurationDlg::OnBnClickedButtonProcessStart)
+ ON_BN_CLICKED(IDC_BUTTON_PROCESS_CANCEL, &CPortConfigurationDlg::OnBnClickedButtonProcessCancel)
END_MESSAGE_MAP()
@@ -139,8 +223,229 @@
CDialogEx::OnInitDialog();
// TODO: 鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+ // 鍒濆鍖栫鍙d笅鎷夋鍐呭
+ CString ports[] = { _T("Port 1"), _T("Port 2"), _T("Port 3"), _T("Port 4") };
+ for (const auto& item : ports) {
+ m_comboPort.AddString(item);
+ }
+ if (0 <= m_nCurSelPort && m_nCurSelPort <= 3) {
+ m_comboPort.SetCurSel(m_nCurSelPort);
+ m_comboPort.EnableWindow(FALSE);
+ }
+ else {
+ m_comboPort.SetCurSel(0);
+ }
+
+ // 鍒濆鍖栭厤鏂逛笅鎷夋鍐呭
+ std::vector<std::string> vecRecipe = RecipeManager::getInstance().getAllPPID();
+ for (const auto& recipe : vecRecipe) {
+ m_comboRecipe.AddString(CString(recipe.c_str()));
+ }
+ m_comboRecipe.SetCurSel(0); // 榛樿閫夋嫨绗竴涓厤鏂�
+
+ // 鍒濆鍖栫墿鏂欑被鍨嬩笅鎷夋鍐呭
+ CString materialTypes[] = { _T("G1"), _T("G2"), _T("G1+G2") };
+ for (const auto& item : materialTypes) {
+ m_comboMaterialsType.AddString(item);
+ }
+ m_comboMaterialsType.SetCurSel(0); // 榛樿閫夋嫨绗竴涓墿鏂欑被鍨�
+ m_comboMaterialsType.EnableWindow(FALSE);
InitGrid();
+
+ LoadPortConfigToUI(m_pPort[0]); // 榛樿鍔犺浇绗竴涓鍙g殑閰嶇疆
+
+ // 璁剧疆瀵硅瘽妗嗘爣棰�
+ BOOL bAutoPopup = 0 <= m_nCurSelPort && m_nCurSelPort <= 3;
+ if (bAutoPopup) {
+ CString strTitle;
+ strTitle.Format(_T("%s Configuration"), ports[m_nCurSelPort]);
+ SetWindowText(strTitle);
+ }
+ else {
+ SetWindowText(_T("Port Configuration"));
+ }
+
+ // Porcess Start / Process Cancel 鎸夐挳鐘舵��
+ GetDlgItem(IDC_BUTTON_PROCESS_START)->EnableWindow(FALSE);
+ GetDlgItem(IDC_BUTTON_PROCESS_CANCEL)->EnableWindow(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
}
+
+void CPortConfigurationDlg::OnSelchangeComboPort()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ int selPort = m_comboPort.GetCurSel();
+ if (selPort < 0 || selPort >= 4) {
+ return; // 鏃犳晥閫夋嫨
+ }
+
+ // 鍔犺浇閫変腑绔彛鐨勯厤缃埌 UI
+ for (int i = 1; i <= 8; i++) {
+ m_wndGrid.SetItemText(i, 0, "");
+ m_wndGrid.SetItemText(i, 1, "");
+ m_wndGrid.SetCellType(i, 1, RUNTIME_CLASS(CGridCellNumeric));
+ }
+ m_wndGrid.Invalidate();
+ LoadPortConfigToUI(m_pPort[selPort]);
+}
+
+void CPortConfigurationDlg::OnBnClickedButtonApply()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ SERVO::PortConfig config;
+
+ // 鑾峰彇 Port 鍚嶇О
+ int selPort = m_comboPort.GetCurSel();
+ if (selPort != CB_ERR) {
+ CString str;
+ m_comboPort.GetLBText(selPort, str);
+ config.strPortName = CT2A(str.GetString());
+ }
+
+ // 鑾峰彇 Recipe 鍚嶇О
+ int selRecipe = m_comboRecipe.GetCurSel();
+ if (selRecipe != CB_ERR) {
+ CString str;
+ m_comboRecipe.GetLBText(selRecipe, str);
+ config.strRecipe = CT2A(str.GetString());
+ }
+ int nRecipeID = RecipeManager::getInstance().getIdByPPID(config.strRecipe);
+ RecipeInfo stRecipeInfo = RecipeManager::getInstance().getRecipeByPPID(config.strRecipe);
+ std::vector<DeviceRecipe> vecRecipeInfo = stRecipeInfo.vecDeviceList;
+
+ // 鑾峰彇 Material Type 绱㈠紩锛堢储寮曚粠 0 寮�濮嬶紝瀵瑰簲鏋氫妇浠� 1 寮�濮嬶級
+ //int selMaterial = m_comboMaterialsType.GetCurSel();
+ //if (selMaterial != CB_ERR) {
+ // config.nMaterialType = selMaterial + 1;
+ //}
+ //else {
+ // AfxMessageBox(_T("Please select a material type!"));
+ // return;
+ //}
+
+ // 鑾峰彇 Lot ID / Product ID / Operation ID
+ CString strText;
+ GetDlgItemText(IDC_EDIT_LOTID, strText);
+ config.strLotID = CT2A(strText.GetString());
+ if (config.strLotID.empty()) {
+ AfxMessageBox(_T("Lot ID cannot be empty!"));
+ return;
+ }
+
+ GetDlgItemText(IDC_EDIT_PRODUCTID, strText);
+ config.strProductID = CT2A(strText.GetString());
+ if (config.strProductID.empty()) {
+ AfxMessageBox(_T("Product ID cannot be empty!"));
+ return;
+ }
+
+ GetDlgItemText(IDC_EDIT_OPERATIONID, strText);
+ config.strOperationID = CT2A(strText.GetString());
+ if (config.strOperationID.empty()) {
+ AfxMessageBox(_T("Operation ID cannot be empty!"));
+ return;
+ }
+
+ // 鑾峰彇 Grid 琛ㄦ牸涓� Slot 鐘舵�侊紙绗�1~8琛岋級
+ for (int i = 1; i <= SLOT_MAX; ++i) {
+ SERVO::CGlass* pGlass = (SERVO::CGlass*)m_wndGrid.GetItemData(i, 0);
+ int nMaterialType = m_wndGrid.GetItemText(i, 2).CompareNoCase("G1") == 0 ? 1 : 2;
+ if (pGlass != nullptr) {
+ CGridCellCheck* pCheck = dynamic_cast<CGridCellCheck*>(m_wndGrid.GetCell(i, 1));
+ CGridCellCombo* pCombo = dynamic_cast<CGridCellCombo*>(m_wndGrid.GetCell(i, 2));
+ ASSERT(pCheck && pCombo);
+ pGlass->setScheduledForProcessing(pCheck->GetCheck());
+ pGlass->setType(static_cast<SERVO::MaterialsType>(nMaterialType));
+
+ SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS();
+ pJobDataS->setLotId(config.strLotID.c_str());
+ pJobDataS->setProductId(config.strProductID.c_str());
+ pJobDataS->setOperationId(config.strOperationID.c_str());
+ pJobDataS->setMaterialsType(nMaterialType);
+ pJobDataS->setMasterRecipe(nRecipeID);
+
+ for (const auto& info : vecRecipeInfo) {
+ const std::string& name = info.strDeviceName;
+ short nRecipeID = (short)info.nRecipeID;
+
+ if (name == EQ_NAME_EFEM) {
+ pJobDataS->setDeviceRecipeId(0, nRecipeID);
+ }
+ else if (name == EQ_NAME_BONDER1) {
+ pJobDataS->setDeviceRecipeId(1, nRecipeID);
+ }
+ else if (name == EQ_NAME_BONDER2) {
+ pJobDataS->setDeviceRecipeId(2, nRecipeID);
+ }
+ else if (name == EQ_NAME_BAKE_COOLING) {
+ pJobDataS->setDeviceRecipeId(3, nRecipeID);
+ }
+ else if (name == EQ_NAME_VACUUMBAKE) {
+ pJobDataS->setDeviceRecipeId(4, nRecipeID);
+ }
+ else if (name == EQ_NAME_MEASUREMENT) {
+ pJobDataS->setDeviceRecipeId(5, nRecipeID);
+ }
+ }
+ }
+ }
+
+ GetDlgItem(IDC_BUTTON_PROCESS_START)->EnableWindow(TRUE);
+ GetDlgItem(IDC_BUTTON_PROCESS_CANCEL)->EnableWindow(TRUE);
+}
+
+void CPortConfigurationDlg::OnDestroy()
+{
+ CDialogEx::OnDestroy();
+
+ if (m_pCheckBox != nullptr) {
+ m_pCheckBox->DestroyWindow();
+ delete m_pCheckBox;
+ m_pCheckBox = nullptr;
+ }
+}
+
+LRESULT CPortConfigurationDlg::OnCheckAllClicked(WPARAM wParam, LPARAM lParam)
+{
+ UINT ctrlID = (UINT)wParam;
+ BOOL bChecked = (BOOL)lParam;
+ for (int i = 1; i <= SLOT_MAX; ++i) {
+ CGridCellCheck* pCheck = dynamic_cast<CGridCellCheck*>(m_wndGrid.GetCell(i, 1));
+ if (pCheck != nullptr) {
+ pCheck->SetCheck(bChecked);
+ }
+ }
+
+
+ return 0;
+}
+
+BOOL CPortConfigurationDlg::IsCheckedAll()
+{
+ for (int i = 1; i <= SLOT_MAX; ++i) {
+ CGridCellCheck* pCheck = dynamic_cast<CGridCellCheck*>(m_wndGrid.GetCell(i, 1));
+ if (pCheck != nullptr) {
+ if (!pCheck->GetCheck()) return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+void CPortConfigurationDlg::OnBnClickedButtonProcessStart()
+{
+ int selPort = (0 <= m_nCurSelPort && m_nCurSelPort <= 3) ? m_nCurSelPort
+ : m_comboPort.GetCurSel();
+ if (selPort < 0 || selPort >= 4) return;
+ m_pPort[selPort]->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
+}
+
+void CPortConfigurationDlg::OnBnClickedButtonProcessCancel()
+{
+ int selPort = (0 <= m_nCurSelPort && m_nCurSelPort <= 3) ? m_nCurSelPort
+ : m_comboPort.GetCurSel();
+ if (selPort < 0 || selPort >= 4) return;
+ m_pPort[selPort]->sendCassetteCtrlCmd(CCC_PROCESS_CANCEL, nullptr, 0, 0, 0, nullptr, nullptr);
+}
--
Gitblit v1.9.3