LAPTOP-SNT8I5JK\Boounion
2024-11-14 314b85f99c1a85c61a3233323160e9626a5f0540
1.移入项目文件;
已添加71个文件
已修改13个文件
已删除2个文件
8318 ■■■■■ 文件已修改
SourceCode/Bond/BEQLibrary/BEQCommon.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BEQLibrary/Equipment.cpp 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BEQLibrary/Equipment.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BEQLibrary/IUnit.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BEQLibrary/Unit.cpp 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BEQLibrary/Unit.h 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BEQLibrarySDK/Include/IUnit.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Alarm.cpp 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Alarm.h 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/AlarmMonitor.cpp 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/AlarmMonitor.h 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/BondEq.cpp 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/BondEq.vcxproj 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/BondEqDlg.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Bonder.cpp 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Bonder.h 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CBonder.cpp 1044 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CBonder.h 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CDataMonitor1.cpp 412 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CDataMonitor1.h 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CPLC.cpp 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CPLC.h 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CPanel.cpp 1006 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CPanel.h 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CParam.cpp 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/CParam.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Common.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Component.cpp 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Component.h 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Context.cpp 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Context.h 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/EQState.cpp 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/EQState.h 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/EQStateMonitor.cpp 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/EQStateMonitor.h 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Intent.cpp 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Intent.h 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/LoadMonitor.cpp 419 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/LoadMonitor.h 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/McBool.cpp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/McBool.h 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/McInt.cpp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/McInt.h 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/McItem.cpp 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/McItem.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/McString.cpp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/McString.h 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Model.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Recipe.cpp 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Recipe.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/stdafx.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo.vcxproj.filters 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo.sln 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/McDemo.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/McDemo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/McDemo.vcxproj.filters 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/mcdemo.cpp 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/mcdemo.vcxproj 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/mcdemodlg.cpp 769 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/mcdemodlg.h 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/readme.txt 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/res/McDemo.ico 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/res/McDemo.rc2 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/res/application.exe.manifest 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/stdafx.cpp 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/stdafx.h 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/targetver.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemoDlg.cpp 794 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/McDemoDlg.h 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/mcdemo.cpp 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/mcdemo.vcxproj 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/readme.txt 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/res/McDemo.ico 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/res/McDemo.rc2 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/res/application.exe.manifest 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/stdafx.cpp 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/stdafx.h 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/McDemo/targetver.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/Readme.docx 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/Readme.pdf 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/include/IMcChannel.h 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/McLibrarySDK/include/McLib.h 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BEQLibrary/BEQCommon.h
@@ -80,5 +80,6 @@
/* EVENT */
#define EVENT_NOTREADY            _T("NOTREADY")
#define EVENT_LOAD                _T("LOAD")
#define EVENT_UNLOAD            _T("UNLOAD")
SourceCode/Bond/BEQLibrary/Equipment.cpp
@@ -144,6 +144,11 @@
                repData(m_pActiveClient, (CUnit*)pUnit, AS_MC_INFO_REP);
            }
        };
        listener.onReqNotReady = [&](void* pUnit, int layer) -> void {
            if (m_pActiveClient != nullptr) {
                repNotReady(m_pActiveClient, (CUnit*)pUnit, layer, AS_SEND_EVENT_REP);
            }
        };
        listener.onReqLoad = [&](void* pUnit, int layer) -> void {
            if (m_pActiveClient != nullptr) {
                repLoad(m_pActiveClient, (CUnit*)pUnit, layer, AS_SEND_EVENT_REP);
@@ -836,6 +841,27 @@
        return 0;
    }
    void CEquipment::repNotReady(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply)
    {
        ASSERT(pClient != nullptr);
        CString strReply;
        if (pUnit->getLayerCount() == 1) {
            strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s#"), pszReply,
                PARAM_EQID, m_strName.c_str(),
                PARAM_UNIT, pUnit->getName().c_str(),
                PARAM_EVENT, EVENT_NOTREADY);
        }
        else {
            strReply.Format(_T("%s@%s=%s/%s=%s%d/%s=%s#"), pszReply,
                PARAM_EQID, m_strName.c_str(),
                PARAM_UNIT, pUnit->getName().c_str(), layer,
                PARAM_EVENT, EVENT_NOTREADY);
        }
        pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
    }
    void CEquipment::repLoad(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply)
    {
        ASSERT(pClient != nullptr);
SourceCode/Bond/BEQLibrary/Equipment.h
@@ -48,6 +48,7 @@
        void repData(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply);
        void repRecipeList(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply);
        void repRunRecipe(CAcceptClient* pClient, CUnit* pUnit, int id, const char* pszName, const char* pszReply);
        void repNotReady(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply);
        void repLoadReady(CAcceptClient* pClient, CUnit* pUnit, const char* pszUnitName, const char* pszMaterielId, const char* pszRecipeId, const char* pszReply);
        void repLoad(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply);
        void repUnload(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply);
SourceCode/Bond/BEQLibrary/IUnit.h
@@ -49,6 +49,7 @@
        virtual unsigned long long getDataTime() = 0;
        virtual void addData(const char* pszName, const char* pszDataText, bool bComplete) = 0;
        virtual void addRecipe(int id, const char* pszName, bool bComplete) = 0;
        virtual int reqNotReady(int layer) = 0;
        virtual int reqLoad(int layer) = 0;
        virtual int reqUnload(int layer) = 0;
    };
SourceCode/Bond/BEQLibrary/Unit.cpp
@@ -62,6 +62,7 @@
        m_listener.onRemoveAlarm = listener.onRemoveAlarm;
        m_listener.onStepChanged = listener.onStepChanged;
        m_listener.onDataChanged = listener.onDataChanged;
        m_listener.onReqNotReady = listener.onReqNotReady;
        m_listener.onReqLoad = listener.onReqLoad;
        m_listener.onReqUnload = listener.onReqUnload;
    }
@@ -212,6 +213,22 @@
        return m_strAlarmText;
    }
    int CUnit::reqNotReady(int layer)
    {
        ASSERT(m_listener.onReqNotReady);
        if (layer <= 0) return -1;
        if (layer > m_nLayerCount) return -2;
        // çŠ¶æ€æ”¹å˜æ‰å›žè°ƒåˆ°ä¸Šå±‚
        if (m_nLayerLoadState[layer - 1] != LAYER_NOT_READY) {
            m_nLayerLoadState[layer - 1] = LAYER_NOT_READY;
            m_listener.onReqNotReady(this, layer);
            return 0;
        }
        return -3;
    }
    int CUnit::reqLoad(int layer)
    {
        ASSERT(m_listener.onReqLoad);
SourceCode/Bond/BEQLibrary/Unit.h
@@ -6,8 +6,9 @@
#define LAYER_LOAD_INIT        0
#define LAYER_LOAD_REQ        1
#define LAYER_UNLOAD_REQ    2
#define LAYER_NOT_READY        1
#define LAYER_LOAD_REQ        2
#define LAYER_UNLOAD_REQ    3
namespace BEQ {
    typedef std::function<void(void* pUnit, EQ_STATE)> ONSTATECHANGED;
@@ -25,6 +26,7 @@
        ONALARM                onRemoveAlarm;
        ONSTEPCHANGED        onStepChanged;
        ONDATACHANGED        onDataChanged;
        ONREQLOAD            onReqNotReady;
        ONREQLOAD            onReqLoad;
        ONREQLOAD            onReqUnload;
    } UnitListener;
@@ -63,6 +65,7 @@
        virtual unsigned long long getDataTime();
        virtual void addData(const char* pszName, const char* pszDataText, bool bComplete);
        virtual void addRecipe(int id, const char* pszName, bool bComplete);
        virtual int reqNotReady(int layer);
        virtual int reqLoad(int layer);
        virtual int reqUnload(int layer);
        
SourceCode/Bond/BEQLibrarySDK/Include/IUnit.h
@@ -49,6 +49,7 @@
        virtual unsigned long long getDataTime() = 0;
        virtual void addData(const char* pszName, const char* pszDataText, bool bComplete) = 0;
        virtual void addRecipe(int id, const char* pszName, bool bComplete) = 0;
        virtual int reqNotReady(int layer) = 0;
        virtual int reqLoad(int layer) = 0;
        virtual int reqUnload(int layer) = 0;
    };
SourceCode/Bond/BondEq/Alarm.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
#include "stdafx.h"
#include "Alarm.h"
#include "ToolUnits.h"
CAlarm::CAlarm()
{
}
CAlarm::CAlarm(int unitId, int status, int id, int level, const char* pszText)
{
    m_nUnitId = unitId;
    m_nStatus = status;
    m_time = CToolUnits::getTimestamp();
    m_nId = id;
    m_nLevel = level;
    m_strText = pszText;
}
CAlarm::~CAlarm()
{
}
std::string& CAlarm::getClassName()
{
    static std::string strName = "CAlarm";
    return strName;
}
std::string CAlarm::toString()
{
    std::string strText;
    strText += "CAlarm[";
    strText += ("time:" + CToolUnits::timeToString2(m_time) + ";");
    strText += ("m_nStatus:" + std::to_string(m_nStatus) + ";");
    strText += ("m_nId:" + std::to_string(m_nId) + ";");
    strText += ("m_nLevel:" + std::to_string(m_nLevel) + ";");
    strText += ("m_strText:" + m_strText + ";");
    strText += "]";
    return strText;
}
int CAlarm::getUnitId()
{
    return m_nUnitId;
}
ULONGLONG CAlarm::getTime()
{
    return m_time;
}
int CAlarm::getId()
{
    return m_nId;
}
int CAlarm::getLevel()
{
    return m_nLevel;
}
int CAlarm::getStatus()
{
    return m_nStatus;
}
std::string& CAlarm::getText()
{
    return m_strText;
}
void CAlarm::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        Lock();
        ar << m_time;
        ar << m_nStatus;
        ar << m_nId;
        ar << m_nLevel;
        WriteString(ar, m_strText);
        Unlock();
    }
    else
    {
        Lock();
        ar >> m_time;
        ar >> m_nStatus;
        ar >> m_nId;
        ar >> m_nLevel;
        ReadString(ar, m_strText);
        Unlock();
    }
}
SourceCode/Bond/BondEq/Alarm.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
#pragma once
#include "Context.h"
class CAlarm :
    public CContext
{
public:
    CAlarm();
    CAlarm(int unitId, int status, int id, int level, const char* pszText);
    ~CAlarm();
public:
    virtual std::string& getClassName();
    virtual std::string toString();
    int getUnitId();
    ULONGLONG getTime();
    int getId();
    int getLevel();
    int getStatus();
    std::string& getText();
    void Serialize(CArchive& ar);
private:
    int m_nUnitId;
    ULONG64 m_time;
    int m_nStatus;
    int m_nId;
    int m_nLevel;
    std::string m_strText;
};
SourceCode/Bond/BondEq/AlarmMonitor.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,176 @@
#include "stdafx.h"
#include "AlarmMonitor.h"
#include "Common.h"
#include "CBonder.h"
#include "Log.h"
#define ALARM_MAX        200
CAlarmMonitor::CAlarmMonitor()
{
    m_nBeginAddr = 0;
    m_nLastId = 0;
    m_nLastLevel = 0;
}
CAlarmMonitor::~CAlarmMonitor()
{
}
std::string& CAlarmMonitor::getClassName()
{
    static std::string strClassName = "CAlarmMonitor";
    return strClassName;
}
void CAlarmMonitor::onRecvBroadcast(void* pSender, CIntent* pIntent)
{
}
void CAlarmMonitor::onData(int id, const void* pData, int size)
{
    const char* pszData = (const char*)pData;
    if (m_nIndex + 1 == id) {
        int addr = m_nBeginAddr * 2;
        int alarmId = (pszData[addr] & 0xff) | (pszData[addr + 1] & 0xff) << 8;
        int alarmLevel = (pszData[addr + 2] & 0xff) | (pszData[addr + 3] & 0xff) << 8;
        if (m_nLastId != alarmId) {
            LOGI("<CAlarmMonitor-%d>AlarmId:%d, AlarmLevel:%d", m_nIndex, alarmId, alarmLevel);
            Alarm(alarmId, alarmLevel);
        }
    }
}
int CAlarmMonitor::readAlarmListFromFile(const char* pszFilepath)
{
    CStdioFile file;
    if (!file.Open(pszFilepath, CFile::modeRead)) {
        return -1;
    }
    CString strLine, strNumber, strDescription;
    while (file.ReadString(strLine)) {
        int index = strLine.Find(",");
        if (index <= 0) continue;
        strNumber = strLine.Left(index).Trim();
        strDescription = strLine.Right(strLine.GetLength() - index - 1).Trim();
        int number = atoi(strNumber);
        m_mapAlarmText[number] = std::string((LPTSTR)(LPCTSTR)strDescription);
    }
    file.Close();
    return (int)m_mapAlarmText.size();
}
void CAlarmMonitor::init()
{
    CComponent::init();
}
void CAlarmMonitor::term()
{
    for (auto item : m_alarms) {
        item->release();
    }
}
void CAlarmMonitor::setBeginAddr(int nAddr)
{
    m_nBeginAddr = nAddr;
}
void CAlarmMonitor::OnTimer(UINT nTimerid)
{
}
const char* CAlarmMonitor::getAlarmText(int nID)
{
    auto iter = m_mapAlarmText.find(nID);
    if (iter == m_mapAlarmText.end()) return "";
    return iter->second.c_str();
}
void CAlarmMonitor::Alarm(int id, int level)
{
    BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex);
    ASSERT(pUnit);
    if (id != 0) {
        // è­¦å‘Š
        pUnit->setAlarm(id, level, getAlarmText(id));
        LOGI("<CAlarmMonitor-%d>设备告警(%d, %d).", m_nIndex, id, level);
        CAlarm* pAlarm = new CAlarm(m_nIndex, 1, id, level, getAlarmText(id));
        AddAlarm(pAlarm);
        SendBroadcast(&CIntent(BC_CODE_ALARM_EVENT, "", pAlarm));
        m_nLastId = id;
        m_nLastLevel = level;
    }
    else {
        // è§£é™¤è­¦å‘Š
        pUnit->setAlarm(0, 0, "");
        LOGI("<CAlarmMonitor-%d>解除设备告警(%d, %d).", m_nIndex, m_nLastId, m_nLastLevel);
        CAlarm* pAlarm = new CAlarm(m_nIndex, 2, m_nLastId, m_nLastLevel, getAlarmText(m_nLastId));
        AddAlarm(pAlarm);
        SendBroadcast(&CIntent(BC_CODE_ALARM_EVENT, "", pAlarm));
        m_nLastId = 0;
        m_nLastLevel = 0;
    }
}
void CAlarmMonitor::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        Lock();
        int count = (int)m_alarms.size();
        ar << count;
        for (auto item : m_alarms) {
            item->Serialize(ar);
        }
        Unlock();
    }
    else
    {
        Lock();
        int count;
        ar >> count;
        for (int i = 0; i < count; i++) {
            CAlarm* pAlarm = new CAlarm();
            pAlarm->addRef();
            pAlarm->Serialize(ar);
            AddAlarm(pAlarm);
            pAlarm->release();
        }
        Unlock();
    }
}
void CAlarmMonitor::AddAlarm(CAlarm* pAlarm)
{
    Lock();
    pAlarm->addRef();
    m_alarms.push_back(pAlarm);
    if (m_alarms.size() > ALARM_MAX) {
        CAlarm* pTemp = m_alarms.front();
        pTemp->release();
        m_alarms.pop_front();
    }
    Unlock();
}
void CAlarmMonitor::getAlarmList(std::list<CAlarm*>& list)
{
    Lock();
    list = m_alarms;
    Unlock();
}
SourceCode/Bond/BondEq/AlarmMonitor.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
#pragma once
#include "Component.h"
#include <map>
#include <list>
#include "Alarm.h"
class CAlarmMonitor :
    public CComponent
{
public:
    CAlarmMonitor();
    ~CAlarmMonitor();
public:
    virtual std::string& getClassName();
    virtual void onData(int id, const void* pData, int size);
    virtual void onRecvBroadcast(void* pSender, CIntent* pIntent);
    virtual void init();
    virtual void term();
    void setBeginAddr(int nAddr);
    int readAlarmListFromFile(const char* pszFilepath);
    virtual void OnTimer(UINT nTimerid);
    const char* getAlarmText(int nID);
    void Alarm(int id, int level);
    virtual void Serialize(CArchive& ar);
    void getAlarmList(std::list<CAlarm*>& list);
private:
    void AddAlarm(CAlarm* pAlarm);
private:
    int m_nBeginAddr;
private:
    std::map<int, std::string> m_mapAlarmText;
    int m_nLastId;
    int m_nLastLevel;
    std::list<CAlarm*> m_alarms;
};
SourceCode/Bond/BondEq/BondEq.cpp
@@ -101,6 +101,17 @@
    RX_Init();
    CString strIniFile;
    strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)m_strAppDir);
    int plcTimeout = GetPrivateProfileInt("PLC", "Timeout", 700, strIniFile);
    int plcBufSize = GetPrivateProfileInt("PLC", "BufSize", 20, strIniFile);
    int plcPacketSize = GetPrivateProfileInt("PLC", "PacketSize", 80, strIniFile);
    MCL_Initialize();
    MCL_SetTimeout(plcTimeout);
    MCL_SetMaxActionSize(plcBufSize);
    MCL_SetPacketSize(plcPacketSize);
    // è‡ªå®šä¹‰ç»„ä»¶
    CAccordionWnd::RegisterWndClass();
    CVerticalLine::RegisterWndClass();
@@ -143,6 +154,7 @@
{
    BEQ_Term();
    RX_Term();
    MCL_Term();
    return CWinApp::ExitInstance();
}
SourceCode/Bond/BondEq/BondEq.vcxproj
@@ -190,13 +190,22 @@
    <Text Include="ReadMe.txt" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="CPLC.h" />
    <ClInclude Include="AccordionWnd.h" />
    <ClInclude Include="Alarm.h" />
    <ClInclude Include="AlarmMonitor.h" />
    <ClInclude Include="ApredTreeCtrl.h" />
    <ClInclude Include="BaseSetPage.h" />
    <ClInclude Include="BlButton.h" />
    <ClInclude Include="BondEq.h" />
    <ClInclude Include="BondEqDlg.h" />
    <ClInclude Include="CBaseView.h" />
    <ClInclude Include="CBonder.h" />
    <ClInclude Include="CDataMonitor1.h" />
    <ClInclude Include="Component.h" />
    <ClInclude Include="Context.h" />
    <ClInclude Include="CPanel.h" />
    <ClInclude Include="CParam.h" />
    <ClInclude Include="CRemoteEqUnitView.h" />
    <ClInclude Include="CRemoteEqView.h" />
    <ClInclude Include="CHomeDialog.h" />
@@ -207,15 +216,23 @@
    <ClInclude Include="Configuration.h" />
    <ClInclude Include="CPanelProject.h" />
    <ClInclude Include="DBManager\UserManager.h" />
    <ClInclude Include="EQState.h" />
    <ClInclude Include="EQStateMonitor.h" />
    <ClInclude Include="HmTab.h" />
    <ClInclude Include="HmVerticalTab.h" />
    <ClInclude Include="HorizontalLine.h" />
    <ClInclude Include="Intent.h" />
    <ClInclude Include="LoadMonitor.h" />
    <ClInclude Include="Log.h" />
    <ClInclude Include="LogEdit.h" />
    <ClInclude Include="McBool.h" />
    <ClInclude Include="McInt.h" />
    <ClInclude Include="McItem.h" />
    <ClInclude Include="McString.h" />
    <ClInclude Include="Model.h" />
    <ClInclude Include="CPageAlarm.h" />
    <ClInclude Include="Recipe.h" />
    <ClInclude Include="Resource.h" />
    <ClInclude Include="Bonder.h" />
    <ClInclude Include="SetPage1.h" />
    <ClInclude Include="SetPage2.h" />
    <ClInclude Include="SettingsDlg.h" />
@@ -228,13 +245,22 @@
    <ClInclude Include="View\LoginDlg.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="CPLC.cpp" />
    <ClCompile Include="AccordionWnd.cpp" />
    <ClCompile Include="Alarm.cpp" />
    <ClCompile Include="AlarmMonitor.cpp" />
    <ClCompile Include="ApredTreeCtrl.cpp" />
    <ClCompile Include="BaseSetPage.cpp" />
    <ClCompile Include="BlButton.cpp" />
    <ClCompile Include="BondEq.cpp" />
    <ClCompile Include="BondEqDlg.cpp" />
    <ClCompile Include="CBaseView.cpp" />
    <ClCompile Include="CBonder.cpp" />
    <ClCompile Include="CDataMonitor1.cpp" />
    <ClCompile Include="Component.cpp" />
    <ClCompile Include="Context.cpp" />
    <ClCompile Include="CPanel.cpp" />
    <ClCompile Include="CParam.cpp" />
    <ClCompile Include="CRemoteEqUnitView.cpp" />
    <ClCompile Include="CRemoteEqView.cpp" />
    <ClCompile Include="CHomeDialog.cpp" />
@@ -244,14 +270,22 @@
    <ClCompile Include="Configuration.cpp" />
    <ClCompile Include="CPanelProject.cpp" />
    <ClCompile Include="DBManager\UserManager.cpp" />
    <ClCompile Include="EQState.cpp" />
    <ClCompile Include="EQStateMonitor.cpp" />
    <ClCompile Include="HmTab.cpp" />
    <ClCompile Include="HmVerticalTab.cpp" />
    <ClCompile Include="HorizontalLine.cpp" />
    <ClCompile Include="Intent.cpp" />
    <ClCompile Include="LoadMonitor.cpp" />
    <ClCompile Include="Log.cpp" />
    <ClCompile Include="LogEdit.cpp" />
    <ClCompile Include="McBool.cpp" />
    <ClCompile Include="McInt.cpp" />
    <ClCompile Include="McItem.cpp" />
    <ClCompile Include="McString.cpp" />
    <ClCompile Include="Model.cpp" />
    <ClCompile Include="CPageAlarm.cpp" />
    <ClCompile Include="Bonder.cpp" />
    <ClCompile Include="Recipe.cpp" />
    <ClCompile Include="SetPage1.cpp" />
    <ClCompile Include="SetPage2.cpp" />
    <ClCompile Include="SettingsDlg.cpp" />
SourceCode/Bond/BondEq/BondEqDlg.cpp
@@ -7,7 +7,7 @@
#include "BondEqDlg.h"
#include "afxdialogex.h"
#include "Common.h"
#include "Bonder.h"
#include "CBonder.h"
#include "SettingsDlg.h"
#include "UserManager.h"
#include "LoginDlg.h"
SourceCode/Bond/BondEq/Bonder.cpp
ÎļþÒÑɾ³ý
SourceCode/Bond/BondEq/Bonder.h
ÎļþÒÑɾ³ý
SourceCode/Bond/BondEq/CBonder.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1044 @@
#include "stdafx.h"
#include "CBonder.h"
#include "Log.h"
#include "EQStateMonitor.h"
#include "CDataMonitor1.h"
#include "AlarmMonitor.h"
#include "LoadMonitor.h"
CBonder* g_pBonder = NULL;
void CALLBACK BonderTimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
{
    if (g_pBonder != NULL) {
        g_pBonder->onTimer(nTimerid);
    }
}
UINT BoonderGetRecipeListThreadFunction(LPVOID lpParam)
{
    DWORD_PTR* p = (DWORD_PTR*)lpParam;
    CBonder* pBonder = (CBonder*)p[0];
    BEQ::IEquipment* pEquipment = (BEQ::IEquipment*)p[1];
    BEQ::IUnit* pUnit = (BEQ::IUnit*)p[2];
    delete[] p;
    return pBonder->GetRecipeListThreadFunction(pEquipment, pUnit);
}
CBonder::CBonder()
{
    m_state = STATE_READY;
    m_ullRunTime = 0;
    m_ullStartTick = 0;
    m_listener.onStateChanged = nullptr;
    m_listener.onPlcStateChanged = nullptr;
    m_listener.onRecvBroadcast = nullptr;
    m_bAreYouThereRequest = TRUE;
    m_strEquipmentModelType = "2860";
    m_strSoftRev = "1.01";
    m_pPlcData = nullptr;
    InitializeCriticalSection(&m_criticalSection);
}
CBonder::~CBonder()
{
    for (auto item : m_components) {
        delete item;
    }
    m_components.clear();
    clearRecipes();
    DeleteCriticalSection(&m_criticalSection);
}
void CBonder::setWorkDir(const char* pszWorkDir)
{
    m_strWorkDir = pszWorkDir;
}
void CBonder::setListener(BondListener& listener)
{
    m_listener.onStateChanged = listener.onStateChanged;
    m_listener.onPlcStateChanged = listener.onPlcStateChanged;
    m_listener.onCimStateChanged = listener.onCimStateChanged;
    m_listener.onEfemStateChanged = listener.onEfemStateChanged;
    m_listener.onRecvBroadcast = listener.onRecvBroadcast;
}
const std::vector<CComponent*>& CBonder::getComponents()
{
    return m_components;
}
int CBonder::save()
{
    CFile file;
    if (!file.Open(m_strFilepath.c_str(), CFile::modeCreate | CFile::modeWrite)) {
        return -1;
    }
    CArchive ar(&file, CArchive::store);
    Serialize(ar);
    ar.Close();
    file.Close();
    return 0;
}
int CBonder::read(const char* pszFilepath)
{
    CFile file;
    m_strFilepath = pszFilepath;
    if (!file.Open(pszFilepath, CFile::modeRead)) {
        return -1;
    }
    CArchive ar(&file, CArchive::load);
    Serialize(ar);
    ar.Close();
    file.Close();
    return 0;
}
void CBonder::Serialize(CArchive& ar)
{
    if (ar.IsStoring()) {
        Lock();
        Unlock();
    }
    else {
        Lock();
        Unlock();
    }
    for (auto item : m_components) {
        item->Serialize(ar);
    }
}
int CBonder::init()
{
    // æœºå™¨çŠ¶æ€
    CEQStateMonitor* pEQStateMonitor1 = new CEQStateMonitor();
    pEQStateMonitor1->setName("机器状态(A单元)");
    pEQStateMonitor1->setDescription("A单机器状态");
    pEQStateMonitor1->setIndex(0);
    pEQStateMonitor1->setBeginAddr(4463 - 4400);
    AddComponent(pEQStateMonitor1);
    pEQStateMonitor1->init();
    CEQStateMonitor* pEQStateMonitor2 = new CEQStateMonitor();
    pEQStateMonitor2->setName("机器状态(B单元)");
    pEQStateMonitor2->setDescription("B单机器状态");
    pEQStateMonitor2->setIndex(1);
    pEQStateMonitor2->setBeginAddr(4563 - 4500);
    AddComponent(pEQStateMonitor2);
    pEQStateMonitor2->init();
    // åˆå§‹åŒ–各种组件
    // è¯»PLC1配置
    // è¯»å–机器名
    CString strIniFile;
    strIniFile.Format(_T("%s\\configuration.ini"), m_strWorkDir.c_str());
    m_pPlcData = new char[1024];
    char szIP[256];
    unsigned int nPort;
    BOOL bAutoSendData = FALSE;
    GetPrivateProfileString("PLC1", "IP", _T(""), szIP, 256, strIniFile);
    nPort = GetPrivateProfileInt("PLC1", "PORT", 8080, strIniFile);
    bAutoSendData = GetPrivateProfileInt("Equipment", "AutoSendData", 0, strIniFile) != 0;
    CPLC* pPlc = new CPLC("PLC1", szIP, nPort);
    PLCListener listener;
    listener.onStateChanged = [&](void* pFrom, int state) -> void {
        if (m_listener.onPlcStateChanged != nullptr) {
            m_listener.onPlcStateChanged(pFrom, state);
        }
    };
    listener.onMonitorData = [&](void* pFrom, int id) -> void {
        if (id == 1) {
            for (auto c : m_components) {
                c->onData(id, m_pPlcData, 200);
            }
        }
        else if (id == 2) {
            char szBuffer[24];
            memset(szBuffer, 0, 24);
            memcpy(szBuffer, &m_pPlcData[200+90*2], 20);
            m_strCurRecipeName = szBuffer;
            for (auto c : m_components) {
                c->onData(id, &m_pPlcData[200], 200);
            }
        }
        else if (id == 3) {
            for (auto c : m_components) {
                c->onData(id, &m_pPlcData[400], 184);
            }
        }
    };
    pPlc->setListener(listener);
    pPlc->addMonitor(1, 4400, 4499, MC::SOFT_COMPONENT::D, m_pPlcData);
    pPlc->addMonitor(2, 4500, 4599, MC::SOFT_COMPONENT::D, &m_pPlcData[200]);
    pPlc->addMonitor(3, 4700, 4791, MC::SOFT_COMPONENT::D, &m_pPlcData[400]);
    pPlc->setName("PLC(1)");
    pPlc->setDescription("PLC");
    pPlc->setIndex(0);
    pPlc->init();
    AddComponent(pPlc);
    CDataMonitor1* pDataMonitor1 = new CDataMonitor1();
    pDataMonitor1->setName("数据监控(A单元)");
    pDataMonitor1->setDescription("A单元真空、压力和温度数据");
    pDataMonitor1->setIndex(0);
    pDataMonitor1->setResponseAddr(4425);
    pDataMonitor1->enableAutoSendData(bAutoSendData);
    AddComponent(pDataMonitor1);
    pDataMonitor1->init();
    CDataMonitor1* pDataMonitor2 = new CDataMonitor1();
    pDataMonitor2->setName("数据监控(B单元)");
    pDataMonitor2->setDescription("B单元真空、压力和温度数据");
    pDataMonitor2->setIndex(1);
    pDataMonitor2->setResponseAddr(4525);
    pDataMonitor2->enableAutoSendData(bAutoSendData);
    AddComponent(pDataMonitor2);
    pDataMonitor2->init();
    CString strAlarmFile;
    strAlarmFile.Format(_T("%s\\AlarmList.txt"), m_strWorkDir.c_str());
    CAlarmMonitor* pAlarmMonitor1 = new CAlarmMonitor();
    pAlarmMonitor1->setName("警告信息(A单元)");
    pAlarmMonitor1->setDescription("警告信息监控(A单元)");
    pAlarmMonitor1->setBeginAddr(4461 - 4400);
    pAlarmMonitor1->setIndex(0);
    pAlarmMonitor1->readAlarmListFromFile((LPTSTR)(LPCTSTR)strAlarmFile);
    AddComponent(pAlarmMonitor1);
    pAlarmMonitor1->init();
    CAlarmMonitor* pAlarmMonitor2 = new CAlarmMonitor();
    pAlarmMonitor2->setName("警告信息(B单元)");
    pAlarmMonitor2->setDescription("警告信息监控(B单元)");
    pAlarmMonitor2->setBeginAddr(4561 - 4500);
    pAlarmMonitor2->setIndex(1);
    pAlarmMonitor2->readAlarmListFromFile((LPTSTR)(LPCTSTR)strAlarmFile);
    AddComponent(pAlarmMonitor2);
    pAlarmMonitor2->init();
    // LoadMonitor
    CLoadMonitor* pLoadMonitor1 = new CLoadMonitor();
    pLoadMonitor1->setName("上下料(A单元)");
    pLoadMonitor1->setDescription("上下料信号监控(A单元)");
    pLoadMonitor1->setBeginAddr(4700);
    pLoadMonitor1->setIndex(0);
    AddComponent(pLoadMonitor1);
    pLoadMonitor1->init();
    CLoadMonitor* pLoadMonitor2 = new CLoadMonitor();
    pLoadMonitor2->setName("上下料(B单元)");
    pLoadMonitor2->setDescription("上下料信号监控(B单元)");
    pLoadMonitor2->setBeginAddr(4700);
    pLoadMonitor2->setIndex(1);
    AddComponent(pLoadMonitor2);
    pLoadMonitor2->init();
    CLoadMonitor* pLoadMonitor3 = new CLoadMonitor();
    pLoadMonitor3->setName("上下料(冷却箱)");
    pLoadMonitor3->setDescription("上下料信号监控(冷却箱)");
    pLoadMonitor3->setBeginAddr(4700);
    pLoadMonitor3->setIndex(2);
    AddComponent(pLoadMonitor3);
    pLoadMonitor3->init();
    // BEQ与EFEM通讯
    BEQ_CreateEquipment(m_pEquipment, m_strUnitId.c_str());
    ASSERT(m_pEquipment != nullptr);
    BEQ::EquipmentListener equListener;
    equListener.onConnected = [&](void* pEquipment, const char* pszAddr, int port) -> void {
        if (m_listener.onEfemStateChanged != nullptr) {
            m_listener.onEfemStateChanged(this, pszAddr, port, 1);
        }
        LOGI("<Bonder>EFEM连接进入[%s:%d]", pszAddr, port);
    };
    equListener.onDisconnected = [&](void* pEquipment, const char* pszAddr, int port) -> void {
        m_listener.onEfemStateChanged(this, pszAddr, port, 0);
        LOGI("<Bonder>EFEM连接断开[%s:%d]", pszAddr, port);
    };
    equListener.onRunRecipe = [&](void* pEquipment, void* pUnit, int id) -> int {
        return runRecipe((BEQ::IUnit*)pUnit, id);
    };
    equListener.onGetRecipeList = [&](void* pEquipment, void* pUnit) -> int {
        getRecipeListInBlock((BEQ::IEquipment*)pEquipment, (BEQ::IUnit*)pUnit);
        return 1;
    };
    equListener.onLoadReady = [&](void* pEquipment, void* pUnit, const char* pszMaterielId, const char* pszRecipeId) -> int {
        return loadReady((BEQ::IUnit*)pUnit, pszMaterielId, pszRecipeId);
    };
    equListener.onLoadComplete = [&](void* pEquipment, void* pUnit, int layer) -> int {
        return loadComplete((BEQ::IUnit*)pUnit, layer);
    };
    equListener.onUnloadComplete = [&](void* pEquipment, void* pUnit, int layer) -> int {
        return unloadComplete((BEQ::IUnit*)pUnit, layer);
    };
    m_pEquipment->setEquipmentListener(equListener);
    m_pEquipment->setVersion(m_strSoftRev.c_str());
    m_pEquipment->addUnit(UNITA, 5);
    m_pEquipment->addUnit(UNITB, 5);
    BEQ::IUnit* pUnitC = m_pEquipment->addUnit(UNITC, 1);
    pUnitC->setLayerCount(4);
    m_pEquipment->runOnServerMode(8192);
    g_pBonder = this;
    SetTimer(NULL, 1, 1000, (TIMERPROC)BonderTimerProc);
    return 0;
}
int CBonder::term()
{
    m_listener.onStateChanged = nullptr;
    m_listener.onPlcStateChanged = nullptr;
    m_listener.onRecvBroadcast = nullptr;
    for (auto item : m_components) {
        item->term();
    }
    if (m_pPlcData != nullptr) {
        delete[] m_pPlcData;
        m_pPlcData = nullptr;
    }
    return 0;
}
void CBonder::sendBroadcast(CComponent* pSender, CIntent* pIntent)
{
    for (auto item : m_components) {
        if (item != pSender) {
            item->onRecvBroadcast(pSender, pIntent);
        }
    }
    this->onRecvBroadcast(pSender, pIntent);
}
void CBonder::onRecvBroadcast(CComponent* pSender, CIntent* pIntent)
{
    int code = pIntent->getCode();
    if (m_listener.onRecvBroadcast != nullptr) {
        m_listener.onRecvBroadcast(pSender, pIntent);
    }
    if (BC_CODE_RUN_RECIPE_RESULT == code) {
        int errorCode = (int)pIntent->getContext();
        m_pEquipment->repLoadReadyComplete(errorCode);
    }
}
void CBonder::setUnitId(const char* pszUnitId)
{
    m_strUnitId = pszUnitId;
}
void CBonder::setEquipmentModelType(const char* pszModelType)
{
    m_strEquipmentModelType = pszModelType;
}
void CBonder::setSoftRev(const char* pszSoftRev)
{
    m_strSoftRev = pszSoftRev;
}
int CBonder::start()
{
    Lock();
    if (m_state == STATE_RUNNING) {
        Unlock();
        return -1;
    }
    if (m_state == STATE_ERROR) {
        Unlock();
        return -2;
    }
    LOGI("<Bonder>Start...");
    m_state = STATE_RUNNING;
    m_ullStartTick = GetTickCount64();
    for (auto item : m_components) {
        item->run();
    }
    Unlock();
    if (m_listener.onStateChanged != nullptr) {
        m_listener.onStateChanged(this, m_state);
    }
    return 0;
}
int CBonder::stop()
{
    Lock();
    if (m_state != STATE_RUNNING) {
        Unlock();
        return -1;
    }
    m_state = STATE_STOP;
    m_ullRunTime += (GetTickCount64() - m_ullStartTick);
    for (auto item : m_components) {
        item->stop();
    }
    Unlock();
    LOGI("<Bonder>Stop.");
    if (m_listener.onStateChanged != nullptr) {
        m_listener.onStateChanged(this, m_state);
    }
    return 0;
}
int CBonder::clearError()
{
    Lock();
    if (m_state != STATE_ERROR) {
        Unlock();
        return -1;
    }
    m_state = STATE_READY;
    Unlock();
    if (m_listener.onStateChanged != nullptr) {
        m_listener.onStateChanged(this, m_state);
    }
    return 0;
}
BOOL CBonder::isRunning()
{
    return m_state == STATE_RUNNING;
}
ULONGLONG CBonder::getRunTime()
{
    if (m_state != STATE_RUNNING) {
        return m_ullRunTime;
    }
    else {
        return m_ullRunTime + (GetTickCount64() - m_ullStartTick);
    }
}
void CBonder::onTimer(UINT nTimerid)
{
    for (auto item : m_components) {
        item->OnTimer(nTimerid);
    }
    static int iii = 0;
    iii++;
    if (iii % 5 == 0) {
        save();
    }
}
void CBonder::AddComponent(CComponent* pComponent)
{
    ASSERT(pComponent);
    pComponent->setBonder(this);
    m_components.push_back(pComponent);
}
CComponent* CBonder::GetComponent(const char* pszName)
{
    for (auto c : m_components) {
        if (c->getName().compare(pszName) == 0) {
            return c;
        }
    }
    return nullptr;
}
int CBonder::writeInt(int unitId, int addr, int value)
{
    static CPLC* pPLC = nullptr;
    if (pPLC == nullptr) {
        pPLC = (CPLC*)GetComponent("PLC(1)");
    }
    ASSERT(pPLC);
    pPLC->writeWord(MC::SOFT_COMPONENT::D, addr, value,
        [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
        if (flag != 0) {
            LOGE("<CBonder>writeInt超时<unitId=%d,addr=%d,value=%d,flag=%d>", unitId, addr, value, flag);
        }
    });
    return 0;
}
int CBonder::writeData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
    const char* pszData, unsigned int length, ONWRITE funOnWrite)
{
    static CPLC* pPLC = nullptr;
    if (pPLC == nullptr) {
        pPLC = (CPLC*)GetComponent("PLC(1)");
    }
    ASSERT(pPLC);
    return pPLC->writeData(softComponent, addr, pszData, length, funOnWrite);
}
int CBonder::readData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
    unsigned int readLen, ONREADDATA funOnRead)
{
    static CPLC* pPLC = nullptr;
    if (pPLC == nullptr) {
        pPLC = (CPLC*)GetComponent("PLC(1)");
    }
    ASSERT(pPLC);
    return pPLC->readData(softComponent, addr, readLen, funOnRead);
}
BOOL CBonder::readDataBlocking(HANDLE hEvent, MC::SOFT_COMPONENT softComponent, unsigned int addr,
    unsigned int readLen, char* pszBuffer)
{
    static CPLC* pPLC = nullptr;
    if (pPLC == nullptr) {
        pPLC = (CPLC*)GetComponent("PLC(1)");
    }
    ASSERT(pPLC);
    BOOL bReadOk = FALSE;
    BOOL bOutputLog = FALSE;
    auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
        if (flag == 0) {
            if (bOutputLog) {
                CString s;
                s.Format(_T("CBonder::readDataBlocking::funOnReadData %d ["), nDataSize);
                for (unsigned int i = 0; i < nDataSize; i++) {
                    s.AppendFormat(" %x", (BYTE)pData[i]);
                }
                s.Append("]");
                LOGI("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
            }
        }
        else {
            LOGE("<CBonder>Addr:%d, PLC批读取数据位超时.flag=%d\n", addr, flag);
        }
        if (nDataSize == readLen && flag == 0) {
            bReadOk = TRUE;
            memcpy(pszBuffer, pData, readLen);
        }
        SetEvent(hEvent);
    };
    ResetEvent(hEvent);
    pPLC->readData(softComponent, addr, readLen, funOnReadData);
    WaitForSingleObject(hEvent, INFINITE);
    return bReadOk;
}
BEQ::IEquipment* CBonder::getEquipment()
{
    return m_pEquipment;
}
BEQ::IUnit* CBonder::getUnit(int index)
{
    if (index == 0)
        return m_pEquipment->getUnit(UNITA);
    if (index == 1)
        return m_pEquipment->getUnit(UNITB);
    if (index == 2)
        return m_pEquipment->getUnit(UNITC);
    return nullptr;
}
std::string& CBonder::getCurRecipeName()
{
    return m_strCurRecipeName;
}
#define RECIPE_HEADER_SIZE    20 * 2
#define RECIPE_NAME_SIZE    10 * 2
#define RECIPE_SIZE        1140
int CBonder::getRecipeList()
{
    CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
    ASSERT(pPLC);
    if (!pPLC->isConnected()) return -1;
    clearRecipes();
    HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    BOOL bOutputLog = TRUE;
    BOOL bReadOk = FALSE;
    char szBuffer[RECIPE_HEADER_SIZE];
    char szRecipeName[RECIPE_NAME_SIZE + 4];
    szRecipeName[RECIPE_NAME_SIZE] = '\0';
    auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
        if (flag == 0) {
            if (bOutputLog) {
                CString s;
                s.Format(_T("CPLC::monitorReadData::funOnReadData %d ["), nDataSize);
                for (unsigned int i = 0; i < nDataSize; i++) {
                    s.AppendFormat(" %x", (BYTE)pData[i]);
                }
                s.Append("]");
                TRACE("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
            }
        }
        else {
            TRACE("<CBonder>Addr:%d, PLC批读取数据位超时.flag=%d\n", addr, flag);
        }
        if (nDataSize == RECIPE_HEADER_SIZE && flag == 0) {
            bReadOk = TRUE;
            memcpy(szBuffer, pData, RECIPE_HEADER_SIZE);
        }
        SetEvent(hEvent);
    };
    for (int i = 0; i < 100; i++) {
        bReadOk = FALSE;
        pPLC->readData(MC::SOFT_COMPONENT::ZR, 270000 + i*RECIPE_SIZE, RECIPE_HEADER_SIZE, funOnReadData);
        WaitForSingleObject(hEvent, 3 * 1000);
        ResetEvent(hEvent);
        // è§£é‡Šæ•°æ®å¾—到配方
        if (bReadOk) {
            int id = (szBuffer[0] & 0xff) | (szBuffer[1] & 0xff) << 8
                | (szBuffer[2] & 0xff) << 16 | (szBuffer[3] & 0xff) << 24;
            int x = (szBuffer[28] & 0xff) | (szBuffer[29] & 0xff) << 8
                | (szBuffer[30] & 0xff) << 16 | (szBuffer[31] & 0xff) << 24;
            int y = (szBuffer[32] & 0xff) | (szBuffer[33] & 0xff) << 8
                | (szBuffer[34] & 0xff) << 16 | (szBuffer[35] & 0xff) << 24;
            int z = (szBuffer[36] & 0xff) | (szBuffer[37] & 0xff) << 8
                | (szBuffer[38] & 0xff) << 16 | (szBuffer[39] & 0xff) << 24;
            if (x > 0 && y > 0 && z > 0 && getRecipe(id) == nullptr) {
                memcpy(szRecipeName, &szBuffer[4], RECIPE_NAME_SIZE);
                Lock();
                CRecipe* pRecipe = new CRecipe(id, szRecipeName);
                m_recipes[id] = pRecipe;
                Unlock();
            }
            // MYTRACE1("<Bonder>读取 %d,%s, xyz<%d,%d,%d>, OK\n", i, szRecipeName, x, y, z);
        }
    }
    CloseHandle(hEvent);
    return 0;
}
int CBonder::getRecipeListInBlock(BEQ::IEquipment* pEquipment, BEQ::IUnit* pUnit)
{
    DWORD_PTR* p = new DWORD_PTR[3];
    p[0] = (DWORD_PTR)this;
    p[1] = (DWORD_PTR)pEquipment;
    p[2] = (DWORD_PTR)pUnit;
    CWinThread* pAcceptThread = AfxBeginThread(&BoonderGetRecipeListThreadFunction, (LPVOID)p,
        THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
    if (pAcceptThread) {
        pAcceptThread->ResumeThread();
    }
    return 0;
}
UINT CBonder::GetRecipeListThreadFunction(BEQ::IEquipment* pEquipment, BEQ::IUnit* pUnit)
{
    char szUnitName[256];
    pUnit->getName(szUnitName, 256);
    LOGI("<CBonder>正在获取%s配方", szUnitName);
    getRecipeList();
    LOGI("<CBonder>获取%s配方完成", szUnitName);
    for (auto item : m_recipes) {
        pUnit->addRecipe(item.first, item.second->getName().c_str(), false);
    }
    pEquipment->repRecipeListComplete();
    return 0;
}
int CBonder::runRecipe(BEQ::IUnit* pUnit, int id)
{
    char szUnitName[256];
    pUnit->getName(szUnitName, 256);
    LOGI("<CBonder>%s正在切换配方-%d", szUnitName, id);
    CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
    ASSERT(pPLC);
    if (!pPLC->isConnected()) return -1;
    // å…ˆå†™æ•°æ®åˆ°plc
    HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    BOOL bWrite = TRUE;
    char szBuffer[8];
    szBuffer[0] = (2 & 0xff);
    szBuffer[1] = (2 & 0xff00) >> 8;
    szBuffer[2] = 0;
    szBuffer[3] = 0;
    szBuffer[4] = (id & 0xff);
    szBuffer[5] = (id & 0xff00) >> 8;
    szBuffer[6] = (id & 0xff0000) >> 16;
    szBuffer[7] = (id & 0xff000000) >> 24;
    pPLC->writeData(MC::SOFT_COMPONENT::D, 4615, szBuffer, 8, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
        if (flag != 0) {
            LOGE("<CBonder::runRecipe-%d>PLC1写数据超时.flag=%d", flag, __LINE__);
            bWrite = FALSE;
        }
        SetEvent(hEvent);
    });
    WaitForSingleObject(hEvent, INFINITE);
    ResetEvent(hEvent);
    if (!bWrite) {
        CloseHandle(hEvent);
        return -2;
    }
    // ç„¶åŽä»ŽPLC读结果
    BOOL bOutputLog = FALSE;
    BOOL bReadOk = FALSE;
    Sleep(5000);
    auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
        if (flag == 0) {
            if (bOutputLog) {
                CString s;
                s.Format(_T("CPLC::runRecipe::funOnReadData %d ["), nDataSize);
                for (unsigned int i = 0; i < nDataSize; i++) {
                    s.AppendFormat(" %x", (BYTE)pData[i]);
                }
                s.Append("]");
                LOGI("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
            }
        }
        else {
            LOGE("<CBonder::runRecipe>Addr:%d, PLC批读取数据位超时.flag=%d\n", addr, flag);
        }
        if (nDataSize == 2 && flag == 0) {
            int value = (pData[0] & 0xff) | (pData[1] & 0xff) << 8;
            bReadOk = (value == 2);
        }
        SetEvent(hEvent);
    };
    pPLC->readData(MC::SOFT_COMPONENT::D, 4630, 2, funOnReadData);
    WaitForSingleObject(hEvent, INFINITE);
    ResetEvent(hEvent);
    // æ¸…空结果
    memset(szBuffer, 0, 8);
    pPLC->writeData(MC::SOFT_COMPONENT::D, 4615, szBuffer, 8, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
        if (flag != 0) {
            LOGE("<CBonder::runRecipe-%d>PLC1写数据超时.flag=%d", flag, __LINE__);
            bWrite = FALSE;
        }
        SetEvent(hEvent);
    });
    CloseHandle(hEvent);
    if (bReadOk) {
        LOGI("<CBonder>%s切换配方-%d完成", szUnitName, id);
        return 0;
    }
    else {
        LOGE("<CBonder>%s切换配方-%d失败", szUnitName, id);
        return -3;
    }
}
int CBonder::loadReady(BEQ::IUnit* pUnit, const char* pszMaterielId, const char* pszRecipeId)
{
    char szUnitName[256];
    pUnit->getName(szUnitName, 256);
    LOGI("<CBonder>%s上料准备就绪,MaterielId:%s, RecipeId:%s", szUnitName, pszMaterielId, pszRecipeId);
    CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
    ASSERT(pPLC);
    if (!pPLC->isConnected()) {
        return -1;
    }
    // å•å…ƒC为水冷塔,不需要写
    if (strcmp(szUnitName, UNITC) == 0) {
        return 0;
    }
    // å¦‚果是单元A或单元B, å†™ç‰©æ–™ID和配方ID到PLC
    CLoadMonitor* pLoadMonitor = nullptr;
    if (strcmp(szUnitName, UNITA) == 0) {
        pLoadMonitor = (CLoadMonitor*)GetComponent("上下料(A单元)");
        return pLoadMonitor->loadReady(pszMaterielId, pszRecipeId);
    }
    else if (strcmp(szUnitName, UNITB) == 0) {
        pLoadMonitor = (CLoadMonitor*)GetComponent("上下料(B单元)");
        return pLoadMonitor->loadReady(pszMaterielId, pszRecipeId);
    }
    return -2;
}
int CBonder::loadComplete(BEQ::IUnit* pUnit, int layer)
{
    char szUnitName[256];
    pUnit->getName(szUnitName, 256);
    LOGI("<CBonder>%s上料完成,layer:%d", szUnitName, layer);
    CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
    ASSERT(pPLC);
    if (!pPLC->isConnected()) {
        return -1;
    }
    if (layer <= 0 || layer > 4) {
        return -2;
    }
    // å†™BIT位到PLC,以告诉它上料完成
    // D寄存器似乎不能按位写,先读出再写入
    BOOL bOutputLog = FALSE;
    BOOL bReadOk = FALSE;
    char szBuffer[32];
    HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
        if (flag == 0) {
            if (bOutputLog) {
                CString s;
                s.Format(_T("CPLC::loadComplete::funOnReadData %d ["), nDataSize);
                for (unsigned int i = 0; i < nDataSize; i++) {
                    s.AppendFormat(" %x", (BYTE)pData[i]);
                }
                s.Append("]");
                TRACE("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
            }
        }
        else {
            LOGE("<CBonder>Addr:%d, PLC批读取数据位超时.flag=%d\n", addr, flag);
        }
        if (nDataSize == 6 && flag == 0) {
            bReadOk = TRUE;
            memcpy(szBuffer, pData, 6);
        }
        SetEvent(hEvent);
    };
    pPLC->readData(MC::SOFT_COMPONENT::D, 4710, 6, funOnReadData);
    WaitForSingleObject(hEvent, INFINITE);
    ResetEvent(hEvent);
    if (!bReadOk) {
        CloseHandle(hEvent);
        LOGE("<CBonder>%s上料完成,读标志位失败。layer:%d", szUnitName, layer);
        return -3;
    }
    // Ð´
    int index, nFlagAddr;
    if (strcmp(szUnitName, UNITA) == 0) {
        index = 0;
        nFlagAddr = 4710;
        szBuffer[index * 2] |= 0x02;
    }
    else if (strcmp(szUnitName, UNITB) == 0) {
        index = 1;
        nFlagAddr = 4711;
        szBuffer[index * 2] |= 0x02;
    }
    else if (strcmp(szUnitName, UNITC) == 0) {
        index = 2;
        nFlagAddr = 4712;
        switch (layer)
        {
        case 1:
            szBuffer[index * 2] |= 0x01;
            break;
        case 2:
            szBuffer[index * 2] |= 0x02;
            break;
        case 3:
            szBuffer[index * 2] |= 0x04;
            break;
        case 4:
            szBuffer[index * 2] |= 0x08;
            break;
        default:
            break;
        }
    }
    BOOL bWriteOk = TRUE;
    pPLC->writeData(MC::SOFT_COMPONENT::D, nFlagAddr, &szBuffer[index * 2], 2, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
        if (flag != 0) {
            LOGE("<CBonder::loadReady-%d>PLC1写数据超时.flag=%d", __LINE__, flag);
            bWriteOk = FALSE;
        }
        SetEvent(hEvent);
    });
    WaitForSingleObject(hEvent, INFINITE);
    ResetEvent(hEvent);
    CloseHandle(hEvent);
    if (bWriteOk) {
        LOGI("<CBonder>%s上料完成,已写入PLC", szUnitName);
        return 0;
    }
    else {
        LOGE("<CBonder>%s上料完成, å†™PLC无响应", szUnitName);
        return -4;
    }
}
int CBonder::unloadComplete(BEQ::IUnit* pUnit, int layer)
{
    char szUnitName[256];
    pUnit->getName(szUnitName, 256);
    LOGI("<CBonder>%s下料完成,layer:%d", szUnitName, layer);
    CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
    ASSERT(pPLC);
    if (!pPLC->isConnected()) {
        return -1;
    }
    if (layer <= 0 || layer > 4) {
        return -2;
    }
    // å†™BIT位到PLC,以告诉它上料完成
    // D寄存器似乎不能按位写,先读出再写入
    BOOL bOutputLog = FALSE;
    BOOL bReadOk = FALSE;
    char szBuffer[32];
    HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
        if (flag == 0) {
            if (bOutputLog) {
                CString s;
                s.Format(_T("CPLC::unloadComplete::funOnReadData %d ["), nDataSize);
                for (unsigned int i = 0; i < nDataSize; i++) {
                    s.AppendFormat(" %x", (BYTE)pData[i]);
                }
                s.Append("]");
                LOGD("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
            }
        }
        else {
            LOGE("<CBonder>Addr:%d, PLC批读取数据位超时.flag=%d\n", addr, flag);
        }
        if (nDataSize == 6 && flag == 0) {
            bReadOk = TRUE;
            memcpy(szBuffer, pData, 6);
        }
        SetEvent(hEvent);
    };
    pPLC->readData(MC::SOFT_COMPONENT::D, 4710, 6, funOnReadData);
    WaitForSingleObject(hEvent, INFINITE);
    ResetEvent(hEvent);
    if (!bReadOk) {
        CloseHandle(hEvent);
        LOGE("<CBonder>%s下料完成,读标志位失败。layer:%d", szUnitName, layer);
        return -3;
    }
    // Ð´
    int index, nFlagAddr;
    if (strcmp(szUnitName, UNITA) == 0) {
        index = 0;
        nFlagAddr = 4710;
        szBuffer[index * 2 + 1] |= 0x02;
    }
    else if (strcmp(szUnitName, UNITB) == 0) {
        index = 1;
        nFlagAddr = 4711;
        szBuffer[index * 2 + 1] |= 0x02;
    }
    else if (strcmp(szUnitName, UNITC) == 0) {
        index = 2;
        nFlagAddr = 4712;
        switch (layer)
        {
        case 1:
            szBuffer[index * 2] |= 0x20;
            break;
        case 2:
            szBuffer[index * 2] |= 0x40;
            break;
        case 3:
            szBuffer[index * 2] |= 0x80;
            break;
        case 4:
            szBuffer[index * 2 + 1] |= 0x01;
            break;
        default:
            break;
        }
    }
    BOOL bWriteOk = TRUE;
    pPLC->writeData(MC::SOFT_COMPONENT::D, nFlagAddr, &szBuffer[index * 2], 2, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
        if (flag != 0) {
            LOGE("<CBonder::unloadReady-%d>PLC1写数据超时.flag=%d", __LINE__, flag);
            bWriteOk = FALSE;
        }
        SetEvent(hEvent);
    });
    WaitForSingleObject(hEvent, INFINITE);
    ResetEvent(hEvent);
    CloseHandle(hEvent);
    if (bWriteOk) {
        LOGI("<CBonder>%s下料完成,已写入PLC", szUnitName);
        return 0;
    }
    else {
        LOGE("<CBonder>%s下料完成, å†™PLC无响应", szUnitName);
        return -4;
    }
}
void CBonder::clearRecipes()
{
    for (auto item : m_recipes) {
        delete item.second;
    }
    m_recipes.clear();
}
CRecipe* CBonder::getRecipe(int id)
{
    auto iter = m_recipes.find(id);
    if (iter == m_recipes.end()) return nullptr;
    return iter->second;
}
SourceCode/Bond/BondEq/CBonder.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
#pragma once
#include "Component.h"
#include <vector>
#include <functional>
#include "CPLC.h"
#include <list>
#include <map>
#include "Recipe.h"
#define ER_NOERROR            0
#define ER_NOTSELECT        -1
#define ER_BUSY                -2
#define STATE_READY            0        /* å°±ç»ª */
#define STATE_RUNNING        1        /* è¿è¡Œä¸­ */
#define STATE_STOP            2        /* Í£Ö¹ */
#define STATE_ERROR            3        /* å‘生故障 */
typedef std::function<void(void* pFrom, int)> ONBONDSTATECHANGED;
typedef std::function<void(void* pFrom, int)> ONPLCSTATECHANGED;
typedef std::function<void(void* pFrom, int)> ONCIMSTATECHANGED;
typedef std::function<void(void* pFrom, const char* pszAddr, int port, int)> ONEFEMSTATECHANGED;
typedef std::function<void(void* pFrom, void*)> ONRECVBROADCAST;
typedef struct _BondListener
{
    ONBONDSTATECHANGED        onStateChanged;
    ONPLCSTATECHANGED        onPlcStateChanged;
    ONCIMSTATECHANGED        onCimStateChanged;
    ONEFEMSTATECHANGED        onEfemStateChanged;
    ONRECVBROADCAST            onRecvBroadcast;
} BondListener;
class CBonder
{
public:
    CBonder();
    virtual ~CBonder();
public:
    void setListener(BondListener& listener);
    void setWorkDir(const char* pszWorkDir);
    const std::vector<CComponent*>& getComponents();
    int init();
    int term();
    void sendBroadcast(CComponent* pSender, CIntent* pIntent);
    void onRecvBroadcast(CComponent* pSender, CIntent* pIntent);
    int start();
    int stop();
    int clearError();
    BOOL isRunning();
    ULONGLONG getRunTime();
    void onTimer(UINT nTimerid);
    int save();
    int read(const char* pszFilepath);
    void setUnitId(const char* pszUnitId);
    void setEquipmentModelType(const char* pszModelType);
    void setSoftRev(const char* pszSoftRev);
    CComponent* GetComponent(const char* pszName);;
    int getRecipeList();
    int getRecipeListInBlock(BEQ::IEquipment* pEquipment, BEQ::IUnit* pUnit);
    int runRecipe(BEQ::IUnit* pUnit, int id);
    UINT GetRecipeListThreadFunction(BEQ::IEquipment* pEquipment, BEQ::IUnit* pUnit);
    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);
public:
    int writeInt(int unitId, int addr, int value);
    int writeData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
        const char* pszData, unsigned int length, ONWRITE funOnWrite);
    int readData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
        unsigned int length, ONREADDATA funOnRead);
    BOOL readDataBlocking(HANDLE hEvent, MC::SOFT_COMPONENT softComponent, unsigned int addr,
        unsigned int readLen, char* pszBuffer);
private:
    inline void Lock() { EnterCriticalSection(&m_criticalSection); }
    inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
    void AddComponent(CComponent* pComponent);
    void Serialize(CArchive& ar);
    unsigned int getSystemByte();
    const char* getCeidDataId();
    CRecipe* getRecipe(int id);
    void clearRecipes();
public:
    BEQ::IEquipment* getEquipment();
    BEQ::IUnit* getUnit(int index);
    std::string& getCurRecipeName();
private:
    std::string m_strWorkDir;
    std::vector<CComponent*> m_components;
    int m_state;
    ULONGLONG m_ullRunTime;
    ULONGLONG m_ullStartTick;
    CRITICAL_SECTION m_criticalSection;
    BondListener m_listener;
private:
    std::string m_strFilepath;
    std::string m_strUnitId;
    std::string m_strEquipmentModelType;
    std::string m_strSoftRev;
    BOOL m_bAreYouThereRequest;
private:
    char* m_pPlcData;
    BEQ::IEquipment* m_pEquipment;
    std::map<int, CRecipe*> m_recipes;
    std::string m_strCurRecipeName;
};
SourceCode/Bond/BondEq/CDataMonitor1.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,412 @@
#include "stdafx.h"
#include "CDataMonitor1.h"
#include "CBonder.h"
#include "Log.h"
CDataMonitor1::CDataMonitor1()
{
    m_pActivePanel = nullptr;
    m_nResponseAddr = 0;
    m_bAutoSendData = TRUE;
    m_bSampling = FALSE;
    m_hRemoveEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    m_pszRemoveParamData = new char[4096];
}
CDataMonitor1::~CDataMonitor1()
{
    Lock();
    if (m_pActivePanel != nullptr) {
        m_pActivePanel->release();
        m_pActivePanel = nullptr;
    }
    for (auto item : m_panels) {
        item->release();
    }
    m_panels.clear();
    Unlock();
    if (m_hRemoveEvent != nullptr) {
        ::CloseHandle(m_hRemoveEvent);
        m_hRemoveEvent = nullptr;
    }
    if (m_pszRemoveParamData != nullptr) {
        delete[] m_pszRemoveParamData;
        m_pszRemoveParamData = nullptr;
    }
}
std::string& CDataMonitor1::getClassName()
{
    static std::string strClassName = "CDataMonitor1";
    return strClassName;
}
void CDataMonitor1::OnTimer(UINT nTimerid)
{
    /*
    if (m_nIndex == 0) {
        char szData[200];
        memset(szData, 0, 200);
        strcpy_s(szData, 20, "ABC123");
        static int step = 0;
        static int iii = 0;
        iii+=5;
        if (iii == 100) {
            step = 20;
            szData[20 * 2] = 20;
            szData[20 * 2 + 1] = 0x00;
        }
        if (iii > 100 + 15 * 5 && iii < 100 + 24 * 5) {
            step = 1;
            szData[20 * 2] = 1;
            szData[20 * 2 + 1] = 0x00;
        }
        if (iii == 100 + 25 * 5) {
            step = 2;
            szData[20 * 2] = 2;
            szData[20 * 2 + 1] = 0x00;
        }
        if (iii == 100 + 35 * 5) {
            step = 30;
            szData[20 * 2] = 30;
            szData[20 * 2 + 1] = 0x00;
        }
        if (step == 1) {
            onData(1, szData, 200);
            onData(1, szData, 200);
            onData(1, szData, 200);
            onData(1, szData, 200);
            onData(1, szData, 200);
        }
        else if (step != 0) {
            onData(1, szData, 200);
        }
    }
    else {
    }
    */
}
void CDataMonitor1::onData(int unitId, const void* pData, int size)
{
    if (m_nIndex + 1 != unitId) return;
    const char* pszData = (const char*)pData;
    BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex);
    ASSERT(pUnit);
    // å…ˆæ£€æŸ¥é‡‡æ ·æ ‡å¿—
    // sapmleFlag: 1采样,2结束采样,20入站,30出站
    int i, v;
    i = 20 * 2;
    int sampleFlag = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
    if (sampleFlag == STEP_RECEIVED) {
        WriteResultFlag(unitId, STEP_RECEIVED);
        CString strId;
        for (int i = 0; i < 10 * 20; i++) {
            strId.Insert(strId.GetLength(), pszData[i]);
        }
        // å½“前面板
        Lock();
        if (m_pActivePanel == nullptr) {
            m_pActivePanel = new CPanel((LPTSTR)(LPCTSTR)strId, m_nIndex);
            m_pActivePanel->setStep(STEP_RECEIVED);
            m_pActivePanel->addRef();
            SendBroadcast(&CIntent(BC_CODE_DATA1_MATERIAL_RECEIVED, "", nullptr));
            LOGI("<CDataMonitor1-%d>产品准备入站,id=%s.", m_nIndex, (LPTSTR)(LPCTSTR)strId);
            pUnit->stepMaterialReceived((LPTSTR)(LPCTSTR)strId);
        }
        ASSERT(m_pActivePanel);
        LOGI("<CDataMonitor1-%d>产品已入站,id=%s.", m_nIndex, (LPTSTR)(LPCTSTR)strId);
        Unlock();
    }
    else if (sampleFlag == STEP_BEGIN_SAMPLING) {
        m_bSampling = TRUE;
        WriteResultFlag(unitId, STEP_BEGIN_SAMPLING);
        // å½“前面板
        if (m_pActivePanel != nullptr) {
            if (m_pActivePanel->getStep() == STEP_RECEIVED) {
                m_pActivePanel->setStep(STEP_BEGIN_SAMPLING);
                LOGI("<CDataMonitor1-%d>采样开始.", m_nIndex);
                pUnit->stepProcessingStarted(m_pActivePanel->getQRCode().c_str());
                SendBroadcast(&CIntent(BC_CODE_DATA1_BEGIN_SAMPLING, "", nullptr));
            }
        }
    }
    else if (sampleFlag == STEP_READY) {
        // å½“前面板
        if (m_bSampling && m_pActivePanel != nullptr) {
            // ä¸Šè…”体温度
            UNITDATA1 ud1;
            ud1.time = m_pActivePanel->GetCurrentSampleTime();
            i = 30 * 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[0] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[1] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[2] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[3] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[4] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[5] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[6] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[7] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[8] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[9] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[10] = v * 0.1f;
            i += 2;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            ud1.temp[11] = v * 0.1f;
            LOGD("<CDataMonitor1-%d>温度:%f %f %f %f %f %f %f %f %f %f %f %f", m_nIndex,
                ud1.temp[0], ud1.temp[1], ud1.temp[2], ud1.temp[3], ud1.temp[4],
                ud1.temp[5], ud1.temp[6], ud1.temp[7], ud1.temp[8], ud1.temp[9], ud1.temp[10], ud1.temp[11]);
            // çœŸç©º
            i += 18;
            ud1.vacuum = toFloat(&pszData[i]);
            LOGD("<CDataMonitor1-%d>vacuum: %f", m_nIndex,
                ud1.vacuum);
            // åŽ‹åŠ›
            i += 10;
            ud1.pressure[0] = short((pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8);
            i += 2;
            ud1.pressure[1] = short((pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8);
            i += 2;
            ud1.pressure[2] = short((pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8);
            i += 2;
            ud1.pressure[3] = short((pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8);
            i += 2;
            ud1.pressure[4] = short((pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8);
            LOGD("<CDataMonitor1-%d>pressure: %.03f %.03f %.03f %.03f %.03f", m_nIndex,
                ud1.pressure[0], ud1.pressure[1], ud1.pressure[2], ud1.pressure[3], ud1.pressure[4]);
            Lock();
            size_t size = m_pActivePanel->addData(ud1);
            Unlock();
            int nSvTime = 15 * 60 * 5;
            int nTvTime = (int)size;
            if (nTvTime % (60 * 5) == 0 && nTvTime < nSvTime) {
                pUnit->stepProcessing(m_pActivePanel->getQRCode().c_str(), 15, nTvTime / (60 * 5));
            }
            // unit data
            CString strTmp, strAir, strPre;
            for (int i = 0; i < 12; i++) {
                strTmp.AppendFormat("%.2f,", ud1.temp[i]);
            }
            strTmp.Delete(strTmp.GetLength() - 1);
            strAir.Format("%.2f", ud1.vacuum);
            for (int i = 0; i < 5; i++) {
                strPre.AppendFormat("%.2f,", ud1.pressure[i]);
            }
            strPre.Delete(strPre.GetLength() - 1);
            pUnit->setDataTimeAndResetData(ud1.time);
            pUnit->addData("TMP", (LPTSTR)(LPCTSTR)strTmp, false);
            pUnit->addData("AIR", (LPTSTR)(LPCTSTR)strAir, false);
            pUnit->addData("PRE", (LPTSTR)(LPCTSTR)strPre, m_bAutoSendData != FALSE);
            SendBroadcast(&CIntent(BC_CODE_DATA1_UPDATE, "", nullptr));
        }
    }
    else if (sampleFlag == STEP_END_SAMPLING) {
        m_bSampling = FALSE;
        WriteResultFlag(unitId, STEP_END_SAMPLING);
        // é‡‡æ ·ç»“束
        if (m_pActivePanel != nullptr) {
            m_pActivePanel->setStep(STEP_END_SAMPLING);
            SendBroadcast(&CIntent(BC_CODE_DATA1_END_SAMPLING, "", nullptr));
            pUnit->stepProcessingCompleted(m_pActivePanel->getQRCode().c_str());
            LOGI("<CDataMonitor1-%d>采样结束.", m_nIndex);
        }
    }
    else if (sampleFlag == STEP_REMOVED) {
        WriteResultFlag(unitId, STEP_REMOVED);
        if (m_pActivePanel != nullptr) {
            // 20241111,客户要求新增出站时读取一大块参数
            BOOL bReadOk;
            bReadOk = m_pBonder->readDataBlocking(m_hRemoveEvent, MC::SOFT_COMPONENT::D,
                5500, 800, &m_pszRemoveParamData[0]);
            if (bReadOk) {
                bReadOk = m_pBonder->readDataBlocking(m_hRemoveEvent, MC::SOFT_COMPONENT::D,
                    5900, 800, &m_pszRemoveParamData[800]);
            }
            if (bReadOk) {
                bReadOk = m_pBonder->readDataBlocking(m_hRemoveEvent, MC::SOFT_COMPONENT::D,
                    6300, 800, &m_pszRemoveParamData[1600]);
            }
            if (bReadOk) {
                m_pActivePanel->SetParamsRawData(m_pszRemoveParamData);
            }
            // è®°å½•当前参数和配方
            i = 70 * 2;
            double air = toFloat(&pszData[i]);
            m_pActivePanel->setAir1(air);
            i += 4;
            air = toFloat(&pszData[i]);
            m_pActivePanel->setAir2(air);
            i += 4;
            air = toFloat(&pszData[i]);
            m_pActivePanel->setAir3(air);
            i += 4;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
            m_pActivePanel->setPre1(v);
            i += 4;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            m_pActivePanel->setTmp1(v * 0.1);
            i += 4;
            v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8;
            m_pActivePanel->setTmp2(v * 0.1);
            m_pActivePanel->setRecipeName(m_pBonder->getCurRecipeName().c_str());
            LOGI("<CDataMonitor1-%d>Recipe:%s, å¹²æ³µå¸çœŸç©ºå€¼:%f,分子泵吸真空值:%f",
                m_nIndex,
                m_pActivePanel->getRecipeName().c_str(),
                m_pActivePanel->getAir1(),
                m_pActivePanel->getAir2());
            LOGI("<CDataMonitor1-%d>气囊压力值:%f,贴合总压力:%d",
                m_nIndex,
                m_pActivePanel->getAir3(),
                m_pActivePanel->getPre1());
            LOGI("<CDataMonitor1-%d>上腔体温度:%f,下腔体温度:%f",
                m_nIndex,
                m_pActivePanel->getTmp1(),
                m_pActivePanel->getTmp2());
            m_pActivePanel->setStep(STEP_REMOVED);
            SendBroadcast(&CIntent(BC_CODE_DATA1_MATERIAL_REMOVED, "", m_pActivePanel));
            AddPanel(m_pActivePanel);
            pUnit->stepMaterialRemoved(m_pActivePanel->getQRCode().c_str());
            Sleep(50);
            pUnit->stepIdle();
            m_pActivePanel->release();
            m_pActivePanel = nullptr;
            LOGI("<CDataMonitor1-%d>出站.", m_nIndex);
        }
    }
}
CPanel* CDataMonitor1::getActivePanel()
{
    return m_pActivePanel;
}
void CDataMonitor1::setResponseAddr(int addr)
{
    m_nResponseAddr = addr;
}
void CDataMonitor1::enableAutoSendData(BOOL bEnable)
{
    m_bAutoSendData = bEnable;
}
const std::list<CPanel*>& CDataMonitor1::getPanels()
{
    return m_panels;
}
void CDataMonitor1::init()
{
    CComponent::init();
}
void CDataMonitor1::term()
{
    CComponent::term();
}
void CDataMonitor1::onRecvBroadcast(void* pSender, CIntent* pIntent)
{
}
void CDataMonitor1::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        Lock();
        int count = (int)m_panels.size() + (m_pActivePanel != nullptr ? 1 : 0);
        ar << count;
        for (auto item : m_panels) {
            item->Serialize(ar);
        }
        if (m_pActivePanel != nullptr) {
            m_pActivePanel->Serialize(ar);
        }
        Unlock();
    }
    else
    {
        Lock();
        int count;
        ar >> count;
        for (int i = 0; i < count; i++) {
            CPanel* pPanel = new CPanel();
            pPanel->addRef();
            pPanel->Serialize(ar);
            AddPanel(pPanel);
            pPanel->release();
        }
        Unlock();
    }
}
void CDataMonitor1::AddPanel(CPanel* pPanel)
{
    pPanel->addRef();
    m_panels.push_back(pPanel);
    if (m_panels.size() > 4 * 24) {
        CPanel* pTemp = m_panels.front();
        pTemp->release();
        m_panels.pop_front();
    }
}
void CDataMonitor1::WriteResultFlag(int unitId, int flag)
{
    WriteInt(unitId, m_nResponseAddr, flag);
}
SourceCode/Bond/BondEq/CDataMonitor1.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
#pragma once
#include "Component.h"
#include "CPanel.h"
#include <list>
class CDataMonitor1 :
    public CComponent
{
public:
    CDataMonitor1();
    virtual ~CDataMonitor1();
public:
    virtual std::string& getClassName();
    virtual void OnTimer(UINT nTimerid);
    virtual void onData(int id, const void* pData, int size);
    virtual void onRecvBroadcast(void* pSender, CIntent* pIntent);
    virtual void init();
    virtual void term();
    virtual void Serialize(CArchive& ar);
    const std::list<CPanel*>& getPanels();
    CPanel* getActivePanel();
    void setResponseAddr(int addr);
    void enableAutoSendData(BOOL bEnable);
private:
    void AddPanel(CPanel* pPanel);
    inline void WriteResultFlag(int unitId, int flag);
private:
    CPanel* m_pActivePanel;
    std::list<CPanel*> m_panels;
    int m_nResponseAddr;
    BOOL m_bAutoSendData;
    BOOL m_bSampling;
private:
    HANDLE m_hRemoveEvent;
    char* m_pszRemoveParamData;
};
SourceCode/Bond/BondEq/CPLC.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,314 @@
#include "stdafx.h"
#include "CPLC.h"
#include "Log.h"
void CALLBACK TimerFileProc(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
    CPLC* pPlc = (CPLC*)dwUser;
    SetEvent(pPlc->m_hTimeEvent);
}
unsigned __stdcall McMonitorThreadFunction(LPVOID lpParam)
{
    CPLC* pPlc = (CPLC*)lpParam;
    return pPlc->onMonitor();
}
CPLC::CPLC()
{
    m_nPort = 0;
    m_state = PLCSTATE::READY;
    m_listener.onStateChanged = nullptr;
    m_listener.onMonitorData = nullptr;
    m_nUnHeartBeat = 0;
    m_hMcMonitorStop = NULL;
    m_hMcMonitorThreadHandle = NULL;
    m_mcMonitorThrdaddr = 0;
    m_nTimerId = 0;
    m_hTimeEvent = nullptr;
}
CPLC::CPLC(const char* pszName, const char* pszIP, unsigned int nPort)
{
    m_strName = pszName;
    m_strIP = pszIP;
    m_nPort = nPort;
    m_state = PLCSTATE::READY;
    m_listener.onStateChanged = nullptr;
    m_listener.onMonitorData = nullptr;
    m_nUnHeartBeat = 0;
    m_hMcMonitorStop = NULL;
    m_hMcMonitorThreadHandle = NULL;
    m_mcMonitorThrdaddr = 0;
    m_nTimerId = 0;
    m_hTimeEvent = nullptr;
}
CPLC::~CPLC()
{
}
std::string& CPLC::getClassName()
{
    static std::string strClassName = "CPLC";
    return strClassName;
}
void CPLC::setListener(PLCListener& listener)
{
    m_listener.onStateChanged = listener.onStateChanged;
    m_listener.onMonitorData = listener.onMonitorData;
}
std::string& CPLC::getIP()
{
    return m_strIP;
}
unsigned int CPLC::getPort()
{
    return m_nPort;
}
int CPLC::addMonitor(int id, int beginAddr, int endAddr, MC::SOFT_COMPONENT softComponent, char* pszRecvBuffer)
{
    // æ£€æŸ¥æ˜¯å¦æœ‰é‡å¤çš„
    Lock();
    for (auto& m : m_monitors) {
        if (m.id == id) {
            Unlock();
            return -1;
        }
    }
    MONITOR m;
    memset(&m, 0, sizeof(MONITOR));
    m.id = id;
    m.beginAddr = beginAddr;
    m.readLen = (endAddr - beginAddr + 1) * 2;
    m.softComponent = softComponent;
    m.szRecvBuffer = pszRecvBuffer;
    m.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    m_monitors.push_back(m);
    Unlock();
    return 0;
}
void CPLC::init()
{
    // mc channel
    McChannelListener m_mcChannellistener;
    m_mcChannellistener.funOnConnected = [&](IMcChannel* pChannel, int nErrorCode) -> void {
        MYTRACE1("<PLC-%s>连接结果<code= %d>", m_strName.c_str(), nErrorCode);
        if (nErrorCode == 0) {
            setState(PLCSTATE::CONNECTED);
        }
        else {
            setState(PLCSTATE::DISCONNECTED);
        }
    };
    m_mcChannellistener.funOnClose = [&](IMcChannel* pChannel) -> void {
        setState(PLCSTATE::DISCONNECTED);
    };
    m_mcChannellistener.funOnClosing = [&](IMcChannel* pChannel) -> void {
    };
    m_mcChannellistener.funOnRead = [&](IMcChannel* pChannel, char* pData, unsigned int nDataSize, int nDecodeRet) -> void {
        CString strText;
        dataToHexString(pData, nDataSize, strText);
        if (nDecodeRet != 0) {
            MYTRACE1("<PLC-%s>funOnRead[%s], nDecodeRet=%d", m_strName.c_str(), (LPTSTR)(LPCTSTR)strText, nDecodeRet);
        }
        m_nUnHeartBeat = 0;
    };
    m_mcChannellistener.funOnWrite = [&](IMcChannel* pChannel) -> void {
    };
    if (0 == MCL_CreateChannel(m_pChannel, m_strName.c_str(), m_strIP.c_str(), m_nPort, 0)
        && m_pChannel != NULL) {
        m_pChannel->setChannelListener(&m_mcChannellistener);
        m_pChannel->setActionInterval(m_nActionInterval);
        MYTRACE1("<PLC-%s>正在连接PLC.", m_strName.c_str());
        setState(PLCSTATE::CONNECTING);
        m_pChannel->connect();
    }
    else if (m_pChannel != NULL) {
        m_pChannel->setChannelListener(&m_mcChannellistener);
        m_pChannel->setActionInterval(m_nActionInterval);
    }
    m_hTimeEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    timeBeginPeriod(1);
    m_nTimerId = timeSetEvent(200, 1, TimerFileProc, (DWORD_PTR)this, TIME_PERIODIC);
    if (m_hMcMonitorStop != NULL) return;
    m_hMcMonitorStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    m_hMcMonitorThreadHandle = (HANDLE)_beginthreadex(NULL, 0, ::McMonitorThreadFunction, this,
        0, &m_mcMonitorThrdaddr);
}
void CPLC::term()
{
    timeKillEvent(m_nTimerId);
    timeEndPeriod(1);        // æ¸…除前面对定时器的设置
    ASSERT(m_hMcMonitorStop);
    SetEvent(m_hMcMonitorStop);
    if (m_hMcMonitorThreadHandle != NULL) {
        WaitForSingleObject(m_hMcMonitorThreadHandle, INFINITE);
        CloseHandle(m_hMcMonitorThreadHandle);
        m_hMcMonitorThreadHandle = NULL;
    }
    CloseHandle(m_hMcMonitorStop);
    m_hMcMonitorStop = NULL;
    for (auto& m : m_monitors) {
        CloseHandle(m.hEvent);
    }
}
unsigned CPLC::onMonitor()
{
    HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    int nReadLen = 60 * 2;
    HANDLE hEvents[2] = { m_hMcMonitorStop, m_hTimeEvent };
    while (1) {
        int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
        ResetEvent(m_hTimeEvent);
        if (nRet == WAIT_OBJECT_0) {
            break;
        }
        if (!m_bRunning || !isConnected()) {
            continue;
        }
        for (auto& m : m_monitors) {
            monitorReadData(m);
        }
    }
    TRACE("CPLC::onMonitor çº¿ç¨‹é€€å‡º\n");
    return 0;
}
void CPLC::monitorReadData(MONITOR& monitor)
{
    BOOL bOutputLog = FALSE;
    BOOL bReadOk;
    // æ‰¹é‡è¯»æ•°æ®å†è§£é‡Š
    auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
        if (flag == 0) {
            if (bOutputLog) {
                CString s;
                s.Format(_T("CPLC::monitorReadData::funOnReadData %d ["), nDataSize);
                for (unsigned int i = 0; i < nDataSize; i++) {
                    s.AppendFormat(" %x", (BYTE)pData[i]);
                }
                s.Append("]");
                MYTRACE1("<CPLC-%d-%d>Received plc data.%s", m_nIndex, monitor.id, (LPTSTR)(LPCTSTR)s);
            }
        }
        else {
            MYTRACE1("<CPLC-%d-%d>PLC批读取数据位超时.flag=%d", m_nIndex, monitor.id, flag);
        }
        if (nDataSize == monitor.readLen && flag == 0) {
            memcpy(monitor.szRecvBuffer, pData, nDataSize);
            monitor.readCount++;
            bReadOk = TRUE;
        }
        SetEvent(monitor.hEvent);
    };
    bReadOk = FALSE;
    m_pChannel->readData(monitor.softComponent, monitor.beginAddr, monitor.readLen, funOnReadData);
    WaitForSingleObject(monitor.hEvent, INFINITE);
    ResetEvent(monitor.hEvent);
    if (bReadOk) {
        ASSERT(m_listener.onMonitorData);
        m_listener.onMonitorData(this, monitor.id);
    }
}
bool CPLC::isConnected()
{
    return m_pChannel->isConnected();
}
int CPLC::readWord(MC::SOFT_COMPONENT softComponent, unsigned int addr,
    ONREAD funOnRead)
{
    return m_pChannel->readWord(softComponent, addr, funOnRead);
}
int CPLC::readData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
    unsigned int nReadLen, ONREADDATA funOnReadData)
{
    return m_pChannel->readData(softComponent, addr, nReadLen, funOnReadData);
}
int CPLC::writeBit(MC::SOFT_COMPONENT softComponent, unsigned int addr,
    BOOL bValue, ONWRITE funOnWrite)
{
    return m_pChannel->writeBit(softComponent, addr, bValue, funOnWrite);
}
int CPLC::writeWord(MC::SOFT_COMPONENT softComponent, unsigned int addr,
    int value, ONWRITE funOnWrite)
{
    return m_pChannel->writeWord(softComponent, addr, value, funOnWrite);
}
int CPLC::writeData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
    const char* pszData, unsigned int length, ONWRITE funOnWrite)
{
    return m_pChannel->writeData(softComponent, addr, pszData, length, funOnWrite);
}
CString& CPLC::dataToHexString(const char* pData, const int size, CString& strOut)
{
    strOut.Empty();
    for (int i = 0; i < size; i++) {
        if (i < size - 1) {
            strOut.AppendFormat(_T("%02X "), (BYTE)pData[i]);
        }
        else {
            strOut.AppendFormat(_T("%02X"), (BYTE)pData[i]);
        }
    }
    return strOut;
}
void CPLC::setActionInterval(unsigned int nInterval)
{
    m_nActionInterval = nInterval;
}
void CPLC::setState(PLCSTATE state)
{
    m_state = state;
    if (m_listener.onStateChanged != nullptr) {
        m_listener.onStateChanged(this, (int)m_state);
    }
}
void CPLC::OnTimer(UINT nTimerid)
{
    static int iii = 0;
    iii++;
    if (iii % 5 == 3) {
        if (!m_pChannel->isConnected())
            m_pChannel->connect();
    }
}
SourceCode/Bond/BondEq/CPLC.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,88 @@
#pragma once
#include "Component.h"
#include <string>
#include <functional>
#include <vector>
#include "MMSystem.h"
#pragma comment(lib,"winmm")
typedef std::function<void(void* pFrom, int)> ONPLCSTATECHANGED;
typedef std::function<void(void* pFrom, int)> ONPLCMONITORDATA;
typedef struct _PLCListener
{
    ONPLCSTATECHANGED        onStateChanged;
    ONPLCMONITORDATA        onMonitorData;
} PLCListener;
typedef struct _MONITOR
{
    int id;
    int beginAddr;
    int readLen;
    MC::SOFT_COMPONENT softComponent;
    char* szRecvBuffer;
    HANDLE hEvent;
    ULONGLONG readCount;
} MONITOR;
enum class PLCSTATE
{
    READY = 0,
    CONNECTING,
    CONNECTED,
    DISCONNECTED
};
class CPLC :
    public CComponent
{
public:
    CPLC();
    CPLC(const char* pszName, const char* pszIP, unsigned int nPort);
    virtual ~CPLC();
public:
    virtual std::string& getClassName();
    void setListener(PLCListener& listener);
    static CString& dataToHexString(const char* pData, const int size, CString& strOut);
    void setActionInterval(unsigned int nInterval);
    void init();
    void term();
    bool isConnected();
    unsigned onMonitor();
    void OnTimer(UINT nTimerid);
    std::string& getIP();
    unsigned int getPort();
    int addMonitor(int id, int beginAddr, int endAddr, MC::SOFT_COMPONENT softComponent, char* pszRecvBuffer);
    int readWord(MC::SOFT_COMPONENT softComponent, unsigned int addr, ONREAD funOnRead);
    int readData(MC::SOFT_COMPONENT softComponent, unsigned int addr, unsigned int nReadLen, ONREADDATA funOnReadData);
    int writeWord(MC::SOFT_COMPONENT softComponent, unsigned int addr, int value, ONWRITE funOnWrite);
    int writeBit(MC::SOFT_COMPONENT softComponent, unsigned int addr, BOOL bValue, ONWRITE funOnWrite);
    int writeData(MC::SOFT_COMPONENT softComponent, unsigned int addr, const char* pszData, unsigned int length, ONWRITE funOnWrite);
private:
    void setState(PLCSTATE state);
    void monitorReadData(MONITOR& monitor);
private:
    std::string m_strName;
    std::string m_strIP;
    unsigned int m_nPort;
    IMcChannel* m_pChannel;
    PLCSTATE m_state;
    unsigned int m_nActionInterval;
    PLCListener m_listener;
    unsigned int m_nUnHeartBeat;
private:
    std::vector<MONITOR> m_monitors;
    HANDLE m_hMcMonitorStop;
    HANDLE m_hMcMonitorThreadHandle;
    unsigned m_mcMonitorThrdaddr;
    MMRESULT m_nTimerId;
public:
    HANDLE m_hTimeEvent;
};
SourceCode/Bond/BondEq/CPanel.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1006 @@
#include "stdafx.h"
#include "CPanel.h"
#include "Log.h"
#include "ToolUnits.h"
CPanel::CPanel() : CContext()
{
    m_datas.reserve(PANEL_DATA_SIZE);
    memset(&m_dataMath[ITOTAL], 0, sizeof(UNITDATA1));
    memset(&m_dataMath[IAVE], 0, sizeof(UNITDATA1));
    for (int i = 0; i < 10; i++) {
        m_dataMath[IMAX].temp[i] = -99999999.0f;
        m_dataMath[IMIN].temp[i] = 99999999.0f;
    }
    m_dataMath[IMAX].vacuum = -99999999.0f;
    m_dataMath[IMIN].vacuum = 99999999.0f;
    for (int i = 0; i < 5; i++) {
        m_dataMath[IMAX].pressure[i] = -99999999.0f;
        m_dataMath[IMIN].pressure[i] = 99999999.0f;
    }
    m_nUnitId = 0;
    m_nStep = 0;
    m_fAir1 = 0.0;
    m_fAir2 = 0.0;
    m_fAir3 = 0.0;
    m_nPre1 = 0;
    m_fTmp1 = 0.0;
    m_fTmp2 = 0.0;
    m_pszParamsRawData = new char[PARAM_RAWDATA_SIZE];
    memset(m_pszParamsRawData, 0, PARAM_RAWDATA_SIZE);
}
CPanel::CPanel(const char* pszQRCode, int nUnitId) : CContext()
{
    m_strQRCode = pszQRCode;
    m_datas.reserve(PANEL_DATA_SIZE);
    memset(&m_dataMath[ITOTAL], 0, sizeof(UNITDATA1));
    memset(&m_dataMath[IAVE], 0, sizeof(UNITDATA1));
    for (int i = 0; i < 10; i++) {
        m_dataMath[IMAX].temp[i] = -99999999.0f;
        m_dataMath[IMIN].temp[i] = 99999999.0f;
    }
    m_dataMath[IMAX].vacuum = -99999999.0f;
    m_dataMath[IMIN].vacuum = 99999999.0f;
    for (int i = 0; i < 5; i++) {
        m_dataMath[IMAX].pressure[i] = -99999999.0f;
        m_dataMath[IMIN].pressure[i] = 99999999.0f;
    }
    m_nUnitId = nUnitId;
    m_nStep = 0;
    m_fAir1 = 0.0;
    m_fAir2 = 0.0;
    m_fAir3 = 0.0;
    m_nPre1 = 0;
    m_fTmp1 = 0.0;
    m_fTmp2 = 0.0;
    m_pszParamsRawData = new char[2048];
    memset(m_pszParamsRawData, 0, 2048);
}
CPanel::~CPanel()
{
    m_datas.clear();
    for (auto item : m_params) {
        delete item;
    }
    m_params.clear();
    if (m_pszParamsRawData != nullptr) {
        delete[] m_pszParamsRawData;
        m_pszParamsRawData = nullptr;
    }
}
std::string& CPanel::getClassName()
{
    static std::string strName = "CPanel";
    return strName;
}
std::string CPanel::toString()
{
    std::string strText;
    strText += "CPanel[";
    strText += ("QRCode:" + m_strQRCode + ";");
    strText += "]";
    return strText;
}
std::string& CPanel::getQRCode()
{
    return m_strQRCode;
}
void CPanel::setQRCode(const char* pszQRCode)
{
    m_strQRCode = pszQRCode;
}
int CPanel::getUnitId()
{
    return m_nUnitId;
}
void CPanel::setUnitId(int id)
{
    m_nUnitId = id;
}
void CPanel::setStep(int step)
{
    if (step == STEP_RECEIVED) {
        m_timeReceived = CToolUnits::getTimestamp();
    }
    else if (step == STEP_BEGIN_SAMPLING) {
        m_timeBeginSampling = CToolUnits::getTimestamp();
    }
    else if (step == STEP_END_SAMPLING) {
        m_timeEndSampling = CToolUnits::getTimestamp();
    }
    else if (step == STEP_REMOVED) {
        m_timeRemoved = CToolUnits::getTimestamp();
    }
    m_nStep = step;
}
int CPanel::getStep()
{
    return m_nStep;
}
int CPanel::addData(UNITDATA1& data)
{
    m_datas.push_back(data);
    int size = (int)m_datas.size();
    // æœ€å¤§æœ€å°å¹³å‡æ•°è®¡ç®—
    for (int i = 0; i < 10; i++) {
        m_dataMath[ITOTAL].temp[i] += data.temp[i];
        m_dataMath[IAVE].temp[i] = m_dataMath[ITOTAL].temp[i] / (float)size;
        m_dataMath[IMAX].temp[i] = max(m_dataMath[IMAX].temp[i], data.temp[i]);
        m_dataMath[IMIN].temp[i] = min(m_dataMath[IMIN].temp[i], data.temp[i]);
    }
    m_dataMath[ITOTAL].vacuum += data.vacuum;
    m_dataMath[IAVE].vacuum = m_dataMath[ITOTAL].vacuum / (float)size;
    m_dataMath[IMAX].vacuum = max(m_dataMath[IMAX].vacuum, data.vacuum);
    m_dataMath[IMIN].vacuum = min(m_dataMath[IMIN].vacuum, data.vacuum);
    for (int i = 0; i < 5; i++) {
        m_dataMath[ITOTAL].pressure[i] += data.pressure[i];
        m_dataMath[IAVE].pressure[i] = m_dataMath[ITOTAL].pressure[i] / (float)size;
        m_dataMath[IMAX].pressure[i] = max(m_dataMath[IMAX].pressure[i], data.pressure[i]);
        m_dataMath[IMIN].pressure[i] = min(m_dataMath[IMIN].pressure[i], data.pressure[i]);
    }
    return size;
}
const std::vector<UNITDATA1>& CPanel::getDatas()
{
    return m_datas;
}
void CPanel::getDatas(std::vector<UNITDATA1>& out)
{
    Lock();
    out = m_datas;
    Unlock();
}
BOOL CPanel::getNewestData(UNITDATA1& data)
{
    if (m_datas.empty()) return FALSE;
    data = m_datas[m_datas.size() - 1];
    return TRUE;
}
UNITDATA1& CPanel::getMathData(int index)
{
    ASSERT(0 <= index && index < 4);
    return m_dataMath[index];
}
void CPanel::setMathData(int index, UNITDATA1& data)
{
    ASSERT(0 <= index && index < 4);
    memcpy(&m_dataMath[index], &data, sizeof(UNITDATA1));
}
int CPanel::getBlodLen()
{
    return sizeof(UNITDATA1) * (4 + m_datas.size()) + PARAM_RAWDATA_SIZE;
}
int CPanel::getBlod(char* pszBuffer, int nBufferSize)
{
    int size = sizeof(UNITDATA1) * (4 + m_datas.size()) + PARAM_RAWDATA_SIZE;
    if (nBufferSize < size)
        return -1;
    memcpy(pszBuffer, m_pszParamsRawData, PARAM_RAWDATA_SIZE);
    pszBuffer += PARAM_RAWDATA_SIZE;
    memcpy(pszBuffer, &m_dataMath[0], sizeof(UNITDATA1) * 4);
    pszBuffer += sizeof(UNITDATA1) * 4;
    for (auto& item : m_datas) {
        memcpy(pszBuffer, &item, sizeof(UNITDATA1));
        pszBuffer += sizeof(UNITDATA1);
    }
    return size;
}
int CPanel::setBlod(char* pszBlod, int len)
{
    if (len < PARAM_RAWDATA_SIZE) return -1;
    int count = (len - PARAM_RAWDATA_SIZE) / sizeof(UNITDATA1);
    if (count < 4) return -2;
    SetParamsRawData(m_pszParamsRawData);
    pszBlod += PARAM_RAWDATA_SIZE;
    memcpy(&m_dataMath[0], pszBlod, sizeof(UNITDATA1) * 4);
    pszBlod += sizeof(UNITDATA1) * 4;
    m_datas.clear();
    for (int i = 4; i < count; i++) {
        UNITDATA1 data;
        memcpy(&data, pszBlod, sizeof(UNITDATA1));
        m_datas.push_back(data);
        pszBlod += sizeof(UNITDATA1);
    }
    return 0;
}
void CPanel::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        Lock();
        ar << m_timeReceived;
        ar << m_timeBeginSampling;
        ar << m_timeEndSampling;
        ar << m_timeRemoved;
        WriteString(ar, m_strQRCode);
        ar << m_fAir1;
        ar << m_fAir2;
        ar << m_fAir3;
        ar << m_nPre1;
        ar << m_fTmp1;
        ar << m_fTmp2;
        WriteString(ar, m_strRecipeName);
        int nCount = (int)m_datas.size();
        ar << nCount;
        for (auto& item : m_datas) {
            ar.Write(&item, sizeof(UNITDATA1));
        }
        nCount = (int)m_params.size();
        ar << nCount;
        for (auto& item : m_params) {
            item->Serialize(ar);
        }
        Unlock();
    }
    else
    {
        Lock();
        ar >> m_timeReceived;
        ar >> m_timeBeginSampling;
        ar >> m_timeEndSampling;
        ar >> m_timeRemoved;
        ReadString(ar, m_strQRCode);
        ar >> m_fAir1;
        ar >> m_fAir2;
        ar >> m_fAir3;
        ar >> m_nPre1;
        ar >> m_fTmp1;
        ar >> m_fTmp2;
        ReadString(ar, m_strRecipeName);
        int nCount = 0;
        ar >> nCount;
        for (int i = 0; i < nCount; i++) {
            UNITDATA1 ud1;
            ar.Read(&ud1, sizeof(UNITDATA1));
            m_datas.push_back(ud1);
        }
        ar >> nCount;
        for (int i = 0; i < nCount; i++) {
            CParam* pParam = new CParam();
            pParam->Serialize(ar);
            m_params.push_back(pParam);
        }
        Unlock();
    }
}
bool CPanel::getReceivedTime(int& year, int& month, int& day)
{
    ULONGLONG time1;
    time1 = m_timeReceived / 1000;
    struct tm timeinfo;
    time_t t = time_t(time1);
    localtime_s(&timeinfo, &t);
    year = timeinfo.tm_year + 1900;
    month = timeinfo.tm_mon + 1;
    day = timeinfo.tm_mday;
    return true;
}
ULONG64 CPanel::GetCurrentSampleTime()
{
    return m_timeBeginSampling + m_datas.size() * 200;
}
ULONGLONG CPanel::getReceivedTime()
{
    return m_timeReceived;
}
void CPanel::setReceivedTime(ULONGLONG time)
{
    m_timeReceived = time;
}
ULONGLONG CPanel::getBeginSamplingTime()
{
    return m_timeBeginSampling;
}
void CPanel::setBeginSamplingTime(ULONGLONG time)
{
    m_timeBeginSampling = time;
}
ULONGLONG CPanel::getEndSamplingTime()
{
    return m_timeEndSampling;
}
void CPanel::setEndSamplingTime(ULONGLONG time)
{
    m_timeEndSampling = time;
}
ULONGLONG CPanel::getRemovedTime()
{
    return m_timeRemoved;
}
void CPanel::setRemovedTime(ULONGLONG time)
{
    m_timeRemoved = time;
}
void CPanel::setRecipeName(const char* pszName)
{
    m_strRecipeName = pszName;
}
std::string& CPanel::getRecipeName()
{
    return m_strRecipeName;
}
void CPanel::setAir1(double air)
{
    m_fAir1 = air;
}
double CPanel::getAir1()
{
    return m_fAir1;
}
void CPanel::setAir2(double air)
{
    m_fAir2 = air;
}
double CPanel::getAir2()
{
    return m_fAir2;
}
void CPanel::setAir3(double air)
{
    m_fAir3 = air;
}
double CPanel::getAir3()
{
    return m_fAir3;
}
void CPanel::setPre1(int pre)
{
    m_nPre1 = pre;
}
int CPanel::getPre1()
{
    return m_nPre1;
}
void CPanel::setTmp1(double tmp)
{
    m_fTmp1 = tmp;
}
double CPanel::getTmp1()
{
    return m_fTmp1;
}
void CPanel::setTmp2(double tmp)
{
    m_fTmp2 = tmp;
}
double CPanel::getTmp2()
{
    return m_fTmp2;
}
void CPanel::addIntParam(const char* pszName, const char* pszUnit, int value)
{
    CParam* pParam = new CParam(pszName, pszUnit, value);
    m_params.push_back(pParam);
}
void CPanel::addDoubleParam(const char* pszName, const char* pszUnit, double value)
{
    CParam* pParam = new CParam(pszName, pszUnit, value);
    m_params.push_back(pParam);
}
std::vector<CParam*>& CPanel::getParams()
{
    return m_params;
}
void CPanel::SetParamsRawData(const char* pszData)
{
    memcpy(m_pszParamsRawData, pszData, PARAM_RAWDATA_SIZE);
    // è§£é‡Šæ•°æ®åˆ°m_params中
    BOOL bUnitA = TRUE, bUnitB = TRUE;
    int i, v, startAddr = 5500;
    if (bUnitA) {
        i = (5520 - startAddr) * 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_下腔体吸真空延时", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_干泵吸真空延时", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_分子泵吸真空延时", "", v);
    }
    if (bUnitB) {
        i = (5540 - startAddr) * 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_下腔体吸真空延时", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_干泵吸真空延时", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_分子泵吸真空延时", "", v);
    }
    if (bUnitA) {
        i = (5600 - startAddr) * 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_上腔体至待预热位速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_上腔体至预热位速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_上腔体预压速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_上腔体压合速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体保压时间", "秒", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体水冷时间", "秒", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_预热延时", "秒", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_分离膜使用次数", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元分离膜次数设定", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_分离速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体初始力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M1轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M2轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M3轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M4轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M5轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_上腔体5轴力矩压合速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_上腔体M1轴压合压力", "kg", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_上腔体M2轴压合压力", "kg", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_上腔体M3轴压合压力", "kg", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_上腔体M4轴压合压力", "kg", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_上腔体M5轴压合压力", "kg", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_上腔体Z轴压合总压力", "kg", v);
        i += 4;
        addDoubleParam("A单元_气囊当前压力", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("A单元_贴合气囊压力设定值", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("A单元_气囊压缩率", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("A单元_上腔体初始温度", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("A单元_下腔体初始温度", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("A单元_干泵抽真空设定值", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("A单元_分子泵抽真空设定值", "", (double)toFloat(&pszData[i]));
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_é¡¶PIN下降速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_干泵气阀关闭延时", "", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_上腔Z轴压入量补偿值", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_收膜力矩值", "%", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_放膜力矩值", "%", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_力矩电机转速", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_分离距离补偿值", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_上腔体冷却温度", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_下腔体冷却温度", "", v);
        i += 2;
        addIntParam("A单元_压感压纸气囊压力设定值", "", (double)toFloat(&pszData[i]));
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_主轴力矩增速率", "%", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_主轴力矩上限", "%", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_主轴力矩减速率", "%", (double)v * 0.1);
        i += 12;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_上腔体分离膜高度补偿", "", v);
        i += 4;
        addDoubleParam("A单元_上腔体压合温度", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("A单元_下腔体压合温度", "", (double)toFloat(&pszData[i]));
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_上腔体Z轴初始压合压力", "kg", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_Step1超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_Step2超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_Step3超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_Step4超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_Step5超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_Step6超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M1轴力矩值%-临时", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M2轴力矩值%-临时", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M3轴力矩值%-临时", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M4轴力矩值%-临时", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_上腔体M5轴力矩值%-临时", "%", (double)v * 0.1);
    }
    if (bUnitB) {
        i = (5700 - startAddr) * 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_上腔体至待预热位速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_上腔体至预热位速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_上腔体预压速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_上腔体压合速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体保压时间", "秒", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体水冷时间", "秒", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_预热延时", "秒", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_分离膜使用次数", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元分离膜次数设定", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_分离速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体初始力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M1轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M2轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M3轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M4轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M5轴力矩值", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_上腔体5轴力矩压合速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_上腔体M1轴压合压力", "kg", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_上腔体M2轴压合压力", "kg", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_上腔体M3轴压合压力", "kg", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_上腔体M4轴压合压力", "kg", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_上腔体M5轴压合压力", "kg", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_上腔体Z轴压合总压力", "kg", v);
        i += 4;
        addDoubleParam("B单元_气囊当前压力", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("B单元_贴合气囊压力设定值", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("B单元_气囊压缩率", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("B单元_上腔体初始温度", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("B单元_下腔体初始温度", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("B单元_干泵抽真空设定值", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("B单元_分子泵抽真空设定值", "", (double)toFloat(&pszData[i]));
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_é¡¶PIN下降速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_干泵气阀关闭延时", "", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_上腔Z轴压入量补偿值", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_收膜力矩值", "%", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_放膜力矩值", "%", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_力矩电机转速", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_分离距离补偿值", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_上腔体冷却温度", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_下腔体冷却温度", "", v);
        i += 2;
        addIntParam("B单元_压感压纸气囊压力设定值", "", (double)toFloat(&pszData[i]));
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_主轴力矩增速率", "%", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_主轴力矩上限", "%", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_主轴力矩减速率", "%", (double)v * 0.1);
        i += 12;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_上腔体分离膜高度补偿", "", v);
        i += 4;
        addDoubleParam("B单元_上腔体压合温度", "", (double)toFloat(&pszData[i]));
        i += 4;
        addDoubleParam("B单元_下腔体压合温度", "", (double)toFloat(&pszData[i]));
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_上腔体Z轴初始压合压力", "kg", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_Step1超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_Step2超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_Step3超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_Step4超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_Step5超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_Step6超时设定", "", v);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M1轴力矩值%-临时", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M2轴力矩值%-临时", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M3轴力矩值%-临时", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M4轴力矩值%-临时", "%", (double)v * 0.1);
        i += 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_上腔体M5轴力矩值%-临时", "%", (double)v * 0.1);
    }
    i = (5800 - startAddr) * 2;
    v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
    addDoubleParam("冷却柜冷却时间", "", (double)v * 0.1);
    if (bUnitA) {
        i = (5840 - startAddr) * 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_温度上公差", "度", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("A单元_温度下公差", "度", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_压力上公差", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_压力下公差", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_é¡¶Pin慢速上升速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_上腔体升到零点位速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("A单元_慢速上升距离", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("A单元_é¡¶Pin破真空延时", "", v);
    }
    if (bUnitB) {
        i = (5870 - startAddr) * 2;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_温度上公差", "度", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addDoubleParam("B单元_温度下公差", "度", (double)v * 0.1);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_压力上公差", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_压力下公差", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_é¡¶Pin慢速上升速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_上腔体升到零点位速度", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24;
        addIntParam("B单元_慢速上升距离", "", v);
        i += 4;
        v = (m_pszParamsRawData[i] & 0xff) | (m_pszParamsRawData[i + 1] & 0xff) << 8;
        addIntParam("B单元_é¡¶Pin破真空延时", "", v);
    }
}
SourceCode/Bond/BondEq/CPanel.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,101 @@
#pragma once
#include "Context.h"
#include "Common.h"
#include <vector>
#include "CParam.h"
#define ITOTAL        0
#define IMAX        1
#define IMIN        2
#define IAVE        3
#define PANEL_DATA_SIZE        5 * 60 * 15
#define PARAM_RAWDATA_SIZE    4096
#define STEP_READY                0
#define STEP_RECEIVED            20
#define STEP_BEGIN_SAMPLING        1
#define STEP_END_SAMPLING        2
#define STEP_REMOVED            30
class CPanel :
    public CContext
{
public:
    CPanel();
    CPanel(const char* pszQRCode, int nUnitId);
    virtual ~CPanel();
public:
    virtual std::string& getClassName();
    virtual std::string toString();
    std::string& getQRCode();
    void setQRCode(const char* pszQRCode);
    int getUnitId();
    void setUnitId(int id);
    void setStep(int step);
    int getStep();
    int addData(UNITDATA1& data);
    const std::vector<UNITDATA1>& getDatas();
    void Serialize(CArchive& ar);
    bool getReceivedTime(int& year, int& month, int& day);
    ULONG64 GetCurrentSampleTime();
    ULONGLONG getReceivedTime();
    void setReceivedTime(ULONGLONG time);
    ULONGLONG getBeginSamplingTime();
    void setBeginSamplingTime(ULONGLONG time);
    ULONGLONG getEndSamplingTime();
    void setEndSamplingTime(ULONGLONG time);
    ULONGLONG getRemovedTime();
    void setRemovedTime(ULONGLONG time);
    void getDatas(std::vector<UNITDATA1>& out);
    BOOL getNewestData(UNITDATA1& data);
    UNITDATA1& getMathData(int index);
    void setMathData(int index, UNITDATA1& data);
    int getBlodLen();
    int getBlod(char* pszBuffer, int nBufferSize);
    int setBlod(char* pszBlod, int len);
public:
    void setRecipeName(const char* pszName);
    std::string& getRecipeName();
    void setAir1(double air);
    double getAir1();
    void setAir2(double air);
    double getAir2();
    void setAir3(double air);
    double getAir3();
    void setPre1(int pre);
    int getPre1();
    void setTmp1(double tmp);
    double getTmp1();
    void setTmp2(double tmp);
    double getTmp2();
    void addIntParam(const char* pszName, const char* pszUnit, int value);
    void addDoubleParam(const char* pszName, const char* pszUnit, double value);
    std::vector<CParam*>& getParams();
    void SetParamsRawData(const char* pszData);
private:
    std::string m_strQRCode;
    int m_nUnitId;
    std::vector<UNITDATA1> m_datas;
    UNITDATA1 m_dataMath[4];            // 0:汇总;1:最大;2:最小;3:平均
    ULONG64 m_timeBeginSampling;
    ULONG64 m_timeEndSampling;
    ULONG64 m_timeReceived;
    ULONG64 m_timeRemoved;
private:
    int m_nStep;            // å½“前步骤;
    std::string m_strRecipeName;
    double m_fAir1;            // å¹²æ³µå¸çœŸç©ºå€¼
    double m_fAir2;            // åˆ†å­æ³µå¸çœŸç©ºå€¼
    double m_fAir3;            // æ°”囊压力值
    int m_nPre1;            // è´´åˆæ€»åŽ‹åŠ›
    double m_fTmp1;            // ä¸Šè…”体温度
    double m_fTmp2;            // ä¸‹è…”体温度
    char* m_pszParamsRawData;
    std::vector<CParam*> m_params;            // å‡ºç«™æ—¶è®°å½•参数
};
SourceCode/Bond/BondEq/CParam.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
#include "stdafx.h"
#include "CParam.h"
CParam::CParam()
{
    m_nValueType = PVT_INT;
    m_nValue = 0;
    m_fValue = 0.0;
}
CParam::CParam(const char* pszName, const char* pszUnit, int value)
{
    m_nValueType = PVT_INT;
    m_nValue = value;
    m_fValue = 0.0;
    m_strName = pszName;
    m_strUnit = pszUnit;
}
CParam::CParam(const char* pszName, const char* pszUnit, double value)
{
    m_nValueType = PVT_DOUBLE;
    m_nValue = 0;
    m_fValue = value;
    m_strName = pszName;
    m_strUnit = pszUnit;
}
CParam::~CParam()
{
}
std::string& CParam::getName()
{
    return m_strName;
}
std::string& CParam::getUnit()
{
    return m_strUnit;
}
int CParam::getValueType()
{
    return m_nValueType;
}
int CParam::getIntValue()
{
    return m_nValue;
}
double CParam::getDoubleValue()
{
    return m_fValue;
}
void CParam::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        WriteString(ar, m_strName);
        WriteString(ar, m_strUnit);
        ar << m_nValueType;
        ar << m_nValue;
        ar << m_fValue;
    }
    else
    {
        ReadString(ar, m_strName);
        ReadString(ar, m_strUnit);
        ar >> m_nValueType;
        ar >> m_nValue;
        ar >> m_fValue;
    }
}
void CParam::ReadString(CArchive& ar, std::string& string)
{
    CString strTemp;
    ar >> strTemp;
    string = (LPTSTR)(LPCTSTR)strTemp;
}
void CParam::WriteString(CArchive& ar, std::string& string)
{
    CString strTemp = string.c_str();
    ar << strTemp;
}
SourceCode/Bond/BondEq/CParam.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
#pragma once
#include <string>
#define PVT_INT        0
#define PVT_DOUBLE    1
class CParam
{
public:
    CParam();
    CParam(const char* pszName, const char* pszUnit, int value);
    CParam(const char* pszName, const char* pszUnit, double value);
    ~CParam();
public:
    std::string& getName();
    std::string& getUnit();
    int getValueType();
    int getIntValue();
    double getDoubleValue();
    void Serialize(CArchive& ar);
private:
    void ReadString(CArchive& ar, std::string& string);
    void WriteString(CArchive& ar, std::string& string);
private:
    int m_nValueType;
    std::string m_strName;
    std::string m_strUnit;
    int m_nValue;
    double m_fValue;
};
SourceCode/Bond/BondEq/Common.h
@@ -4,6 +4,11 @@
#define MC_TIME_SEPAR                1000
#define UNITA            _T("UNITA")
#define UNITB            _T("UNITB")
#define UNITC            _T("C")
/* Context Ret code */
#define CRC_ACK_REJECT                            -3
#define CRC_TIMEOUT                                -2
@@ -87,3 +92,21 @@
/* æŒ‰é’®id */
#define VIEW_TOOL_BTN_CLOSE                0x1016
/* å•元数据 */
typedef struct _UNITDATA1
{
    ULONG64 time;
    /* 0:上腔体温度 */
    /* 1:下腔体温度 */
    /* 2~9:8个腔体监测温度 */
    float temp[12];
    /* è…”体真空 pa */
    float vacuum;
    /* 5个压力值 kg */
    float pressure[5];
} UNITDATA1;
SourceCode/Bond/BondEq/Component.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
#include "stdafx.h"
#include "Common.h"
#include "Component.h"
#include "Log.h"
#include "CBonder.h"
CComponent::CComponent()
{
    m_pBonder = NULL;
    m_pChannel1 = NULL;
    m_nIndex = 0;
    m_bRunning = FALSE;
    InitializeCriticalSection(&m_criticalSection);
}
CComponent::~CComponent()
{
    DeleteCriticalSection(&m_criticalSection);
}
void CComponent::setBonder(CBonder* pBonder)
{
    m_pBonder = pBonder;
}
void CComponent::init()
{
    MCL_GetChannel(m_pChannel1, MC_CHANNEL1_NAME);
}
void CComponent::term()
{
}
int CComponent::run()
{
    m_bRunning = TRUE;
    return 0;
}
int CComponent::stop()
{
    m_bRunning = FALSE;
    return 0;
}
void CComponent::setName(const char* pszName)
{
    m_strName = pszName;
}
std::string& CComponent::getName()
{
    return m_strName;
}
void CComponent::setDescription(const char* pszDescription)
{
    m_strDescription = pszDescription;
}
std::string& CComponent::getDescription()
{
    return m_strDescription;
}
void CComponent::setIndex(int index)
{
    m_nIndex = index;
}
int CComponent::getIndex()
{
    return m_nIndex;
}
void CComponent::onRecvBroadcast(void* pSender, CIntent* pIntent)
{
}
void CComponent::onData(int id, const void* pData, int size)
{
}
void CComponent::SendBroadcast(CIntent* pIntent)
{
    m_pBonder->sendBroadcast(this, pIntent);
}
int CComponent::WriteInt(int unitId, int addr, int value)
{
    return m_pBonder->writeInt(unitId, addr, value);
}
int CComponent::WriteData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
    const char* pszData, unsigned int length, ONWRITE funOnWrite)
{
    return m_pBonder->writeData(softComponent, addr, pszData, length, funOnWrite);
}
void CComponent::OnTimer(UINT nTimerid)
{
}
void CComponent::Serialize(CArchive& ar)
{
}
float CComponent::toFloat(const char* pszAddr)
{
    BYTE szBuffer[4];
    szBuffer[0] = pszAddr[0];
    szBuffer[1] = pszAddr[1];
    szBuffer[2] = pszAddr[2];
    szBuffer[3] = pszAddr[3];
    float f = 0.0;
    memcpy(&f, szBuffer, 4);
    return f;
}
SourceCode/Bond/BondEq/Component.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
#pragma once
#include <functional>
#include <string>
#include "Context.h"
#include "Intent.h"
#include "McBool.h"
#include "McString.h"
#include "McInt.h"
class CBonder;
class CComponent
{
public:
    CComponent();
    virtual ~CComponent();
public:
    virtual std::string& getClassName() = 0;
    void setBonder(CBonder* pBonder);
    void setName(const char* pszName);
    std::string& getName();
    void setDescription(const char* pszDescription);
    std::string& getDescription();
    void setIndex(int index);
    int getIndex();
    virtual void onRecvBroadcast(void* pSender, CIntent* pIntent);
    virtual void onData(int id, const void* pData, int size);
    virtual void init();
    virtual void term();
    virtual int run();
    virtual int stop();
    virtual void OnTimer(UINT nTimerid);
    virtual void Serialize(CArchive& ar);
    static float toFloat(const char* pszAddr);
    int WriteInt(int unitId, int addr, int value);
    int WriteData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
        const char* pszData, unsigned int length, ONWRITE funOnWrite);
protected:
    inline void Lock() { EnterCriticalSection(&m_criticalSection); }
    inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
    void SendBroadcast(CIntent* pIntent);
protected:
    CBonder* m_pBonder;
    IMcChannel* m_pChannel1;
    int m_nIndex;
    std::string m_strName;
    std::string m_strDescription;
    CRITICAL_SECTION m_criticalSection;
protected:
    BOOL m_bRunning;
};
SourceCode/Bond/BondEq/Context.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,157 @@
#include "stdafx.h"
#include "Context.h"
CContext::CContext()
{
    m_nRef = 0;
    m_nRetCode = 0;
    m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    InitializeCriticalSection(&m_criticalSection);
}
CContext::~CContext()
{
    if (m_hEvent != NULL) {
        CloseHandle(m_hEvent);
        m_hEvent = NULL;
    }
    DeleteCriticalSection(&m_criticalSection);
}
int CContext::addRef()
{
    Lock();
    m_nRef++;
    Unlock();
    return m_nRef;
}
int CContext::release()
{
    Lock();
    m_nRef--;
    BOOL bDelete = m_nRef == 0;
    Unlock();
    int nRef = m_nRef;;
    if (bDelete) delete this;
    return nRef;
}
void CContext::setRetCode(int code)
{
    m_nRetCode = code;
}
int CContext::getRetCode()
{
    return m_nRetCode;
}
void CContext::setRetMsg(const char* pszMsg)
{
    m_strRetMsg = pszMsg;
}
std::string& CContext::getRetMsg()
{
    return m_strRetMsg;
}
HANDLE CContext::getEventHandle()
{
    return m_hEvent;
}
void CContext::setEvent()
{
    if (m_hEvent != NULL) {
        SetEvent(m_hEvent);
    }
}
void CContext::resetEvent()
{
    if (m_hEvent != NULL) {
        ResetEvent(m_hEvent);
    }
}
void CContext::ReadString(CArchive& ar, std::string& string)
{
    CString strTemp;
    ar >> strTemp;
    string = (LPTSTR)(LPCTSTR)strTemp;
}
void CContext::WriteString(CArchive& ar, std::string& string)
{
    CString strTemp = string.c_str();
    ar << strTemp;
}
void CContext::createDir(CString strDir)
{
    int lastIndex = 0;
    int index = strDir.Find(_T("\\"), lastIndex);
    while (index > 0) {
        CString strTempDir = strDir.Left(index);
        CreateDirectory(strTempDir, NULL);
        lastIndex = index + 1;
        index = strDir.Find(_T("\\"), lastIndex);
    }
    CreateDirectory(strDir, NULL);
}
BOOL CContext::IsBoxId(CString& strId)
{
    //'W20'开头,倒数第五位为'Z'的字符串
    if (strId.GetLength() < 8) {
        return FALSE;
    }
    if (strId.Left(3).Compare(_T("W20")) != 0) {
        return FALSE;
    }
    if (strId.Right(5).GetAt(0) != (char)'Z') {
        return FALSE;
    }
    return TRUE;
}
BOOL CContext::IsLotId(CString& strId)
{
    //'N20'开头,倒数第五位为'Z'的字符串
    if (strId.GetLength() < 8) {
        return FALSE;
    }
    if (strId.Left(3).Compare(_T("N20")) != 0) {
        return FALSE;
    }
    if (strId.Right(5).GetAt(0) != (char)'Z') {
        return FALSE;
    }
    return TRUE;
}
float CContext::toFloat(const char* pszAddr)
{
    BYTE szBuffer[4];
    szBuffer[0] = pszAddr[0];
    szBuffer[1] = pszAddr[1];
    szBuffer[2] = pszAddr[2];
    szBuffer[3] = pszAddr[3];
    float f = 0.0;
    memcpy(&f, szBuffer, 4);
    return f;
}
SourceCode/Bond/BondEq/Context.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
#pragma once
#include "Common.h"
class CContext : public IRxObject
{
public:
    CContext();
    virtual ~CContext();
public:
    int addRef();
    int release();
public:
    virtual std::string& getClassName() = 0;
    virtual std::string toString() = 0;
    void setRetCode(int code);
    int getRetCode();
    void setRetMsg(const char* pszMsg);
    std::string& getRetMsg();
    HANDLE getEventHandle();
    void setEvent();
    void resetEvent();
    static void createDir(CString strDir);
    float toFloat(const char* pszAddr);
protected:
    inline void Lock() { EnterCriticalSection(&m_criticalSection); }
    inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
    void ReadString(CArchive& ar, std::string& string);
    void WriteString(CArchive& ar, std::string& string);
    static BOOL IsBoxId(CString& strId);
    static BOOL IsLotId(CString& strId);
private:
    int m_nRef;
    CRITICAL_SECTION m_criticalSection;
protected:
    int m_nRetCode;
    std::string m_strRetMsg;
    HANDLE m_hEvent;
};
SourceCode/Bond/BondEq/EQState.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
#include "stdafx.h"
#include "EQState.h"
#include "ToolUnits.h"
CEQState::CEQState()
{
    m_nUnitId = 0;
    m_state = EQSTATE::Idle;
    m_nDoorState = -1;
    m_time = CToolUnits::getTimestamp();
}
CEQState::CEQState(int unitId, EQSTATE state)
{
    m_nUnitId = unitId;
    m_state = state;
    m_nDoorState = -1;
    m_time = CToolUnits::getTimestamp();
}
CEQState::~CEQState()
{
}
std::string& CEQState::getClassName()
{
    static std::string strName = "CAlarm";
    return strName;
}
std::string CEQState::toString()
{
    CString strTemp;
    std::string strText;
    strText += "CAlarm[";
    strText += ("time:" + CToolUnits::timeToString2(m_time) + ";");
    strText += ("State:" + std::string((LPTSTR)(LPCTSTR)getText(strTemp)) + ";");
    strText += "]";
    return strText;
}
void CEQState::setDoorState(int doorst)
{
    m_nDoorState = doorst;
}
int CEQState::getUnitId()
{
    return m_nUnitId;
}
ULONGLONG CEQState::getTime()
{
    return m_time;
}
EQSTATE CEQState::getState()
{
    return m_state;
}
CString& CEQState::getText(CString& strOut)
{
    static char* pszState[] = {"Idle", "Run", "Down", "Maintenance", "MCHG", "E_TIME"};
    if (m_nDoorState != -1) {
        strOut.Empty();
        if (m_nDoorState & 0x01) strOut.Append("Door State<Open,");
        else strOut.Append("Door State<Close,");
        if (m_nDoorState & 0x02) strOut.Append("Open,");
        else strOut.Append("Close,");
        if (m_nDoorState & 0x04) strOut.Append("Open,");
        else strOut.Append("Close,");
        if (m_nDoorState & 0x08) strOut.Append("Open,");
        else strOut.Append("Close,");
        if (m_nDoorState & 0x10) strOut.Append("Open>");
        else strOut.Append("Close>");
    }
    else {
        strOut = CString(pszState[(int)m_state - 1]);
    }
    return strOut;
}
void CEQState::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        Lock();
        ar << m_nUnitId;
        ar << m_time;
        ar << (int)m_state;
        ar << m_nDoorState;
        Unlock();
    }
    else
    {
        int temp;
        Lock();
        ar >> m_nUnitId;
        ar >> m_time;
        ar >> temp;
        m_state = (EQSTATE)temp;
        ar >> m_nDoorState;
        Unlock();
    }
}
SourceCode/Bond/BondEq/EQState.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
#pragma once
#include "Context.h"
enum class EQSTATE
{
    Idle = 1,
    Run,
    Down,
    Maintenance,
    MCHG,
    E_TIME
};
class CEQState :
    public CContext
{
public:
    CEQState();
    CEQState(int unitId, EQSTATE state);
    ~CEQState();
public:
    virtual std::string& getClassName();
    virtual std::string toString();
    void setDoorState(int doorst);
    int getUnitId();
    ULONGLONG getTime();
    EQSTATE getState();
    CString& getText(CString& strOut);
    void Serialize(CArchive& ar);
private:
    int m_nUnitId;
    ULONG64 m_time;
    EQSTATE m_state;
    int m_nDoorState;
};
SourceCode/Bond/BondEq/EQStateMonitor.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,155 @@
#include "stdafx.h"
#include "EQStateMonitor.h"
#include "Common.h"
#include "CBonder.h"
#include "Log.h"
#define EQSTATE_MAX        200
CEQStateMonitor::CEQStateMonitor()
{
    m_nBeginAddr = 0;
    m_bStatusReport = FALSE;
    m_lastState = EQSTATE::Idle;
    m_nLastDoorState = 0;
}
CEQStateMonitor::~CEQStateMonitor()
{
}
std::string& CEQStateMonitor::getClassName()
{
    static std::string strClassName = "CEQStateMonitor";
    return strClassName;
}
void CEQStateMonitor::onRecvBroadcast(void* pSender, CIntent* pIntent)
{
}
void CEQStateMonitor::onData(int id, const void* pData, int size)
{
    const char* pszData = (const char*)pData;
    if (m_nIndex + 1 == id) {
        int addr = m_nBeginAddr * 2;
        int state = (pszData[addr] & 0xff) | (pszData[addr + 1] & 0xff) << 8;
        if ((int)m_lastState != state && (state >= 1 && state <= 6)) {
            LOGI("<CEQStateMonitor-%d>state:%d", m_nIndex, state);
            ReportStatus(state);
        }
        int doorState = (pszData[addr + 2] & 0xff) | (pszData[addr + 3] & 0xff) << 8;
        if (m_nLastDoorState != doorState) {
            LOGI("<CEQStateMonitor-%d>door state:%d", m_nIndex, doorState);
            ReportDoorState((int)m_lastState, doorState);
        }
    }
}
void CEQStateMonitor::enableStatusReport(BOOL bEnable)
{
    m_bStatusReport = bEnable;
}
void CEQStateMonitor::init()
{
    CComponent::init();
}
void CEQStateMonitor::term()
{
    for (auto item : m_eqStates) {
        item->release();
    }
}
void CEQStateMonitor::setBeginAddr(int nAddr)
{
    m_nBeginAddr = nAddr;
}
void CEQStateMonitor::OnTimer(UINT nTimerid)
{
}
void CEQStateMonitor::ReportStatus(int eqst)
{
    BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex);
    ASSERT(pUnit);
    pUnit->setState((BEQ::EQ_STATE)(eqst-1));
    LOGI("<CEQStateMonitor-%d> æ›´æ–°è®¾å¤‡çŠ¶æ€(%d).", m_nIndex, eqst);
    CEQState* pState = new CEQState(m_nIndex, (EQSTATE)eqst);
    AddEQState(pState);
    SendBroadcast(&CIntent(BC_CODE_EQSTATE_EVENT, "", pState));
    m_lastState = (EQSTATE)eqst;
}
void CEQStateMonitor::ReportDoorState(int eqst, int doorst)
{
    BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex);
    ASSERT(pUnit);
    pUnit->setDoorState(doorst);
    LOGI("<CEQStateMonitor-%d>更新安全门状态(%d).", m_nIndex, doorst);
    CEQState* pState = new CEQState(m_nIndex, (EQSTATE)eqst);
    pState->setDoorState(doorst);
    AddEQState(pState);
    SendBroadcast(&CIntent(BC_CODE_EQSTATE_EVENT, "", pState));
    m_nLastDoorState = doorst;
}
void CEQStateMonitor::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        Lock();
        int count = (int)m_eqStates.size();
        ar << count;
        for (auto item : m_eqStates) {
            item->Serialize(ar);
        }
        Unlock();
    }
    else
    {
        Lock();
        int count;
        ar >> count;
        for (int i = 0; i < count; i++) {
            CEQState* pState = new CEQState();
            pState->addRef();
            pState->Serialize(ar);
            AddEQState(pState);
            pState->release();
        }
        Unlock();
    }
}
void CEQStateMonitor::AddEQState(CEQState* pEQState)
{
    Lock();
    pEQState->addRef();
    m_eqStates.push_back(pEQState);
    if (m_eqStates.size() > EQSTATE_MAX) {
        CEQState* pTemp = m_eqStates.front();
        pTemp->release();
        m_eqStates.pop_front();
    }
    Unlock();
}
void CEQStateMonitor::getEQStateList(std::list<CEQState*>& list)
{
    Lock();
    list = m_eqStates;
    Unlock();
}
SourceCode/Bond/BondEq/EQStateMonitor.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
#pragma once
#include "Component.h"
#include <map>
#include <list>
#include "EQState.h"
class CEQStateMonitor :
    public CComponent
{
public:
    CEQStateMonitor();
    ~CEQStateMonitor();
public:
    virtual std::string& getClassName();
    virtual void onData(int id, const void* pData, int size);
    virtual void onRecvBroadcast(void* pSender, CIntent* pIntent);
    virtual void init();
    virtual void term();
    void setBeginAddr(int nAddr);
    void enableStatusReport(BOOL bEnable);
    virtual void OnTimer(UINT nTimerid);
    void ReportStatus(int eqst);
    void ReportDoorState(int eqst, int doorst);
    virtual void Serialize(CArchive& ar);
    void getEQStateList(std::list<CEQState*>& list);
private:
    void AddEQState(CEQState* eqState);
private:
    int m_nBeginAddr;
private:
    BOOL m_bStatusReport;
    EQSTATE m_lastState;
    int m_nLastDoorState;
    std::list<CEQState*> m_eqStates;
};
SourceCode/Bond/BondEq/Intent.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
#include "stdafx.h"
#include "Intent.h"
CIntent::CIntent()
{
    m_nCode = 0;
    m_pContext = nullptr;
}
CIntent::CIntent(int nCode, const char* pszMsg, CContext* pContext)
{
    m_nCode = nCode;
    m_strMsg = pszMsg;
    m_pContext = pContext;
}
CIntent::~CIntent()
{
}
void CIntent::setCode(int nCode)
{
    m_nCode = nCode;
}
int CIntent::getCode()
{
    return m_nCode;
}
void CIntent::setMsg(const char* pszMsg)
{
    m_strMsg = pszMsg;
}
const char* CIntent::getMsg()
{
    return m_strMsg.c_str();
}
void CIntent::setContext(CContext* pContext)
{
    pContext->addRef();
    m_pContext = pContext;
}
CContext* CIntent::getContext()
{
    return m_pContext;
}
SourceCode/Bond/BondEq/Intent.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
#pragma once
#include <string>
#include "Context.h"
class CIntent
{
public:
    CIntent();
    CIntent(int nCode, const char* pszMsg, CContext* pContext);
    ~CIntent();
public:
    void setCode(int nCode);
    int getCode();
    void setMsg(const char* pszMsg);
    const char* getMsg();
    void setContext(CContext* pContext);
    CContext* getContext();
private:
    int m_nCode;
    std::string m_strMsg;
    CContext* m_pContext;
};
SourceCode/Bond/BondEq/LoadMonitor.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,419 @@
#include "stdafx.h"
#include "LoadMonitor.h"
#include "Common.h"
#include "CBonder.h"
#include "Log.h"
#define ALARM_MAX        200
unsigned __stdcall LoadMonitorRunRecipeThreadFunction(LPVOID lpParam)
{
    CLoadMonitor* p = (CLoadMonitor*)lpParam;
    return p->RunRecipeThreadFunction();
}
CLoadMonitor::CLoadMonitor()
{
    m_nBeginAddr = 0;
    m_nLastId = 0;
    m_nLastLevel = 0;
    m_hEventRunRecipeResult = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    m_nRunRecipeResult = 0;
    m_hRunRecipeWorkThreadHandle = NULL;
    m_nRunRecipeWorkThrdaddr = 0;
    m_bRunRecipeWorking = FALSE;
    m_hRunRecipeWorkEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    m_bWaitingRecipeResult = FALSE;
}
CLoadMonitor::~CLoadMonitor()
{
    if (m_hEventRunRecipeResult != nullptr) {
        CloseHandle(m_hEventRunRecipeResult);
        m_hEventRunRecipeResult = nullptr;
    }
}
std::string& CLoadMonitor::getClassName()
{
    static std::string strClassName = "CLoadMonitor";
    return strClassName;
}
void CLoadMonitor::onRecvBroadcast(void* pSender, CIntent* pIntent)
{
}
void CLoadMonitor::onData(int id, const void* pData, int size)
{
    const char* pszData = (const char*)pData;
    if (3 != id) return;
    BOOL bPause, bReqLoad, bReqUnload;
    if (m_nIndex == 0 || m_nIndex == 1) {
        // å…¥æ–™è¯·æ±‚
        bPause = pszData[m_nIndex * 2] & 0x04;
        if (bPause) {
            ReqNotReady(1);
        }
        else {
            bReqLoad = pszData[m_nIndex * 2] & 0x01;
            if (bReqLoad) {
                ReqLoad(1);
            }
            else {
                // å‡ºæ–™è¯·æ±‚
                bReqUnload = pszData[m_nIndex * 2 + 1] & 0x01;
                if (bReqUnload) {
                    ReqUnload(1);
                }
            }
        }
    }
    else if (m_nIndex == 2) {
        // Layer1 å…¥æ–™è¯·æ±‚
        bReqLoad = pszData[m_nIndex * 2] & 0x01;
        if (bReqLoad) {
            ReqLoad(1);
        }
        else {
            // å‡ºæ–™è¯·æ±‚
            bReqUnload = pszData[m_nIndex * 2] & 0x20;
            if (bReqUnload) {
                ReqUnload(1);
            }
        }
        // Layer2
        bReqLoad = pszData[m_nIndex * 2] & 0x02;
        if (bReqLoad) {
            ReqLoad(2);
        }
        else {
            bReqUnload = pszData[m_nIndex * 2] & 0x40;
            if (bReqUnload) {
                ReqUnload(2);
            }
        }
        // Layer3
        bReqLoad = pszData[m_nIndex * 2] & 0x04;
        if (bReqLoad) {
            ReqLoad(3);
        }
        else {
            bReqUnload = pszData[m_nIndex * 2] & 0x80;
            if (bReqUnload) {
                ReqUnload(3);
            }
        }
        // Layer4
        bReqLoad = pszData[m_nIndex * 2] & 0x08;
        if (bReqLoad) {
            ReqLoad(4);
        }
        else {
            bReqUnload = pszData[m_nIndex * 2 + 1] & 0x01;
            if (bReqUnload) {
                ReqUnload(4);
            }
        }
    }
    // åˆ‡æ¢é…æ–¹ç»“æžœ
    if (m_nIndex == 0 || m_nIndex == 1) {
        int nAddr = (90 + m_nIndex) * 2;
        m_nRunRecipeResult = (pszData[nAddr] & 0xff) | (pszData[nAddr + 1]) << 8;
        if (m_bWaitingRecipeResult) {
            LOGI("<CLoadMonitor>正在读取PLC切换配方的结果(RunRecipeResult:%d).", m_nRunRecipeResult);
        }
        if (m_nRunRecipeResult != 0) {
            SetEvent(m_hEventRunRecipeResult);
        }
    }
}
void CLoadMonitor::init()
{
    m_bRunRecipeWorking = TRUE;
    m_hRunRecipeWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, ::LoadMonitorRunRecipeThreadFunction, this,
        0, &m_nRunRecipeWorkThrdaddr);
    CComponent::init();
}
void CLoadMonitor::term()
{
    // ç»“束线程
    m_bRunRecipeWorking = FALSE;
    SetEvent(m_hRunRecipeWorkEvent);
    if (m_hRunRecipeWorkThreadHandle != NULL) {
        WaitForSingleObject(m_hRunRecipeWorkThreadHandle, INFINITE);
        CloseHandle(m_hRunRecipeWorkThreadHandle);
        m_hRunRecipeWorkThreadHandle = NULL;
    }
    for (auto item : m_alarms) {
        item->release();
    }
}
void CLoadMonitor::setBeginAddr(int nAddr)
{
    m_nBeginAddr = nAddr;
}
void CLoadMonitor::OnTimer(UINT nTimerid)
{
    /*
    char szBuffer[184];
    memset(szBuffer, 0, 184);
    if (m_nIndex == 0) {
        static int iii = 0;
        iii++;
        if (iii > 30 && iii < 35) {
            szBuffer[0] = 0x01;
            onData(3, &szBuffer[0], 184);
        }
        else if (iii > 35 && iii < 52) {
            szBuffer[90 * 2] = 0x08;
            onData(3, &szBuffer[0], 184);
        }
        else if (iii > 60 && iii < 90) {
            szBuffer[1] = 0x01;
            onData(3, &szBuffer[0], 184);
        }
    }
    if (m_nIndex == 1) {
        static int iii = 0;
        iii++;
        if (iii > 130 && iii < 160) {
            szBuffer[2] = 0x01;
            onData(3, &szBuffer[0], 184);
        }
        else if (iii > 160 && iii < 190) {
            szBuffer[3] = 0x01;
            onData(3, &szBuffer[0], 184);
        }
    }
    if (m_nIndex == 2) {
        static int iii = 0;
        iii++;
        if (iii > 30 && iii < 60) {
            szBuffer[4] = 0x20;
            onData(3, &szBuffer[0], 184);
        }
        else if (iii > 60 && iii < 90) {
            szBuffer[4] = 0x40;
            onData(3, &szBuffer[0], 184);
        }
        else if (iii > 90 && iii < 120) {
            szBuffer[4] = 0x80;
            szBuffer[5] = 0x1;
            onData(3, &szBuffer[0], 184);
        }
    }
    */
}
void CLoadMonitor::ReqNotReady(int layer)
{
    BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex);
    ASSERT(pUnit);
    // è¯·æ±‚上料
    if (0 == pUnit->reqNotReady(layer))
        LOGI("<CLoadMonitor-%d>Layer%d暂停上下料.", m_nIndex, layer);
}
void CLoadMonitor::ReqLoad(int layer)
{
    BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex);
    ASSERT(pUnit);
    // è¯·æ±‚上料
    if(0 == pUnit->reqLoad(layer))
        LOGI("<CLoadMonitor-%d>Layer%d请求上料.", m_nIndex, layer);
}
void CLoadMonitor::ReqUnload(int layer)
{
    BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex);
    ASSERT(pUnit);
    // è¯·æ±‚上料
    if(0 == pUnit->reqUnload(layer))
        LOGI("<CLoadMonitor-%d>Layer%d请求下料.", m_nIndex, layer);
}
int CLoadMonitor::loadReady(const char* pszMaterielId, const char* pszRecipeId)
{
    // æ ¹æ®å•元号取得PLC地址
    int nMaterielIdAddr, nRecipeIdAddr;
    if (m_nIndex == 0) {
        nMaterielIdAddr = 4720;
        nRecipeIdAddr = 4780;
    }
    else if (m_nIndex == 1) {
        nMaterielIdAddr = 4750;
        nRecipeIdAddr = 4781;
    }
    else {
        return 0;
    }
    // å†™å…¥ç‰©æ–™ID
    HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    BOOL bWriteOk = TRUE;
    char szBuffer[40];
    memset(szBuffer, 0, 40);
    memcpy(szBuffer, pszMaterielId, min(40, strlen(pszMaterielId)));
    WriteData(MC::SOFT_COMPONENT::D, nMaterielIdAddr, szBuffer, 40, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
        if (flag != 0) {
            LOGE("<CBonder::loadReady-%d>PLC1写数据超时.flag=%d", __LINE__, flag);
            bWriteOk = FALSE;
        }
        SetEvent(hEvent);
    });
    WaitForSingleObject(hEvent, INFINITE);
    ResetEvent(hEvent);
    if (!bWriteOk) {
        LOGE("<CBonder>%s上料准备就绪, PLC已写入物料id失败", m_strName.c_str());
        CloseHandle(hEvent);
        return -3;
    }
    LOGI("<CBonder>%s上料准备就绪,PLC已写入物料id", m_strName.c_str());
    // å†™å…¥é…æ–¹ID
    bWriteOk = TRUE;
    int nRecipeId = atoi(pszRecipeId);
    szBuffer[0] = (nRecipeId & 0xff);
    szBuffer[1] = (nRecipeId & 0xff00) >> 8;
    WriteData(MC::SOFT_COMPONENT::D, nRecipeIdAddr, szBuffer, 2, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
        if (flag != 0) {
            LOGE("<CBonder::loadReady-%d>PLC1写数据超时.flag=%d", __LINE__, flag);
            bWriteOk = FALSE;
        }
        SetEvent(hEvent);
    });
    WaitForSingleObject(hEvent, INFINITE);
    ResetEvent(hEvent);
    CloseHandle(hEvent);
    if (!bWriteOk) {
        LOGE("<CBonder>%s上料准备就绪, PLC写配方ID无响应", m_strName.c_str());
        return -4;
    }
    LOGI("<CBonder>%s上料准备就绪,PLC已写入配方id", m_strName.c_str());
    // ç­‰å¾…PLC响应,PLC D4790(D4791)切换配方结果:1成功,2稍候重试,3报警.txt
    // è¿™é‡Œè¦æ”¾åˆ°çº¿ç¨‹åŽ»æ‰§è¡Œäº†
    SetEvent(m_hRunRecipeWorkEvent);
    return 1;
}
void CLoadMonitor::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        Lock();
        int count = (int)m_alarms.size();
        ar << count;
        for (auto item : m_alarms) {
            item->Serialize(ar);
        }
        Unlock();
    }
    else
    {
        Lock();
        int count;
        ar >> count;
        for (int i = 0; i < count; i++) {
            CAlarm* pAlarm = new CAlarm();
            pAlarm->addRef();
            pAlarm->Serialize(ar);
            AddAlarm(pAlarm);
            pAlarm->release();
        }
        Unlock();
    }
}
void CLoadMonitor::AddAlarm(CAlarm* pAlarm)
{
    Lock();
    pAlarm->addRef();
    m_alarms.push_back(pAlarm);
    if (m_alarms.size() > ALARM_MAX) {
        CAlarm* pTemp = m_alarms.front();
        pTemp->release();
        m_alarms.pop_front();
    }
    Unlock();
}
DWORD CLoadMonitor::WaitForGetRunRecipeResult(int timeout, int& result)
{
    m_bWaitingRecipeResult = TRUE;
    ResetEvent(m_hEventRunRecipeResult);
    m_nRunRecipeResult = 0;
    DWORD nRet = WaitForSingleObject(m_hEventRunRecipeResult, timeout);
    result = m_nRunRecipeResult;
    m_bWaitingRecipeResult = FALSE;
    return nRet;
}
unsigned CLoadMonitor::RunRecipeThreadFunction()
{
    while (m_bRunRecipeWorking) {
        // å¾…退出信号或时间到
        int nRet = WaitForSingleObject(m_hRunRecipeWorkEvent, INFINITE);
        ResetEvent(m_hRunRecipeWorkEvent);
        if (!m_bRunRecipeWorking) break;
        // ç­‰å¾…PLC切换配方结果
        int nError = 0;
        int nRunRecipeResult = 0;
        nRet = WaitForGetRunRecipeResult(3000, nRunRecipeResult);
        if (nRet != WAIT_OBJECT_0) {
            LOGE("<CBonder>%s, è¯»å–PLC切换配方结果超时", m_strName.c_str());
            nError = -5;
        }
        else {
            if (nRunRecipeResult == 1) {
                LOGI("<CBonder>%s, PLC切换配方成功", m_strName.c_str());
                nError = 0;
            }
            else if (nRunRecipeResult == 2) {
                LOGE("<CBonder>%s, PLC忙碌,请稍候重试。", m_strName.c_str());
                nError = -6;
            }
            else {
                LOGE("<CBonder>%s, PLC切换配方失败", m_strName.c_str());
                nError = -7;
            }
        }
        SendBroadcast(&CIntent(BC_CODE_RUN_RECIPE_RESULT, "", (CContext*)(__int64)nError));
        TRACE("RunRecipeThreadFunction...... \n");
    }
    // _endthreadex(0);
    TRACE("RunRecipeThreadFunction exit\n");
    return 0;
}
SourceCode/Bond/BondEq/LoadMonitor.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
#pragma once
#include "Component.h"
#include <map>
#include <list>
#include "Alarm.h"
class CLoadMonitor :
    public CComponent
{
public:
    CLoadMonitor();
    ~CLoadMonitor();
public:
    virtual std::string& getClassName();
    virtual void onData(int id, const void* pData, int size);
    virtual void onRecvBroadcast(void* pSender, CIntent* pIntent);
    virtual void init();
    virtual void term();
    void setBeginAddr(int nAddr);
    virtual void OnTimer(UINT nTimerid);
    void ReqNotReady(int layer);
    void ReqLoad(int layer);
    void ReqUnload(int layer);
    int loadReady(const char* pszMaterielId, const char* pszRecipeId);
    DWORD WaitForGetRunRecipeResult(int timeout, int& result);
    unsigned RunRecipeThreadFunction();
    virtual void Serialize(CArchive& ar);
private:
    void AddAlarm(CAlarm* pAlarm);
private:
    int m_nBeginAddr;
private:
    std::map<int, std::string> m_mapAlarmText;
    int m_nLastId;
    int m_nLastLevel;
    std::list<CAlarm*> m_alarms;
    HANDLE m_hEventRunRecipeResult;
    BOOL m_bWaitingRecipeResult;
    int m_nRunRecipeResult;
    BOOL m_bRunRecipeWorking;
    HANDLE m_hRunRecipeWorkEvent;
    HANDLE m_hRunRecipeWorkThreadHandle;
    unsigned m_nRunRecipeWorkThrdaddr;
};
SourceCode/Bond/BondEq/McBool.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
#include "stdafx.h"
#include "McBool.h"
CMcBool::CMcBool()
{
    m_nAddr = 0;
    m_bValue = false;
}
CMcBool::~CMcBool()
{
}
SourceCode/Bond/BondEq/McBool.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
#pragma once
class CMcBool
{
public:
    CMcBool();
    ~CMcBool();
public:
    int m_nAddr;
    bool m_bValue;
};
SourceCode/Bond/BondEq/McInt.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
#include "stdafx.h"
#include "McInt.h"
CMcInt::CMcInt()
{
    m_nAddr = 0;
    m_nValue = 0;
}
CMcInt::~CMcInt()
{
}
SourceCode/Bond/BondEq/McInt.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
#pragma once
class CMcInt
{
public:
    CMcInt();
    ~CMcInt();
public:
    int m_nAddr;
    int m_nValue;
};
SourceCode/Bond/BondEq/McItem.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
#include "stdafx.h"
#include "McItem.h"
CMcItem::CMcItem()
{
}
CMcItem::~CMcItem()
{
}
SourceCode/Bond/BondEq/McItem.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
#pragma once
class CMcItem
{
public:
    CMcItem();
    ~CMcItem();
};
SourceCode/Bond/BondEq/McString.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
#include "stdafx.h"
#include "McString.h"
CMcString::CMcString()
{
    m_nAddrStart = 0;
    m_nAddrEnd = 0;
}
CMcString::~CMcString()
{
}
SourceCode/Bond/BondEq/McString.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
#pragma once
#include <string>
class CMcString
{
public:
    CMcString();
    ~CMcString();
public:
    int m_nAddrStart;
    int m_nAddrEnd;
    std::string m_strValue;
};
SourceCode/Bond/BondEq/Model.h
@@ -1,5 +1,5 @@
#pragma once
#include "Bonder.h"
#include "CBonder.h"
#include "Configuration.h"
SourceCode/Bond/BondEq/Recipe.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
#include "stdafx.h"
#include "Recipe.h"
CRecipe::CRecipe()
{
}
CRecipe::CRecipe(int id, const char* pszName)
{
    m_nId = id;
    m_strName = pszName;
}
CRecipe::~CRecipe()
{
}
int CRecipe::getId()
{
    return m_nId;
}
std::string& CRecipe::getName()
{
    return m_strName;
}
SourceCode/Bond/BondEq/Recipe.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
#pragma once
class CRecipe
{
public:
    CRecipe();
    CRecipe(int id, const char* pszName);
    ~CRecipe();
public:
    int getId();
    std::string& getName();
private:
    int m_nId;
    std::string m_strName;
};
SourceCode/Bond/BondEq/stdafx.h
@@ -40,6 +40,7 @@
#include "..\RxWindows1.0\include\RxWindowsLib.h"
#include "..\BEQLibrarySDK\include\BEQLib.h"
#include "..\McLibrarySDK\include\McLib.h"
// æ•°æ®åº“模块
#include "..\DatabaseSDK\include\Database.h"
SourceCode/Bond/McLibrarySDK/McDemo/McDemo.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
// McDemo.h : PROJECT_NAME åº”用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
    #error "在包含此文件之前包含“stdafx.h”以生成 PCH æ–‡ä»¶"
#endif
#include "resource.h"        // ä¸»ç¬¦å·
#include "..\McLibrarySDK\include\McLib.h"
// CMcDemoApp:
// æœ‰å…³æ­¤ç±»çš„实现,请参阅 McDemo.cpp
//
class CMcDemoApp : public CWinApp
{
public:
    CMcDemoApp();
// é‡å†™
public:
    virtual BOOL InitInstance();
// å®žçް
    DECLARE_MESSAGE_MAP()
    virtual int ExitInstance();
};
extern CMcDemoApp theApp;
SourceCode/Bond/McLibrarySDK/McDemo/McDemo.rc
Binary files differ
SourceCode/Bond/McLibrarySDK/McDemo/McDemo.vcxproj.filters
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="源文件">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="头文件">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
    </Filter>
    <Filter Include="资源文件">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
    </Filter>
    <Filter Include="McLIbrarySDK">
      <UniqueIdentifier>{63fc133b-6db0-45cc-8346-1fd184790be0}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <Text Include="ReadMe.txt" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="McDemo.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="McDemoDlg.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="stdafx.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="targetver.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="Resource.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="..\McLibrarySDK\include\IMcChannel.h">
      <Filter>McLIbrarySDK</Filter>
    </ClInclude>
    <ClInclude Include="..\McLibrarySDK\include\McLib.h">
      <Filter>McLIbrarySDK</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="McDemo.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="McDemoDlg.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="stdafx.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="McDemo.rc">
      <Filter>资源文件</Filter>
    </ResourceCompile>
  </ItemGroup>
  <ItemGroup>
    <None Include="res\McDemo.rc2">
      <Filter>资源文件</Filter>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Image Include="res\McDemo.ico">
      <Filter>资源文件</Filter>
    </Image>
  </ItemGroup>
  <ItemGroup>
    <Manifest Include="res\application.exe.manifest" />
  </ItemGroup>
</Project>
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo.sln
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "McDemo", "McDemo\McDemo.vcxproj", "{09A3010B-32B2-45EF-AAE1-4311997C99CD}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x64 = Debug|x64
        Debug|x86 = Debug|x86
        Release|x64 = Release|x64
        Release|x86 = Release|x86
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {09A3010B-32B2-45EF-AAE1-4311997C99CD}.Debug|x64.ActiveCfg = Debug|x64
        {09A3010B-32B2-45EF-AAE1-4311997C99CD}.Debug|x64.Build.0 = Debug|x64
        {09A3010B-32B2-45EF-AAE1-4311997C99CD}.Debug|x86.ActiveCfg = Debug|Win32
        {09A3010B-32B2-45EF-AAE1-4311997C99CD}.Debug|x86.Build.0 = Debug|Win32
        {09A3010B-32B2-45EF-AAE1-4311997C99CD}.Release|x64.ActiveCfg = Release|x64
        {09A3010B-32B2-45EF-AAE1-4311997C99CD}.Release|x64.Build.0 = Release|x64
        {09A3010B-32B2-45EF-AAE1-4311997C99CD}.Release|x86.ActiveCfg = Release|Win32
        {09A3010B-32B2-45EF-AAE1-4311997C99CD}.Release|x86.Build.0 = Release|Win32
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {7D650640-3FDB-411F-A158-FA36512DEC3B}
    EndGlobalSection
EndGlobal
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/McDemo.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
// McDemo.h : PROJECT_NAME åº”用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
    #error "在包含此文件之前包含“stdafx.h”以生成 PCH æ–‡ä»¶"
#endif
#include "resource.h"        // ä¸»ç¬¦å·
#include "..\McLibrarySDK\include\McLib.h"
// CMcDemoApp:
// æœ‰å…³æ­¤ç±»çš„实现,请参阅 McDemo.cpp
//
class CMcDemoApp : public CWinApp
{
public:
    CMcDemoApp();
// é‡å†™
public:
    virtual BOOL InitInstance();
// å®žçް
    DECLARE_MESSAGE_MAP()
    virtual int ExitInstance();
};
extern CMcDemoApp theApp;
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/McDemo.rc
Binary files differ
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/McDemo.vcxproj.filters
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="源文件">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="头文件">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
    </Filter>
    <Filter Include="资源文件">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
    </Filter>
    <Filter Include="McLIbrarySDK">
      <UniqueIdentifier>{63fc133b-6db0-45cc-8346-1fd184790be0}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <Text Include="ReadMe.txt" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="McDemo.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="McDemoDlg.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="stdafx.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="targetver.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="Resource.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="..\McLibrarySDK\include\IMcChannel.h">
      <Filter>McLIbrarySDK</Filter>
    </ClInclude>
    <ClInclude Include="..\McLibrarySDK\include\McLib.h">
      <Filter>McLIbrarySDK</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="McDemo.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="McDemoDlg.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="stdafx.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="McDemo.rc">
      <Filter>资源文件</Filter>
    </ResourceCompile>
  </ItemGroup>
  <ItemGroup>
    <None Include="res\McDemo.rc2">
      <Filter>资源文件</Filter>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Image Include="res\McDemo.ico">
      <Filter>资源文件</Filter>
    </Image>
  </ItemGroup>
  <ItemGroup>
    <Manifest Include="res\application.exe.manifest" />
  </ItemGroup>
</Project>
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/mcdemo.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,121 @@
// McDemo.cpp : å®šä¹‰åº”用程序的类行为。
//
#include "stdafx.h"
#include "McDemo.h"
#include "McDemoDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMcDemoApp
BEGIN_MESSAGE_MAP(CMcDemoApp, CWinApp)
    ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CMcDemoApp æž„造
CMcDemoApp::CMcDemoApp()
{
    // æ”¯æŒé‡æ–°å¯åŠ¨ç®¡ç†å™¨
    m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
    // TODO: åœ¨æ­¤å¤„添加构造代码,
    // å°†æ‰€æœ‰é‡è¦çš„初始化放置在 InitInstance ä¸­
}
// å”¯ä¸€çš„一个 CMcDemoApp å¯¹è±¡
CMcDemoApp theApp;
// CMcDemoApp åˆå§‹åŒ–
BOOL CMcDemoApp::InitInstance()
{
    // å¦‚果一个运行在 Windows XP ä¸Šçš„应用程序清单指定要
    // ä½¿ç”¨ ComCtl32.dll ç‰ˆæœ¬ 6 æˆ–更高版本来启用可视化方式,
    //则需要 InitCommonControlsEx()。  å¦åˆ™ï¼Œå°†æ— æ³•创建窗口。
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // å°†å®ƒè®¾ç½®ä¸ºåŒ…括所有要在应用程序中使用的
    // å…¬å…±æŽ§ä»¶ç±»ã€‚
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);
    CWinApp::InitInstance();
    AfxEnableControlContainer();
    // åˆ›å»º shell ç®¡ç†å™¨ï¼Œä»¥é˜²å¯¹è¯æ¡†åŒ…含
    // ä»»ä½• shell æ ‘视图控件或 shell åˆ—表视图控件。
    CShellManager *pShellManager = new CShellManager;
    // æ¿€æ´»â€œWindows Native”视觉管理器,以便在 MFC æŽ§ä»¶ä¸­å¯ç”¨ä¸»é¢˜
    CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
    // æ ‡å‡†åˆå§‹åŒ–
    // å¦‚果未使用这些功能并希望减小
    // æœ€ç»ˆå¯æ‰§è¡Œæ–‡ä»¶çš„大小,则应移除下列
    // ä¸éœ€è¦çš„特定初始化例程
    // æ›´æ”¹ç”¨äºŽå­˜å‚¨è®¾ç½®çš„æ³¨å†Œè¡¨é¡¹
    // TODO: åº”适当修改该字符串,
    // ä¾‹å¦‚修改为公司或组织名
    SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
    // åˆå§‹åŒ–
    MCL_Initialize();
    CMcDemoDlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: åœ¨æ­¤æ”¾ç½®å¤„理何时用
        //  â€œç¡®å®šâ€æ¥å…³é—­å¯¹è¯æ¡†çš„代码
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: åœ¨æ­¤æ”¾ç½®å¤„理何时用
        //  â€œå–消”来关闭对话框的代码
    }
    else if (nResponse == -1)
    {
        TRACE(traceAppMsg, 0, "警告: å¯¹è¯æ¡†åˆ›å»ºå¤±è´¥ï¼Œåº”用程序将意外终止。\n");
        TRACE(traceAppMsg, 0, "警告: å¦‚果您在对话框上使用 MFC æŽ§ä»¶ï¼Œåˆ™æ— æ³• #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
    }
    // åˆ é™¤ä¸Šé¢åˆ›å»ºçš„ shell ç®¡ç†å™¨ã€‚
    if (pShellManager != NULL)
    {
        delete pShellManager;
    }
#ifndef _AFXDLL
    ControlBarCleanUp();
#endif
    // ç”±äºŽå¯¹è¯æ¡†å·²å…³é—­ï¼Œæ‰€ä»¥å°†è¿”回 FALSE ä»¥ä¾¿é€€å‡ºåº”用程序,
    //  è€Œä¸æ˜¯å¯åŠ¨åº”ç”¨ç¨‹åºçš„æ¶ˆæ¯æ³µã€‚
    return FALSE;
}
int CMcDemoApp::ExitInstance()
{
    // TODO: åœ¨æ­¤æ·»åŠ ä¸“ç”¨ä»£ç å’Œ/或调用基类
    MCL_Term();
    return CWinApp::ExitInstance();
}
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/mcdemo.vcxproj
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{09A3010B-32B2-45EF-AAE1-4311997C99CD}</ProjectGuid>
    <RootNamespace>McDemo</RootNamespace>
    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
    <Keyword>MFCProj</Keyword>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <CharacterSet>MultiByte</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>MultiByte</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
    </Link>
    <Midl>
      <MkTypLibCompatible>false</MkTypLibCompatible>
      <ValidateAllParameters>true</ValidateAllParameters>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </Midl>
    <ResourceCompile>
      <Culture>0x0804</Culture>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
    </Link>
    <Midl>
      <MkTypLibCompatible>false</MkTypLibCompatible>
      <ValidateAllParameters>true</ValidateAllParameters>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </Midl>
    <ResourceCompile>
      <Culture>0x0804</Culture>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
    <Midl>
      <MkTypLibCompatible>false</MkTypLibCompatible>
      <ValidateAllParameters>true</ValidateAllParameters>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </Midl>
    <ResourceCompile>
      <Culture>0x0804</Culture>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
    <Midl>
      <MkTypLibCompatible>false</MkTypLibCompatible>
      <ValidateAllParameters>true</ValidateAllParameters>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </Midl>
    <ResourceCompile>
      <Culture>0x0804</Culture>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemGroup>
    <Text Include="ReadMe.txt" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="..\McLibrarySDK\include\IMcChannel.h" />
    <ClInclude Include="..\McLibrarySDK\include\McLib.h" />
    <ClInclude Include="McDemo.h" />
    <ClInclude Include="McDemoDlg.h" />
    <ClInclude Include="Resource.h" />
    <ClInclude Include="stdafx.h" />
    <ClInclude Include="targetver.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="McDemo.cpp" />
    <ClCompile Include="McDemoDlg.cpp" />
    <ClCompile Include="stdafx.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="McDemo.rc" />
  </ItemGroup>
  <ItemGroup>
    <None Include="res\McDemo.rc2" />
  </ItemGroup>
  <ItemGroup>
    <Image Include="res\McDemo.ico" />
  </ItemGroup>
  <ItemGroup>
    <Manifest Include="res\application.exe.manifest" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
  <ProjectExtensions>
    <VisualStudio>
      <UserProperties RESOURCE_FILE="McDemo.rc" />
    </VisualStudio>
  </ProjectExtensions>
</Project>
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/mcdemodlg.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,769 @@
// McDemoDlg.cpp : å®žçŽ°æ–‡ä»¶
//
#include "stdafx.h"
#include "McDemo.h"
#include "McDemoDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define MAX_MESSAGE_LENGTH        1024
#define CHANNEL_NAME            _T("Test1")
// ç”¨äºŽåº”用程序“关于”菜单项的 CAboutDlg å¯¹è¯æ¡†
class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_ABOUTBOX };
#endif
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV æ”¯æŒ
// å®žçް
protected:
    DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CMcDemoDlg å¯¹è¯æ¡†
CMcDemoDlg::CMcDemoDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(IDD_MCDEMO_DIALOG, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_pChannel = NULL;
}
void CMcDemoDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CMcDemoDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BUTTON_CREATE, &CMcDemoDlg::OnBnClickedButtonCreate)
    ON_BN_CLICKED(IDC_BUTTON_SEND, &CMcDemoDlg::OnBnClickedButtonSend)
    ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CMcDemoDlg::OnBnClickedButtonClose)
    ON_BN_CLICKED(IDC_BUTTON_DESTROY, &CMcDemoDlg::OnBnClickedButtonDestroy)
    ON_BN_CLICKED(IDC_BUTTON_READ, &CMcDemoDlg::OnBnClickedButtonRead)
    ON_BN_CLICKED(IDC_BUTTON_RAWDATA, &CMcDemoDlg::OnBnClickedButtonRawdata)
    ON_BN_CLICKED(IDC_BUTTON_WRITE, &CMcDemoDlg::OnBnClickedButtonWrite)
    ON_BN_CLICKED(IDC_BUTTON_READ_BIT, &CMcDemoDlg::OnBnClickedButtonReadBit)
    ON_BN_CLICKED(IDC_CHECK_WRITE_BIT_VALUE, &CMcDemoDlg::OnBnClickedCheckWriteBitValue)
    ON_BN_CLICKED(IDC_BUTTON_WRITE_BIT, &CMcDemoDlg::OnBnClickedButtonWriteBit)
    ON_BN_CLICKED(IDC_BUTTON_READ_DWORD, &CMcDemoDlg::OnBnClickedButtonReadDword)
    ON_BN_CLICKED(IDC_BUTTON_WRITE_DWORD, &CMcDemoDlg::OnBnClickedButtonWriteDword)
END_MESSAGE_MAP()
// CMcDemoDlg æ¶ˆæ¯å¤„理程序
BOOL CMcDemoDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // å°†â€œå…³äºŽ...”菜单项添加到系统菜单中。
    // IDM_ABOUTBOX å¿…须在系统命令范围内。
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }
    // è®¾ç½®æ­¤å¯¹è¯æ¡†çš„图标。  å½“应用程序主窗口不是对话框时,框架将自动
    //  æ‰§è¡Œæ­¤æ“ä½œ
    SetIcon(m_hIcon, TRUE);            // è®¾ç½®å¤§å›¾æ ‡
    SetIcon(m_hIcon, FALSE);        // è®¾ç½®å°å›¾æ ‡
    // TODO: åœ¨æ­¤æ·»åŠ é¢å¤–çš„åˆå§‹åŒ–ä»£ç 
    CIPAddressCtrl* pIpAddressCtrl = (CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS_SERVER);
    pIpAddressCtrl->SetAddress(192, 168, 3, 39);
    // pIpAddressCtrl->SetAddress(127, 0, 0, 1);
    SetDlgItemInt(IDC_EDIT_SERVER_PORT, 9300);
    ((CButton*)GetDlgItem(IDC_RADIO2))->SetCheck(1);
    //CString strText = _T("50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 01 00");
    //SetDlgItemText(IDC_EDIT_RAW, strText);
    // è½¯å…ƒä»¶
    std::vector<std::string> softComponents;
    int softComponentsSize = MCL_GetSoftComponents(softComponents);
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM);
    CComboBox* pComboBox2 = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    for (auto item : softComponents) {
        pComboBox->InsertString(pComboBox->GetCount(), item.c_str());
        pComboBox2->InsertString(pComboBox2->GetCount(), item.c_str());
    }
    if (softComponentsSize > 0) {
        pComboBox->SetCurSel(0);
        pComboBox2->SetCurSel(0);
    }
    // å‘½ä»¤
    std::vector<std::string> cmds;
    int cmdsSize = MCL_GetCmds(cmds);
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_CMD);
    for (auto item : cmds) {
        pComboBox->InsertString(pComboBox->GetCount(), item.c_str());
    }
    if (cmdsSize > 0) {
        pComboBox->SetCurSel(0);
    }
    // å­å‘½ä»¤
    std::vector<std::string> subCmds;
    int subCmdsSize = MCL_GetSubCmds(subCmds);
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SUBCMD);
    for (auto item : subCmds) {
        pComboBox->InsertString(pComboBox->GetCount(), item.c_str());
    }
    if (cmdsSize > 0) {
        pComboBox->SetCurSel(0);
    }
    SetDlgItemInt(IDC_EDIT_HEAD_ADDR, 100);
    SetDlgItemInt(IDC_EDIT_READ_COUNT, 1);
    UpdateUISecsion1();
    UpdateUISecsion2();
    UpdateUISecsion3();
    return TRUE;  // é™¤éžå°†ç„¦ç‚¹è®¾ç½®åˆ°æŽ§ä»¶ï¼Œå¦åˆ™è¿”回 TRUE
}
void CMcDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}
// å¦‚果向对话框添加最小化按钮,则需要下面的代码
//  æ¥ç»˜åˆ¶è¯¥å›¾æ ‡ã€‚  å¯¹äºŽä½¿ç”¨æ–‡æ¡£/视图模型的 MFC åº”用程序,
//  è¿™å°†ç”±æ¡†æž¶è‡ªåŠ¨å®Œæˆã€‚
void CMcDemoDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // ç”¨äºŽç»˜åˆ¶çš„设备上下文
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
        // ä½¿å›¾æ ‡åœ¨å·¥ä½œåŒºçŸ©å½¢ä¸­å±…中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        // ç»˜åˆ¶å›¾æ ‡
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMcDemoDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}
void CMcDemoDlg::OnBnClickedButtonCreate()
{
    m_mcChannellistener.funOnConnected = [&](IMcChannel* pChannel, int nErrorCode) -> void {
        CString strText;
        strText.Format(_T(">> funOnConnected, %s连接结果<code =  %d>\r\n"), pChannel->getName().c_str(), nErrorCode);
        AppendLog(strText);
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    };
    m_mcChannellistener.funOnClose = [&](IMcChannel* pChannel) -> void {
        AppendLog(">> funOnClose, %s已关闭\r\n", pChannel->getName().c_str());
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    };
    m_mcChannellistener.funOnClosing = [&](IMcChannel* pChannel) -> void {
        AppendLog(">> funOnClosing, æ­£åœ¨å…³é—­ %s\r\n", pChannel->getName().c_str());
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    };
    m_mcChannellistener.funOnRead = [&](IMcChannel* pChannel, char* pData, unsigned int nDataSize) -> void {
        CString strText;
        DataToHexString(pData, nDataSize, strText);
        AppendLog(">> funOnRead:[%s]\r\n", strText);
    };
    m_mcChannellistener.funOnWrite = [&](IMcChannel* pChannel) -> void {
        AppendLog(">> funOnWrite\r\n");
    };
    CIPAddressCtrl* pIpAddressCtrl = (CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS_SERVER);
    BYTE b1, b2, b3, b4;
    pIpAddressCtrl->GetAddress(b1, b2, b3, b4);
    CString strIP;
    strIP.Format("%d.%d.%d.%d", b1, b2, b3, b4);
    UINT port = GetDlgItemInt(IDC_EDIT_SERVER_PORT);
    m_pChannel = NULL;
    if (0 == MCL_CreateChannel(m_pChannel, CHANNEL_NAME, (LPTSTR)(LPCTSTR)strIP, port, 0) && m_pChannel != NULL) {
        m_pChannel->setChannelListener(&m_mcChannellistener);
        CString strText;
        strText.Format(_T(">> åˆ›å»ºé€šé“(%s)成功\r\n"), m_pChannel->getName().c_str()),
        AppendLog(strText);
        //m_pChannel->connect();
    }
    else if(m_pChannel != NULL){
        m_pChannel->setChannelListener(&m_mcChannellistener);
        AppendLog(">> æ‰¾åˆ°çŽ°æœ‰é€šé“(%s).\r\n", m_pChannel->getName().c_str());
    }
    UpdateUISecsion1();
    UpdateUISecsion2();
    UpdateUISecsion3();
}
void CMcDemoDlg::OnBnClickedButtonSend()
{
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        CString strText;
        GetDlgItemText(IDC_EDIT_RAW, strText);
        CButton* pButton = (CButton*)GetDlgItem(IDC_RADIO2);
        if (pButton->GetCheck() == 1) {
            char szBuffer[1024];
            int nLen = HexStringToData(strText, szBuffer, 1024);
            if (nLen > 0) {
                m_pChannel->sendRawData(szBuffer, nLen);
            }
        }
        else {
            m_pChannel->sendRawData((LPTSTR)(LPCTSTR)strText, strText.GetLength());
        }
    }
}
void CMcDemoDlg::OnBnClickedButtonClose()
{
    if (m_pChannel != NULL) {
        if (m_pChannel->isConnected()) {
            m_pChannel->close();
        }
        else {
            AppendLog(_T(">> æ­£åœ¨è¿žæŽ¥ %s, %s:%d\r\n"), m_pChannel->getName().c_str(), m_pChannel->getIp().c_str(), m_pChannel->getServerPort());
            m_pChannel->connect();
        }
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    }
    /*
    IMcChannel* pChannel = NULL;
    if (0 == MCL_GetChannel(pChannel, CHANNEL_NAME) && pChannel != NULL) {
        pChannel->close();
    }*/
}
void CMcDemoDlg::OnBnClickedButtonDestroy()
{
    if (m_pChannel != NULL) {
        MCL_DestroyChannel(m_pChannel->getName().c_str());
        m_pChannel = NULL;
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    }
}
void CMcDemoDlg::AppendLog(CString strText)
{
    CEdit *pEdit = (CEdit *)GetDlgItem(IDC_EDIT_LOG);
    if (pEdit == NULL) {
        return;
    }
    // è¶…过指定行则删除最前面一行
    int nLine = pEdit->GetLineCount();
    if (nLine > 100) {
        CString strOldText;
        pEdit->GetWindowText(strOldText);
        int nIndex = strOldText.Find(_T("\r\n"), 0);
        for (int i = 0; i < 1111; i++) {
            nIndex = strOldText.Find(_T("\r\n"), nIndex + 2);
        }
        pEdit->SetSel(0, nIndex);
        pEdit->ReplaceSel(_T(""));
    }
    // è¿½åŠ åˆ°æœ€åŽ
    int length = pEdit->GetWindowTextLength();
    pEdit->SetSel(length, length);
    pEdit->ReplaceSel(strText);
    pEdit->PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
}
void CMcDemoDlg::AppendLog(char* szMessage, ...)
{
    if (!::IsWindow(GetSafeHwnd())) {
        return;
    }
    CEdit *pEdit = (CEdit *)GetDlgItem(IDC_EDIT_LOG);
    if (pEdit == NULL) {
        return;
    }
    char szFormatMessage[MAX_MESSAGE_LENGTH];
    va_list ap;
    va_start(ap, szMessage);
    _vsnprintf_s(szFormatMessage, MAX_MESSAGE_LENGTH, szMessage, ap);
    va_end(ap);
    // è¶…过指定行则删除最前面一行
    int nLine = pEdit->GetLineCount();
    if (nLine > 100) {
        CString strOldText;
        pEdit->GetWindowText(strOldText);
        int nIndex = strOldText.Find(_T("\r\n"), 0);
        for (int i = 0; i < 1111; i++) {
            nIndex = strOldText.Find(_T("\r\n"), nIndex + 2);
        }
        pEdit->SetSel(0, nIndex);
        pEdit->ReplaceSel(_T(""));
    }
    // è¿½åŠ åˆ°æœ€åŽ
    int length = pEdit->GetWindowTextLength();
    pEdit->SetSel(length, length);
    pEdit->ReplaceSel(szFormatMessage);
    pEdit->PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
}
void CMcDemoDlg::DataToHexString(const char* pData, const int size, CString& strOut)
{
    strOut.Empty();
    for (int i = 0; i < size; i++) {
        if (i < size - 1) {
            strOut.AppendFormat(_T("%02X "), (BYTE)pData[i]);
        }
        else {
            strOut.AppendFormat(_T("%02X"), (BYTE)pData[i]);
        }
    }
}
int CMcDemoDlg::HexStringToData(CString& strHex, char* pszBuffer, const int nBufferSize)
{
    int index = 0;
    int nLength = strHex.GetLength();
    CString strItem;
    for (int i = 0; i < nLength; i++) {
        if (strHex.GetAt(i) == ' ') {
            if (!strItem.IsEmpty()) {
                BYTE b = (BYTE)strtol(strItem, NULL, 16);
                pszBuffer[index] = b;
                index++;
                if (index >= nBufferSize) {
                    break;
                }
                strItem.Empty();
            }
            continue;
        }
        strItem.AppendChar(strHex.GetAt(i));
        if (strItem.GetLength() == 2) {
            BYTE b = (BYTE)strtol(strItem, NULL, 16);
            pszBuffer[index] = b;
            index++;
            if (index >= nBufferSize) {
                break;
            }
            strItem.Empty();
        }
    }
    return index;
}
void CMcDemoDlg::UpdateUISecsion1()
{
    if (!::IsWindow(GetSafeHwnd())) {
        return;
    }
    GetDlgItem(IDC_BUTTON_CREATE)->EnableWindow(m_pChannel == NULL);
    GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(m_pChannel != NULL);
    SetDlgItemText(IDC_BUTTON_CLOSE, (m_pChannel != NULL && m_pChannel->isConnected()) ? _T("Close") : _T("Open"));
    GetDlgItem(IDC_BUTTON_DESTROY)->EnableWindow(m_pChannel != NULL);
}
void CMcDemoDlg::UpdateUISecsion2()
{
    if (!::IsWindow(GetSafeHwnd())) {
        return;
    }
    BOOL bEnable = (m_pChannel != NULL && m_pChannel->isConnected());
    GetDlgItem(IDC_RADIO1)->EnableWindow(bEnable);
    GetDlgItem(IDC_RADIO2)->EnableWindow(bEnable);
    GetDlgItem(IDC_EDIT_RAW)->EnableWindow(bEnable);
    GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(bEnable);
    GetDlgItem(IDC_COMBO_CMD)->EnableWindow(bEnable);
    GetDlgItem(IDC_COMBO_SUBCMD)->EnableWindow(bEnable);
    GetDlgItem(IDC_COMBO_SOFTITEM)->EnableWindow(bEnable);
    GetDlgItem(IDC_EDIT_HEAD_ADDR)->EnableWindow(bEnable);
    GetDlgItem(IDC_EDIT_READ_COUNT)->EnableWindow(bEnable);
    GetDlgItem(IDC_BUTTON_RAWDATA)->EnableWindow(bEnable);
}
void CMcDemoDlg::UpdateUISecsion3()
{
    if (!::IsWindow(GetSafeHwnd())) {
        return;
    }
    GetDlgItem(IDC_COMBO_SOFTITEM2)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_EDIT_HEAD_ADDR2)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_READ_DWORD)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_READ)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_READ_BIT)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_EDIT_WRITE_VALUE)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_CHECK_WRITE_BIT_VALUE)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_WRITE_DWORD)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_WRITE)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_WRITE_BIT)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
}
void CMcDemoDlg::OnBnClickedButtonRawdata()
{
    /*
    char szBuffer[] = {0x50, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x01,
    0x04, 0x00, 0x00, 0x64, 0x00, 0x00, 0xa8, 0x01, 0x00};
    // è½¯å…ƒç±»åž‹
    static char szSoftItem[] = {0x90, 0xa8, 0x9c, 0x9d, 0xb0};
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM);
    szBuffer[18] = szSoftItem[pComboBox->GetCurSel()];
    // é¦–地址
    int nHeadAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR);
    szBuffer[15] = nHeadAddr & 0xff;
    szBuffer[16] = (nHeadAddr & 0xff00) >> 8;
    szBuffer[17] = (nHeadAddr & 0xff0000) >> 16;
    // æ•°é‡
    int nReadCount = GetDlgItemInt(IDC_EDIT_READ_COUNT);
    szBuffer[19] = nReadCount & 0xff;
    szBuffer[20] = (nReadCount & 0xff00) >> 8;
    // å‘½ä»¤
    int nCmd = ((CComboBox*)GetDlgItem(IDC_COMBO_CMD))->GetCurSel();
    if (nCmd == 0) {
    // æˆæ‰¹è¯»
    szBuffer[11] = 0x01;
    szBuffer[12] = 0x04;
    }
    else if (nCmd == 1) {
    // æˆæ‰¹å†™
    szBuffer[11] = 0x01;
    szBuffer[12] = 0x14;
    }
    else if (nCmd == 2) {
    // éšæœºè¯»
    szBuffer[11] = 0x03;
    szBuffer[12] = 0x04;
    }
    else if (nCmd == 3) {
    // æµ‹è¯•(随机写)
    szBuffer[11] = 0x02;
    szBuffer[12] = 0x14;
    }
    else if (nCmd == 4) {
    // ç›‘视登录数据
    szBuffer[11] = 0x01;
    szBuffer[12] = 0x08;
    }
    else if (nCmd == 5) {
    // ç›‘视
    szBuffer[11] = 0x02;
    szBuffer[12] = 0x08;
    }
    // å­å‘½ä»¤
    int nSubCmd = ((CComboBox*)GetDlgItem(IDC_COMBO_SUBCMD))->GetCurSel();
    if (nSubCmd == 0) {
    // æŒ‰å­—
    szBuffer[13] = 0x00;
    szBuffer[14] = 0x00;
    }
    else if (nSubCmd == 1) {
    // æŒ‰ä½
    szBuffer[13] = 0x00;
    szBuffer[14] = 0x01;
    }
    CString strRawData;
    DataToHexString(szBuffer, sizeof(szBuffer), strRawData);
    SetDlgItemText(IDC_EDIT_RAW, strRawData);
    */
    // æ–°æ–¹æ³•
    CComboBox* pComboBox = NULL;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_CMD);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strCmd = (LPTSTR)(LPCTSTR)strLbText;
    MC::CMD cmd;
    MCL_GetCmd(strCmd, cmd);
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SUBCMD);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSubCmd = (LPTSTR)(LPCTSTR)strLbText;
    MC::SUBCMD subCmd;
    MCL_GetSubCmd(strSubCmd, subCmd);
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nFirstAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR);
    int nOperateCount = GetDlgItemInt(IDC_EDIT_READ_COUNT);
    char szRawData[1024];
    char szAttach[4] = { 0x10, 0x11, 0x12, 0x13 };
    int nDataSize = MCL_GetRawData(cmd, subCmd, softComponent, nFirstAddr, nOperateCount, NULL, 0, szRawData, sizeof(szRawData));
    CString strRawData2;
    DataToHexString(szRawData, nDataSize, strRawData2);
    SetDlgItemText(IDC_EDIT_RAW, strRawData2);
    // AfxMessageBox(strRawData2);
}
void CMcDemoDlg::OnBnClickedButtonRead()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnRead = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnRead:[%d]\r\n", value);
            CString strText;
            strText.Format(_T("Read Word(%d)"), value);
            SetDlgItemText(IDC_BUTTON_READ, strText);
        };
        m_pChannel->readWord(softComponent, nAddr, funOnRead);
    }
}
void CMcDemoDlg::OnBnClickedButtonReadBit()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnRead = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnRead:[%s]\r\n", value != 0 ? "ON" : "OFF");
            CString strText;
            strText.Format(_T("Read Bit(%s)"), value != 0 ? "ON" : "OFF");
            SetDlgItemText(IDC_BUTTON_READ_BIT, strText);
        };
        m_pChannel->readBit(softComponent, nAddr, funOnRead);
    }
}
void CMcDemoDlg::OnBnClickedButtonWrite()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    int nValue = GetDlgItemInt(IDC_EDIT_WRITE_VALUE);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnWrite = [&](IMcChannel* pChannel, int addr, DWORD value) -> void {
            AppendLog(">> funOnWrite:[%d]\r\n", value);
        };
        m_pChannel->writeWord(softComponent, nAddr, nValue, funOnWrite);
    }
}
void CMcDemoDlg::OnBnClickedButtonReadDword()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnRead = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnRead:[%d]\r\n", value);
            CString strText;
            strText.Format(_T("Read DWORD(%d)"), value);
            SetDlgItemText(IDC_BUTTON_READ_DWORD, strText);
        };
        m_pChannel->readDWord(softComponent, nAddr, funOnRead);
    }
}
void CMcDemoDlg::OnBnClickedButtonWriteDword()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    int nValue = GetDlgItemInt(IDC_EDIT_WRITE_VALUE);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnWrite = [&](IMcChannel* pChannel, int addr, DWORD value) -> void {
            AppendLog(">> funOnWrite:[%d]\r\n", value);
        };
        m_pChannel->writeDWord(softComponent, nAddr, nValue, funOnWrite);
    }
}
void CMcDemoDlg::OnBnClickedButtonWriteBit()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_WRITE_BIT_VALUE);
    BOOL bValue = pButton->GetCheck();;
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnWrite = [&](IMcChannel* pChannel, int addr, DWORD value) -> void {
            AppendLog(">> funOnWrite:[%s]\r\n", value != 0 ? "ON" : "OFF");
        };
        m_pChannel->writeBit(softComponent, nAddr, bValue, funOnWrite);
    }
}
void CMcDemoDlg::OnBnClickedCheckWriteBitValue()
{
    CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_WRITE_BIT_VALUE);
    pButton->SetWindowText(pButton->GetCheck() ? "ON" : "OFF");
}
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/mcdemodlg.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
// McDemoDlg.h : å¤´æ–‡ä»¶
//
#pragma once
// CMcDemoDlg å¯¹è¯æ¡†
class CMcDemoDlg : public CDialogEx
{
// æž„造
public:
    CMcDemoDlg(CWnd* pParent = NULL);    // æ ‡å‡†æž„造函数
    void AppendLog(CString strText);
    void AppendLog(char* szMessage, ...);
    void DataToHexString(const char* pData, const int size, CString& strOut);
    int HexStringToData(CString& strHex, char* pszBuffer, const int nBufferSize);
    void UpdateUISecsion1();
    void UpdateUISecsion2();
    void UpdateUISecsion3();
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_MCDEMO_DIALOG };
#endif
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV æ”¯æŒ
// å®žçް
protected:
    HICON m_hIcon;
    McChannelListener m_mcChannellistener;
    IMcChannel* m_pChannel;
    // ç”Ÿæˆçš„æ¶ˆæ¯æ˜ å°„函数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnBnClickedButtonCreate();
    afx_msg void OnBnClickedButtonSend();
    afx_msg void OnBnClickedButtonClose();
    afx_msg void OnBnClickedButtonDestroy();
    afx_msg void OnBnClickedButtonRead();
    afx_msg void OnBnClickedButtonRawdata();
    afx_msg void OnBnClickedButtonWrite();
    afx_msg void OnBnClickedButtonReadBit();
    afx_msg void OnBnClickedCheckWriteBitValue();
    afx_msg void OnBnClickedButtonWriteBit();
    afx_msg void OnBnClickedButtonReadDword();
    afx_msg void OnBnClickedButtonWriteDword();
};
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/readme.txt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
================================================================================
    MICROSOFT åŸºç¡€ç±»åº“ : McDemo é¡¹ç›®æ¦‚è¿°
===============================================================================
应用程序向导已为您创建了此 McDemo åº”用程序。此应用程序不仅演示 Microsoft åŸºç¡€ç±»çš„基本使用方法,还可作为您编写应用程序的起点。
本文件概要介绍组成 McDemo åº”用程序的每个文件的内容。
McDemo.vcxproj
    è¿™æ˜¯ä½¿ç”¨åº”用程序向导生成的 VC++ é¡¹ç›®çš„主项目文件,其中包含生成该文件的 Visual C++ çš„版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
McDemo.vcxproj.filters
    è¿™æ˜¯ä½¿ç”¨â€œåº”用程序向导”生成的 VC++ é¡¹ç›®ç­›é€‰å™¨æ–‡ä»¶ã€‚它包含有关项目文件与筛选器之间的关联信息。在 IDE ä¸­ï¼Œé€šè¿‡è¿™ç§å…³è”,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
McDemo.h
    è¿™æ˜¯åº”用程序的主头文件。
    å…¶ä¸­åŒ…括其他项目特定的标头(包括 Resource.h),并声明 CMcDemoApp åº”用程序类。
McDemo.cpp
    è¿™æ˜¯åŒ…含应用程序类 CMcDemoApp çš„主应用程序源文件。
McDemo.rc
    è¿™æ˜¯ç¨‹åºä½¿ç”¨çš„æ‰€æœ‰ Microsoft Windows èµ„源的列表。它包括 RES å­ç›®å½•中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ ä¸­è¿›è¡Œç¼–辑。项目资源包含在 2052 ä¸­ã€‚
res\McDemo.ico
    è¿™æ˜¯ç”¨ä½œåº”用程序图标的图标文件。此图标包括在主资源文件 McDemo.rc ä¸­ã€‚
res\McDemo.rc2
    æ­¤æ–‡ä»¶åŒ…含不在 Microsoft Visual C++ ä¸­è¿›è¡Œç¼–辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
/////////////////////////////////////////////////////////////////////////////
应用程序向导创建一个对话框类:
McDemoDlg.h、McDemoDlg.cpp - å¯¹è¯æ¡†
    è¿™äº›æ–‡ä»¶åŒ…含 CMcDemoDlg ç±»ã€‚此类定义应用程序的主对话框的行为。对话框模板包含在 McDemo.rc ä¸­ï¼Œè¯¥æ–‡ä»¶å¯ä»¥åœ¨ Microsoft Visual C++ ä¸­ç¼–辑。
/////////////////////////////////////////////////////////////////////////////
其他功能:
ActiveX æŽ§ä»¶
    è¯¥åº”用程序包含对使用 ActiveX æŽ§ä»¶çš„æ”¯æŒã€‚
/////////////////////////////////////////////////////////////////////////////
其他标准文件:
StdAfx.h, StdAfx.cpp
    è¿™äº›æ–‡ä»¶ç”¨äºŽç”Ÿæˆåä¸º McDemo.pch çš„预编译头 (PCH) æ–‡ä»¶å’Œåä¸º StdAfx.obj çš„预编译类型文件。
Resource.h
    è¿™æ˜¯æ ‡å‡†å¤´æ–‡ä»¶ï¼Œå¯ç”¨äºŽå®šä¹‰æ–°çš„资源 ID。Microsoft Visual C++ å°†è¯»å–并更新此文件。
McDemo.manifest
    Windows XP ä½¿ç”¨åº”用程序清单文件来描述特定版本的并行程序集的应用程序依赖项。加载程序使用这些信息来从程序集缓存中加载相应的程序集,并保护其不被应用程序访问。应用程序清单可能会包含在内,以作为与应用程序可执行文件安装在同一文件夹中的外部 .manifest æ–‡ä»¶è¿›è¡Œé‡æ–°åˆ†å‘,它还可能以资源的形式包含在可执行文件中。
/////////////////////////////////////////////////////////////////////////////
其他注释:
应用程序向导使用“TODO:”来指示应添加或自定义的源代码部分。
如果应用程序使用共享 DLL ä¸­çš„ MFC,您将需要重新分发 MFC DLL。如果应用程序所使用的语言与操作系统的区域设置不同,则还需要重新分发相应的本地化资源 mfc110XXX.DLL。
有关上述话题的更多信息,请参见 MSDN æ–‡æ¡£ä¸­æœ‰å…³é‡æ–°åˆ†å‘ Visual C++ åº”用程序的部分。
/////////////////////////////////////////////////////////////////////////////
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/res/McDemo.ico
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/res/McDemo.rc2
Binary files differ
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/res/application.exe.manifest
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity
         name="XP style manifest"
         processorArchitecture="amd64"
         version="1.0.0.0"
         type="win32"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity
                type="win32"
                name="Microsoft.Windows.Common-Controls"
                version="6.0.0.0"
                processorArchitecture="amd64"
                publicKeyToken="6595b64144ccf1df"
                language="*"
            />
        </dependentAssembly>
    </dependency>
</assembly>
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/resource.h
Binary files differ
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/stdafx.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
// stdafx.cpp : åªåŒ…括标准包含文件的源文件
// McDemo.pch å°†ä½œä¸ºé¢„编译头
// stdafx.obj å°†åŒ…含预编译类型信息
#include "stdafx.h"
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/stdafx.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
// stdafx.h : æ ‡å‡†ç³»ç»ŸåŒ…含文件的包含文件,
// æˆ–是经常使用但不常更改的
// ç‰¹å®šäºŽé¡¹ç›®çš„包含文件
#pragma once
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN            // ä»Ž Windows å¤´ä¸­æŽ’除极少使用的资料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // æŸäº› CString æž„造函数将是显式的
// å…³é—­ MFC å¯¹æŸäº›å¸¸è§ä½†ç»å¸¸å¯æ”¾å¿ƒå¿½ç•¥çš„警告消息的隐藏
#define _AFX_ALL_WARNINGS
#include <afxwin.h>         // MFC æ ¸å¿ƒç»„件和标准组件
#include <afxext.h>         // MFC æ‰©å±•
#include <afxdisp.h>        // MFC è‡ªåŠ¨åŒ–ç±»
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>           // MFC å¯¹ Internet Explorer 4 å…¬å…±æŽ§ä»¶çš„æ”¯æŒ
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>             // MFC å¯¹ Windows å…¬å…±æŽ§ä»¶çš„æ”¯æŒ
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h>     // åŠŸèƒ½åŒºå’ŒæŽ§ä»¶æ¡çš„ MFC æ”¯æŒ
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
SourceCode/Bond/McLibrarySDK/McDemo/McDemo/McDemo/targetver.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
#pragma once
// åŒ…括 SDKDDKVer.h å°†å®šä¹‰å¯ç”¨çš„æœ€é«˜ç‰ˆæœ¬çš„ Windows å¹³å°ã€‚
// å¦‚果要为以前的 Windows å¹³å°ç”Ÿæˆåº”用程序,请包括 WinSDKVer.h,并将
// å°† _WIN32_WINNT å®è®¾ç½®ä¸ºè¦æ”¯æŒçš„平台,然后再包括 SDKDDKVer.h。
#include <SDKDDKVer.h>
SourceCode/Bond/McLibrarySDK/McDemo/McDemoDlg.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,794 @@
// McDemoDlg.cpp : å®žçŽ°æ–‡ä»¶
//
#include "stdafx.h"
#include "McDemo.h"
#include "McDemoDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define MAX_MESSAGE_LENGTH        1024
#define CHANNEL_NAME            _T("Test1")
// ç”¨äºŽåº”用程序“关于”菜单项的 CAboutDlg å¯¹è¯æ¡†
class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_ABOUTBOX };
#endif
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV æ”¯æŒ
// å®žçް
protected:
    DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CMcDemoDlg å¯¹è¯æ¡†
CMcDemoDlg::CMcDemoDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(IDD_MCDEMO_DIALOG, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_pChannel = NULL;
}
void CMcDemoDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CMcDemoDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BUTTON_CREATE, &CMcDemoDlg::OnBnClickedButtonCreate)
    ON_BN_CLICKED(IDC_BUTTON_SEND, &CMcDemoDlg::OnBnClickedButtonSend)
    ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CMcDemoDlg::OnBnClickedButtonClose)
    ON_BN_CLICKED(IDC_BUTTON_DESTROY, &CMcDemoDlg::OnBnClickedButtonDestroy)
    ON_BN_CLICKED(IDC_BUTTON_READ, &CMcDemoDlg::OnBnClickedButtonRead)
    ON_BN_CLICKED(IDC_BUTTON_RAWDATA, &CMcDemoDlg::OnBnClickedButtonRawdata)
    ON_BN_CLICKED(IDC_BUTTON_WRITE, &CMcDemoDlg::OnBnClickedButtonWrite)
    ON_BN_CLICKED(IDC_BUTTON_READ_BIT, &CMcDemoDlg::OnBnClickedButtonReadBit)
    ON_BN_CLICKED(IDC_CHECK_WRITE_BIT_VALUE, &CMcDemoDlg::OnBnClickedCheckWriteBitValue)
    ON_BN_CLICKED(IDC_BUTTON_WRITE_BIT, &CMcDemoDlg::OnBnClickedButtonWriteBit)
    ON_BN_CLICKED(IDC_BUTTON_READ_DWORD, &CMcDemoDlg::OnBnClickedButtonReadDword)
    ON_BN_CLICKED(IDC_BUTTON_WRITE_DWORD, &CMcDemoDlg::OnBnClickedButtonWriteDword)
    ON_WM_TIMER()
END_MESSAGE_MAP()
// CMcDemoDlg æ¶ˆæ¯å¤„理程序
BOOL CMcDemoDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // å°†â€œå…³äºŽ...”菜单项添加到系统菜单中。
    // IDM_ABOUTBOX å¿…须在系统命令范围内。
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }
    // è®¾ç½®æ­¤å¯¹è¯æ¡†çš„图标。  å½“应用程序主窗口不是对话框时,框架将自动
    //  æ‰§è¡Œæ­¤æ“ä½œ
    SetIcon(m_hIcon, TRUE);            // è®¾ç½®å¤§å›¾æ ‡
    SetIcon(m_hIcon, FALSE);        // è®¾ç½®å°å›¾æ ‡
    // TODO: åœ¨æ­¤æ·»åŠ é¢å¤–çš„åˆå§‹åŒ–ä»£ç 
    CIPAddressCtrl* pIpAddressCtrl = (CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS_SERVER);
    pIpAddressCtrl->SetAddress(192, 168, 90, 17);
    // pIpAddressCtrl->SetAddress(127, 0, 0, 1);
    SetDlgItemInt(IDC_EDIT_SERVER_PORT, 8080);
    ((CButton*)GetDlgItem(IDC_RADIO2))->SetCheck(1);
    //CString strText = _T("50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 01 00");
    //SetDlgItemText(IDC_EDIT_RAW, strText);
    // è½¯å…ƒä»¶
    std::vector<std::string> softComponents;
    int softComponentsSize = MCL_GetSoftComponents(softComponents);
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM);
    CComboBox* pComboBox2 = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    for (auto item : softComponents) {
        pComboBox->InsertString(pComboBox->GetCount(), item.c_str());
        pComboBox2->InsertString(pComboBox2->GetCount(), item.c_str());
    }
    if (softComponentsSize > 0) {
        pComboBox->SetCurSel(0);
        pComboBox2->SetCurSel(0);
    }
    // å‘½ä»¤
    std::vector<std::string> cmds;
    int cmdsSize = MCL_GetCmds(cmds);
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_CMD);
    for (auto item : cmds) {
        pComboBox->InsertString(pComboBox->GetCount(), item.c_str());
    }
    if (cmdsSize > 0) {
        pComboBox->SetCurSel(0);
    }
    // å­å‘½ä»¤
    std::vector<std::string> subCmds;
    int subCmdsSize = MCL_GetSubCmds(subCmds);
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SUBCMD);
    for (auto item : subCmds) {
        pComboBox->InsertString(pComboBox->GetCount(), item.c_str());
    }
    if (cmdsSize > 0) {
        pComboBox->SetCurSel(0);
    }
    SetDlgItemInt(IDC_EDIT_HEAD_ADDR, 100);
    SetDlgItemInt(IDC_EDIT_READ_COUNT, 1);
    UpdateUISecsion1();
    UpdateUISecsion2();
    UpdateUISecsion3();
    return TRUE;  // é™¤éžå°†ç„¦ç‚¹è®¾ç½®åˆ°æŽ§ä»¶ï¼Œå¦åˆ™è¿”回 TRUE
}
void CMcDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}
// å¦‚果向对话框添加最小化按钮,则需要下面的代码
//  æ¥ç»˜åˆ¶è¯¥å›¾æ ‡ã€‚  å¯¹äºŽä½¿ç”¨æ–‡æ¡£/视图模型的 MFC åº”用程序,
//  è¿™å°†ç”±æ¡†æž¶è‡ªåŠ¨å®Œæˆã€‚
void CMcDemoDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // ç”¨äºŽç»˜åˆ¶çš„设备上下文
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
        // ä½¿å›¾æ ‡åœ¨å·¥ä½œåŒºçŸ©å½¢ä¸­å±…中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        // ç»˜åˆ¶å›¾æ ‡
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMcDemoDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}
void CMcDemoDlg::OnBnClickedButtonCreate()
{
    m_mcChannellistener.funOnConnected = [&](IMcChannel* pChannel, int nErrorCode) -> void {
        CString strText;
        strText.Format(_T(">> funOnConnected, %s连接结果<code =  %d>\r\n"), pChannel->getName().c_str(), nErrorCode);
        AppendLog(strText);
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    };
    m_mcChannellistener.funOnClose = [&](IMcChannel* pChannel) -> void {
        AppendLog(">> funOnClose, %s已关闭\r\n", pChannel->getName().c_str());
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    };
    m_mcChannellistener.funOnClosing = [&](IMcChannel* pChannel) -> void {
        AppendLog(">> funOnClosing, æ­£åœ¨å…³é—­ %s\r\n", pChannel->getName().c_str());
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    };
    m_mcChannellistener.funOnRead = [&](IMcChannel* pChannel, char* pData, unsigned int nDataSize, int nDecodeRet) -> void {
        CString strText;
        DataToHexString(pData, nDataSize, strText);
        AppendLog(">> funOnRead:[%s]\r\n", strText);
    };
    m_mcChannellistener.funOnWrite = [&](IMcChannel* pChannel) -> void {
        AppendLog(">> funOnWrite\r\n");
    };
    CIPAddressCtrl* pIpAddressCtrl = (CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS_SERVER);
    BYTE b1, b2, b3, b4;
    pIpAddressCtrl->GetAddress(b1, b2, b3, b4);
    CString strIP;
    strIP.Format("%d.%d.%d.%d", b1, b2, b3, b4);
    UINT port = GetDlgItemInt(IDC_EDIT_SERVER_PORT);
    m_pChannel = NULL;
    if (0 == MCL_CreateChannel(m_pChannel, CHANNEL_NAME, (LPTSTR)(LPCTSTR)strIP, port, 0) && m_pChannel != NULL) {
        m_pChannel->setChannelListener(&m_mcChannellistener);
        CString strText;
        strText.Format(_T(">> åˆ›å»ºé€šé“(%s)成功\r\n"), m_pChannel->getName().c_str()),
        AppendLog(strText);
        //m_pChannel->connect();
    }
    else if(m_pChannel != NULL){
        m_pChannel->setChannelListener(&m_mcChannellistener);
        AppendLog(">> æ‰¾åˆ°çŽ°æœ‰é€šé“(%s).\r\n", m_pChannel->getName().c_str());
    }
    UpdateUISecsion1();
    UpdateUISecsion2();
    UpdateUISecsion3();
}
void CMcDemoDlg::OnBnClickedButtonSend()
{
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        CString strText;
        GetDlgItemText(IDC_EDIT_RAW, strText);
        CButton* pButton = (CButton*)GetDlgItem(IDC_RADIO2);
        if (pButton->GetCheck() == 1) {
            char szBuffer[1024];
            int nLen = HexStringToData(strText, szBuffer, 1024);
            if (nLen > 0) {
                m_pChannel->sendRawData(szBuffer, nLen);
            }
        }
        else {
            m_pChannel->sendRawData((LPTSTR)(LPCTSTR)strText, strText.GetLength());
        }
    }
}
void CMcDemoDlg::OnBnClickedButtonClose()
{
    if (m_pChannel != NULL) {
        if (m_pChannel->isConnected()) {
            m_pChannel->close();
        }
        else {
            AppendLog(_T(">> æ­£åœ¨è¿žæŽ¥ %s, %s:%d\r\n"), m_pChannel->getName().c_str(), m_pChannel->getIp().c_str(), m_pChannel->getServerPort());
            m_pChannel->connect();
        }
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    }
    /*
    IMcChannel* pChannel = NULL;
    if (0 == MCL_GetChannel(pChannel, CHANNEL_NAME) && pChannel != NULL) {
        pChannel->close();
    }*/
}
void CMcDemoDlg::OnBnClickedButtonDestroy()
{
    if (m_pChannel != NULL) {
        MCL_DestroyChannel(m_pChannel->getName().c_str());
        m_pChannel = NULL;
        UpdateUISecsion1();
        UpdateUISecsion2();
        UpdateUISecsion3();
    }
}
void CMcDemoDlg::AppendLog(CString strText)
{
    CEdit *pEdit = (CEdit *)GetDlgItem(IDC_EDIT_LOG);
    if (pEdit == NULL) {
        return;
    }
    // è¶…过指定行则删除最前面一行
    int nLine = pEdit->GetLineCount();
    if (nLine > 100) {
        CString strOldText;
        pEdit->GetWindowText(strOldText);
        int nIndex = strOldText.Find(_T("\r\n"), 0);
        for (int i = 0; i < 1111; i++) {
            nIndex = strOldText.Find(_T("\r\n"), nIndex + 2);
        }
        pEdit->SetSel(0, nIndex);
        pEdit->ReplaceSel(_T(""));
    }
    // è¿½åŠ åˆ°æœ€åŽ
    int length = pEdit->GetWindowTextLength();
    pEdit->SetSel(length, length);
    pEdit->ReplaceSel(strText);
    pEdit->PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
}
void CMcDemoDlg::AppendLog(char* szMessage, ...)
{
    if (!::IsWindow(GetSafeHwnd())) {
        return;
    }
    CEdit *pEdit = (CEdit *)GetDlgItem(IDC_EDIT_LOG);
    if (pEdit == NULL) {
        return;
    }
    char szFormatMessage[MAX_MESSAGE_LENGTH];
    va_list ap;
    va_start(ap, szMessage);
    _vsnprintf_s(szFormatMessage, MAX_MESSAGE_LENGTH, szMessage, ap);
    va_end(ap);
    // è¶…过指定行则删除最前面一行
    int nLine = pEdit->GetLineCount();
    if (nLine > 100) {
        CString strOldText;
        pEdit->GetWindowText(strOldText);
        int nIndex = strOldText.Find(_T("\r\n"), 0);
        for (int i = 0; i < 1111; i++) {
            nIndex = strOldText.Find(_T("\r\n"), nIndex + 2);
        }
        pEdit->SetSel(0, nIndex);
        pEdit->ReplaceSel(_T(""));
    }
    // è¿½åŠ åˆ°æœ€åŽ
    int length = pEdit->GetWindowTextLength();
    pEdit->SetSel(length, length);
    pEdit->ReplaceSel(szFormatMessage);
    pEdit->PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
}
void CMcDemoDlg::DataToHexString(const char* pData, const int size, CString& strOut)
{
    strOut.Empty();
    for (int i = 0; i < size; i++) {
        if (i < size - 1) {
            strOut.AppendFormat(_T("%02X "), (BYTE)pData[i]);
        }
        else {
            strOut.AppendFormat(_T("%02X"), (BYTE)pData[i]);
        }
    }
}
int CMcDemoDlg::HexStringToData(CString& strHex, char* pszBuffer, const int nBufferSize)
{
    int index = 0;
    int nLength = strHex.GetLength();
    CString strItem;
    for (int i = 0; i < nLength; i++) {
        if (strHex.GetAt(i) == ' ') {
            if (!strItem.IsEmpty()) {
                BYTE b = (BYTE)strtol(strItem, NULL, 16);
                pszBuffer[index] = b;
                index++;
                if (index >= nBufferSize) {
                    break;
                }
                strItem.Empty();
            }
            continue;
        }
        strItem.AppendChar(strHex.GetAt(i));
        if (strItem.GetLength() == 2) {
            BYTE b = (BYTE)strtol(strItem, NULL, 16);
            pszBuffer[index] = b;
            index++;
            if (index >= nBufferSize) {
                break;
            }
            strItem.Empty();
        }
    }
    return index;
}
void CMcDemoDlg::UpdateUISecsion1()
{
    if (!::IsWindow(GetSafeHwnd())) {
        return;
    }
    GetDlgItem(IDC_BUTTON_CREATE)->EnableWindow(m_pChannel == NULL);
    GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(m_pChannel != NULL);
    SetDlgItemText(IDC_BUTTON_CLOSE, (m_pChannel != NULL && m_pChannel->isConnected()) ? _T("Close") : _T("Open"));
    GetDlgItem(IDC_BUTTON_DESTROY)->EnableWindow(m_pChannel != NULL);
}
void CMcDemoDlg::UpdateUISecsion2()
{
    if (!::IsWindow(GetSafeHwnd())) {
        return;
    }
    BOOL bEnable = (m_pChannel != NULL && m_pChannel->isConnected());
    GetDlgItem(IDC_RADIO1)->EnableWindow(bEnable);
    GetDlgItem(IDC_RADIO2)->EnableWindow(bEnable);
    GetDlgItem(IDC_EDIT_RAW)->EnableWindow(bEnable);
    GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(bEnable);
    GetDlgItem(IDC_COMBO_CMD)->EnableWindow(bEnable);
    GetDlgItem(IDC_COMBO_SUBCMD)->EnableWindow(bEnable);
    GetDlgItem(IDC_COMBO_SOFTITEM)->EnableWindow(bEnable);
    GetDlgItem(IDC_EDIT_HEAD_ADDR)->EnableWindow(bEnable);
    GetDlgItem(IDC_EDIT_READ_COUNT)->EnableWindow(bEnable);
    GetDlgItem(IDC_BUTTON_RAWDATA)->EnableWindow(bEnable);
}
void CMcDemoDlg::UpdateUISecsion3()
{
    if (!::IsWindow(GetSafeHwnd())) {
        return;
    }
    GetDlgItem(IDC_COMBO_SOFTITEM2)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_EDIT_HEAD_ADDR2)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_READ_DWORD)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_READ)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_READ_BIT)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_EDIT_WRITE_VALUE)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_CHECK_WRITE_BIT_VALUE)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_WRITE_DWORD)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_WRITE)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
    GetDlgItem(IDC_BUTTON_WRITE_BIT)->EnableWindow((m_pChannel != NULL && m_pChannel->isConnected()));
}
void CMcDemoDlg::OnBnClickedButtonRawdata()
{
    /*
    char szBuffer[] = {0x50, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x01,
    0x04, 0x00, 0x00, 0x64, 0x00, 0x00, 0xa8, 0x01, 0x00};
    // è½¯å…ƒç±»åž‹
    static char szSoftItem[] = {0x90, 0xa8, 0x9c, 0x9d, 0xb0};
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM);
    szBuffer[18] = szSoftItem[pComboBox->GetCurSel()];
    // é¦–地址
    int nHeadAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR);
    szBuffer[15] = nHeadAddr & 0xff;
    szBuffer[16] = (nHeadAddr & 0xff00) >> 8;
    szBuffer[17] = (nHeadAddr & 0xff0000) >> 16;
    // æ•°é‡
    int nReadCount = GetDlgItemInt(IDC_EDIT_READ_COUNT);
    szBuffer[19] = nReadCount & 0xff;
    szBuffer[20] = (nReadCount & 0xff00) >> 8;
    // å‘½ä»¤
    int nCmd = ((CComboBox*)GetDlgItem(IDC_COMBO_CMD))->GetCurSel();
    if (nCmd == 0) {
    // æˆæ‰¹è¯»
    szBuffer[11] = 0x01;
    szBuffer[12] = 0x04;
    }
    else if (nCmd == 1) {
    // æˆæ‰¹å†™
    szBuffer[11] = 0x01;
    szBuffer[12] = 0x14;
    }
    else if (nCmd == 2) {
    // éšæœºè¯»
    szBuffer[11] = 0x03;
    szBuffer[12] = 0x04;
    }
    else if (nCmd == 3) {
    // æµ‹è¯•(随机写)
    szBuffer[11] = 0x02;
    szBuffer[12] = 0x14;
    }
    else if (nCmd == 4) {
    // ç›‘视登录数据
    szBuffer[11] = 0x01;
    szBuffer[12] = 0x08;
    }
    else if (nCmd == 5) {
    // ç›‘视
    szBuffer[11] = 0x02;
    szBuffer[12] = 0x08;
    }
    // å­å‘½ä»¤
    int nSubCmd = ((CComboBox*)GetDlgItem(IDC_COMBO_SUBCMD))->GetCurSel();
    if (nSubCmd == 0) {
    // æŒ‰å­—
    szBuffer[13] = 0x00;
    szBuffer[14] = 0x00;
    }
    else if (nSubCmd == 1) {
    // æŒ‰ä½
    szBuffer[13] = 0x00;
    szBuffer[14] = 0x01;
    }
    CString strRawData;
    DataToHexString(szBuffer, sizeof(szBuffer), strRawData);
    SetDlgItemText(IDC_EDIT_RAW, strRawData);
    */
    // æ–°æ–¹æ³•
    CComboBox* pComboBox = NULL;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_CMD);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strCmd = (LPTSTR)(LPCTSTR)strLbText;
    MC::CMD cmd;
    MCL_GetCmd(strCmd, cmd);
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SUBCMD);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSubCmd = (LPTSTR)(LPCTSTR)strLbText;
    MC::SUBCMD subCmd;
    MCL_GetSubCmd(strSubCmd, subCmd);
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nFirstAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR);
    int nOperateCount = GetDlgItemInt(IDC_EDIT_READ_COUNT);
    char szRawData[1024];
    char szAttach[4] = { 0x10, 0x11, 0x12, 0x13 };
    int nDataSize = MCL_GetRawData(cmd, subCmd, softComponent, nFirstAddr, nOperateCount, NULL, 0, szRawData, sizeof(szRawData));
    CString strRawData2;
    DataToHexString(szRawData, nDataSize, strRawData2);
    SetDlgItemText(IDC_EDIT_RAW, strRawData2);
    // AfxMessageBox(strRawData2);
}
void CMcDemoDlg::OnBnClickedButtonRead()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnRead = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnRead:[%d]\r\n", value);
            CString strText;
            strText.Format(_T("Read Word(%d)"), value);
            SetDlgItemText(IDC_BUTTON_READ, strText);
        };
        m_pChannel->readWord(softComponent, nAddr, funOnRead);
    }
}
void CMcDemoDlg::OnBnClickedButtonReadBit()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnRead = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnRead:[%s]\r\n", value != 0 ? "ON" : "OFF");
            CString strText;
            strText.Format(_T("Read Bit(%s)"), value != 0 ? "ON" : "OFF");
            SetDlgItemText(IDC_BUTTON_READ_BIT, strText);
            TRACE("MC Read Bit(%s)\n", value != 0 ? "ON" : "OFF");
        };
        m_pChannel->readBit(softComponent, nAddr, funOnRead);
    }
}
void CMcDemoDlg::OnBnClickedButtonWrite()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    int nValue = GetDlgItemInt(IDC_EDIT_WRITE_VALUE);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnWrite = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnWrite:[%d]\r\n", value);
        };
        m_pChannel->writeWord(softComponent, nAddr, nValue, funOnWrite);
    }
}
void CMcDemoDlg::OnBnClickedButtonReadDword()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnRead = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnRead:[%d]\r\n", value);
            CString strText;
            strText.Format(_T("Read DWORD(%d)"), value);
            SetDlgItemText(IDC_BUTTON_READ_DWORD, strText);
        };
        m_pChannel->readDWord(softComponent, nAddr, funOnRead);
    }
    // SetTimer(1, 500, NULL);
}
void CMcDemoDlg::OnBnClickedButtonWriteDword()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    int nValue = GetDlgItemInt(IDC_EDIT_WRITE_VALUE);
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnWrite = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnWrite:[%d]\r\n", value);
        };
        m_pChannel->writeDWord(softComponent, nAddr, nValue, funOnWrite);
    }
}
void CMcDemoDlg::OnBnClickedButtonWriteBit()
{
    CComboBox* pComboBox;
    CString strLbText;
    pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_SOFTITEM2);
    pComboBox->GetLBText(pComboBox->GetCurSel(), strLbText);
    std::string strSoftComponent = (LPTSTR)(LPCTSTR)strLbText;
    MC::SOFT_COMPONENT softComponent;
    MCL_GetSoftComponent(strSoftComponent, softComponent);
    int nAddr = GetDlgItemInt(IDC_EDIT_HEAD_ADDR2);
    CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_WRITE_BIT_VALUE);
    BOOL bValue = pButton->GetCheck();;
    if (m_pChannel != NULL && m_pChannel->isConnected()) {
        auto funOnWrite = [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
            AppendLog(">> funOnWrite:[%s]\r\n", value != 0 ? "ON" : "OFF");
        };
        m_pChannel->writeBit(softComponent, nAddr, bValue, funOnWrite);
    }
}
void CMcDemoDlg::OnBnClickedCheckWriteBitValue()
{
    CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_WRITE_BIT_VALUE);
    pButton->SetWindowText(pButton->GetCheck() ? "ON" : "OFF");
}
void CMcDemoDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: åœ¨æ­¤æ·»åŠ æ¶ˆæ¯å¤„ç†ç¨‹åºä»£ç å’Œ/或调用默认值
    if (1 == nIDEvent) {
        auto funOnReadData = [&](IMcChannel* pChannel, int addr, char *pData, unsigned int nDataSize, int flag) -> void {
            CString s = "Packer funOnReadData [";
            for (int i = 0; i < nDataSize; i++) {
                s.AppendFormat(" %x", (BYTE)pData[i]);
            }
            TRACE(s);
        };
        TRACE("Packer readData");
        m_pChannel->readData(MC::SOFT_COMPONENT::B, 0x2000, 5,
            funOnReadData);
    }
    CDialogEx::OnTimer(nIDEvent);
}
SourceCode/Bond/McLibrarySDK/McDemo/McDemoDlg.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
// McDemoDlg.h : å¤´æ–‡ä»¶
//
#pragma once
// CMcDemoDlg å¯¹è¯æ¡†
class CMcDemoDlg : public CDialogEx
{
// æž„造
public:
    CMcDemoDlg(CWnd* pParent = NULL);    // æ ‡å‡†æž„造函数
    void AppendLog(CString strText);
    void AppendLog(char* szMessage, ...);
    void DataToHexString(const char* pData, const int size, CString& strOut);
    int HexStringToData(CString& strHex, char* pszBuffer, const int nBufferSize);
    void UpdateUISecsion1();
    void UpdateUISecsion2();
    void UpdateUISecsion3();
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_MCDEMO_DIALOG };
#endif
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV æ”¯æŒ
// å®žçް
protected:
    HICON m_hIcon;
    McChannelListener m_mcChannellistener;
    IMcChannel* m_pChannel;
    // ç”Ÿæˆçš„æ¶ˆæ¯æ˜ å°„函数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnBnClickedButtonCreate();
    afx_msg void OnBnClickedButtonSend();
    afx_msg void OnBnClickedButtonClose();
    afx_msg void OnBnClickedButtonDestroy();
    afx_msg void OnBnClickedButtonRead();
    afx_msg void OnBnClickedButtonRawdata();
    afx_msg void OnBnClickedButtonWrite();
    afx_msg void OnBnClickedButtonReadBit();
    afx_msg void OnBnClickedCheckWriteBitValue();
    afx_msg void OnBnClickedButtonWriteBit();
    afx_msg void OnBnClickedButtonReadDword();
    afx_msg void OnBnClickedButtonWriteDword();
    afx_msg void OnTimer(UINT_PTR nIDEvent);
};
SourceCode/Bond/McLibrarySDK/McDemo/mcdemo.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,121 @@
// McDemo.cpp : å®šä¹‰åº”用程序的类行为。
//
#include "stdafx.h"
#include "McDemo.h"
#include "McDemoDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMcDemoApp
BEGIN_MESSAGE_MAP(CMcDemoApp, CWinApp)
    ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CMcDemoApp æž„造
CMcDemoApp::CMcDemoApp()
{
    // æ”¯æŒé‡æ–°å¯åŠ¨ç®¡ç†å™¨
    m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
    // TODO: åœ¨æ­¤å¤„添加构造代码,
    // å°†æ‰€æœ‰é‡è¦çš„初始化放置在 InitInstance ä¸­
}
// å”¯ä¸€çš„一个 CMcDemoApp å¯¹è±¡
CMcDemoApp theApp;
// CMcDemoApp åˆå§‹åŒ–
BOOL CMcDemoApp::InitInstance()
{
    // å¦‚果一个运行在 Windows XP ä¸Šçš„应用程序清单指定要
    // ä½¿ç”¨ ComCtl32.dll ç‰ˆæœ¬ 6 æˆ–更高版本来启用可视化方式,
    //则需要 InitCommonControlsEx()。  å¦åˆ™ï¼Œå°†æ— æ³•创建窗口。
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // å°†å®ƒè®¾ç½®ä¸ºåŒ…括所有要在应用程序中使用的
    // å…¬å…±æŽ§ä»¶ç±»ã€‚
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);
    CWinApp::InitInstance();
    AfxEnableControlContainer();
    // åˆ›å»º shell ç®¡ç†å™¨ï¼Œä»¥é˜²å¯¹è¯æ¡†åŒ…含
    // ä»»ä½• shell æ ‘视图控件或 shell åˆ—表视图控件。
    CShellManager *pShellManager = new CShellManager;
    // æ¿€æ´»â€œWindows Native”视觉管理器,以便在 MFC æŽ§ä»¶ä¸­å¯ç”¨ä¸»é¢˜
    CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
    // æ ‡å‡†åˆå§‹åŒ–
    // å¦‚果未使用这些功能并希望减小
    // æœ€ç»ˆå¯æ‰§è¡Œæ–‡ä»¶çš„大小,则应移除下列
    // ä¸éœ€è¦çš„特定初始化例程
    // æ›´æ”¹ç”¨äºŽå­˜å‚¨è®¾ç½®çš„æ³¨å†Œè¡¨é¡¹
    // TODO: åº”适当修改该字符串,
    // ä¾‹å¦‚修改为公司或组织名
    SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
    // åˆå§‹åŒ–
    MCL_Initialize();
    CMcDemoDlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: åœ¨æ­¤æ”¾ç½®å¤„理何时用
        //  â€œç¡®å®šâ€æ¥å…³é—­å¯¹è¯æ¡†çš„代码
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: åœ¨æ­¤æ”¾ç½®å¤„理何时用
        //  â€œå–消”来关闭对话框的代码
    }
    else if (nResponse == -1)
    {
        TRACE(traceAppMsg, 0, "警告: å¯¹è¯æ¡†åˆ›å»ºå¤±è´¥ï¼Œåº”用程序将意外终止。\n");
        TRACE(traceAppMsg, 0, "警告: å¦‚果您在对话框上使用 MFC æŽ§ä»¶ï¼Œåˆ™æ— æ³• #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
    }
    // åˆ é™¤ä¸Šé¢åˆ›å»ºçš„ shell ç®¡ç†å™¨ã€‚
    if (pShellManager != NULL)
    {
        delete pShellManager;
    }
#ifndef _AFXDLL
    ControlBarCleanUp();
#endif
    // ç”±äºŽå¯¹è¯æ¡†å·²å…³é—­ï¼Œæ‰€ä»¥å°†è¿”回 FALSE ä»¥ä¾¿é€€å‡ºåº”用程序,
    //  è€Œä¸æ˜¯å¯åŠ¨åº”ç”¨ç¨‹åºçš„æ¶ˆæ¯æ³µã€‚
    return FALSE;
}
int CMcDemoApp::ExitInstance()
{
    // TODO: åœ¨æ­¤æ·»åŠ ä¸“ç”¨ä»£ç å’Œ/或调用基类
    MCL_Term();
    return CWinApp::ExitInstance();
}
SourceCode/Bond/McLibrarySDK/McDemo/mcdemo.vcxproj
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{09A3010B-32B2-45EF-AAE1-4311997C99CD}</ProjectGuid>
    <RootNamespace>McDemo</RootNamespace>
    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
    <Keyword>MFCProj</Keyword>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <CharacterSet>MultiByte</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>MultiByte</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
    </Link>
    <Midl>
      <MkTypLibCompatible>false</MkTypLibCompatible>
      <ValidateAllParameters>true</ValidateAllParameters>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </Midl>
    <ResourceCompile>
      <Culture>0x0804</Culture>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
    </Link>
    <Midl>
      <MkTypLibCompatible>false</MkTypLibCompatible>
      <ValidateAllParameters>true</ValidateAllParameters>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </Midl>
    <ResourceCompile>
      <Culture>0x0804</Culture>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
    <Midl>
      <MkTypLibCompatible>false</MkTypLibCompatible>
      <ValidateAllParameters>true</ValidateAllParameters>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </Midl>
    <ResourceCompile>
      <Culture>0x0804</Culture>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
    <Midl>
      <MkTypLibCompatible>false</MkTypLibCompatible>
      <ValidateAllParameters>true</ValidateAllParameters>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </Midl>
    <ResourceCompile>
      <Culture>0x0804</Culture>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemGroup>
    <Text Include="ReadMe.txt" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="..\McLibrarySDK\include\IMcChannel.h" />
    <ClInclude Include="..\McLibrarySDK\include\McLib.h" />
    <ClInclude Include="McDemo.h" />
    <ClInclude Include="McDemoDlg.h" />
    <ClInclude Include="Resource.h" />
    <ClInclude Include="stdafx.h" />
    <ClInclude Include="targetver.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="McDemo.cpp" />
    <ClCompile Include="McDemoDlg.cpp" />
    <ClCompile Include="stdafx.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="McDemo.rc" />
  </ItemGroup>
  <ItemGroup>
    <None Include="res\McDemo.rc2" />
  </ItemGroup>
  <ItemGroup>
    <Image Include="res\McDemo.ico" />
  </ItemGroup>
  <ItemGroup>
    <Manifest Include="res\application.exe.manifest" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
  <ProjectExtensions>
    <VisualStudio>
      <UserProperties RESOURCE_FILE="McDemo.rc" />
    </VisualStudio>
  </ProjectExtensions>
</Project>
SourceCode/Bond/McLibrarySDK/McDemo/readme.txt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
================================================================================
    MICROSOFT åŸºç¡€ç±»åº“ : McDemo é¡¹ç›®æ¦‚è¿°
===============================================================================
应用程序向导已为您创建了此 McDemo åº”用程序。此应用程序不仅演示 Microsoft åŸºç¡€ç±»çš„基本使用方法,还可作为您编写应用程序的起点。
本文件概要介绍组成 McDemo åº”用程序的每个文件的内容。
McDemo.vcxproj
    è¿™æ˜¯ä½¿ç”¨åº”用程序向导生成的 VC++ é¡¹ç›®çš„主项目文件,其中包含生成该文件的 Visual C++ çš„版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
McDemo.vcxproj.filters
    è¿™æ˜¯ä½¿ç”¨â€œåº”用程序向导”生成的 VC++ é¡¹ç›®ç­›é€‰å™¨æ–‡ä»¶ã€‚它包含有关项目文件与筛选器之间的关联信息。在 IDE ä¸­ï¼Œé€šè¿‡è¿™ç§å…³è”,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
McDemo.h
    è¿™æ˜¯åº”用程序的主头文件。
    å…¶ä¸­åŒ…括其他项目特定的标头(包括 Resource.h),并声明 CMcDemoApp åº”用程序类。
McDemo.cpp
    è¿™æ˜¯åŒ…含应用程序类 CMcDemoApp çš„主应用程序源文件。
McDemo.rc
    è¿™æ˜¯ç¨‹åºä½¿ç”¨çš„æ‰€æœ‰ Microsoft Windows èµ„源的列表。它包括 RES å­ç›®å½•中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ ä¸­è¿›è¡Œç¼–辑。项目资源包含在 2052 ä¸­ã€‚
res\McDemo.ico
    è¿™æ˜¯ç”¨ä½œåº”用程序图标的图标文件。此图标包括在主资源文件 McDemo.rc ä¸­ã€‚
res\McDemo.rc2
    æ­¤æ–‡ä»¶åŒ…含不在 Microsoft Visual C++ ä¸­è¿›è¡Œç¼–辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
/////////////////////////////////////////////////////////////////////////////
应用程序向导创建一个对话框类:
McDemoDlg.h、McDemoDlg.cpp - å¯¹è¯æ¡†
    è¿™äº›æ–‡ä»¶åŒ…含 CMcDemoDlg ç±»ã€‚此类定义应用程序的主对话框的行为。对话框模板包含在 McDemo.rc ä¸­ï¼Œè¯¥æ–‡ä»¶å¯ä»¥åœ¨ Microsoft Visual C++ ä¸­ç¼–辑。
/////////////////////////////////////////////////////////////////////////////
其他功能:
ActiveX æŽ§ä»¶
    è¯¥åº”用程序包含对使用 ActiveX æŽ§ä»¶çš„æ”¯æŒã€‚
/////////////////////////////////////////////////////////////////////////////
其他标准文件:
StdAfx.h, StdAfx.cpp
    è¿™äº›æ–‡ä»¶ç”¨äºŽç”Ÿæˆåä¸º McDemo.pch çš„预编译头 (PCH) æ–‡ä»¶å’Œåä¸º StdAfx.obj çš„预编译类型文件。
Resource.h
    è¿™æ˜¯æ ‡å‡†å¤´æ–‡ä»¶ï¼Œå¯ç”¨äºŽå®šä¹‰æ–°çš„资源 ID。Microsoft Visual C++ å°†è¯»å–并更新此文件。
McDemo.manifest
    Windows XP ä½¿ç”¨åº”用程序清单文件来描述特定版本的并行程序集的应用程序依赖项。加载程序使用这些信息来从程序集缓存中加载相应的程序集,并保护其不被应用程序访问。应用程序清单可能会包含在内,以作为与应用程序可执行文件安装在同一文件夹中的外部 .manifest æ–‡ä»¶è¿›è¡Œé‡æ–°åˆ†å‘,它还可能以资源的形式包含在可执行文件中。
/////////////////////////////////////////////////////////////////////////////
其他注释:
应用程序向导使用“TODO:”来指示应添加或自定义的源代码部分。
如果应用程序使用共享 DLL ä¸­çš„ MFC,您将需要重新分发 MFC DLL。如果应用程序所使用的语言与操作系统的区域设置不同,则还需要重新分发相应的本地化资源 mfc110XXX.DLL。
有关上述话题的更多信息,请参见 MSDN æ–‡æ¡£ä¸­æœ‰å…³é‡æ–°åˆ†å‘ Visual C++ åº”用程序的部分。
/////////////////////////////////////////////////////////////////////////////
SourceCode/Bond/McLibrarySDK/McDemo/res/McDemo.ico
SourceCode/Bond/McLibrarySDK/McDemo/res/McDemo.rc2
Binary files differ
SourceCode/Bond/McLibrarySDK/McDemo/res/application.exe.manifest
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity
         name="XP style manifest"
         processorArchitecture="amd64"
         version="1.0.0.0"
         type="win32"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity
                type="win32"
                name="Microsoft.Windows.Common-Controls"
                version="6.0.0.0"
                processorArchitecture="amd64"
                publicKeyToken="6595b64144ccf1df"
                language="*"
            />
        </dependentAssembly>
    </dependency>
</assembly>
SourceCode/Bond/McLibrarySDK/McDemo/resource.h
Binary files differ
SourceCode/Bond/McLibrarySDK/McDemo/stdafx.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
// stdafx.cpp : åªåŒ…括标准包含文件的源文件
// McDemo.pch å°†ä½œä¸ºé¢„编译头
// stdafx.obj å°†åŒ…含预编译类型信息
#include "stdafx.h"
SourceCode/Bond/McLibrarySDK/McDemo/stdafx.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
// stdafx.h : æ ‡å‡†ç³»ç»ŸåŒ…含文件的包含文件,
// æˆ–是经常使用但不常更改的
// ç‰¹å®šäºŽé¡¹ç›®çš„包含文件
#pragma once
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN            // ä»Ž Windows å¤´ä¸­æŽ’除极少使用的资料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // æŸäº› CString æž„造函数将是显式的
// å…³é—­ MFC å¯¹æŸäº›å¸¸è§ä½†ç»å¸¸å¯æ”¾å¿ƒå¿½ç•¥çš„警告消息的隐藏
#define _AFX_ALL_WARNINGS
#include <afxwin.h>         // MFC æ ¸å¿ƒç»„件和标准组件
#include <afxext.h>         // MFC æ‰©å±•
#include <afxdisp.h>        // MFC è‡ªåŠ¨åŒ–ç±»
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>           // MFC å¯¹ Internet Explorer 4 å…¬å…±æŽ§ä»¶çš„æ”¯æŒ
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>             // MFC å¯¹ Windows å…¬å…±æŽ§ä»¶çš„æ”¯æŒ
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h>     // åŠŸèƒ½åŒºå’ŒæŽ§ä»¶æ¡çš„ MFC æ”¯æŒ
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
SourceCode/Bond/McLibrarySDK/McDemo/targetver.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
#pragma once
// åŒ…括 SDKDDKVer.h å°†å®šä¹‰å¯ç”¨çš„æœ€é«˜ç‰ˆæœ¬çš„ Windows å¹³å°ã€‚
// å¦‚果要为以前的 Windows å¹³å°ç”Ÿæˆåº”用程序,请包括 WinSDKVer.h,并将
// å°† _WIN32_WINNT å®è®¾ç½®ä¸ºè¦æ”¯æŒçš„平台,然后再包括 SDKDDKVer.h。
#include <SDKDDKVer.h>
SourceCode/Bond/McLibrarySDK/Readme.docx
Binary files differ
SourceCode/Bond/McLibrarySDK/Readme.pdf
Binary files differ
SourceCode/Bond/McLibrarySDK/include/IMcChannel.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,131 @@
#pragma once
#include <string>
#include <functional>
#define TIMEOUT        -99
class IMcChannel;
typedef std::function<void(IMcChannel*)> ONCLOSE;
typedef std::function<void(IMcChannel*)> ONCLOSING;
typedef std::function<void(IMcChannel*, int nErrorCode)> ONCONNECTED;
typedef std::function<void(IMcChannel*, char *pData, unsigned int nDataSize, int nDecodeRet)> ONREADRAWDATA;
typedef std::function<void(IMcChannel*)> ONWRITERAWDATA;
typedef std::function<void(IMcChannel*, int addr, DWORD value, int flag)> ONREAD;
typedef std::function<void(IMcChannel*, int addr, char *pData, unsigned int nDataSize, int flag)> ONREADDATA;
typedef std::function<void(IMcChannel*, int addr, DWORD value, int flag)> ONWRITE;
typedef struct _McChannelListener
{
    ONCLOSE                funOnClose;
    ONCLOSING            funOnClosing;
    ONCONNECTED            funOnConnected;
    ONREADRAWDATA        funOnRead;
    ONWRITERAWDATA        funOnWrite;
} McChannelListener;
namespace MC {
#define LERROR        4
#define LWARN        3
#define LINFO        2
#define LDEBUG        1
    /** @brief å‘½ä»¤*/
    typedef enum CMD
    {
        /** @brief æˆæ‰¹è¯» */
        BATCH_READ = 0x0401,
        /** @brief æˆæ‰¹å†™ */
        BATCH_WRITE = 0x1401,
        /** @brief éšæœºè¯» */
        RANDOM_READ = 0x0403,
        /** @brief æµ‹è¯•(随机写) */
        TEST_RANDOM_WRITE = 0x0402,
        /** @brief ç›‘视注册数据 */
        MONITOR_REGISTER_DATA = 0x0801,
        /** @brief ç›‘视 */
        MONITOR = 0x0802,
    } CMD;
    /** @brief å­å‘½ä»¤*/
    typedef enum SUBCMD
    {
        /** @brief æŒ‰å­— */
        SC_WORD = 0x0000,
        /** @brief æŒ‰ä½ */
        SC_BIT = 0x0001,
    } SUBCMD;
    /** @brief è½¯å…ƒä»¶ç±»åž‹*/
    typedef enum SOFT_COMPONENT
    {
        /** @brief å†…部继电器(M*) */
        M = 0x90,
        /** @brief æ•°æ®å¯„存器(D*) */
        D = 0xa8,
        /** @brief é“¾æŽ¥å¯„存器(W*) */
        W = 0xb4,
        /** @brief è¾“å…¥(X*) */
        X = 0x9c,
        /** @brief è¾“出(Y*) */
        Y = 0x9d,
        /** @brief é”å­˜ç»§ç”µå™¨(L*) */
        L = 0x92,
        /** @brief æ­¥è¿›ç»§ç”µå™¨(S*) */
        S = 0x98,
        /** @brief é“¾æŽ¥ç»§ç”µå™¨(B*) */
        B = 0xA0,
        /** @brief æŠ¥è­¦å™¨(F*) */
        F = 0x93,
        /** @brief æ–‡ä»¶å¯„存器(ZR*) */
        ZR = 0xB0,
    } SOFT_COMPONENT;
}
class IMcChannel
{
public:
    virtual void setChannelListener(McChannelListener *pListener) = 0;
    virtual void setActionInterval(int millisecond) = 0;
    virtual std::string &getName() = 0;
    virtual std::string &getIp() = 0;
    virtual unsigned int getServerPort() = 0;
    virtual unsigned int getLocalPort() = 0;
    virtual bool isConnected() = 0;
    virtual int connect() = 0;
    virtual int close() = 0;
    virtual int sendRawData(char *pData, int nDataSize) = 0;
    virtual int readData(MC::SOFT_COMPONENT softComponent, unsigned int addr, unsigned int nReadLen, ONREADDATA funOnReadData) = 0;
    virtual int readData2(MC::SOFT_COMPONENT softComponent, unsigned int addr, unsigned int nReadLen, int executeTime, ONREADDATA funOnReadData) = 0;
    virtual int readDWord(MC::SOFT_COMPONENT softComponent, unsigned int addr, ONREAD funOnRead) = 0;
    virtual int readWord(MC::SOFT_COMPONENT softComponent, unsigned int addr, ONREAD funOnRead) = 0;
    virtual int readWordIfIdle(MC::SOFT_COMPONENT softComponent, unsigned int addr, ONREAD funOnRead) = 0;
    virtual int readBit(MC::SOFT_COMPONENT softComponent, unsigned int addr, ONREAD funOnRead) = 0;
    virtual int writeData(MC::SOFT_COMPONENT softComponent, unsigned int addr, const char* pData, unsigned int nDataLen, ONWRITE funOnWrite) = 0;
    virtual int writeWord(MC::SOFT_COMPONENT softComponent, unsigned int addr, WORD value, ONWRITE funOnWrite) = 0;
    virtual int writeDWord(MC::SOFT_COMPONENT softComponent, unsigned int addr, DWORD value, ONWRITE funOnWrite) = 0;
    virtual int writeBit(MC::SOFT_COMPONENT softComponent, unsigned int addr, BOOL value, ONWRITE funOnWrite) = 0;
    virtual int writeBit2(MC::SOFT_COMPONENT softComponent, unsigned int addr, BOOL value, int executeTime, ONWRITE funOnWrite) = 0;
    virtual int writeBitIfIdle(MC::SOFT_COMPONENT softComponent, unsigned int addr, BOOL value, ONWRITE funOnWrite) = 0;
};
SourceCode/Bond/McLibrarySDK/include/McLib.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
#pragma once
#include <functional>
#include <vector>
#include "IMcChannel.h"
#ifdef _COMPILE_AS_LIB
#warning "compiling as lib!"
#else
#ifdef _DEBUG
#ifndef _WIN64
#pragma comment(lib, "../McLibrarySDK/lib/Win32/Debug/McLibrary.lib")
#else
#pragma comment(lib, "../McLibrarySDK/lib/x64/Debug/McLibrary.lib")
#endif
#else
#ifndef _WIN64
#pragma comment(lib, "../McLibrarySDK/lib/Win32/Release/McLibrary.lib")
#else
#pragma comment(lib, "../McLibrarySDK/lib/x64/Release/McLibrary.lib")
#endif
#endif
#endif // !BUILD_AS_LIB
///////////////////////////////////////////////////////////////////////////////////
//// Define C linkage if using a C++ compiler
///////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
    ///////////////////////////////////////////////////////////////////////////////////
    //// Determine callling convention baesd on compiler
    ///////////////////////////////////////////////////////////////////////////////////
#ifdef __BORLANDC__
#ifdef __WIN32__
#define EXPORTED __declspec(dllexport) __stdcall
#else
#define EXPORTED FAR PASCAL __export
#endif // WIN32
#else // __BORLANDC__
#ifdef WIN32
#define EXPORTED __declspec(dllexport)
#else
#define EXPORTED FAR PASCAL __export
#endif // WIN32
#endif //__BORLANDC__
    /////////////////////////////////////////////////////////////////////////////////////
    //// å¯¼å‡ºå‡½æ•°
    ////////////////////////////////////////////////////////////////////////////////////
    int            EXPORTED    MCL_Initialize();
    int            EXPORTED    MCL_Term();
    int            EXPORTED    MCL_SetTimeout(int timeout);
    int            EXPORTED    MCL_SetMaxActionSize(int actionSize);
    int            EXPORTED    MCL_SetPacketSize(int size);
    int            EXPORTED    MCL_CreateChannel(IMcChannel*& pChannel, const char* pszName, const char* pszIp,
        const unsigned int nServerPort, const unsigned int nLocalPort = 0);
    int            EXPORTED    MCL_DestroyChannel(const char* pszName);
    int            EXPORTED    MCL_GetChannel(IMcChannel*& pChannel, const char* pszName);
    int            EXPORTED    MCL_GetCmds(std::vector<std::string>& cmds);
    int            EXPORTED    MCL_GetCmdString(IN MC::CMD cmd, OUT std::string& strCmd);
    int            EXPORTED    MCL_GetCmd(IN std::string& strCmd, OUT MC::CMD& cmd);
    int            EXPORTED    MCL_GetSubCmds(std::vector<std::string>& subCmds);
    int            EXPORTED    MCL_GetSubCmdString(IN MC::SUBCMD subcmd, OUT std::string& strSubCmd);
    int            EXPORTED    MCL_GetSubCmd(IN std::string& strSubCmd, OUT MC::SUBCMD& subcmd);
    int            EXPORTED    MCL_GetSoftComponents(std::vector<std::string>& softComponents);
    int            EXPORTED    MCL_GetSoftComponentString(std::vector<std::string>& softComponents);
    int            EXPORTED    MCL_GetSoftComponent(IN std::string& strSoftComponent, OUT MC::SOFT_COMPONENT& softComponent);
    int            EXPORTED    MCL_GetRawData(MC::CMD cmd, MC::SUBCMD subCmd, MC::SOFT_COMPONENT softComponent,
                                unsigned int firstAddr, int count, char* pszAttach, const unsigned int nAttachSize, char* pszBuffer, const unsigned int nBufferSize);
#ifdef __cplusplus
};
#endif //__cplusplus