| | |
| | |
|
| | | // ON_COMMAND(ID_INDICATOR_MONITOR_STATUS, &CMTerm1View::OnIndicatorMonitorStatus)
|
| | | // ON_UPDATE_COMMAND_UI(ID_INDICATOR_MONITOR_STATUS, &CMTerm1View::OnUpdateIndicatorMonitorStatus)
|
| | | ON_WM_KEYDOWN()
|
| | | ON_WM_KEYDOWN()
|
| | | END_MESSAGE_MAP()
|
| | |
|
| | |
|
| | |
| | | {
|
| | |
|
| | | }
|
| | | else if (nType == typeEND) {
|
| | |
|
| | | if (needReDraw) {
|
| | | //画左侧横线
|
| | | //DrawLeftRightLine(pDC, x0, y0, 14, 18);
|
| | | DrawAngleBracket(pDC, x0, y0, 8, 32);
|
| | | DrawCellText1(pDC, _T("ED"), x0 + 16, y0 + m_LinePosY - 8, 24, 14);
|
| | | }
|
| | | }
|
| | | else if (nType == typeLine1)
|
| | | { //Draw Line
|
| | | //画直横线
|
| | |
| | | else if (nType == typeLine2)
|
| | | { //Draw Line
|
| | | //画直竖线
|
| | | pDC->MoveTo(x0, y0 + (0.32 * CellTotalHeight));
|
| | | pDC->LineTo(x0, y0 - (0.69 * CellTotalHeight));
|
| | | pDC->MoveTo(x0, y0 + int(0.32 * CellTotalHeight));
|
| | | pDC->LineTo(x0, y0 - int(0.69 * CellTotalHeight));
|
| | | }
|
| | | else if (nType == typeNO)
|
| | | {
|
| | |
| | | nCol = 0;
|
| | | }
|
| | | }
|
| | | CellFocusChg(nRow, nCol);
|
| | | }
|
| | | if (nChar == VK_RIGHT) {
|
| | | nCol += 1;
|
| | |
| | | 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;
|
| | |
| | | {
|
| | | CString s1;
|
| | | stCell & thecell = Cells[nRow][nCol];
|
| | | s1.Format(_T("Cell %d %d Type %02X \r\n"), nRow, nCol, thecell.nType);
|
| | | s1.Format(_T("Cell %d %d Type %02X OpType %02X \r\n"), nRow, nCol, thecell.nType,thecell.nOpType);
|
| | | s1.AppendFormat(_T(" sCoilName %s sParam %s \r\n"), thecell.sCoilName, thecell.sParam );
|
| | | s1.AppendFormat(_T("LeftUp %d leftDn %d "), thecell.bLeftLineUp, thecell.bLeftLineDn);
|
| | | DbgLog(s1);
|
| | |
| | | m_nCurProgStep = Cells[nRow][nCol].nProgStep;
|
| | | }
|
| | | if (!pDoc->m_bOnline) return;
|
| | | //if (!m_bMonitoring) return;
|
| | |
|
| | | if (!m_bMonitoring || !pDoc->m_bOnline) {
|
| | | |
| | | };
|
| | | |
| | | CString sParam;
|
| | | sParam = Cells[nRow][nCol].sParam;
|
| | | int nDataType, nDataAddr, nStat;
|
| | |
| | | // TODO: 在此添加消息处理程序代码和/或调用默认值
|
| | | CString s1;
|
| | | CMTerm1Doc * pDoc = (CMTerm1Doc*)GetDocument();
|
| | |
|
| | | static int nCount = 0;
|
| | | if (nIDEvent == 0) {
|
| | |
|
| | | }
|
| | | else if (nIDEvent == 1)
|
| | | {
|
| | | if (m_bMonitoring) {
|
| | | nCount++;
|
| | | if (m_bMonitoring && (nCount &1)) {
|
| | | //this->RedrawWindow();
|
| | | DoReDraw();
|
| | | }
|
| | |
| | | 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);
|
| | | int r = TransLDSToProg();
|
| | | SysLog(s1);
|
| | | int r = TransLDSToProgAOV(); //TransLDSToProg();
|
| | | s1.Format(_T("LDS To Prog result %d"), r);
|
| | | SysLog(s1);
|
| | | ///*
|
| | | if (r==0)
|
| | | {
|
| | | // m_bModified = 0;
|
| | | GetDocument()->FindProgPair();
|
| | | GetDocument()->TransProgToBin();
|
| | | int j=TransProgToLDS();
|
| | | s1.Format(_T("Porg to LDS retuls %d"), j);
|
| | | SysLog(s1);
|
| | |
| | | s1.Format(_T("Error in Prog Convert"));
|
| | | SysLog(s1);
|
| | | }
|
| | | //*/
|
| | | }
|
| | |
|
| | | void CMTerm1View::OnUpdateProgConvert(CCmdUI *pCmdUI)
|
| | |
| | | /// <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;
|
| | |
| | | }
|
| | | //添加纵线时同步添加上一行
|
| | | Cells[m_FocusRow - 1][m_FocusCol].bLeftLineDn = 1;
|
| | |
|
| | | }break;
|
| | | case 2:
|
| | | {
|
| | |
| | | }
|
| | | //删除纵线时同步删除上一行
|
| | | 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;
|
| | |
| | | for (int j = 0; j < 16; j++)
|
| | | {
|
| | | Cells[i][j].clear();
|
| | | s1.Format(_T("%d:%d"), i, j);
|
| | | s1.Format(_T("%d:%d"), i, j);
|
| | | Cells[i][j].sCoilName = s1;
|
| | | }
|
| | | }
|
| | | 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;
|
| | |
| | | switch (nOp)
|
| | | {
|
| | | case OP_NOP:
|
| | | break;
|
| | | case OP_END:
|
| | | nCellType = typeEND;
|
| | | nCurLine = cy;
|
| | | cx = 0;
|
| | | if (cx <= m_CellPerLine) {
|
| | |
|
| | | int hasData = 1;
|
| | | while (hasData) {
|
| | | hasData = 0;
|
| | | for (int j = 0; j < m_CellPerLine; j++) {
|
| | | if (Cells[nCurLine][j].nType != 0) {
|
| | | nCurLine++; hasData = 1; break;
|
| | | }
|
| | | }
|
| | | }
|
| | | cy = nCurLine;
|
| | | for (int j = 0; j < m_CellPerLine; j++)
|
| | | {
|
| | | Cells[cy][j].nType = typeLine1;
|
| | | }
|
| | | Cells[cy][m_CellPerLine - 1].nType = nCellType;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][m_CellPerLine - 1].nProgStep = i;
|
| | | }
|
| | | if (cy > maxy) { maxy = cy; }
|
| | | //cy++;
|
| | | break;
|
| | | break;
|
| | | case OP_ST:
|
| | | case OP_ST_:
|
| | |
| | | }
|
| | | 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;
|
| | | StPts[nSts] = POINT{ cx,cy };
|
| | | nSts++;
|
| | | Cells[cy][cx].nType = pDoc->Progs[i].nOpType1 == OP_ST ? typeNO : typeNC; //typeNC
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
|
| | | Cells[cy][cx].sParam = pDoc->Progs[i].Params[0].sParamStr;
|
| | |
| | | StPts[nSts] = POINT{ cx,cy };
|
| | | nSts++;
|
| | | Cells[cy][cx].nType = typeCMP;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sParam = OpName;
|
| | | Cells[cy][cx].sCoilName = ShowTxt;
|
| | |
| | | case OP_AN_:
|
| | |
|
| | | Cells[cy][cx].nType = nOp == OP_AN ? typeNO : typeNC; //typeNC
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sParam = pDoc->Progs[i].Params[0].sParamStr;
|
| | | Cells[cy][cx].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
|
| | |
| | | case OP_AN_LE:
|
| | | case OP_AN_GE:
|
| | | Cells[cy][cx].nType = typeCMP;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sCoilName = ShowTxt;
|
| | | Cells[cy][cx + 1].nType = typeExt1;
|
| | |
| | | case OP_OR:
|
| | | case OP_OR_:
|
| | | EndPt[nEndPts] = POINT{ cx,cy };
|
| | | nEndPts++;
|
| | | nEndPts++;
|
| | | cx = StPts[nSts - 1].x;
|
| | | nCurLine = cy + 1; //另起一行
|
| | | {
|
| | | int hasData = 1;
|
| | | while (hasData) {
|
| | | hasData = 0;
|
| | | for (int j = cx; j < m_CellPerLine; j++) {
|
| | | if (Cells[nCurLine][j].nType != 0) {
|
| | | nCurLine++; hasData = 1; break;
|
| | | while (hasData) |
| | | {
|
| | | hasData = 0; |
| | | for (int j = cx; j < m_CellPerLine; j++) |
| | | {
|
| | | if (Cells[nCurLine][j].nType != 0) |
| | | {
|
| | | nCurLine++; |
| | | hasData = 1; |
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | if (nCurLine > maxy) maxy = nCurLine;
|
| | | for (int j = cy; j < nCurLine; j++) {
|
| | | if (nCurLine > maxy)
|
| | | {
|
| | | maxy = nCurLine;
|
| | | }
|
| | | for (int j = cy; j < nCurLine; j++) |
| | | {
|
| | | Cells[j][cx].bLeftLineDn = 1;
|
| | | Cells[j + 1][cx].bLeftLineUp = 1;
|
| | | }
|
| | | cy = nCurLine;
|
| | | StPts[nSts] = POINT{ cx,cy };//+++
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].nType = nOp == OP_OR ? typeNO : typeNC; //typeNC
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
|
| | | Cells[cy][cx].sParam = pDoc->Progs[i].Params[0].sParamStr;
|
| | | Cells[cy][cx].nDataType = pDoc->Progs[i].Params[0].nParamType;
|
| | | Cells[cy][cx].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr;
|
| | | cx++;
|
| | | if (cx < EndPt[nEndPts - 1].x)
|
| | | if (cx <= EndPt[nEndPts - 1].x)
|
| | | { //本行补齐
|
| | | for (int j = cx; j < EndPt[nEndPts - 1].x; j++)
|
| | | {
|
| | |
| | | }
|
| | | //光标位置, 前一结束点位置
|
| | | cy = EndPt[nEndPts - 1].y;
|
| | |
|
| | | nEndPts--;
|
| | |
|
| | | break;
|
| | |
| | | }
|
| | | cy = nCurLine;
|
| | | Cells[cy][cx].nType = typeCMP;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sCoilName = ShowTxt;
|
| | | Cells[cy][cx + 1].nType = typeExt1;
|
| | |
| | | break;
|
| | | case OP_NOT:
|
| | | Cells[cy][cx].nType = typeNOT;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].sCoilName = _T("NOT");
|
| | |
|
| | | Cells[cy][cx].nProgStep = i;
|
| | |
| | | case OP_DF:
|
| | | case OP_DF_:
|
| | | Cells[cy][cx].nType = nOp == OP_DF ? typeDF : typeDF_;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].sCoilName = nOp == OP_DF ? _T("DF") : _T("DF/");
|
| | |
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | 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];
|
| | | 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;
|
| | | }
|
| | | }
|
| | | }
|
| | | //连接上下线
|
| | | for (int j = EndPt[nEndPts - 1].y; j < cy; j++)
|
| | | {
|
| | | Cells[j][cx].bLeftLineDn = 1;
|
| | | Cells[j + 1][cx].bLeftLineUp = 1;
|
| | | }
|
| | | //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;
|
| | |
| | | Cells[j + 1][cx].bLeftLineUp = 1;
|
| | | }
|
| | | nEndPts--;
|
| | |
|
| | | /*
|
| | | nStrPts--;
|
| | | cy = StrPt[nStrPts].y;
|
| | | cx = StrPt[nStrPts].x;
|
| | | */
|
| | | break;
|
| | | case OP_OUT:
|
| | | case OP_SET:
|
| | |
| | | Cells[cy][j].nType = typeLine1;
|
| | | }
|
| | | Cells[cy][m_CellPerLine - 1].nType = nCellType;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][m_CellPerLine - 1].nProgStep = i;
|
| | | Cells[cy][m_CellPerLine - 1].sParam = pDoc->Progs[i].Params[0].sParamStr;
|
| | | Cells[cy][m_CellPerLine - 1].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
|
| | |
| | | }
|
| | | else {
|
| | | Cells[cy][cx].nType = nCellType;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sParam = pDoc->Progs[i].Params[0].sParamStr;
|
| | | Cells[cy][cx].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
|
| | |
| | | case OP_TMR:
|
| | | case OP_TMX:
|
| | | case OP_TMY:
|
| | | nCurLine = cy;
|
| | | {
|
| | | int hasData = 1;
|
| | | while (hasData) {
|
| | | hasData = 0;
|
| | | for (int j = cx; j < m_CellPerLine; j++) {
|
| | | if (Cells[nCurLine][j].nType != 0) {
|
| | | nCurLine++; hasData = 1; break;
|
| | | }
|
| | | }
|
| | | }
|
| | | //if (nCurLine > maxy) maxy = nCurLine;
|
| | | for (int j = cy; j < nCurLine; j++) {
|
| | | Cells[j][cx].bLeftLineDn = 1;
|
| | | Cells[j + 1][cx].bLeftLineUp = 1;
|
| | | }
|
| | | }
|
| | | cy = nCurLine;
|
| | | Cells[cy][cx].nType = typeTM;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sCoilName = ShowTxt;
|
| | | Cells[cy][cx + 1].nType = typeExt1;
|
| | |
| | | case OP_INC:
|
| | | case OP_DEC:
|
| | | Cells[cy][cx].nType = typeFN1;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sCoilName = ShowTxt;
|
| | | Cells[cy][cx + 1].nType = typeExt1;
|
| | |
| | | case OP_ADD2:
|
| | | case OP_SUB2:
|
| | | Cells[cy][cx].nType = typeFN2;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sCoilName = ShowTxt;
|
| | | Cells[cy][cx + 1].nType = typeExt1;
|
| | |
| | | case OP_MUL:
|
| | | case OP_DIV:
|
| | | Cells[cy][cx].nType = typeFN3;
|
| | | Cells[cy][cx].nOpType = nOp;
|
| | | Cells[cy][cx].nProgStep = i;
|
| | | Cells[cy][cx].sCoilName = ShowTxt;
|
| | | Cells[cy][cx + 1].nType = typeExt1;
|
| | |
| | | default:
|
| | | break;
|
| | | }
|
| | | if (cy > maxy) { maxy = cy; }
|
| | | }
|
| | | }
|
| | | catch (const std::exception&)
|
| | |
| | | needReDraw = 1;
|
| | | return 0;
|
| | | }
|
| | | bool firstCoil = true;//本段第一个单元格
|
| | |
|
| | |
|
| | | int CMTerm1View::AddNode(int nType, int CellX, int CellY, CString sCoilName, int PrevNode)
|
| | | {
|
| | | node& theNode = nodes[nNodeCount];
|
| | |
|
| | | theNode.nId = nNodeCount;
|
| | |
|
| | | theNode.bEnable = 1;
|
| | | theNode.nType = nType;
|
| | | theNode.indegree = 0;
|
| | | theNode.outdegree = 0;
|
| | | theNode.firstOut = 0;
|
| | | theNode.firstIn = 0;
|
| | | theNode.input = 0;
|
| | | theNode.result = 0;
|
| | | theNode.nCellX = CellX;
|
| | | theNode.nCellY = CellY;
|
| | | theNode.CoilName = sCoilName;
|
| | | theNode.InProcCount = 0;
|
| | | theNode.OutProcCount = 0;
|
| | | theNode.OutProcAllDone = 0;
|
| | | theNode.prog1.Progs.clear();
|
| | | int nOp = Cells[CellY][CellX].nOpType;
|
| | | int nCoilType, nCoilAddr;
|
| | | if (nType == typeNO)
|
| | | {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | if (CellX == 0) {
|
| | | prog0.nOpType1 = OP_ST; // OP_AN;
|
| | | }else |
| | | if (nOp >= 1 && nOp <= 255) {
|
| | | //prog0.nOpType1 = nOp; // OP_AN;
|
| | | prog0.nOpType1 = OP_AN; // OP_AN;
|
| | | }
|
| | | else {
|
| | | prog0.nOpType1 = OP_AN; // OP_AN;
|
| | | }
|
| | | prog0.nParamCount = 1;
|
| | | prog0.Params[0].sParamStr = sCoilName;
|
| | | CStringA s2A;
|
| | | s2A = sCoilName;
|
| | | GetDocument()->TxtToCoilType(s2A,&nCoilType,&nCoilAddr);
|
| | |
|
| | | prog0.Params[0].nParamType = nCoilType;
|
| | | prog0.Params[0].nParamAddr = nCoilAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeNC) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | if (CellX == 0) {
|
| | | prog0.nOpType1 = OP_ST_; // OP_AN;
|
| | | }
|
| | | else if (nOp >= 1 && nOp <= 255) {
|
| | | //prog0.nOpType1 = nOp; // OP_AN;
|
| | | prog0.nOpType1 = OP_AN_; // OP_AN;
|
| | | }
|
| | | else {
|
| | | prog0.nOpType1 = OP_AN_; // OP_AN;
|
| | | }
|
| | | prog0.nParamCount = 1;
|
| | | prog0.Params[0].sParamStr = Cells[CellY][CellX].sCoilName;
|
| | | CStringA s2A;
|
| | | s2A = sCoilName;
|
| | | GetDocument()->TxtToCoilType(s2A, &nCoilType, &nCoilAddr);
|
| | |
|
| | | prog0.Params[0].nParamType = nCoilType;
|
| | | prog0.Params[0].nParamAddr = nCoilAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeEND) {
|
| | | theNode.prog1.Append(CMTerm1Doc::stProg(OP_END));
|
| | | }
|
| | | else if (nType == typePP) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = Cells[CellY][CellX].nOpType;
|
| | | prog0.nParamCount = 1;
|
| | | prog0.Params[0].sParamStr = sCoilName;
|
| | | prog0.Params[0].nParamType = Cells[CellY][CellX].nDataType;
|
| | | prog0.Params[0].nParamAddr = Cells[CellY][CellX].nDataAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typePN) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = Cells[CellY][CellX].nOpType;
|
| | | prog0.nParamCount = 1;
|
| | | prog0.Params[0].sParamStr = sCoilName;
|
| | | prog0.Params[0].nParamType = Cells[CellY][CellX].nDataType;
|
| | | prog0.Params[0].nParamAddr = Cells[CellY][CellX].nDataAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeNOT) {
|
| | | theNode.prog1.Append(CMTerm1Doc::stProg(OP_NOT));
|
| | | }
|
| | | else if (nType == typeDF) {
|
| | | theNode.prog1.Append(CMTerm1Doc::stProg(OP_DF));
|
| | | }
|
| | | else if (nType == typeDF_) {
|
| | | theNode.prog1.Append(CMTerm1Doc::stProg(OP_DF_));
|
| | | }
|
| | | else if (nType == typeOUT) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = OP_OUT;
|
| | | prog0.nParamCount = 1;
|
| | | prog0.Params[0].sParamStr = sCoilName;
|
| | | CStringA s2A;
|
| | | s2A = sCoilName;
|
| | | GetDocument()->TxtToCoilType(s2A, &nCoilType, &nCoilAddr);
|
| | |
|
| | | prog0.Params[0].nParamType = nCoilType;
|
| | | prog0.Params[0].nParamAddr = nCoilAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeSET) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = OP_SET;
|
| | | prog0.nParamCount = 1;
|
| | | prog0.Params[0].sParamStr = sCoilName;
|
| | | CStringA s2A;
|
| | | s2A = sCoilName;
|
| | | GetDocument()->TxtToCoilType(s2A, &nCoilType, &nCoilAddr);
|
| | |
|
| | | prog0.Params[0].nParamType = nCoilType;
|
| | | prog0.Params[0].nParamAddr = nCoilAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeRESET) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = OP_RESET;
|
| | | prog0.nParamCount = 1;
|
| | | prog0.Params[0].sParamStr = sCoilName;
|
| | | CStringA s2A;
|
| | | s2A = sCoilName;
|
| | | GetDocument()->TxtToCoilType(s2A, &nCoilType, &nCoilAddr);
|
| | |
|
| | | prog0.Params[0].nParamType = nCoilType;
|
| | | prog0.Params[0].nParamAddr = nCoilAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeCMP) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | Cells[CellY][CellX];
|
| | | prog0.nOpType1 = Cells[CellY][CellX].nOpType;
|
| | | prog0.nParamCount = 2;
|
| | | prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
|
| | | prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
|
| | | prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
|
| | | prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
|
| | | prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
|
| | | prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeTM) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = Cells[CellY][CellX].nOpType;
|
| | | prog0.nParamCount = 2;
|
| | | prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
|
| | | prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
|
| | | prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
|
| | |
|
| | | prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
|
| | | prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
|
| | | prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
|
| | |
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeFN1) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = Cells[CellY][CellX].nOpType;;
|
| | | prog0.nParamCount = 1;
|
| | | prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
|
| | | prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
|
| | | prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeFN2) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = Cells[CellY][CellX].nOpType;;
|
| | | prog0.nParamCount = 2;
|
| | | prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
|
| | | prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
|
| | | prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
|
| | | prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
|
| | | prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
|
| | | prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeFN3) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = Cells[CellY][CellX].nOpType;;
|
| | | prog0.nParamCount = 3;
|
| | | prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
|
| | | prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
|
| | | prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
|
| | | prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
|
| | | prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
|
| | | prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
|
| | | prog0.Params[2].sParamStr = Cells[CellY][CellX + 3].sParam;
|
| | | prog0.Params[2].nParamType = Cells[CellY][CellX + 3].nDataType;
|
| | | prog0.Params[2].nParamAddr = Cells[CellY][CellX + 3].nDataAddr;
|
| | |
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | else if (nType == typeFN4) {
|
| | | CMTerm1Doc::stProg prog0;
|
| | | prog0.nOpType1 = Cells[CellY][CellX].nOpType;;
|
| | | prog0.nParamCount = 4;
|
| | | prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
|
| | | prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
|
| | | prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
|
| | | prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
|
| | | prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
|
| | | prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
|
| | | prog0.Params[2].sParamStr = Cells[CellY][CellX + 3].sParam;
|
| | | prog0.Params[2].nParamType = Cells[CellY][CellX + 3].nDataType;
|
| | | prog0.Params[2].nParamAddr = Cells[CellY][CellX + 3].nDataAddr;
|
| | | prog0.Params[3].sParamStr = Cells[CellY][CellX + 4].sParam;
|
| | | prog0.Params[3].nParamType = Cells[CellY][CellX + 4].nDataType;
|
| | | prog0.Params[3].nParamAddr = Cells[CellY][CellX + 4].nDataAddr;
|
| | | theNode.prog1.Append(prog0);
|
| | | }
|
| | | if (PrevNode > 0) {
|
| | | AddArc(PrevNode, nNodeCount);
|
| | | }
|
| | | nNodeCount++;
|
| | | return nNodeCount-1;
|
| | | }
|
| | |
|
| | | int SearchLastInArc(int nNodeID)
|
| | | {
|
| | | int ArcId = 0;
|
| | |
|
| | | return ArcId;
|
| | | }
|
| | |
|
| | | int SearchLastOutArc(int nNodeID)
|
| | | {
|
| | | int ArcId = 0;
|
| | |
|
| | | return ArcId;
|
| | | }
|
| | |
|
| | | int CMTerm1View::AddArc(int nNodeID1, int nNodeID2)
|
| | | {
|
| | | node& theNode1 = nodes[nNodeID1];
|
| | | node& theNode2 = nodes[nNodeID2];
|
| | |
|
| | | arc& theArc = arcs[nArcCount];
|
| | | theArc.nId = nArcCount;
|
| | | theArc.bEnable = 1;
|
| | | theNode2.firstIn;
|
| | |
|
| | |
|
| | | theArc.headNode = nNodeID2;
|
| | | theArc.tailNode = nNodeID1;
|
| | | theArc.hlinkId = 0;
|
| | | theArc.tlinkId = 0;
|
| | |
|
| | | theArc.tailvex = &theNode1;
|
| | | theArc.headvex = &theNode2;
|
| | | theArc.tlink = 0;
|
| | | theArc.hlink = 0;
|
| | |
|
| | | theNode1.outdegree++;
|
| | | theNode2.indegree++;
|
| | |
|
| | | //如果顶点已经有 连接 ,将新的弧加到已有弧的后面。
|
| | |
|
| | | if (theNode1.firstOut == 0) {
|
| | | theNode1.firstOut = &theArc; |
| | | }else {
|
| | | arc * p1 = theNode1.firstOut;
|
| | | for (; p1->tlink != 0;) {
|
| | | p1 = p1->tlink;
|
| | | }
|
| | | p1->tlink = &theArc;
|
| | | p1->tlinkId = nArcCount;
|
| | | }
|
| | |
|
| | | if (theNode2.firstIn == 0) {
|
| | | theNode2.firstIn = &theArc;
|
| | | }else{
|
| | | arc* p1 = theNode2.firstIn;
|
| | | for (; p1->hlink != 0;) {
|
| | | p1 = p1->hlink;
|
| | | }
|
| | | p1->hlink = &theArc;
|
| | | p1->hlinkId = nArcCount;
|
| | | }
|
| | |
|
| | | nArcCount++;
|
| | | return nArcCount;
|
| | | }
|
| | |
|
| | | int CMTerm1View::MergeParallelNodeWithinVP(int nVPNodeId1, int nVPNodeId2) //合并两个串联的虚节点之间所有的并行 Node,并行数量可能大于2个。
|
| | | {
|
| | | node& theNode1 = nodes[nVPNodeId1]; //虚节点1
|
| | | node& theNode2 = nodes[nVPNodeId2]; //虚节点2
|
| | | // 必须前者 与 后者 之间有两条以上 且连续,其中一方为另一方的子集 才能合并。
|
| | | // 先找到两者连接的弧
|
| | | if (!theNode1.bEnable || !theNode2.bEnable) return -1;
|
| | | if (theNode1.outdegree < 2 || theNode2.indegree < 2 ) return -2;
|
| | | // if (theNode1.firstOut != theNode2.firstIn) return -3;
|
| | | // |
| | | // 先找到第一个连接
|
| | | // |
| | | CString s1;
|
| | | //先判断两者大小
|
| | | int n1 = theNode1.outdegree;
|
| | | int n2 = theNode2.indegree;
|
| | |
|
| | | if (n1 <= n2) { //前者是后的的子集
|
| | | int n = 0;
|
| | | arc* ptheArc1 = theNode1.firstOut;
|
| | | while (ptheArc1)
|
| | | { // 取得连接的实节点地址;
|
| | | node* pThisNode1 = ptheArc1->headvex;
|
| | | // 取得实节点连接的弧;
|
| | | arc* ptheArc2 = pThisNode1->firstOut;
|
| | | // 取出弧连接的下一个节点, 目标虚节点
|
| | | node* pThatNode1 = ptheArc2->headvex;
|
| | | // 判断这个点是不是指定的虚节点
|
| | | if (pThatNode1 != &theNode2) { return -3; } // 没连接到第二个虚节点
|
| | | n++;
|
| | | // 继续下一个连接的弧;
|
| | | ptheArc1 = ptheArc1->tlink;
|
| | | }
|
| | | if (theNode1.outdegree != n ) return -2;
|
| | |
|
| | | //node& theNode;
|
| | | // 第二次,重来一遍,开始合并程序 |
| | |
|
| | | stProgSection prog2;
|
| | | ptheArc1 = theNode1.firstOut;
|
| | | node* pThisNode1 = ptheArc1->headvex; // 第一个实节点
|
| | | stProgSection prog1 = pThisNode1->prog1;
|
| | | if (prog1.Progs[0].nOpType1 == OP_AN) { prog1.Progs[0].nOpType1 = OP_ST; }
|
| | | else if (prog1.Progs[0].nOpType1 == OP_AN_) { prog1.Progs[0].nOpType1 = OP_ST_; }
|
| | | else if (prog1.Progs[0].nOpType1 == OP_ST || prog1.Progs[0].nOpType1 == OP_ST_ ){
|
| | | prog1.Prefix += 1;
|
| | | s1.Format(_T(" <+1 %s"),prog1.ToText()); DbgLog(s1);
|
| | | }
|
| | | else {
|
| | | prog1.Prefix += 0;
|
| | | s1.Format(_T(" < +0 %s"),prog1.ToText()); DbgLog(s1);
|
| | | }
|
| | | prog2 = prog1; // 取得第一个实节点的程序
|
| | | ptheArc1 = ptheArc1->tlink; //下一个弧
|
| | | while (ptheArc1)
|
| | | {
|
| | | //取得相连的实节点地址
|
| | | node* pThisNode2 = ptheArc1->headvex;
|
| | | stProgSection prog1 = pThisNode2->prog1;
|
| | | if (prog1.Progs[0].nOpType1 == OP_AN) { prog1.Progs[0].nOpType1 = OP_ST; }
|
| | | else if (prog1.Progs[0].nOpType1 == OP_AN_) { prog1.Progs[0].nOpType1 = OP_ST_; }
|
| | | else if (prog1.Progs[0].nOpType1 == OP_ST || prog1.Progs[0].nOpType1 == OP_ST_) {
|
| | | prog1.Prefix += 1;
|
| | | s1.Format(_T(" < 2 +1 %s"), prog1.ToText()); DbgLog(s1);
|
| | | if (theNode1.nType == -1) { prog1.reduce(); }
|
| | | }
|
| | | else {
|
| | | prog1.Prefix += 0;
|
| | | s1.Format(_T(" < 2 +0 %s"),prog1.ToText()); DbgLog(s1);
|
| | | }
|
| | |
|
| | | if (prog1.Progs.size() > 1) {
|
| | | prog1.Append(CMTerm1Doc::stProg(OP_ORS));
|
| | | }
|
| | | else {
|
| | | if (pThisNode2->nType == typeNC) prog1.Progs[0].nOpType1 = OP_OR_;
|
| | | else if (pThisNode2->nType == typeNO) prog1.Progs[0].nOpType1 = OP_OR;
|
| | | else prog1.Progs[0].nOpType1 = OP_OR;
|
| | | }
|
| | | prog2 += prog1;
|
| | |
|
| | | // 取得实节点连接的弧;
|
| | |
|
| | | arc* ptheArc2 = pThisNode2->firstOut;
|
| | | RemoveArc(ptheArc2->nId); //删除弧
|
| | | arc* pTheNextArc = ptheArc1->tlink; //取得下一个弧并保存
|
| | | RemoveArc(ptheArc1->nId); //删除当前弧
|
| | | pThisNode2->bEnable = 0; //删除实节点
|
| | | ptheArc1 = pTheNextArc;
|
| | | }
|
| | | if (theNode1.nType == -1 && theNode2.nType == -1) { prog2.Append(CMTerm1Doc::stProg(OP_ANS)); }
|
| | | pThisNode1->prog1 = prog2; //将所有程序汇总到第一个实节点
|
| | | // pThisNode1->prog1.reduce();
|
| | | // s1 = prog2.ToText(GetDocument());
|
| | | // DbgLog(_T("------ ") + s1);
|
| | | }
|
| | | else { // n1> n2 // 后者是前者的子集
|
| | | int n = 0;
|
| | | arc* ptheArc1 = theNode2.firstIn;
|
| | | while (ptheArc1)
|
| | | {
|
| | |
|
| | | //取得相连的虚节点地址
|
| | |
|
| | | // 取得连接的实节点地址;
|
| | | node* pThisNode1 = ptheArc1->tailvex;
|
| | | // 取得实节点连接的弧;
|
| | | arc* ptheArc2 = pThisNode1->firstIn;
|
| | | // 取出弧连接的下一个节点
|
| | | node* pThatNode1 = ptheArc2->tailvex;
|
| | | // 判断这个点是不是指定的虚节点
|
| | | if (pThatNode1 != &theNode1) { return -3; } // 没连接到第二个虚节点
|
| | | n++;
|
| | | // 继续下一个连接的弧;
|
| | | ptheArc1 = ptheArc1->hlink;
|
| | | }
|
| | | if (theNode2.indegree != n) return -1;
|
| | | //node& theNode;
|
| | | // 第二次,重来一遍,开始合并程序 |
| | | stProgSection prog2;
|
| | | ptheArc1 = theNode2.firstIn;
|
| | | node* pThisNode1 = ptheArc1->tailvex; // 第一个实节点
|
| | | stProgSection prog1 = pThisNode1->prog1;
|
| | | if (prog1.Progs[0].nOpType1 == OP_AN) { prog1.Progs[0].nOpType1 = OP_ST; }
|
| | | else if (prog1.Progs[0].nOpType1 == OP_AN_) { prog1.Progs[0].nOpType1 = OP_ST_; }
|
| | | else if (prog1.Progs[0].nOpType1 == OP_ST || prog1.Progs[0].nOpType1 == OP_ST_) {
|
| | | prog1.Prefix += 1;
|
| | | s1.Format(_T(" > +1 %s"),prog1.ToText()); DbgLog(s1);
|
| | | }
|
| | | else {
|
| | | prog1.Prefix += 0;
|
| | | s1.Format(_T(" > +0 %s"), prog1.ToText()); DbgLog(s1);
|
| | | }
|
| | | prog2 = prog1; // 取得第一个实节点的程序
|
| | |
|
| | | ptheArc1 = ptheArc1->hlink;
|
| | | bool NeedANS = 0;
|
| | | while (ptheArc1)
|
| | | {
|
| | | //取得相连的虚节点地址
|
| | | node* pThisNode2 = ptheArc1->tailvex;
|
| | |
|
| | | stProgSection prog1 = pThisNode2->prog1;
|
| | | if (prog1.Progs[0].nOpType1 == OP_AN) { prog1.Progs[0].nOpType1 = OP_ST; }
|
| | | else if (prog1.Progs[0].nOpType1 == OP_AN_) { prog1.Progs[0].nOpType1 = OP_ST_; }
|
| | | else if (prog1.Progs[0].nOpType1 == OP_ST || prog1.Progs[0].nOpType1 == OP_ST_) {
|
| | | prog1.Prefix += 1;
|
| | | s1.Format(_T(" > 2 +1 %s"),prog1.ToText()); DbgLog(s1);
|
| | | }
|
| | | else {
|
| | | prog1.Prefix += 0;
|
| | | s1.Format(_T(" >2 +0 %s"),prog1.ToText()); DbgLog(s1);
|
| | | }
|
| | | if (prog1.Progs.size() > 1) {
|
| | | prog1.Append(CMTerm1Doc::stProg(OP_ORS));
|
| | | NeedANS = 1;
|
| | | }
|
| | | else {
|
| | | if (pThisNode2->nType == typeNC) prog1.Progs[0].nOpType1 = OP_OR_;
|
| | | else if (pThisNode2->nType == typeNO) prog1.Progs[0].nOpType1 = OP_OR;
|
| | | else prog1.Progs[0].nOpType1 = OP_OR;
|
| | | NeedANS = 1;
|
| | | }
|
| | | prog2 += prog1;
|
| | |
|
| | | arc* ptheArc2 = pThisNode2->firstIn;
|
| | | RemoveArc(ptheArc2->nId); //删除弧
|
| | | arc* pTheNextArc = ptheArc1->hlink; //取得下一个弧并保存
|
| | | RemoveArc(ptheArc1->nId); //删除当前弧
|
| | | pThisNode2->bEnable = 0; //删除实节点
|
| | | ptheArc1 = pTheNextArc;
|
| | | }
|
| | | if (theNode1.nType == -1 && theNode2.nType == -1 && NeedANS) { prog2.Append(CMTerm1Doc::stProg(OP_ANS)); }
|
| | | pThisNode1->prog1 = prog2; //将所有程序汇总到第一个实节点
|
| | | // pThisNode1->prog1.reduce();
|
| | | // s1 = prog2.ToText(GetDocument());
|
| | | // DbgLog(_T("------ ") + s1);
|
| | | }
|
| | |
|
| | | return 0;
|
| | | }
|
| | |
|
| | | int CMTerm1View::RemoveArc(int nArcId)
|
| | | {
|
| | | arc& theArc = arcs[nArcId];
|
| | | node& theNode1 = *theArc.tailvex;
|
| | | node& theNode2 = *theArc.headvex;
|
| | | |
| | | // 先看 Node1 这边, |
| | | // 首弧
|
| | | if (theNode1.firstOut == &theArc) {
|
| | | theNode1.firstOut = theArc.tlink;
|
| | | }
|
| | | else {
|
| | | arc* thatArc = theNode1.firstOut;
|
| | | while (thatArc->tlink !=0){
|
| | | if (thatArc->tlink == &theArc) {
|
| | | thatArc->tlink = theArc.tlink;
|
| | | break;
|
| | | }
|
| | | thatArc = thatArc->tlink;
|
| | | }
|
| | | }
|
| | | |
| | |
|
| | | // 再看 Node2 这边, |
| | | // 首弧
|
| | | if (theNode2.firstIn == &theArc) {
|
| | | theNode2.firstIn = theArc.hlink;
|
| | | }
|
| | | else {
|
| | | arc* thatArc = theNode2.firstIn;
|
| | | while (thatArc->hlink != 0) {
|
| | | if (thatArc->hlink == &theArc) {
|
| | | thatArc->hlink = theArc.hlink;
|
| | | break;
|
| | | }
|
| | | thatArc = thatArc->hlink;
|
| | | }
|
| | | }
|
| | |
|
| | | theNode1.outdegree--;
|
| | | theNode2.indegree--;
|
| | | return nArcCount;
|
| | | }
|
| | |
|
| | | int CMTerm1View::RemoveNode(int nNodeId)
|
| | | {
|
| | | node& theNode = nodes[nNodeId];
|
| | | theNode.bEnable = 0;
|
| | | if (theNode.indegree) {
|
| | |
|
| | | }
|
| | | return nNodeCount;
|
| | | }
|
| | |
|
| | | int CMTerm1View::MergeNode(int nNodeId1, int nNodeId2) //合并两个串联的 实 Node
|
| | | {
|
| | | node& theNode1 = nodes[nNodeId1];
|
| | | node& theNode2 = nodes[nNodeId2];
|
| | | // 必须前者出度 为1 后者 入度 为1, 且 相连, 才能合并。
|
| | | // 先找到两者连接的弧
|
| | | if (!theNode1.bEnable || !theNode2.bEnable) return -1;
|
| | | if (theNode1.outdegree != 1 || theNode2.indegree != 1) return -2;
|
| | | if (theNode1.firstOut != theNode2.firstIn) return -3;
|
| | | // 删除两者之间的弧。
|
| | | RemoveArc(theNode1.firstOut->nId);
|
| | |
|
| | | theNode1.firstOut = 0;
|
| | | theNode2.firstIn = 0;
|
| | |
|
| | | // 将 Node2 的 出 弧, 转移 到 node1 上
|
| | | theNode1.CoilName += _T(" ") + theNode2.CoilName;
|
| | | theNode1.firstOut = theNode2.firstOut;
|
| | | theNode1.outdegree = theNode2.outdegree;
|
| | | theNode1.prog1 += theNode2.prog1; // 段程序合并
|
| | |
|
| | | arc* thatArc = theNode2.firstOut;
|
| | | while (thatArc != 0)
|
| | | {
|
| | | thatArc->tailvex = &theNode1;
|
| | | thatArc->tailNode = nNodeId1;
|
| | | thatArc = thatArc->tlink;
|
| | | theNode2.outdegree--;
|
| | | }
|
| | | // |
| | | // 现在 Node2 的入度和出度 均为 0, 删除 node2
|
| | | RemoveNode(nNodeId2);
|
| | | return 0;
|
| | | }
|
| | |
|
| | | // 合并从 nNodeId 虚节点发出的 各个单行 Nodes; 直到下一个多输出的虚节点
|
| | | int CMTerm1View::MergeVPSubSerialNodes(int nNodeId)
|
| | | {
|
| | | node& theNode = nodes[nNodeId];
|
| | |
|
| | | arc* theArc = theNode.firstOut;
|
| | | while (theArc != 0) {
|
| | | // 从当前弧 取出一个顶点
|
| | | node * thisNode = theArc->headvex;
|
| | | // 从这个顶点,找到下一个顶点
|
| | | if (thisNode->outdegree == 1 && thisNode->firstOut != 0) {
|
| | | node* thatNode = thisNode->firstOut->headvex;
|
| | | while (thatNode->indegree == 1 && thatNode->outdegree <= 1 && thatNode->nType != -2) {
|
| | | if (thatNode->nType == typeOUT || thatNode->nType == typeSET || thatNode->nType == typeRESET) {
|
| | | //break;
|
| | | }
|
| | | MergeNode(thisNode->nId, thatNode->nId);
|
| | | if (thatNode->firstOut) thatNode = thatNode->firstOut->headvex;
|
| | | else break;
|
| | | }
|
| | | if (thatNode->nType == -1) { //找到下一个虚顶点
|
| | | if (!thatNode->OutProcAllDone) {
|
| | | MergeVPSubSerialNodes(thatNode->nId); //从虚顶点继续
|
| | | }
|
| | | }
|
| | | }
|
| | | // 同一个出发点的 下一条弧
|
| | | theArc = theArc->tlink;
|
| | | };
|
| | | theNode.OutProcAllDone = 1;
|
| | |
|
| | | return 0;
|
| | | }
|
| | |
|
| | | // 合并从 nNodeId 虚节点发出的 各个单行 Nodes; 直到下一个 多输出的虚节点
|
| | | int CMTerm1View::MergeVPSerialNodes(int nNodeId)
|
| | | {
|
| | | node& theNode = nodes[nNodeId];
|
| | |
|
| | | arc* theArc = theNode.firstOut;
|
| | | while (theArc != 0) {
|
| | | // 从当前弧 取出一个顶点
|
| | | node* thisNode = theArc->headvex;
|
| | | // 从这个顶点,找到下一个顶点
|
| | | if (thisNode->outdegree == 1 && thisNode->firstOut != 0) {
|
| | | node* thatNode = thisNode->firstOut->headvex;
|
| | | while (thatNode->nType != -2 && thatNode->indegree ==1 && thatNode->outdegree <= 1) {
|
| | | if (thatNode->nType == typeOUT || thatNode->nType == typeSET || thatNode->nType == typeRESET) {
|
| | | //break;
|
| | | }
|
| | | MergeNode(thisNode->nId, thatNode->nId);
|
| | | if (thatNode->firstOut) thatNode = thatNode->firstOut->headvex;
|
| | | else break;
|
| | | }
|
| | | if (thatNode->nType == -1) { //找到下一个虚顶点
|
| | | if (!thatNode->OutProcAllDone) {
|
| | | MergeVPSerialNodes(thatNode->nId); //从虚顶点继续
|
| | | }
|
| | | }
|
| | | }
|
| | | // 同一个出发点的 下一条弧
|
| | | theArc = theArc->tlink;
|
| | | };
|
| | | theNode.OutProcAllDone = 1;
|
| | |
|
| | | return 0;
|
| | | }
|
| | |
|
| | | //从 X,Y 点,向上查找 虚节点,最多终止于 endy;
|
| | | int CMTerm1View::FindVPNode(int x, int y, int endy)
|
| | | {
|
| | | int nNodeId = 0;
|
| | | for (int i = nNodeCount -1 ; i>=1; i--) {
|
| | | if (nodes[i].bEnable && nodes[i].nType == -1 && nodes[i].nCellX == x && nodes[i].nCellY <= y &&nodes[i].nCellY >=endy )
|
| | | {
|
| | | nNodeId = i; break;
|
| | | }
|
| | | }
|
| | | return nNodeId;
|
| | | }
|
| | |
|
| | |
|
| | | int CMTerm1View::ScanVPAOV(int nVPNodeId1, int nVPNodeId2)
|
| | | {
|
| | | MergeParallelNodeWithinVP(nVPNodeId1, nVPNodeId2);
|
| | | return 0;
|
| | | }
|
| | | int CMTerm1View::ScanAOV1(int nNodeId)
|
| | | {
|
| | | node& theNode = nodes[nNodeId];
|
| | | CString s1;
|
| | | int nInput = theNode.indegree;
|
| | | int nOutput = theNode.outdegree;
|
| | | // s1.Format(_T("%d type %d op %s coil %s in %d out %d"), theNode.nId, theNode.nType, theNode.Op, theNode.CoilName, theNode.indegree, theNode.outdegree);
|
| | | // DbgLog(s1);
|
| | | if (theNode.InProcCount < theNode.indegree) return 0;
|
| | | // 虚拟结点,完成所有输入。
|
| | |
|
| | | stProgSection prog2;
|
| | | if (theNode.outdegree > 0) {
|
| | | // 一直搜索下去,遇到 输入不为0的 虚节点 时 停止,进行下一个迭代
|
| | | arc* theArc = theNode.firstOut;
|
| | | int allOutputMerged = 1;
|
| | | int allOutputSimple = 1;
|
| | | for (int i = 0; i < nOutput && theArc != 0; i++) {
|
| | | node* thisNode = theArc->headvex;
|
| | | thisNode->InProcCount++;
|
| | | s1.Format(_T("- %d type %d op %s coil %s in %d out %d"), thisNode->nId, thisNode->nType, thisNode->Op, thisNode->CoilName, thisNode->indegree, thisNode->outdegree);
|
| | | DbgLog(s1);
|
| | | s1 = thisNode->prog1.ToText();
|
| | | DbgLog(_T("------ \r\n") + s1);
|
| | |
|
| | | arc* thisArc = thisNode->firstOut;
|
| | | if (thisNode->outdegree > 0) { allOutputMerged = 0; }
|
| | | if (thisNode->nType == typeOUT || thisNode->nType == typeSET || thisNode->nType == typeRESET) {
|
| | | thisNode->prog1.bModifyVal = 0;
|
| | | }
|
| | | else {
|
| | | allOutputSimple = 0;
|
| | | thisNode->prog1.bModifyVal = 1;
|
| | | }
|
| | | while (thisArc) {
|
| | | thisNode = thisArc->headvex;
|
| | | thisNode->InProcCount++;
|
| | | s1.Format(_T("-- %d type %d op %s coil %s in %d out %d"), thisNode->nId, thisNode->nType, thisNode->Op, thisNode->CoilName, thisNode->indegree, thisNode->outdegree);
|
| | | DbgLog(s1);
|
| | | if (thisNode->nType > 0) //thatNode.indegree == 1 && thatNode.outdegree == 1) |
| | | {
|
| | | thisArc = thisNode->firstOut;
|
| | | // node* thatNode = thisArc->headvex;
|
| | |
|
| | | }
|
| | | else {
|
| | | ScanVPAOV(nNodeId, thisNode->nId);
|
| | |
|
| | | if (thisNode->InProcCount >= thisNode->indegree) {
|
| | | s1.Format(_T("-> %d type %d op %s coil %s in %d out %d"), thisNode->nId, thisNode->nType, thisNode->Op, thisNode->CoilName, thisNode->indegree, thisNode->outdegree);
|
| | | DbgLog(s1);
|
| | |
|
| | | ScanAOV1(thisNode->nId);
|
| | | }
|
| | | break;
|
| | | }
|
| | | }
|
| | | // if (thatNode.nType > 0) {
|
| | | // prog2.Append(thatNode.prog1);
|
| | | // }
|
| | | //RemoveArc(theArc->nId);
|
| | | // 同一个出发点的 下一条弧
|
| | | theArc = theArc->tlink;
|
| | | }
|
| | | if (theNode.outdegree >= 2 && allOutputMerged) {
|
| | | s1.Format(_T(" Merge Output %d %d allsimple = %d "), nNodeId,theNode.outdegree,allOutputSimple);
|
| | | DbgLog(s1);
|
| | | if (allOutputSimple) {
|
| | | arc * thisArc = theNode.firstOut;
|
| | | node* thisNode = thisArc->headvex;
|
| | | thisArc = thisArc->tlink;
|
| | | for (int i = 1; i < nOutput && thisArc != 0; i++) {
|
| | | node* thatNode = thisArc->headvex;
|
| | | thisNode->prog1 += thatNode->prog1;
|
| | | arc * tempArc = thisArc->tlink;
|
| | | RemoveArc(thisArc->nId);
|
| | | thisArc = tempArc;
|
| | | RemoveNode(thatNode->nId);
|
| | | }
|
| | | }
|
| | | else {
|
| | | arc* thisArc = theNode.firstOut;
|
| | | node* thisNode = thisArc->headvex;
|
| | | stProgSection prog2;
|
| | | prog2.Append(CMTerm1Doc::stProg(OP_PSHS));
|
| | | int bLastModify = 1;
|
| | | prog2 += thisNode->prog1;
|
| | | if (thisNode->prog1.bModifyVal == 0) { bLastModify = 0; s1.Format(_T(" ModifyVal = 0, %s"), thisNode->prog1.ToText()); }
|
| | | thisArc = thisArc->tlink;
|
| | |
|
| | | for (int i = 1; i < nOutput && thisArc != 0; i++) {
|
| | | node* thatNode = thisArc->headvex;
|
| | | if (i == nOutput - 1) { // 最后一个
|
| | | prog2.Append(CMTerm1Doc::stProg(OP_POPS));
|
| | | }
|
| | | else {
|
| | | if (bLastModify) { prog2.Append(CMTerm1Doc::stProg(OP_RDS)); }
|
| | | }
|
| | | if (thisNode->prog1.bModifyVal == 0) { bLastModify = 0;s1.Format(_T(" ModifyVal = 0, %s"), thisNode->prog1.ToText()); }
|
| | | else { bLastModify = 1; }
|
| | | prog2 += thatNode->prog1;
|
| | | arc* tempArc = thisArc->tlink;
|
| | | RemoveArc(thisArc->nId);
|
| | | thisArc = tempArc;
|
| | | RemoveNode(thatNode->nId);
|
| | | }
|
| | | thisNode->prog1 = prog2;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | return 0;
|
| | | /*
|
| | | node& theNode = nodes[nNodeId];
|
| | |
|
| | | arc* theArc = theNode.firstOut;
|
| | | while (theArc != 0) {
|
| | | // 从当前弧 取出一个顶点
|
| | | node* thisNode = theArc->headvex;
|
| | | // 从这个顶点,找到下一个顶点
|
| | | if (thisNode->outdegree == 1 && thisNode->firstOut != 0) {
|
| | | node* thatNode = thisNode->firstOut->headvex;
|
| | | while (thatNode->nType != -1) {
|
| | | if (thatNode->nType == typeOUT || thatNode->nType == typeSET || thatNode->nType == typeRESET) {
|
| | | break;
|
| | | }
|
| | | MergeNode(thisNode->nId, thatNode->nId);
|
| | | if (thatNode->firstOut) thatNode = thatNode->firstOut->headvex;
|
| | | else break;
|
| | | }
|
| | | if (thatNode->nType == -1) { //找到下一个虚顶点
|
| | | if (!thatNode->OutProcAllDone) {
|
| | | MergeSerialNodes(thatNode->nId); //从虚顶点继续
|
| | | }
|
| | | }
|
| | | }
|
| | | // 同一个出发点的 下一条弧
|
| | | theArc = theArc->tlink;
|
| | | };
|
| | | theNode.OutProcAllDone = 1;
|
| | | */
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 试用 AOV 方式 梯形图转Prog
|
| | | /// </summary>
|
| | | /// <returns></returns>
|
| | | int CMTerm1View::TransLDSToProgAOV()
|
| | | {
|
| | | CMTerm1Doc* pDoc = GetDocument();
|
| | | CString s1;
|
| | | s1.Format(_T("Trans LDS to PRrog"));
|
| | | DbgLog(s1);
|
| | | s1.Format(_T("AOV 方式 将梯形图转成prog格式"));
|
| | | DbgLog(s1);
|
| | |
|
| | | //梯形图 ROW数量
|
| | | s1.Format(_T("总计行数 %d"), m_nTotalRow);
|
| | | DbgLog(s1);
|
| | | s1.Format(_T("Total Lines %d"), m_nTotalRow);
|
| | | DbgLog(s1);
|
| | |
|
| | | //分段
|
| | | int nDivCount = 0;
|
| | | //分段 点集合
|
| | | int Divs[100] = { 0 };
|
| | | for (int i = 0; i < m_nTotalRow+5 ; i++)
|
| | | {
|
| | | int nRow = i;
|
| | | int bConnected = 0;
|
| | | //扫描程序,建立十字链表?
|
| | | for (int j = 0; j < m_CellPerLine; j++)
|
| | | {
|
| | | int nCol = j;
|
| | | if (Cells[nRow][nCol].bLeftLineDn)
|
| | | {
|
| | | bConnected = 1;
|
| | | //s1.Format(_T("row==%d col==%d 有左下竖线!!!"), nRow, nCol);
|
| | | //DbgLog(s1);
|
| | | break;
|
| | | }
|
| | | }
|
| | | if (!bConnected)
|
| | | {
|
| | | //找到一处分界点
|
| | | Divs[nDivCount] = i;
|
| | | s1.Format(_T("Div at Line %d 是 ::::::::::::分界点"), nRow);
|
| | | DbgLog(s1);
|
| | | nDivCount++;
|
| | | }
|
| | | }
|
| | | stProgSection allprogs;
|
| | | //每段单独处理
|
| | | for (int i = 0; i < nDivCount; i++)
|
| | | {
|
| | | int nStartLine, nEndLine;
|
| | | nNodeCount = 0;
|
| | | if (i == 0)
|
| | | {
|
| | | nStartLine = 0;
|
| | | nEndLine = Divs[i];
|
| | | }
|
| | | else
|
| | | {
|
| | | nStartLine = Divs[i - 1] + 1;
|
| | | nEndLine = Divs[i];
|
| | | }
|
| | | s1.Format(_T("本段行号 起始-终止: %d - %d "), nStartLine, nEndLine);
|
| | | DbgLog(s1);
|
| | | //s1.Format(_T("Process Line %d - %d "), nStartLine, nEndLine);
|
| | | //DbgLog(s1);
|
| | | int nCounts[20] = { 0 };
|
| | | int nCounts2[20] = { 0 };
|
| | | int nCounts3[20] = { 0 };
|
| | | s1.Empty();
|
| | | stProgSection section1;
|
| | | CString s2;
|
| | | int PrevNode = 0;
|
| | | nNodeCount = 1; //清理存储的顶点和弧数据。
|
| | | nArcCount = 1;
|
| | | AddNode(-2, 0, 0, _T("Mother")); //增加母线顶点
|
| | | for (int j = nStartLine; j <= nEndLine; j++) {
|
| | | int nPosX = 0;
|
| | | PrevNode = 1; //从母线开始
|
| | | s1.Empty();
|
| | | for (int k = 0; k < m_CellPerLine; k++) {
|
| | | stCell theCell = Cells[j][k];
|
| | | int nNextX = 1;
|
| | | int nType;
|
| | | int bRightLineUp = 0;
|
| | | if (k < m_CellPerLine - 1) { bRightLineUp = Cells[j][k + 1].bLeftLineUp; }
|
| | | nType = theCell.nType;
|
| | | if (nType == typeNone) { PrevNode = 0; } // 不连接母线;
|
| | | if (nType ) {
|
| | | if (nType == typeLine1 && !theCell.bLeftLineUp && !theCell.bLeftLineDn && !bRightLineUp) continue;
|
| | | if (nType == typeExt1 || nType == typeExt2 || nType == typeExt3 || nType == typeExt4) continue;
|
| | | if (k!=0 && theCell.bLeftLineDn && !theCell.bLeftLineUp) {
|
| | | PrevNode = AddNode(-1, k, j, _T("VP"),PrevNode);
|
| | | }
|
| | | if (k != 0 && theCell.bLeftLineUp) {
|
| | | int VPNodeId = 0;
|
| | | VPNodeId = FindVPNode(k , j, nStartLine);
|
| | | PrevNode = VPNodeId;
|
| | | }
|
| | |
|
| | |
|
| | | switch (nType) {
|
| | | case typeLine1:
|
| | |
|
| | | break;
|
| | | case typeEND:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeNO:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeNC:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName +_T("/"), PrevNode);
|
| | | break;
|
| | | case typePP:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typePN:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeNOT:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeDF:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeDF_:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeOUT:
|
| | | case typeSET:
|
| | | case typeRESET:
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeCMP:
|
| | | nNextX = 3;
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeExt1:
|
| | | case typeExt2:
|
| | | case typeExt3:
|
| | | break;
|
| | | case typeTM:
|
| | | nNextX = 3;
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeFN1:
|
| | | nNextX = 2;
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeFN2:
|
| | | nNextX = 3;
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeFN3:
|
| | | nNextX = 4;
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeFN4:
|
| | | nNextX = 5;
|
| | | PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
|
| | | break;
|
| | | case typeCoil:
|
| | | break;
|
| | | default:
|
| | | break;
|
| | | }
|
| | | s2 = Cells[j][k].sCoilName;
|
| | | //k += nStep - 1;
|
| | | s1 += s2 + _T(" ") + intToString(nNextX) + _T(" ");
|
| | |
|
| | | if (bRightLineUp) {
|
| | | int VPNodeId = 0;
|
| | | VPNodeId = FindVPNode(k + 1, j, nStartLine);
|
| | | AddArc(PrevNode, VPNodeId);
|
| | | PrevNode = VPNodeId;
|
| | | }
|
| | | }
|
| | | }
|
| | | DbgLog(s1);
|
| | | }
|
| | | //输出已经生成的 AOV 图 顶点信息
|
| | | for (int j = 1; j < nNodeCount; j++) {
|
| | | s1.Format(_T("%d %d %s %s in %d out %d %s "), j, nodes[j].nType,nodes[j].Op, nodes[j].CoilName,nodes[j].indegree,nodes[j].outdegree, nodes[j].prog1.ToText());
|
| | | DbgLog(s1);
|
| | | }
|
| | | //输出AOV图的 弧 数据 |
| | | for (int j = 1; j < nArcCount; j++) {
|
| | | s1.Format(_T("%3d %2d - %2d "), j, arcs[j].tailNode, arcs[j].headNode);
|
| | | // DbgLog(s1);
|
| | | }
|
| | |
|
| | | for (int n = 1; n < 8; n++) {
|
| | | s1.Format(_T("处理步骤 %d "), n);
|
| | | DbgLog(s1);
|
| | | for (int j = 1; j < nNodeCount; j++) {
|
| | | if (nodes[j].bEnable) nodes[j].OutProcAllDone = 0;
|
| | | }
|
| | | // 处理 AOV 图
|
| | | // 从 母线 开始 |
| | | //串联归并 // 归并原则, 普通节点,非虚节点, 两个虚节点之间 多个连续的,归并, 非输出。
|
| | | s1.Format(_T("合并串联的节点 %d "), n);
|
| | | DbgLog(s1);
|
| | | MergeVPSubSerialNodes(1);
|
| | | // 处理虚节点
|
| | | // 虚节点的多输入处理, 单 OR 或者 多 ORS。
|
| | | // 虚节点的输出处理, |
| | | // 对于后续还有共同虚节点的输出, 第一个不处理,
|
| | | // 第二个,单不处理,多处理 ST, 后面由虚节点再 ORS, ANS。
|
| | | // 对于直接输出的,如果后面没有改变的输出, 直接输出不处理。
|
| | | // 对于后面还有改变的, PSHS, RDS, POPS
|
| | | // 另外,可以后期简化, ST 后紧跟 ORS 的, 简化为 OR。
|
| | | // PSHS RDS POPS 后跟不改变的。 简化
|
| | | s1.Format(_T("处理虚节点的输出 %d "), n);
|
| | | DbgLog(s1);
|
| | | ScanAOV1(1);
|
| | | if (nodes[2].outdegree == 0) break;
|
| | | }
|
| | | // 输出处理完的 AOV 图
|
| | | s1.Format(_T("处理完的AOV图"));
|
| | | DbgLog(s1);
|
| | | for (int j = 2; j < nNodeCount; j++) {
|
| | | CStringA s2;
|
| | | if (nodes[j].bEnable) {
|
| | | s1.Format(_T("%d type %d op %s coil %s in %d out %d"), j, nodes[j].nType, nodes[j].Op, nodes[j].CoilName, nodes[j].indegree, nodes[j].outdegree);
|
| | | DbgLog(s1);
|
| | | s1 = nodes[j].prog1.ToText();
|
| | | DbgLog(s1);
|
| | | }
|
| | | }
|
| | | allprogs += nodes[2].prog1;
|
| | | nodes[2].prog1.Progs.clear();
|
| | | }
|
| | | s1.Format(_T("完整的PLC程序 \r\n"));
|
| | | s1 += allprogs.ToText();
|
| | | DbgLog(s1);
|
| | | // 创建 AOV 图
|
| | |
|
| | | //输出程序
|
| | | int n = (int)allprogs.Progs.size();
|
| | | s1.Format(_T("总程序步数 %d "), n);
|
| | | DbgLog(s1);
|
| | | s1.Format(_T("all prog steps %d "), n);
|
| | | DbgLog(s1);
|
| | | for (int i = 0; i < n; i++)
|
| | | {
|
| | | int optype = allprogs.Progs[i].nOpType1;
|
| | | allprogs.Progs[i].PairTo = 0;//??????????
|
| | | allprogs.Progs[i].nBinStep = i;
|
| | | CStringA OpTxtA, OpShowTxtA;
|
| | | CString OpTxt, OpShowTxt;
|
| | | pDoc->OpToTxt(optype, OpTxtA);
|
| | | pDoc->OpToShowTxt(optype, OpShowTxtA);
|
| | | OpTxt = OpTxtA;
|
| | | OpShowTxt = OpShowTxtA;
|
| | | s1.Format(_T("%d %s %s"), optype, OpTxt, OpShowTxt);
|
| | | pDoc->Progs[i] = allprogs.Progs[i];
|
| | | DbgLog(s1);
|
| | | }
|
| | | pDoc->m_nProgSteps = n;
|
| | | return 0;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 梯形图转Prog
|
| | |
| | | {
|
| | | int nRow = i;
|
| | | int bConnected = 0;
|
| | | for (int j = 0; j < m_CellPerLine; j++) |
| | | for (int j = 0; j < m_CellPerLine; j++) |
| | | {
|
| | | int nCol = j;
|
| | | if (Cells[nRow][nCol].bLeftLineDn)
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | stProgSection allprogs;
|
| | | stProgSection allprogs;
|
| | | //每段单独处理
|
| | | for (int i = 0; i < nDivCount; i++)
|
| | | {
|
| | |
| | | {
|
| | | nStartLine = 0;
|
| | | nEndLine = Divs[i];
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | nStartLine = Divs[i - 1]+1;
|
| | |
| | | {
|
| | | 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);
|
| | |
| | | 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;
|
| | |
| | | OpShowTxt = OpShowTxtA;
|
| | | s1.Format(_T("%d %s %s"), optype, OpTxt, OpShowTxt);
|
| | | pDoc->Progs[i] = allprogs.Progs[i];
|
| | | // DbgLog(s1);
|
| | | DbgLog(s1);
|
| | | }
|
| | | pDoc->m_nProgSteps = n;
|
| | | return 0;
|
| | |
| | | /// </summary>
|
| | | /// <param name="nStartLine"></param>
|
| | | /// <param name="nEndLine"></param>
|
| | | /// <param name="nPosY"></param>
|
| | | /// <param name="nPosX"></param>
|
| | | /// <param name="nLevel"></param>
|
| | | /// <param name="nPosY">行</param>
|
| | | /// <param name="nPosX">列</param>
|
| | | /// <param name="nLevel">层级</param>
|
| | | /// <param name="progsec">prog格式的指令集</param>
|
| | | /// <param name="sProgSec">指令集</param>
|
| | | /// <param name="nSteps">程序步数</param>
|
| | | /// <returns></returns>
|
| | | int CMTerm1View::ScanLDSCells(int nStartLine, int nEndLine, int nPosY, int nPosX, int nLevel, stProgSection & progsec, CString & sProgSec, int &nSteps)
|
| | | int CMTerm1View::ScanLDSCells(int nStartLine, int nEndLine, int nPosY, int nPosX,
|
| | | int nLevel, stProgSection & progsec, CString & sProgSec, int &nSteps)
|
| | | {
|
| | | // TODO: 在此处添加实现代码.
|
| | | CString s1;
|
| | | int nCurPosX, nCurPosY;
|
| | | int nNextX = 1;//步长
|
| | | int nNextX = 1;//步长(下个起始点移动的距离)
|
| | | nCurPosY = nPosY;
|
| | | nCurPosX = nPosX;
|
| | | int nCoilType, CoilAddr;
|
| | | // int nCoilType, CoilAddr;
|
| | | CMTerm1Doc* pDoc = GetDocument();
|
| | | 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;
|
| | |
| | | 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;
|
| | | }
|
| | | //左上是否有链接
|
| | | //右侧一格的左上是否有链接
|
| | | 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)
|
| | | {
|
| | |
| | | s1.Format(_T("LeftUp %d LeftDn %d"), nLeftUpCon, nLeftDnCon);
|
| | | DbgLog(s1);
|
| | |
|
| | | //左侧下面有连接,那么扫描到这个竖线时返回,继续扫描左侧下面的内容。
|
| | | //右侧一格的左侧下面有连接,那么扫描到这个竖线时返回,继续扫描左侧下面的内容。
|
| | | if (nLeftDnCon)
|
| | | {
|
| | | return 1;
|
| | | }
|
| | | // 左侧下面没有连接,那么这个就是左面最后的单元,开始处理右面的单元。
|
| | | //右侧一格的左侧下面没有连接,那么这个就是左面最后的单元,开始处理右面的单元。
|
| | | else
|
| | | {
|
| | | if (nLeftUpCon)
|
| | |
| | |
|
| | | if (nRightCon == 1)
|
| | | {
|
| | | //s1.Format(_T(">>>> Go %d : %d , level %d "), nLineTop, j + nNextX, nLevel);
|
| | | //DbgLog(s1);
|
| | | //CString ProgSec;
|
| | | //int theSteps = 0;
|
| | | //stProgSection thisprogsec;
|
| | | 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);
|
| | | //这有问题,应该是在最高点的时候,单独进行一次转换?
|
| | | int r = ScanLDSCells(nStartLine, nEndLine, nLineTop, j + nNextX, nLevel, thisprogsec, ProgSec, theSteps);
|
| | |
|
| | | //sProgSec += ProgSec;
|
| | | //nSteps += theSteps;
|
| | | //progsec += thisprogsec;
|
| | | //s1.Format(_T("<<<< Re %d : %d , Result %d "), nLineTop, j + nNextX, r);
|
| | | //DbgLog(s1);
|
| | | sProgSec += ProgSec;
|
| | | nSteps += theSteps;
|
| | | progsec += thisprogsec;
|
| | | s1.Format(_T("<<<< Re %d : %d , Result %d "), nLineTop, j + nNextX, 0);
|
| | | DbgLog(s1);
|
| | | continue;
|
| | | }
|
| | | else
|
| | | {
|
| | |
| | | DbgLog(s1);
|
| | | if (nRightCount == 0)
|
| | | {
|
| | |
|
| | | //这里是不是应该做点什么
|
| | | }
|
| | | else if (res[nRightCount - 1] == 0)
|
| | | {
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | //如果没有竖线直接翻译
|
| | | else
|
| | | {
|
| | | Translate2Prog(nType, j + nNextX, nLevel, sCellName, progsec, sProgSec, nSteps);
|
| | | }
|
| | | /*
|
| | | #pragma region 根据单元格类型转换为指令和prog
|
| | |
|
| | | if (nType == typeNO)
|
| | | {
|
| | | 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;
|
| | | //先看往上面有没有连接
|
| | | 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);
|
| | | theprog.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;
|
| | |
| | | }
|
| | |
|
| | | #pragma endregion
|
| | |
|
| | | */
|
| | | }
|
| | | return 0;
|
| | | }
|
| | | // 记录y,x
|
| | |
|
| | | 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();
|
| | |
|
| | | 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;
|
| | |
|
| | | 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>
|
| | | /// 全部图形校验
|
| | |
| | | /// 计划在第一个返回值中使用不同的错误代码代表不同的错误类型,
|
| | | /// 并在第二个返回值中填充错误提示信息
|
| | | /// </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);
|
| | | }
|