1.顶部工具条增加按钮"批运行",用于ControlJob模式调度的运行;
2.CMaster增加startBatch,启动批运动模式;
3.CMaster在兼容原单片Glass调试的情况下,增加startBatch调度,开始实现调度功能。
已修改8个文件
426 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CEquipment.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 367 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/TopToolbar.cpp 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/TopToolbar.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp
@@ -1655,7 +1655,7 @@
    int CEquipment::decodeVCREventReport(CStep* pStep, const char* pszData, size_t size)
    {
        CVcrEventReport vcrEventReport;
        vcrEventReport.unserialize(pszData, size);
        vcrEventReport.unserialize(pszData, (int)size);
        LOGI("<CEquipment-%s>decodeVCREventReport<Result:%d, GlassId:%s>\n", m_strName.c_str(),
            vcrEventReport.getVcrResult(),
            vcrEventReport.getGlassId().c_str());
SourceCode/Bond/Servo/CMaster.cpp
@@ -59,6 +59,7 @@
        m_bEnableEventReport = true;
        m_bEnableAlarmReport = true;
        m_bContinuousTransfer = false;
        m_bBatch = false;
        m_nContinuousTransferCount = 0;
        m_nContinuousTransferStep = CTStep_Unknow;
        m_pControlJob = nullptr;
@@ -270,6 +271,7 @@
        }
        m_bContinuousTransfer = false;
        m_bBatch = false;
        setState(MASTERSTATE::STARTING);
        m_ullStartTime = GetTickCount64();
@@ -283,6 +285,21 @@
        }
        m_bContinuousTransfer = true;
        m_bBatch = false;
        setState(MASTERSTATE::STARTING);
        m_ullStartTime = GetTickCount64();
        return 0;
    }
    int CMaster::startBatch()
    {
        if (m_state != MASTERSTATE::READY) {
            return -1;
        }
        m_bContinuousTransfer = false;
        m_bBatch = true;
        setState(MASTERSTATE::STARTING);
        m_ullStartTime = GetTickCount64();
@@ -292,12 +309,28 @@
    int CMaster::stop()
    {
        // 运行时间为累加结果,本次停止时刷新;
        if (m_state != MASTERSTATE::RUNNING && m_state != MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
        lock();
        if (m_state != MASTERSTATE::RUNNING && m_state != MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER
            && m_state != MASTERSTATE::RUNNING_BATCH) {
            unlock();
            return -1;
        }
        m_ullRunTime += (GetTickCount64() - m_ullStartTime);
        unlock();
        // 更新状态
        setState(MASTERSTATE::STOPPING);
        // ControlJob暂停
        lock();
        if (m_pControlJob != nullptr) {
            m_pControlJob->pause();
            saveState();
        }
        unlock();
        return 0;
    }
@@ -311,7 +344,8 @@
    ULONGLONG CMaster::getRunTime()
    {
        if (m_state == MASTERSTATE::RUNNING || m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER)
        if (m_state == MASTERSTATE::RUNNING || m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER
            || m_state == MASTERSTATE::RUNNING_BATCH)
            return m_ullRunTime + (GetTickCount64() - m_ullStartTime);
        else
            return m_ullRunTime;
@@ -471,18 +505,21 @@
                }
                
                // 检查看是否都已经切换到START状态
                /*
                if (!bIomcOk[6]) {
                    unlock();
                    setState(MASTERSTATE::MSERROR);
                    continue;
                }
                */
                unlock();
                if(!m_bContinuousTransfer)
                    setState(MASTERSTATE::RUNNING);
                else
                if(m_bContinuousTransfer)
                    setState(MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER);
                else if (m_bBatch)
                    setState(MASTERSTATE::RUNNING_BATCH);
                else
                    setState(MASTERSTATE::RUNNING);
                continue;
            }
@@ -694,6 +731,226 @@
                }
PORT_GET:
                CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                unlock();
                continue;
            }
            // 批处理模式,最终以此为准,但先保留之前的单片模式
            else if (m_state == MASTERSTATE::RUNNING_BATCH) {
                // 首选检查有没有CControlJob, 状态等
                if (m_pControlJob == nullptr) {
                    unlock();
                    continue;
                }
                CJState state = m_pControlJob->state();
                if (state == CJState::Completed || state == CJState::Aborted || state == CJState::Failed) {
                    // ConrolJpb已完成
                    LOGI("<Master>ControlJob已经完成或失败中断");
                    unlock();
                    continue;
                }
                if (m_pControlJob->state() == CJState::NoState) {
                    LOGI("<Master>ControlJob已经进入列队");
                    m_pControlJob->queue();
                }
                if (m_pControlJob->state() == CJState::Queued) {
                    LOGI("<Master>ControlJob已经启动");
                    m_pControlJob->start();
                }
                if (m_pControlJob->state() == CJState::Paused) {
                    LOGI("<Master>ControlJob已经恢复运行");
                    m_pControlJob->resume();
                }
                // 如果当前未选择CProcessJob, 选择一个
                if (m_inProcesJobs.empty()) {
                    auto pj = acquireNextProcessJob();
                    if (pj != nullptr) {
                        m_inProcesJobs.push_back(pj);
                    }
                }
                if (m_inProcesJobs.empty()) {
                    LOGI("<Master>选择当前ProcessJob失败!");
                    unlock();
                    continue;
                }
                // 如果当前没有Glass, 选择
                if (m_queueGlasses.empty()) {
                    int nCount = acquireGlassToQueue();
                    LOGI("<Master>已加入 %d 块Glass到工艺列队!", nCount);
                }
                // 检测判断robot状态
                RMDATA& rmd = pEFEM->getRobotMonitoringData();
                if (rmd.status != ROBOT_STATUS::Idle && rmd.status != ROBOT_STATUS::Run) {
                    unlock();
                    continue;
                }
                if (m_pActiveRobotTask != nullptr) {
                    if (m_pActiveRobotTask->isPicked()) {
                        m_pActiveRobotTask->place();
                    }
                    unlock();
                    // 检测到当前有正在下午的任务,确保当前任务完成或中止后继续
                    // LOGI("检测到当前有正在下午的任务,确保当前任务完成或中止后继续...");
                    continue;
                }
                // 此处检测优先类型和次要类型(G1或G2)
                // 如果其中一Bonder有单个玻璃,优先取它的配对类型,否则无所谓了
                primaryType = MaterialsType::G1;
                secondaryType = MaterialsType::G2;
                if ((!pBonder1->canPlaceGlassInSlot(0) && !pBonder1->canPlaceGlassInSlot(1))
                    && (!pBonder2->canPlaceGlassInSlot(0) && !pBonder2->canPlaceGlassInSlot(1))) {
                    // 如果G1和G2都满了,那就看Aligner, 如果Aligner有玻璃为G1, 则取G2
                    CGlass* pGlass = pAligner->getGlassFromSlot(1);
                    if (pGlass != nullptr && pGlass->getType() == MaterialsType::G1) {
                        primaryType = MaterialsType::G2;
                        secondaryType = MaterialsType::G1;
                    }
                }
                else if ((pBonder1->canPlaceGlassInSlot(0) && !pBonder1->canPlaceGlassInSlot(1))
                    || (pBonder2->canPlaceGlassInSlot(0) && !pBonder2->canPlaceGlassInSlot(1))) {
                    primaryType = MaterialsType::G2;
                    secondaryType = MaterialsType::G1;
                }
                // Measurement -> LoadPort
                if (rmd.armState[0] || rmd.armState[1]) {
                    LOGI("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("不可用") : _T("可用"),
                        rmd.armState[1] ? _T("不可用") : _T("可用"));
                }
                for (int s = 0; s < 4; s++) {
                    PortType pt = pLoadPorts[s]->getPortType();
                    if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
                        && (pt == PortType::Unloading || pt == PortType::Both)
                        && pLoadPorts[s]->getPortStatus() == PORT_INUSE) {
                        m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], primaryType, secondaryType);
                        if (m_pActiveRobotTask != nullptr) {
                            goto BATCH_PORT_PUT;
                        }
                    }
                }
            BATCH_PORT_PUT:
                CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                // Measurement NG -> LoadPort
                // NG回原位
                if (!rmd.armState[1]) {
                    m_pActiveRobotTask = createTransferTask_restore(pMeasurement, pLoadPorts);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                // BakeCooling ->Measurement
                if (!rmd.armState[0]) {
                    m_pActiveRobotTask = createTransferTask_bakecooling_to_measurement(pBakeCooling, pMeasurement);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                // BakeCooling内部
                // Bake -> Cooling
                if (!rmd.armState[0]) {
                    m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                // Bonder -> BakeCooling
                if (!rmd.armState[0]) {
                    m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder1, pBakeCooling);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                if (!rmd.armState[0]) {
                    m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder2, pBakeCooling);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                // Fliper(G2) -> Bonder
                auto pSrcSlot = pVacuumBake->getProcessedSlot(primaryType);
                if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder1->hasBondClass()) {
                    m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder2->hasBondClass()) {
                    m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                // VacuumBake(G1) -> Bonder
                if (!rmd.armState[0] && !pBonder1->hasBondClass()) {
                    m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                if (!rmd.armState[0] && !pBonder2->hasBondClass()) {
                    m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                // Aligner -> Fliper(G2)
                // Aligner -> VacuumBake(G1)
                if (!rmd.armState[1]) {
                    m_pActiveRobotTask = createTransferTask(pAligner, pFliper, primaryType, secondaryType);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                if (!rmd.armState[0]) {
                    m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, primaryType, secondaryType);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                // Aligner -> LoadPort
                if (!rmd.armState[1]) {
                    m_pActiveRobotTask = createTransferTask_restore(pAligner, pLoadPorts);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                }
                // LoadPort -> Aligner
                for (int s = 0; s < 4; s++) {
                    PortType pt = pLoadPorts[s]->getPortType();
                    if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
                        && (pt == PortType::Loading || pt == PortType::Both)
                        && pLoadPorts[s]->getPortStatus() == PORT_INUSE) {
                        m_pActiveRobotTask = createTransferTask(pLoadPorts[s], pAligner, primaryType, secondaryType, m_bJobMode);
                        if (m_pActiveRobotTask != nullptr) {
                            pEFEM->setContext(m_pActiveRobotTask->getContext());
                            bool bMoved = glassFromQueueToInPorcess((CGlass*)m_pActiveRobotTask->getContext());
                            if (bMoved) {
                                LOGI("<Master>Glass(%s)从等待列队到工艺列队转移成功.",
                                    ((CGlass*)m_pActiveRobotTask->getContext())->getID().c_str());
                            }
                            else {
                                LOGE("<Master>Glass(%s)从等待列队到工艺列队转移失败.",
                                    ((CGlass*)m_pActiveRobotTask->getContext())->getID().c_str());
                            }
                            goto BATCH_PORT_GET;
                        }
                    }
                }
            BATCH_PORT_GET:
                CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
@@ -1103,6 +1360,21 @@
                    LOGI("放片完成...");
                    // 完成此条搬送任务,但要把数据和消息上抛应用层
                    // 如果是搬送回从AOI搬送回Port, 则glass工艺完成
                    if (m_pActiveRobotTask->getSrcPosition() == EQ_ID_MEASUREMENT) {
                        bool bMoved = glassFromInPorcessToComplete((CGlass*)m_pActiveRobotTask->getContext());
                        if (bMoved) {
                            LOGI("<Master>Glass(%s)从工艺列队到完成列队转移成功.",
                                ((CGlass*)m_pActiveRobotTask->getContext())->getID().c_str());
                        }
                        else {
                            LOGE("<Master>Glass(%s)从工艺列队到完成列队转移失败.",
                                ((CGlass*)m_pActiveRobotTask->getContext())->getID().c_str());
                        }
                    }
                    unlock();
@@ -2095,4 +2367,85 @@
        return true;
    }
    CProcessJob* CMaster::acquireNextProcessJob()
    {
        auto& pjs = m_pControlJob->getPjs();
        for (const auto pj : pjs) {
            if (pj->state() == PJState::Queued) {
                pj->start();
            }
            return pj;
        }
        return nullptr;
    }
    CGlass* CMaster::acquireNextGlass()
    {
        for (auto* pj : m_inProcesJobs) {
            // 遍历 PJ 的 carriers 和 slots
            for (auto& cs : pj->carriers()) {
                for (auto ctx : cs.contexts) {
                    CGlass* pGlass = (CGlass*)ctx;
                    if (pGlass->state() == GlsState::NoState) {
                        pGlass->queue();
                        return pGlass;
                    }
                }
            }
        }
        return nullptr; // 没有可加工的 Glass
    }
    int CMaster::acquireGlassToQueue()
    {
        int nCount = 0;
        for (auto* pj : m_inProcesJobs) {
            // 遍历 PJ 的 carriers 和 slots
            for (auto& cs : pj->carriers()) {
                for (auto ctx : cs.contexts) {
                    CGlass* pGlass = (CGlass*)ctx;
                    if (pGlass->state() == GlsState::NoState) {
                        pGlass->queue();
                        if(addGlassToQueue(pGlass)) nCount++;
                    }
                }
            }
        }
        return nCount;
    }
    bool CMaster::addGlassToQueue(CGlass* pGlass)
    {
        for (auto g : m_queueGlasses) {
            if (g == pGlass) return false;
        }
        m_queueGlasses.push_back(pGlass);
        return true;
    }
    bool CMaster::glassFromQueueToInPorcess(CGlass* pGlass)
    {
        auto it = std::find(m_queueGlasses.begin(), m_queueGlasses.end(), pGlass);
        if (it != m_queueGlasses.end()) {
            m_inProcesGlasses.push_back(*it);
            m_queueGlasses.erase(it);
            return true;
        }
        return false;
    }
    bool CMaster::glassFromInPorcessToComplete(CGlass* pGlass)
    {
        auto it = std::find(m_inProcesGlasses.begin(), m_inProcesGlasses.end(), pGlass);
        if (it != m_inProcesGlasses.end()) {
            m_completeGlasses.push_back(*it);
            m_inProcesGlasses.erase(it);
            return true;
        }
        return false;
    }
}
SourceCode/Bond/Servo/CMaster.h
@@ -39,6 +39,7 @@
        STARTING,
        RUNNING,
        RUNNING_CONTINUOUS_TRANSFER,
        RUNNING_BATCH,
        STOPPING,
        MSERROR
    };
@@ -79,6 +80,7 @@
        int term();
        int start();
        int startContinuousTransfer();
        int startBatch();
        int stop();
        void clearError();
        ULONGLONG getRunTime();
@@ -154,6 +156,15 @@
        bool slotUsable(const std::string& carrierId, uint16_t slot) const override;
        bool ceidDefined(uint32_t ceid) const override;
    public:
        // 新增函数
        CProcessJob* acquireNextProcessJob();
        CGlass* acquireNextGlass();
        int acquireGlassToQueue();
        bool addGlassToQueue(CGlass* pGlass);
        bool glassFromQueueToInPorcess(CGlass* pGlass);
        bool glassFromInPorcessToComplete(CGlass* pGlass);
    private:
        CRITICAL_SECTION m_criticalSection;
        MasterListener m_listener;
@@ -162,6 +173,7 @@
        std::string m_strFilepath;
        BOOL m_bDataModify;
        bool m_bContinuousTransfer;
        bool m_bBatch;
    private:
        /* 监控比特位的线程*/
@@ -197,6 +209,12 @@
        int m_nContinuousTransferCount;
        int m_nContinuousTransferStep;
        // 新增已经开始处理的ProcessJob列表
        std::vector<CProcessJob*> m_inProcesJobs;
        std::vector<CGlass*> m_queueGlasses;
        std::vector<CGlass*> m_inProcesGlasses;
        std::vector<CGlass*> m_completeGlasses;
    private:
        bool m_bEnableEventReport;
        bool m_bEnableAlarmReport;
SourceCode/Bond/Servo/Servo.rc
Binary files differ
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -192,6 +192,7 @@
                SERVO::MASTERSTATE state = theApp.m_model.getMaster().getState();
                if (state == SERVO::MASTERSTATE::READY) {
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
                    m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_NORMAL);
@@ -208,14 +209,17 @@
                }
                else if (state == SERVO::MASTERSTATE::MSERROR) {
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(TRUE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
                    m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_ALARM);
                    m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0));
                    m_pMyStatusbar->setRunTimeText("启动失败.");
                }
                else if (state == SERVO::MASTERSTATE::RUNNING || state == SERVO::MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
                else if (state == SERVO::MASTERSTATE::RUNNING || state == SERVO::MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER
                    || state == SERVO::MASTERSTATE::RUNNING_BATCH) {
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(FALSE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(FALSE);
                    m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE);
                    m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_RUNNING);
@@ -959,6 +963,19 @@
        else {
            if (theApp.m_model.getMaster().start() == 0) {
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(FALSE);
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(FALSE);
            }
        }
    }
    else if (id == IDC_BUTTON_RUN_BATCH) {
        if (theApp.m_model.getMaster().getState() == SERVO::MASTERSTATE::MSERROR) {
            AfxMessageBox("当前有机台发生错误,不能启动,请确认解决问题后再尝试重新启动!");
        }
        else {
            if (theApp.m_model.getMaster().startBatch() == 0) {
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(FALSE);
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(FALSE);
            }
        }
@@ -970,6 +987,7 @@
        else {
            if (theApp.m_model.getMaster().startContinuousTransfer() == 0) {
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(FALSE);
                m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(FALSE);
            }
        }
@@ -1099,6 +1117,9 @@
    else if (state == SERVO::MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
        strText.Format(_T("千传模式:%02d:%02d:%02d   %s"), h, m, s, pszSuffix);
    }
    else if (state == SERVO::MASTERSTATE::RUNNING_BATCH) {
        strText.Format(_T("JOB模式:%02d:%02d:%02d   %s"), h, m, s, pszSuffix);
    }
    else {
        strText.Format(_T("已运行:%02d:%02d:%02d   %s"), h, m, s, pszSuffix);
    }
SourceCode/Bond/Servo/TopToolbar.cpp
@@ -8,6 +8,9 @@
#include "Common.h"
#define SHOW_BATCH    1
#define SHOW_CT        1
// CTopToolbar 对话框
IMPLEMENT_DYNAMIC(CTopToolbar, CDialogEx)
@@ -27,6 +30,7 @@
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_BUTTON_RUN, m_btnRun);
    DDX_Control(pDX, IDC_BUTTON_RUN_BATCH, m_btnRunBatch);
    DDX_Control(pDX, IDC_BUTTON_RUN_CT, m_btnRunCt);
    DDX_Control(pDX, IDC_BUTTON_STOP, m_btnStop);
    DDX_Control(pDX, IDC_BUTTON_JOBS, m_btnCJobs);
@@ -54,6 +58,7 @@
    CDialogEx::OnInitDialog();
    InitBtn(m_btnRun, "Run_High_32.ico", "Run_Gray_32.ico");
    InitBtn(m_btnRunBatch, "Run_High_32.ico", "Run_Gray_32.ico");
    InitBtn(m_btnRunCt, "RunCt_High_32.ico", "RunCt_Gray_32.ico");
    InitBtn(m_btnStop, "Stop_High_32.ico", "Stop_Gray_32.ico");
    InitBtn(m_btnAlarm, "Alarm_o_32.ico", "Alarm_gray_32.ico");
@@ -120,10 +125,19 @@
    x += BTN_WIDTH;
    x += 2;
#ifdef SHOW_BATCH
    pItem = GetDlgItem(IDC_BUTTON_RUN_BATCH);
    pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight);
    x += BTN_WIDTH;
    x += 2;
#endif
#ifdef SHOW_CT
    pItem = GetDlgItem(IDC_BUTTON_RUN_CT);
    pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight);
    x += BTN_WIDTH;
    x += 2;
#endif
    pItem = GetDlgItem(IDC_BUTTON_STOP);
    pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight);
@@ -204,6 +218,7 @@
{
    switch (LOWORD(wParam)) {
    case IDC_BUTTON_RUN:
    case IDC_BUTTON_RUN_BATCH:
    case IDC_BUTTON_RUN_CT:
    case IDC_BUTTON_STOP:
    case IDC_BUTTON_JOBS:
SourceCode/Bond/Servo/TopToolbar.h
@@ -31,6 +31,7 @@
private:
    CBlButton m_btnRun;
    CBlButton m_btnRunBatch;
    CBlButton m_btnRunCt;
    CBlButton m_btnStop;
    CBlButton m_btnCJobs;
SourceCode/Bond/Servo/resource.h
Binary files differ