LAPTOP-SNT8I5JK\Boounion
2025-09-04 1efb832676e8ad27e7a495dba6ffc19479e0c76f
SourceCode/Bond/Servo/PageRecipe.cpp
@@ -5,8 +5,8 @@
#include "Servo.h"
#include "afxdialogex.h"
#include "PageRecipe.h"
#include "MsgDlg.h"
#include "RecipeDeviceBindDlg.h"
// CPageRecipe 对话框
@@ -160,8 +160,9 @@
   m_listPPID.SetColumnWidth(nColCount - 1, LVSCW_AUTOSIZE_USEHEADER);
}
void CPageRecipe::FillRecipeListToListCtrl(SERVO::CRecipeList* pList)
void CPageRecipe::FillRecipeListToListCtrl(SERVO::CEquipment* pEq)
{
   SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
   CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_PPID);
   if (pListCtrl == nullptr || !::IsWindow(pListCtrl->m_hWnd)) {
      return;
@@ -169,16 +170,23 @@
   // 清空当前CListCtrl中的所有项
   pListCtrl->DeleteAllItems();
   if (pList == nullptr) {
   if (pRecipeList == nullptr) {
      return;
   }
   // 遍历数据并插入到CListCtrl中
   std::map<int, short>& ids = pList->getIds();
   std::map<int, short>& ids = pRecipeList->getIds();
   auto rawDatas = pRecipeList->getParamsRawData();
   for (auto item : ids) {
      int index = m_listPPID.InsertItem(m_listPPID.GetItemCount(), _T(""));
      m_listPPID.SetItemText(index, 1, std::to_string(item.first).c_str());
      m_listPPID.SetItemText(index, 2, std::to_string(item.second).c_str());
      auto iter = rawDatas.find(item.second);
      if (iter != rawDatas.end()) {
         std::string strDescription;
         pEq->parsingParams((const char*)iter->second.data(), iter->second.size(), strDescription);
      }
   }
   // 获取列数
@@ -338,8 +346,12 @@
               pEq[i] == nullptr ? _T("Master") : pEq[i]->getName().c_str());
            pComboBox->SetItemDataPtr(i, pEq[i]);
            // 读取回来
            char szBuffer[_MAX_PATH];
            if (pEq[i]) {
               pEq[i]->masterRecipeListRequest(0, nullptr);
               sprintf_s(szBuffer, _MAX_PATH, "%s\\Recipe\\EQ%d_Unit0.recipelist", (LPTSTR)(LPCTSTR)theApp.m_strAppDir, pEq[i]->getID());
               std::string strFilepath(szBuffer);
               pEq[i]->readRecipeList(0, strFilepath);
            }
         }
         pComboBox->SetCurSel(0);
@@ -486,32 +498,11 @@
      FillDataToListCtrl(vecData);
   }
   else {
      // enable port
      CMsgDlg msgDlg("请等待", "正在获取配方...");
      pEq->masterRecipeListRequest(0, [&, pEq](int status) -> void {
         if (status == SS_FAILED || status == SS_TIMEOUT) {
            CString strMsg;
            strMsg.Format(status == SS_FAILED ? _T("获取配方失败!") : _T("获取配方超时!"));
            msgDlg.DelayClose(3000);
            msgDlg.SetIcon(MSG_BOX_ERROR);
            msgDlg.SetTitle(_T("操作失败"));
            msgDlg.SetMessage((LPTSTR)(LPCTSTR)strMsg);
            msgDlg.SetMarquee(FALSE, 0);
            msgDlg.SetCompleteCode(-1);
         }
         else if (status == SS_COMPLETE) {
            CString strMsg;
            strMsg.Format(_T("获取配方完成!"));
            msgDlg.DelayClose(3000);
            msgDlg.SetIcon(MSG_BOX_SUCCEED);
            msgDlg.SetTitle(_T("操作成功"));
            msgDlg.SetMessage((LPTSTR)(LPCTSTR)strMsg);
            msgDlg.SetMarquee(FALSE, 0);
            msgDlg.SetCompleteCode(0);
            SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
            FillRecipeListToListCtrl(pRecipeList);
         }
      });
      // 获取配方列表
      CMsgDlg msgDlg("请等待", "正在获取配方列表...");
      msgDlg.SetData((DWORD_PTR)this);
      msgDlg.SetDataEx((DWORD_PTR)pEq);
      msgDlg.BeginThread(SyncThreadFunction);
      msgDlg.DoModal();
   }
}
@@ -552,7 +543,131 @@
   }
   else {
      InitListCtrlHeaderForDevice();
      SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
      FillRecipeListToListCtrl(pRecipeList);
      FillRecipeListToListCtrl(pEq);
   }
}
UINT CPageRecipe::SyncThreadFunction(LPVOID lpvData)
{
   CMsgDlg* pMsgDlg = (CMsgDlg*)lpvData;
   CPageRecipe* pPageRecipe = (CPageRecipe*)pMsgDlg->GetData();
   return pPageRecipe->SyncThreadFunctionInner(pMsgDlg);
}
UINT CPageRecipe::SyncThreadFunctionInner(CMsgDlg* pMsgDlg)
{
   SERVO::CEquipment* pEq = (SERVO::CEquipment*)pMsgDlg->GetDataEx();
   HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
   int nStep = 0;
   // 准备配方路径
   char szBuffer[_MAX_PATH];
   sprintf_s(szBuffer, _MAX_PATH, "%s\\Recipe\\EQ%d_Unit0.recipelist", (LPTSTR)(LPCTSTR)theApp.m_strAppDir, pEq->getID());
   std::string strFilepath(szBuffer);
   pEq->masterRecipeListRequest(0, [&, pEq, pMsgDlg, hEvent](int status) -> void {
      Sleep(300);
      if (status == SS_FAILED || status == SS_TIMEOUT) {
         CString strMsg;
         strMsg.Format(status == SS_FAILED ? _T("获取配方列表失败!") : _T("获取配方列表超时!"));
         pMsgDlg->SetIcon(MSG_BOX_ERROR);
         pMsgDlg->SetTitle(_T("操作失败"));
         pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
         SetEvent(hEvent);
      }
      else if (status == SS_LIST_COMPLETE) {
         CString strMsg;
         strMsg.Format(_T("获取配方列表完成!"));
         pMsgDlg->SetTitle(_T("操作成功"));
         pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
         SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
         if (pRecipeList != nullptr && !pRecipeList->getIds().empty()) {
            nStep = 1;
         }
         SetEvent(hEvent);
      }
   });
   ::WaitForSingleObject(hEvent, INFINITE);
   if (nStep != 1) {
      pEq->saveRecipeList(0, strFilepath);
      pMsgDlg->SetIcon(MSG_BOX_SUCCEED);
      pMsgDlg->SetMarquee(FALSE, 0);
      pMsgDlg->SetCompleteCode(-1);
      pMsgDlg->DelayClose(3000);
   }
   ResetEvent(hEvent);
   // 参数列表
   if (nStep == 1) {
      SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
      ASSERT(pRecipeList);
      auto& ids = pRecipeList->getIds();
      pMsgDlg->SetTitle(_T("正在获取参数"));
      for (auto item : ids) {
         int recipeId = item.second;
         CString strMsg;
         strMsg.Format(_T("正在获取配方 %d 参数..."), item.second);
         pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
         pEq->recipeParameterRequest(0, recipeId, 0, [&, pEq, pMsgDlg, recipeId, hEvent](int status) -> void {
            Sleep(500);
            if (status == SS_FAILED || status == SS_TIMEOUT) {
               CString strMsg;
               strMsg.Format(status == SS_FAILED ? _T("获取配方 %d 参数失败!") : _T("获取配方 %d 参数超时!"), recipeId);
               pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
               Sleep(30);
               SetEvent(hEvent);
            }
            else if (status == SS_PARAMS_COMPLETE) {
               CString strMsg;
               strMsg.Format(_T("获取配方 %d 参数完成!"), item.second);
               pMsgDlg->SetMessage((LPTSTR)(LPCTSTR)strMsg);
               Sleep(30);
               SetEvent(hEvent);
            }
            });
         ::WaitForSingleObject(hEvent, INFINITE);
         ResetEvent(hEvent);
      }
      pEq->saveRecipeList(0, strFilepath);
      pMsgDlg->SetIcon(MSG_BOX_SUCCEED);
      pMsgDlg->SetTitle(_T("操作完成"));
      pMsgDlg->SetCompleteCode(0);
      pMsgDlg->SetMarquee(FALSE, 0);
      pMsgDlg->DelayClose(3000);
   };
   FillRecipeListToListCtrl(pEq);
   CloseHandle(hEvent);
   // 在此打印配方参数以便核对数据
   SERVO::CRecipeList* pRecipeList = pEq->getRecipeList(0);
   ASSERT(pRecipeList);
   auto rawDatas = pRecipeList->getParamsRawData();
   for (auto item : rawDatas) {
      TRACE("================= 配方 %d\n", item.first);
      std::vector<CParam> params;
      pEq->parsingParams((const char*)item.second.data(), item.second.size(), params);
      for (auto p : params) {
         if (p.getValueType() == PVT_INT) {
            TRACE("%s: %d\n", p.getName().c_str(), p.getIntValue());
         }
         else if (p.getValueType() == PVT_DOUBLE) {
            TRACE("%s: %f\n", p.getName().c_str(), p.getDoubleValue());
         }
      }
   }
   return 0;
}