chenluhua1980
2025-12-10 f71f467b68ce6c8dc6c983a2963ec9b131515441
1.实现删除变量的功能;
已修改8个文件
193 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CHMPropertyDlg.cpp 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CHMPropertyDlg.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CHMPropertyPage.cpp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CHMPropertyPage.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageVarialbles.cpp 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageVarialbles.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/HsmsPassive.cpp 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/HsmsPassive.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CHMPropertyDlg.cpp
@@ -5,6 +5,7 @@
#include "Servo.h"
#include "CHMPropertyDlg.h"
#include "afxdialogex.h"
#include <algorithm>
// CEquipmentDlg 对话框
@@ -159,11 +160,11 @@
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow(x2 - rcItem.Width(), y2 - rcItem.Height(),
        rcItem.Width(), rcItem.Height());
    y2 -= rcItem.Height() + 12;
    // 当前子页按钮(如果有)
    int btnY = y2 - rcItem.Height(); // 保持与应用按钮同高
    int btnY = y2 - rcItem.Height();
    int btnX = 12;
    y2 -= rcItem.Height() + 12;
    int curIndex = (m_pTab != nullptr) ? m_pTab->GetCurSel() : 0;
    if (curIndex >= 0 && curIndex < (int)m_pages.size()) {
        auto& btnMap = m_pages[curIndex]->getBtns();
@@ -284,3 +285,22 @@
        }
    }
}
BOOL CHMPropertyDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
    UINT code = HIWORD(wParam);
    HWND hCtrl = (HWND)lParam;
    if (code == BN_CLICKED && hCtrl != nullptr) {
        for (auto page : m_pages) {
            for (auto& kv : page->getBtns()) {
                if (kv.second != nullptr && kv.second->GetSafeHwnd() == hCtrl) {
                    page->HandleBtnClick(hCtrl);
                    return TRUE;
                }
            }
        }
    }
    return CDialogEx::OnCommand(wParam, lParam);
}
SourceCode/Bond/Servo/CHMPropertyDlg.h
@@ -51,4 +51,5 @@
    afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result);
    afx_msg void OnBnClickedOk();
    afx_msg void OnBnClickedButtonApply();
    virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
};
SourceCode/Bond/Servo/CHMPropertyPage.cpp
@@ -58,6 +58,16 @@
    return m_btns;
}
void CHMPropertyPage::HandleBtnClick(HWND hBtn)
{
    for (auto& kv : m_btns) {
        if (kv.second != nullptr && kv.second->GetSafeHwnd() == hBtn) {
            OnClickedBtn(kv.first.c_str());
            break;
        }
    }
}
BEGIN_MESSAGE_MAP(CHMPropertyPage, CDialogEx)
    ON_WM_DESTROY()
END_MESSAGE_MAP()
SourceCode/Bond/Servo/CHMPropertyPage.h
@@ -14,6 +14,11 @@
    afx_msg void OnDestroy();
    std::map<std::string, CButton*>& getBtns();
    CButton* GetBtnByName(const char* name);
    void HandleBtnClick(HWND hBtn);
protected:
    // 子类可重写:新增/删除/编辑按钮点击处理
    virtual void OnClickedBtn(const char* btnName) {};
protected:
    CButton* CreateBtn(const char* name, int w, int h, const UINT id);
SourceCode/Bond/Servo/CPageVarialbles.cpp
@@ -32,6 +32,7 @@
    ON_WM_CTLCOLOR()
    ON_WM_DESTROY()
    ON_WM_SIZE()
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CPageVarialbles::OnLvnItemchangedList1)
END_MESSAGE_MAP()
@@ -139,3 +140,45 @@
    CreateBtn(_T("删除"), BTN_W, BTN_H, 1002)->EnableWindow(FALSE);
    CreateBtn(_T("编辑"), BTN_W, BTN_H, 1003)->EnableWindow(FALSE);
}
void CPageVarialbles::OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    int nSelCount = m_listCtrl.GetSelectedCount();
    // 根据选中状态启用/禁用按钮
    if (CButton* pDel = GetBtnByName("删除")) {
        pDel->EnableWindow(nSelCount > 0);
    }
    if (CButton* pEdit = GetBtnByName("编辑")) {
        pEdit->EnableWindow(nSelCount > 0);
    }
    *pResult = 0;
}
void CPageVarialbles::OnClickedBtn(const char* btnName)
{
    ASSERT(btnName);
    if (_strcmpi(btnName, "新增") == 0) {
        // TODO: 新增逻辑
    }
    else if (_strcmpi(btnName, "删除") == 0) {
        POSITION pos = m_listCtrl.GetFirstSelectedItemPosition();
        if (pos == nullptr) return;
        int nItem = m_listCtrl.GetNextSelectedItem(pos);
        auto pVar = reinterpret_cast<SERVO::CVariable*>(m_listCtrl.GetItemData(nItem));
        if (pVar == nullptr) return;
        int ret = theApp.m_model.m_hsmsPassive.deleteVariable(pVar->getVarialbleId());
        if (ret == 0) {
            m_listCtrl.DeleteAllItems();
            loadVariables();
            if (CButton* pDel = GetBtnByName("删除")) pDel->EnableWindow(FALSE);
            if (CButton* pEdit = GetBtnByName("编辑")) pEdit->EnableWindow(FALSE);
        }
    }
    else if (_strcmpi(btnName, "编辑") == 0) {
        // TODO: 编辑逻辑
    }
}
SourceCode/Bond/Servo/CPageVarialbles.h
@@ -19,6 +19,9 @@
private:
    CListCtrlEx m_listCtrl;
protected:
    virtual void OnClickedBtn(const char* btnName) override;
// 对话框数据
#ifdef AFX_DESIGN_TIME
@@ -34,4 +37,5 @@
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg void OnDestroy();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult);
};
SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -228,6 +228,9 @@
int CHsmsPassive::loadVarialbles(const char* pszFilepath)
{
    m_strVariableFilepath = pszFilepath;
    m_bVariableUtf8 = false;
    m_bVariableUtf8Bom = false;
    // 先读原始字节,后续再按 UTF-8/BOM 或本地编码转换
    CFile file;
    if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) {
@@ -251,6 +254,8 @@
    // UTF-8 BOM
    if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
        offset = 3;
        m_bVariableUtf8 = true;
        m_bVariableUtf8Bom = true;
    }
    // UTF-16 LE BOM
@@ -281,6 +286,7 @@
            MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off,
                static_cast<int>(buffer.size() - off), temp.data(), need);
            content = temp.c_str();
            m_bVariableUtf8 = true;
            return true;
        };
@@ -397,6 +403,102 @@
    m_variabels.clear();
}
CStringA WideToUtf8(const CStringW& ws)
{
    int need = WideCharToMultiByte(CP_UTF8, 0, ws, -1, nullptr, 0, nullptr, nullptr);
    if (need <= 0) return "";
    CStringA out;
    LPSTR buf = out.GetBufferSetLength(need - 1);
    WideCharToMultiByte(CP_UTF8, 0, ws, -1, buf, need, nullptr, nullptr);
    out.ReleaseBuffer();
    return out;
}
CStringA WideToAnsi(const CStringW& ws)
{
    int need = WideCharToMultiByte(CP_ACP, 0, ws, -1, nullptr, 0, nullptr, nullptr);
    if (need <= 0) return "";
    CStringA out;
    LPSTR buf = out.GetBufferSetLength(need - 1);
    WideCharToMultiByte(CP_ACP, 0, ws, -1, buf, need, nullptr, nullptr);
    out.ReleaseBuffer();
    return out;
}
static CStringA AnsiToUtf8(const std::string& s)
{
    int wlen = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, nullptr, 0);
    if (wlen <= 0) return "";
    CStringW ws;
    LPWSTR wbuf = ws.GetBufferSetLength(wlen - 1);
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, wbuf, wlen);
    ws.ReleaseBuffer();
    return WideToUtf8(ws);
}
int CHsmsPassive::deleteVariable(int variableId)
{
    Lock();
    auto it = std::find_if(m_variabels.begin(), m_variabels.end(), [=](SERVO::CVariable* v) {
        return v != nullptr && v->getVarialbleId() == variableId;
        });
    if (it == m_variabels.end()) {
        Unlock();
        return -1;
    }
    delete *it;
    m_variabels.erase(it);
    auto filepath = m_strVariableFilepath;
    Unlock();
    if (filepath.empty()) return -2;
    // 写回文件,保持原编码(UTF-8 或本地编码)
    CFile file;
    if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) {
        return -3;
    }
    // header
    const std::string headerAnsi = "SVID,SV Name,SV Format,SV Remark\r\n";
    if (m_bVariableUtf8) {
        if (m_bVariableUtf8Bom) {
            const BYTE bom[3] = { 0xEF, 0xBB, 0xBF };
            file.Write(bom, 3);
        }
        CStringA header = AnsiToUtf8(headerAnsi);
        file.Write(header.GetString(), header.GetLength());
    }
    else {
        file.Write(headerAnsi.data(), (UINT)headerAnsi.size());
    }
    for (auto v : m_variabels) {
        if (v == nullptr) continue;
        std::string lineAnsi;
        lineAnsi.reserve(256);
        lineAnsi += std::to_string(v->getVarialbleId());
        lineAnsi.push_back(',');
        lineAnsi += v->getName();
        lineAnsi.push_back(',');
        lineAnsi += SERVO::CVariable::formatToString(v->getFormat());
        lineAnsi.push_back(',');
        lineAnsi += v->getRemark();
        lineAnsi.append("\r\n");
        if (m_bVariableUtf8) {
            CStringA outLine = AnsiToUtf8(lineAnsi);
            file.Write(outLine.GetString(), outLine.GetLength());
        }
        else {
            file.Write(lineAnsi.data(), (UINT)lineAnsi.size());
        }
    }
    file.Close();
    return 0;
}
void CHsmsPassive::setVariableValue(const char* pszName, __int64 value)
{
    auto v = getVariable(pszName);
SourceCode/Bond/Servo/HsmsPassive.h
@@ -146,6 +146,7 @@
    // 取得指定Variable
    SERVO::CVariable* getVariable(int variableId);
    SERVO::CVariable* getVariable(const char* pszName);
    int deleteVariable(int variableId);
    // 设置变量值
    void setVariableValue(const char* pszName, __int64 value);
@@ -251,6 +252,9 @@
private:
    SECSListener m_listener;
    std::string m_strVariableFilepath;
    bool m_bVariableUtf8{ false };
    bool m_bVariableUtf8Bom{ false };
    BOOL m_bCimWorking;
    HANDLE m_hCimWorkEvent;
    HANDLE m_hCimWorkThreadHandle;