zxd
2023-10-21 89cd7441c184d37f90d4d5311b348e938119765f
MTerm1/MTerm1View.cpp
@@ -1155,6 +1155,7 @@
            nCol = 0; 
         }
      }
      CellFocusChg(nRow, nCol);
   }
   if (nChar == VK_RIGHT) {
      nCol += 1;
@@ -1167,15 +1168,17 @@
            nCol = m_CellPerLine - 1;
         }
      }
      CellFocusChg(nRow, nCol);
   }
   if (nChar == VK_UP) {
      nRow -= 1;
      if (nRow < 0) { nRow = 0; }
      CellFocusChg(nRow, nCol);
   }
   if (nChar == VK_DOWN) {
      nRow += 1;
      if (nRow >= m_nTotalRow + nLinesinView) { nRow = m_nTotalRow + nLinesinView -1; }
      CellFocusChg(nRow, nCol);
   }
   m_FocusRow = nRow;
   m_FocusCol = nCol;
@@ -1485,16 +1488,16 @@
void CMTerm1View::OnProgConvert()
{
   //转换前先对LDS的规则进行检验(检验规则与返回参数并未完全确定
    std::pair<int,CString> result = LDSCheckRule();
   if (result.first == 111)
   {
      DbgLog(result.second);
      return;
   }
 //   std::pair<int,CString> result = LDSCheckRule();
   //if (result.first == 111)
   //{
   //   DbgLog(result.second);
   //   return;
   //}
   CString s1;
   s1.Format(_T("Prog Convert"));
   SysLog(s1);
    SysLog(s1);
   int r = TransLDSToProg();
   s1.Format(_T("LDS To Prog result %d"), r);
   SysLog(s1);
@@ -1591,6 +1594,12 @@
/// <param name="cell1"></param>
void CMTerm1View::SetCellToView(stCell cell1, int flag)               //**************************************************************************************************//
{
   bool changeVLine = false;
   if ((Cells[m_FocusRow][m_FocusCol].bLeftLineDn != cell1.bLeftLineDn)
      || (Cells[m_FocusRow][m_FocusCol].bLeftLineUp != cell1.bLeftLineUp))
   {
      changeVLine = true;
   }
   Cells[m_FocusRow][m_FocusCol] = cell1;
   m_bModified = 1;
   needReDraw = 1;
@@ -1614,6 +1623,7 @@
      }
      //添加纵线时同步添加上一行
      Cells[m_FocusRow - 1][m_FocusCol].bLeftLineDn = 1;
   }break;
   case 2:
   {
@@ -1625,13 +1635,18 @@
      }
      //删除纵线时同步删除上一行
      Cells[m_FocusRow - 1][m_FocusCol].bLeftLineDn = 0;
   }break;
   default:
      break;
   }
   //单元格位置后移
   m_FocusCol += 1;
   //如果变化的是竖线,焦点不后移
   if (!changeVLine)
   {
      //单元格位置后移
      m_FocusCol += 1;
   }
   if (m_FocusCol >= 16) 
   { 
      m_FocusCol = 0;
@@ -1951,6 +1966,9 @@
   POINT StPts[100];
   //   StPts[0] = POINT{ 0, 0 };
   POINT EndPt[100];
   POINT StrPt[100];
   int nStrPts = 0;
   int nEndPts = 0;
   nSts = 0;
   int nCurLine = 0;
@@ -2048,9 +2066,16 @@
               }
               else if (nPairOp == 0) 
               {
                  nCurLine = maxy + 1; //另起一行
                  maxy = nCurLine;
                  cx = 0; cy = nCurLine;
                  if (i > 0 && nOp == pDoc->Progs[i-1].nOpType1)//如果前面也是ST,那就不换行
                  {
                  }
                  else
                  {
                     nCurLine = ++maxy;
                     cx = 0;
                     cy = nCurLine;
                  }
               }
            }
            stpos[nSts] = i;
@@ -2306,57 +2331,73 @@
            cx++;
            break;
         case OP_ANS:
            //ANS说明是有环路,整行进行移动(向右)从后向前进行移动
            EndPt[nEndPts].y;
            for (int i = EndPt[nEndPts-1].x ; i > 0; i--)
            {
               for (int j = EndPt[nEndPts].x; j >= 0; j--)
               {
                  if (j > 0
                     && Cells[cy + 1][j-1].nType == typeNone
                     || Cells[cy + 1][j - 1].nType == typeLine1
                     || Cells[cy + 1][j - 1].nType == typeLine2)
                  {
                     continue;
                  }
                  Cells[cy + 1][j] = Cells[cy + 1][j - 1];
               }
            }
            Cells[EndPt[nEndPts].y][EndPt[nEndPts-1].x].bLeftLineDn = 1;
            Cells[EndPt[nEndPts].y+1][EndPt[nEndPts-1].x].bLeftLineUp = 1;
            nSts--;
            nEndPts--;
            break;
         case OP_ORS:
            //当前序列与前面的序列合并。
            //当前序列的开始结束位置
            //EndPt[nEndPts] = POINT{ cx,cy };
            //nEndPts++;
            //StPts[nSts - 1]; EndPt[nEndPts - 1];
            //前一序列的开始结束位置
            StPts[nSts - 1];
            EndPt[nEndPts - 1];
            if (nEndPts <= 0)
            {
               break;
            }
            ////判断二者长度
            //if (cx < EndPt[nEndPts - 1].x)
            //{
            //   //本行补齐
            //   for (int j = cx; j < EndPt[nEndPts - 1].x; j++)
            //   {
            //      Cells[cy][j].nType = typeLine1;
            //   }
            //   cx = EndPt[nEndPts - 1].x;
            //}
            //else
            //{
            //   //前一行补齐
            //   for (int j = EndPt[nEndPts - 1].x; j < cx; j++)
            //   {
            //      Cells[EndPt[nEndPts - 1].y][j].nType = typeLine1;
            //   }
            //}
            ////连接上下线
            //for (int j = EndPt[nEndPts - 1].y; j < cy; j++)
            //{
            //   Cells[j][cx].bLeftLineDn = 1;
            //   Cells[j + 1][cx].bLeftLineUp = 1;
            //}
            ////光标位置, 前一结束点位置
            //cy = EndPt[nEndPts - 1].y;
            //判断二者长度
            if (cx < EndPt[nEndPts - 1].x)
            {
               //本行补齐
               for (int j = cx; j < EndPt[nEndPts - 1].x; j++)
               {
                  Cells[cy][j].nType = typeLine1;
               }
               cx = EndPt[nEndPts - 1].x;
            }
            else
            {
               //前一行补齐
               for (int j = EndPt[nEndPts - 1].x; j < cx; j++)
               {
                  if (Cells[EndPt[nEndPts - 1].y][j].nType == typeNone)
                  {
                     Cells[EndPt[nEndPts - 1].y][j].nType = typeLine1;
                  }
               }
            }
            //连接上下线
            Cells[cy][cx].bLeftLineUp = 1;
            Cells[cy-1][cx].bLeftLineDn = 1;
            //光标位置, 前一结束点位置
            nSts--;
            nEndPts--;
            cy = EndPt[nEndPts].y;
            cx = EndPt[nEndPts].x;
            break;
         case OP_PSHS:
            EndPt[nEndPts] = POINT{ cx,cy };
            nEndPts++;
            StrPt[nStrPts] = POINT{ EndPt[nEndPts].x,EndPt[nEndPts].y+1 };
            nStrPts++;
            break;
         case OP_RDS:
            cx = EndPt[nEndPts - 1].x;
@@ -2373,20 +2414,9 @@
            }
            break;
         case OP_POPS:
            cx = EndPt[nEndPts - 1].x;
            for (int j = cx; j < m_CellPerLine; j++) {
               if (Cells[cy][j].nType != 0)
               {
                  cy++; j = cx - 1; break;
               }
            }
            for (int j = EndPt[nEndPts - 1].y; j < cy; j++)
            {
               Cells[j][cx].bLeftLineDn = 1;
               Cells[j + 1][cx].bLeftLineUp = 1;
            }
            nEndPts--;
            nStrPts--;
            cy = StrPt[nStrPts].y;
            cx = StrPt[nStrPts].x;
            break;
         case OP_OUT:
         case OP_SET:
@@ -2528,7 +2558,7 @@
   return 0;
}
bool firstCoil = true;//本段第一个单元格
bool isPops = false;
/// <summary>
/// 梯形图转Prog
/// </summary>
@@ -2586,7 +2616,7 @@
      {
         nStartLine = 0; 
         nEndLine = Divs[i]; 
      }
       }
      else 
      {
         nStartLine = Divs[i - 1]+1;
@@ -2665,13 +2695,21 @@
         {
            firstCoil = true;
            //循环遍历单元格(转换的逻辑在这个函数)
            ScanLDSCells(nStartLine, nEndLine, nCurPosY, nCurPosX, 0, thisprogsec, sProgSec, nSteps);
            //ScanLDSCells(nStartLine, nEndLine, nCurPosY, nCurPosX, 0, thisprogsec, sProgSec, nSteps);
            //ScanLDSCells2(nStartLine, nEndLine, nCurPosY, nCurPosX, 0, thisprogsec, sProgSec, nSteps);
         }
         sProg += sProgSec;
          nAllSteps += nSteps;
         Progsec += thisprogsec;
         //sProg += sProgSec;
       //   nAllSteps += nSteps;
         //Progsec += thisprogsec;
      }
      CString sProgSec;
      int nSteps = 0;;
      nCurPosY = i;
      stProgSection thisprogsec;
      ScanLDSCells2(nStartLine, nEndLine, nCurPosY, nCurPosX, 16,0, thisprogsec, sProgSec, nSteps);
      sProg += sProgSec;
      nAllSteps += nSteps;
      Progsec += thisprogsec;
      DbgLog(_T("\r\n")+ sProg);
      int n = int(Progsec.Progs.size());
      s1.Format(_T("程序段步数: %d "), n);
@@ -2702,7 +2740,7 @@
   for (int i = 0; i < n; i++)   
   {
      int optype=allprogs.Progs[i].nOpType1;
      allprogs.Progs[i].PairTo = 0;
      allprogs.Progs[i].PairTo = 0;//??????????
      allprogs.Progs[i].nBinStep = i;
      CStringA OpTxtA,OpShowTxtA;
      CString OpTxt,OpShowTxt;
@@ -2736,7 +2774,7 @@
{
   CString s1;
   int nCurPosX, nCurPosY;
   int nNextX = 1;//步长
   int nNextX = 1;//步长(下个起始点移动的距离)
   nCurPosY = nPosY;
   nCurPosX = nPosX;
   int nCoilType, CoilAddr;
@@ -2744,7 +2782,7 @@
   for (int j = nPosX; j < m_CellPerLine; j += nNextX)
   {
      nCurPosX = j;
      //先处理当前单元;
      //先处理当前单元基本信息;
      int nType = Cells[nCurPosY][nCurPosX].nType;
      CString sCellName = Cells[nCurPosY][nCurPosX].sCoilName;
      CMTerm1Doc::stProg theprog;
@@ -2761,30 +2799,28 @@
         || Cells[nCurPosY][j + nNextX].bLeftLineDn)
      {
         ////先看往上面有没有连接
         //if (Cells[nCurPosY][j + nNextX].bLeftLineUp)
         //{
         //   // 往上面有连接且有触点连接,才使用ORS
         //   s1.Format(_T("%d %d ORS "), nCurPosY, nCurPosX);
         //   DbgLog(s1);
         //   theprog.nOpType1 = OP_ORS;
         //   //theprog.nOpType1 = OP_ST;
         //   //theprog.PairTo = OP_ORS;
         //   progsec.Append(theprog);
         //   sProgSec.AppendFormat(_T("ORS \r\n"));
         //   firstCoil = false;
         //   nSteps += 1;
         //   nLevel -= 1;
         //}
         //左上是否有链接
         //先看往上面有没有连接
         if (Cells[nCurPosY][j + nNextX].bLeftLineUp)
         {
            // 往上面有连接且有触点连接,才使用ORS
            s1.Format(_T("%d %d ORS "), nCurPosY, nCurPosX);
            DbgLog(s1);
            theprog.nOpType1 = OP_ORS;
            progsec.Append(theprog);
            sProgSec.AppendFormat(_T("ORS \r\n"));
            firstCoil = false;
            nSteps += 1;
            nLevel -= 1;
         }
         //右侧一格的左上是否有链接
         int nLeftUpCon = 0;
         if (Cells[nCurPosY][j + nNextX].bLeftLineUp)
         {
            nLeftUpCon = 1;
         }
         //向下查找,看看竖线的左侧下面还有没有连接其他东西
         int nLeftDnCon = 0;//单元格左侧向下连接数
         for (int k = nCurPosY + 1; k <= nEndLine; k++)
         //向下查找,看看竖线的右侧一格的左侧下面还有没有连接其他东西
         int nLeftDnCon = 0;//单元格右侧一格的左侧向下连接数
         for (int k = nCurPosY; k <= nEndLine; k++)
         {
            if (Cells[k][j + nNextX].bLeftLineDn)
            {
@@ -2802,12 +2838,12 @@
         s1.Format(_T("LeftUp %d   LeftDn  %d"), nLeftUpCon, nLeftDnCon);
         DbgLog(s1);
         //左侧下面有连接,那么扫描到这个竖线时返回,继续扫描左侧下面的内容。
         //右侧一格的左侧下面有连接,那么扫描到这个竖线时返回,继续扫描左侧下面的内容。
         if (nLeftDnCon)
         {
            return 1;
         }
         // 左侧下面没有连接,那么这个就是左面最后的单元,开始处理右面的单元。
         //右侧一格的左侧下面没有连接,那么这个就是左面最后的单元,开始处理右面的单元。
         else
         {
            if (nLeftUpCon)
@@ -2854,13 +2890,13 @@
            if (nRightCon == 1)
            {
               s1.Format(_T(">>>> Go %d : %d , level %d "), nLineTop, j + nNextX, nLevel);
                s1.Format(_T(">>>> Go %d : %d , level %d "), nLineTop, j + nNextX, nLevel);
               DbgLog(s1);
               CString ProgSec;
               int theSteps = 0;
               stProgSection thisprogsec;
               //
               //这有问题,应该是在最高点的时候,单独进行一次转换?
               int r = ScanLDSCells(nStartLine, nEndLine, nLineTop, j + nNextX, nLevel, thisprogsec, ProgSec, theSteps);
               sProgSec += ProgSec;
@@ -2868,6 +2904,7 @@
               progsec += thisprogsec;
               s1.Format(_T("<<<< Re %d : %d , Result %d "), nLineTop, j + nNextX, 0);
               DbgLog(s1);
               continue;
            }
            else
            {
@@ -2899,7 +2936,7 @@
                     DbgLog(s1);
                     if (nRightCount == 0)
                     {
                        //这里是不是应该做点什么
                     }
                     else if (res[nRightCount - 1] == 0)
                     {
@@ -2948,7 +2985,12 @@
            }
         }
      }
      //如果没有竖线直接翻译
      else
      {
         Translate2Prog(nType, j + nNextX, nLevel, sCellName, progsec, sProgSec, nSteps);
      }
      /*
      #pragma region  根据单元格类型转换为指令和prog
      if (nType == typeNO)
@@ -3180,253 +3222,371 @@
      }
      
      #pragma endregion
      */
   }
   return 0;
 }
 /*
 void CMTerm1View::chuansileitetoprog(int nStartLine, int nEndLine, int nPosY, int nPosX, int nLevel, stProgSection& progsec, CString& sProgSec, int& nSteps)
 {
    CString s1;
    int nCurPosX, nCurPosY;
    int nNextX = 1;//步长
    nCurPosY = nPosY;
    nCurPosX = nPosX;
    int nCoilType, CoilAddr;
    CMTerm1Doc* pDoc = GetDocument();
#pragma region  根据单元格类型转换为指令和prog
//   记录y,x
std::pair<int, int> popsPoint[100];      int nPSHS = -1;
int CMTerm1View::ScanLDSCells2(int nStartLine, int nEndLine, int nPosY, int nPosX, int nSizeX,
   int nLevel, stProgSection& progsec, CString& sProgSec, int& nSteps)
{
   CString s1;
   int nCurPosX, nCurPosY;
   int nNextX = 0;//步长(到下个线圈起始位置应移动距离
   nCurPosY = nStartLine;
   nCurPosX = nPosX;
   int nCoilType, CoilAddr;
   CMTerm1Doc* pDoc = GetDocument();
    if (nType == typeNO)
    {
       if (firstCoil && nType != typeLine1 && nType != typeLine2)
       {
          //先看往上面有没有连接
          if (Cells[nCurPosY][j + nNextX].bLeftLineUp)
          {
             // 往上面有连接且有触点连接,才使用OR
             s1.Format(_T("%d %d OR %s"), nCurPosY, nCurPosX, sCellName);
             sProgSec.AppendFormat(_T("OR %s\r\n"), sCellName);
               .nOpType1 = OP_OR;
          }
          else
          {
             s1.Format(_T("%d %d ST %s"), nCurPosY, nCurPosX, sCellName);
             sProgSec.AppendFormat(_T("ST %s\r\n"), sCellName);
             theprog.nOpType1 = OP_ST;
          }
          theprog.nParamCount = 1;
          pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
          theprog.Params[0].nParamType = nCoilType;
          theprog.Params[0].nParamAddr = CoilAddr;
          theprog.Params[0].sParamStr = sCellNameA;
          progsec.Append(theprog);
          firstCoil = false;
       }
       else
       {
          s1.Format(_T("%d %d AN %s"), nCurPosY, nCurPosX, sCellName);
          sProgSec.AppendFormat(_T("NO %s\r\n"), sCellName);
          theprog.nOpType1 = OP_AN;
          theprog.nParamCount = 1;
          pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
          theprog.Params[0].nParamType = nCoilType;
          theprog.Params[0].nParamAddr = CoilAddr;
          theprog.Params[0].sParamStr = sCellNameA;
          progsec.Append(theprog);
       }
       nSteps += 1;
       DbgLog(s1);
       nNextX = 1;
    }
    else if (nType == typeNC)
    {
       if (firstCoil && nType != typeLine1 && nType != typeLine2)
       {
          s1.Format(_T("%d %d ST/ %s"), nCurPosY, nCurPosX, sCellName);
          sProgSec.AppendFormat(_T("ST/ %s\r\n"), sCellName);
          theprog.nOpType1 = OP_ST_;
          theprog.nParamCount = 1;
          pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
          theprog.Params[0].nParamType = nCoilType;
          theprog.Params[0].nParamAddr = CoilAddr;
          theprog.Params[0].sParamStr = sCellNameA;
          progsec.Append(theprog);
          firstCoil = false;
       }
       else
       {
          s1.Format(_T("%d %d AN/ %s"), nCurPosY, nCurPosX, sCellName);
          sProgSec.AppendFormat(_T("AN/ %s\r\n"), sCellName);
          theprog.nOpType1 = OP_AN_;
          theprog.nParamCount = 1;
          pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
          theprog.Params[0].nParamType = nCoilType;
          theprog.Params[0].nParamAddr = CoilAddr;
          theprog.Params[0].sParamStr = sCellNameA;
          progsec.Append(theprog);
       }
       DbgLog(s1);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typePP)
    {
       s1.Format(_T("%d %d PP %s"), nCurPosY, nCurPosX, sCellName);
       DbgLog(s1);
       //progsec.Append(theprog);
       sProgSec.AppendFormat(_T("PP %s\r\n"), sCellName);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typePN)
    {
       s1.Format(_T("%d %d PN %s"), nCurPosY, nCurPosX, sCellName);
       DbgLog(s1);
       //progsec.Append(theprog);
       sProgSec.AppendFormat(_T("PN %s\r\n"), sCellName, sCellName);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typeNOT)
    {
       s1.Format(_T("%d %d NOT %s"), nCurPosY, nCurPosX, sCellName);
       DbgLog(s1);
       sProgSec.AppendFormat(_T("NOT %s\r\n"), sCellName);
       theprog.nOpType1 = OP_NOT;
       progsec.Append(theprog);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typeDF)
    {
       s1.Format(_T("%d %d DF %s"), nCurPosY, nCurPosX, sCellName);
       DbgLog(s1);
       sProgSec.AppendFormat(_T("DF %s\r\n"), sCellName);
       theprog.nOpType1 = OP_DF;
       progsec.Append(theprog);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typeDF_)
    {
       s1.Format(_T("%d %d DF/ %s"), nCurPosY, nCurPosX, sCellName);
       DbgLog(s1);
       sProgSec.AppendFormat(_T("DF/ %s\r\n"), sCellName);
       theprog.nOpType1 = OP_DF_;
       progsec.Append(theprog);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typeOUT)
    {
       s1.Format(_T("%d %d OUT %s"), nCurPosY, nCurPosX, sCellName);
       DbgLog(s1);
       sProgSec.AppendFormat(_T("OUT %s\r\n"), sCellName);
       theprog.nOpType1 = OP_OUT;
       theprog.nParamCount = 1;
       pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
       theprog.Params[0].nParamType = nCoilType;
       theprog.Params[0].nParamAddr = CoilAddr;
       theprog.Params[0].sParamStr = sCellNameA;
       progsec.Append(theprog);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typeSET)
    {
       s1.Format(_T("%d %d SET %s"), nCurPosY, nCurPosX, sCellName);
       DbgLog(s1);
       sProgSec.AppendFormat(_T("SET %s\r\n"), sCellName);
       theprog.nOpType1 = OP_SET;
       theprog.nParamCount = 1;
       pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
       theprog.Params[0].nParamType = nCoilType;
       theprog.Params[0].nParamAddr = CoilAddr;
       theprog.Params[0].sParamStr = sCellNameA;
       progsec.Append(theprog);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typeRESET)
    {
       s1.Format(_T("%d %d RESET %s"), nCurPosY, nCurPosX, sCellName);
       DbgLog(s1);
       sProgSec.AppendFormat(_T("RESET %s\r\n"), sCellName);
       theprog.nOpType1 = OP_RESET;
       theprog.nParamCount = 1;
       pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
       theprog.Params[0].nParamType = nCoilType;
       theprog.Params[0].nParamAddr = CoilAddr;
       theprog.Params[0].sParamStr = sCellNameA;
       progsec.Append(theprog);
       nSteps += 1;
       nNextX = 1;
    }
    else if (nType == typeCMP)
    {
       s1.Format(_T("%d %d CMP %s %s %s"), nCurPosY, nCurPosX, sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
       DbgLog(s1);
       theprog.nOpType1 = OP_ST_GT;
       theprog.nParamCount = 1;
       progsec.Append(theprog);
       sProgSec.AppendFormat(_T("CMP %s %s %s \r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
       nSteps += 1;
       nNextX = 3;
    }
    else if (nType == typeTM)
    {
       s1.Format(_T("%d %d TM %s %d %s"), nCurPosY, nCurPosX, sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
       DbgLog(s1);
       theprog.nOpType1 = OP_TMX;
       theprog.nParamCount = 1;
       pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
       theprog.Params[0].nParamType = nCoilType;
       theprog.Params[0].nParamAddr = CoilAddr;
       theprog.Params[0].sParamStr = sCellNameA;
       progsec.Append(theprog);
       sProgSec.AppendFormat(_T("TM %s %d %s\r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
       nSteps += 1;
       nNextX = 3;
    }
    else if (nType == typeFN1)
    {
       s1.Format(_T("%d %d FN1 %s %s"), nCurPosY, nCurPosX, sCellName, Cells[nCurPosY][nCurPosX + 1].sParam);
       DbgLog(s1);
       theprog.nOpType1 = OP_INC;
       progsec.Append(theprog);
       sProgSec.AppendFormat(_T("FN1 %s %s\r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam);
       nSteps += 1;
       nNextX = 2;
    }
    else if (nType == typeFN2)
    {
       s1.Format(_T("%d %d FN2 %s %s %s "), nCurPosY, nCurPosX, sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
       DbgLog(s1);
       theprog.nOpType1 = OP_MV;
       progsec.Append(theprog);
       sProgSec.AppendFormat(_T("FN2 %s %s %s \r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
       nSteps += 1;
       nNextX = 3;
    }
    else if (nType == typeFN3)
    {
       s1.Format(_T("%d %d FN3 %s %s %s %s"), nCurPosY, nCurPosX, sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam, Cells[nCurPosY][nCurPosX + 3].sParam);
       DbgLog(s1);
       theprog.nOpType1 = OP_ADD3;
       progsec.Append(theprog);
       sProgSec.AppendFormat(_T("FN3 %s %s %s %s\r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam, Cells[nCurPosY][nCurPosX + 3].sParam);
       nSteps += 1;
       nNextX = 4;
    }
    else
    {
       nNextX = 1;
       //continue;
    }
   for (int j = nPosX; j < nSizeX; j += nNextX)
   {
      nCurPosX = j;
      //先处理当前单元;
      int nType = Cells[nCurPosY][nCurPosX].nType;
      CString sCellName = Cells[nCurPosY][nCurPosX].sCoilName;
      CMTerm1Doc::stProg theprog;
      CStringA sCellNameA;
      sCellNameA = sCellName;
      CString ProgSec;
      int theSteps = 0;
#pragma endregion
      stProgSection thisprogsec;
      //判断越界
      if (j + nNextX > m_CellPerLine)
      {
         continue;
      }
      //if (!firstCoil && Cells[nCurPosY][j].bLeftLineUp)
      //{
      //   break;
      //}
      if (Cells[nCurPosY][nCurPosX].nType == typeNone)
      {
         nNextX = 1;
         continue;
      }
      //开始翻译单个单元格,并返回下个单元格位置
      nNextX = Translate2Prog(nType, nCurPosY, nCurPosX, sCellName, progsec, sProgSec, nSteps);
      //1.判断此单元格右侧一格是否有向下的竖线
      if (Cells[nCurPosY][j + nNextX].bLeftLineDn)
      {
         //1.1:有分支,直接开始读取下一行
         if (Cells[nCurPosY +1][j].nType == typeNone)
         {
            if (Cells[nCurPosY + 1][j + nNextX].nType != typeNone)
            {
               firstCoil = true;
            }
            continue;
         }
         firstCoil = true;
         ScanLDSCells2(nCurPosY + 1, nCurPosY + 1, nCurPosY + 1, 0, j + nNextX, ++nLevel, thisprogsec, ProgSec, theSteps);
         //有OR关系且不只一个节点
         if (theSteps > 1 && nLevel > 0)
         {
            // 步数大于1,是复合结果,才使用ORS
            s1.Format(_T("%d %d ORS "), nCurPosY, nCurPosX);
            DbgLog(s1);
            theprog.nOpType1 = OP_ORS;
            //progsec.Append(theprog);
            //sProgSec.AppendFormat(_T("ORS \r\n"));
            thisprogsec.Append(theprog);
            ProgSec.AppendFormat(_T("ORS \r\n"));
            firstCoil = false;
            nSteps += 1;
         }
         //1.2:从后向前查找下一行是否还有向上的竖线(形成闭环)(ORS、ANS)
         for (int k = j; k >= 0; k--)
         {
            if (Cells[nCurPosY + 1][k].nType == typeNone)
            {
               //如果遇到空格,还没搜到,就结束搜索
               break;
            }
            if (Cells[nCurPosY+1][k].bLeftLineUp)
            {
               //如果有一条竖线,说明是形成了环,要用ANS
               if (theSteps >= 1 && nLevel > 0)
               {
                  //步数大于1,是复合结果,使用ANS
                  s1.Format(_T("%d %d ANS "), nCurPosY, nCurPosX);
                  DbgLog(s1);
                  theprog.nOpType1 = OP_ANS;
                  //progsec.Append(theprog);
                  //sProgSec.AppendFormat(_T("ANS \r\n"));
                  thisprogsec.Append(theprog);
                  ProgSec.AppendFormat(_T("ANS \r\n"));
                  nSteps += 1;
               }
            }
         }
         //将转换完成的部分加入到总集中
         nSteps += theSteps;
         progsec += thisprogsec;
         sProgSec += ProgSec;
         //1.3:查询此分支下一级连接点左右均存在节点,存在就PSHS
         if (Cells[nCurPosY + 1][j].nType != typeNone
            && Cells[nCurPosY + 1][j + 1].nType != typeNone)
         {
            ++nPSHS;
            CString push = _T("PSHS \r\n");
            theprog.nOpType1 = OP_PSHS;
            progsec.Append(theprog);
            sProgSec.Append(push);
            popsPoint[nPSHS] = std::make_pair(nCurPosY + 1, j + 1);
         }
      }//end  1.判断此单元格右侧一格是否有向下的竖线
   }
   nLevel--;
   //已回到起始层
   if (nLevel == 0)
   {
      CMTerm1Doc::stProg theprog;
      for (int i = nPSHS; i >= 0; i--)
      {
         //+POP
         CString pop = _T("POPS \r\n");
         theprog.nOpType1 = OP_POPS;
         progsec.Append(theprog);
         sProgSec.Append(pop);
         //+fanyi
         //开始翻译单个单元格,并返回下个单元格位置
         //firstCoil = true;
         ScanLDSCells2(popsPoint[nPSHS].first, popsPoint[nPSHS].first, popsPoint[nPSHS].first, popsPoint[nPSHS].second, 16, nLevel, progsec, sProgSec, nSteps);
         nPSHS--;
      }
      if (nPSHS == -1)
      {
         fill(popsPoint, popsPoint + 100, std::make_pair(0, 0));
      }
   }
   return 0;
}
*/
int CMTerm1View::Translate2Prog(
   int nType, int nCurPosY, int nCurPosX, CString sCellName,
   stProgSection& progsec, CString& sProgSec, int& nSteps)
{
   CString s1;
   int nNextX = 1;//步长
   int nCoilType, CoilAddr;
   CMTerm1Doc::stProg theprog;
   CMTerm1Doc* pDoc = GetDocument();
   CStringA sCellNameA;
   sCellNameA = sCellName;
   //if (nType == typeNone)
   //{
   //   return 0;
   //}
   if (nType == typeNO)
   {
      if (firstCoil && nType != typeLine1 && nType != typeLine2)
      {
         //先看往上面有没有连接
         if (Cells[nCurPosY][nCurPosX + nNextX].bLeftLineUp)
         {
            // 往上面有连接,使用OR
            sProgSec.AppendFormat(_T("OR %s\r\n"), sCellName);
            theprog.nOpType1 = OP_OR;
         }
         else
         {
            sProgSec.AppendFormat(_T("ST %s\r\n"), sCellName);
            theprog.nOpType1 = OP_ST;
         }
         theprog.nParamCount = 1;
         pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
         theprog.Params[0].nParamType = nCoilType;
         theprog.Params[0].nParamAddr = CoilAddr;
         theprog.Params[0].sParamStr = sCellNameA;
         progsec.Append(theprog);
         firstCoil = false;
      }
      else
      {
         sProgSec.AppendFormat(_T("AN %s\r\n"), sCellName);
         theprog.nOpType1 = OP_AN;
         theprog.nParamCount = 1;
         pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
         theprog.Params[0].nParamType = nCoilType;
         theprog.Params[0].nParamAddr = CoilAddr;
         theprog.Params[0].sParamStr = sCellNameA;
         progsec.Append(theprog);
      }
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typeNC)
   {
      if (firstCoil && nType != typeLine1 && nType != typeLine2)
      {
         sProgSec.AppendFormat(_T("ST/ %s\r\n"), sCellName);
         theprog.nOpType1 = OP_ST_;
         theprog.nParamCount = 1;
         pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
         theprog.Params[0].nParamType = nCoilType;
         theprog.Params[0].nParamAddr = CoilAddr;
         theprog.Params[0].sParamStr = sCellNameA;
         progsec.Append(theprog);
         firstCoil = false;
      }
      else
      {
         sProgSec.AppendFormat(_T("AN/ %s\r\n"), sCellName);
         theprog.nOpType1 = OP_AN_;
         theprog.nParamCount = 1;
         pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
         theprog.Params[0].nParamType = nCoilType;
         theprog.Params[0].nParamAddr = CoilAddr;
         theprog.Params[0].sParamStr = sCellNameA;
         progsec.Append(theprog);
      }
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typePP)
   {
      //progsec.Append(theprog);
      sProgSec.AppendFormat(_T("PP %s\r\n"), sCellName);
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typePN)
   {
      //progsec.Append(theprog);
      sProgSec.AppendFormat(_T("PN %s\r\n"), sCellName, sCellName);
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typeNOT)
   {
      sProgSec.AppendFormat(_T("NOT %s\r\n"), sCellName);
      theprog.nOpType1 = OP_NOT;
      progsec.Append(theprog);
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typeDF)
   {
      sProgSec.AppendFormat(_T("DF %s\r\n"), sCellName);
      theprog.nOpType1 = OP_DF;
      progsec.Append(theprog);
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typeDF_)
   {
      sProgSec.AppendFormat(_T("DF/ %s\r\n"), sCellName);
      theprog.nOpType1 = OP_DF_;
      progsec.Append(theprog);
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typeOUT)
   {
      sProgSec.AppendFormat(_T("OUT %s\r\n"), sCellName);
      theprog.nOpType1 = OP_OUT;
      theprog.nParamCount = 1;
      pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
      theprog.Params[0].nParamType = nCoilType;
      theprog.Params[0].nParamAddr = CoilAddr;
      theprog.Params[0].sParamStr = sCellNameA;
      progsec.Append(theprog);
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typeSET)
   {
      sProgSec.AppendFormat(_T("SET %s\r\n"), sCellName);
      theprog.nOpType1 = OP_SET;
      theprog.nParamCount = 1;
      pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
      theprog.Params[0].nParamType = nCoilType;
      theprog.Params[0].nParamAddr = CoilAddr;
      theprog.Params[0].sParamStr = sCellNameA;
      progsec.Append(theprog);
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typeRESET)
   {
      sProgSec.AppendFormat(_T("RESET %s\r\n"), sCellName);
      theprog.nOpType1 = OP_RESET;
      theprog.nParamCount = 1;
      pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
      theprog.Params[0].nParamType = nCoilType;
      theprog.Params[0].nParamAddr = CoilAddr;
      theprog.Params[0].sParamStr = sCellNameA;
      progsec.Append(theprog);
      nSteps += 1;
      nNextX = 1;
   }
   else if (nType == typeCMP)
   {
      theprog.nOpType1 = OP_ST_GT;
      theprog.nParamCount = 1;
      progsec.Append(theprog);
      sProgSec.AppendFormat(_T("CMP %s %s %s \r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
      nSteps += 1;
      nNextX = 3;
   }
   else if (nType == typeTM)
   {
      theprog.nOpType1 = OP_TMX;
      theprog.nParamCount = 1;
      pDoc->TxtToCoilType(sCellNameA, &nCoilType, &CoilAddr);
      theprog.Params[0].nParamType = nCoilType;
      theprog.Params[0].nParamAddr = CoilAddr;
      theprog.Params[0].sParamStr = sCellNameA;
      progsec.Append(theprog);
      sProgSec.AppendFormat(_T("TM %s %d %s\r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
      nSteps += 1;
      nNextX = 3;
   }
   else if (nType == typeFN1)
   {
      theprog.nOpType1 = OP_INC;
      progsec.Append(theprog);
      sProgSec.AppendFormat(_T("FN1 %s %s\r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam);
      nSteps += 1;
      nNextX = 2;
   }
   else if (nType == typeFN2)
   {
      theprog.nOpType1 = OP_MV;
      progsec.Append(theprog);
      sProgSec.AppendFormat(_T("FN2 %s %s %s \r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam);
      nSteps += 1;
      nNextX = 3;
   }
   else if (nType == typeFN3)
   {
      theprog.nOpType1 = OP_ADD3;
      progsec.Append(theprog);
      sProgSec.AppendFormat(_T("FN3 %s %s %s %s\r\n"), sCellName, Cells[nCurPosY][nCurPosX + 1].sParam, Cells[nCurPosY][nCurPosX + 2].sParam, Cells[nCurPosY][nCurPosX + 3].sParam);
      nSteps += 1;
      nNextX = 4;
   }
   else
   {
      nNextX = 1;
      //continue;
   }
   return nNextX;
}
/// <summary>
/// 全部图形校验
@@ -3436,75 +3596,75 @@
/// 计划在第一个返回值中使用不同的错误代码代表不同的错误类型,
/// 并在第二个返回值中填充错误提示信息
/// </remark>
std::pair<int, CString> CMTerm1View::LDSCheckRule()
{
   CString message;
   int nDivCount = 0;
   int Divs[100] = { 0 };
   //以行为单位从上到下遍历(行遍历)
   for (int i = 0; i < m_nTotalRow; i++)
   {
      int nRow = i;
      int bConnected = 0;
      bool checkFlag = false;//0列检验结果
 std::pair<int, CString> CMTerm1View::LDSCheckRule()
 {
    CString message;
    int nDivCount = 0;
    int Divs[100] = { 0 };
    //以行为单位从上到下遍历(行遍历)
    for (int i = 0; i < m_nTotalRow; i++)
    {
       int nRow = i;
       int bConnected = 0;
       bool checkFlag = false;//0列检验结果
      //本行的0列检查
      if (Cells[nRow][0].nType == 0)
      {
         checkFlag = true;
      }
       //本行的0列检查
       if (Cells[nRow][0].nType == 0)
       {
          checkFlag = true;
       }
      //遍历此行的1-15列(确定单元格)
      for (int j = 1; j < m_CellPerLine; j++)
      {
         int nCol = j;
         //如果0列为空
         if (checkFlag)
         {
            //有左侧上竖线
            if (Cells[nRow][nCol].bLeftLineUp)
            {
               //如果上层为空单元格,无效竖线,直接删除-----可以单独判断
               if (nRow - 1 >= 0 && Cells[nRow-1][nCol].nType == 0)
               {
                  //清理单元格
                  Cells[nRow][nCol].clear();
               }
               //如果是none,错误:短路或回路
               else if (Cells[nRow][nCol].nType == 0)
               {
                  message.Format(_T("((%d,%d) 附近位置产生触点短路或回路!"),nRow,nCol);
                  return std::make_pair(111, message);
               }
               //如果不为none。可以转换,但是提示:无法绘制图形(程序不合理)
               if (Cells[nRow][nCol].nType != 1)
               {
                  message.Format(_T("((%d,%d) 无法绘制图形(程序不合理)"), nRow, nCol);
                  return std::make_pair(111, message);
               }
       //遍历此行的1-15列(确定单元格)
       for (int j = 1; j < m_CellPerLine; j++)
       {
          int nCol = j;
          //如果0列为空
          if (checkFlag)
          {
             //有左侧上竖线
             if (Cells[nRow][nCol].bLeftLineUp)
             {
                //如果上层为空单元格,无效竖线,直接删除-----可以单独判断
                if (nRow - 1 >= 0 && Cells[nRow - 1][nCol].nType == 0)
                {
                   //清理单元格
                   Cells[nRow][nCol].clear();
                }
                //如果是none,错误:短路或回路
                else if (Cells[nRow][nCol].nType == 0)
                {
                   message.Format(_T("((%d,%d) 附近位置产生触点短路或回路!"), nRow, nCol);
                   return std::make_pair(111, message);
                }
                //如果不为none。可以转换,但是提示:无法绘制图形(程序不合理)
                if (Cells[nRow][nCol].nType != 1)
                {
                   message.Format(_T("((%d,%d) 无法绘制图形(程序不合理)"), nRow, nCol);
                   return std::make_pair(111, message);
                }
            }
            //没有左侧上竖线,且此单元格类型 不为空或线
            else if (Cells[nRow][nCol].nType > 2)
            {
               //此单元格为单独的线圈或指令单元,需要触点输入
               message.Format(_T("((%d,%d) 需要触点输入"), nRow, nCol);
               return std::make_pair(111, message);
            }
            //有左侧下竖线,且此单元格类型为空
            if (Cells[nRow][nCol].bLeftLineDn)
            {
               //不支持回路
            }
         }
         //如0列非空
         else
         {
             }
             //没有左侧上竖线,且此单元格类型 不为空或线
             else if (Cells[nRow][nCol].nType > 2)
             {
                //此单元格为单独的线圈或指令单元,需要触点输入
                message.Format(_T("((%d,%d) 需要触点输入"), nRow, nCol);
                return std::make_pair(111, message);
             }
             //有左侧下竖线,且此单元格类型为空
             if (Cells[nRow][nCol].bLeftLineDn)
             {
                //不支持回路
             }
          }
          //如0列非空
          else
          {
         }
      }
          }
       }
   }
   return std::make_pair(0,message);
}
    }
    return std::make_pair(0, message);
 }