LAPTOP-SNT8I5JK\Boounion
2025-07-08 f0f942498d6b0c9a92ee2d7b9ea62a592b8f4cce
1.基础通讯,建立连接;
已添加12个文件
已修改17个文件
1451 ■■■■■ 文件已修改
SourceCode/Bond/EAPSimulator/CHsmsActive.cpp 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/CHsmsActive.h 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/CModel.cpp 300 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/CModel.h 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/Common.h 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/Context.cpp 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/Context.h 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/EAPSimulator.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/EAPSimulator.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/EAPSimulator.vcxproj 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/EAPSimulator.vcxproj.filters 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/EAPSimulator.vcxproj.user 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/Log.cpp 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/Log.h 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/LogEdit.cpp 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/LogEdit.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/Resource.h 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/res/EAPSimulator.ico 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/HSMSSDK/Include/HSMSSDK.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/HSMSSDK/Include/IActive.h 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMyStatusbar.cpp 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMyStatusbar.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/HsmsPassive.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.user 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/EAPSimulator/CHsmsActive.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,115 @@
#include "pch.h"
#include "CHsmsActive.h"
CHsmsActive::CHsmsActive()
{
    m_listener = {};
    m_pActive = nullptr;
    m_nSessionId = 0;
    m_nSystemByte = 0;
}
CHsmsActive::~CHsmsActive()
{
}
void CHsmsActive::setListener(ACTIVEListener listener)
{
    m_listener = listener;
}
int CHsmsActive::init(const char* pszIp, int port)
{
    m_strIp = pszIp;
    m_nPort = port;
    ++m_nSessionId;
    auto onStatusChanged = [&](void* pFrom, ACTIVESTATE state) -> void {
        if (m_listener.onStateChanged != nullptr) {
            m_listener.onStateChanged(this, state);
        }
        if (ACTIVESTATE::NOT_SELECTED == state) {
            hsmsSelectRequest();
        }
        else if (ACTIVESTATE::SELECTED == state) {
            hsmsEstablishCommunications();
        }
        else if (ACTIVESTATE::NOT_CONNECTED == state) {
            m_pActive->disconnect();
        }
    };
    auto onRecvSysMessage = [&](void* pFrom, IMessage* pMessage) -> void {
        TRACE("sessionId:%d, sType:%d\n", pMessage->getHeader()->sessionId, pMessage->getHeader()->sType);
    };
    auto onError = [&](void* pFrom, int error) -> void {
        TRACE("onError:%d\n", error);
    };
    auto onRecvRawData = [&](void* pFrom, const char* pszData, int size) {
        TRACE("onRec ,vRawData:<0x%x, %d>\n", pszData, size);
    };
    auto onRecvDataMessage = [&](void* pFrom, IMessage* pMessage) -> void {
        HEADER* pHeader = pMessage->getHeader();
        TRACE("收到消息 S%dF%d================\n", pHeader->stream & 0x7F, pHeader->function);
        TRACE("Body:%s\n", pMessage->toString());
    };
    ActiveListener listener;
    listener.funStateChanged = onStatusChanged;
    listener.funRecvRawData = onRecvRawData;
    listener.funRecvDataMessage = onRecvDataMessage;
    listener.funRecvSysMessage = onRecvSysMessage;
    listener.funError = onError;
    int nRet = HSMS_CreateActive(m_pActive, _T(""), m_strIp.c_str(), m_nPort);
    if (nRet == 0 && m_pActive != nullptr) {
        m_pActive->setListener(listener);
        m_pActive->connect();
    }
    return 0;
}
int CHsmsActive::term()
{
    if (m_pActive != nullptr) {
        ::HSMS_DestroyActive(m_pActive);
        m_pActive = nullptr;
    }
    return 0;
}
int CHsmsActive::hsmsSelectRequest()
{
    IMessage* pMessage = nullptr;
    int nRet = HSMS_CreateMessageWithSType(pMessage, MSG_SELECT_REQ, ++m_nSystemByte);
    m_pActive->sendMessage(pMessage);
    HSMS_Destroy1Message(pMessage);
    return 0;
}
int CHsmsActive::hsmsDeselectRequest()
{
    IMessage* pMessage = nullptr;
    int nRet = HSMS_CreateMessageWithSType(pMessage, MSG_DESELECT_REQ, ++m_nSystemByte);
    m_pActive->sendMessage(pMessage);
    HSMS_Destroy1Message(pMessage);
    return 0;
}
int CHsmsActive::hsmsEstablishCommunications()
{
    IMessage* pMessage = nullptr;
    int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 13, ++m_nSystemByte);
    m_pActive->sendMessage(pMessage);
    HSMS_Destroy1Message(pMessage);
    return 0;
}
SourceCode/Bond/EAPSimulator/CHsmsActive.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
#pragma once
#include <string>
typedef std::function<void(void* pFrom, ACTIVESTATE state)> STATECHANGED;
typedef struct _ACTIVEListener
{
    STATECHANGED            onStateChanged;
} ACTIVEListener;
class CHsmsActive
{
public:
    CHsmsActive();
    ~CHsmsActive();
public:
    void setListener(ACTIVEListener listener);
    int init(const char* pszIp, int port);
    int term();
public:
    // Select
    int hsmsSelectRequest();
    // Deselect Request
    int hsmsDeselectRequest();
    // å»ºç«‹é€šè®¯(S1F13)
    int hsmsEstablishCommunications();
private:
    ACTIVEListener m_listener;
    IActive* m_pActive;
    std::string m_strIp;
    int m_nPort;
    unsigned short m_nSessionId;
    unsigned int m_nSystemByte;
};
SourceCode/Bond/EAPSimulator/CModel.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,300 @@
#include "pch.h"
#include "CModel.h"
#include "Log.h"
#include "Common.h"
CModel::CModel()
{
    m_pObservableEmitter = nullptr;
    m_pObservable = nullptr;
    m_pHsmsActive = nullptr;
}
CModel::~CModel()
{
}
IObservable* CModel::getObservable()
{
    if (m_pObservable == nullptr) {
        m_pObservable = RX_AllocaObservable([&](IObservableEmitter* e) -> void {
            m_pObservableEmitter = e;            // ä¿å­˜å‘射器
            });
    }
    return m_pObservable;
}
void CModel::setWorkDir(const char* pszWorkDir)
{
    m_strWorkDir = pszWorkDir;
}
int CModel::init()
{
    CString strIniFile;
    // Log
    CString strLogDir;
    strLogDir.Format(_T("%s\\Log"), (LPTSTR)(LPCTSTR)m_strWorkDir);
    ::CreateDirectory(strLogDir, NULL);
    CLog::GetLog()->SetOnLogCallback([&](int level, const char* pszMessage) -> void {
        notifyTextAndInt(RX_CODE_LOG, pszMessage, level);
        });
    CLog::GetLog()->SetAutoAppendTimeString(TRUE);
    CLog::GetLog()->SetOutputTarget(OT_FILE);
    CLog::GetLog()->SetLogsDir(strLogDir);
    CLog::GetLog()->SetEquipmentId(_T("EAP"));
    LOGI("\r\n\r\n~~~ Prog Start! ~~~");
    return 0;
}
int CModel::term()
{
    CLog::GetLog()->SetOnLogCallback(nullptr);
    if (m_pHsmsActive != nullptr) {
        m_pHsmsActive->term();
        delete m_pHsmsActive;
    }
    return 0;
}
int CModel::connectEq(const char* pszIp, int port)
{
    if (m_pHsmsActive != nullptr) {
        m_pHsmsActive->term();
        delete m_pHsmsActive;
    }
    ACTIVEListener listener;
    listener.onStateChanged = [&](void* pFrom, ACTIVESTATE state) -> void {
        notifyInt(RX_CODE_ACTIVE_STATUS_CHANGED, (int)state);
    };
    m_pHsmsActive = new CHsmsActive();
    m_pHsmsActive->setListener(listener);
    m_pHsmsActive->init(pszIp, port);
    return 0;
}
int CModel::disconnect()
{
    if (m_pHsmsActive == nullptr) {
        return -1;
    }
    m_pHsmsActive->hsmsDeselectRequest();
    return 0;
}
int CModel::notify(int code)
{
    /* code */
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 1;
}
int CModel::notifyPtr(int code, void* ptr/* = NULL*/)
{
    /* code */
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setPtrValue("ptr", ptr);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 1;
}
int CModel::notifyObj(int code, IRxObject* pObj)
{
    /* code */
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setObject("obj", pObj);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 1;
}
int CModel::notifyObjAndPtr(int code, IRxObject* pObj, void* ptr)
{
    /* code */
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setObject("obj", pObj);
            pAny->setPtrValue("ptr", ptr);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 1;
}
int CModel::notifyInt(int code, int exCode)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setIntValue("exCode", exCode);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyInt2(int code, int exCode, int exCode2)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setIntValue("exCode", exCode);
            pAny->setIntValue("exCode2", exCode2);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyDouble(int code, double dValue)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setDoubleValue("value", dValue);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyObjAndInt(int code, IRxObject* pObj1, IRxObject* pObj2, int exCode)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            if (pObj1 != nullptr) pAny->setObject("obj", pObj1);
            if (pObj2 != nullptr) pAny->setObject("obj2", pObj2);
            pAny->setIntValue("exCode", exCode);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyText(int code, const char* pszText)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setStringValue("text", pszText);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyTextAndInt(int code, const char* pszText, int exCode)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setStringValue("text", pszText);
            pAny->setIntValue("exCode", exCode);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyPtrAndInt(int code, void* ptr1, void* ptr2, int exCode)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setPtrValue("ptr", ptr1);
            pAny->setPtrValue("ptr1", ptr1);
            pAny->setPtrValue("ptr2", ptr2);
            pAny->setIntValue("exCode", exCode);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
int CModel::notifyMesMsg(int code, int stream, int function, const char* pszText)
{
    if (m_pObservableEmitter != NULL) {
        IAny* pAny = RX_AllocaAny();
        if (pAny != NULL) {
            pAny->addRef();
            pAny->setCode(code);
            pAny->setIntValue("stream", stream);
            pAny->setIntValue("function", function);
            pAny->setStringValue("text", pszText);
            m_pObservableEmitter->onNext(pAny);
            pAny->release();
        }
    }
    return 0;
}
SourceCode/Bond/EAPSimulator/CModel.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
#pragma once
#include "CHsmsActive.h"
class CModel
{
public:
    CModel();
    ~CModel();
public:
    IObservable* getObservable();
    void setWorkDir(const char* pszWorkDir);
    int init();
    int term();
    int connectEq(const char* pszIp, int port);
    int disconnect();
public:
    int notify(int code);
    int notifyPtr(int code, void* ptr = NULL);
    int notifyObj(int code, IRxObject* pObj);
    int notifyObjAndPtr(int code, IRxObject* pObj, void* ptr);
    int notifyObjAndInt(int code, IRxObject* pObj1, IRxObject* pObj2, int exCode);
    int notifyInt(int code, int exCode);
    int notifyInt2(int code, int exCode, int exCode2);
    int notifyDouble(int code, double dValue);
    int notifyText(int code, const char* pszText);
    int notifyPtrAndInt(int code, void* ptr1, void* ptr2, int exCode);
    int notifyTextAndInt(int code, const char* pszText, int exCode);
    int notifyMesMsg(int code, int stream, int function, const char* pszText);
public:
    CHsmsActive* m_pHsmsActive;
private:
    IObservable* m_pObservable;
    IObservableEmitter* m_pObservableEmitter;
    CString m_strWorkDir;
    CString m_strDataDir;
};
SourceCode/Bond/EAPSimulator/Common.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
#pragma once
#define RX_CODE_TEST                    0
#define RX_CODE_LOG                        1000
#define RX_CODE_ACTIVE_STATUS_CHANGED    1001
SourceCode/Bond/EAPSimulator/Context.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,184 @@
#include "pch.h"
#include "Context.h"
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")
void PrintStackTrace()
{
    void* stack[62]; // æœ€å¤šæŠ“62层
    USHORT frames = CaptureStackBackTrace(0, 62, stack, NULL);
    HANDLE process = GetCurrentProcess();
    SymInitialize(process, NULL, TRUE);
    for (USHORT i = 0; i < frames; ++i) {
        DWORD64 address = (DWORD64)(stack[i]);
        char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
        PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
        symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
        symbol->MaxNameLen = MAX_SYM_NAME;
        if (SymFromAddr(process, address, 0, symbol)) {
            TRACE(">>>> name:%s\n", symbol->Name);
        }
        else {
            TRACE(">>>> name:%s\n", "SymFromAddr failed");
        }
    }
    SymCleanup(process);
}
CContext::CContext()
{
    m_onReleaseCallback = nullptr;
    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);
}
void CContext::setOnRelease(ONRELEASECALLBACK fOnRelease)
{
    m_onReleaseCallback = fOnRelease;
}
int CContext::addRef()
{
    Lock();
    m_nRef++;
    Unlock();
    return m_nRef;
}
int CContext::release()
{
    Lock();
    if (m_nRef > 0) {
        m_nRef--;
        BOOL bRefCount0 = m_nRef == 0;
        Unlock();
        if (bRefCount0 && m_onReleaseCallback != nullptr) {
            m_onReleaseCallback(this);
        }
    }
    else {
        Unlock();
    }
    return m_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;
}
SourceCode/Bond/EAPSimulator/Context.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
#pragma once
#include "Common.h"
#include <functional>
typedef std::function<void(void*)> ONRELEASECALLBACK;
class CContext : public IRxObject
{
public:
    CContext();
    virtual ~CContext();
public:
    void setOnRelease(ONRELEASECALLBACK fOnRelease);
    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);
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:
    ONRELEASECALLBACK m_onReleaseCallback;
    int m_nRef;
    CRITICAL_SECTION m_criticalSection;
protected:
    int m_nRetCode;
    std::string m_strRetMsg;
    HANDLE m_hEvent;
};
SourceCode/Bond/EAPSimulator/EAPSimulator.h
@@ -9,6 +9,7 @@
#endif
#include "resource.h"        // ä¸»ç¬¦å·
#include "CModel.h"
// CEAPSimulatorApp:
@@ -20,6 +21,10 @@
public:
    CEAPSimulatorApp();
public:
    CModel m_model;
// é‡å†™
public:
    virtual BOOL InitInstance();
SourceCode/Bond/EAPSimulator/EAPSimulator.rc
Binary files differ
SourceCode/Bond/EAPSimulator/EAPSimulator.vcxproj
@@ -183,16 +183,27 @@
    </ResourceCompile>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClInclude Include="CHsmsActive.h" />
    <ClInclude Include="CModel.h" />
    <ClInclude Include="Common.h" />
    <ClInclude Include="Context.h" />
    <ClInclude Include="EAPSimulator.h" />
    <ClInclude Include="EAPSimulatorDlg.h" />
    <ClInclude Include="framework.h" />
    <ClInclude Include="Log.h" />
    <ClInclude Include="LogEdit.h" />
    <ClInclude Include="pch.h" />
    <ClInclude Include="Resource.h" />
    <ClInclude Include="targetver.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="CHsmsActive.cpp" />
    <ClCompile Include="CModel.cpp" />
    <ClCompile Include="Context.cpp" />
    <ClCompile Include="EAPSimulator.cpp" />
    <ClCompile Include="EAPSimulatorDlg.cpp" />
    <ClCompile Include="Log.cpp" />
    <ClCompile Include="LogEdit.cpp" />
    <ClCompile Include="pch.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
SourceCode/Bond/EAPSimulator/EAPSimulator.vcxproj.filters
@@ -33,6 +33,24 @@
    <ClInclude Include="pch.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="Log.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="LogEdit.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="CModel.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="Context.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="CHsmsActive.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="Common.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="EAPSimulator.cpp">
@@ -44,6 +62,21 @@
    <ClCompile Include="pch.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="Log.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="LogEdit.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="CModel.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="Context.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="CHsmsActive.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="EAPSimulator.rc">
SourceCode/Bond/EAPSimulator/EAPSimulator.vcxproj.user
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup />
  <PropertyGroup>
    <RESOURCE_FILE>EAPSimulator.rc</RESOURCE_FILE>
  </PropertyGroup>
</Project>
SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.cpp
@@ -7,6 +7,9 @@
#include "EAPSimulator.h"
#include "EAPSimulatorDlg.h"
#include "afxdialogex.h"
#include "Common.h"
#include <regex>
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -54,21 +57,75 @@
    : CDialogEx(IDD_EAPSIMULATOR_DIALOG, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_pObserver = nullptr;
}
void CEAPSimulatorDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT_LOG, m_logEdit);
}
BEGIN_MESSAGE_MAP(CEAPSimulatorDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_DESTROY()
    ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CEAPSimulatorDlg::OnBnClickedButtonConnect)
    ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, &CEAPSimulatorDlg::OnBnClickedButtonDisconnect)
END_MESSAGE_MAP()
// CEAPSimulatorDlg æ¶ˆæ¯å¤„理程序
void CEAPSimulatorDlg::InitRxWindow()
{
    /* code */
    // è®¢é˜…数据
    IRxWindows* pRxWindows = RX_GetRxWindows();
    pRxWindows->enableLog(5);
    if (m_pObserver == NULL) {
        m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
            // onNext
            pAny->addRef();
            int code = pAny->getCode();
            if (RX_CODE_LOG == code && ::IsWindow(m_hWnd)) {
                const char* pszLogMsg;
                int level;
                if (pAny->getStringValue("text", pszLogMsg)
                    && pAny->getIntValue("exCode", level)) {
                    CString strText = pszLogMsg;
                    strText.Replace("\n", "\r\n");
                    AppendLog(level, (LPTSTR)(LPCTSTR)strText);
                }
            }
            else if (RX_CODE_ACTIVE_STATUS_CHANGED == code) {
                int state;
                if (pAny->getIntValue("exCode", state)) {
                    if ((ACTIVESTATE)state == ACTIVESTATE::SELECTED) {
                        GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(TRUE);
                    }
                    if ((ACTIVESTATE)state == ACTIVESTATE::NOT_CONNECTED) {
                        GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(FALSE);
                        GetDlgItem(IDC_EDIT_IP)->EnableWindow(TRUE);
                        GetDlgItem(IDC_EDIT_PORT)->EnableWindow(TRUE);
                        GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);
                    }
                }
            }
            pAny->release();
            }, [&]() -> void {
                // onComplete
            }, [&](IThrowable* pThrowable) -> void {
                // onErrorm
                pThrowable->printf();
            });
        theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
            ->subscribe(m_pObserver);
    }
}
BOOL CEAPSimulatorDlg::OnInitDialog()
{
@@ -99,7 +156,14 @@
    SetIcon(m_hIcon, TRUE);            // è®¾ç½®å¤§å›¾æ ‡
    SetIcon(m_hIcon, FALSE);        // è®¾ç½®å°å›¾æ ‡
    // TODO: åœ¨æ­¤æ·»åŠ é¢å¤–çš„åˆå§‹åŒ–ä»£ç 
    SetDlgItemText(IDC_EDIT_IP, _T("127.0.0.1"));
    SetDlgItemInt(IDC_EDIT_PORT, 7000);
    // log edit
    m_logEdit.SetMaxLineCount(8000);
    m_logEdit.SetLimitText(-1);
    InitRxWindow();
    return TRUE;  // é™¤éžå°†ç„¦ç‚¹è®¾ç½®åˆ°æŽ§ä»¶ï¼Œå¦åˆ™è¿”回 TRUE
}
@@ -153,3 +217,38 @@
    return static_cast<HCURSOR>(m_hIcon);
}
void CEAPSimulatorDlg::AppendLog(int level, const char* pszText)
{
    if (!::IsWindow(m_logEdit.m_hWnd)) {
        return;
    }
    m_logEdit.AppendText(pszText);
}
void CEAPSimulatorDlg::OnDestroy()
{
    CDialogEx::OnDestroy();
    ASSERT(m_pObserver != NULL);
    m_pObserver->unsubscribe();
    m_pObserver = NULL;
}
void CEAPSimulatorDlg::OnBnClickedButtonConnect()
{
    CString strIp;
    UINT port;
    GetDlgItemText(IDC_EDIT_IP, strIp);
    port = GetDlgItemInt(IDC_EDIT_PORT);
    theApp.m_model.connectEq((LPTSTR)(LPCTSTR)strIp, port);
    GetDlgItem(IDC_EDIT_IP)->EnableWindow(FALSE);
    GetDlgItem(IDC_EDIT_PORT)->EnableWindow(FALSE);
    GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(FALSE);
}
void CEAPSimulatorDlg::OnBnClickedButtonDisconnect()
{
    theApp.m_model.disconnect();
}
SourceCode/Bond/EAPSimulator/EAPSimulatorDlg.h
@@ -3,6 +3,7 @@
//
#pragma once
#include "LogEdit.h"
// CEAPSimulatorDlg å¯¹è¯æ¡†
@@ -11,6 +12,11 @@
// æž„造
public:
    CEAPSimulatorDlg(CWnd* pParent = nullptr);    // æ ‡å‡†æž„造函数
private:
    void AppendLog(int level, const char* pszText);
    void InitRxWindow();
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
@@ -24,6 +30,8 @@
// å®žçް
protected:
    HICON m_hIcon;
    CLogEdit m_logEdit;
    IObserver* m_pObserver;
    // ç”Ÿæˆçš„æ¶ˆæ¯æ˜ å°„函数
    virtual BOOL OnInitDialog();
@@ -31,4 +39,8 @@
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnDestroy();
    afx_msg void OnBnClickedButtonConnect();
    afx_msg void OnBnClickedButtonDisconnect();
};
SourceCode/Bond/EAPSimulator/Log.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,214 @@
#include "pch.h"
#include "Log.h"
static const char* pszLevel[] = {" [Debug] ", " [Info] ", " [Warn] ", " [Error] "};
CLog::CLog()
{
    m_nLevel = 0;
    m_nOutputTarget = OT_TRACE;
    m_bAutoAppendTime = TRUE;
    m_strEquipmentId = _T("Unknown");
    m_nDay = 0;
    m_funOnLog = nullptr;
    InitializeCriticalSection(&m_criticalSection);
}
CLog::~CLog()
{
    DeleteCriticalSection(&m_criticalSection);
}
CLog *CLog::GetLog(void)
{
    static CLog* pLog = NULL;
    if (pLog == NULL) {
        static CLog log;
        pLog = &log;
    }
    return pLog;
}
void CLog::SetOnLogCallback(ONLOG funOnLog)
{
    m_funOnLog = funOnLog;
}
void CLog::SetOutputTarget(int flag)
{
    m_nOutputTarget = flag;
}
void CLog::SetEquipmentId(const char* pszEquipmentId)
{
    m_strEquipmentId = pszEquipmentId;
}
void CLog::SetAutoAppendTimeString(BOOL bAutoAppendTime)
{
    m_bAutoAppendTime = bAutoAppendTime;
}
void CLog::Batch()
{
    if (m_file.m_hFile != CFile::hFileNull) {
        m_file.Close();
    }
}
BOOL CLog::BatchAndNew(int& nDay)
{
    Batch();
    if ( (m_nOutputTarget & OT_FILE) && m_file.m_hFile == CFile::hFileNull) {
        CString strFilepath;
        BOOL bRet = m_file.Open(MakeFilepathD(strFilepath, nDay), CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::shareDenyWrite);
        if (bRet) {
            m_file.SeekToEnd();
        }
        return bRet;
    }
    return FALSE;
}
#define BUFFERSIZE        1024*10
void CLog::LogFormat(int nLevel, const char* pszTag, char* szMessage, ...)
{
    // æ£€æŸ¥æ—¥æœŸæ˜¯å¦æœ‰å˜åŒ–,有变化则结批
    Lock();
    _SYSTEMTIME sysTime;
    GetLocalTime(&sysTime);
    if(m_nDay != sysTime.wDay) {
        int nDay = 0;
        if (BatchAndNew(nDay)) {
            m_nDay = nDay;
        }
    }
    Unlock();
    if (nLevel < m_nLevel) {
        return;
    }
    char szFullMessage[BUFFERSIZE];
    char szFormatMessage[BUFFERSIZE];
    // format message
    va_list ap;
    va_start(ap, szMessage);
    _vsnprintf_s(szFormatMessage, BUFFERSIZE, szMessage, ap);
    va_end(ap);
    if (m_bAutoAppendTime) {
        CString strTime;
        strcpy_s(szFullMessage, BUFFERSIZE, (LPTSTR)(LPCTSTR)GetCurTime(strTime));
    }
    strcat_s(szFullMessage, BUFFERSIZE, pszLevel[nLevel]);
    strcat_s(szFullMessage, szFormatMessage);
    strcat_s(szFullMessage, BUFFERSIZE, "\n");
    if (m_nOutputTarget & OT_FILE) {
        Lock();
        if (m_file.m_hFile != CFile::hFileNull) {
            m_file.WriteString(szFullMessage);
        }
        Unlock();
    }
    if (m_nOutputTarget & OT_ODSTRING) {
        OutputDebugStringA(szFullMessage);
    }
    else if(m_nOutputTarget & OT_TRACE) {
        TRACE(szFormatMessage);
    }
    if (m_funOnLog != nullptr) {
        m_funOnLog(nLevel, szFullMessage);
    }
}
void CLog::Log(int nLevel, const char* pszTag, const char* szMessage)
{
    // æ£€æŸ¥æ—¥æœŸæ˜¯å¦æœ‰å˜åŒ–,有变化则结批
    Lock();
    _SYSTEMTIME sysTime;
    GetLocalTime(&sysTime);
    if (m_nDay != sysTime.wDay) {
        int nDay = 0;
        if (BatchAndNew(nDay)) {
            m_nDay = nDay;
        }
    }
    Unlock();
    if (nLevel < m_nLevel) {
        return;
    }
    CString strMsg;
    if (m_bAutoAppendTime) {
        CString strTime;
        GetCurTime(strTime);
        strMsg.Append(strTime);
    }
    strMsg.Append(pszTag);
    strMsg.Append(szMessage);
    strMsg.Append("\n");
    if (m_nOutputTarget & OT_FILE) {
        Lock();
        if (m_file.m_hFile != CFile::hFileNull) {
            m_file.WriteString(strMsg);
        }
        Unlock();
    }
    if (m_nOutputTarget & OT_ODSTRING) {
        OutputDebugStringA(strMsg);
    }
    else if (m_nOutputTarget & OT_TRACE) {
        TRACE(strMsg);
    }
    if (m_funOnLog != nullptr) {
        m_funOnLog(nLevel, strMsg);
    }
}
CString& CLog::GetCurTime(CString& strTime)
{
    _SYSTEMTIME sysTime;
    GetLocalTime(&sysTime);
    strTime.Format(_T("%d/%02d/%02d %02d:%02d:%02d.%03d"), sysTime.wYear, sysTime.wMonth, sysTime.wDay,
        sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds);
    return strTime;
}
CString& CLog::MakeFilepath(CString& strFilepath)
{
    _SYSTEMTIME sysTime;
    GetLocalTime(&sysTime);
    strFilepath.Format(_T("%s\\Log(%s)_%d_%02d_%02d.log"), (LPTSTR)(LPCTSTR)m_strLogsDir,
        (LPTSTR)(LPCTSTR)m_strEquipmentId,
        sysTime.wYear, sysTime.wMonth, sysTime.wDay);
    return strFilepath;
}
CString& CLog::MakeFilepathD(CString& strFilepath, int& day)
{
    _SYSTEMTIME sysTime;
    GetLocalTime(&sysTime);
    strFilepath.Format(_T("%s\\Log(%s)_%d_%02d_%02d.log"), (LPTSTR)(LPCTSTR)m_strLogsDir,
        (LPTSTR)(LPCTSTR)m_strEquipmentId,
        sysTime.wYear, sysTime.wMonth, sysTime.wDay);
    day = sysTime.wDay;
    return strFilepath;
}
void CLog::SetLogsDir(CString strDir)
{
    m_strLogsDir = strDir;
}
SourceCode/Bond/EAPSimulator/Log.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
#pragma once
#include <functional>
#define LEVEL_DEBUG        0
#define LEVEL_INFO        1
#define LEVEL_WARN        2
#define LEVEL_ERROR        3
#define LOGD(msg, ...)        CLog::GetLog()->LogFormat(LEVEL_DEBUG, "", msg, __VA_ARGS__)
#define LOGI(msg, ...)        CLog::GetLog()->LogFormat(LEVEL_INFO, "", msg, __VA_ARGS__)
#define LOGW(msg, ...)        CLog::GetLog()->LogFormat(LEVEL_WARN, "", msg, __VA_ARGS__)
#define LOGE(msg, ...)        CLog::GetLog()->LogFormat(LEVEL_ERROR, "", msg, __VA_ARGS__)
#define OT_FILE            0x01
#define OT_ODSTRING        0x02
#define OT_TRACE        0x04
#define LOGBATHCH()                CLog::GetLog()->Batch()
#define LOGNEW()                CLog::GetLog()->BatchAndNew()
typedef std::function<void(int level, const char* pszMessage)> ONLOG;
class CLog
{
public:
    CLog();
    ~CLog();
public:
    void SetOnLogCallback(ONLOG funOnLog);
    static CLog *GetLog(void);
    void SetOutputTarget(int flag);
    void SetEquipmentId(const char* pszEquipmentId);
    static CString& GetCurTime(CString& strTime);
    CString& MakeFilepath(CString& strFilepath);
    CString& MakeFilepathD(CString& strFilepath, int& day);
    void LogFormat(int nLevel, const char* pszTag, char* szMessage, ...);
    void Log(int nLevel, const char* pszTag, const char* szMessage);
    void SetAutoAppendTimeString(BOOL bAutoAppendTime);
    void SetLogsDir(CString strDir);
    void Batch();
    BOOL BatchAndNew(int& nDay);
private:
    inline void Lock() { EnterCriticalSection(&m_criticalSection); }
    inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
private:
    ONLOG m_funOnLog;
    int m_nOutputTarget;
    int m_nLevel;
    BOOL m_bAutoAppendTime;
    CString m_strLogsDir;
    CString m_strEquipmentId;
    CStdioFile m_file;
    int m_nDay;                        // æŒ‰æ—¥ä¿å­˜ä¸€æ¡è®°å½•,比较此数字,以决定是否结批并创建新文件
    CRITICAL_SECTION m_criticalSection;
};
SourceCode/Bond/EAPSimulator/LogEdit.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
#include "pch.h"
#include "LogEdit.h"
#define MENU_ITEM_SEL_ALL        0x666
#define MENU_ITEM_COPY            0x667
#define MENU_ITEM_CLEAR            0x668
CLogEdit::CLogEdit()
{
    m_nMaxLines = 0xffff;
    m_nTrimLines = 100;
    m_bAutoScroll = TRUE;
}
CLogEdit::~CLogEdit()
{
}
BEGIN_MESSAGE_MAP(CLogEdit, CEdit)
    ON_WM_CONTEXTMENU()
    ON_WM_VSCROLL()
    ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()
void CLogEdit::SetMaxLineCount(int line)
{
    m_nMaxLines = line;
    m_nTrimLines = min(m_nMaxLines, 4000);
}
void CLogEdit::OnContextMenu(CWnd* pWnd, CPoint point)
{
    HMENU hMenu = CreatePopupMenu();
    InsertMenu(hMenu, 0, MF_BYPOSITION, MENU_ITEM_SEL_ALL, "ȫѡ");
    InsertMenu(hMenu, 1, MF_BYPOSITION, MENU_ITEM_COPY, "复制");
    InsertMenu(hMenu, 2, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);
    InsertMenu(hMenu, 3, MF_BYPOSITION, MENU_ITEM_CLEAR, "全部清除");
    int cmd = ::TrackPopupMenu(hMenu,
        TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
        point.x, point.y + 2, 0, m_hWnd, NULL);
    DestroyMenu(hMenu);
    if (cmd == MENU_ITEM_SEL_ALL) {
        SetFocus();
        this->SetSel(0, -1);
    }
    else if (cmd == MENU_ITEM_COPY) {
        this->Copy();
    }
    else if (cmd == MENU_ITEM_CLEAR) {
        SetWindowText(_T(""));
    }
}
void CLogEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // æ¯æ¬¡æ»šåŠ¨æ—¶æ£€æŸ¥æ˜¯å¦è¿˜åœ¨åº•éƒ¨
    m_bAutoScroll = IsScrollBarAtBottom();
    CEdit::OnVScroll(nSBCode, nPos, pScrollBar);
}
BOOL CLogEdit::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
    // æ¯æ¬¡æ»šåŠ¨æ—¶æ£€æŸ¥æ˜¯å¦è¿˜åœ¨åº•éƒ¨
    m_bAutoScroll = IsScrollBarAtBottom();
    return CEdit::OnMouseWheel(nFlags, zDelta, pt);
}
BOOL CLogEdit::IsScrollBarAtBottom()
{
    SCROLLINFO si = { sizeof(si), SIF_ALL };
    GetScrollInfo(SB_VERT, &si);
    return (si.nPos + (int)si.nPage >= si.nMax);
}
void CLogEdit::AppendText(const char* pszText)
{
    SetRedraw(FALSE);
    // å‰ªåˆ‡è¿‡å¤šè¡Œ
    int totalLines = GetLineCount();
    if (totalLines > m_nMaxLines) {
        int startChar = LineIndex(0);
        int endChar = LineIndex(m_nTrimLines);
        if (startChar >= 0 && endChar > startChar) {
            SetSel(startChar, endChar);
            ReplaceSel(_T(""));
        }
    }
    // ä¿å­˜å½“前选择
    int start, end;
    GetSel(start, end);
    bool hasSelection = (start != end);
    int endPos = GetWindowTextLength();
    SetSel(endPos, endPos);
    ReplaceSel(pszText);
    if (m_bAutoScroll && !hasSelection) {
        LineScroll(GetLineCount());
    }
    // æ¢å¤é€‰æ‹©
    if (hasSelection) {
        SetSel(start, end);
    }
    SetRedraw(TRUE);
    if (m_bAutoScroll && !hasSelection) {
        Invalidate();
        UpdateWindow();
    }
}
SourceCode/Bond/EAPSimulator/LogEdit.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
#pragma once
#include "afxwin.h"
class CLogEdit :
    public CEdit
{
public:
    CLogEdit();
    ~CLogEdit();
public:
    void SetMaxLineCount(int line);
    void AppendText(const char* pszText);
    BOOL IsScrollBarAtBottom();
private:
    int m_nMaxLines;
    int m_nTrimLines;
    BOOL m_bAutoScroll;        // æ˜¯å¦è‡ªåŠ¨æ»šåŠ¨
    DECLARE_MESSAGE_MAP()
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
public:
    afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
};
SourceCode/Bond/EAPSimulator/Resource.h
@@ -1,21 +1,25 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ ç”Ÿæˆçš„包含文件。
// ç”± EAPSimulator.rc ä½¿ç”¨
// ä¾› EAPSimulator.rc ä½¿ç”¨
//
#define IDR_MAINFRAME                    128
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_EAPSIMULATOR_DIALOG                102
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_EAPSIMULATOR_DIALOG         102
#define IDR_MAINFRAME                   128
#define IDC_EDIT_LOG                    1000
#define IDC_EDIT_IP                     1001
#define IDC_EDIT_PORT                   1002
#define IDC_BUTTON_CONNECT              1003
#define IDC_BUTTON_DISCONNECT           1004
// æ–°å¯¹è±¡çš„下一组默认值
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE    129
#define _APS_NEXT_CONTROL_VALUE        1000
#define _APS_NEXT_SYMED_VALUE        101
#define _APS_NEXT_COMMAND_VALUE        32771
#define _APS_NEXT_RESOURCE_VALUE        129
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1005
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
SourceCode/Bond/EAPSimulator/res/EAPSimulator.ico

SourceCode/Bond/HSMSSDK/Include/HSMSSDK.h
@@ -1,6 +1,7 @@
#pragma once
#include <functional>
#include "IPassive.h"
#include "IActive.h"
#include "IMessage.h"
@@ -62,7 +63,10 @@
    int                EXPORTED    HSMS_Term();
    int                EXPORTED    HSMS_CreatePassive(OUT IPassive*& pPassive, const char* pName, const unsigned int nPort);
    int                EXPORTED    HSMS_DestroyPassive(IPassive* pPassive);
    int                EXPORTED    HSMS_CreateActive(OUT IActive*& pAcitve, const char* pName, const char* pszIp, const unsigned int nPort);
    int                EXPORTED    HSMS_DestroyActive(IActive* pAcitve);
    int                EXPORTED    HSMS_Create1Message(OUT IMessage*& pMessage, unsigned short sessionId, BYTE stream, BYTE function, unsigned int nSystemBytes);
    int                EXPORTED    HSMS_CreateMessageWithSType(OUT IMessage*& pMessage, BYTE sType, unsigned int nSystemBytes);
    int                EXPORTED    HSMS_Destroy1Message(IMessage* pMessage);
#ifdef __cplusplus
SourceCode/Bond/HSMSSDK/Include/IActive.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
#pragma once
#include <functional>
#include "IMessage.h"
enum class ACTIVESTATE
{
    NOT_CONNECTED = 0,
    NOT_SELECTED = 1,
    SELECTED = 2
};
typedef std::function<void(void* pFrom, ACTIVESTATE state)> ONACTIVESTATECHANGED;
typedef std::function<void(void* pFrom, const char* pszData, int size)> ONRECVRAWDATA;
typedef std::function<void(void* pFrom, IMessage* pMessage)> ONRECVDATAMSG;
typedef std::function<void(void* pFrom, IMessage* pMessage)> ONRECVSYSMSG;
typedef std::function<void(void* pFrom, int error)> ONDATAERROR;
typedef struct _ActiveListener
{
    ONACTIVESTATECHANGED    funStateChanged;
    ONRECVRAWDATA            funRecvRawData;
    ONRECVDATAMSG            funRecvDataMessage;
    ONRECVSYSMSG            funRecvSysMessage;
    ONDATAERROR                funError;
} ActiveListener;
class IActive
{
public:
    virtual void setListener(ActiveListener listener) = 0;
    virtual void setTimeout3(int timeout) = 0;
    virtual void setTimeout5(int timeout) = 0;
    virtual void setTimeout6(int timeout) = 0;
    virtual void setTimeout7(int timeout) = 0;
    virtual void setTimeout8(int timeout) = 0;
    virtual int sendMessage(IMessage* pMessage) = 0;
    virtual ACTIVESTATE getState() = 0;
    virtual int connect() = 0;
    virtual int disconnect() = 0;
};
SourceCode/Bond/Servo/CMyStatusbar.cpp
@@ -75,6 +75,11 @@
    SetDlgItemText(IDC_BUTTON_ROBOTTASK, pszText);
}
void CMyStatusbar::setCimBtnText(const char* pszText)
{
    SetDlgItemText(IDC_BUTTON_CIM, pszText);
}
BOOL CMyStatusbar::OnInitDialog()
{
    CDialogEx::OnInitDialog();
@@ -87,6 +92,11 @@
    m_btnCurTask.SetFrameColor(BS_HOVER, RGB(218, 218, 218));
    m_btnCurTask.SetFrameColor(BS_PRESS, RGB(168, 168, 168));
    m_btnCim.SubclassDlgItem(IDC_BUTTON_CIM, this);
    m_btnCim.SetFaceColor(m_crBkgnd);
    m_btnCim.SetFrameColor(m_crBkgnd);
    m_btnCim.SetFrameColor(BS_HOVER, RGB(218, 218, 218));
    m_btnCim.SetFrameColor(BS_PRESS, RGB(168, 168, 168));
    return TRUE;  // return TRUE unless you set the focus to a control
                  // å¼‚常: OCX å±žæ€§é¡µåº”返回 FALSE
@@ -129,6 +139,11 @@
        pItem->GetWindowRect(rcItem);
        GetParent()->SendMessage(ID_MSG_STATUSBAR_BTN_CLICKED, rcItem.left, LOWORD(wParam));
        break;
    case IDC_BUTTON_CIM:
        pItem = GetDlgItem(IDC_BUTTON_CIM);
        pItem->GetWindowRect(rcItem);
        GetParent()->SendMessage(ID_MSG_STATUSBAR_BTN_CLICKED, rcItem.left, LOWORD(wParam));
        break;
    }
    return CDialogEx::OnCommand(wParam, lParam);
@@ -165,4 +180,16 @@
    pItem->GetClientRect(rcItem);
    pItem->MoveWindow(x, (rcClient.Height() - rcItem.Height()) / 2, rcItem.Width(), rcItem.Height());
    x += rcItem.Width();
    x += 8;
    pItem = GetDlgItem(IDC_LABEL_CIM);
    pItem->GetClientRect(rcItem);
    pItem->MoveWindow(x, (rcClient.Height() - rcItem.Height()) / 2, rcItem.Width(), rcItem.Height());
    x += rcItem.Width();
    x += 8;
    pItem = GetDlgItem(IDC_BUTTON_CIM);
    pItem->GetClientRect(rcItem);
    pItem->MoveWindow(x, (rcClient.Height() - rcItem.Height()) / 2, rcItem.Width(), rcItem.Height());
    x += rcItem.Width();
}
SourceCode/Bond/Servo/CMyStatusbar.h
@@ -21,6 +21,7 @@
    void setForegroundColor(COLORREF cr);
    void setRunTimeText(const char* pszText);
    void setCurTaskBtnText(const char* pszText);
    void setCimBtnText(const char* pszText);
private:
    void Resize();
@@ -30,6 +31,7 @@
    COLORREF m_crBkgnd;
    CBrush m_brBkgnd;
    CBlButton m_btnCurTask;
    CBlButton m_btnCim;
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -499,7 +499,7 @@
    pList->addItem(m_strEquipmentModelType.c_str(), "MDLN");
    pList->addItem(m_strSoftRev.c_str(), "SOFTREV");
    m_pPassive->sendMessage(pMessage);
    LOGI("<HSMS>[SECS Msg SEND]S1F14 (SysByte=%u)", pMessage->getHeader()->systemBytes);
    LOGI("<HSMS>[SECS Msg SEND]%s", pMessage->toString());
    HSMS_Destroy1Message(pMessage);
    return 0;
SourceCode/Bond/Servo/Servo.rc
Binary files differ
SourceCode/Bond/Servo/Servo.vcxproj.user
@@ -7,6 +7,6 @@
    <RemoteDebuggerCommand>\\DESKTOP-IODBVIQ\Servo\Debug\Servo.exe</RemoteDebuggerCommand>
    <RemoteDebuggerWorkingDirectory>\\DESKTOP-IODBVIQ\Servo\Debug\</RemoteDebuggerWorkingDirectory>
    <RemoteDebuggerServerName>DESKTOP-IODBVIQ</RemoteDebuggerServerName>
    <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
</Project>
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -241,7 +241,26 @@
                    }
                }
            }
            if (RX_CODE_PASSIVE_STATUS_CHANGED == code) {
                int state = 0;
                pAny->getIntValue("exCode", state);
                if (STATE::NOT_CONNECTED == state) {
                    m_pMyStatusbar->setCimBtnText("Disconnected");
                    //m_labelPassiveState.setBackground(DISCONNECTED_BACKGROUND);
                    //m_labelPassiveState.setForeground(DISCONNECTED_FOREGROUND, TRUE);
                }
                else if (STATE::NOT_SELECTED == state) {
                    m_pMyStatusbar->setCimBtnText("Not Selected");
                    //m_labelPassiveState.setBackground(NOT_SELECTED_BACKGROUND);
                    //m_labelPassiveState.setForeground(NOT_SELECTED_FOREGROUND, TRUE);
                }
                else if (STATE::SELECTED == state) {
                    m_pMyStatusbar->setCimBtnText("Selected");
                    //m_labelPassiveState.setBackground(SELECTED_BACKGROUND);
                    //m_labelPassiveState.setForeground(SELECTED_FOREGROUND, TRUE);
                }
            }
            pAny->release();
        }, [&]() -> void {
            // onComplete
@@ -981,6 +1000,9 @@
        m_pRobotTaskDlg->MoveWindow(x, rcBar.top - h, w, h);
        m_pRobotTaskDlg->ShowWindow(SW_SHOW);
    }
    else if (id == IDC_BUTTON_CIM) {
        AfxMessageBox("IDC_BUTTON_CIM");
    }
    return 0;
}
SourceCode/Bond/Servo/resource.h
Binary files differ