// CPageGraph2.cpp: 实现文件 // #include "stdafx.h" #include "Servo.h" #include "CPageGraph2.h" #include "afxdialogex.h" #include "CHMPropertyDlg.h" #include "CEquipmentPage1.h" #include "CEquipmentPage2.h" #include "CEquipmentPage3.h" #include "CPagePortProperty.h" #include "CPagePortStatus.h" #include "CPageCassetteCtrlCmd.h" #include "CJobDataB.h" // CPageGraph2 对话框 IMPLEMENT_DYNAMIC(CPageGraph2, CDialogEx) CPageGraph2::CPageGraph2(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_PAGE_GRAPH2, pParent) { m_pEqsGraphWnd = nullptr; m_crBkgnd = PAGE_GRPAH2_BACKGROUND_COLOR; m_hbrBkgnd = nullptr; m_pObserver = nullptr; } CPageGraph2::~CPageGraph2() { } void CPageGraph2::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CPageGraph2, CDialogEx) ON_WM_CTLCOLOR() ON_WM_DESTROY() ON_WM_SIZE() ON_WM_TIMER() END_MESSAGE_MAP() // CPageGraph2 消息处理程序 void CPageGraph2::InitRxWindows() { /* code */ // 订阅数据 IRxWindows* pRxWindows = RX_GetRxWindows(); pRxWindows->enableLog(5); if (m_pObserver == NULL) { m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void { // onNext pAny->addRef(); int code = pAny->getCode(); if (RX_CODE_EQ_DATA_CHANGED == code) { // 通知设备状态 SERVO::CEquipment* pEquipment = nullptr; if (pAny->getPtrValue("ptr", (void*&)pEquipment)) { if (pEquipment != nullptr) { m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, pEquipment->hasGlass()); } } } pAny->release(); }, [&]() -> void { // onComplete }, [&](IThrowable* pThrowable) -> void { // onErrorm pThrowable->printf(); }); theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread()) ->subscribe(m_pObserver); } } BOOL CPageGraph2::OnInitDialog() { CDialogEx::OnInitDialog(); InitRxWindows(); SetTimer(1, 2000, nullptr); // filter graph wnd EqsGraphListener listener; listener.onCheckConnectPin = [](PIN* pPin1, PIN* pPin2) -> bool { ASSERT(pPin1); ASSERT(pPin2); ASSERT(pPin1->pData); ASSERT(pPin2->pData); return false; }; listener.onConnectPin = [](PIN* pPin1, PIN* pPin2) -> bool { ASSERT(pPin1); ASSERT(pPin2); ASSERT(pPin1->pData); ASSERT(pPin2->pData); return false; }; listener.onDisconnectPin = [](PIN* pPin) -> bool { ASSERT(pPin); ASSERT(pPin->pData); return false; }; listener.onDeleteEqItem = [&](EQITEM* pItem) -> bool { ASSERT(pItem); ASSERT(pItem->pData); return false; }; listener.onEqItemPosChanged = [&](EQITEM* pItem, int x, int y) -> void { ASSERT(pItem); }; listener.onDblckEqItem = [&](EQITEM* pItem) -> bool { ASSERT(pItem); SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; CHMPropertyDlg dlg(pEquipment->getName().c_str(), 658, 788); CEquipmentPage1* pPage1 = new CEquipmentPage1(); pPage1->setEquipment(pEquipment); pPage1->Create(IDD_PAGE_EQUIPMENT1); dlg.addPage(pPage1, "Link Signal"); if (_strcmpi(pEquipment->getClassName(), "CLoadPort") == 0) { CPagePortProperty* pPageA = new CPagePortProperty(); pPageA->setLoadPort((SERVO::CLoadPort*)pEquipment); pPageA->Create(IDD_PAGE_PORT_PROPERTY); dlg.addPage(pPageA, "属性"); CPagePortStatus* pPageB = new CPagePortStatus(); pPageB->setLoadPort((SERVO::CLoadPort*)pEquipment); pPageB->Create(IDD_PAGE_PORT_STATUS); dlg.addPage(pPageB, "Status"); } CEquipmentPage2* pPage2 = new CEquipmentPage2(); pPage2->setEquipment(pEquipment); pPage2->Create(IDD_PAGE_EQUIPMENT2); dlg.addPage(pPage2, "Glass"); if (pEquipment->getID() == EQ_ID_EFEM) { CEquipmentPage3* pPage3 = new CEquipmentPage3(); pPage3->setEquipment(pEquipment); pPage3->Create(IDD_PAGE_EQUIPMENT3); dlg.addPage(pPage3, "Dispatching Mode"); } if (pEquipment->getID() == EQ_ID_LOADPORT1 || pEquipment->getID() == EQ_ID_LOADPORT2) { CPageCassetteCtrlCmd* pPage = new CPageCassetteCtrlCmd(); pPage->setEquipment(pEquipment); pPage->Create(IDD_PAGE_CASSETTE_CTRL_CMD); dlg.addPage(pPage, "Cassette control command"); } dlg.DoModal(); return true; }; listener.onRclickEqItem = [&](EQITEM* pItem) -> bool { ASSERT(pItem); CMenu menu, menuCommand; CMenu* pPopupMenu; menu.LoadMenu(IDR_MENU_EQSGRAPH_ITEM); pPopupMenu = menu.GetSubMenu(0); // 显示模式 pPopupMenu->EnableMenuItem(ID_EQSGRAPHITEM_SMALL, MF_DISABLED | MF_GRAYED); pPopupMenu->EnableMenuItem(ID_EQSGRAPHITEM_NORMAL, MF_DISABLED | MF_GRAYED); pPopupMenu->EnableMenuItem(ID_EQSGRAPHITEM_LARGE, MF_DISABLED | MF_GRAYED); if (pItem->nShowType == ITEM_SMALL) { pPopupMenu->CheckMenuRadioItem(ID_EQSGRAPHITEM_SMALL, ID_EQSGRAPHITEM_LARGE, ID_EQSGRAPHITEM_SMALL, MF_CHECKED); } else if (pItem->nShowType == ITEM_LARGE) { pPopupMenu->CheckMenuRadioItem(ID_EQSGRAPHITEM_SMALL, ID_EQSGRAPHITEM_LARGE, ID_EQSGRAPHITEM_LARGE, MF_CHECKED); } else { pPopupMenu->CheckMenuRadioItem(ID_EQSGRAPHITEM_SMALL, ID_EQSGRAPHITEM_LARGE, ID_EQSGRAPHITEM_NORMAL, MF_CHECKED); } POINT pt; GetCursorPos(&pt); int nCmd = pPopupMenu->TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, this, NULL); if (nCmd == ID_EQSGRAPHITEM_SMALL) { m_pEqsGraphWnd->SetItemType(pItem, ITEM_SMALL); } else if (nCmd == ID_EQSGRAPHITEM_NORMAL) { m_pEqsGraphWnd->SetItemType(pItem, ITEM_NORMAL); } else if (nCmd == ID_EQSGRAPHITEM_LARGE) { m_pEqsGraphWnd->SetItemType(pItem, ITEM_LARGE); } // 测试 else if (nCmd == ID_EQSGRAPHITEM_TEST1) { BOOL bTestGenerate = FALSE; SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; if (pEquipment->getID() == EQ_ID_LOADPORT1 && !pEquipment->hasGlass()) { ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G1, "P20250320G1X", 1); bTestGenerate = TRUE; } else if (pEquipment->getID() == EQ_ID_LOADPORT2 && !pEquipment->hasGlass()) { ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G2, "P20250320G2X", 1); bTestGenerate = TRUE; } if (!bTestGenerate) { SERVO::CRobotTask* pTask = theApp.m_model.getMaster().getActiveRobotTask(); if (pTask != nullptr) { SERVO::CGlass* pGlass = (SERVO::CGlass*)pTask->getContext(); SERVO::CJobDataB* pJobDataB = pGlass->getJobDataB(); SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); if (pJobDataB != nullptr && pJobDataS != nullptr) { pEquipment->onFetchedOutJob(0, pJobDataB); pEquipment->onSentOutJob(0, pJobDataS); } } } } else if (nCmd == ID_EQSGRAPHITEM_TEST2) { SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; SERVO::CArm* pArm = (SERVO::CArm*)pEquipment->getArm(); if (pArm != nullptr) { SERVO::CGlass* pGlass = pArm->getAnyGlass(); if (pGlass != nullptr) { SERVO::CJobDataB* pJobDataB = pGlass->getJobDataB(); SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); if (pJobDataB != nullptr && pJobDataS != nullptr) { pEquipment->onReceivedJob(0, pJobDataS); Sleep(600); pEquipment->onStoredJob(0, pJobDataB); } } } } else if (nCmd == ID_EQSGRAPHITEM_TEST3) { SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; if (pEquipment != nullptr) { SERVO::CGlass* pGlass = pEquipment->getAnyGlass(); if (pGlass != nullptr) { SERVO::CProcessData pd; pd.setGlassId(pGlass->getID().c_str()); pEquipment->onProcessData(&pd); } } } else if (nCmd == ID_EQSGRAPHITEM_TEST4) { SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; if (pEquipment != nullptr) { pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_INLINE, TRUE); pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_TROUBLE, FALSE); pEquipment->setLinkSignal(0, SIGNAL_INTERLOCK, TRUE); pEquipment->setLinkSignal(0, SIGNAL_SEND_ABLE, TRUE); pEquipment->setLinkSignal(1, SIGNAL_UPSTREAM_INLINE, TRUE); pEquipment->setLinkSignal(1, SIGNAL_UPSTREAM_TROUBLE, FALSE); pEquipment->setLinkSignal(1, SIGNAL_INTERLOCK, TRUE); pEquipment->setLinkSignal(1, SIGNAL_SEND_ABLE, TRUE); } if (pEquipment != nullptr && (pEquipment->getID() == EQ_ID_Bonder1 || pEquipment->getID() == EQ_ID_Bonder2)) { SERVO::CGlass* pGlass = pEquipment->getAnyGlass(); if (pGlass != nullptr) { SERVO::CProcessData pd; pd.setGlassId(pGlass->getID().c_str()); pEquipment->onProcessData(&pd); } } } else if (nCmd == ID_EQSGRAPHITEM_TEST5) { SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; if (pEquipment != nullptr) { pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_INLINE, TRUE); pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_TROUBLE, TRUE); pEquipment->setLinkSignal(0, SIGNAL_INTERLOCK, TRUE); pEquipment->setLinkSignal(0, SIGNAL_SEND_ABLE, FALSE); } } else if (nCmd == ID_EQSGRAPHITEM_TEST6) { SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; // 测试下发Cim Message /* if (pEquipment->getID() == EQ_ID_Bonder1 || pEquipment->getID() == EQ_ID_Bonder2) { static int msgId = 0; msgId++; if (msgId % 2 == 0) { pEquipment->setCimMessage("Hello!", msgId, 1); } else { pEquipment->setCimMessage("ABC0123456789", msgId, 2); } } */ // 测试清除Cim Message /* if (pEquipment->getID() == EQ_ID_Bonder1 || pEquipment->getID() == EQ_ID_Bonder2) { static int msgId = 0; msgId++; if (msgId % 2 == 0) { pEquipment->clearCimMessage(msgId, 1); } else { pEquipment->clearCimMessage(msgId, 2); } } */ // 测试设置时间 /* if (pEquipment->getID() == EQ_ID_Bonder1 || pEquipment->getID() == EQ_ID_Bonder2) { CTime time = CTime::GetCurrentTime(); pEquipment->setDateTime((short)time.GetYear(), (short)time.GetMonth(), (short)time.GetDay(), (short)time.GetHour(), (short)time.GetMinute(), (short)time.GetSecond()); } */ // 测试设置cim mode /* if (pEquipment->getID() == EQ_ID_Bonder1 || pEquipment->getID() == EQ_ID_Bonder2) { static int ii = 0; ii++; pEquipment->setCimMode(ii % 2 == 0); } */ if (pEquipment->getID() == EQ_ID_Bonder1 || pEquipment->getID() == EQ_ID_Bonder2) { static int ii = 0; ii++; pEquipment->setEqMode((ii % 5) + 1); } /* SERVO::CGlass* pGlass = pEquipment->getAnyGlass(); if (pGlass != nullptr) { std::string strDescription; SERVO::CPath* pPath = pGlass->getPath(); while (pPath != nullptr) { pPath->getDescription(strDescription); AfxMessageBox(strDescription.c_str()); pPath = pPath->getNext(); } } */ // 请求主配方列表 if (pEquipment != nullptr) { pEquipment->masterRecipeListRequest(0); } } return true; }; listener.onSelectEqItem = [&](EQITEM* pItem) -> bool { ASSERT(pItem); SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; theApp.m_model.notifyPtr(RX_CODE_SELECT_EQUIPMENT, pEquipment); return true; }; m_pEqsGraphWnd = CEqsGraphWnd::FromHandle(GetDlgItem(IDC_EQSGRAPHWND1)->m_hWnd); m_pEqsGraphWnd->SetBkgndColor(m_crBkgnd); m_pEqsGraphWnd->SetOnListener(listener); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } HBRUSH CPageGraph2::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); if (nCtlColor == CTLCOLOR_STATIC) { pDC->SetBkColor(m_crBkgnd); pDC->SetTextColor(RGB(0, 0, 0)); } if (m_hbrBkgnd == nullptr) { m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); } return m_hbrBkgnd; } void CPageGraph2::OnDestroy() { CDialogEx::OnDestroy(); SaveEqsGraphData(); if (m_hbrBkgnd != nullptr) { ::DeleteObject(m_hbrBkgnd); } if (m_pObserver != nullptr) { m_pObserver->unsubscribe(); m_pObserver = NULL; } } void CPageGraph2::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (GetDlgItem(IDC_EQSGRAPHWND1) == nullptr) return; CRect rcClient; GetClientRect(&rcClient); GetDlgItem(IDC_EQSGRAPHWND1)->MoveWindow(0, 0, rcClient.Width(), rcClient.Height()); } #define INPIN 1 #define OUTPIN 2 void CPageGraph2::AddEqToGraphWnd(SERVO::CEquipment* pEquipment) { int x, y; GetItemDataFormIni(pEquipment->getName().c_str(), x, y); EQITEM* pItem = m_pEqsGraphWnd->AddItem(0, pEquipment->getName().c_str(), (DWORD_PTR)pEquipment); m_pEqsGraphWnd->SetItemType(pItem, ITEM_SMALL); if (x > 0 && y > 0) { m_pEqsGraphWnd->SetItemPos(pItem, x, y); } std::vector& inPins = pEquipment->getInputPins(); for (auto inPin : inPins) { m_pEqsGraphWnd->AddPin(pItem, INPIN, inPin->getName().c_str(), (DWORD_PTR)inPin); } std::vector& outPins = pEquipment->getOutputPins(); for (auto outPin : outPins) { m_pEqsGraphWnd->AddPin(pItem, OUTPIN, outPin->getName().c_str(), (DWORD_PTR)outPin); } m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, pEquipment->hasGlass()); } void CPageGraph2::OnTimer(UINT_PTR nIDEvent) { if (1 == nIDEvent) { KillTimer(1); std::list& eqs = theApp.m_model.m_master.getEquipmentList(); for (auto eq : eqs) { AddEqToGraphWnd(eq); } for (auto eq : eqs) { auto& pins = eq->getOutputPins(); for (auto pin : pins) { SERVO::CPin* pPin2 = pin->getConnectedPin(); if (pPin2 != nullptr) { m_pEqsGraphWnd->ConnectPin((DWORD_PTR)eq, (DWORD_PTR)pin, (DWORD_PTR)pPin2->getEquipment(), (DWORD_PTR)pPin2); } } } } CDialogEx::OnTimer(nIDEvent); } void CPageGraph2::SaveEqsGraphData() { char szFilepath[MAX_PATH]; CString strValue; sprintf_s(szFilepath, MAX_PATH, "%s\\EqsGraph.ini", (LPTSTR)(LPCTSTR)theApp.m_strAppDir); std::list& eqs = theApp.m_model.m_master.getEquipmentList(); for (auto item : eqs) { EQITEM* pEqItem = m_pEqsGraphWnd->GetItem((DWORD_PTR)item); if (nullptr == pEqItem) { continue; } strValue.Format(_T("%d"), pEqItem->rect.left); WritePrivateProfileString(item->getName().c_str(), _T("Left"), (LPTSTR)(LPCTSTR)strValue, szFilepath); strValue.Format(_T("%d"), pEqItem->rect.top); WritePrivateProfileString(item->getName().c_str(), _T("Top"), (LPTSTR)(LPCTSTR)strValue, szFilepath); } } void CPageGraph2::GetItemDataFormIni(const char* pszItemName, int& left, int& top) { char szFilepath[MAX_PATH]; CString strValue; sprintf_s(szFilepath, MAX_PATH, "%s\\EqsGraph.ini", (LPTSTR)(LPCTSTR)theApp.m_strAppDir); left = GetPrivateProfileInt(pszItemName, _T("Left"), 0, szFilepath); top = GetPrivateProfileInt(pszItemName, _T("Top"), 0, szFilepath); }