QuakeGod
2023-09-12 78e91efc666606328e3fc63fbd54eb2da4442799
MTerm1/MTerm1View.cpp
@@ -1,5 +1,5 @@

// MTerm1View.cpp: CMTerm1View 类的实现
// MultiTerminal2View.cpp: CMTerm1View 类的实现
//
#include "pch.h"
@@ -12,6 +12,12 @@
#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
@@ -20,16 +26,61 @@
// CMTerm1View
IMPLEMENT_DYNCREATE(CMTerm1View, CView)
IMPLEMENT_DYNCREATE(CMTerm1View, CScrollView)
BEGIN_MESSAGE_MAP(CMTerm1View, CView)
BEGIN_MESSAGE_MAP(CMTerm1View, CScrollView)
   // 标准打印命令
   ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
   ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
   ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMTerm1View::OnFilePrintPreview)
   ON_WM_CONTEXTMENU()
   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 构造/析构
@@ -48,12 +99,30 @@
   // TODO: 在此处通过修改
   //  CREATESTRUCT cs 来修改窗口类或样式
   return CView::PreCreateWindow(cs);
   return CScrollView::PreCreateWindow(cs);
}
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 = ((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;
   SetTimer(1, 50,NULL);
   SetTimer(2, 10, NULL);
}
// CMTerm1View 绘图
void CMTerm1View::OnDraw(CDC* /*pDC*/)
void CMTerm1View::OnDraw(CDC* pDC)
{
   CMTerm1Doc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
@@ -61,18 +130,13 @@
      return;
   // TODO: 在此处为本机数据添加绘制代码
   CString s1;
   needReDraw = 1;
   DrawLDSGraph(pDC);
   needReDraw = 0;
}
// CMTerm1View 打印
void CMTerm1View::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
   AFXPrintPreview(this);
#endif
}
BOOL CMTerm1View::OnPreparePrinting(CPrintInfo* pInfo)
{
@@ -90,31 +154,18 @@
   // TODO: 添加打印后进行的清理过程
}
void CMTerm1View::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
   ClientToScreen(&point);
   OnContextMenu(this, point);
}
void CMTerm1View::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
   theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
// CMTerm1View 诊断
#ifdef _DEBUG
void CMTerm1View::AssertValid() const
{
   CView::AssertValid();
   CScrollView::AssertValid();
}
void CMTerm1View::Dump(CDumpContext& dc) const
{
   CView::Dump(dc);
   CScrollView::Dump(dc);
}
CMTerm1Doc* CMTerm1View::GetDocument() const // 非调试版本是内联的
@@ -124,5 +175,2663 @@
}
#endif //_DEBUG
int CMTerm1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   if (CScrollView::OnCreate(lpCreateStruct) == -1)
      return -1;
   // TODO:  在此添加您专用的创建代码
   return 0;
}
int CMTerm1View::DoReDraw()
{
   // TODO: 在此处添加实现代码.
   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);
      }
   }
   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);
//      pDC->LineTo(x0, y0 + 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;
         }
      }
   }
   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;
         }
      }
   }
   if (nChar == VK_UP) {
      nRow -= 1;
      if (nRow < 0) { nRow = 0; }
   }
   if (nChar == VK_DOWN) {
      nRow += 1;
      if (nRow >= m_nTotalRow + nLinesinView) { nRow = m_nTotalRow + nLinesinView -1; }
   }
   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);
   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("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);
   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()
{
   // TODO: 在此添加命令处理程序代码
   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;
}
void CMTerm1View::SetCellToView(stCell cell1)               //**************************************************************************************************//
{
   Cells[m_FocusRow][m_FocusCol] = cell1;
   m_bModified = 1;
   needReDraw = 1;
   m_FocusCol += 1;
   Cells[m_FocusRow][0].bEditing = 1;
   if (m_nTotalRow < m_FocusRow + 1) {
      m_nTotalRow = m_FocusRow + 1;
   }
   if (m_FocusCol >= 16)
   { m_FocusCol = 0;m_FocusRow += 1; }
   this->RedrawWindow();
}
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];
   int nEndPts = 0;
   nSts = 0;
   int nCurLine = 0;
   int cx = 0, cy = 0;
   int maxy = 0;
   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) {
               nCurLine = maxy + 1; //另起一行
               maxy = nCurLine;
               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;
         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:
         nSts--;
         nEndPts--;
         break;
      case OP_ORS:
         // 当前序列与前面的序列合并。
         //当前序列的开始结束位置
         //EndPt[nEndPts] = POINT{ cx,cy };
         //nEndPts++;
         //StPts[nSts - 1]; EndPt[nEndPts - 1];
         //前一序列的开始结束位置
         StPts[nSts - 1]; EndPt[nEndPts - 1];
         //判断二者长度
         if (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;
         nSts--;
         nEndPts--;
         break;
      case OP_PSHS:
         EndPt[nEndPts] = POINT{ cx,cy };
         nEndPts++;
         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:
         cx = EndPt[nEndPts - 1].x;
         for (int j = cx; j < m_CellPerLine; j++) {
            if (Cells[cy][j].nType != 0)
            {
               cy++; j = cx - 1; break;
            }
         }
         for (int j = EndPt[nEndPts - 1].y; j < cy; j++)
         {
            Cells[j][cx].bLeftLineDn = 1;
            Cells[j + 1][cx].bLeftLineUp = 1;
         }
         nEndPts--;
         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;
      }
   }
   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;
}
int CMTerm1View::TransLDSToProg()
{
   // TODO: 在此处添加实现代码.
   CMTerm1Doc * pDoc = GetDocument();
   CString s1;
   s1.Format(_T("Trans LDS to PRrog"));
   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; 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("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(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)
         ScanLDSCells(nStartLine, nEndLine, nCurPosY, nCurPosX, 0, thisprogsec, sProgSec,nSteps);
         sProg += sProgSec;
         nAllSteps += nSteps;
         Progsec += thisprogsec;
      }
      DbgLog(_T("\r\n")+ sProg);
      int n = int(Progsec.Progs.size());
      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("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;
}
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;
   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 (nType == typeNO) {
         if (j==0) {
            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);
         }
         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 (j == 0) {
            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);
         }
         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;
      }
      if (j + nNextX >= m_CellPerLine) continue;
      if (Cells[nCurPosY][j + nNextX].bLeftLineUp || Cells[nCurPosY][j + nNextX].bLeftLineDn) {   // 发现竖线
         //先看往上面有没有连接
         if (Cells[nCurPosY][j + nNextX].bLeftLineUp) { // 往上面有连接
            s1.Format(_T("%d %d ORS "), nCurPosY, nCurPosX);
            DbgLog(s1);
            theprog.nOpType1 = OP_ORS;
            progsec.Append(theprog);
            sProgSec.AppendFormat(_T("ORS \r\n"));
            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++) {
            if (!Cells[k][j + nNextX].bLeftLineUp) break;  // 竖线到最下面的端点了。
            if (Cells[k][j + nNextX - 1 ].nType) { nLeftDnCon += 1; break; }
         }
         s1.Format(_T("LeftUp %d   LeftDn  %d"), nLeftUpCon, nLeftDnCon);
         DbgLog(s1);
         if (nLeftDnCon) {   //左侧有连接,那么扫描到这个竖线,继续扫描左侧下面的内容。
            return 1;
         }
         if (!nLeftDnCon) {// 左侧下面没有连接,那么这个就是左面最后的单元,开始处理右面的单元。
            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, r);
               DbgLog(s1);
            }
            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;
            }
         }
      }
   }
   return 0;
}