LAPTOP-SNT8I5JK\Boounion
2025-09-13 b17d444a0da9cabf775f90be04d14fac113bb9fb
1.优化代码;
2.增加CControlJobManagerDlg对话框, 准备处理批任务。
已添加6个文件
已修改17个文件
739 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CCjPage1.cpp 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CCjPage1.h 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CControlJob.cpp 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CControlJob.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CControlJobManagerDlg.cpp 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CControlJobManagerDlg.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageCollectionEvent.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageReport.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageVarialbles.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CServoUtilsTool.cpp 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/GroupLabel.cpp 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/GroupLabel.h 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/PageLog.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ProcessJob.cpp 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ProcessJob.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/TerminalDisplayDlg.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CCjPage1.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
// CPjPage1.cpp: å®žçŽ°æ–‡ä»¶
//
#include "stdafx.h"
#include "Servo.h"
#include "CCjPage1.h"
#include "afxdialogex.h"
// CPjPage1 å¯¹è¯æ¡†
IMPLEMENT_DYNAMIC(CCjPage1, CDialogEx)
CCjPage1::CCjPage1(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_CJ_PAGE1, pParent)
{
    m_crBkgnd = RGB(255, 255, 255);
    m_crBkgndCached = CLR_INVALID;
}
CCjPage1::~CCjPage1()
{
}
void CCjPage1::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CCjPage1, CDialogEx)
    ON_WM_CTLCOLOR()
    ON_WM_DESTROY()
    ON_WM_SIZE()
END_MESSAGE_MAP()
// CPjPage1 æ¶ˆæ¯å¤„理程序
BOOL CCjPage1::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    Resize();
    return TRUE;  // return TRUE unless you set the focus to a control
                  // å¼‚常: OCX å±žæ€§é¡µåº”返回 FALSE
}
HBRUSH CCjPage1::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
    // æƒ³ç»™å“ªäº›æŽ§ä»¶æ”¹åº•色就把它们的类型写进来:
    const bool needCustomBg =
        (nCtlColor == CTLCOLOR_STATIC) ||
        (nCtlColor == CTLCOLOR_DLG) ||   // å¯¹è¯æ¡†åº•色
        (nCtlColor == CTLCOLOR_BTN);        // æŒ‰é’®ï¼ˆå¯é€‰ï¼‰
    if (needCustomBg)
    {
        // è‹¥ç¬¬ä¸€æ¬¡åˆ›å»ºï¼Œæˆ–颜色改变则重建
        if (m_brBkgnd.GetSafeHandle() == nullptr || m_crBkgndCached != m_crBkgnd)
        {
            if (m_brBkgnd.GetSafeHandle())
                m_brBkgnd.DeleteObject();
            m_brBkgnd.CreateSolidBrush(m_crBkgnd);
            m_crBkgndCached = m_crBkgnd;
        }
        // æ–‡æœ¬å‰æ™¯/背景设置(仅影响文本绘制)
        pDC->SetBkColor(m_crBkgnd);
        pDC->SetTextColor(RGB(0, 0, 0));
        // å¦‚需让静态文本透明叠在底色上,可用:
        // pDC->SetBkMode(TRANSPARENT);
        return (HBRUSH)m_brBkgnd; // å®‰å…¨çš„隐式转换
    }
    // å…¶ä»–控件类型沿用基类默认的刷子
    return hbr;
}
void CCjPage1::OnDestroy()
{
    CDialogEx::OnDestroy();
    // TODO: åœ¨æ­¤å¤„添加消息处理程序代码
}
void CCjPage1::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    if (GetDlgItem(IDC_LABEL_NO_SEL) == nullptr) return;
    Resize();
}
void CCjPage1::Resize()
{
    CWnd* pItem;
    CRect rcClient, rcItem;
    GetClientRect(&rcClient);
    pItem = GetDlgItem(IDC_LABEL_NO_SEL);
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow((rcClient.Width() - rcItem.Width()) / 2,
        (rcClient.Height() - rcItem.Height()) / 2,
        rcItem.Width(), rcItem.Height());
}
SourceCode/Bond/Servo/CCjPage1.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
#pragma once
// CPjPage1 å¯¹è¯æ¡†
class CCjPage1 : public CDialogEx
{
    DECLARE_DYNAMIC(CCjPage1)
public:
    CCjPage1(CWnd* pParent = nullptr);   // æ ‡å‡†æž„造函数
    virtual ~CCjPage1();
private:
    void Resize();
private:
    COLORREF m_crBkgnd;
    COLORREF m_crBkgndCached;
    CBrush m_brBkgnd;
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_CJ_PAGE1 };
#endif
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV æ”¯æŒ
    DECLARE_MESSAGE_MAP()
public:
    virtual BOOL OnInitDialog();
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg void OnDestroy();
    afx_msg void OnSize(UINT nType, int cx, int cy);
};
SourceCode/Bond/Servo/CControlJob.cpp
@@ -4,9 +4,12 @@
#include "SerializeUtil.h"
static inline std::string trimCopy(std::string s) {
    auto notspace = [](int ch) { return !std::isspace(ch); };
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace));
    s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end());
    s.erase(s.begin(),
        std::find_if(s.begin(), s.end(),
            [](char c) { return !std::isspace(static_cast<unsigned char>(c)); }));
    s.erase(std::find_if(s.rbegin(), s.rend(),
        [](char c) { return !std::isspace(static_cast<unsigned char>(c)); }).base(),
        s.end());
    return s;
}
@@ -281,23 +284,12 @@
        out = CControlJob(cjId);
        out.setPriority(prio);
        // ç›´æŽ¥æ¢å¤å†…部状态(若你要求走状态机,可在这里按合法过渡调用 queue()/start()/...)
        // ç®€åŒ–:直接赋值(你在 CControlJob.cpp å†…部,可访问私有成员)
        struct Access : CControlJob {
            using CControlJob::m_state;
            using CControlJob::m_failReason;
            using CControlJob::m_tQueued;
            using CControlJob::m_tStart;
            using CControlJob::m_tEnd;
            using CControlJob::m_pjIds;
        };
        auto& a = reinterpret_cast<Access&>(out);
        a.m_state = static_cast<CJState>(st);
        a.m_failReason = std::move(failText);
        a.m_tQueued = std::move(tQ);
        a.m_tStart = std::move(tS);
        a.m_tEnd = std::move(tE);
        a.m_pjIds = std::move(pjIds);
        out.m_state = static_cast<CJState>(st);
        out.m_failReason = std::move(failText);
        out.m_tQueued = std::move(tQ);
        out.m_tStart = std::move(tS);
        out.m_tEnd = std::move(tE);
        out.m_pjIds = std::move(pjIds);
        return true;
    }
SourceCode/Bond/Servo/CControlJob.h
@@ -68,7 +68,7 @@
            const std::function<bool(const std::string&)>& getPjExistsFn,
            const std::function<bool(const std::string&)>& canJoinFn
        );
        const std::vector<CControlJob::ValidationIssue>& CControlJob::issues();
        const std::vector<ValidationIssue>& CControlJob::issues();
        // â€”— S14F9 â†’ S14F10 çš„“应用结果”模型 â€”— //
        struct CreateRequest {
SourceCode/Bond/Servo/CControlJobManagerDlg.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,131 @@
// CControlJobManagerDlg.cpp: å®žçŽ°æ–‡ä»¶
//
#include "stdafx.h"
#include "Servo.h"
#include "CControlJobManagerDlg.h"
#include "afxdialogex.h"
// CControlJobManagerDlg å¯¹è¯æ¡†
IMPLEMENT_DYNAMIC(CControlJobManagerDlg, CDialogEx)
CControlJobManagerDlg::CControlJobManagerDlg(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_DIALOG_CONTROL_JOB_MANAGER, pParent)
{
    m_pPage1 = nullptr;
}
CControlJobManagerDlg::~CControlJobManagerDlg()
{
}
void CControlJobManagerDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CControlJobManagerDlg, CDialogEx)
    ON_WM_SIZE()
    ON_WM_GETMINMAXINFO()
END_MESSAGE_MAP()
// CControlJobManagerDlg æ¶ˆæ¯å¤„理程序
BOOL CControlJobManagerDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // page1
    m_pPage1 = new CCjPage1(this);
    m_pPage1->Create(IDD_CJ_PAGE1, this);
    m_pPage1->ShowWindow(SW_SHOW);
    Resize();
    return TRUE;  // return TRUE unless you set the focus to a control
                  // å¼‚常: OCX å±žæ€§é¡µåº”返回 FALSE
}
void CControlJobManagerDlg::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    if (GetDlgItem(IDC_TREE1) == nullptr) return;
    Resize();
}
void CControlJobManagerDlg::Resize()
{
    CWnd* pItem;
    CRect rcClient, rcItem;
    GetClientRect(&rcClient);
    GetDlgItem(IDCANCEL)->GetWindowRect(&rcItem);
    ScreenToClient(&rcItem);
    const int LEFTWIDTH = 218;
    int x = 12;
    int x2 = rcClient.right - 12;
    int y2 = rcClient.bottom - 12;
    // å…ˆç§»åŠ¨æŒ‰é’®
    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_NEW);
    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(IDCANCEL);
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow(x2 - rcItem.Width(), y2 - rcItem.Height(), rcItem.Width(), rcItem.Height());
    y2 -= rcItem.Height();
    y2 -= 8;
    // æ ‘控件
    x = 12;
    pItem = GetDlgItem(IDC_TREE1);
    pItem->MoveWindow(x, 12, LEFTWIDTH, y2 - 12);
    x += LEFTWIDTH;
    x += 5;
    // å­é¡µé¢
    if (m_pPage1 != nullptr) {
        m_pPage1->MoveWindow(x, 12, x2 - x, y2 - 12);
    }
}
void CControlJobManagerDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
    CDialogEx::OnGetMinMaxInfo(lpMMI);
    // è®¾ç½®æœ€å°å®½é«˜ï¼ˆæ¯”如 400x300)
    lpMMI->ptMinTrackSize.x = 600;
    lpMMI->ptMinTrackSize.y = 400;
    // ä¹Ÿå¯ä»¥é¡ºä¾¿è®¾ç½®æœ€å¤§å®½é«˜
    // lpMMI->ptMaxTrackSize.x = 800;
    // lpMMI->ptMaxTrackSize.y = 600;
}
SourceCode/Bond/Servo/CControlJobManagerDlg.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
#pragma once
#include "CCjPage1.h"
// CControlJobManagerDlg å¯¹è¯æ¡†
class CControlJobManagerDlg : public CDialogEx
{
    DECLARE_DYNAMIC(CControlJobManagerDlg)
public:
    CControlJobManagerDlg(CWnd* pParent = nullptr);   // æ ‡å‡†æž„造函数
    virtual ~CControlJobManagerDlg();
private:
    void Resize();
private:
    CCjPage1* m_pPage1;
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_DIALOG_CONTROL_JOB_MANAGER };
#endif
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV æ”¯æŒ
    DECLARE_MESSAGE_MAP()
public:
    virtual BOOL OnInitDialog();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
};
SourceCode/Bond/Servo/CEquipment.cpp
@@ -2237,7 +2237,7 @@
                return -1;
            });
        pStep->setName(STEP_EQ_FAC_DATA_REPORT);
        pStep->setProp("Port", (void*)port);
        pStep->setProp("Port", (void*)(__int64)port);
        pStep->setWriteSignalDev(writeSignalDev);
        if (addStep(STEP_ID_FAC_DATA_REPORT, pStep) != 0) {
            delete pStep;
SourceCode/Bond/Servo/CLoadPort.cpp
@@ -404,7 +404,6 @@
            m_portStatusReport.serialize(ar);
        }
        else {
            int temp;
            ar >> m_nIndex;
            m_portStatusReport.serialize(ar);
        }
SourceCode/Bond/Servo/CPageCollectionEvent.cpp
@@ -106,7 +106,6 @@
    CHMPropertyPage::OnSize(nType, cx, cy);
    if (GetDlgItem(IDC_LIST1) == nullptr) return;
    CWnd* pItem;
    CRect rcClient, rcItem;
    GetClientRect(&rcClient);
    m_listCtrl.MoveWindow(12, 12, rcClient.Width() - 24, rcClient.Height() - 24);
SourceCode/Bond/Servo/CPageReport.cpp
@@ -108,7 +108,6 @@
    CHMPropertyPage::OnSize(nType, cx, cy);
    if (GetDlgItem(IDC_LIST1) == nullptr) return;
    CWnd* pItem;
    CRect rcClient, rcItem;
    GetClientRect(&rcClient);
    m_listCtrl.MoveWindow(12, 12, rcClient.Width() - 24, rcClient.Height() - 24);
SourceCode/Bond/Servo/CPageVarialbles.cpp
@@ -108,7 +108,6 @@
    if (GetDlgItem(IDC_LIST1) == nullptr) return;
    CWnd* pItem;
    CRect rcClient, rcItem;
    GetClientRect(&rcClient);
    m_listCtrl.MoveWindow(12, 12, rcClient.Width() - 24, rcClient.Height() - 24);
SourceCode/Bond/Servo/CServoUtilsTool.cpp
@@ -39,11 +39,6 @@
            if (unit == 1) return "烘烤B腔";
        }
        if (eqid == EQ_ID_VACUUMBAKE) {
            if (unit == 0) return "烘烤A腔";
            if (unit == 1) return "烘烤B腔";
        }
        if (eqid == EQ_ID_Bonder1) {
            return "Bonder1";
        }
@@ -56,8 +51,8 @@
            if (unit == 0) return "后烘烤A腔";
            if (unit == 1) return "冷却A";
            if (unit == 0) return "后烘烤B腔";
            if (unit == 1) return "冷却B";
            if (unit == 2) return "后烘烤B腔";
            if (unit == 3) return "冷却B";
        }
        if (eqid == EQ_ID_MEASUREMENT) {
SourceCode/Bond/Servo/GroupLabel.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,275 @@
#include "stdafx.h"
#include "GroupLabel.h"
CGroupLabel::CGroupLabel()
{
    m_crBkgnd = RGB(255, 255, 255);
    m_crLine = RGB(188, 188, 188);
    m_crText = RGB(88, 88, 88);
    m_nPadding[PADDING_LEFT] = 5;
    m_nPadding[PADDING_TOP] = 5;
    m_nPadding[PADDING_RIGHT] = 5;
    m_nPadding[PADDING_BOTTOM] = 5;
    m_nTextAlign = TEXT_ALIGN_CENTER;
    m_bEnableResize = FALSE;
}
CGroupLabel::~CGroupLabel()
{
}
BEGIN_MESSAGE_MAP(CGroupLabel, CStatic)
    ON_WM_PAINT()
    ON_WM_LBUTTONDOWN()
    ON_WM_SETCURSOR()
END_MESSAGE_MAP()
void CGroupLabel::EnableResize()
{
    m_bEnableResize = TRUE;
    DWORD dwStyle = GetStyle();
    dwStyle |= SS_NOTIFY;
    SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle);
}
void CGroupLabel::DisableResize()
{
    m_bEnableResize = FALSE;
}
void CGroupLabel::OnPaint()
{
    CPaintDC dc(this); // device context for painting
                       // TODO: åœ¨æ­¤å¤„添加消息处理程序代码
                       // ä¸ä¸ºç»˜å›¾æ¶ˆæ¯è°ƒç”¨ CStatic::OnPaint()
    HDC hMemDC;
    HBITMAP hBitmap;
    RECT rcClient;
    CString strText;
    HFONT hFont;
    HBRUSH hBrushBK;
    ::GetClientRect(m_hWnd, &rcClient);
    hMemDC = ::CreateCompatibleDC(dc.m_hDC);
    hBitmap = ::CreateCompatibleBitmap(dc.m_hDC, rcClient.right - rcClient.left,
        rcClient.bottom - rcClient.top);
    ::SelectObject(hMemDC, hBitmap);
    ::SetBkMode(hMemDC, TRANSPARENT);
    // èƒŒæ™¯é¢œè‰²
    hBrushBK = CreateSolidBrush(m_crBkgnd);
    ::FillRect(hMemDC, &rcClient, hBrushBK);
    DeleteObject(hBrushBK);
    // çª—口标题
    int x1, x2, x3, x4;
    x1 = rcClient.left + m_nPadding[PADDING_LEFT];
    x4 = rcClient.right - m_nPadding[PADDING_RIGHT];
    hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
    ::SelectObject(hMemDC, hFont);
    ::SetTextColor(hMemDC, m_crText);
    char szTitle[256];
    int nTextLen = ::GetWindowText(m_hWnd, szTitle, 256);
    if (nTextLen > 0) {
        RECT rcTitle;
        SIZE sizeText;
        rcTitle.left = x1;
        rcTitle.top = rcClient.top + 2;
        rcTitle.bottom = rcClient.bottom - 2;
        rcTitle.right = x4;
#define TEXT_SPAGE    12
        GetTextExtentPoint32(hMemDC, szTitle, nTextLen, &sizeText);
        if (TEXT_ALIGN_LEFT == m_nTextAlign) {
            ::DrawText(hMemDC, szTitle, nTextLen, &rcTitle, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
            x1 += sizeText.cx + TEXT_SPAGE;
        }
        else if (TEXT_ALIGN_CENTER == m_nTextAlign) {
            ::DrawText(hMemDC, szTitle, nTextLen, &rcTitle, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            x2 = x1 + (x4 - x1 - sizeText.cx - TEXT_SPAGE * 2) / 2;
            x3 = x2 + sizeText.cx + TEXT_SPAGE * 2;
        }
        else {
            ::DrawText(hMemDC, szTitle, nTextLen, &rcTitle, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
            x4 -= (sizeText.cx + TEXT_SPAGE);
        }
    }
    // åˆ†éš”线
    HPEN hPen = CreatePen(PS_SOLID, 1, m_crLine);
    HPEN hOldPen = (HPEN)SelectObject(hMemDC, hPen);
    int y = (rcClient.bottom - rcClient.top) / 2;
    if (TEXT_ALIGN_LEFT == m_nTextAlign) {
        ::MoveToEx(hMemDC, x1, y, NULL);
        ::LineTo(hMemDC, x4, y);
    }
    else if (TEXT_ALIGN_CENTER == m_nTextAlign) {
        ::MoveToEx(hMemDC, x1, y, NULL);
        ::LineTo(hMemDC, x2, y);
        ::MoveToEx(hMemDC, x3, y, NULL);
        ::LineTo(hMemDC, x4, y);
    }
    else {
        ::MoveToEx(hMemDC, x1, y, NULL);
        ::LineTo(hMemDC, x4, y);
    }
    SelectObject(hMemDC, hOldPen);
    ::DeleteObject(hPen);
    // EndPaint
    ::BitBlt(dc.m_hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
        hMemDC, 0, 0, SRCCOPY);
    ::DeleteObject(hBitmap);
    ::DeleteDC(hMemDC);
}
void CGroupLabel::SetTextAlignMode(int nAlign)
{
    if (nAlign == TEXT_ALIGN_LEFT || nAlign == TEXT_ALIGN_CENTER || nAlign == TEXT_ALIGN_RIGHT) {
        m_nTextAlign = nAlign;
        RECT rcClient;
        ::GetClientRect(m_hWnd, &rcClient);
        ::InvalidateRect(m_hWnd, &rcClient, TRUE);
    }
}
void CGroupLabel::Setpadding(int type, unsigned int nPadding)
{
    if (type >= PADDING_LEFT && PADDING_LEFT <= PADDING_BOTTOM) {
        m_nPadding[type] = nPadding;
    }
}
/*
 * è®¾ç½®èƒŒæ™¯è‰²
 * color -- èƒŒæ™¯è‰²
 */
void CGroupLabel::SetBkgndColor(COLORREF color)
{
    m_crBkgnd = color;
}
/*
 * è®¾ç½®æ–‡æœ¬è‰²
 * color -- èƒŒæ™¯è‰²
 */
void CGroupLabel::SetTextColor(COLORREF color)
{
    m_crText = color;
    RECT rcClient;
    ::GetClientRect(m_hWnd, &rcClient);
    ::InvalidateRect(m_hWnd, &rcClient, TRUE);
}
/*
 * è®¾ç½®çº¿è‰²
 * color -- èƒŒæ™¯è‰²
 */
void CGroupLabel::SetLineColor(COLORREF color)
{
    m_crLine = color;
    RECT rcClient;
    ::GetClientRect(m_hWnd, &rcClient);
    ::InvalidateRect(m_hWnd, &rcClient, TRUE);
}
 void CGroupLabel::OnLButtonDown(UINT nFlags, CPoint point)
 {
     if (!m_bEnableResize) {
         CStatic::OnLButtonDown(nFlags, point);
         return;
     }
     CPoint pt, ptNew;
     pt = point;
     int nMoveY = 0;
     // æ•捉鼠标消息,检测是否拖动
     CRect rcParent, rcWindows;
     GetClientRect(&rcWindows);
     ::ClientToScreen(m_hWnd, (LPPOINT)&rcWindows);
     ::ClientToScreen(m_hWnd, (LPPOINT)&rcWindows.right);
     GetParent()->GetClientRect(&rcParent);
     ::ClientToScreen(GetParent()->m_hWnd, (LPPOINT)&rcParent);
     HDC hDC = ::GetDC(::GetDesktopWindow());
     ::DrawFocusRect(hDC, &rcWindows);
     if (::GetCapture() == NULL) {
         SetCapture();
         ASSERT(this == GetCapture());
         AfxLockTempMaps();
         for (;;) {
             MSG msg;
             VERIFY(::GetMessage(&msg, NULL, 0, 0));
             if (GetCapture() != this) break;
             switch (msg.message)
             {
             case WM_MOUSEMOVE:
                 ptNew = msg.pt;
                 if (ptNew.y < rcParent.top) ptNew.y = rcParent.top;
                 ::DrawFocusRect(hDC, &rcWindows);
                 rcWindows.top = ptNew.y - 3;
                 rcWindows.bottom = ptNew.y + 3;
                 ::DrawFocusRect(hDC, &rcWindows);
                 ::ScreenToClient(m_hWnd, &ptNew);
                 break;
             case WM_LBUTTONUP:
                 ptNew = msg.pt;
                 ::ScreenToClient(m_hWnd, &ptNew);
                 nMoveY = ptNew.y - pt.y;
                 goto ExitLoop;
             case WM_KEYDOWN:
                 if (msg.wParam == VK_ESCAPE) {
                     goto ExitLoop;
                 }
                 break;
             default:
                 DispatchMessage(&msg);
                 break;
             }
         }
     ExitLoop:
         ::DrawFocusRect(hDC, &rcWindows);
         ::ReleaseDC(::GetDesktopWindow(), hDC);
         ReleaseCapture();
         ::InvalidateRect(m_hWnd, NULL, TRUE);
         GetParent()->SendMessage(ID_MSG_RESIZEY, nMoveY, 0);
         AfxUnlockTempMaps(FALSE);
     }
     CStatic::OnLButtonDown(nFlags, point);
 }
 BOOL CGroupLabel::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
 {
     if (m_bEnableResize) {
         ::SetCursor(::LoadCursor(NULL, IDC_SIZENS));
         return TRUE;
     }
     return CStatic::OnSetCursor(pWnd, nHitTest, message);
 }
SourceCode/Bond/Servo/GroupLabel.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
#pragma once
#define PADDING_LEFT        0
#define PADDING_TOP            1
#define PADDING_RIGHT        2
#define PADDING_BOTTOM        3
#define TEXT_ALIGN_LEFT        0
#define TEXT_ALIGN_CENTER    1
#define TEXT_ALIGN_RIGHT    3
#define ID_MSG_RESIZEY        WM_USER+123
class CGroupLabel : public CStatic
{
public:
    CGroupLabel();
    ~CGroupLabel();
public:
    void SetBkgndColor(COLORREF color);
    void SetTextColor(COLORREF color);
    void SetLineColor(COLORREF color);
    void Setpadding(int type, unsigned int nPadding);
    void SetTextAlignMode(int nAlign);
    void EnableResize();
    void DisableResize();
private:
    COLORREF    m_crBkgnd;
    unsigned int m_nPadding[4];
    COLORREF    m_crLine;
    COLORREF    m_crText;
    int            m_nTextAlign;
private:
    BOOL m_bEnableResize;
    DECLARE_MESSAGE_MAP()
    afx_msg void OnPaint();
public:
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
};
SourceCode/Bond/Servo/PageLog.cpp
@@ -84,7 +84,7 @@
                                        std::regex((LPTSTR)(LPCTSTR)m_strFilterText));
                                }
                                catch (const std::regex_error& e) {
                                    TRACE(_T("正在表达式匹配检测异常: %s\n"), e.what());
                                }
                            }
                            if (m_filterMode == FilterMode::Exclude) {
SourceCode/Bond/Servo/ProcessJob.cpp
@@ -7,9 +7,12 @@
namespace SERVO {
    static inline std::string trimCopy(std::string s) {
        auto notspace = [](int ch) { return !std::isspace(ch); };
        s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace));
        s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end());
        s.erase(s.begin(),
            std::find_if(s.begin(), s.end(),
                [](char c) { return !std::isspace(static_cast<unsigned char>(c)); }));
        s.erase(std::find_if(s.rbegin(), s.rend(),
            [](char c) { return !std::isspace(static_cast<unsigned char>(c)); }).base(),
            s.end());
        return s;
    }
@@ -61,7 +64,7 @@
        m_pauseEvents.erase(std::unique(m_pauseEvents.begin(), m_pauseEvents.end()), m_pauseEvents.end());
    }
    const std::vector<CProcessJob::ValidationIssue>& CProcessJob::issues()
    const std::vector<CProcessJob::ValidationIssue>& CProcessJob::issues() const
    {
        return m_issues;
    }
@@ -278,7 +281,7 @@
        // é…æ–¹
        uint8_t recipeType = static_cast<uint8_t>(m_recipeMethod);
        write_pod(os, m_recipeMethod);
        write_pod(os, recipeType);
        write_string(os, m_recipeSpec);
        // ç‰©æ–™ï¼ˆå¤š Carrier & Slot)
@@ -399,13 +402,13 @@
            return "InProcess";
            break;
        case SERVO::PJState::Paused:
            return "Queued";
            return "Paused";
            break;
        case SERVO::PJState::Aborting:
            return "Aborting";
            break;
        case SERVO::PJState::Completed:
            return "Queued";
            return "Completed";
            break;
        case SERVO::PJState::Aborted:
            return "Aborted";
@@ -420,7 +423,7 @@
        return "";
    }
    CarrierSlotInfo* CProcessJob::getCarrier(std::string& strId)
    CarrierSlotInfo* CProcessJob::getCarrier(const  std::string& strId)
    {
        for (auto& item : m_carriers) {
            if (item.carrierId.compare(strId) == 0) {
SourceCode/Bond/Servo/ProcessJob.h
@@ -121,7 +121,7 @@
        };
        // è¿”回问题清单(空=通过)
        bool validate(const IResourceView& rv);
        const std::vector<ValidationIssue>& issues();
        const std::vector<ValidationIssue>& issues() const;
        // â€”— çŠ¶æ€æœºï¼ˆå¸¦å®ˆå«ï¼‰â€”â€”
        bool queue();           // NoState -> Queued
@@ -155,7 +155,7 @@
        // è®¿é—®å™¨
        const std::vector<CarrierSlotInfo>& carriers() const noexcept { return m_carriers; }
        CarrierSlotInfo* getCarrier(std::string& strId);
        CarrierSlotInfo* getCarrier(const std::string& strId);
        // åˆ¤å®šæ˜¯å¦â€œæŒ‰è½½å…·/卡位”方式
        bool usesCarrierSlots() const noexcept { return !m_carriers.empty(); }
SourceCode/Bond/Servo/Servo.rc
Binary files differ
SourceCode/Bond/Servo/Servo.vcxproj
@@ -212,6 +212,7 @@
    <ClInclude Include="CBaseDlg.h" />
    <ClInclude Include="CControlJob.h" />
    <ClInclude Include="CControlJobDlg.h" />
    <ClInclude Include="CControlJobManagerDlg.h" />
    <ClInclude Include="CCustomCheckBox.h" />
    <ClInclude Include="CCollectionEvent.h" />
    <ClInclude Include="CEquipmentPage3.h" />
@@ -225,6 +226,7 @@
    <ClInclude Include="CPageReport.h" />
    <ClInclude Include="CPageVarialbles.h" />
    <ClInclude Include="CParam.h" />
    <ClInclude Include="CCjPage1.h" />
    <ClInclude Include="CProcessDataListDlg.h" />
    <ClInclude Include="CReport.h" />
    <ClInclude Include="CRobotCmdContainerDlg.h" />
@@ -254,6 +256,7 @@
    <ClInclude Include="GridControl\TitleTip.h" />
    <ClInclude Include="CRobotTask.h" />
    <ClInclude Include="CSlot.h" />
    <ClInclude Include="GroupLabel.h" />
    <ClInclude Include="HorizontalLine.h" />
    <ClInclude Include="InputDialog.h" />
    <ClInclude Include="JobSlotGrid.h" />
@@ -388,6 +391,7 @@
    <ClCompile Include="CBaseDlg.cpp" />
    <ClCompile Include="CControlJob.cpp" />
    <ClCompile Include="CControlJobDlg.cpp" />
    <ClCompile Include="CControlJobManagerDlg.cpp" />
    <ClCompile Include="CCustomCheckBox.cpp" />
    <ClCompile Include="CCollectionEvent.cpp" />
    <ClCompile Include="CEquipmentPage3.cpp" />
@@ -401,6 +405,7 @@
    <ClCompile Include="CPageReport.cpp" />
    <ClCompile Include="CPageVarialbles.cpp" />
    <ClCompile Include="CParam.cpp" />
    <ClCompile Include="CCjPage1.cpp" />
    <ClCompile Include="CProcessDataListDlg.cpp" />
    <ClCompile Include="CReport.cpp" />
    <ClCompile Include="CRobotCmdContainerDlg.cpp" />
@@ -428,6 +433,7 @@
    <ClCompile Include="GridControl\TitleTip.cpp" />
    <ClCompile Include="CRobotTask.cpp" />
    <ClCompile Include="CSlot.cpp" />
    <ClCompile Include="GroupLabel.cpp" />
    <ClCompile Include="HorizontalLine.cpp" />
    <ClCompile Include="InputDialog.cpp" />
    <ClCompile Include="JobSlotGrid.cpp" />
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -198,6 +198,9 @@
    <ClCompile Include="GlassLogDb.cpp" />
    <ClCompile Include="sqlite3.c" />
    <ClCompile Include="CProcessDataListDlg.cpp" />
    <ClCompile Include="GroupLabel.cpp" />
    <ClCompile Include="CControlJobManagerDlg.cpp" />
    <ClCompile Include="CCjPage1.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AlarmManager.h" />
@@ -421,6 +424,9 @@
    <ClInclude Include="sqlite3.h" />
    <ClInclude Include="sqlite3ext.h" />
    <ClInclude Include="CProcessDataListDlg.h" />
    <ClInclude Include="GroupLabel.h" />
    <ClInclude Include="CControlJobManagerDlg.h" />
    <ClInclude Include="CCjPage1.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc" />
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -28,6 +28,7 @@
#include "CPageCollectionEvent.h"
#include "CControlJobDlg.h"
#include "InputDialog.h"
#include "CControlJobManagerDlg.h"
#ifdef _DEBUG
@@ -989,20 +990,6 @@
{
    int id = (int)lParam;
    if (id == IDC_BUTTON_RUN || id == IDC_BUTTON_STOP) {
        //CInputDialog inputDialog(_T("验证用户"), _T("请输入用户密码:"));
        //if (inputDialog.DoModal() != IDOK) {
        //    AfxMessageBox(_T("取消验证!"));
        //    return 0;
        //}
        //CString inputText = inputDialog.GetInputText();
        //std::string strPass = UserManager::getInstance().getCurrentPass();
        //if (inputText.Compare(strPass.c_str()) != 0) {
        //    AfxMessageBox(_T("密码错误!"));
        //    SystemLogManager::getInstance().log(SystemLogManager::LogType::Info, _T("验证时,密码错误!"));
        //    return 0;
        //}
        UserRole emRole = UserManager::getInstance().getCurrentUserRole();
        if (emRole != UserRole::SuperAdmin) {
            AfxMessageBox(_T("当前用户并非管理员!!!")); 
@@ -1052,9 +1039,14 @@
        }
    }
    else if (id == IDC_BUTTON_JOBS) {
        CControlJobManagerDlg dlg;
        dlg.DoModal();
        /*
        CControlJobDlg dlg;
        dlg.SetControlJob(theApp.m_model.m_master.getControlJob());
        dlg.DoModal();
        */
    }
    else if (id == IDC_BUTTON_PORT_CONFIG) {
        CPortConfigurationDlg dlg;
SourceCode/Bond/Servo/TerminalDisplayDlg.cpp
@@ -104,7 +104,6 @@
void CTerminalDisplayDlg::Resize()
{
    CWnd* pItem;
    CRect rcClient, rcItem;
    GetClientRect(&rcClient);
    rcClient.top += 38;
SourceCode/Bond/Servo/resource.h
Binary files differ