From 8e2b7558c6dce11bfbb144a5d6bf329d41d43827 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期三, 17 九月 2025 17:35:34 +0800
Subject: [PATCH] 1.调整CControlJobManagerDlg的版面;
---
SourceCode/Bond/Servo/CCjPage2.cpp | 129 +++-
SourceCode/Bond/Servo/Servo.vcxproj | 2
SourceCode/Bond/Servo/CCarrierSlotGrid.cpp | 902 +++++++++++++++++++++++++++++++++++++
SourceCode/Bond/Servo/Servo.vcxproj.filters | 2
SourceCode/Bond/Servo/resource.h | 0
SourceCode/Bond/Servo/CCarrierSlotGrid.h | 160 ++++++
SourceCode/Bond/Servo/CCjPage2.h | 12
SourceCode/Bond/Servo/Servo.rc | 0
SourceCode/Bond/Servo/CControlJobManagerDlg.h | 7
SourceCode/Bond/Servo/CControlJobManagerDlg.cpp | 173 +-----
SourceCode/Bond/Servo/CLoadPort.cpp | 2
11 files changed, 1,204 insertions(+), 185 deletions(-)
diff --git a/SourceCode/Bond/Servo/CCarrierSlotGrid.cpp b/SourceCode/Bond/Servo/CCarrierSlotGrid.cpp
new file mode 100644
index 0000000..f26ed7f
--- /dev/null
+++ b/SourceCode/Bond/Servo/CCarrierSlotGrid.cpp
@@ -0,0 +1,902 @@
+#include "stdafx.h"
+#include "CCarrierSlotGrid.h"
+#include <gdiplus.h>
+#pragma comment(lib, "gdiplus.lib")
+
+using namespace Gdiplus;
+
+#define SAFE_PORT(p) ((p) >= 0 && (p) < (int)m_ports.size())
+#define SAFE_SLOT(s) ((s) >= 0 && (s) < m_nSlots)
+
+static bool s_gdiplusInited = false;
+static ULONG_PTR s_gdiplusToken = 0;
+static void EnsureGdiplus()
+{
+ if (!s_gdiplusInited)
+ {
+ GdiplusStartupInput in;
+ if (GdiplusStartup(&s_gdiplusToken, &in, nullptr) == Ok)
+ s_gdiplusInited = true;
+ }
+}
+
+BEGIN_MESSAGE_MAP(CCarrierSlotGrid, CWnd)
+ ON_WM_ERASEBKGND()
+ ON_WM_PAINT()
+ ON_WM_CREATE()
+ ON_WM_SIZE()
+ ON_WM_HSCROLL()
+ ON_WM_VSCROLL() // ★ 新增
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
+ ON_WM_MOUSEWHEEL()
+ ON_WM_MOUSEMOVE()
+ ON_WM_SETCURSOR()
+ ON_WM_SHOWWINDOW()
+ ON_WM_WINDOWPOSCHANGED()
+END_MESSAGE_MAP()
+
+CCarrierSlotGrid::CCarrierSlotGrid() {}
+CCarrierSlotGrid::~CCarrierSlotGrid()
+{
+ if ((HFONT)m_fntText) m_fntText.DeleteObject();
+ if ((HFONT)m_fntBold) m_fntBold.DeleteObject();
+ if ((HFONT)m_fntSmall) m_fntSmall.DeleteObject();
+}
+
+void CCarrierSlotGrid::PreSubclassWindow()
+{
+ CWnd::PreSubclassWindow();
+ if (GetParent() && GetParent()->GetFont()) SetFont(GetParent()->GetFont());
+ EnsureFonts();
+ EnsureGdiplus();
+ // 确保样式包含滚动条
+ ModifyStyle(0, WS_HSCROLL | WS_VSCROLL, 0);
+ SetWindowPos(nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+}
+
+int CCarrierSlotGrid::OnCreate(LPCREATESTRUCT cs)
+{
+ if (CWnd::OnCreate(cs) == -1) return -1;
+ if (GetParent() && GetParent()->GetFont()) SetFont(GetParent()->GetFont());
+ EnsureFonts();
+ EnsureGdiplus();
+ ModifyStyle(0, WS_HSCROLL | WS_VSCROLL, 0);
+ return 0;
+}
+
+void CCarrierSlotGrid::EnsureFonts()
+{
+ if ((HFONT)m_fntText) return;
+
+ LOGFONT lf{}; bool ok = false;
+ if (GetParent() && GetParent()->GetFont()) { GetParent()->GetFont()->GetLogFont(&lf); ok = true; }
+ else if (GetFont()) { GetFont()->GetLogFont(&lf); ok = true; }
+ else {
+ NONCLIENTMETRICS ncm = { 0 }; ncm.cbSize = sizeof(NONCLIENTMETRICS);
+ if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)) { lf = ncm.lfMessageFont; ok = true; }
+ }
+ if (!ok) { CFont* pDef = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)); pDef->GetLogFont(&lf); }
+
+ m_fntText.CreateFontIndirect(&lf);
+ LOGFONT lfb = lf; lfb.lfWeight = FW_SEMIBOLD; m_fntBold.CreateFontIndirect(&lfb);
+ LOGFONT lfs = lf; lfs.lfHeight = (LONG)(lf.lfHeight * 0.9); if (lfs.lfHeight == 0) lfs.lfHeight = lf.lfHeight - 1; m_fntSmall.CreateFontIndirect(&lfs);
+}
+
+void CCarrierSlotGrid::InitGrid(int nPorts, int nSlots)
+{
+ ASSERT(nPorts >= 1 && nSlots >= 1);
+ m_ports.assign(nPorts, PortColumn{});
+ m_portColCXs.assign(nPorts, 180);
+ m_nSlots = nSlots;
+ for (auto& pc : m_ports) pc.slots.assign(m_nSlots, SlotCell{});
+ UpdateScrollRange();
+ Invalidate(FALSE);
+}
+
+void CCarrierSlotGrid::SetColumnWidths(int slotColWidth, int portColWidth)
+{
+ if (slotColWidth > 0) m_slotColCX = slotColWidth;
+ if (portColWidth > 0)
+ for (size_t i = 0; i < m_portColCXs.size(); ++i) m_portColCXs[i] = portColWidth;
+ UpdateScrollRange();
+ Invalidate(FALSE);
+}
+
+void CCarrierSlotGrid::SetRowHeight(int cy) { m_rowHeight = max(18, min(cy, 64)); UpdateScrollRange(); Invalidate(FALSE); }
+void CCarrierSlotGrid::SetHeaderHeight(int cy) { m_headerCY = max(20, min(cy, 48)); UpdateScrollRange(); Invalidate(FALSE); }
+void CCarrierSlotGrid::SetShowMaterialToggle(BOOL bShow) { m_bShowMatToggle = bShow; Invalidate(FALSE); }
+
+void CCarrierSlotGrid::SetPortInfo(int portIndex, LPCTSTR portName, LPCTSTR carrierName)
+{
+ if (!SAFE_PORT(portIndex)) return;
+ if (portName) m_ports[portIndex].portName = portName;
+ if (carrierName) m_ports[portIndex].carrierName = carrierName;
+ Invalidate(FALSE);
+}
+
+void CCarrierSlotGrid::SetPortAllocated(int portIndex, BOOL allocated, LPCTSTR byName)
+{
+ if (!SAFE_PORT(portIndex)) return;
+ auto& pc = m_ports[portIndex];
+ pc.allocated = !!allocated;
+ pc.allocatedBy = byName ? byName : _T("");
+ if (pc.allocated)
+ for (auto& cell : pc.slots) cell.checked = false;
+ Invalidate(FALSE);
+}
+
+BOOL CCarrierSlotGrid::IsPortAllocated(int portIndex) const
+{
+ if (!SAFE_PORT(portIndex)) return FALSE; return m_ports[portIndex].allocated;
+}
+
+void CCarrierSlotGrid::SetSlotGlass(int portIndex, int slotIndex, BOOL hasGlass, LPCTSTR coreId, int material)
+{
+ if (!SAFE_PORT(portIndex) || !SAFE_SLOT(slotIndex)) return;
+ auto& cell = m_ports[portIndex].slots[slotIndex];
+ cell.hasGlass = !!hasGlass;
+ cell.coreId = coreId ? coreId : _T("");
+ cell.material = (material == MAT_G2) ? MAT_G2 : MAT_G1;
+ if (!cell.hasGlass) cell.checked = false;
+ Invalidate(FALSE);
+}
+
+void CCarrierSlotGrid::SetSlotChecked(int portIndex, int slotIndex, BOOL checked)
+{
+ if (!SAFE_PORT(portIndex) || !SAFE_SLOT(slotIndex)) return;
+ auto& pc = m_ports[portIndex];
+ if (pc.allocated) return;
+ auto& cell = pc.slots[slotIndex];
+ if (!cell.hasGlass) return;
+ cell.checked = !!checked;
+ NotifySelectionChanged(portIndex, slotIndex, cell.checked);
+ Invalidate(FALSE);
+}
+
+BOOL CCarrierSlotGrid::GetSlotChecked(int portIndex, int slotIndex) const
+{
+ if (!SAFE_PORT(portIndex) || !SAFE_SLOT(slotIndex)) return FALSE;
+ return m_ports[portIndex].slots[slotIndex].checked ? TRUE : FALSE;
+}
+
+int CCarrierSlotGrid::GetSlotMaterialType(int portIndex, int slotIndex) const
+{
+ if (!SAFE_PORT(portIndex) || !SAFE_SLOT(slotIndex)) return MAT_G1;
+ return m_ports[portIndex].slots[slotIndex].material;
+}
+
+void CCarrierSlotGrid::SetSlotMaterialType(int portIndex, int slotIndex, int material, BOOL bNotify)
+{
+ if (!SAFE_PORT(portIndex) || !SAFE_SLOT(slotIndex)) return;
+ auto& pc = m_ports[portIndex];
+ if (pc.allocated) return;
+ auto& cell = pc.slots[slotIndex];
+ if (!cell.hasGlass) return;
+ int mt = (material == MAT_G2) ? MAT_G2 : MAT_G1;
+ if (cell.material != mt) {
+ cell.material = mt;
+ if (bNotify) NotifyMaterialChanged(portIndex, slotIndex, cell.material);
+ Invalidate(FALSE);
+ }
+}
+
+CString CCarrierSlotGrid::GetDisplayId(int portIndex, int slotIndex) const
+{
+ CString s(_T("—"));
+ if (!SAFE_PORT(portIndex) || !SAFE_SLOT(slotIndex)) return s;
+ const auto& cell = m_ports[portIndex].slots[slotIndex];
+ if (!cell.hasGlass) return s;
+ s.Format(_T("G%d-%s"), (cell.material == MAT_G2) ? 2 : 1, cell.coreId.GetString());
+ return s;
+}
+
+void CCarrierSlotGrid::CheckAllInPort(int portIndex, BOOL checked, BOOL bNotify)
+{
+ if (!SAFE_PORT(portIndex)) return;
+ auto& pc = m_ports[portIndex];
+ if (pc.allocated) return;
+ for (int r = 0; r < m_nSlots; ++r) {
+ auto& cell = pc.slots[r];
+ if (!cell.hasGlass) continue;
+ if (cell.checked != !!checked) {
+ cell.checked = !!checked;
+ if (bNotify) NotifySelectionChanged(portIndex, r, cell.checked);
+ }
+ }
+ Invalidate(FALSE);
+}
+
+void CCarrierSlotGrid::RebuildTexts() { Invalidate(FALSE); }
+
+CSize CCarrierSlotGrid::CalcBestClientSize(int nSlotsOverride) const
+{
+ const int slots = (nSlotsOverride > 0) ? nSlotsOverride : m_nSlots;
+ int w = m_slotColCX;
+ for (int cx : m_portColCXs) w += cx;
+ int h = m_headerCY + slots * m_rowHeight;
+ return CSize(w, h);
+}
+
+CSize CCarrierSlotGrid::CalcBestWindowSize(BOOL includeNonClient, int nSlotsOverride) const
+{
+ CSize cli = CalcBestClientSize(nSlotsOverride);
+ if (!includeNonClient) return cli;
+
+ RECT rc = { 0, 0, cli.cx, cli.cy };
+
+ // 目标是“刚好不出现滚动条”的窗口外框大小:
+ // 用当前样式去掉 WS_HSCROLL/WS_VSCROLL 再做 AdjustWindowRectEx
+ DWORD style = GetStyle();
+ DWORD exStyle = GetExStyle();
+ style &= ~(WS_HSCROLL | WS_VSCROLL);
+
+ ::AdjustWindowRectEx(&rc, style, FALSE, exStyle);
+ return CSize(rc.right - rc.left, rc.bottom - rc.top);
+}
+
+// ---------- 几何 ----------
+CRect CCarrierSlotGrid::GetClientRectNoSB() const
+{
+ CRect rc; GetClientRect(&rc); return rc;
+}
+CRect CCarrierSlotGrid::GetHeaderRect() const
+{
+ CRect rc = GetClientRectNoSB(); rc.bottom = rc.top + m_headerCY; return rc;
+}
+int CCarrierSlotGrid::GetTotalContentWidth() const
+{
+ int w = m_slotColCX;
+ for (int cx : m_portColCXs) w += cx;
+ return w;
+}
+CRect CCarrierSlotGrid::GetHeaderItemRect(int iItem) const
+{
+ CRect rcHeader = GetHeaderRect();
+ int x = rcHeader.left - m_scrollX;
+ if (iItem == 0)
+ return CRect(x, rcHeader.top, x + m_slotColCX, rcHeader.bottom);
+
+ x += m_slotColCX;
+ for (int c = 1; c < iItem; ++c) x += m_portColCXs[c - 1];
+ int w = m_portColCXs[iItem - 1];
+ return CRect(x, rcHeader.top, x + w, rcHeader.bottom);
+}
+BOOL CCarrierSlotGrid::GetCellRect(int row, int sub, CRect& rc) const
+{
+ CRect cli = GetClientRectNoSB();
+ int y0 = cli.top + m_headerCY - m_scrollY;
+ int top = y0 + row * m_rowHeight;
+ int bottom = top + m_rowHeight;
+ if (bottom <= cli.top + m_headerCY || top >= cli.bottom) return FALSE;
+
+ int x = cli.left - m_scrollX;
+ if (sub == 0) { rc = CRect(x, top, x + m_slotColCX, bottom); return TRUE; }
+ x += m_slotColCX;
+ for (int c = 1; c < sub; ++c) x += m_portColCXs[c - 1];
+ int w = m_portColCXs[sub - 1];
+ rc = CRect(x, top, x + w, bottom);
+ return TRUE;
+}
+CRect CCarrierSlotGrid::GetHeaderCheckboxRect(int iItem) const
+{
+ CRect rItem = GetHeaderItemRect(iItem);
+ const int box = 16;
+ const int padR = 6;
+ int vpad = max(0, (rItem.Height() - box) / 2);
+ return CRect(rItem.right - padR - box, rItem.top + vpad, rItem.right - padR, rItem.bottom - vpad);
+}
+CRect CCarrierSlotGrid::GetCheckboxRect(const CRect& cell) const
+{
+ int sz = max(14, min(int(m_rowHeight * 0.70), 20));
+ int leftPad = 8;
+ int top = cell.top + (cell.Height() - sz) / 2;
+ return CRect(cell.left + leftPad, top, cell.left + leftPad + sz, top + sz);
+}
+CRect CCarrierSlotGrid::GetMaterialTagRect(const CRect& cell) const
+{
+ int h = max(14, min(int(m_rowHeight * 0.65), m_rowHeight - 8));
+ int w = 32;
+ int gap = 6;
+ int rightPadForDot = 16;
+ int top = cell.top + (cell.Height() - h) / 2;
+ int right = cell.right - rightPadForDot - gap;
+ return CRect(right - w, top, right, top + h);
+}
+CRect CCarrierSlotGrid::GetStatusDotRect(const CRect& cell) const
+{
+ int d = max(8, min(int(m_rowHeight * 0.42), 12));
+ int rightPad = 6;
+ int top = cell.top + (cell.Height() - d) / 2;
+ return CRect(cell.right - rightPad - d, top, cell.right - rightPad, top + d);
+}
+
+void CCarrierSlotGrid::UpdateScrollRange()
+{
+ CRect rc; GetClientRect(&rc);
+
+ // 垂直
+ const int contentH = m_headerCY + m_nSlots * m_rowHeight;
+ const int pageY = max(1, rc.Height());
+ const int maxPosY = max(0, contentH - pageY);
+ m_scrollY = max(0, min(m_scrollY, maxPosY));
+ SCROLLINFO siY = { sizeof(SCROLLINFO) };
+ siY.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+ siY.nMin = 0; siY.nMax = contentH - 1; siY.nPage = pageY; siY.nPos = m_scrollY;
+ SetScrollInfo(SB_VERT, &siY, TRUE);
+
+ // 水平
+ const int contentW = GetTotalContentWidth();
+ const int pageX = max(1, rc.Width());
+ const int maxPosX = max(0, contentW - pageX);
+ m_scrollX = max(0, min(m_scrollX, maxPosX));
+ SCROLLINFO siX = { sizeof(SCROLLINFO) };
+ siX.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+ siX.nMin = 0; siX.nMax = contentW - 1; siX.nPage = pageX; siX.nPos = m_scrollX;
+ SetScrollInfo(SB_HORZ, &siX, TRUE);
+}
+
+// ---------- 表头分隔线命中 ----------
+int CCarrierSlotGrid::HitHeaderEdge(CPoint pt) const
+{
+ if (!m_bAllowResize) return -1; // ← 新增
+ if (!GetHeaderRect().PtInRect(pt)) return -1;
+ const int tol = 4;
+ int x = GetHeaderRect().left - m_scrollX + m_slotColCX;
+ if (abs(pt.x - x) <= tol) return 0;
+
+ int cum = GetHeaderRect().left - m_scrollX + m_slotColCX;
+ for (int i = 0; i <= GetPortCount() - 2; ++i) {
+ cum += m_portColCXs[i];
+ if (abs(pt.x - cum) <= tol) return i + 1;
+ }
+ return -1;
+}
+
+// ---------- 绘制 ----------
+BOOL CCarrierSlotGrid::OnEraseBkgnd(CDC* /*pDC*/) { return TRUE; }
+
+void CCarrierSlotGrid::DrawFlatCheckbox(CDC* pDC, const CRect& r, bool checked, bool disabled)
+{
+ CBrush br(disabled ? RGB(245, 245, 245) : RGB(255, 255, 255));
+ CPen pen(PS_SOLID, 1, disabled ? RGB(200, 200, 200) : RGB(130, 130, 135));
+ CBrush* pOldB = pDC->SelectObject(&br);
+ CPen* pOldP = pDC->SelectObject(&pen);
+ pDC->RoundRect(r, CPoint(3, 3));
+ pDC->SelectObject(pOldB); pDC->SelectObject(pOldP);
+
+ if (!checked) return;
+ COLORREF c = disabled ? RGB(160, 160, 160) : RGB(40, 150, 90);
+ CPen penTick(PS_SOLID, max(2, r.Height() / 8), c);
+ CPen* pOld = pDC->SelectObject(&penTick);
+ POINT p1 = { r.left + r.Width() * 2 / 9, r.top + r.Height() * 5 / 9 };
+ POINT p2 = { r.left + r.Width() * 4 / 9, r.top + r.Height() * 7 / 9 };
+ POINT p3 = { r.left + r.Width() * 7 / 9, r.top + r.Height() * 3 / 9 };
+ pDC->MoveTo(p1); pDC->LineTo(p2); pDC->LineTo(p3);
+ pDC->SelectObject(pOld);
+}
+
+void CCarrierSlotGrid::PaintTo(CDC* pDC)
+{
+ EnsureGdiplus();
+
+ CRect cli = GetClientRectNoSB();
+ pDC->FillSolidRect(cli, m_colBg);
+
+ // Header
+ CRect rh = GetHeaderRect();
+ pDC->FillSolidRect(rh, ::GetSysColor(COLOR_BTNFACE));
+ CPen penSep(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
+ CPen* pOldPen = pDC->SelectObject(&penSep);
+ pDC->MoveTo(rh.left, rh.bottom - 1); pDC->LineTo(rh.right, rh.bottom - 1);
+ pDC->SelectObject(pOldPen);
+
+ for (int i = 0; i <= GetPortCount(); ++i)
+ {
+ CRect rItem = GetHeaderItemRect(i);
+
+ // 修改为:
+ if (i < GetPortCount()) { // ★ 最后一列不画分隔线
+ CPen pen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
+ pOldPen = pDC->SelectObject(&pen);
+ pDC->MoveTo(rItem.right - 1, rItem.top);
+ pDC->LineTo(rItem.right - 1, rItem.bottom);
+ pDC->SelectObject(pOldPen);
+ }
+
+ CString text;
+ if (i == 0) {
+ text = _T("Slot");
+ CRect rt = rItem; rt.DeflateRect(6, 0, 6, 0);
+ pDC->SetBkMode(TRANSPARENT);
+ pDC->SelectObject(&m_fntBold);
+ pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
+ pDC->DrawText(text, rt, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
+ }
+ else {
+ const auto& pc = m_ports[i - 1];
+ int selected = 0; bool any = false, all = true;
+ for (const auto& cell : pc.slots) {
+ if (cell.hasGlass) { any = true; if (cell.checked) ++selected; else all = false; }
+ }
+ if (!any) all = false;
+
+ CString leftTitle = pc.carrierName.IsEmpty()
+ ? pc.portName
+ : (pc.portName + _T(" (") + pc.carrierName + _T(")"));
+
+ // 勾选框靠右
+ CRect rcCb = GetHeaderCheckboxRect(i);
+ DrawFlatCheckbox(pDC, rcCb, all, pc.allocated);
+
+ // 计数贴近勾选框左侧
+ CString cnt; cnt.Format(_T("%d/%d"), selected, m_nSlots);
+ SIZE szCnt{ 0,0 };
+ { CFont* o = pDC->SelectObject(&m_fntBold);
+ GetTextExtentPoint32(pDC->GetSafeHdc(), cnt, cnt.GetLength(), &szCnt);
+ pDC->SelectObject(o); }
+ const int gap = 6;
+ CRect rcCnt(rcCb.left - gap - szCnt.cx, rItem.top, rcCb.left - gap, rItem.bottom);
+
+ // 左侧标题
+ CRect rt = rItem; rt.DeflateRect(6, 0, (rItem.right - rcCnt.left) + 6, 0);
+ pDC->SetBkMode(TRANSPARENT);
+ pDC->SelectObject(&m_fntBold);
+ pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
+ pDC->DrawText(leftTitle, rt, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
+
+ // 计数
+ pDC->SelectObject(&m_fntBold);
+ pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
+ pDC->DrawText(cnt, rcCnt, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
+ }
+ }
+
+ // Cells
+ for (int r = 0; r < m_nSlots; ++r)
+ {
+ for (int s = 0; s <= GetPortCount(); ++s)
+ {
+ CRect rc;
+ if (!GetCellRect(r, s, rc)) continue;
+
+ COLORREF bk = m_colBg;
+ if (s >= 1) {
+ int port = s - 1;
+ if (port % 2 == 0) bk = m_colAlt;
+ if (SAFE_PORT(port) && m_ports[port].allocated) bk = m_colLock;
+ }
+ pDC->FillSolidRect(rc, bk);
+
+ CPen penMajor(PS_SOLID, (s >= 1 && ((s - 1) % 2 == 0)) ? 2 : 1, m_gridMajor);
+ CPen* pOld = pDC->SelectObject(&penMajor);
+ pDC->MoveTo(rc.left, rc.top); pDC->LineTo(rc.right, rc.top);
+ pDC->MoveTo(rc.left, rc.top); pDC->LineTo(rc.left, rc.bottom);
+ pDC->SelectObject(pOld);
+
+ CPen penMinor(PS_SOLID, 1, m_gridMinor);
+ pOld = pDC->SelectObject(&penMinor);
+ if (s == GetPortCount()) { pDC->MoveTo(rc.right - 1, rc.top); pDC->LineTo(rc.right - 1, rc.bottom); }
+ if (r == m_nSlots - 1) { pDC->MoveTo(rc.left, rc.bottom - 1); pDC->LineTo(rc.right, rc.bottom - 1); }
+ pDC->SelectObject(pOld);
+
+ if (s == 0) {
+ CString sl; sl.Format(_T("Slot %d"), r + 1);
+ CRect rt = rc; rt.DeflateRect(8, 0, 8, 0);
+ pDC->SelectObject(&m_fntBold);
+ pDC->SetBkMode(TRANSPARENT);
+ pDC->SetTextColor(RGB(60, 60, 64));
+ pDC->DrawText(sl, rt, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ else {
+ int port = s - 1;
+ const auto& pc = m_ports[port];
+ const auto& cell = pc.slots[r];
+
+ CRect rChk = GetCheckboxRect(rc);
+ DrawFlatCheckbox(pDC, rChk, cell.checked, pc.allocated || !cell.hasGlass);
+
+ CString t = GetDisplayId(port, r);
+ CRect rText = rc;
+ int leftPad = rChk.right + 6;
+ CRect rDot = GetStatusDotRect(rc);
+ CRect rTag = GetMaterialTagRect(rc);
+ int rightPad = rc.right - min(rTag.left - 6, rDot.left - 6);
+ rText.DeflateRect(leftPad - rc.left, 0, rightPad, 0);
+
+ pDC->SelectObject(&m_fntText);
+ pDC->SetBkMode(TRANSPARENT);
+ pDC->SetTextColor(cell.hasGlass ? m_text : m_textDim);
+ pDC->DrawText(t, rText, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
+
+ if (m_bShowMatToggle)
+ {
+ CRect rT = GetMaterialTagRect(rc);
+ COLORREF crBorder = (cell.material == MAT_G2) ? RGB(180, 150, 220) : RGB(120, 160, 220);
+ COLORREF crFill = (cell.material == MAT_G2) ? RGB(243, 235, 250) : RGB(233, 240, 252);
+ COLORREF crText = (cell.material == MAT_G2) ? RGB(90, 60, 150) : RGB(50, 90, 160);
+ if (pc.allocated || !cell.hasGlass) { crBorder = RGB(210, 210, 210); crFill = RGB(245, 245, 245); crText = RGB(160, 160, 160); }
+ CBrush br(crFill); CPen tagPen(PS_SOLID, 1, crBorder);
+ CPen* pOldP = pDC->SelectObject(&tagPen);
+ CBrush* pOldB = pDC->SelectObject(&br);
+ pDC->RoundRect(rT, CPoint(6, 6));
+ pDC->SelectObject(pOldB); pDC->SelectObject(pOldP);
+ CString tx; tx.Format(_T("G%d"), (cell.material == MAT_G2) ? 2 : 1);
+ pDC->SelectObject(&m_fntSmall);
+ pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(crText);
+ pDC->DrawText(tx, rT, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ }
+
+ // 状态点(GDI+ 抗锯齿)
+ {
+ Graphics g(pDC->GetSafeHdc());
+ g.SetSmoothingMode(SmoothingModeAntiAlias);
+ COLORREF c = cell.hasGlass ? (pc.allocated ? RGB(215, 160, 60) : RGB(60, 170, 80)) : RGB(160, 160, 160);
+ SolidBrush brush(Color(255, GetRValue(c), GetGValue(c), GetBValue(c)));
+ Pen outline(Color(255, 120, 120, 120), 1.f);
+ g.FillEllipse(&brush, rDot.left, rDot.top, rDot.Width(), rDot.Height());
+ g.DrawEllipse(&outline, (REAL)rDot.left, (REAL)rDot.top, (REAL)rDot.Width(), (REAL)rDot.Height());
+ }
+ }
+ }
+ }
+
+
+
+// ===== 在每个已分配(allocated)的列中央绘制半透明 LOCK 水印(用 HDC+LOGFONT 构造字体)=====
+ {
+ Gdiplus::Graphics g(pDC->GetSafeHdc());
+ g.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+
+ CRect cli = GetClientRectNoSB();
+ CRect rh = GetHeaderRect();
+
+ // 取当前 UI 字体(优先粗体)
+ LOGFONT lf{};
+ if ((HFONT)m_fntBold) m_fntBold.GetLogFont(&lf);
+ else if ((HFONT)m_fntText) m_fntText.GetLogFont(&lf);
+
+ for (int i = 0; i < GetPortCount(); ++i)
+ {
+ if (!m_ports[i].allocated) continue;
+
+ // 列矩形(除去表头,考虑水平滚动)
+ CRect rCol = GetHeaderItemRect(i + 1);
+ rCol.top = rh.bottom;
+ rCol.bottom = cli.bottom;
+ if (rCol.right <= cli.left || rCol.left >= cli.right || rCol.Height() <= 0) continue;
+
+ // 自适应一个合适的像素高度
+ int availW = rCol.Width() - 12;
+ int availH = rCol.Height() - 12;
+ int emPx = max(16, min(min(availW / 3, availH / 5), 72));
+ if (emPx < 16) emPx = 16;
+ // 字号减半(并给个更低的兜底,避免太小)
+ emPx = max(12, emPx / 2);
+
+ // 用 LOGFONTW + HDC 构造 GDI+ 字体
+ LOGFONTW lfw{};
+#ifdef UNICODE
+ lfw = *reinterpret_cast<LOGFONTW*>(&lf);
+#else
+ lfw.lfHeight = lf.lfHeight;
+ lfw.lfWidth = lf.lfWidth;
+ lfw.lfEscapement = lf.lfEscapement;
+ lfw.lfOrientation = lf.lfOrientation;
+ lfw.lfWeight = lf.lfWeight;
+ lfw.lfItalic = lf.lfItalic;
+ lfw.lfUnderline = lf.lfUnderline;
+ lfw.lfStrikeOut = lf.lfStrikeOut;
+ lfw.lfCharSet = lf.lfCharSet;
+ lfw.lfOutPrecision = lf.lfOutPrecision;
+ lfw.lfClipPrecision = lf.lfClipPrecision;
+ lfw.lfQuality = lf.lfQuality;
+ lfw.lfPitchAndFamily = lf.lfPitchAndFamily;
+ MultiByteToWideChar(CP_ACP, 0, lf.lfFaceName, -1, lfw.lfFaceName, LF_FACESIZE);
+#endif
+ lfw.lfHeight = -emPx; // 负值=按像素高度
+ lfw.lfWeight = FW_BOLD;
+
+ Gdiplus::Font gdifont(pDC->GetSafeHdc(), &lfw); // ★ 加上 Gdiplus::
+ Gdiplus::StringFormat fmt;
+ fmt.SetAlignment(Gdiplus::StringAlignmentCenter);
+ fmt.SetLineAlignment(Gdiplus::StringAlignmentCenter);
+ Gdiplus::Color col(140, 120, 100, 60); // 半透明
+ Gdiplus::SolidBrush brush(col);
+ Gdiplus::RectF box((Gdiplus::REAL)rCol.left, (Gdiplus::REAL)rCol.top,
+ (Gdiplus::REAL)rCol.Width(), (Gdiplus::REAL)rCol.Height());
+
+ if (gdifont.GetLastStatus() == Gdiplus::Ok) {
+ g.DrawString(L"LOCK", -1, &gdifont, box, &fmt, &brush);
+ }
+ else {
+ Gdiplus::Font fallback(L"Arial", (Gdiplus::REAL)emPx, Gdiplus::FontStyleBold, Gdiplus::UnitPixel);
+ g.DrawString(L"LOCK", -1, &fallback, box, &fmt, &brush);
+ }
+ }
+ }
+
+ // === 客户区内 1px 灰色边框(不包滚动条,但不会缺角/抢绘制)===
+ {
+ CRect cli; GetClientRect(&cli);
+
+ // 用 FrameRect 更稳(避免右下角丢线)
+ CBrush br; br.CreateSolidBrush(::GetSysColor(COLOR_3DSHADOW));
+ CRect r = cli;
+ // 注意:客户区坐标是 [0..width, 0..height];FrameRect 会在内侧画 1px
+ pDC->FrameRect(&r, &br);
+ br.DeleteObject();
+ }
+}
+
+void CCarrierSlotGrid::OnPaint()
+{
+ CPaintDC dc(this);
+ CRect rc; GetClientRect(&rc);
+
+ CDC mem; mem.CreateCompatibleDC(&dc);
+ CBitmap bmp; bmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
+ HGDIOBJ ob = mem.SelectObject(bmp);
+
+ PaintTo(&mem);
+ dc.BitBlt(0, 0, rc.Width(), rc.Height(), &mem, 0, 0, SRCCOPY);
+
+ mem.SelectObject(ob);
+}
+
+void CCarrierSlotGrid::OnSize(UINT nType, int cx, int cy)
+{
+ CWnd::OnSize(nType, cx, cy);
+ UpdateScrollRange();
+ Invalidate(FALSE);
+ RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
+}
+
+void CCarrierSlotGrid::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pBar)
+{
+ UNREFERENCED_PARAMETER(pBar);
+
+ SCROLLINFO si = { sizeof(SCROLLINFO) };
+ si.fMask = SIF_ALL;
+ GetScrollInfo(SB_HORZ, &si);
+
+ int pos = m_scrollX;
+ const int maxPos = max(0, (int)si.nMax - (int)si.nPage + 1);
+
+ switch (nSBCode)
+ {
+ case SB_LINELEFT: pos -= 30; break;
+ case SB_LINERIGHT: pos += 30; break;
+ case SB_PAGELEFT: pos -= (int)si.nPage; break;
+ case SB_PAGERIGHT: pos += (int)si.nPage; break;
+ case SB_THUMBTRACK:
+ case SB_THUMBPOSITION:
+ pos = (int)si.nTrackPos; // ★ 32 位拖动位置
+ break;
+ default:
+ return;
+ }
+
+ pos = max(0, min(pos, maxPos));
+ if (pos != m_scrollX) {
+ m_scrollX = pos;
+ SetScrollPos(SB_HORZ, m_scrollX);
+ Invalidate(FALSE);
+ }
+}
+
+void CCarrierSlotGrid::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pBar)
+{
+ UNREFERENCED_PARAMETER(pBar);
+
+ SCROLLINFO si = { sizeof(SCROLLINFO) };
+ si.fMask = SIF_ALL;
+ GetScrollInfo(SB_VERT, &si);
+
+ int pos = m_scrollY;
+ const int maxPos = max(0, (int)si.nMax - (int)si.nPage + 1);
+
+ switch (nSBCode)
+ {
+ case SB_LINEUP: pos -= m_rowHeight; break;
+ case SB_LINEDOWN: pos += m_rowHeight; break;
+ case SB_PAGEUP: pos -= (int)si.nPage; break;
+ case SB_PAGEDOWN: pos += (int)si.nPage; break;
+ case SB_THUMBTRACK:
+ case SB_THUMBPOSITION:
+ pos = (int)si.nTrackPos; // ★ 32 位拖动位置
+ break;
+ default:
+ return;
+ }
+
+ pos = max(0, min(pos, maxPos));
+ if (pos != m_scrollY) {
+ m_scrollY = pos;
+ SetScrollPos(SB_VERT, m_scrollY);
+ Invalidate(FALSE);
+ }
+}
+
+BOOL CCarrierSlotGrid::OnMouseWheel(UINT, short zDelta, CPoint)
+{
+ int delta = (zDelta > 0 ? -1 : +1) * (m_rowHeight * 3);
+ m_scrollY = max(0, m_scrollY + delta);
+ UpdateScrollRange();
+ Invalidate(FALSE);
+ return TRUE;
+}
+
+void CCarrierSlotGrid::OnShowWindow(BOOL bShow, UINT nStatus)
+{
+ CWnd::OnShowWindow(bShow, nStatus);
+ if (bShow) { UpdateScrollRange(); Invalidate(FALSE); }
+}
+
+void CCarrierSlotGrid::OnWindowPosChanged(WINDOWPOS* wp)
+{
+ CWnd::OnWindowPosChanged(wp);
+ if (wp && (wp->flags & SWP_SHOWWINDOW)) { UpdateScrollRange(); Invalidate(FALSE); }
+}
+
+void CCarrierSlotGrid::OnLButtonDown(UINT nFlags, CPoint pt)
+{
+ // 是否拖动列宽
+ int edge = m_bAllowResize ? HitHeaderEdge(pt) : -1; // ← 修改
+ if (edge >= 0)
+ {
+ m_bResizing = true;
+ m_resizeEdge = edge;
+ m_resizeStartX = pt.x;
+ m_slotColCXStart = m_slotColCX;
+ m_portColCXsStart = m_portColCXs;
+ SetCapture();
+ return;
+ }
+
+ // Header 点击(仅复选框区域)
+ if (GetHeaderRect().PtInRect(pt))
+ {
+ for (int i = 1; i <= GetPortCount(); ++i)
+ {
+ CRect rItem = GetHeaderItemRect(i);
+ if (!rItem.PtInRect(pt)) continue;
+
+ CRect rcCb = GetHeaderCheckboxRect(i);
+ if (!rcCb.PtInRect(pt)) return;
+
+ int port = i - 1;
+ if (!SAFE_PORT(port) || m_ports[port].allocated) return;
+
+ bool any = false, all = true;
+ for (auto& cell : m_ports[port].slots) {
+ if (!cell.hasGlass) continue;
+ any = true; if (!cell.checked) { all = false; break; }
+ }
+ if (!any) return;
+ CheckAllInPort(port, all ? FALSE : TRUE, TRUE);
+ return;
+ }
+ return;
+ }
+
+ // Cell 点击
+ CRect cli = GetClientRectNoSB();
+ if (pt.y < cli.top + m_headerCY) return;
+ int yIn = pt.y - (cli.top + m_headerCY) + m_scrollY;
+ int row = yIn / m_rowHeight;
+ if (!SAFE_SLOT(row)) return;
+
+ int x = pt.x + m_scrollX - cli.left;
+ int sub = 0;
+ if (x < m_slotColCX) sub = 0;
+ else {
+ x -= m_slotColCX;
+ sub = 1;
+ for (size_t i = 0; i < m_portColCXs.size(); ++i) {
+ if (x < m_portColCXs[i]) { sub = (int)i + 1; break; }
+ x -= m_portColCXs[i];
+ sub = (int)i + 2;
+ }
+ if (sub < 1 || sub > GetPortCount()) return;
+ }
+
+ if (sub == 0) return;
+ int port = sub - 1;
+ if (!SAFE_PORT(port)) return;
+
+ auto& pc = m_ports[port];
+ auto& cell = pc.slots[row];
+
+ CRect rc; if (!GetCellRect(row, sub, rc)) return;
+
+ if (pc.allocated || !cell.hasGlass) return;
+
+ if (GetCheckboxRect(rc).PtInRect(pt))
+ {
+ cell.checked = !cell.checked;
+ NotifySelectionChanged(port, row, cell.checked);
+ Invalidate(FALSE);
+ return;
+ }
+
+ if (m_bShowMatToggle && GetMaterialTagRect(rc).PtInRect(pt))
+ {
+ cell.material = (cell.material == MAT_G1) ? MAT_G2 : MAT_G1;
+ NotifyMaterialChanged(port, row, cell.material);
+ Invalidate(FALSE);
+ return;
+ }
+
+ CWnd::OnLButtonDown(nFlags, pt);
+}
+
+void CCarrierSlotGrid::OnLButtonUp(UINT nFlags, CPoint pt)
+{
+ if (m_bResizing)
+ {
+ ReleaseCapture();
+ m_bResizing = false;
+ m_resizeEdge = -1;
+ UpdateScrollRange();
+ Invalidate(FALSE);
+ }
+ CWnd::OnLButtonUp(nFlags, pt);
+}
+
+void CCarrierSlotGrid::OnMouseMove(UINT nFlags, CPoint pt)
+{
+ if (m_bResizing)
+ {
+ int dx = pt.x - m_resizeStartX;
+ if (m_resizeEdge == 0)
+ {
+ int nw = max(m_slotColMin, m_slotColCXStart + dx);
+ if (nw != m_slotColCX) { m_slotColCX = nw; UpdateScrollRange(); Invalidate(FALSE); }
+ }
+ else
+ {
+ int idx = m_resizeEdge - 1; // 调整 Port idx 的宽度
+ int nw = max(m_portColMin, m_portColCXsStart[idx] + dx);
+ if (nw != m_portColCXs[idx]) { m_portColCXs[idx] = nw; UpdateScrollRange(); Invalidate(FALSE); }
+ }
+ return;
+ }
+
+ int edge = HitHeaderEdge(pt);
+ if (edge != m_hitEdgeHover)
+ {
+ m_hitEdgeHover = edge;
+ if (m_hitEdgeHover >= 0) ::SetCursor(::LoadCursor(nullptr, IDC_SIZEWE));
+ else ::SetCursor(::LoadCursor(nullptr, IDC_ARROW));
+ }
+}
+
+BOOL CCarrierSlotGrid::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
+{
+ CPoint pt; ::GetCursorPos(&pt); ScreenToClient(&pt);
+ if (m_bAllowResize && (m_bResizing || HitHeaderEdge(pt) >= 0))
+ {
+ ::SetCursor(::LoadCursor(nullptr, IDC_SIZEWE));
+ return TRUE;
+ }
+ return CWnd::OnSetCursor(pWnd, nHitTest, message);
+}
+
+// ---------- 通知 ----------
+void CCarrierSlotGrid::NotifySelectionChanged(int /*port*/, int /*slot*/, BOOL /*checked*/)
+{
+ if (GetParent())
+ {
+ const int code = 0x2001;
+ GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), code), (LPARAM)m_hWnd);
+ }
+}
+void CCarrierSlotGrid::NotifyMaterialChanged(int /*port*/, int /*slot*/, int /*material*/)
+{
+ if (GetParent())
+ {
+ const int code = 0x2002;
+ GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), code), (LPARAM)m_hWnd);
+ }
+}
diff --git a/SourceCode/Bond/Servo/CCarrierSlotGrid.h b/SourceCode/Bond/Servo/CCarrierSlotGrid.h
new file mode 100644
index 0000000..73b1765
--- /dev/null
+++ b/SourceCode/Bond/Servo/CCarrierSlotGrid.h
@@ -0,0 +1,160 @@
+#include "stdafx.h"
+#pragma once
+
+#include <vector>
+
+#ifndef _AFX
+#include <afxwin.h>
+#endif
+
+class CCarrierSlotGrid : public CWnd
+{
+public:
+ enum MaterialType { MAT_G1 = 1, MAT_G2 = 2 };
+
+ struct SlotCell {
+ bool hasGlass = false;
+ CString coreId;
+ int material = MAT_G1;
+ bool checked = false;
+ };
+ struct PortColumn {
+ CString portName;
+ CString carrierName;
+ bool allocated = false;
+ CString allocatedBy;
+ std::vector<SlotCell> slots;
+ };
+
+public:
+ CCarrierSlotGrid();
+ virtual ~CCarrierSlotGrid();
+
+ BOOL SubclassDlgItem(UINT nID, CWnd* pParent) {
+ BOOL ok = CWnd::SubclassDlgItem(nID, pParent);
+ if (ok) {
+ if (pParent && pParent->GetFont()) SetFont(pParent->GetFont());
+ EnsureFonts();
+ Invalidate(FALSE);
+ }
+ return ok;
+ }
+ virtual void PreSubclassWindow() override;
+
+ // 初始化
+ void InitGrid(int nPorts, int nSlots);
+ void SetColumnWidths(int slotColWidth, int portColWidth);
+ void SetRowHeight(int cy);
+ void SetHeaderHeight(int cy);
+ void SetShowMaterialToggle(BOOL bShow);
+
+ // 读/写
+ int GetPortCount() const { return (int)m_ports.size(); }
+ int GetSlotCount() const { return m_nSlots; }
+
+ void SetPortInfo(int portIndex, LPCTSTR portName, LPCTSTR carrierName);
+ void SetPortAllocated(int portIndex, BOOL allocated, LPCTSTR byName = nullptr);
+ BOOL IsPortAllocated(int portIndex) const;
+
+ void SetSlotGlass(int portIndex, int slotIndex, BOOL hasGlass, LPCTSTR coreId, int material);
+ void SetSlotChecked(int portIndex, int slotIndex, BOOL checked);
+ BOOL GetSlotChecked(int portIndex, int slotIndex) const;
+
+ int GetSlotMaterialType(int portIndex, int slotIndex) const;
+ void SetSlotMaterialType(int portIndex, int slotIndex, int material, BOOL bNotify = TRUE);
+
+ CString GetDisplayId(int portIndex, int slotIndex) const;
+ void CheckAllInPort(int portIndex, BOOL checked, BOOL bNotify = TRUE);
+
+ void RebuildTexts();
+ void EnableColumnResize(BOOL enable) { m_bAllowResize = !!enable; Invalidate(FALSE); }
+
+ // 计算最佳大小:
+// - CalcBestClientSize:内容区域(不含滚动条/非客户区)刚好容纳表头+所有行、全部列
+// - CalcBestWindowSize:在当前窗口样式下,将“内容大小”转换为窗口外框大小(会考虑 WS_BORDER/CLIENTEDGE 等)
+// 默认按“隐藏滚动条”的目标来算(即不把 WS_HSCROLL/WS_VSCROLL 计入调整)
+ CSize CalcBestClientSize(int nSlotsOverride = -1) const;
+ CSize CalcBestWindowSize(BOOL includeNonClient = TRUE, int nSlotsOverride = -1) const;
+
+
+protected:
+ // 数据
+ int m_nSlots = 0;
+ std::vector<PortColumn> m_ports;
+ BOOL m_bShowMatToggle = TRUE;
+
+ // 尺寸/滚动
+ int m_rowHeight = 26;
+ int m_headerCY = 28;
+ int m_slotColCX = 100;
+ std::vector<int> m_portColCXs;
+ int m_scrollY = 0;
+ int m_scrollX = 0;
+ int m_slotColMin = 60;
+ int m_portColMin = 80;
+
+ // 颜色
+ COLORREF m_colBg = RGB(255, 255, 255);
+ COLORREF m_colAlt = RGB(240, 242, 245);
+ COLORREF m_colLock = RGB(255, 244, 214);
+ COLORREF m_gridMajor = RGB(210, 214, 220);
+ COLORREF m_gridMinor = RGB(220, 224, 230);
+ COLORREF m_text = RGB(40, 40, 40);
+ COLORREF m_textDim = RGB(150, 150, 150);
+
+ // 字体
+ CFont m_fntText;
+ CFont m_fntBold;
+ CFont m_fntSmall;
+
+ // 拖动列宽
+ bool m_bResizing = false;
+ int m_resizeEdge = -1; // 0=Slot|Port1;1..N-1=Port i|i+1
+ int m_resizeStartX = 0;
+ int m_slotColCXStart = 0;
+ std::vector<int> m_portColCXsStart;
+ int m_hitEdgeHover = -1;
+ bool m_bAllowResize = true; // ← 新增:是否允许拖动列宽
+
+ // 工具
+ void EnsureFonts();
+ void UpdateScrollRange();
+ int GetTotalContentWidth() const;
+ void NotifySelectionChanged(int port, int slot, BOOL checked);
+ void NotifyMaterialChanged(int port, int slot, int material);
+
+ // 几何
+ CRect GetClientRectNoSB() const;
+ BOOL GetCellRect(int row, int sub, CRect& rc) const; // sub: 0=Slot, 1..N=Port
+ CRect GetHeaderRect() const;
+ CRect GetHeaderItemRect(int iItem) const;
+ CRect GetHeaderCheckboxRect(int iItem) const;
+ CRect GetCheckboxRect(const CRect& cell) const;
+ CRect GetMaterialTagRect(const CRect& cell) const;
+ CRect GetStatusDotRect(const CRect& cell) const;
+ BOOL IsColumnResizeEnabled() const { return m_bAllowResize ? TRUE : FALSE; }
+
+ int HitHeaderEdge(CPoint pt) const;
+
+ // 绘制
+ void DrawFlatCheckbox(CDC* pDC, const CRect& r, bool checked, bool disabled);
+ void PaintTo(CDC* pDC);
+
+protected:
+ // 消息
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnPaint();
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); // ★ 纵向滚动条
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint pt);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint pt);
+ afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint pt);
+ afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+ afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
+ afx_msg void OnWindowPosChanged(WINDOWPOS* wp);
+
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/SourceCode/Bond/Servo/CCjPage2.cpp b/SourceCode/Bond/Servo/CCjPage2.cpp
index b736ba4..3e973a3 100644
--- a/SourceCode/Bond/Servo/CCjPage2.cpp
+++ b/SourceCode/Bond/Servo/CCjPage2.cpp
@@ -32,6 +32,10 @@
ON_WM_DESTROY()
ON_EN_CHANGE(IDC_EDIT_PJ_ID, &CCjPage2::OnEnChangeEditPjId)
ON_CBN_SELCHANGE(IDC_COMBO_RECIPE, &CCjPage2::OnCbnSelchangeComboRecipe)
+ ON_BN_CLICKED(IDC_RADIO1, &CCjPage2::OnBnClickedRadio1)
+ ON_BN_CLICKED(IDC_RADIO2, &CCjPage2::OnBnClickedRadio2)
+ ON_BN_CLICKED(IDC_RADIO3, &CCjPage2::OnBnClickedRadio3)
+ ON_BN_CLICKED(IDC_RADIO4, &CCjPage2::OnBnClickedRadio4)
END_MESSAGE_MAP()
@@ -43,50 +47,32 @@
UpdatePjData();
}
+void CCjPage2::SetExclusionNames(std::vector<std::string>& names)
+{
+ m_exclusionNames = names;
+}
+
BOOL CCjPage2::OnInitDialog()
{
CCjPageBase::OnInitDialog();
- // 鑻ヤ綘鐨勮祫婧愰噷鏈変竴涓崰浣嶇殑 ListCtrl锛堟瘮濡� IDC_LIST1锛夛紝杩欓噷鍋氬瓙绫诲寲锛�
- m_selector.SubclassDlgItem(IDC_LIST_SELECTOR, this);
+ m_grid.SubclassDlgItem(IDC_GRID1, this);
+ m_grid.InitGrid(4, 8);
+ m_grid.SetColumnWidths(100, 220);
+ m_grid.SetRowHeight(28);
+ m_grid.SetHeaderHeight(32);
+ m_grid.EnableColumnResize(FALSE); // 绂佹鎷栧姩鍒楀
- // 鍒濆鍖栵細4 鍒� 脳 8 琛�
- m_selector.InitGrid(4, 8);
- m_selector.SetColumnWidths(100, 180);
- m_selector.SetRowHeight(36);
-
- // 璁剧疆鍒椾俊鎭�
- m_selector.SetPortInfo(0, _T("Port 1"), _T("Carrier A"));
- m_selector.SetPortInfo(1, _T("Port 2"), _T("Carrier B"));
- m_selector.SetPortInfo(2, _T("Port 3"), _T("Carrier C"));
- m_selector.SetPortInfo(3, _T("Port 4"), _T("Carrier D"));
-
- // 璁剧疆閮ㄥ垎 Glass锛堟牳蹇僆D鍥哄畾锛�
- m_selector.SetSlotGlass(0, 0, TRUE, _T("001"), CCarrierSlotSelector::MAT_G1);
- m_selector.SetSlotGlass(0, 1, TRUE, _T("002"), CCarrierSlotSelector::MAT_G1);
- m_selector.SetSlotGlass(0, 3, TRUE, _T("004"), CCarrierSlotSelector::MAT_G1);
-
- m_selector.SetSlotGlass(1, 0, TRUE, _T("101"), CCarrierSlotSelector::MAT_G2);
- m_selector.SetSlotGlass(1, 1, TRUE, _T("102"), CCarrierSlotSelector::MAT_G2);
- m_selector.SetSlotGlass(1, 2, TRUE, _T("103"), CCarrierSlotSelector::MAT_G2);
- m_selector.SetSlotGlass(1, 5, TRUE, _T("106"), CCarrierSlotSelector::MAT_G2);
- m_selector.SetSlotGlass(1, 7, TRUE, _T("108"), CCarrierSlotSelector::MAT_G2);
-
- m_selector.SetSlotGlass(2, 5, TRUE, _T("206"), CCarrierSlotSelector::MAT_G1);
- m_selector.SetSlotGlass(2, 6, TRUE, _T("207"), CCarrierSlotSelector::MAT_G1);
- m_selector.SetSlotGlass(2, 7, TRUE, _T("208"), CCarrierSlotSelector::MAT_G1);
-
- m_selector.SetSlotGlass(3, 0, TRUE, _T("301"), CCarrierSlotSelector::MAT_G1);
-
- // 閿佸畾 Port 1锛堢ず渚嬶級
- m_selector.SetPortAllocated(0, TRUE, _T("ProcessJob 1"));
+ m_grid.SetPortInfo(0, _T("Port 1"), _T(""));
+ m_grid.SetPortInfo(1, _T("Port 2"), _T(""));
+ m_grid.SetPortInfo(2, _T("Port 3"), _T(""));
+ m_grid.SetPortInfo(3, _T("Port 4"), _T(""));
UpdatePjData();
-
-
- ;
+
+
return TRUE; // return TRUE unless you set the focus to a control
// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
}
@@ -101,14 +87,21 @@
void CCjPage2::Resize()
{
CCjPageBase::Resize();
- /*
+
+
CWnd* pItem;
CRect rcClient, rcItem;
GetClientRect(&rcClient);
- pItem = GetDlgItem(IDC_LABEL_TITLE);
+ pItem = GetDlgItem(IDC_GRID1);
pItem->GetWindowRect(&rcItem);
- pItem->MoveWindow(12, 8, rcClient.Width() - 24, rcItem.Height());
- */
+ ScreenToClient(rcItem);
+
+ // 璁╂帶浠剁獥鍙e昂瀵歌嚜鍔ㄥ尮閰嶅綋鍓嶅垪瀹�/琛屾暟锛堜笉鍑虹幇婊氬姩鏉★級
+ if (::IsWindow(m_grid.m_hWnd)) {
+ CSize best = m_grid.CalcBestWindowSize(TRUE); // 璁$畻鍒板惈闈炲鎴峰尯鐨勬渶缁堢獥鍙eぇ灏�
+ pItem->MoveWindow(rcItem.left, rcItem.top, best.cx, best.cy);
+ pItem->Invalidate();
+ }
}
void CCjPage2::OnApply()
@@ -118,8 +111,21 @@
SERVO::CProcessJob* pProcessJob = (SERVO::CProcessJob*)m_pContext;
// 鏇存柊鍚嶇О
+ BOOL bOkName = TRUE;
char szBuffer[256];
GetDlgItemText(IDC_EDIT_PJ_ID, szBuffer, 256);
+ for (auto item : m_exclusionNames) {
+ if (item.compare(std::string(szBuffer)) == 0) {
+ bOkName = FALSE;
+ break;
+ }
+ }
+ if (!bOkName) {
+ AfxMessageBox("涓嶈兘浣跨敤鍜屽叾瀹働rocess Job鐩稿悓鐨処D");
+ return;
+ }
+
+
pProcessJob->setId(std::string(szBuffer));
// 鏇存柊閰嶆柟
@@ -137,8 +143,6 @@
pProcessJob->setRecipe(SERVO::RecipeMethod::NoTuning, recipe);
}
-
-
ContentChanged(1);
@@ -162,6 +166,17 @@
if (idx != CB_ERR) pComboBox->SetCurSel(idx);
}
+ // 绀轰緥锛氳缃甈ort淇℃伅銆侀攣鍒椼�佸~鍏匞lass
+ /*
+ m_grid.SetPortInfo(0, _T("Port 1"), _T(""));
+ m_grid.SetPortInfo(1, _T("Port 2"), _T(""));
+ m_grid.SetPortInfo(2, _T("Port 3"), _T("Carrier C"));
+ m_grid.SetPortInfo(3, _T("Port 4"), _T("Carrier D"));
+ m_grid.SetPortAllocated(2, TRUE, _T("ProcessJob 1"));
+ m_grid.SetSlotGlass(0, 0, TRUE, _T("A00123"), CCarrierSlotGrid::MAT_G1);
+ m_grid.SetSlotGlass(0, 1, TRUE, _T("A00124"), CCarrierSlotGrid::MAT_G1);
+ */
+
m_bContentChangedLock = FALSE;
}
@@ -174,3 +189,35 @@
{
ContentChanged(0);
}
+
+void CCjPage2::OnBnClickedRadio1()
+{
+ m_grid.SetPortAllocated(0, FALSE, _T(""));
+ m_grid.SetPortAllocated(1, TRUE, _T(""));
+ m_grid.SetPortAllocated(2, TRUE, _T(""));
+ m_grid.SetPortAllocated(3, TRUE, _T(""));
+}
+
+void CCjPage2::OnBnClickedRadio2()
+{
+ m_grid.SetPortAllocated(0, TRUE, _T(""));
+ m_grid.SetPortAllocated(1, FALSE, _T(""));
+ m_grid.SetPortAllocated(2, TRUE, _T(""));
+ m_grid.SetPortAllocated(3, TRUE, _T(""));
+}
+
+void CCjPage2::OnBnClickedRadio3()
+{
+ m_grid.SetPortAllocated(0, TRUE, _T(""));
+ m_grid.SetPortAllocated(1, TRUE, _T(""));
+ m_grid.SetPortAllocated(2, FALSE, _T(""));
+ m_grid.SetPortAllocated(3, TRUE, _T(""));
+}
+
+void CCjPage2::OnBnClickedRadio4()
+{
+ m_grid.SetPortAllocated(0, TRUE, _T(""));
+ m_grid.SetPortAllocated(1, TRUE, _T(""));
+ m_grid.SetPortAllocated(2, TRUE, _T(""));
+ m_grid.SetPortAllocated(3, FALSE, _T(""));
+}
diff --git a/SourceCode/Bond/Servo/CCjPage2.h b/SourceCode/Bond/Servo/CCjPage2.h
index 5a7338b..c68c377 100644
--- a/SourceCode/Bond/Servo/CCjPage2.h
+++ b/SourceCode/Bond/Servo/CCjPage2.h
@@ -1,7 +1,7 @@
锘�#pragma once
#include "CCjPageBase.h"
#include "ProcessJob.h"
-#include "CCarrierSlotSelector.h"
+#include "CCarrierSlotGrid.h"
// CPjPage1 瀵硅瘽妗�
@@ -14,6 +14,9 @@
CCjPage2(CWnd* pParent = nullptr); // 鏍囧噯鏋勯�犲嚱鏁�
virtual ~CCjPage2();
+public:
+ void SetExclusionNames(std::vector<std::string>& names);
+
protected:
void Resize();
virtual void OnApply();
@@ -23,7 +26,8 @@
void UpdatePjData();
private:
- CCarrierSlotSelector m_selector;
+ CCarrierSlotGrid m_grid;
+ std::vector<std::string> m_exclusionNames;
// 瀵硅瘽妗嗘暟鎹�
#ifdef AFX_DESIGN_TIME
@@ -39,4 +43,8 @@
afx_msg void OnDestroy();
afx_msg void OnEnChangeEditPjId();
afx_msg void OnCbnSelchangeComboRecipe();
+ afx_msg void OnBnClickedRadio1();
+ afx_msg void OnBnClickedRadio2();
+ afx_msg void OnBnClickedRadio3();
+ afx_msg void OnBnClickedRadio4();
};
diff --git a/SourceCode/Bond/Servo/CControlJobManagerDlg.cpp b/SourceCode/Bond/Servo/CControlJobManagerDlg.cpp
index 6783528..da7db7e 100644
--- a/SourceCode/Bond/Servo/CControlJobManagerDlg.cpp
+++ b/SourceCode/Bond/Servo/CControlJobManagerDlg.cpp
@@ -34,7 +34,6 @@
void CControlJobManagerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
- DDX_Control(pDX, IDC_LIST1, m_listBox);
DDX_Control(pDX, IDC_TREE1, m_tree);
}
@@ -42,10 +41,6 @@
BEGIN_MESSAGE_MAP(CControlJobManagerDlg, CDialogEx)
ON_WM_SIZE()
ON_WM_GETMINMAXINFO()
- ON_BN_CLICKED(IDC_BUTTON_CREATE_CJ, &CControlJobManagerDlg::OnBnClickedCreateCJ)
- ON_BN_CLICKED(IDC_BUTTON_CREATE_PJ, &CControlJobManagerDlg::OnBnClickedButtonCreatePj)
- ON_CLBN_CHKCHANGE(IDC_LIST1, &CControlJobManagerDlg::OnListChkChange) // 澶嶉�夌姸鎬佸彉鏇撮�氱煡
- ON_LBN_SELCHANGE(IDC_LIST1, &CControlJobManagerDlg::OnLbnSelchangeList1)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &CControlJobManagerDlg::OnTvnSelchangedTree1)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BUTTON_APPLY, &CControlJobManagerDlg::OnBnClickedButtonApply)
@@ -93,12 +88,12 @@
m_pages.push_back(pPage3);
- // ListBox
- m_listBox.ModifyStyle(0, LBS_OWNERDRAWFIXED | LBS_HASSTRINGS);
- m_listBox.SetCheckStyle(BS_AUTOCHECKBOX);
- m_listBox.SetItemHeight(0, max(22, ::GetSystemMetrics(SM_CYMENUCHECK) + 4));
+ // tree
+ m_tree.ModifyStyle(0, TVS_CHECKBOXES);
+ InitData();
+ UpdateControlJob();
UpdateCtrlState();
Resize();
@@ -131,50 +126,25 @@
// 鍏堢Щ鍔ㄦ寜閽�
- pItem = GetDlgItem(IDC_BUTTON_CREATE_PJ);
- pItem->GetWindowRect(&rcItem);
- pItem->MoveWindow(x, y2 - rcItem.Height(), rcItem.Width(), rcItem.Height());
- x += rcItem.Width();
- x += 8;
-
- pItem = GetDlgItem(IDC_BUTTON_CREATE_CJ);
- pItem->GetWindowRect(&rcItem);
- pItem->MoveWindow(x, y2 - rcItem.Height(), rcItem.Width(), rcItem.Height());
- x += rcItem.Width();
- x += 8;
-
- pItem = GetDlgItem(IDC_BUTTON_BATH_COMPLETION);
- pItem->GetWindowRect(&rcItem);
- pItem->MoveWindow(x, y2 - rcItem.Height(), rcItem.Width(), rcItem.Height());
- x += rcItem.Width();
- x += 8;
-
- pItem = GetDlgItem(IDC_BUTTON_BATH_DELETE);
- pItem->GetWindowRect(&rcItem);
- pItem->MoveWindow(x, y2 - rcItem.Height(), rcItem.Width(), rcItem.Height());
- x += rcItem.Width();
- x += 8;
-
pItem = GetDlgItem(IDC_BUTTON_APPLY);
pItem->GetWindowRect(&rcItem);
pItem->MoveWindow(x2 - rcItem.Width(), y2 - rcItem.Height(), rcItem.Width(), rcItem.Height());
+ x2 -= rcItem.Width();
+ x2 -= 8;
+
+ pItem = GetDlgItem(IDC_BUTTON_BATH_COMPLETION);
+ pItem->GetWindowRect(&rcItem);
+ pItem->MoveWindow(x2 - rcItem.Width(), y2 - rcItem.Height(), rcItem.Width(), rcItem.Height());
+ x += rcItem.Width();
+ x += 8;
+
y2 -= rcItem.Height();
y2 -= 8;
- // 鍒楄〃鎺т欢
- x = 12;
- y = 12;
- pItem = GetDlgItem(IDC_LIST1);
- pItem->MoveWindow(x, y, LEFTWIDTH, 180);
- x += LEFTWIDTH;
- x += 5;
- y += 180;
- y += 5;
-
-
// 鏍戞帶浠�
x = 12;
+ y = 12;
pItem = GetDlgItem(IDC_TREE1);
pItem->MoveWindow(x, y, LEFTWIDTH, y2 - y);
x += LEFTWIDTH;
@@ -182,6 +152,7 @@
// 瀛愰〉闈�
+ x2 = rcClient.right - 12;
for (auto page : m_pages) {
page->MoveWindow(x, 12, x2 - x, y2 - 12);
}
@@ -204,45 +175,7 @@
void CControlJobManagerDlg::UpdateCtrlState()
{
auto& master = theApp.m_model.getMaster();
- auto cj = master.getControlJob();
- GetDlgItem(IDC_BUTTON_CREATE_PJ)->EnableWindow(TRUE);
- GetDlgItem(IDC_BUTTON_CREATE_CJ)->EnableWindow(
- m_pControlJob == nullptr
- );
GetDlgItem(IDC_BUTTON_BATH_COMPLETION)->EnableWindow(false);
- GetDlgItem(IDC_BUTTON_BATH_DELETE)->EnableWindow(true);
-}
-
-
-void CControlJobManagerDlg::OnBnClickedButtonCreatePj()
-{
- static int index = 0;
- char szBuffer[256];
- sprintf_s(szBuffer, 256, "PJ%03d", ++index);
- SERVO::CProcessJob* pj = new SERVO::CProcessJob(std::string(szBuffer));
- m_processJobs.push_back(pj);
- UpdateProcessJobs();
- UpdateCtrlState();
-}
-
-void CControlJobManagerDlg::OnBnClickedCreateCJ()
-{
- if (m_pControlJob != nullptr) {
- return;
- }
-
- m_pControlJob = new SERVO::CControlJob("CJ" + CToolUnits::NowStrSec());
- UpdateControlJob();
- UpdateCtrlState();
-}
-
-void CControlJobManagerDlg::UpdateProcessJobs()
-{
- m_listBox.ResetContent();
- for (auto item : m_processJobs) {
- int index = m_listBox.InsertString(m_listBox.GetCount(), item->id().c_str());
- m_listBox.SetItemDataPtr(index, item);
- }
}
void CControlJobManagerDlg::UpdateControlJob()
@@ -252,31 +185,13 @@
HTREEITEM hRoot = m_tree.InsertItem(m_pControlJob->id().c_str(), 0, 0);
m_tree.SetItemData(hRoot, (DWORD_PTR)m_pControlJob);
- auto& pjs = m_pControlJob->getPjs();
- for (auto pj : pjs) {
+ m_tree.SetItemState(hRoot, 0, TVIS_STATEIMAGEMASK);
+ for (auto pj : m_processJobs) {
HTREEITEM hItem = m_tree.InsertItem(pj->id().c_str(), 0, 0, hRoot);
m_tree.SetItemData(hItem, (DWORD_PTR)pj);
+ m_tree.SetItemState(hItem, INDEXTOSTATEIMAGEMASK(false ? 2 : 1), TVIS_STATEIMAGEMASK);
}
m_tree.Expand(hRoot, TVE_EXPAND);
-}
-
-void CControlJobManagerDlg::OnListChkChange()
-{
- int idx = m_listBox.GetCurSel();
- if (idx != LB_ERR) {
- SERVO::CProcessJob* pj = (SERVO::CProcessJob*)m_listBox.GetItemDataPtr(idx);
- BOOL checked = m_listBox.GetCheck(idx); // 鑻ヤ笁鎬�: 0/1/2
- if (checked) {
- if (AddPorcessJob(pj)) {
- UpdateControlJob();
- }
- }
- else {
- if (RemovePorcessJob(pj)) {
- UpdateControlJob();
- }
- }
- }
}
bool CControlJobManagerDlg::AddPorcessJob(SERVO::CProcessJob* pj)
@@ -289,21 +204,6 @@
{
if (m_pControlJob == nullptr) return false;
return m_pControlJob->removePjPointer(pj->id());
-}
-
-void CControlJobManagerDlg::OnLbnSelchangeList1()
-{
- int idx = m_listBox.GetCurSel();
- if (idx != LB_ERR) {
- SERVO::CProcessJob* pj = (SERVO::CProcessJob*)m_listBox.GetItemDataPtr(idx);
-
- ASSERT(m_pages.size() == 3);
- m_pages[0]->ShowWindow(SW_HIDE);
- m_pages[1]->ShowWindow(SW_SHOW);
- m_pages[2]->ShowWindow(SW_HIDE);
-
- m_pages[1]->SetContext(pj, 1);
- }
}
void CControlJobManagerDlg::OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult)
@@ -325,8 +225,15 @@
m_pages[0]->ShowWindow(SW_HIDE);
m_pages[1]->ShowWindow(SW_SHOW);
m_pages[2]->ShowWindow(SW_HIDE);
-
m_pages[1]->SetContext(pj, 1);
+
+ std::vector<std::string> names;
+ for (auto item : m_processJobs) {
+ if (item != pj) {
+ names.push_back(item->id());
+ }
+ }
+ ((CCjPage2*)m_pages[1])->SetExclusionNames(names);
}
else {
// 鏈夌鍏� 鈫� 绗笁灞傚強浠ヤ笅 鈫� Glass
@@ -346,6 +253,18 @@
}
}
+void CControlJobManagerDlg::InitData()
+{
+ ASSERT(m_pControlJob == nullptr);
+ m_pControlJob = new SERVO::CControlJob("CJ" + CToolUnits::NowStrSec());
+
+ char szBuffer[256];
+ for (int i = 0; i < 4; i++) {
+ sprintf_s(szBuffer, 256, "PJ%03d", i + 1);
+ SERVO::CProcessJob* pj = new SERVO::CProcessJob(std::string(szBuffer));
+ m_processJobs.push_back(pj);
+ }
+}
void CControlJobManagerDlg::OnBnClickedButtonApply()
{
@@ -357,22 +276,6 @@
void CControlJobManagerDlg::UpProcessJobId(SERVO::CProcessJob* pJob)
{
- // 鏇存柊listbox
- int count = m_listBox.GetCount();
- for (int idx = 0; idx < count; idx++) {
- if ((m_listBox.GetItemDataPtr(idx) == (void*)pJob)) {
- BOOL check = m_listBox.GetCheck(idx);
- BOOL wasCurSel = (m_listBox.GetCurSel() == idx); // 鍗曢�夋ā寮�
- m_listBox.DeleteString(idx);
- int newIdx = m_listBox.InsertString(idx, pJob->id().c_str());
- m_listBox.SetItemDataPtr(newIdx, pJob);
- m_listBox.SetCheck(newIdx, check);
- if (wasCurSel) {
- m_listBox.SetCurSel(newIdx);
- }
- }
- }
-
// 鏇存柊鏍戞帶浠�
// 閬嶅巻鏍硅妭鐐�
HTREEITEM hRoot = m_tree.GetRootItem();
diff --git a/SourceCode/Bond/Servo/CControlJobManagerDlg.h b/SourceCode/Bond/Servo/CControlJobManagerDlg.h
index 23d6523..380bdf2 100644
--- a/SourceCode/Bond/Servo/CControlJobManagerDlg.h
+++ b/SourceCode/Bond/Servo/CControlJobManagerDlg.h
@@ -18,17 +18,16 @@
private:
void Resize();
void UpdateCtrlState();
- void UpdateProcessJobs();
void UpdateControlJob();
bool AddPorcessJob(SERVO::CProcessJob* pj);
bool RemovePorcessJob(SERVO::CProcessJob* pj);
void UpProcessJobId(SERVO::CProcessJob* pJob);
+ void InitData();
private:
std::vector<CCjPageBase*> m_pages;
SERVO::CControlJob* m_pControlJob;
std::vector<SERVO::CProcessJob*> m_processJobs;
- CCheckListBox m_listBox;
CApredTreeCtrl2 m_tree;
@@ -45,10 +44,6 @@
virtual BOOL OnInitDialog();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
- afx_msg void OnBnClickedCreateCJ();
- afx_msg void OnBnClickedButtonCreatePj();
- afx_msg void OnListChkChange();
- afx_msg void OnLbnSelchangeList1();
afx_msg void OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDestroy();
afx_msg void OnBnClickedButtonApply();
diff --git a/SourceCode/Bond/Servo/CLoadPort.cpp b/SourceCode/Bond/Servo/CLoadPort.cpp
index 13df4d9..096f845 100644
--- a/SourceCode/Bond/Servo/CLoadPort.cpp
+++ b/SourceCode/Bond/Servo/CLoadPort.cpp
@@ -353,7 +353,7 @@
// 从配置读出的enable,初始化时写给efem
static int i_enable[4] = { 0 };
- if ((++i_enable[m_nIndex]) == 10 + m_nIndex) {
+ if ((++i_enable[m_nIndex]) == 20 + m_nIndex) {
eablePort(m_bEnable, [&](int code) -> int {
LOGI("<LoadPort-%d>eablePort:code=%d", m_nIndex, code);
return 0;
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 4bacf31..0aedf92 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
Binary files differ
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index a80c7ab..4dc50af 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -210,6 +210,7 @@
<ClInclude Include="..\jsoncpp\include\json\writer.h" />
<ClInclude Include="..\jsoncpp\lib_json\json_batchallocator.h" />
<ClInclude Include="CBaseDlg.h" />
+ <ClInclude Include="CCarrierSlotGrid.h" />
<ClInclude Include="CCarrierSlotSelector.h" />
<ClInclude Include="CCjPage2.h" />
<ClInclude Include="CCjPage3.h" />
@@ -393,6 +394,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="CBaseDlg.cpp" />
+ <ClCompile Include="CCarrierSlotGrid.cpp" />
<ClCompile Include="CCarrierSlotSelector.cpp" />
<ClCompile Include="CCjPage2.cpp" />
<ClCompile Include="CCjPage3.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index fb2a15e..b76c3a5 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -205,6 +205,7 @@
<ClCompile Include="CCjPage3.cpp" />
<ClCompile Include="CCjPageBase.cpp" />
<ClCompile Include="CCarrierSlotSelector.cpp" />
+ <ClCompile Include="CCarrierSlotGrid.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AlarmManager.h" />
@@ -435,6 +436,7 @@
<ClInclude Include="CCjPage3.h" />
<ClInclude Include="CCjPageBase.h" />
<ClInclude Include="CCarrierSlotSelector.h" />
+ <ClInclude Include="CCarrierSlotGrid.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Servo.rc" />
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 5a9214e..cf0f3ff 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
Binary files differ
--
Gitblit v1.9.3