| SourceCode/Bond/Servo/CControlJobDlg.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/CControlJobDlg.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/CExpandableListCtrl.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/CExpandableListCtrl.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/Servo.rc | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/Servo.vcxproj | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/Servo.vcxproj.filters | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/ServoDlg.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/resource.h | 补丁 | 查看 | 原始文档 | blame | 历史 |
SourceCode/Bond/Servo/CControlJobDlg.cpp
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,73 @@ // CControlJobDlg.cpp: å®ç°æä»¶ // #include "stdafx.h" #include "Servo.h" #include "CControlJobDlg.h" #include "afxdialogex.h" // CControlJobDlg å¯¹è¯æ¡ IMPLEMENT_DYNAMIC(CControlJobDlg, CDialogEx) CControlJobDlg::CControlJobDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_DIALOG_CONTROL_JOB, pParent) { } CControlJobDlg::~CControlJobDlg() { } void CControlJobDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST1, m_listCtrl); } BEGIN_MESSAGE_MAP(CControlJobDlg, CDialogEx) END_MESSAGE_MAP() // CControlJobDlg æ¶æ¯å¤çç¨åº BOOL CControlJobDlg::OnInitDialog() { CDialogEx::OnInitDialog(); DWORD dwStyle = m_listCtrl.GetExtendedStyle(); dwStyle |= LVS_EX_FULLROWSELECT; dwStyle |= LVS_EX_GRIDLINES; m_listCtrl.SetExtendedStyle(dwStyle); HIMAGELIST imageList = ImageList_Create(24, 24, ILC_COLOR24, 1, 1); ListView_SetImageList(m_listCtrl.GetSafeHwnd(), imageList, LVSIL_SMALL); // m_list å·²ç»æ¯å¯¹è¯æ¡ä¸ç CExpandableListCtrl æåï¼ææ§ä»¶æ¹ç±»ï¼ m_listCtrl.ModifyStyle(0, LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS); m_listCtrl.InsertColumn(0, _T("åç§°"), LVCFMT_LEFT, 260); m_listCtrl.InsertColumn(1, _T("ç¶æ"), LVCFMT_LEFT, 120); m_listCtrl.InsertColumn(2, _T("æè¿°"), LVCFMT_LEFT, 260); auto* root1 = m_listCtrl.InsertRoot({ _T("EFEM"), _T("Ready"), _T("Front End Module") }); m_listCtrl.InsertChild(root1, { _T("Slot #1"), _T("OK"), _T("150mm wafer") }); m_listCtrl.InsertChild(root1, { _T("Slot #2"), _T("Empty"), _T("") }); auto* root2 = m_listCtrl.InsertRoot({ _T("Bonder"), _T("Run"), _T("G1+G2 Process") }); auto* ch21 = m_listCtrl.InsertChild(root2, { _T("Job A"), _T("Proc"), _T("Step 1") }); m_listCtrl.InsertChild(ch21, { _T("SubStep A1"), _T("Done"), _T("Align") }); m_listCtrl.InsertChild(ch21, { _T("SubStep A2"), _T("Run"), _T("Bond") }); // åå§è®©é¡¶å±å±å¼ //root1->expanded = true; //root2->expanded = true; m_listCtrl.RebuildVisible(); return TRUE; // return TRUE unless you set the focus to a control // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE } SourceCode/Bond/Servo/CControlJobDlg.h
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,30 @@ #pragma once #include "CExpandableListCtrl.h" // CControlJobDlg å¯¹è¯æ¡ class CControlJobDlg : public CDialogEx { DECLARE_DYNAMIC(CControlJobDlg) public: CControlJobDlg(CWnd* pParent = nullptr); // æ åæé 彿° virtual ~CControlJobDlg(); protected: CExpandableListCtrl m_listCtrl; // å¯¹è¯æ¡æ°æ® #ifdef AFX_DESIGN_TIME enum { IDD = IDD_DIALOG_CONTROL_JOB }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); }; SourceCode/Bond/Servo/CExpandableListCtrl.cpp
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,217 @@ #include "stdafx.h" #include "CExpandableListCtrl.h" IMPLEMENT_DYNAMIC(CExpandableListCtrl, CListCtrl) CExpandableListCtrl::CExpandableListCtrl() {} CExpandableListCtrl::~CExpandableListCtrl() {} BEGIN_MESSAGE_MAP(CExpandableListCtrl, CListCtrl) ON_WM_CREATE() ON_NOTIFY_REFLECT(NM_CLICK, &CExpandableListCtrl::OnClick) ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CExpandableListCtrl::OnCustomDraw) END_MESSAGE_MAP() int CExpandableListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CListCtrl::OnCreate(lpCreateStruct) == -1) return -1; // æ¥è¡¨é£æ ¼åä¸¾ä¾ SetExtendedStyle(GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_EX_GRIDLINES); // 示ä¾åï¼å¯å¨å¤é¨è®¾ç½®ï¼ if (GetHeaderCtrl() == nullptr || GetHeaderCtrl()->GetItemCount() == 0) { InsertColumn(0, _T("åç§°"), LVCFMT_LEFT, 260); InsertColumn(1, _T("ç¶æ"), LVCFMT_LEFT, 120); InsertColumn(2, _T("æè¿°"), LVCFMT_LEFT, 260); } return 0; } CExpandableListCtrl::Node* CExpandableListCtrl::InsertRoot(const std::vector<CString>& cols) { auto n = std::make_unique<Node>((int)max(1, (int)cols.size())); for (size_t i = 0; i < cols.size(); ++i) n->cols[i] = cols[i]; n->level = 0; Node* raw = n.get(); m_roots.emplace_back(std::move(n)); return raw; } CExpandableListCtrl::Node* CExpandableListCtrl::InsertChild(Node* parent, const std::vector<CString>& cols) { ASSERT(parent); auto n = std::make_unique<Node>((int)max(1, (int)cols.size())); for (size_t i = 0; i < cols.size(); ++i) n->cols[i] = cols[i]; n->parent = parent; n->level = parent->level + 1; Node* raw = n.get(); parent->children.emplace_back(std::move(n)); return raw; } void CExpandableListCtrl::appendVisible(Node* n) { m_visible.push_back(n); if (n->expanded) { for (auto& ch : n->children) { appendVisible(ch.get()); } } } void CExpandableListCtrl::RebuildVisible() { // 1) é建å¯è§åºå m_visible.clear(); for (auto& r : m_roots) appendVisible(r.get()); // 2) éç»/éå¡«æ°æ® SetRedraw(FALSE); DeleteAllItems(); // æå ¥å¯è§è¡ for (int i = 0; i < (int)m_visible.size(); ++i) { Node* n = m_visible[i]; LVITEM lvi{}; lvi.mask = LVIF_TEXT; lvi.iItem = i; lvi.iSubItem = 0; lvi.pszText = const_cast<LPTSTR>((LPCTSTR)(n->cols.empty() ? _T("") : n->cols[0])); InsertItem(&lvi); for (int col = 1; col < GetHeaderCtrl()->GetItemCount(); ++col) { CString txt = (col < (int)n->cols.size()) ? n->cols[col] : _T(""); SetItemText(i, col, txt); } } SetRedraw(TRUE); Invalidate(); } void CExpandableListCtrl::Expand(Node* n) { if (!n || n->children.empty()) return; if (!n->expanded) { n->expanded = true; RebuildVisible(); } } void CExpandableListCtrl::Collapse(Node* n) { if (!n || n->children.empty()) return; if (n->expanded) { n->expanded = false; RebuildVisible(); } } void CExpandableListCtrl::Toggle(Node* n) { if (!n || n->children.empty()) return; n->expanded = !n->expanded; RebuildVisible(); } CExpandableListCtrl::Node* CExpandableListCtrl::GetNodeByVisibleIndex(int i) const { if (i < 0 || i >= (int)m_visible.size()) return nullptr; return m_visible[i]; } CRect CExpandableListCtrl::expanderRectForRow(int row) const { CRect rc; // åé¦åç©å½¢ if (!GetSubItemRect(row, 0, LVIR_BOUNDS, rc)) return CRect(0, 0, 0, 0); Node* n = const_cast<CExpandableListCtrl*>(this)->GetNodeByVisibleIndex(row); int indent = (n ? n->level : 0); // 缩è¿ï¼æ¯çº§ç» 16px int left = rc.left + m_expanderPadding + indent * 16; CRect box(left, rc.CenterPoint().y - m_expanderSize / 2, left + m_expanderSize, rc.CenterPoint().y + m_expanderSize / 2); return box; } void CExpandableListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult) { LPNMITEMACTIVATE pia = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); if (pia->iItem >= 0) { CPoint pt = pia->ptAction; // å½ä¸å±å¼æé®ï¼ CRect expRc = expanderRectForRow(pia->iItem); if (expRc.PtInRect(pt)) { Node* n = GetNodeByVisibleIndex(pia->iItem); if (n && !n->children.empty()) { Toggle(n); } } } *pResult = 0; } void CExpandableListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) { LPNMLVCUSTOMDRAW pCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR); switch (pCD->nmcd.dwDrawStage) { case CDDS_PREPAINT: *pResult = CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYSUBITEMDRAW; return; case CDDS_ITEMPREPAINT: *pResult = CDRF_NOTIFYSUBITEMDRAW; return; case CDDS_ITEMPREPAINT | CDDS_SUBITEM: { int row = (int)pCD->nmcd.dwItemSpec; int col = pCD->iSubItem; CDC* pDC = CDC::FromHandle(pCD->nmcd.hdc); // ä» å¨é¦åç»å¶å±å¼æé®ä¸ç¼©è¿å¼å¯¼ if (col == 0) { CRect rc; GetSubItemRect(row, 0, LVIR_BOUNDS, rc); // é»è®¤ææ¬è®©ç³»ç»ç»ï¼æä»¬å ç»æé®å缩è¿èæ¯ï¼åè¿å CDRF_DODEFAULT Node* n = GetNodeByVisibleIndex(row); if (n) { // ç»å¶å±å¼ä¸è§/æ¹å if (!n->children.empty()) { CRect box = expanderRectForRow(row); // å°æ¹æ¡ pDC->Rectangle(box); // ç»â+âæâ-â CPen pen(PS_SOLID, 1, RGB(0, 0, 0)); CPen* oldPen = pDC->SelectObject(&pen); // 横线 pDC->MoveTo(box.left + 2, box.CenterPoint().y); pDC->LineTo(box.right - 2, box.CenterPoint().y); if (!n->expanded) { // ç«çº¿ï¼è¡¨ç¤º + å·ï¼ pDC->MoveTo(box.CenterPoint().x, box.top + 2); pDC->LineTo(box.CenterPoint().x, box.bottom - 2); } pDC->SelectObject(oldPen); } // æææ¬å·¦è¾¹çå³ç§»ï¼çåºç¼©è¿ä¸æé®ç©ºé´ // è¿é䏿¹ç³»ç»ç»å¶çææ¬èµ·ç¹ï¼èæ¯éè¿å¨ææ¬åç½®ç©ºæ ¼çæ¹å¼å¤çæ´ç®åï¼ // æä»¬ç´æ¥æ¹æ¾ç¤ºææ¬ï¼æ§è½è¶³å¤ï¼ï¼å¨ RebuildVisible æ¶å·²ç»å¡«äºçº¯ææ¬ã // å¦æä½ è¦ç²¾åæ§å¶ææ¬ä½ç½®ï¼å¯ä»¥æ¹ OWNERDRAW æèªç»ææ¬ã } } *pResult = CDRF_DODEFAULT; return; } } *pResult = CDRF_DODEFAULT; } SourceCode/Bond/Servo/CExpandableListCtrl.h
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,57 @@ #pragma once #include <vector> #include <memory> class CExpandableListCtrl : public CListCtrl { DECLARE_DYNAMIC(CExpandableListCtrl) public: struct Node { Node* parent = nullptr; std::vector<std::unique_ptr<Node>> children; std::vector<CString> cols; // ååææ¬ bool expanded = false; int level = 0; // 缩è¿å±çº§ Node(int nCols = 1) : cols(nCols) {} }; CExpandableListCtrl(); virtual ~CExpandableListCtrl(); // æ°æ®æå»º Node* InsertRoot(const std::vector<CString>& cols); Node* InsertChild(Node* parent, const std::vector<CString>& cols); // å±å¼/æå void Expand(Node* n); void Collapse(Node* n); void Toggle(Node* n); // å·æ°å¯è§å表 void RebuildVisible(); // 便æ·ï¼éè¿å¯è§è¡å·å Node* Node* GetNodeByVisibleIndex(int i) const; protected: // æ¶æ¯ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult); DECLARE_MESSAGE_MAP() private: std::vector<std::unique_ptr<Node>> m_roots; // é¡¶å±èç¹ std::vector<Node*> m_visible; // å±å¼åçå¯è§èç¹é¡ºåº int m_expanderPadding = 6; // é¦åå ä¾§è¾¹è· int m_expanderSize = 10; // å°ä¸è§/æ¹åå¤§å° int m_textGap = 6; void appendVisible(Node* n); CRect expanderRectForRow(int row) const; // é¦åå±å¼æé®åºå }; SourceCode/Bond/Servo/Servo.rcBinary files differ
SourceCode/Bond/Servo/Servo.vcxproj
@@ -202,9 +202,11 @@ <ItemGroup> <ClInclude Include="CBaseDlg.h" /> <ClInclude Include="CControlJob.h" /> <ClInclude Include="CControlJobDlg.h" /> <ClInclude Include="CCustomCheckBox.h" /> <ClInclude Include="CCollectionEvent.h" /> <ClInclude Include="CEquipmentPage3.h" /> <ClInclude Include="CExpandableListCtrl.h" /> <ClInclude Include="CGlassPool.h" /> <ClInclude Include="ChangePasswordDlg.h" /> <ClInclude Include="CMyStatusbar.h" /> @@ -354,9 +356,11 @@ <ItemGroup> <ClCompile Include="CBaseDlg.cpp" /> <ClCompile Include="CControlJob.cpp" /> <ClCompile Include="CControlJobDlg.cpp" /> <ClCompile Include="CCustomCheckBox.cpp" /> <ClCompile Include="CCollectionEvent.cpp" /> <ClCompile Include="CEquipmentPage3.cpp" /> <ClCompile Include="CExpandableListCtrl.cpp" /> <ClCompile Include="CGlassPool.cpp" /> <ClCompile Include="ChangePasswordDlg.cpp" /> <ClCompile Include="CMyStatusbar.cpp" /> SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -178,6 +178,8 @@ <ClCompile Include="CPageCollectionEvent.cpp" /> <ClCompile Include="ProcessJob.cpp" /> <ClCompile Include="CControlJob.cpp" /> <ClCompile Include="CExpandableListCtrl.cpp" /> <ClCompile Include="CControlJobDlg.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="AlarmManager.h" /> @@ -362,6 +364,8 @@ <ClInclude Include="ProcessJob.h" /> <ClInclude Include="CControlJob.h" /> <ClInclude Include="SerializeUtil.h" /> <ClInclude Include="CExpandableListCtrl.h" /> <ClInclude Include="CControlJobDlg.h" /> </ItemGroup> <ItemGroup> <ResourceCompile Include="Servo.rc" /> SourceCode/Bond/Servo/ServoDlg.cpp
@@ -26,6 +26,7 @@ #include "CPageVarialbles.h" #include "CPageReport.h" #include "CPageCollectionEvent.h" #include "CControlJobDlg.h" #ifdef _DEBUG @@ -979,7 +980,8 @@ } } else if (id == IDC_BUTTON_JOBS) { AfxMessageBox("IDC_BUTTON_CJOBS"); CControlJobDlg dlg; dlg.DoModal(); } else if (id == IDC_BUTTON_PORT_CONFIG) { CPortConfigurationDlg dlg; SourceCode/Bond/Servo/resource.hBinary files differ