// RecipeDeviceBindDlg.cpp: 实现文件
|
//
|
|
#include "stdafx.h"
|
#include "Servo.h"
|
#include "afxdialogex.h"
|
#include "RecipeDeviceBindDlg.h"
|
#include "RecipeManager.h"
|
#include "Common.h"
|
|
#define IDC_EDIT_DEVICEID_BASE 3000
|
#define IDC_EDIT_DEVICENAME_BASE 3050
|
#define IDC_COMBO_RECIPEID_BASE 3100
|
|
// 绑定界面需要显示的设备
|
static const std::vector<DeviceMetaInfo> g_vecBindDevices = {
|
{ EQ_ID_VACUUMBAKE, EQ_NAME_VACUUMBAKE },
|
{ EQ_ID_Bonder1, EQ_NAME_BONDER1 },
|
{ EQ_ID_Bonder2, EQ_NAME_BONDER2 },
|
{ EQ_ID_BAKE_COOLING, EQ_NAME_BAKE_COOLING },
|
{ EQ_ID_MEASUREMENT, EQ_NAME_MEASUREMENT },
|
{ EQ_ID_EFEM, EQ_NAME_EFEM }
|
};
|
|
// CRecipeDeviceBindDlg 对话框
|
|
IMPLEMENT_DYNAMIC(CRecipeDeviceBindDlg, CDialogEx)
|
|
CRecipeDeviceBindDlg::CRecipeDeviceBindDlg(CWnd* pParent /*=nullptr*/)
|
: CDialogEx(IDD_DIALOG_RECIPE_DEVICE_BIND, pParent)
|
, m_strPPID(_T(""))
|
, m_strDesc(_T(""))
|
{
|
|
}
|
|
CRecipeDeviceBindDlg::~CRecipeDeviceBindDlg()
|
{
|
}
|
|
const RecipeInfo& CRecipeDeviceBindDlg::GetRecipeInfo() const {
|
return m_recipe;
|
}
|
|
void CRecipeDeviceBindDlg::SetRecipeInfo(const RecipeInfo& info)
|
{
|
m_recipe = info;
|
}
|
|
void CRecipeDeviceBindDlg::ReleaseDeviceControls()
|
{
|
for (auto& ctrl : m_vecDevices) {
|
delete ctrl.editDeviceID; ctrl.editDeviceID = nullptr;
|
delete ctrl.editDeviceName; ctrl.editDeviceName = nullptr;
|
delete ctrl.comboRecipeID; ctrl.comboRecipeID = nullptr;
|
}
|
m_vecDevices.clear();
|
}
|
|
void CRecipeDeviceBindDlg::CreateDeviceControls(int nXStart, int nYStart, int nTotalControlWidth, int nRowHeight)
|
{
|
for (size_t i = 0; i < g_vecBindDevices.size(); ++i) {
|
int y = nYStart + static_cast<int>(i) * nRowHeight;
|
auto* pEditID = new CEdit;
|
pEditID->Create(WS_CHILD | WS_VISIBLE | WS_BORDER | ES_CENTER, CRect(nXStart, y, nXStart + 100, y + 25), this, (UINT)(IDC_EDIT_DEVICEID_BASE + i));
|
pEditID->SetFont(&m_font);
|
|
auto* pEditName = new CEdit;
|
pEditName->Create(WS_CHILD | WS_VISIBLE | WS_BORDER | ES_CENTER, CRect(nXStart + 110, y, nXStart + 210, y + 25), this, (UINT)(IDC_EDIT_DEVICENAME_BASE + i));
|
pEditName->SetFont(&m_font);
|
|
auto* pCombo = new CComboBox;
|
pCombo->Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, CRect(nXStart + 220, y, nXStart + nTotalControlWidth, y + 25), this, (UINT)(IDC_COMBO_RECIPEID_BASE + i));
|
pCombo->SetFont(&m_font);
|
|
m_vecDevices.push_back({ pEditID, pEditName, pCombo });
|
}
|
}
|
|
bool CRecipeDeviceBindDlg::FillComboRecipeList(CComboBox* pCombo, int nDeviceID, int nSelectedRecipeID)
|
{
|
auto& master = theApp.m_model.getMaster();
|
auto* pEq = master.getEquipment(nDeviceID);
|
if (!pEq) {
|
return false;
|
}
|
|
auto* pRecipeList = pEq->getRecipeList(0);
|
if (!pRecipeList) {
|
return false;
|
}
|
|
auto& mapRecipeIds = pRecipeList->getIds();
|
bool bFound = false;
|
pCombo->ResetContent();
|
for (const auto& pair : mapRecipeIds) {
|
int nRecipeID = pair.second;
|
|
std::string strDeviceName;
|
for (const auto& dev : g_vecBindDevices) {
|
if (dev.nDeviceID == pEq->getID()) {
|
strDeviceName = dev.strDeviceName;
|
}
|
}
|
|
std::string strRecipeName = RecipeManager::getInstance().getDeviceRecipeName(strDeviceName, nRecipeID);
|
if (strRecipeName.empty()) {
|
strRecipeName = std::to_string(nRecipeID);
|
}
|
|
CString str;
|
str.Format(_T("%s"), strRecipeName.c_str());
|
int idx = pCombo->AddString(str);
|
pCombo->SetItemData(idx, nRecipeID);
|
if (nSelectedRecipeID == nRecipeID) {
|
pCombo->SetCurSel(idx);
|
bFound = true;
|
}
|
}
|
|
if (nSelectedRecipeID != -1 && !bFound) {
|
pCombo->SetCurSel(CB_ERR);
|
}
|
else if (pCombo->GetCount() > 0 && nSelectedRecipeID == -1) {
|
pCombo->SetCurSel(0);
|
}
|
|
return true;
|
}
|
|
bool CRecipeDeviceBindDlg::FillDeviceInfo(int idx, int nDeviceID, const CString& strDeviceName, int nSelectedRecipeID)
|
{
|
if (idx < 0 || idx >= (int)m_vecDevices.size()) {
|
return false;
|
}
|
|
auto& ctrl = m_vecDevices[idx];
|
CString strID;
|
strID.Format(_T("%d"), nDeviceID);
|
ctrl.editDeviceID->SetWindowText(strID);
|
ctrl.editDeviceID->SetReadOnly(TRUE);
|
ctrl.editDeviceName->SetWindowText(strDeviceName);
|
ctrl.editDeviceName->SetReadOnly(TRUE);
|
|
if (!FillComboRecipeList(ctrl.comboRecipeID, nDeviceID, nSelectedRecipeID)) {
|
CString str;
|
str.Format(_T("设备 [%s] 或其配方列表未找到,请检查设备配置"), strDeviceName.GetString());
|
AfxMessageBox(str);
|
return false;
|
}
|
return true;
|
}
|
|
void CRecipeDeviceBindDlg::DoDataExchange(CDataExchange* pDX)
|
{
|
CDialogEx::DoDataExchange(pDX);
|
DDX_Text(pDX, IDC_EDIT_PPID, m_strPPID);
|
DDX_Text(pDX, IDC_EDIT_DESC, m_strDesc);
|
}
|
|
BEGIN_MESSAGE_MAP(CRecipeDeviceBindDlg, CDialogEx)
|
ON_WM_CLOSE()
|
ON_WM_SIZE()
|
ON_BN_CLICKED(IDOK, &CRecipeDeviceBindDlg::OnBnClickedOk)
|
END_MESSAGE_MAP()
|
|
|
// CRecipeDeviceBindDlg 消息处理程序
|
|
BOOL CRecipeDeviceBindDlg::OnInitDialog()
|
{
|
CDialogEx::OnInitDialog();
|
|
// 设置对话框标题
|
SetWindowText(m_recipe.vecDeviceList.empty() ? _T("新建配方") : _T("编辑配方"));
|
|
// 创建动态控件字体
|
if (!m_font.m_hObject) {
|
CFont* pDlgFont = GetFont();
|
LOGFONT lf;
|
if (pDlgFont && pDlgFont->GetLogFont(&lf)) {
|
lf.lfHeight = -16;
|
m_font.CreateFontIndirect(&lf);
|
}
|
}
|
|
// 计算坐标
|
CRect rDesc;
|
int nXStart = 30, nYStart = 30, nTotalControlWidth = 340;
|
if (auto* pWndDesc = GetDlgItem(IDC_STATIC_DESC)) {
|
pWndDesc->GetWindowRect(&rDesc); ScreenToClient(&rDesc);
|
nXStart = rDesc.left;
|
}
|
if (auto* pWndEdit = GetDlgItem(IDC_EDIT_DESC)) {
|
pWndEdit->GetWindowRect(&rDesc); ScreenToClient(&rDesc);
|
nYStart = rDesc.bottom + 20;
|
}
|
CRect rClient; GetClientRect(&rClient);
|
nTotalControlWidth = rClient.Width() - nXStart * 2;
|
const int nRowHeight = 30;
|
|
// 清空旧控件
|
ReleaseDeviceControls();
|
|
// 创建新控件
|
CreateDeviceControls(nXStart, nYStart, nTotalControlWidth, nRowHeight);
|
|
auto& master = theApp.m_model.getMaster();
|
|
// 填充内容
|
if (m_recipe.vecDeviceList.empty()) {
|
// 新建
|
for (size_t i = 0; i < g_vecBindDevices.size(); ++i) {
|
const auto& meta = g_vecBindDevices[i];
|
FillDeviceInfo((int)i, meta.nDeviceID, meta.strDeviceName);
|
}
|
}
|
else {
|
// 编辑
|
m_strPPID = CA2T(m_recipe.strPPID.c_str());
|
m_strDesc = CA2T(m_recipe.strDescription.c_str());
|
UpdateData(FALSE);
|
|
for (size_t i = 0; i < m_recipe.vecDeviceList.size() && i < m_vecDevices.size(); ++i) {
|
const auto& d = m_recipe.vecDeviceList[i];
|
FillDeviceInfo((int)i, d.nDeviceID, d.strDeviceName.c_str(), d.nRecipeID);
|
}
|
}
|
|
CenterWindow();
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
// 异常: OCX 属性页应返回 FALSE
|
}
|
|
void CRecipeDeviceBindDlg::OnClose()
|
{
|
// TODO: 在此添加消息处理程序代码和/或调用默认值
|
CDialogEx::OnClose();
|
|
// 清理控件
|
ReleaseDeviceControls();
|
}
|
|
void CRecipeDeviceBindDlg::OnSize(UINT nType, int cx, int cy)
|
{
|
CDialogEx::OnSize(nType, cx, cy);
|
|
// TODO: 在此处添加消息处理程序代码
|
}
|
|
void CRecipeDeviceBindDlg::OnBnClickedOk()
|
{
|
// TODO: 在此添加控件通知处理程序代码
|
UpdateData(TRUE);
|
|
// 收集所有设备映射
|
m_recipe.vecDeviceList.clear();
|
for (const auto& dev : m_vecDevices) {
|
DeviceRecipe info;
|
CString strID, strName;
|
dev.editDeviceID->GetWindowText(strID);
|
dev.editDeviceName->GetWindowText(strName);
|
|
int sel = dev.comboRecipeID->GetCurSel();
|
info.nRecipeID = -1;
|
if (sel != CB_ERR) {
|
info.nRecipeID = (int)dev.comboRecipeID->GetItemData(sel);
|
}
|
info.nDeviceID = _ttoi(strID);
|
info.strDeviceName = CT2A(strName);
|
|
m_recipe.vecDeviceList.push_back(info);
|
}
|
|
// 检查 PPID 是否为空
|
if (m_strPPID.IsEmpty()) {
|
AfxMessageBox(_T("配方 PPID 不能为空"));
|
return;
|
}
|
|
// PPID和描述
|
m_recipe.strPPID = CT2A(m_strPPID);
|
m_recipe.strDescription = CT2A(m_strDesc);
|
|
CDialogEx::OnOK();
|
}
|