LAPTOP-SNT8I5JK\Boounion
2025-01-03 518ed5e189c36f99af1157995ddd2bb61489b5a5
1.联调后优化;
已修改12个文件
488 ■■■■ 文件已修改
SourceCode/Bond/BondEq/AlarmMonitor.cpp 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/AlarmPopupDlg.cpp 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/AlarmPopupDlg.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/BondEqDlg.cpp 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CBonder.cpp 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CBonder.h 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CProjectPageMain.cpp 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CProjectPageMain.h 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Common.h 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Model.cpp 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Model.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/GangBond2860.sln 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/AlarmMonitor.cpp
@@ -161,29 +161,9 @@
void CAlarmMonitor::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        Lock();
        int count = (int)m_mapAlarming.size();
        ar << count;
        for (auto item : m_mapAlarming) {
            item.second->Serialize(ar);
        }
        Unlock();
    if (ar.IsStoring()) {
    }
    else
    {
        Lock();
        int count;
        ar >> count;
        for (int i = 0; i < count; i++) {
            CAlarm* pAlarm = new CAlarm();
            pAlarm->addRef();
            pAlarm->Serialize(ar);
            addAlarming(pAlarm);
            pAlarm->release();
        }
        Unlock();
    else {
    }
}
SourceCode/Bond/BondEq/AlarmPopupDlg.cpp
@@ -21,6 +21,7 @@
    m_crBkgnd = RGB(225, 225, 225);
    m_hbrBkgnd = nullptr;
    m_pActiveAlarm = nullptr;
    m_pObserver = nullptr;
}
CAlarmPopupDlg::~CAlarmPopupDlg()
@@ -52,6 +53,35 @@
// CAlarmPopupDlg 消息处理程序
void CAlarmPopupDlg::InitRxWindows()
{
    /* code */
    // 订阅数据
    IRxWindows* pRxWindows = RX_GetRxWindows();
    pRxWindows->enableLog(5);
    if (m_pObserver == NULL) {
        m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
            // onNext
            pAny->addRef();
            int code = pAny->getCode();
            if (RX_CODE_BONDER_BEEP == code) {
                bool bMute = theApp.m_model.getBonder().isMute();
                SetButtonBackgroundColors(bMute);
                TRACE("RX_CODE_BONDER_BEEP %s\n", bMute ? "1" : "0");
            }
            pAny->release();
        }, [&]() -> void {
            // onComplete
        }, [&](IThrowable* pThrowable) -> void {
            // onErrorm
            pThrowable->printf();
        });
        theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
            ->subscribe(m_pObserver);
    }
}
BOOL CAlarmPopupDlg::OnInitDialog()
{
@@ -143,6 +173,7 @@
    pLine->SetLineColor(RGB(168, 168, 168));
    InitRxWindows();
    return TRUE;  // return TRUE unless you set the focus to a control
                  // 异常: OCX 属性页应返回 FALSE
}
@@ -176,6 +207,11 @@
    if (m_pActiveAlarm != nullptr) {
        m_pActiveAlarm->release();
        m_pActiveAlarm = nullptr;
    }
    if (m_pObserver != nullptr) {
        m_pObserver->unsubscribe();
        m_pObserver = NULL;
    }
}
@@ -231,11 +267,13 @@
        m_btnSoundOff.SetBkgndColor(BS_NORMAL, BTN_SOUND_OFF_BKGND_NORMAL);
        m_btnSoundOff.SetBkgndColor(BS_HOVER, BTN_SOUND_OFF_BKGND_HOVER);
        m_btnSoundOff.SetBkgndColor(BS_PRESS, BTN_SOUND_OFF_BKGND_PRESS);
        m_btnSoundOff.Invalidate();
    }
    else {
        m_btnSoundOff.SetBkgndColor(BS_NORMAL, BTN_SOUND_ON_BKGND_NORMAL);
        m_btnSoundOff.SetBkgndColor(BS_HOVER, BTN_SOUND_ON_BKGND_HOVER);
        m_btnSoundOff.SetBkgndColor(BS_PRESS, BTN_SOUND_ON_BKGND_PRESS);
        m_btnSoundOff.Invalidate();
    }
}
@@ -258,8 +296,6 @@
            TRACE("操作失败:地址=1003,错误码=%d\n", nFlag);
        }
    });
    SetButtonBackgroundColors(!bMute);
}
void CAlarmPopupDlg::OnBnClickedButtonAlarmOff()
SourceCode/Bond/BondEq/AlarmPopupDlg.h
@@ -21,6 +21,7 @@
    void AlarmOff();
private:
    void InitRxWindows();
    void ShowFirstAlarm();
    void SetButtonBackgroundColors(bool bMute);
@@ -33,6 +34,7 @@
    CFont m_fontDescription;
private:
    IObserver* m_pObserver;
    CPLC* m_pPLC;
    CAlarm* m_pActiveAlarm;
    CBlButton m_btnClose;
SourceCode/Bond/BondEq/BondEqDlg.cpp
@@ -306,6 +306,13 @@
    logManager.log(SystemLogManager::LogType::Info, _T("BondEq启动..."));
    // 自动启动
    theApp.m_model.getBonder().start();
    m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
    m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE);
    logManager.log(SystemLogManager::LogType::Operation, _T("运行..."));
    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
SourceCode/Bond/BondEq/CBonder.cpp
@@ -5,6 +5,8 @@
#include "CDataMonitor1.h"
#include "AlarmMonitor.h"
#include "LoadMonitor.h"
#include "ToolUnits.h"
#include "Model.h"
CBonder* g_pBonder = NULL;
@@ -37,6 +39,12 @@
    m_strEquipmentModelType = "2860";
    m_strSoftRev = "1.01";
    m_pPlcData = nullptr;
    m_pModel = nullptr;
    m_bMute = false;
    m_nVelocityRatio = 0;
    m_dTactTime = 0.0;
    m_nDayShiftCapacity = 0;
    m_nNightShiftCapacity = 0;
    InitializeCriticalSection(&m_criticalSection);
}
@@ -62,6 +70,11 @@
    m_listener.onPlcStateChanged = listener.onPlcStateChanged;
    m_listener.onEfemStateChanged = listener.onEfemStateChanged;
    m_listener.onRecvBroadcast = listener.onRecvBroadcast;
}
void CBonder::setModel(CModel* pModel)
{
    m_pModel = pModel;
}
const std::vector<CComponent*>& CBonder::getComponents()
@@ -430,6 +443,12 @@
    if (iii % 5 == 0) {
        save();
    }
    // 需要定时读取的数据
    readTaktTime();
    // 测试
@@ -981,3 +1000,128 @@
{
    m_bMute = bMute;
}
double CBonder::getTackTime()
{
    return m_dTactTime;
}
#define ADDR_NIGHT_SHIFT_CAPACTITY        2027
void CBonder::readTaktTime()
{
    CPLC* pPlc = getPLC("PLC(1)");
    if (pPlc == nullptr || !pPlc->isConnected()) return;
    {
        auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
            if (nDataSize == 2 && flag == 0) {
                bool bMute = CToolUnits::toInt16(&pData[0]) != 0;
                if (m_bMute != bMute) {
                    m_bMute = bMute;
                    m_pModel->notify(RX_CODE_BONDER_BEEP);
                }
            }
        };
        pPlc->readData(MC::M, 1003, 2, funOnReadData);
    }
    {
        auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
            if (nDataSize == 2 && flag == 0) {
                int nVelocityRatio = CToolUnits::toInt16(&pData[0]);
                if (nVelocityRatio != m_nVelocityRatio) {
                    m_nVelocityRatio = nVelocityRatio;
                    m_pModel->notifyInt(RX_CODE_BONDER_VELOCITY_RATIO, m_nVelocityRatio);
                }
            }
        };
        pPlc->readData(MC::D, 530, 2, funOnReadData);
    }
    {
        auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
            if (nDataSize == 2 && flag == 0) {
                double dTactTime = (double)CToolUnits::toInt16(&pData[0]);
                if (dTactTime != m_dTactTime) {
                    m_dTactTime = dTactTime;
                    m_pModel->notifyDouble(RX_CODE_BONDER_TACT_TIME, m_dTactTime);
                }
            }
        };
        pPlc->readData(MC::ZR, 1500, 2, funOnReadData);
    }
    {
        auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
            if (nDataSize == (ADDR_NIGHT_SHIFT_CAPACTITY - 2012 + 1) * 2 && flag == 0) {
                int nDayShiftCapacity = CToolUnits::toInt16(&pData[0]);
                int nNightShiftCapacity = CToolUnits::toInt16(&pData[(ADDR_NIGHT_SHIFT_CAPACTITY - 2012) * 2]);
                if (nDayShiftCapacity != m_nDayShiftCapacity) {
                    m_nDayShiftCapacity = nDayShiftCapacity;
                    m_pModel->notifyInt(RX_CODE_BONDER_DAY_SHIFT_CAPACTITY, nDayShiftCapacity);
                }
                if (nNightShiftCapacity != m_nNightShiftCapacity) {
                    m_nNightShiftCapacity = nNightShiftCapacity;
                    m_pModel->notifyInt(RX_CODE_BONDER_NIGHT_SHIFT_CAPACTITY, nNightShiftCapacity);
                }
            }
        };
        pPlc->readData(MC::ZR, 2012, (ADDR_NIGHT_SHIFT_CAPACTITY - 2012 + 1)*2, funOnReadData);
    }
    {
        int nStartAddress = 1000;
        int nEndAddress = 1200;
        int nReadSize = (nEndAddress - nStartAddress + 1) * 2;
        auto funOnReadData = [this, nStartAddress, nReadSize](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
            if (nDataSize == nReadSize && flag == 0) {
                bool bValue0 = CToolUnits::toInt16(&pData[(1103 - nStartAddress) * 2]) != 0; // 启动
                bool bValue1 = CToolUnits::toInt16(&pData[(1100 - nStartAddress) * 2]) != 0; // 自动
                bool bValue2 = CToolUnits::toInt16(&pData[(1104 - nStartAddress) * 2]) != 0; // 暂停
                bool bValue3 = CToolUnits::toInt16(&pData[(1100 - nStartAddress) * 2]) != 0; // 手动
                bool bValue4 = CToolUnits::toInt16(&pData[(1003 - nStartAddress) * 2]) != 0; // 静音
                bool bValue5 = CToolUnits::toInt16(&pData[(1150 - nStartAddress) * 2]) != 0; // 复位
                bool bValue6 = CToolUnits::toInt16(&pData[(1114 - nStartAddress) * 2]) != 0; // ֹͣ
                bValue4 = pData[0] & 0x8;
                bValue3 = pData[100*2/8] & 0x1;
                if (m_bBlBtnsStates[0] != bValue0) {
                    m_bBlBtnsStates[0] = bValue0;
                    m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN0, bValue0);
                }
                if (m_bBlBtnsStates[1] != bValue1) {
                    m_bBlBtnsStates[1] = bValue1;
                    m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN1, bValue1);
                }
                if (m_bBlBtnsStates[2] != bValue2) {
                    m_bBlBtnsStates[2] = bValue2;
                    m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN2, bValue2);
                }
                if (m_bBlBtnsStates[3] != bValue3) {
                    m_bBlBtnsStates[3] = bValue3;
                    m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN3, bValue3);
                }
                if (m_bBlBtnsStates[4] != bValue4) {
                    m_bBlBtnsStates[4] = bValue4;
                    m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN4, bValue4);
                }
                if (m_bBlBtnsStates[5] != bValue5) {
                    m_bBlBtnsStates[5] = bValue5;
                    m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN5, bValue5);
                }
                if (m_bBlBtnsStates[6] != bValue6) {
                    m_bBlBtnsStates[6] = bValue6;
                    m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN6, bValue6);
                }
            }
        };
        pPlc->readData(MC::M, nStartAddress, nReadSize, funOnReadData);
    }
}
SourceCode/Bond/BondEq/CBonder.h
@@ -34,6 +34,7 @@
    ONRECVBROADCAST            onRecvBroadcast;
} BondListener;
class CModel;
class CBonder
{
public:
@@ -45,6 +46,7 @@
    void setListener(BondListener& listener);
    void setWorkDir(const char* pszWorkDir);
    const std::vector<CComponent*>& getComponents();
    void setModel(CModel* pModel);
    CPLC* getPLC(const char* pszName);
    int init();
    int term();
@@ -69,8 +71,10 @@
    int loadReady(BEQ::IUnit* pUnit, const char* pszMaterielId, const char* pszRecipeId);
    int loadComplete(BEQ::IUnit* pUnit, int layer);
    int unloadComplete(BEQ::IUnit* pUnit, int layer);
    double getTackTime();
    bool isMute();
    void setMute(bool bMute);
    void readTaktTime();
public:
    int writeInt(int unitId, int addr, int value);
@@ -113,10 +117,18 @@
    BOOL m_bAreYouThereRequest;
private:
    CModel* m_pModel;
    char* m_pPlcData;
    BEQ::IEquipment* m_pEquipment;
    std::map<int, CRecipe*> m_recipes;
    std::string m_strCurRecipeName;
private:
    bool m_bMute;
    bool m_bBlBtnsStates[7];    // 主页面按钮状态
    int m_nVelocityRatio;        // 速度比
    double m_dTactTime;            // 周期时间
    int m_nDayShiftCapacity;
    int m_nNightShiftCapacity;
};
SourceCode/Bond/BondEq/CProjectPageMain.cpp
@@ -23,14 +23,16 @@
    m_hbrBkgnd = nullptr;
    m_pObserver = nullptr;
    nVelocityRatio = 0.0;
    dTactTime = 0.0;
    nDayShiftCapacity = 0;
    nNightShiftCapacity = 0;
    for (int i = 0; i < BTN_MAX; i++) {
        m_pBlBtns[i] = new CBlButton();
    }
}
CProjectPageMain::~CProjectPageMain()
{
    for (int i = 0; i < BTN_MAX; i++) {
        delete m_pBlBtns[i];
    }
}
void CProjectPageMain::SetPLC(CPLC* pPLC)
@@ -107,47 +109,6 @@
    });
}
void CProjectPageMain::ReadPLCDataToUI()
{
    ASSERT(m_pPLC->isConnected());
    // 总任务数
    int nPendingTasks = 5;
    auto createReadTask = [this, &nPendingTasks](MC::SOFT_COMPONENT type, int nAddr, auto onProcessData) {
        return [this, &nPendingTasks, onProcessData](IMcChannel* pChannel, int nAddr, char* pData, unsigned int nDataSize, int nFlag) {
            if (nDataSize == 2 && nFlag == 0 && ::IsWindow(m_hWnd)) {
                onProcessData(CToolUnits::toInt16(&pData[0]));
            }
            // 任务完成,减少计数
            if (--nPendingTasks == 0) {
                PostMessage(ID_MSG_UPDATA_DATA_TO_UI);
            }
        };
    };
    m_pPLC->readData(MC::M, 1003, 2, createReadTask(MC::M, 1003, [this](int nValue) {
        theApp.m_model.getBonder().setMute(nValue != 0);
    }));
    m_pPLC->readData(MC::D, 530, 2, createReadTask(MC::D, 530, [this](int nValue) {
        nVelocityRatio = static_cast<unsigned int>(nValue);
    }));
    m_pPLC->readData(MC::ZR, 1500, 2, createReadTask(MC::ZR, 1500, [this](int nValue) {
        dTactTime = nValue;
    }));
    m_pPLC->readData(MC::ZR, 2012, 2, createReadTask(MC::ZR, 2012, [this](int nValue) {
        nDayShiftCapacity = nValue;
    }));
    m_pPLC->readData(MC::ZR, 2027, 2, createReadTask(MC::ZR, 2027, [this](int nValue) {
        nNightShiftCapacity = nValue;
    }));
}
BEGIN_MESSAGE_MAP(CProjectPageMain, CDialogEx)
    ON_WM_CTLCOLOR()
    ON_WM_DESTROY()
@@ -178,9 +139,82 @@
            // onNext
            pAny->addRef();
            int code = pAny->getCode();
            //if (true) {
            if (RX_CODE_BONDER_BEEP == code) {
                bool bMute = theApp.m_model.getBonder().isMute();
                GetDlgItem(IDC_BUTTON_SOUND_OFF)->SetWindowText(bMute ? _T("静音") : _T("声音"));
            }
            else if (RX_CODE_BONDER_VELOCITY_RATIO == code) {
                int nVelocityRatio;
                if (pAny->getIntValue("exCode", nVelocityRatio)) {
                    CString strText;
                    strText.Format(_T("%d %s"), nVelocityRatio, _T("%"));
                    GetDlgItem(IDC_EDIT_VELOCITY_RATIO)->SetWindowText(strText);
                }
            }
            else if (RX_CODE_BONDER_TACT_TIME == code) {
                double dTactTime;
                if (pAny->getDoubleValue("value", dTactTime)) {
                    CString strText;
                    strText.Format(_T("%.2f"), dTactTime);
                    GetDlgItem(IDC_EDIT_TACT_TIME)->SetWindowText(strText);
                }
            }
            else if (RX_CODE_BONDER_DAY_SHIFT_CAPACTITY == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetDlgItemInt(IDC_EDIT_DAY_SHIFT_CAPACITY, capactity);
                }
            }
            else if (RX_CODE_BONDER_NIGHT_SHIFT_CAPACTITY == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetDlgItemInt(IDC_EDIT_NIGHT_SHIFT_CAPACITY, capactity);
                }
            }
            // 临时添加
            else if (RX_CODE_BONDER_STATES_BTN0 == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetButtonBackgroundColors(m_pBlBtns[BTN_RUN], capactity == 0);
                }
            }
            else if (RX_CODE_BONDER_STATES_BTN1 == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetButtonBackgroundColors(m_pBlBtns[BTN_AUTO], capactity == 0);
                }
            }
            else if (RX_CODE_BONDER_STATES_BTN2 == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetButtonBackgroundColors(m_pBlBtns[BTN_PUASE], capactity == 0);
                }
            }
            else if (RX_CODE_BONDER_STATES_BTN3 == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetButtonBackgroundColors(m_pBlBtns[BTN_MANUAL], capactity == 0);
                }
            }
            else if (RX_CODE_BONDER_STATES_BTN4 == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetButtonBackgroundColors(m_pBlBtns[BTN_MUTE], capactity == 0);
                }
            }
            else if (RX_CODE_BONDER_STATES_BTN5 == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetButtonBackgroundColors(m_pBlBtns[BTN_OPR], capactity == 0);
                }
            }
            else if (RX_CODE_BONDER_STATES_BTN6 == code) {
                int capactity;
                if (pAny->getIntValue("exCode", capactity)) {
                    SetButtonBackgroundColors(m_pBlBtns[BTN_STOP], capactity == 0);
                }
            }
            //}
            pAny->release();
        }, [&]() -> void {
            // onComplete
@@ -194,12 +228,49 @@
    }
}
void CProjectPageMain::SetButtonBackgroundColors(CBlButton* btn, bool bOff)
{
    if (bOff) {
        btn->SetBkgndColor(BS_NORMAL, BTN_SOUND_OFF_BKGND_NORMAL);
        btn->SetBkgndColor(BS_HOVER, BTN_SOUND_OFF_BKGND_HOVER);
        btn->SetBkgndColor(BS_PRESS, BTN_SOUND_OFF_BKGND_PRESS);
        btn->Invalidate();
    }
    else {
        btn->SetBkgndColor(BS_NORMAL, BTN_SOUND_ON_BKGND_NORMAL);
        btn->SetBkgndColor(BS_HOVER, BTN_SOUND_ON_BKGND_HOVER);
        btn->SetBkgndColor(BS_PRESS, BTN_SOUND_ON_BKGND_PRESS);
        btn->Invalidate();
    }
}
BOOL CProjectPageMain::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    InitRxWindows();
    SetTimer(TIMER_READ_PLC_DATA, 500, nullptr);
    // 按钮初始化
    m_pBlBtns[BTN_RUN]->SubclassDlgItem(IDC_BUTTON_ACTIVATE, this);
    m_pBlBtns[BTN_AUTO]->SubclassDlgItem(IDC_BUTTON_AUTO, this);
    m_pBlBtns[BTN_PUASE]->SubclassDlgItem(IDC_BUTTON_PUASE, this);
    m_pBlBtns[BTN_MANUAL]->SubclassDlgItem(IDC_BUTTON_MANUAL_OPERATION, this);
    m_pBlBtns[BTN_MUTE]->SubclassDlgItem(IDC_BUTTON_SOUND_OFF, this);
    m_pBlBtns[BTN_OPR]->SubclassDlgItem(IDC_BUTTON_RESETTING, this);
    m_pBlBtns[BTN_STOP]->SubclassDlgItem(IDC_BUTTON_STOP, this);
    for (int i = 0; i < BTN_MAX; i++) {
        m_pBlBtns[i]->SetFrameColor(BS_NORMAL, BTN_SOUND_OFF_FRAME_NORMAL);
        m_pBlBtns[i]->SetFrameColor(BS_HOVER, BTN_SOUND_OFF_FRAME_HOVER);
        m_pBlBtns[i]->SetFrameColor(BS_PRESS, BTN_SOUND_OFF_FRAME_PRESS);
    }
    // 初始值
    SetDlgItemText(IDC_EDIT_VELOCITY_RATIO, _T("0 %"));
    SetDlgItemText(IDC_EDIT_TACT_TIME, _T("0.00"));
    SetDlgItemText(IDC_EDIT_DAY_SHIFT_CAPACITY, _T("0"));
    SetDlgItemText(IDC_EDIT_NIGHT_SHIFT_CAPACITY, _T("0"));
    return TRUE;  // return TRUE unless you set the focus to a control
    // 异常: OCX 属性页应返回 FALSE
}
@@ -242,14 +313,6 @@
void CProjectPageMain::OnTimer(UINT_PTR nIDEvent)
{
    if (TIMER_READ_PLC_DATA == nIDEvent) {
        ASSERT(m_pPLC);
        if (m_pPLC != nullptr && m_pPLC->isConnected()) {
            ReadPLCDataToUI();
        }
    }
    CDialogEx::OnTimer(nIDEvent);
}
@@ -306,6 +369,7 @@
LRESULT CProjectPageMain::OnUpdateDataToUI(WPARAM wParam, LPARAM lParam)
{
    /*
    CString strText;
    strText.Format(_T("%d %s"), nVelocityRatio, _T("%"));
    GetDlgItem(IDC_EDIT_VELOCITY_RATIO)->SetWindowText(strText);
@@ -315,6 +379,6 @@
    SetDlgItemInt(IDC_EDIT_DAY_SHIFT_CAPACITY, nDayShiftCapacity);
    SetDlgItemInt(IDC_EDIT_NIGHT_SHIFT_CAPACITY, nNightShiftCapacity);
    */
    return 0;
}
SourceCode/Bond/BondEq/CProjectPageMain.h
@@ -1,5 +1,16 @@
#pragma once
#include "afxdialogex.h"
#include "BlButton.h"
// BUTTON控件
#define BTN_MAX            7
#define BTN_RUN            0
#define BTN_AUTO        1
#define BTN_PUASE        2
#define BTN_MANUAL        3
#define BTN_MUTE        4
#define BTN_OPR            5
#define BTN_STOP        6
// CProjectPageMain 对话框
@@ -26,9 +37,9 @@
private:
    void InitRxWindows();
    void SetButtonBackgroundColors(CBlButton* btn, bool bOff);
    void HandleOperation(OperationType eOpType);
    void WriteOperationDataToPLC(OperationType eOpType, bool bPressed);
    void ReadPLCDataToUI();
private:
    COLORREF m_crBkgnd;
@@ -36,10 +47,9 @@
    IObserver* m_pObserver;
    CPLC* m_pPLC;
    int nVelocityRatio;            // 速度比
    double dTactTime;            // 周期时间
    int nDayShiftCapacity;
    int nNightShiftCapacity;
private:
    // 控件
    CBlButton* m_pBlBtns[BTN_MAX];
// 对话框数据
#ifdef AFX_DESIGN_TIME
SourceCode/Bond/BondEq/Common.h
@@ -37,6 +37,21 @@
#define RX_CODE_EFEM_STATUS_CHANGED        1015
#define RX_CODE_EQ_STATE_CHANGED        1016
#define RX_CODE_SELECT_COMPONENT        1017
#define RX_CODE_BONDER_BEEP                1018
#define RX_CODE_BONDER_VELOCITY_RATIO    1019
#define RX_CODE_BONDER_TACT_TIME        1020
#define RX_CODE_BONDER_DAY_SHIFT_CAPACTITY        1021
#define RX_CODE_BONDER_NIGHT_SHIFT_CAPACTITY    1022
// 临时添加 m_bBlBtnsStates[7]
#define RX_CODE_BONDER_STATES_BTN0                1023
#define RX_CODE_BONDER_STATES_BTN1                1024
#define RX_CODE_BONDER_STATES_BTN2                1025
#define RX_CODE_BONDER_STATES_BTN3                1026
#define RX_CODE_BONDER_STATES_BTN4                1027
#define RX_CODE_BONDER_STATES_BTN5                1028
#define RX_CODE_BONDER_STATES_BTN6                1029
/* 广播代码 */
#define BC_CODE_DATA1_MATERIAL_RECEIVED    5000
SourceCode/Bond/BondEq/Model.cpp
@@ -175,6 +175,7 @@
        }
    };
    m_bonder.setListener(bonderListener);
    m_bonder.setModel(this);
    m_bonder.init();
@@ -290,6 +291,39 @@
    return 0;
}
int CModel::notifyInt2(int code, int exCode, int exCode2)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setIntValue("exCode", exCode);
            pAny->setIntValue("exCode2", exCode2);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyDouble(int code, double dValue)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setDoubleValue("value", dValue);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyObjAndInt(int code, IRxObject* pObj1, IRxObject* pObj2, int exCode)
{
    if (m_pObservableEmitter != NULL) {
SourceCode/Bond/BondEq/Model.h
@@ -27,6 +27,8 @@
    int notifyObjAndPtr(int code, IRxObject* pObj, void* ptr);
    int notifyObjAndInt(int code, IRxObject* pObj1, IRxObject* pObj2, int exCode);
    int notifyInt(int code, int exCode);
    int notifyInt2(int code, int exCode, int exCode2);
    int notifyDouble(int code, double dValue);
    int notifyText(int code, const char* pszText);
    int notifyPtrAndInt(int code, void* ptr1, void* ptr2, int exCode);
    int notifyTextAndInt(int code, const char* pszText, int exCode);
SourceCode/Bond/GangBond2860.sln
@@ -11,6 +11,8 @@
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BondEq", "BondEq\BondEq.vcxproj", "{7864134E-C538-4C0F-AF24-215FFCCBBAB4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Servo", "Servo\Servo.vcxproj", "{66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x64 = Debug|x64
@@ -51,6 +53,14 @@
        {7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Release|x64.Build.0 = Release|x64
        {7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Release|x86.ActiveCfg = Release|Win32
        {7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Release|x86.Build.0 = Release|Win32
        {66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}.Debug|x64.ActiveCfg = Debug|x64
        {66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}.Debug|x64.Build.0 = Debug|x64
        {66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}.Debug|x86.ActiveCfg = Debug|Win32
        {66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}.Debug|x86.Build.0 = Debug|Win32
        {66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}.Release|x64.ActiveCfg = Release|x64
        {66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}.Release|x64.Build.0 = Release|x64
        {66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}.Release|x86.ActiveCfg = Release|Win32
        {66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}.Release|x86.Build.0 = Release|Win32
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE