1. 优化设备配方绑定界面;
2. 获取设备的配方列表,并显示在下拉框中。
已修改3个文件
238 ■■■■ 文件已修改
SourceCode/Bond/Servo/RecipeDeviceBindDlg.cpp 233 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/RecipeDeviceBindDlg.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/RecipeDeviceBindDlg.cpp
@@ -47,6 +47,97 @@
    m_recipe = info;
}
void CRecipeDeviceBindDlg::ReleaseDeviceControls()
{
    for (auto& ctrl : m_vecDevices) {
        delete ctrl.editDeviceID;    ctrl.editDeviceID = nullptr;
        delete ctrl.editDeviceName;  ctrl.editDeviceName = nullptr;
        delete ctrl.comboRecipeID;   ctrl.comboRecipeID = nullptr;
    }
    m_vecDevices.clear();
}
void CRecipeDeviceBindDlg::CreateDeviceControls(int nXStart, int nYStart, int nTotalControlWidth, int nRowHeight)
{
    for (size_t i = 0; i < g_vecBindDevices.size(); ++i) {
        int y = nYStart + static_cast<int>(i) * nRowHeight;
        auto* pEditID = new CEdit;
        pEditID->Create(WS_CHILD | WS_VISIBLE | WS_BORDER | ES_CENTER, CRect(nXStart, y, nXStart + 100, y + 25), this, (UINT)(IDC_EDIT_DEVICEID_BASE + i));
        pEditID->SetFont(&m_font);
        auto* pEditName = new CEdit;
        pEditName->Create(WS_CHILD | WS_VISIBLE | WS_BORDER | ES_CENTER, CRect(nXStart + 110, y, nXStart + 210, y + 25), this, (UINT)(IDC_EDIT_DEVICENAME_BASE + i));
        pEditName->SetFont(&m_font);
        auto* pCombo = new CComboBox;
        pCombo->Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, CRect(nXStart + 220, y, nXStart + nTotalControlWidth, y + 25), this, (UINT)(IDC_COMBO_RECIPEID_BASE + i));
        pCombo->SetFont(&m_font);
        m_vecDevices.push_back({ pEditID, pEditName, pCombo });
    }
}
bool CRecipeDeviceBindDlg::FillComboRecipeList(CComboBox* pCombo, int nDeviceID, int nSelectedRecipeID)
{
    auto& master = theApp.m_model.getMaster();
    auto* pEq = master.getEquipment(nDeviceID);
    if (!pEq) {
        return false;
    }
    auto* pRecipeList = pEq->getRecipeList(0);
    if (!pRecipeList) {
        return false;
    }
    auto& mapRecipeIds = pRecipeList->getIds();
    bool bFound = false;
    pCombo->ResetContent();
    for (const auto& pair : mapRecipeIds) {
        int nRecipeID = pair.second;
        CString strRecipeName;
        strRecipeName.Format(_T("%d"), nRecipeID);
        int idx = pCombo->AddString(strRecipeName);
        pCombo->SetItemData(idx, nRecipeID);
        if (nSelectedRecipeID == nRecipeID) {
            pCombo->SetCurSel(idx);
            bFound = true;
        }
    }
    if (nSelectedRecipeID != -1 && !bFound) {
        pCombo->SetCurSel(CB_ERR);
    }
    else if (pCombo->GetCount() > 0 && nSelectedRecipeID == -1) {
        pCombo->SetCurSel(0);
    }
    return true;
}
bool CRecipeDeviceBindDlg::FillDeviceInfo(int idx, int nDeviceID, const CString& strDeviceName, int nSelectedRecipeID)
{
    if (idx < 0 || idx >= (int)m_vecDevices.size()) {
        return false;
    }
    auto& ctrl = m_vecDevices[idx];
    CString strID;
    strID.Format(_T("%d"), nDeviceID);
    ctrl.editDeviceID->SetWindowText(strID);
    ctrl.editDeviceID->SetReadOnly(TRUE);
    ctrl.editDeviceName->SetWindowText(strDeviceName);
    ctrl.editDeviceName->SetReadOnly(TRUE);
    if (!FillComboRecipeList(ctrl.comboRecipeID, nDeviceID, nSelectedRecipeID)) {
        CString str;
        str.Format(_T("设备 [%s] 或其配方列表未找到,请检查设备配置"), strDeviceName.GetString());
        AfxMessageBox(str);
        return false;
    }
    return true;
}
void CRecipeDeviceBindDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
@@ -70,134 +161,60 @@
    // 设置对话框标题
    SetWindowText(m_recipe.vecDeviceList.empty() ? _T("新建配方") : _T("编辑配方"));
    if (m_font.m_hObject == NULL) {
        // 获取对话框的字体
    // 创建动态控件字体
    if (!m_font.m_hObject) {
        CFont* pDlgFont = GetFont();
        LOGFONT lf;
        if (pDlgFont && pDlgFont->GetLogFont(&lf)) {
            lf.lfHeight = -16;
            m_font.CreateFontIndirect(&lf);
        }
    }
    // 计算x起始坐标
    CWnd* pWndDesc = GetDlgItem(IDC_STATIC_DESC);
    // 计算坐标
    CRect rDesc;
    int nYStart = 0;
    int nXStart = 0;
    int nTotalControlWidth = 340; // 默认兜底
    if (pWndDesc) {
        pWndDesc->GetWindowRect(&rDesc);
        ScreenToClient(&rDesc);
    int nXStart = 30, nYStart = 30, nTotalControlWidth = 340;
    if (auto* pWndDesc = GetDlgItem(IDC_STATIC_DESC)) {
        pWndDesc->GetWindowRect(&rDesc); ScreenToClient(&rDesc);
        nXStart = rDesc.left;
    }
    else {
        nXStart = 30;
    }
    // 计算x起始坐标
    pWndDesc = GetDlgItem(IDC_EDIT_DESC);
    if (pWndDesc) {
        pWndDesc->GetWindowRect(&rDesc);
        ScreenToClient(&rDesc);
    if (auto* pWndEdit = GetDlgItem(IDC_EDIT_DESC)) {
        pWndEdit->GetWindowRect(&rDesc); ScreenToClient(&rDesc);
        nYStart = rDesc.bottom + 20;
    }
    else {
        nYStart = 30;
    }
    // 保证每次进来都清空
    for (auto& ctrl : m_vecDevices) {
        if (ctrl.editDeviceID) {
            delete ctrl.editDeviceID;
            ctrl.editDeviceID = nullptr;
        }
        if (ctrl.editDeviceName) {
            delete ctrl.editDeviceName;
            ctrl.editDeviceName = nullptr;
        }
        if (ctrl.comboRecipeID) {
            delete ctrl.comboRecipeID;
            ctrl.comboRecipeID = nullptr;
        }
    }
    m_vecDevices.clear();
    // 创建控件(不管新建还是编辑,都先创建好)
    CRect rClient;
    GetClientRect(&rClient);
    nTotalControlWidth = (rClient.Width() - nXStart * 2);
    CRect rClient; GetClientRect(&rClient);
    nTotalControlWidth = rClient.Width() - nXStart * 2;
    const int nRowHeight = 30;
    const int nRowCount = static_cast<int>(g_vecBindDevices.size());
    for (int i = 0; i < nRowCount; ++i) {
        int y = nYStart + i * nRowHeight;
        const auto& meta = g_vecBindDevices[i];
        CEdit* pEditID = new CEdit();
        pEditID->Create(WS_CHILD | WS_VISIBLE | WS_BORDER, CRect(nXStart, y, nXStart + 100, y + 25), this, IDC_EDIT_DEVICEID_BASE + i);
    // 清空旧控件
    ReleaseDeviceControls();
        CEdit* pEditName = new CEdit();
        pEditName->Create(WS_CHILD | WS_VISIBLE | WS_BORDER, CRect(nXStart + 110, y, nXStart + 210, y + 25), this, IDC_EDIT_DEVICENAME_BASE + i);
    // 创建新控件
    CreateDeviceControls(nXStart, nYStart, nTotalControlWidth, nRowHeight);
        CComboBox* pCombo = new CComboBox();
        pCombo->Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, CRect(nXStart + 220, y, nXStart + nTotalControlWidth, y + 25), this, IDC_COMBO_RECIPEID_BASE + i);
        pEditID->SetFont(&m_font);
        pEditName->SetFont(&m_font);
        pCombo->SetFont(&m_font);
        m_vecDevices.push_back({ pEditID, pEditName, pCombo });
    }
    auto& master = theApp.m_model.getMaster();
    // 填充内容
    if (m_recipe.vecDeviceList.empty()) {
        // 新建模式
        for (int i = 0; i < nRowCount; ++i) {
    if (m_recipe.vecDeviceList.empty()) {
        // 新建
        for (size_t i = 0; i < g_vecBindDevices.size(); ++i) {
            const auto& meta = g_vecBindDevices[i];
            CString strID;
            strID.Format(_T("%d"), meta.nDeviceID);
            m_vecDevices[i].editDeviceID->SetWindowText(strID);
            m_vecDevices[i].editDeviceID->SetReadOnly(TRUE);
            m_vecDevices[i].editDeviceName->SetWindowText(CA2T(meta.strDeviceName));
            m_vecDevices[i].editDeviceName->SetReadOnly(TRUE);
            // 这里你可以初始化 ComboBox 选项,例如:
            // for (const auto& r : GetRecipeListForDevice(meta.nDeviceID)) {
            //     int idx = m_vecDevices[i].comboRecipeID->AddString(CA2T(r.strRecipeName));
            //     m_vecDevices[i].comboRecipeID->SetItemData(idx, r.nRecipeID);
            // }
            FillDeviceInfo((int)i, meta.nDeviceID, meta.strDeviceName);
        }
    }
    else {
        // 编辑模式
    else {
        // 编辑
        m_strPPID = CA2T(m_recipe.strPPID.c_str());
        m_strDesc = CA2T(m_recipe.strDescription.c_str());
        UpdateData(FALSE);
        for (size_t i = 0; i < m_recipe.vecDeviceList.size() && i < m_vecDevices.size(); ++i) {
            const DeviceRecipe& d = m_recipe.vecDeviceList[i];
            CString str;
            // 设备ID
            str.Format(_T("%d"), d.nDeviceID);
            m_vecDevices[i].editDeviceID->SetWindowText(str);
            m_vecDevices[i].editDeviceID->SetReadOnly(TRUE);
            // 设备名称
            m_vecDevices[i].editDeviceName->SetWindowText(CA2T(d.strDeviceName.c_str()));
            m_vecDevices[i].editDeviceName->SetReadOnly(TRUE);
            // ComboBox 选项填充
            // for (const auto& r : GetRecipeListForDevice(d.nDeviceID)) {
            //     int idx = m_vecDevices[i].comboRecipeID->AddString(CA2T(r.strRecipeName));
            //     m_vecDevices[i].comboRecipeID->SetItemData(idx, r.nRecipeID);
            //     // 默认选中对应配方ID
            //     if (r.nRecipeID == d.nRecipeID)
            //         m_vecDevices[i].comboRecipeID->SetCurSel(idx);
            // }
            const auto& d = m_recipe.vecDeviceList[i];
            FillDeviceInfo((int)i, d.nDeviceID, d.strDeviceName.c_str(), d.nRecipeID);
        }
    }
    CenterWindow();
    return TRUE;  // return TRUE unless you set the focus to a control
    // 异常: OCX 属性页应返回 FALSE
@@ -209,21 +226,7 @@
    CDialogEx::OnClose();
    // 清理控件
    for (auto& device : m_vecDevices) {
        if (device.editDeviceID) {
            device.editDeviceID->DestroyWindow();
            delete device.editDeviceID;
        }
        if (device.editDeviceName) {
            device.editDeviceName->DestroyWindow();
            delete device.editDeviceName;
        }
        if (device.comboRecipeID) {
            device.comboRecipeID->DestroyWindow();
            delete device.comboRecipeID;
        }
    }
    m_vecDevices.clear();
    ReleaseDeviceControls();
}
void CRecipeDeviceBindDlg::OnSize(UINT nType, int cx, int cy)
SourceCode/Bond/Servo/RecipeDeviceBindDlg.h
@@ -29,6 +29,11 @@
    DECLARE_MESSAGE_MAP()
private:
    void ReleaseDeviceControls();
    void CreateDeviceControls(int nXStart, int nYStart, int nTotalControlWidth, int nRowHeight);
    bool FillDeviceInfo(int idx, int nDeviceID, const CString& strDeviceName, int nSelectedRecipeID = -1);
    bool FillComboRecipeList(CComboBox* pCombo, int nDeviceID, int nSelectedRecipeID = -1);
    struct DeviceWidget {
        CEdit* editDeviceID;
        CEdit* editDeviceName;
SourceCode/Bond/Servo/Servo.rc
Binary files differ