// MultiTerminal2View.cpp: CMTerm1View 类的实现 // #include "pch.h" #include "framework.h" // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 // ATL 项目中进行定义,并允许与该项目共享文档代码。 #ifndef SHARED_HANDLERS #include "MTerm1.h" #endif #include "MTerm1Doc.h" #include "MTerm1View.h" #include "ChildFrm.h" #include "DialogSetCoil.h" #include "DialogSetData.h" #include "DialogIoComment.h" #include "KDefine.h" #include "MainFrm.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CMTerm1View IMPLEMENT_DYNCREATE(CMTerm1View, CScrollView) /// /// 消息映射 /// 是 MFC 中用于将 Windows 消息(如鼠标点击、按键等)映射到成员函数的机制。 /// BEGIN_MESSAGE_MAP(CMTerm1View, CScrollView) // 标准打印命令 ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CScrollView::OnFilePrintPreview) ON_WM_CREATE() ON_WM_TIMER() ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() ON_WM_CONTEXTMENU() ON_WM_INITMENUPOPUP() ON_COMMAND(ID_RECT_SELECT, &CMTerm1View::OnRectSelect) ON_UPDATE_COMMAND_UI(ID_RECT_SELECT, &CMTerm1View::OnUpdateRectSelect) ON_COMMAND(ID_TEXT_FIRST, &CMTerm1View::OnTextFirst) ON_UPDATE_COMMAND_UI(ID_TEXT_FIRST, &CMTerm1View::OnUpdateTextFirst) ON_COMMAND(ID_INSERT_BLANK_LINE, &CMTerm1View::OnInsertBlankLine) ON_UPDATE_COMMAND_UI(ID_INSERT_BLANK_LINE, &CMTerm1View::OnUpdateInsertBlankLine) ON_COMMAND(ID_DELETE_BLANK_LINE, &CMTerm1View::OnDeleteBlankLine) ON_UPDATE_COMMAND_UI(ID_DELETE_BLANK_LINE, &CMTerm1View::OnUpdateDeleteBlankLine) ON_COMMAND(ID_DISPLAY_COMMENTS, &CMTerm1View::OnDisplayComments) ON_UPDATE_COMMAND_UI(ID_DISPLAY_COMMENTS, &CMTerm1View::OnUpdateDisplayComments) ON_COMMAND(ID_MONITOR, &CMTerm1View::OnMonitor) ON_UPDATE_COMMAND_UI(ID_MONITOR, &CMTerm1View::OnUpdateMonitor) ON_COMMAND(ID_PROG_CONVERT, &CMTerm1View::OnProgConvert) ON_UPDATE_COMMAND_UI(ID_PROG_CONVERT, &CMTerm1View::OnUpdateProgConvert) ON_COMMAND(ID_PROG_CANCEL_EDIT, &CMTerm1View::OnProgCancelEdit) ON_UPDATE_COMMAND_UI(ID_PROG_CANCEL_EDIT, &CMTerm1View::OnUpdateProgCancelEdit) ON_COMMAND(ID_INPUT_IO_COMMENT, &CMTerm1View::OnInputIoComment) // ON_UPDATE_COMMAND_UI_RANGE(ID_INDICATOR_MACHINE_TYPE, ID_INDICATOR_INFO_DISPLAY, OnUpdateIndicators) ON_COMMAND_RANGE(ID_INDICATOR_MACHINE_TYPE, ID_INDICATOR_INFO_DISPLAY, NULL) // ON_UPDATE_COMMAND_UI(ID_INDICATOR_MACHINE_TYPE, &CMTerm1View::OnUpdateMachineType) // ON_UPDATE_COMMAND_UI(ID_INDICATOR_PROGRAM_POS, &CMTerm1View::OnUpdateProgramPos) // ON_UPDATE_COMMAND_UI(ID_INDICATOR_CONNECTIVITY, &CMTerm1View::OnUpdateConnectivity) // ON_UPDATE_COMMAND_UI(ID_INDICATOR_RUN_STATUS, &CMTerm1View::OnUpdateRunStatus) // ON_UPDATE_COMMAND_UI(ID_INDICATOR_MONITOR_STATUS, &CMTerm1View::OnUpdateMonitorStatus) // ON_UPDATE_COMMAND_UI(ID_INDICATOR_TARGET_ADDRESS, &CMTerm1View::OnUpdateTargetAddress) // ON_UPDATE_COMMAND_UI(ID_INDICATOR_INFO_DISPLAY, &CMTerm1View::OnUpdateDisplayComments) // ON_COMMAND(ID_INDICATOR_MONITOR_STATUS, &CMTerm1View::OnIndicatorMonitorStatus) // ON_UPDATE_COMMAND_UI(ID_INDICATOR_MONITOR_STATUS, &CMTerm1View::OnUpdateIndicatorMonitorStatus) ON_WM_KEYDOWN() END_MESSAGE_MAP() // CMTerm1View 构造/析构 CMTerm1View::CMTerm1View() noexcept { // TODO: 在此处添加构造代码 } CMTerm1View::~CMTerm1View() { } BOOL CMTerm1View::PreCreateWindow(CREATESTRUCT& cs) { // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 return CScrollView::PreCreateWindow(cs); } /// /// MFC 中的一个函数,它在视图首次显示之前被调用 /// void CMTerm1View::OnInitialUpdate() { CScrollView::OnInitialUpdate(); //创建了三种不同的字体 TextFont.CreateFont(13, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("宋体")); MonTextFont.CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("宋体")); AnnoFont.CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("宋体")); //获取了状态栏的引用并存储在 m_pStatusBar 成员变量中 m_pStatusBar = ((CChildFrame *)GetParentFrame())->GetStatusBar(); CSize sizeTotal; // TODO: 计算此视图的合计大小 sizeTotal.cx = m_LeftMargin + m_CellWidth* m_CellPerLine + m_CellWidth *2; sizeTotal.cy = 2000; //设置了滚动大小 SetScrollSizes(MM_TEXT, sizeTotal); CString s1;//没啥用 //设置了两个定时器,一个间隔为50毫秒,另一个为10毫秒。 SetTimer(1, 50,NULL); SetTimer(2, 10, NULL); } // CMTerm1View 绘图 void CMTerm1View::OnDraw(CDC* pDC) { CMTerm1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 CString s1;//没啥用 needReDraw = 1; DrawLDSGraph(pDC); needReDraw = 0; } // CMTerm1View 打印,MFC 函数,用于准备打印。 BOOL CMTerm1View::OnPreparePrinting(CPrintInfo* pInfo) { // 默认准备 return DoPreparePrinting(pInfo); } // MFC 函数,用于在打印开始之前进行初始化。 void CMTerm1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: 添加额外的打印前进行的初始化过程 } //MFC 函数,用于在打印结束后进行清理。 void CMTerm1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: 添加打印后进行的清理过程 } // CMTerm1View 诊断 #ifdef _DEBUG //函数用于验证对象的有效性。 void CMTerm1View::AssertValid() const { CScrollView::AssertValid(); } // 函数用于将对象的内容转储到指定的上下文。 void CMTerm1View::Dump(CDumpContext& dc) const { CScrollView::Dump(dc); } //函数返回与此视图关联的文档对象。 CMTerm1Doc* CMTerm1View::GetDocument() const // 非调试版本是内联的 { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMTerm1Doc))); return (CMTerm1Doc*)m_pDocument; } #endif //_DEBUG //MFC 函数,用于处理视图的创建事件。 int CMTerm1View::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CScrollView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: 在此添加您专用的创建代码 return 0; } /// /// 用于重新绘制视图。 /// /// int CMTerm1View::DoReDraw() { CPoint scroll1; scroll1 = this->GetScrollPosition(); CClientDC dc1(this); XFORM xform1; xform1.eM11 = 1; xform1.eM12 = 0; xform1.eM21 = 0; xform1.eM22 = 1; xform1.eDx = float(-scroll1.x); xform1.eDy = float(-scroll1.y); XFORM xform2 = { 1, 0, 0, 1, 0, 0 }; dc1.SetGraphicsMode(GM_ADVANCED); dc1.SetWorldTransform(&xform1); DrawLDSGraph(&dc1); return 0; } /// /// 滚动到特定单元格 /// 函数内部计算了单元格的总高度,考虑了是否显示注释 /// /// /// /// int CMTerm1View::ScrollToCell(int nRow, int nCol) { int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); CSize sizeTotal; // TODO: 计算此视图的合计大小 sizeTotal.cx = m_LeftMargin + m_CellWidth * m_CellPerLine + m_CellWidth * 2; sizeTotal.cy = m_TopMargin + CellTotalHeight * (m_nTotalRow ); CSize sizeSb; GetScrollBarSizes(sizeSb); POINT pt1; pt1.x = 0; pt1.y = nRow * CellTotalHeight; ScrollToPosition(pt1); return 0; } /// /// 滚动单元格进入视图(未完成的功能) /// /// /// /// int CMTerm1View::ScrollCellIntoView(int nRow, int nCol) { int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); return 0; } /// /// 检查单元格是否在视图中(未完成的功能) /// /// /// /// int CMTerm1View::isCellInView(int nRow, int nCol) { int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); return 0; } /// /// 用于在视图中绘制图形的主要函数 /// /// 文档 /// int CMTerm1View::DrawLDSGraph(CDC* pDC) { // TODO: 在此处添加实现代码. CString s1;//没啥用 //验证文档引用 CMTerm1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return false; if (m_bMonitoring) { pDoc->DoPLCMonitor(); } int x1, y1, x2, y2; // RECT rect1; int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); int nDataType, nDataAddr; int nStat; CBrush br0(BkColor);//背景颜色 CBrush br01(BkEditColor);//编辑(选中)状态下的背景颜色 int nRow, nCol; CRect rect0; this->GetClientRect(&rect0); int viewWidth = rect0.Width(); CPoint scroll1; scroll1 = this->GetScrollPosition(); int nFirstVisibleLine;//用于确定可见行范围-起始位置 int nLastVisibleLine;//用于确定可见行范围-终止位置 //通过滚动位置和视图的高度计算上述两个值 nFirstVisibleLine = (scroll1.y - m_TopMargin) / CellTotalHeight; nLastVisibleLine = (rect0.Height() + scroll1.y - m_TopMargin) / CellTotalHeight + 1; if (nFirstVisibleLine < 0) { nFirstVisibleLine = 0; } if (nLastVisibleLine < 0) { nLastVisibleLine = 0; } //选择字体 CFont *pOldFont; pOldFont = (CFont *)pDC->SelectObject(&TextFont); for (int i = nFirstVisibleLine; i < nLastVisibleLine && i < 1000; i++) { // 画一行 单元 nRow = i; int x0, y0; x0 = m_LeftMargin; y0 = m_TopMargin + CellTotalHeight * i; y2 = y0 + CellTotalHeight; //画背景 if (needReDraw) { // 左半部分 if (scroll1.x < x0) { CRect rect1(scroll1.x, y0, x0, y2); pDC->FillRect(&rect1, &br0); } //中间部分 x1 = max(scroll1.x, x0); x2 = min(scroll1.x + viewWidth, x0 + m_CellPerLine * m_CellWidth); CRect rect2(x1, y0, x2, y2); //背景颜色 if (!Cells[nRow][0].bEditing){ pDC->FillRect(&rect2, &br0); } else { pDC->FillRect(&rect2, &br01); } // 右边部分 if (x2 < scroll1.x + viewWidth) { CRect rect3(x2, y0, scroll1.x + viewWidth, y2); pDC->FillRect(&rect3, &br0); } if (m_FocusRow == i) DrawFocusRect(pDC); } //* // 画本行左侧母线 x1 = m_LeftMargin; y1 = m_TopMargin + CellTotalHeight * i; x2 = x1; y2 = y1 + CellTotalHeight; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); //画左侧母线小短横线 x1 = m_LeftMargin; y1 = m_TopMargin + CellTotalHeight * i + m_LinePosY; x2 = x1 + 3; y2 = y1; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); // 如果本行第一个ST是程序段的起始,输出程序步数 //*/ int nType = Cells[nRow][0].nType; int nProgSetp = Cells[nRow][0].nProgStep; if (nType == typeNO || nType == typeNC || nType == typeCMP) { int nPairTo = pDoc->Progs[nProgSetp].PairTo; int nPairOp = 0; if (nPairTo) nPairOp = pDoc->Progs[nPairTo].nOpType1; if (nPairOp == 0) { //程序段开始 //在当前行的左侧输出 当前 程序步数 s1.Format(_T(" %d"), nProgSetp); CRect rect2(0, m_TopMargin + CellTotalHeight * i + m_LinePosY - 8, m_LeftMargin - 4, m_TopMargin + CellTotalHeight * i + m_LinePosY + 14); pDC->DrawText(s1, &rect2, DT_RIGHT); } } // 获取数据 并显示各单元 for (int j = 0; j < m_CellPerLine; j++) { nCol = j; nDataType = Cells[nRow][nCol].nDataType; nDataAddr = Cells[nRow][nCol].nDataAddr; if (m_bMonitoring) { if ((nDataType & TYPEDATA) == TYPEDATA) { nStat = pDoc->GetVarData(nDataType, nDataAddr); } else { nStat = pDoc->GetCoilValue(nDataType, nDataAddr); } Cells[nRow][nCol].nStat = nStat; nType = Cells[nRow][nCol].nType; if (nType == typeNO || nType == typeNC || nType == typeCMP || nType == typeTM) { int nProgStep = Cells[nRow][nCol].nProgStep; int nBinProgStep = pDoc->Progs[nProgStep].nBinStep; Cells[nRow][nCol].nTrace = pDoc->ProgTrace[nBinProgStep]; } } else { Cells[nRow][nCol].nStat = 0; Cells[nRow][nCol].nTrace = 0; } DrawCell(pDC, i, j); } // 画本行右侧母线 //* x1 = m_LeftMargin + m_CellWidth * m_CellPerLine; y1 = m_TopMargin + CellTotalHeight * i; x2 = x1; y2 = y1 + CellTotalHeight; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); // 画本行右侧母线小短横线 x1 = m_LeftMargin + m_CellWidth * m_CellPerLine; y1 = m_TopMargin + CellTotalHeight * i + m_LinePosY; x2 = x1 - 3; y2 = y1; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); //*/ } pDC->SelectObject(pOldFont); CRect rect2(0, 30, 240, 100); // pDC->DrawText(_T("这是测试字符串111,222,33,aa,bb,cc"), &rect2, 0); s1.Format(_T("This is New Info..")); needReDraw = 0; return 0; } void CMTerm1View::DrawFocusRect(CDC* pDC) { // DrawCell(pDC, m_oldFocusRow, m_oldFocusCol); CPen BluePen(PS_SOLID, 3, FocusColor); CPen * pOldPen = pDC->SelectObject(&BluePen); //CBrush * pOldBrush = ; pDC->SelectStockObject(NULL_BRUSH); int x0, y0; // int x1, y1, x2, y2; RECT rect1; int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); rect1.left = m_LeftMargin + 1 + m_CellWidth * m_FocusCol; rect1.right = rect1.left + m_CellWidth - 4; rect1.top = m_TopMargin + CellTotalHeight * m_FocusRow; rect1.bottom = rect1.top + CellTotalHeight - 2; x0 = rect1.left; y0 = rect1.top; //pDC->DrawFocusRect(&rect1); pDC->Rectangle(&rect1); m_oldFocusCol = m_FocusCol; m_oldFocusRow = m_FocusRow; pDC->SelectObject(pOldPen); // pDC->SelectObject(poldBrush); } int CMTerm1View::DrawLeftRightLine(CDC* pDC, int x0, int y0, int size1, int size2) { // TODO: 在此处添加实现代码. int x1, y1, x2, y2; //画左侧横线 x1 = x0; y1 = y0 + m_LinePosY; x2 = x1 + size1; y2 = y1; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); //画右侧横线 x1 = x0 + size1 +size2; y1 = y0 + m_LinePosY; x2 = x0 + m_CellWidth; y2 = y1; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); return 0; } void CMTerm1View::DrawOT(CDC* pDC, int x0, int y0) { int x1, y1; //画左右侧横线 DrawLeftRightLine(pDC, x0, y0); x1 = x0 +16; y1 = y0 + m_LinePosY; pDC->MoveTo(x1 + 6 + 6, y1); pDC->AngleArc(x1 + 6, y1, 6, 0, 360); } void CMTerm1View::DrawRelay(CDC* pDC, int x0, int y0) { int x1, y1, x2, y2; //画左右侧横线 DrawLeftRightLine(pDC, x0, y0); // 画左侧竖线 x1 = x0+16; y1 = y0 + m_LinePosY - 6; x2 = x1; y2 = y1 + 12; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); // 画右侧竖线 x1 = x2 + 12; y1 = y1; x2 = x1; y2 = y1 + 12; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); } int CMTerm1View::DrawBracket(CDC* pDC, int x0, int y0, int sizex, int sty, int sizey) { // TODO: 在此处添加实现代码. int x1, y1, x2, y2; // 左边的短横线 x1 = x0 ; y1 = y0 + m_LinePosY; x2 = x0 + 3; y2 = y1; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); // 左方括号 x1 = x0 + 9; y1 = y0 + sty; x2 = x0 + 3; y2 = y1; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); x2 = x2; y2 = y2 + sizey; pDC->LineTo(x2, y2); x2 = x2 + 6; y2 = y2; pDC->LineTo(x2, y2); // 右方括号 x1 = x0 + sizex - 6 - 6; y1 = y0 + sty; x2 = x0 + sizex -6 ; y2 = y1; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); x2 = x2; y2 = y2 + sizey; pDC->LineTo(x2, y2); x2 = x2 - 6; y2 = y2; pDC->LineTo(x2, y2); // 右边的短横线 x1 = x0 + sizex - 6; y1 = y0 + m_LinePosY; x2 = x0 + sizex ; y2 = y1; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); return 0; } int CMTerm1View::DrawAngleBracket(CDC* pDC, int x0, int y0, int size1, int size2) { // TODO: 在此处添加实现代码. int x1,y1,x2, y2; DrawLeftRightLine(pDC, x0, y0, size1, size2); // 左尖括号 x1 = x0 + size1 + 6; y1 = y0 + m_LinePosY -6; x2 = x1 -6; y2 = y1 +6 ; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); x2 = x2 +6; y2 = y2 + 6; pDC->LineTo(x2, y2); // 右尖括号 x1 = x0 + size1 + size2 - 6; y1 = y0 + m_LinePosY - 6; x2 = x1 + 6; y2 = y1 + 6 ; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); x2 = x2 -6 ; y2 = y2 + 6; pDC->LineTo(x2, y2); return 0; } int CMTerm1View::DrawCellStat1(CDC * pDC, int x1, int y1, int sizex, int sizey, int nStat) { // TODO: 在此处添加实现代码. CRect rect1; rect1.left = x1; rect1.top = y1; rect1.right = x1+sizex; rect1.bottom = y1+sizey; CBrush br0(BkColor); CBrush br1(MonCoilColor); if (m_bMonitoring) { if (nStat) { pDC->FillRect(&rect1, &br1); }else{ pDC->FillRect(&rect1, &br0); } } return 0; } int CMTerm1View::DrawCellStat2(CDC* pDC, int x1, int y1, int sizex, int sizey, int nStat) { // TODO: 在此处添加实现代码. CRect rect1; rect1.left = x1; rect1.top = y1; rect1.right = x1+sizex; rect1.bottom = y1+sizey; CBrush br2(TraceBkColor); CBrush br3(TraceColor); if (m_bMonitoring) { if (nStat) { pDC->FillRect(&rect1, &br3); }else{ pDC->FillRect(&rect1, &br2); } } return 0; } int CMTerm1View::DrawCellText1(CDC* pDC, CString sText, int x1, int y1, int sizex, int sizey, int nFormat) { // TODO: 在此处添加实现代码. CRect rect1; rect1.left = x1; rect1.top = y1; rect1.right = rect1.left + sizex; rect1.bottom = rect1.top + sizey; pDC->DrawText(sText, &rect1, nFormat); return 0; } int CMTerm1View::DrawCellText2(CDC* pDC, CString sText, int x1, int y1, int sizex, int sizey, int nFormat, int nTextColor) { // TODO: 在此处添加实现代码. COLORREF clrOld = pDC->SetTextColor(nTextColor); CRect rect1; rect1.left = x1; rect1.top = y1; rect1.right = rect1.left + sizex; rect1.bottom = rect1.top + sizey; pDC->DrawText(sText, &rect1, nFormat); pDC->SetTextColor(clrOld); return 0; } int CMTerm1View::DrawCellAnno(CDC * pDC, int nRow, int nCol, CString sAnno) { // TODO: 在此处添加实现代码. if (!m_bShowComments) return 0; if (!needReDraw) return 0; CMTerm1Doc * pDoc = GetDocument(); int x0, y0; int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); x0 = m_LeftMargin + 1 + m_CellWidth * nCol; y0 = m_TopMargin + CellTotalHeight * nRow; int nType, nAddr; nType = Cells[nRow][nCol].nDataType; nAddr = Cells[nRow][nCol].nDataAddr; CString s1; if (pDoc->GetAnno(nType, nAddr, s1)) { CFont *pOldFont; pOldFont = (CFont *)pDC->SelectObject(&AnnoFont); DrawCellText2(pDC, s1, x0 + 2, y0 + m_LinePosY + 6, m_CellWidth-10, 32, DT_WORDBREAK, AnnoColor); pDC->SelectObject(pOldFont); } return 0; } void CMTerm1View::DrawCell(CDC* pDC, int nRow, int nCol) { //CMTerm1Doc * pDoc= GetDocument(); int x0, y0; int x1, y1, x2, y2; RECT rect1; int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); rect1.left = m_LeftMargin + 1 + m_CellWidth * nCol; rect1.right = rect1.left + m_CellWidth; rect1.top = m_TopMargin + CellTotalHeight * nRow; rect1.bottom = rect1.top + CellTotalHeight; x0 = rect1.left; y0 = rect1.top; CString s1; // pDC->DrawFocusRect(&rect1); if (Cells[nRow][nCol].bLeftLineUp && nCol !=0) { if (needReDraw) { pDC->MoveTo(x0, y0); pDC->LineTo(x0, y0 + m_LinePosY); //画直竖线 //pDC->MoveTo(x0, y0 + (0.32 * CellTotalHeight)); //pDC->LineTo(x0, y0 - (0.69 * CellTotalHeight)); } } if (Cells[nRow][nCol].bLeftLineDn && nCol != 0) { if (needReDraw) { pDC->MoveTo(x0, y0 + m_LinePosY); pDC->LineTo(x0, y0 + CellTotalHeight); } } int nType = Cells[nRow][nCol].nType; if (nType == typeNone) { } else if (nType == typeLine1) { //Draw Line //画直横线 if (needReDraw) { pDC->MoveTo(x0, y0 + m_LinePosY); pDC->LineTo(x0 + m_CellWidth, y0 + m_LinePosY); } } else if (nType == typeLine2) { //Draw Line //画直竖线 pDC->MoveTo(x0, y0 + (0.32 * CellTotalHeight)); pDC->LineTo(x0, y0 - (0.69 * CellTotalHeight)); } else if (nType == typeNO) { // Draw Coil if (needReDraw) { DrawRelay(pDC, x0, y0); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol, _T("")); } if (m_bMonitoring){ //Draw Stat DrawCellStat1(pDC, x0 + 16 + 2, y0 + m_LinePosY - 6, 8, 12, Cells[nRow][nCol].nStat); // tracing DrawCellStat2(pDC, x0 + 16 + 2 + 10 + 4, y0 + m_LinePosY - 4, 4, 4, Cells[nRow][nCol].nTrace); } } else if (nType == typeNC) { if (needReDraw) { DrawRelay(pDC, x0, y0); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol, _T("")); //画常闭斜线 x1 = x0 + 16 + 12 - 3; y1 = y0 + m_LinePosY - 6; x2 = x0 + 16 + 2; y2 = y1 + 12; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); } if (m_bMonitoring) { //Draw Stat DrawCellStat1(pDC, x0 + 16 + 2, y0 + m_LinePosY - 6, 8, 12, ! Cells[nRow][nCol].nStat); // tracing DrawCellStat2(pDC, x0 + 16 + 2 + 10 + 4, y0 + m_LinePosY - 4, 4, 4, Cells[nRow][nCol].nTrace); //画常闭斜线 x1 = x0 + 16 + 12 - 3; y1 = y0 + m_LinePosY - 6; x2 = x0 + 16 + 2; y2 = y1 + 12; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); } } else if (nType == typePP) { if (needReDraw) { DrawRelay(pDC, x0, y0); //画上升沿箭头 x1 = x0 + 16 + 6; y1 = y0 + m_LinePosY - 5; x2 = x1; y2 = y1 + 10; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); //* x2 = x1 - 3; y2 = y1 + 4; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); x2 = x1 + 3; y2 = y1 + 4; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); //*/ //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol, _T("")); } } else if (nType == typePN) { if (needReDraw) { DrawRelay(pDC, x0, y0); //画下降沿箭头 x1 = x0 + 16 + 6; y1 = y0 + m_LinePosY + 5; x2 = x1; y2 = y1 - 10; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); //* x2 = x1 - 3; y2 = y1 - 3; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); x2 = x1 + 3; y2 = y1 - 3; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); //*/ //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol, _T("")); } } else if (nType == typeNOT) { if (needReDraw) { DrawLeftRightLine(pDC, x0, y0); //画常闭斜线 x1 = x0 + 16 + 12 - 3; y1 = y0 + m_LinePosY - 6; x2 = x0 + 16 + 2; y2 = y1 + 12; pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); //显示文字 // DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 2, y0, m_CellWidth, 14); } } else if (nType == typeDF) { if (needReDraw) { // DrawLeftRightLine(pDC, x0, y0); DrawAngleBracket(pDC, x0, y0, 8, 32); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 16, y0 + m_LinePosY - 8, 16, 14); } } else if (nType == typeDF_) { if (needReDraw) { // DrawLeftRightLine(pDC, x0, y0); DrawAngleBracket(pDC, x0, y0, 8, 40); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 16, y0 + m_LinePosY - 8, 24, 14); } } else if (nType == typeOUT) { if (needReDraw) { //显示外形 DrawOT(pDC, x0, y0); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol, _T("")); } if (m_bMonitoring) { //Draw Stat DrawCellStat1(pDC, x0 + 16 + 2, y0 + m_LinePosY - 6, 8, 12, Cells[nRow][nCol].nStat); } } else if (nType == typeSET) { if (needReDraw) { //画左侧横线 //DrawLeftRightLine(pDC, x0, y0, 14, 18); DrawAngleBracket(pDC, x0, y0, 8, 32); DrawCellText1(pDC, _T("S"), x0 + 18, y0 + m_LinePosY - 8, 8, 14); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol, _T("")); } if (m_bMonitoring) { //Draw Stat DrawCellStat1(pDC, x0 + 14, y0 + m_LinePosY - 8, 16, 16, Cells[nRow][nCol].nStat); DrawCellText1(pDC, _T("S"), x0 + 18, y0 + m_LinePosY - 8, 8, 14); } } else if (nType == typeRESET) { if (needReDraw) { //画左右侧横线 //DrawLeftRightLine(pDC, x0, y0, 14, 18); DrawAngleBracket(pDC, x0, y0, 8, 32); DrawCellText1(pDC, _T("R"), x0 + 17, y0 + m_LinePosY - 8, 9, 14); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol, _T("")); } if (m_bMonitoring) { //Draw Stat DrawCellStat1(pDC, x0 + 14, y0 + m_LinePosY - 8, 16, 16, Cells[nRow][nCol].nStat); DrawCellText1(pDC, _T("R"), x0 + 17, y0 + m_LinePosY - 8, 9, 14); } } else if (nType == typeCMP) { if (needReDraw) { // 画中括号 DrawBracket(pDC, x0, y0, m_CellWidth * 3); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 12, y0, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 1].sParam, x0 + m_CellWidth + 2, y0, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 2].sParam, x0 + m_CellWidth * 2 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol + 1, _T("")); DrawCellAnno(pDC, nRow, nCol + 2, _T("")); } if (m_bMonitoring) { s1.Format(_T(" %d"), Cells[nRow][nCol + 1].nStat); DrawCellText2(pDC, s1,x0+m_CellWidth+2,y0+m_LinePosY-6,m_CellWidth-10,14,DT_RIGHT, MonTextColor); s1.Format(_T(" %d"), Cells[nRow][nCol + 2].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth*2 + 2, y0 + m_LinePosY - 6, m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); // tracing DrawCellStat2(pDC, x0 + m_CellWidth * 3 - 4, y0 + m_LinePosY - 8, 4, 4, Cells[nRow][nCol].nTrace); } } else if (nType == typeTM) { if (needReDraw) { // 画中括号 DrawBracket(pDC, x0, y0, m_CellWidth * 3); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 12, y0, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 1].sParam, x0 + m_CellWidth + 2, y0, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 2].sParam, x0 + m_CellWidth * 2 + 2, y0, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol, _T("")); DrawCellAnno(pDC, nRow, nCol + 1, _T("")); DrawCellAnno(pDC, nRow, nCol + 2, _T("")); } if (m_bMonitoring) { s1.Format(_T(" %d"), Cells[nRow][nCol + 1].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth + 2, y0 + m_LinePosY - 6, m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); s1.Format(_T(" %d"), Cells[nRow][nCol + 2].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth * 2 + 2, y0 + m_LinePosY - 6, m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); // tracing DrawCellStat2(pDC, x0 + m_CellWidth * 3 - 4, y0 + m_LinePosY - 8, 4, 4, Cells[nRow][nCol].nTrace); } } else if (nType == typeFN1) { if (needReDraw) { // 画中括号 DrawBracket(pDC, x0, y0, m_CellWidth * 2, m_LinePosY - 8, 16); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 12, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 1].sParam, x0 + m_CellWidth + 2, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol + 1, _T("")); } if (m_bMonitoring) { s1.Format(_T(" %d"), Cells[nRow][nCol + 1].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth + 2, y0 , m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); // tracing DrawCellStat2(pDC, x0 + m_CellWidth * 2 - 4, y0 + m_LinePosY - 8, 4, 4, Cells[nRow][nCol].nTrace); } } else if (nType == typeFN2) { if (needReDraw) { // 画中括号 DrawBracket(pDC, x0, y0, m_CellWidth * 3, m_LinePosY - 8, 16); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 12, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 1].sParam, x0 + m_CellWidth + 2, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 2].sParam, x0 + m_CellWidth * 2 + 2, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol + 1, _T("")); DrawCellAnno(pDC, nRow, nCol + 2, _T("")); } if (m_bMonitoring) { s1.Format(_T(" %d"), Cells[nRow][nCol + 1].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth + 2, y0, m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); s1.Format(_T(" %d"), Cells[nRow][nCol + 2].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth * 2 + 2, y0, m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); // tracing DrawCellStat2(pDC, x0 + m_CellWidth * 3 - 4, y0 + m_LinePosY - 8, 4, 4, Cells[nRow][nCol].nTrace); } } else if (nType == typeFN3) { if (needReDraw) { // 画中括号 DrawBracket(pDC, x0, y0, m_CellWidth * 4, m_LinePosY - 8, 16); //显示文字 DrawCellText1(pDC, Cells[nRow][nCol].sCoilName, x0 + 12, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 1].sParam, x0 + m_CellWidth + 2, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 2].sParam, x0 + m_CellWidth * 2 + 2, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellText1(pDC, Cells[nRow][nCol + 3].sParam, x0 + m_CellWidth * 3 + 2, y0 + m_LinePosY - 6, m_CellWidth, 14); DrawCellAnno(pDC, nRow, nCol + 1, _T("")); DrawCellAnno(pDC, nRow, nCol + 2, _T("")); DrawCellAnno(pDC, nRow, nCol + 3, _T("")); } if (m_bMonitoring) { s1.Format(_T(" %d"), Cells[nRow][nCol + 1].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth + 2, y0, m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); s1.Format(_T(" %d"), Cells[nRow][nCol + 2].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth * 2 + 2, y0, m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); s1.Format(_T(" %d"), Cells[nRow][nCol + 3].nStat); DrawCellText2(pDC, s1, x0 + m_CellWidth * 3 + 2, y0, m_CellWidth - 10, 14, DT_RIGHT, MonTextColor); // tracing DrawCellStat2(pDC, x0 + m_CellWidth * 4 - 4, y0 + m_LinePosY - 8, 4, 4, Cells[nRow][nCol].nTrace); } } else { } } // CMTerm1View 消息处理程序 void CMTerm1View::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* /*pHint*/) { // TODO: 在此添加专用代码和/或调用基类 //初始化 cell 内容 if (lHint == 0 || lHint == 1) { TransProgToLDS(); CRect rect0; this->GetClientRect(&rect0); int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); CSize sizeTotal; // TODO: 计算此视图的合计大小 sizeTotal.cx = m_LeftMargin + m_CellWidth * m_CellPerLine + m_CellWidth * 2; sizeTotal.cy = m_TopMargin + CellTotalHeight * (m_nTotalRow - 1) + rect0.Height(); SetScrollSizes(MM_TEXT, sizeTotal); needReDraw = 1; this->RedrawWindow(); } else if (lHint == 2) { UpdateStatusBar(); } } BOOL CMTerm1View::OnEraseBkgnd(CDC* pDC) { // TODO: 在此添加消息处理程序代码和/或调用默认值 return true; return CScrollView::OnEraseBkgnd(pDC); } void CMTerm1View::OnSize(UINT nType, int cx, int cy) { CScrollView::OnSize(nType, cx, cy); // CString s1; // s1.Format(_T("OnSize %d %d %d"), nType, cx, cy); // DbgLog(s1); if (this->IsWindowVisible()) { CRect rect0; this->GetClientRect(&rect0); int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); CSize sizeTotal; // TODO: 计算此视图的合计大小 sizeTotal.cx = m_LeftMargin + m_CellWidth * m_CellPerLine + m_CellWidth * 2; sizeTotal.cy = m_TopMargin + CellTotalHeight * (m_nTotalRow - 1) + rect0.Height(); SetScrollSizes(MM_TEXT, sizeTotal); needReDraw = 1; this->RedrawWindow(); } needReDraw = 1; // TODO: 在此处添加消息处理程序代码 } BOOL CMTerm1View::OnScrollBy(CSize sizeScroll, BOOL bDoScroll) { // TODO: 在此添加专用代码和/或调用基类 needReDraw = 1; return CScrollView::OnScrollBy(sizeScroll, bDoScroll); } void CMTerm1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CString s1; // s1.Format(_T("KeyDown %d %d %d"), nChar, nRepCnt, nFlags); // DbgLog(s1); int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); CRect rect0; this->GetClientRect(&rect0); int viewWidth = rect0.Width(); CPoint scroll1; scroll1 = this->GetScrollPosition(); int nFirstVisibleLine; int nLastVisibleLine; int nLinesinView; nFirstVisibleLine = (scroll1.y - m_TopMargin) / CellTotalHeight; nLastVisibleLine = (rect0.Height() + scroll1.y - m_TopMargin) / CellTotalHeight + 1; if (nFirstVisibleLine < 0) { nFirstVisibleLine = 0; } if (nLastVisibleLine < 0) { nLastVisibleLine = 0; } nLinesinView = nLastVisibleLine - 1 - nFirstVisibleLine; int nRow, nCol; nRow = m_FocusRow; nCol = m_FocusCol; if (nChar == VK_LEFT) { nCol -= 1; if (nCol < 0) { if (nRow > 0) { nRow -= 1; nCol += m_CellPerLine; }else { nCol = 0; } } CellFocusChg(nRow, nCol); } if (nChar == VK_RIGHT) { nCol += 1; if (nCol >= m_CellPerLine) { if (nRow < m_nTotalRow + nLinesinView - 1 ) { nCol -= m_CellPerLine; nRow += 1; } else { 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; if (Cells[nRow][nCol].nType) { m_nCurProgStep = Cells[nRow][nCol].nProgStep; } if (nRow < nFirstVisibleLine) { scroll1.y -= CellTotalHeight; ScrollToPosition(scroll1); } if (nRow > 0 && nRow >= nLastVisibleLine - 1 ) { scroll1.y += CellTotalHeight; ScrollToPosition(scroll1); } // DrawFocusRect(); GetDocument()->UpdateAllViews(this, m_FocusCol); needReDraw = 1; this->RedrawWindow(); UpdateStatusBar(); CScrollView::OnKeyDown(nChar, nRepCnt, nFlags); } /// /// 单元格焦点变化*选中点变化 /// /// /// /// int CMTerm1View::CellFocusChg(int nRow, int nCol) { CString s1; stCell & thecell = Cells[nRow][nCol]; s1.Format(_T("Cell %d %d Type %02X \r\n"), nRow, nCol, thecell.nType); 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); auto p1 = (CMainFrame*)AfxGetMainWnd(); auto p2 = p1->GetInputWnd(); p2->SetCurCellPos(nRow,nCol,thecell); p2->focusCell = thecell; return 0; } //鼠标左键点击事件 void CMTerm1View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CString s1; CPoint scroll1; scroll1 = this->GetScrollPosition(); int tx, ty; tx = point.x + scroll1.x; ty = point.y + scroll1.y; int nRow, nCol; int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); nRow = (ty - m_TopMargin) / CellTotalHeight; nCol = (tx - m_LeftMargin) / m_CellWidth; if (nRow < 0) { nRow = 0; } if (nCol < 0) { nCol = 0; } if (nCol >= m_CellPerLine) { nCol = m_CellPerLine - 1; } s1.Format(_T("OnLButtonDown::zxd:: LD %d %d %02X Scroll %d %d Total %d %d Row %d Col %d"), point.x, point.y, nFlags, scroll1.x, scroll1.y, tx, ty, nRow, nCol); DbgLog(s1);//zxd add to test m_pStatusBar->SetPaneText(6, s1); m_FocusRow = nRow; m_FocusCol = nCol; if (Cells[nRow][nCol].nType) { m_nCurProgStep = Cells[nRow][nCol].nProgStep; } // DrawFocusRect(); CellFocusChg(nRow, nCol); GetDocument()->UpdateAllViews(this, m_FocusCol); needReDraw = 1; this->RedrawWindow(); UpdateStatusBar(); // m_pStatusBar->Set CScrollView::OnLButtonDown(nFlags, point); } void CMTerm1View::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CScrollView::OnLButtonUp(nFlags, point); } void CMTerm1View::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CString s1; CMTerm1Doc * pDoc = (CMTerm1Doc*)GetDocument(); CPoint scroll1; scroll1 = this->GetScrollPosition(); int tx, ty; tx = point.x + scroll1.x; ty = point.y + scroll1.y; int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); int nRow = (ty - m_TopMargin) / CellTotalHeight; int nCol = (tx - m_LeftMargin) / m_CellWidth; if (nRow < 0) { nRow = 0; } if (nCol < 0) { nCol = 0; } if (nCol >= m_CellPerLine) { nCol = m_CellPerLine - 1; } s1.Format(_T("LD db Clk %d %d %02X Scroll %d %d Total %d %d Row %d Col %d"), point.x, point.y, nFlags, scroll1.x, scroll1.y, tx, ty, nRow, nCol); m_pStatusBar->SetPaneText(6, s1); m_pStatusBar->SetPaneBackgroundColor(6, RGB(255, 255, 0)); m_pStatusBar->SetPaneTextColor(6, RGB(0, 0, 255)); m_pStatusBar->EnablePaneProgressBar(6); m_pStatusBar->SetPaneProgress(6, 5); SysLog(s1); m_FocusRow = nRow; m_FocusCol = nCol; if (Cells[nRow][nCol].nType) { m_nCurProgStep = Cells[nRow][nCol].nProgStep; } if (!pDoc->m_bOnline) return; //if (!m_bMonitoring) return; CString sParam; sParam = Cells[nRow][nCol].sParam; int nDataType, nDataAddr, nStat; nDataType = Cells[nRow][nCol].nDataType; nDataAddr = Cells[nRow][nCol].nDataAddr; nStat = Cells[nRow][nCol].nStat; s1.Format(_T("Name %s DataType %d DataAddr %d Stat %d"), sParam, nDataType, nDataAddr, nStat); SysLog(s1); if (Cells[m_FocusRow][m_FocusCol].sParam == _T("")) { return; } needReDraw = 1; if ((nDataType&TYPEDATA) == TYPEDATA) { CDialogSetData dialog2; dialog2.m_strAddr = sParam; dialog2.m_nStat = nStat; INT_PTR r = dialog2.DoModal(); if (r == IDOK) { int s = dialog2.m_nStat; /// pDoc->SetVarData(nDataType, nDataAddr, s); //Cells[nRow][nCol].nStat = s; s1.Format(_T("Set Data %s as %d "), sParam, s); SysLog(s1); this->RedrawWindow(); } } else { CDialogSetCoil dialog1; dialog1.m_strAddr = sParam; dialog1.m_nStat = nStat; INT_PTR r = dialog1.DoModal(); if (r == IDOK) { int s = dialog1.m_nStat; /// pDoc->SetCoilValue(nDataType, nDataAddr, s); // Cells[nRow][nCol].nStat = nStat; // Cells[m_FocusRow][m_FocusCol].nStat = s; // s1.Format(_T("Set Coild %s as %d "), sParam, s); // AfxMessageBox(s1); this->RedrawWindow(); } } CScrollView::OnLButtonDblClk(nFlags, point); } void CMTerm1View::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CString s1; CPoint scroll1; scroll1 = this->GetScrollPosition(); int tx, ty; tx = point.x + scroll1.x; ty = point.y + scroll1.y; int nRow, nCol; int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); nRow = (ty- m_TopMargin )/ CellTotalHeight; nCol = (tx - m_LeftMargin) / m_CellWidth; if (nRow < 0) { nRow = 0; } if (nCol < 0) { nCol = 0; } if (nCol >= m_CellPerLine) { nCol = m_CellPerLine - 1; } s1.Format(_T("RD %d %d %02X Scroll %d %d Total %d %d Row %d Col %d"), point.x, point.y, nFlags, scroll1.x, scroll1.y, tx, ty, m_FocusRow, m_FocusCol); m_pStatusBar->SetPaneText(6, s1); m_FocusRow = nRow; m_FocusCol = nCol; // DrawFocusRect(); GetDocument()->UpdateAllViews(this, m_FocusCol); needReDraw = 1; this->RedrawWindow(); CScrollView::OnRButtonDown(nFlags, point); } void CMTerm1View::OnRButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 //CContextMenuManager CScrollView::OnRButtonUp(nFlags, point); } void CMTerm1View::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { // TODO: 在此处添加消息处理程序代码 CMenu menu1; menu1.LoadMenu(IDR_MENU1); CMenu *pContextMenu = menu1.GetSubMenu(0); pContextMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); } void CMTerm1View::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) { CScrollView::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); // TODO: 在此处添加消息处理程序代码 if (!bSysMenu && pPopupMenu) { CCmdUI cmdUI; cmdUI.m_pOther = NULL; cmdUI.m_pMenu = pPopupMenu; cmdUI.m_pSubMenu = NULL; UINT count = pPopupMenu->GetMenuItemCount(); cmdUI.m_nIndexMax = count; for (UINT i = 0; i < count; i++) { UINT nID = pPopupMenu->GetMenuItemID(i); if (-1 == nID || 0 == nID) { continue; } cmdUI.m_nID = nID; cmdUI.m_nIndex = i; cmdUI.DoUpdate(this, FALSE); } } } void CMTerm1View::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CString s1; CMTerm1Doc * pDoc = (CMTerm1Doc*)GetDocument(); if (nIDEvent == 0) { } else if (nIDEvent == 1) { if (m_bMonitoring) { //this->RedrawWindow(); DoReDraw(); } } else if (nIDEvent == 2) { pDoc->OnTimer(2); } else { } CScrollView::OnTimer(nIDEvent); } void CMTerm1View::OnMonitor() { // TODO: 在此添加命令处理程序代码 m_bMonitoring = !m_bMonitoring; this->RedrawWindow(); UpdateStatusBar(); } void CMTerm1View::OnUpdateMonitor(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 pCmdUI->SetCheck(m_bMonitoring == true); } /// /// 程序转换按钮点击 /// void CMTerm1View::OnProgConvert() { //转换前先对LDS的规则进行检验(检验规则与返回参数并未完全确定 // std::pair result = LDSCheckRule(); //if (result.first == 111) //{ // DbgLog(result.second); // return; //} CString s1; s1.Format(_T("Prog Convert")); SysLog(s1); int r = TransLDSToProg(); s1.Format(_T("LDS To Prog result %d"), r); SysLog(s1); if (r==0) { // m_bModified = 0; int j=TransProgToLDS(); s1.Format(_T("Porg to LDS retuls %d"), j); SysLog(s1); needReDraw = 1; RedrawWindow(); } else { s1.Format(_T("Error in Prog Convert")); SysLog(s1); } } void CMTerm1View::OnUpdateProgConvert(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 pCmdUI->SetCheck(0); pCmdUI->Enable(m_bModified); } void CMTerm1View::OnProgCancelEdit() { CString s1; s1.Format(_T("Prog Cancel Edit")); SysLog(s1); // TODO: 在此添加命令处理程序代码 } void CMTerm1View::OnUpdateProgCancelEdit(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 // pCmdUI->SetCheck(m_bModified); pCmdUI->Enable(m_bModified); } void CMTerm1View::OnInsertBlankLine() { // TODO: 在此添加命令处理程序代码 CString s1; s1.Format(_T("Insert Blank Line")); SysLog(s1); m_FocusRow; //当前行之后的所有,下移一行 for (int i = m_nTotalRow - 1; i >= m_FocusRow; i--) { for (int j = 0; j < m_CellPerLine; j++) { Cells[i + 1][j] = Cells[i][j]; } } m_nTotalRow += 1; // 当前行灰色 for (int j = 0; j < m_CellPerLine; j++) { Cells[m_FocusRow][j].clear(); Cells[m_FocusRow][j].bEditing = 1; Cells[m_FocusRow][j].bModified = 1; if (Cells[m_FocusRow + 1][j].bLeftLineUp) { Cells[m_FocusRow][j].bLeftLineUp = 1; Cells[m_FocusRow][j].bLeftLineDn = 1; } } // 当前行 加入 触点 // m_FocusCol; // Cells[m_FocusRow][0].nType= typeNO; // Cells[m_FocusRow][0].nDataType = KLCoilTypeX; // Cells[m_FocusRow][0].nDataAddr = 15; // Cells[m_FocusRow][0].sCoilName = "ABCDEFG"; m_bModified = 1; needReDraw = 1; this->RedrawWindow(); } int FindTypeIndex(CString str[], CString strType, int num) { for (int i = 0;i < num;i++) { if (strType == str[i]) { return i; } } return -1; } /// /// 设置Cell到窗口视图 /// /// 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][0].bEditing = 1; if (m_nTotalRow < m_FocusRow + 1) { m_nTotalRow = m_FocusRow + 1; } //单元格关联修改 switch (flag) { case 1: { if(Cells[m_FocusRow - 1][m_FocusCol].nType == CMTerm1View::typeExt1) { //发送错误信息 DbgLog(_T("插入纵线失败:光标位置错误!参数位置不允许添加纵线")); return; } //添加纵线时同步添加上一行 Cells[m_FocusRow - 1][m_FocusCol].bLeftLineDn = 1; }break; case 2: { if (Cells[m_FocusRow - 1][m_FocusCol].nType == CMTerm1View::typeExt1) { //发送错误信息 DbgLog(_T("删除纵线失败:光标位置错误!参数位置不允许删除纵线")); return; } //删除纵线时同步删除上一行 Cells[m_FocusRow - 1][m_FocusCol].bLeftLineDn = 0; }break; default: break; } //如果变化的是竖线,焦点不后移 if (!changeVLine) { //单元格位置后移 m_FocusCol += 1; } if (m_FocusCol >= 16) { m_FocusCol = 0; m_FocusRow += 1; } this->RedrawWindow(); this->CellFocusChg(m_FocusRow, m_FocusCol);//改变焦点 } void CMTerm1View::OnUpdateInsertBlankLine(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 } void CMTerm1View::OnDeleteBlankLine() { // TODO: 在此添加命令处理程序代码 CString s1; s1.Format(_T("Delete Blank Line")); SysLog(s1); } void CMTerm1View::OnUpdateDeleteBlankLine(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 } void CMTerm1View::OnRectSelect() { // TODO: 在此添加命令处理程序代码 } void CMTerm1View::OnUpdateRectSelect(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 } void CMTerm1View::OnTextFirst() { // TODO: 在此添加命令处理程序代码 } void CMTerm1View::OnUpdateTextFirst(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 } void CMTerm1View::OnDisplayComments() { // TODO: 在此添加命令处理程序代码 m_bShowComments = !m_bShowComments; int CellTotalHeight = m_CellHeight + (m_bShowComments ? m_CommentHeight : 0); CRect rect0; this->GetClientRect(&rect0); CSize sizeTotal; // TODO: 计算此视图的合计大小 sizeTotal.cx = m_LeftMargin + m_CellWidth * m_CellPerLine + m_CellWidth * 2; sizeTotal.cy = m_TopMargin + CellTotalHeight * (m_nTotalRow-1) + rect0.Height(); SetScrollSizes(MM_TEXT, sizeTotal); needReDraw = 1; this->Invalidate(); } void CMTerm1View::OnUpdateDisplayComments(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 pCmdUI->SetCheck(m_bShowComments == true); } int CMTerm1View::UpdateStatusBar(int nIndex) { // TODO: 在此处添加实现代码. CString s1; CMTerm1Doc * pDoc = (CMTerm1Doc*)GetDocument(); if (nIndex == idxMachineType || nIndex == -1) { //机型代码 s1 = pDoc->m_sMachineType; m_pStatusBar->SetPaneText(idxMachineType,s1); } if (nIndex == idxProgPos || nIndex == -1) { //程序位置/步数 s1.Format(_T("%5d/%5d"), m_nCurProgStep,pDoc->m_nProgSteps); m_pStatusBar->SetPaneText(idxProgPos, s1); } if (nIndex == idxOnline || nIndex == -1) { //在线 /离线 if (!pDoc->m_bOnline) { s1 = _T("离线"); m_pStatusBar->SetPaneText(idxOnline, s1); m_pStatusBar->SetPaneBackgroundColor(idxOnline); } else if (pDoc->m_bOnline) { if (pDoc->m_bSimulate) { s1 = _T("在线(仿真)"); m_pStatusBar->SetPaneText(2, s1); m_pStatusBar->SetPaneBackgroundColor(idxOnline, OnlineColor); }else{ s1 = _T("在线"); m_pStatusBar->SetPaneText(2, s1); m_pStatusBar->SetPaneBackgroundColor(idxOnline, OnlineColor); } } } if (nIndex == idxRunning || nIndex == -1) { // 运行 / 停止 if (!pDoc->m_bOnline) { s1 = _T(""); m_pStatusBar->SetPaneText(idxRunning, s1); m_pStatusBar->SetPaneBackgroundColor(idxRunning); m_pStatusBar->SetPaneWidth(idxRunning, 0); m_pStatusBar->SetPaneStyle(idxRunning, SBPS_DISABLED); }else if (!pDoc->m_bPlcRunning) { s1 = _T("PROG"); m_pStatusBar->SetPaneText(idxRunning, s1); m_pStatusBar->SetPaneWidth(idxRunning, s1.GetLength()*8); m_pStatusBar->SetPaneBackgroundColor(idxRunning, ProgColor); }else { s1 = _T("RUN"); m_pStatusBar->SetPaneText(idxRunning, s1); m_pStatusBar->SetPaneWidth(idxRunning, s1.GetLength() * 8); m_pStatusBar->SetPaneBackgroundColor(idxRunning, RunningColor); } } if (nIndex == idxMonitor || nIndex == -1) { // 监控 // // s1 = pDoc->m_sMachineType; if (!m_bMonitoring) { s1 = _T("[监控停止]"); m_pStatusBar->SetPaneText(idxMonitor, s1); m_pStatusBar->SetPaneBackgroundColor(idxMonitor); }else{ s1 = _T("[正在监控]"); m_pStatusBar->SetPaneText(idxMonitor, s1); m_pStatusBar->SetPaneBackgroundColor(idxMonitor, MonitorColor); } } if (nIndex == idxAddress || nIndex == -1) { // 地址,本站 // s1 = pDoc->m_sMachineType; if (!pDoc->m_bOnline) { s1 = _T("本站"); m_pStatusBar->SetPaneText(idxAddress, s1); m_pStatusBar->SetPaneBackgroundColor(idxMonitor); }else { s1 = _T("本站"); m_pStatusBar->SetPaneText(idxAddress, s1); m_pStatusBar->SetPaneBackgroundColor(idxMonitor, AddressColor); } } if (nIndex == idxInfoDisp || nIndex == -1) { // INFO DISPLAY // s1 = pDoc->m_sMachineType; m_pStatusBar->SetPaneText(idxInfoDisp, s1); } return 0; } void CMTerm1View::OnUpdateIndicatorMonitorStatus(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 //pCmdUI->SetCheck(m_bMonitoring == true); if (!m_bMonitoring) pCmdUI->SetText(_T("[监控停止]")); else pCmdUI->SetText(_T("[正在监控]")); } void CMTerm1View::OnUpdateIndicators(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 CString s1; s1.Format(_T("pCmdUI nID %d ")); DbgLog(s1); pCmdUI->m_nID; pCmdUI->SetText(_T("KL-D20N16")); } void CMTerm1View::OnUpdateMachineType(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 CString s1; s1.Format(_T("pCmdUI nID %d ")); DbgLog(s1); pCmdUI->m_nID; pCmdUI->SetText(_T("KL-D20N16")); } void CMTerm1View::OnUpdateProgramPos(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 CString s1; s1.Format(_T("%5d/%5d"), 18, 55); pCmdUI->SetText(s1); } void CMTerm1View::OnUpdateConnectivity(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 CString s1; s1 = _T("离线"); s1 = _T("在线"); pCmdUI->SetText(s1); } void CMTerm1View::OnUpdateRunStatus(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 CString s1; CMTerm1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; if (pDoc->m_bPlcRunning) { s1 = _T("运行"); m_pStatusBar->SetPaneText(3, s1); m_pStatusBar->SetPaneTextColor(3, RGB(0, 0, 0)); } else { s1 = _T("停止"); m_pStatusBar->SetPaneText(3, s1); m_pStatusBar->SetPaneTextColor(3, RGB(0, 0, 0)); } s1.Format(_T("PCmdUI %d %d"), pCmdUI->m_nID, pCmdUI->m_nIndex); DbgLog(s1); // pCmdUI->SetText(s1); } void CMTerm1View::OnUpdateMonitorStatus(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 CString s1; s1 = _T("停止监控"); s1 = _T("监控中"); if (!m_bMonitoring) pCmdUI->SetText(_T("[监控停止]")); else pCmdUI->SetText(_T("[正在监控]")); // pCmdUI->SetText(s1); } void CMTerm1View::OnUpdateTargetAddress(CCmdUI *pCmdUI) { // TODO: 在此添加命令更新用户界面处理程序代码 CString s1; s1 = _T("远程"); s1 = _T("本站"); pCmdUI->SetText(s1); } void CMTerm1View::OnInputIoComment() { // TODO: 在此添加命令处理程序代码 CString s1; int nRow, nCol; nRow = m_FocusRow; nCol = m_FocusCol; if (nCol < 0) { nCol = 0; } if (nCol >= m_CellPerLine) { nCol = m_CellPerLine - 1; } CString sParam; sParam = Cells[nRow][nCol].sParam; int nDataType, nDataAddr, nStat; nDataType = Cells[nRow][nCol].nDataType; nDataAddr = Cells[nRow][nCol].nDataAddr; nStat = Cells[nRow][nCol].nStat; s1.Format(_T("Name %s DataType %d DataAddr %d Stat %d"), sParam, nDataType, nDataAddr, nStat); SysLog(s1); if (Cells[m_FocusRow][m_FocusCol].sParam == _T("")) { return; } CMTerm1Doc * pDoc = GetDocument(); CString sComment; pDoc->GetAnno(nDataType, nDataAddr, sComment); CDialogIoComment dialog1; dialog1.m_sIOName = sParam; dialog1.m_sComment = sComment; dialog1.m_nCoilType = nDataType; dialog1.m_nCoilAddr = nDataAddr; INT_PTR r = dialog1.DoModal(); if (r == IDOK) { sComment = dialog1.m_sComment; pDoc->SetAnno(nDataType, nDataAddr, sParam, sComment); s1.Format(_T("Set %s %d %d comment -> %s"), sParam, nDataType, nDataAddr, sComment); SysLog(s1); //needReDraw = 1; this->RedrawWindow(); } } /// /// 程序数据转为梯形图 /// /// int CMTerm1View::TransProgToLDS() { CString s1; CMTerm1Doc * pDoc = (CMTerm1Doc*)GetDocument(); // 先扫描分开的程序段 int stpos[100] = { 0 }; int nSts = 0; for (int i = 0; i < m_nTotalRow && i < 2000; i++) { for (int j = 0; j < 16; j++) { Cells[i][j].clear(); 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; int cx = 0, cy = 0; int maxy = 0; try { for (int i = 0; i < pDoc->m_nProgSteps; i++) { int nOp = pDoc->Progs[i].nOpType1; int nParamCount = pDoc->Progs[i].nParamCount; CStringA OpName; CStringA ShowTxt; pDoc->OpToTxt(nOp, OpName); pDoc->OpToShowTxt(nOp, ShowTxt); int nPairTo = pDoc->Progs[i].PairTo; int nPairOp = 0; if (nPairTo) { nPairOp = pDoc->Progs[nPairTo].nOpType1; } int nCellType; switch (nOp) { case OP_NOP: break; case OP_ST: case OP_ST_: if (i == 0) { } else { //记录当前位置 EndPt[nEndPts] = POINT{ cx,cy }; nEndPts++; if (nPairOp == OP_ANS) { //继续前进 //cx = 0, cy = nCurLine; //cx = StPts[nSts - 1].x; //nCurLine = cy + 1; //另起一行 ///* nCurLine = cy; int hasData = 1; while (hasData) { hasData = 0; for (int j = cx + 1; j < m_CellPerLine; j++) { if (Cells[nCurLine][j].nType != 0) { nCurLine++; hasData = 1; break; } } } //nCurLine = maxy + 1; //另起一行 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; //*/ } else if (nPairOp == OP_ORS) { 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; } } } // nCurLine = maxy + 1; //另起一行 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; } else if (nPairOp == 0) { 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].nProgStep = i; 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++; //移到下一格 break; case OP_ST_EQ: case OP_ST_NE: case OP_ST_LT: case OP_ST_GT: case OP_ST_LE: case OP_ST_GE: if (i == 0) { } else { //记录当前位置 EndPt[nEndPts] = POINT{ cx,cy }; nEndPts++; if (nPairOp == OP_ANS) { //继续前进 //cx = 0, cy = nCurLine; } else if (nPairOp == OP_ORS) { 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; } } } // nCurLine = maxy + 1; //另起一行 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; } else if (nPairOp == 0) { nCurLine = maxy + 1; //另起一行 maxy = nCurLine; cx = 0; cy = nCurLine; } } stpos[nSts] = i; StPts[nSts] = POINT{ cx,cy }; nSts++; Cells[cy][cx].nType = typeCMP; Cells[cy][cx].nProgStep = i; Cells[cy][cx].sParam = OpName; Cells[cy][cx].sCoilName = ShowTxt; Cells[cy][cx + 1].nType = typeExt1; Cells[cy][cx + 1].sParam = pDoc->Progs[i].Params[0].sParamStr; Cells[cy][cx + 1].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][cx + 1].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; Cells[cy][cx + 2].nType = typeExt1; Cells[cy][cx + 2].sParam = pDoc->Progs[i].Params[1].sParamStr; Cells[cy][cx + 2].nDataType = pDoc->Progs[i].Params[1].nParamType; Cells[cy][cx + 2].nDataAddr = pDoc->Progs[i].Params[1].nParamAddr; cx += 3; //移到下3格 break; case OP_AN: case OP_AN_: Cells[cy][cx].nType = nOp == OP_AN ? typeNO : typeNC; //typeNC 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; Cells[cy][cx].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][cx].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; cx++; break; case OP_AN_EQ: case OP_AN_NE: case OP_AN_LT: case OP_AN_GT: case OP_AN_LE: case OP_AN_GE: Cells[cy][cx].nType = typeCMP; Cells[cy][cx].nProgStep = i; Cells[cy][cx].sCoilName = ShowTxt; Cells[cy][cx + 1].nType = typeExt1; Cells[cy][cx + 1].sParam = pDoc->Progs[i].Params[0].sParamStr; Cells[cy][cx + 1].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][cx + 1].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; Cells[cy][cx + 2].nType = typeExt1; Cells[cy][cx + 2].sParam = pDoc->Progs[i].Params[1].sParamStr; Cells[cy][cx + 2].nDataType = pDoc->Progs[i].Params[1].nParamType; Cells[cy][cx + 2].nDataAddr = pDoc->Progs[i].Params[1].nParamAddr; cx += 3; break; case OP_OR: case OP_OR_: EndPt[nEndPts] = POINT{ cx,cy }; 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; } } } } 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].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) //{ //本行补齐 // 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; nEndPts--; break; case OP_OR_EQ: case OP_OR_NE: case OP_OR_LT: case OP_OR_GT: case OP_OR_LE: case OP_OR_GE: EndPt[nEndPts] = POINT{ cx,cy }; 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; } } } } 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 = typeCMP; Cells[cy][cx].nProgStep = i; Cells[cy][cx].sCoilName = ShowTxt; Cells[cy][cx + 1].nType = typeExt1; Cells[cy][cx + 1].sParam = pDoc->Progs[i].Params[0].sParamStr; Cells[cy][cx + 1].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][cx + 1].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; Cells[cy][cx + 2].nType = typeExt1; Cells[cy][cx + 2].sParam = pDoc->Progs[i].Params[1].sParamStr; Cells[cy][cx + 2].nDataType = pDoc->Progs[i].Params[1].nParamType; Cells[cy][cx + 2].nDataAddr = pDoc->Progs[i].Params[1].nParamAddr; cx += 3; 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; nEndPts--; break; case OP_NOT: Cells[cy][cx].nType = typeNOT; Cells[cy][cx].sCoilName = _T("NOT"); Cells[cy][cx].nProgStep = i; cx++; break; case OP_DF: case OP_DF_: Cells[cy][cx].nType = nOp == OP_DF ? typeDF : typeDF_; 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: 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++) { 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: StrPt[nStrPts] = POINT{ EndPt[nEndPts].x,EndPt[nEndPts].y+1 }; nStrPts++; break; case OP_RDS: 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; } break; case OP_POPS: nStrPts--; cy = StrPt[nStrPts].y; cx = StrPt[nStrPts].x; break; case OP_OUT: case OP_SET: case OP_RESET: nCellType = nOp == OP_OUT ? typeOUT : nOp == OP_SET ? typeSET : typeRESET; nCurLine = cy; if (cx <= m_CellPerLine) { 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; for (int j = cx; j < m_CellPerLine; j++) { Cells[cy][j].nType = typeLine1; } Cells[cy][m_CellPerLine - 1].nType = nCellType; 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; Cells[cy][m_CellPerLine - 1].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][m_CellPerLine - 1].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; } else { Cells[cy][cx].nType = nCellType; 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; Cells[cy][cx].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][cx].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; } if (cy > maxy) { maxy = cy; } //cy++; break; case OP_TML: case OP_TMR: case OP_TMX: case OP_TMY: Cells[cy][cx].nType = typeTM; Cells[cy][cx].nProgStep = i; Cells[cy][cx].sCoilName = ShowTxt; Cells[cy][cx + 1].nType = typeExt1; Cells[cy][cx + 1].sParam = pDoc->Progs[i].Params[0].sParamStr; Cells[cy][cx + 1].nDataType = KLDataTypeEV; Cells[cy][cx + 1].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; Cells[cy][cx + 2].nType = typeExt1; Cells[cy][cx + 2].sParam = pDoc->Progs[i].Params[1].sParamStr; Cells[cy][cx + 2].nDataType = pDoc->Progs[i].Params[1].nParamType; Cells[cy][cx + 2].nDataAddr = pDoc->Progs[i].Params[1].nParamAddr; cx += 3; break; case OP_INC: case OP_DEC: Cells[cy][cx].nType = typeFN1; Cells[cy][cx].nProgStep = i; Cells[cy][cx].sCoilName = ShowTxt; Cells[cy][cx + 1].nType = typeExt1; Cells[cy][cx + 1].sParam = pDoc->Progs[i].Params[0].sParamStr; Cells[cy][cx + 1].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][cx + 1].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; cx += 2; break; case OP_MV: case OP_ADD2: case OP_SUB2: Cells[cy][cx].nType = typeFN2; Cells[cy][cx].nProgStep = i; Cells[cy][cx].sCoilName = ShowTxt; Cells[cy][cx + 1].nType = typeExt1; Cells[cy][cx + 1].sParam = pDoc->Progs[i].Params[0].sParamStr; Cells[cy][cx + 1].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][cx + 1].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; Cells[cy][cx + 2].nType = typeExt1; Cells[cy][cx + 2].sParam = pDoc->Progs[i].Params[1].sParamStr; Cells[cy][cx + 2].nDataType = pDoc->Progs[i].Params[1].nParamType; Cells[cy][cx + 2].nDataAddr = pDoc->Progs[i].Params[1].nParamAddr; cx += 3; break; case OP_ADD3: case OP_SUB3: case OP_MUL: case OP_DIV: Cells[cy][cx].nType = typeFN3; Cells[cy][cx].nProgStep = i; Cells[cy][cx].sCoilName = ShowTxt; Cells[cy][cx + 1].nType = typeExt1; Cells[cy][cx + 1].sParam = pDoc->Progs[i].Params[0].sParamStr; Cells[cy][cx + 1].nDataType = pDoc->Progs[i].Params[0].nParamType; Cells[cy][cx + 1].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr; Cells[cy][cx + 2].nType = typeExt1; Cells[cy][cx + 2].sParam = pDoc->Progs[i].Params[1].sParamStr; Cells[cy][cx + 2].nDataType = pDoc->Progs[i].Params[1].nParamType; Cells[cy][cx + 2].nDataAddr = pDoc->Progs[i].Params[1].nParamAddr; Cells[cy][cx + 3].nType = typeExt1; Cells[cy][cx + 3].sParam = pDoc->Progs[i].Params[2].sParamStr; Cells[cy][cx + 3].nDataType = pDoc->Progs[i].Params[2].nParamType; Cells[cy][cx + 3].nDataAddr = pDoc->Progs[i].Params[2].nParamAddr; cx += 4; break; default: break; } } } catch (const std::exception&) { DbgLog(_T("无法绘制图形(程序不合理)")); } m_nTotalRow = maxy + 1; /* for (int i = 0; i < 25; i++) { for (int j = 0; j < 16; j++) { Cells[i][j].nType = i; s1.Format(_T("%d:%d"), i, j); Cells[i][j].sCoilName = s1; } } */ needReDraw = 1; return 0; } bool firstCoil = true;//本段第一个单元格 bool isPops = false; /// /// 梯形图转Prog /// /// int CMTerm1View::TransLDSToProg() { CMTerm1Doc * pDoc = GetDocument(); CString s1; s1.Format(_T("Trans LDS to PRrog")); DbgLog(s1); s1.Format(_T("将梯形图转成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; 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; 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(); for (int j = 0; j < m_CellPerLine; j++) { int nCount = 0; int nCount2 = 0; int nCount3 = 0; for (int k = nStartLine; k <= nEndLine; k++) { if (Cells[k][j].nType) { nCount += 1; nCount2 += 1; nCount3 += 1; if (Cells[k][j].bLeftLineUp) { nCount2 -= 1; } // if (Cells[k][j].bLeftLineDn) nCount2 -= 1; if (j != m_CellPerLine - 1) { if (Cells[k][j + 1].bLeftLineUp) { nCount3 -= 1; } // if (Cells[k][j + 1].bLeftLineDn) nCount3 -= 1; } } } nCounts[j] = nCount; nCounts2[j] = nCount2; nCounts3[j] = nCount3; } s1.Empty(); for (int j = 0; j < m_CellPerLine; j++) { s1.AppendFormat(_T(" %d(%d)"), nCounts[j],nCounts3[j]); } DbgLog(_T("")); DbgLog(s1); s1.Empty(); for (int j = 0; j < m_CellPerLine; j++) { s1.AppendFormat(_T(" %d "), nCounts2[j]); } DbgLog(s1); //开始从左到右,从上到下扫描,主要关注 竖直连接线。 int nCurPosX,nCurPosY; nCurPosY = nStartLine; nCurPosX = 0; CString sProg; int nAllSteps=0; stProgSection Progsec; for (int i = nStartLine; i <= nEndLine; i++) { CString sProgSec; int nSteps = 0;; nCurPosY = i; stProgSection thisprogsec; if (Cells[i][0].nType) { firstCoil = true; //循环遍历单元格(转换的逻辑在这个函数) //ScanLDSCells(nStartLine, nEndLine, nCurPosY, nCurPosX, 0, thisprogsec, sProgSec, nSteps); //ScanLDSCells2(nStartLine, nEndLine, nCurPosY, nCurPosX, 0, thisprogsec, sProgSec, nSteps); } //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); DbgLog(s1); s1.Format(_T("progSec steps %d "), n); DbgLog(s1); for (int i = 0; i < n; i++) { int optype = Progsec.Progs[i].nOpType1; 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); DbgLog(s1); } allprogs += Progsec; } //输出程序 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; } /// /// :绘制每个单元格的内容 /// /// /// /// 行 /// 列 /// 层级 /// prog格式的指令集 /// 指令集 /// 程序步数 /// int CMTerm1View::ScanLDSCells(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(); 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; CStringA sCellNameA; sCellNameA = sCellName; if (j + nNextX >= m_CellPerLine) { continue; } //1.先获取此单元格右侧一格的竖线 if (Cells[nCurPosY][j + nNextX].bLeftLineUp || 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; 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; k <= nEndLine; k++) { if (Cells[k][j + nNextX].bLeftLineDn) { if (Cells[k][j + nNextX - 1].nType) { nLeftDnCon += 1; } } else { break; // 竖线到最下面的端点了。 } } s1.Format(_T("LeftUp %d LeftDn %d"), nLeftUpCon, nLeftDnCon); DbgLog(s1); //右侧一格的左侧下面有连接,那么扫描到这个竖线时返回,继续扫描左侧下面的内容。 if (nLeftDnCon) { return 1; } //右侧一格的左侧下面没有连接,那么这个就是左面最后的单元,开始处理右面的单元。 else { if (nLeftUpCon) { if (nPosX > 0 || nLevel > 0) { s1.Format(_T("%d %d ANS "), nCurPosY, nCurPosX); DbgLog(s1); theprog.nOpType1 = OP_ANS; progsec.Append(theprog); sProgSec.AppendFormat(_T("ANS \r\n")); nSteps += 1; nLevel -= 1; } } //从头到尾处理, 查找此竖线的最高位置; int nLineTop = nCurPosY; int nLineBottom = nCurPosY; for (int k = nCurPosY; k >= nStartLine; k--) { if (!Cells[k][j + nNextX].bLeftLineUp) { break; } nLineTop = k - 1; } // 查找右侧有几个连接 int nRightCon = 0;//单元格右侧连接数 for (int k = nLineTop; k <= nEndLine; k++) { if (Cells[k][j + nNextX].nType) { nRightCon += 1; } nLineBottom = k; if (!Cells[k][j + nNextX].bLeftLineDn) { break; } } s1.Format(_T("VLine %d - %d : %d , right = %d "), nLineTop, nLineBottom, j + nNextX, nRightCon); DbgLog(s1); if (nRightCon == 1) { 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; nSteps += theSteps; progsec += thisprogsec; s1.Format(_T("<<<< Re %d : %d , Result %d "), nLineTop, j + nNextX, 0); DbgLog(s1); continue; } else { int nLastResult = 0; int nRightCount = 0; CString sCons[100]; CString ProgSecs[100]; int res[100] = { 0 }; int nLastSteps = 0; for (int k = nLineTop; k <= nLineBottom; k++) { //s1.Format(_T("VLine %d - %d : %d %d of %d "), nLineTop, nLineBottom, j + nNextX, k+1,nRightCon); //DbgLog(s1); if (Cells[k][j + nNextX].nType) { s1.Format(_T(" >>> Go %d : %d , level %d "), k, j + nNextX, nLevel + 1); DbgLog(s1); CString ProgSec; int theSteps = 0; nLevel += 1; stProgSection thisprogsec; res[nRightCount] = ScanLDSCells(nStartLine, nEndLine, k, j + nNextX, nLevel, thisprogsec, ProgSecs[nRightCount], theSteps); nLastResult = res[nRightCount]; nSteps += theSteps; progsec += thisprogsec; //if (res[nRightCount] > 0) nLevel += 1; sProgSec += ProgSec; s1.Format(_T(" <<< Re %d : %d , Result %d Steps %d Last %d"), k, j + nNextX, res[nRightCount], theSteps, nLastSteps); DbgLog(s1); if (nRightCount == 0) { //这里是不是应该做点什么 } else if (res[nRightCount - 1] == 0) { s1.Format(_T(" POPS"), k, j + nNextX, nLevel + 1); DbgLog(s1); //sProgSec.AppendFormat(_T("POPS \r\n")); if (nLastSteps > 1) { if (sCons[nRightCount - 1] == _T("POPS")) { sCons[nRightCount - 1] = _T("RDS"); } else { sCons[nRightCount - 1] = _T("PSHS"); } sCons[nRightCount] = _T("POPS"); } } else { } nLastSteps = theSteps; nRightCount++; } } nLastResult = 0; for (int k = 0; k < nRightCount; k++) { if (nLastResult || res[k]) { s1 = _T("ST") + ProgSecs[k]; ProgSecs[k] = s1; } s1 = sCons[k] + _T("\r\n") + ProgSecs[k]; sProgSec.Append(s1); nLastResult = res[k]; } if (nLastResult) { sProgSec.Append(_T("ANS\r\n")); } return 0; } } } //如果没有竖线直接翻译 else { Translate2Prog(nType, j + nNextX, nLevel, sCellName, progsec, sProgSec, nSteps); } /* #pragma region 根据单元格类型转换为指令和prog 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); 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; 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; } #pragma endregion */ } return 0; } // 记录y,x std::pair 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(); 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; } /// /// 全部图形校验 /// /// /// /// 计划在第一个返回值中使用不同的错误代码代表不同的错误类型, /// 并在第二个返回值中填充错误提示信息 /// std::pair 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; } //遍历此行的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 { } } } return std::make_pair(0, message); }