QuakeGod
2024-01-16 6ff05a44b01c6ac6e33db2ec28dcf6e2a7c2abb0
fix LDS to Prog
22个文件已修改
1个文件已添加
1652 ■■■■■ 已修改文件
ConfigTool/ConfigTool.vcxproj 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
KLink1/KLink1.vcxproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LCDDisplay/LCDDisplay.rc 补丁 | 查看 | 原始文档 | blame | 历史
LCDDisplay/LCDDisplay.vcxproj 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
LCDDisplay/LCDDisplayTestDlg.cpp 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LCDDisplay/LCDDisplayTestDlg.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LCDDisplay/resource.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/0prog3.kpg 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/IOPoint.cpp 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1.cpp 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1.rc 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1.vcxproj 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1.vcxproj.filters 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1CommDevView.cpp 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1CommDevView.h 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1Doc.cpp 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1Doc.h 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1View.cpp 1111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MTerm1View.h 107 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MyDlgBarFuncKey.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/MyFormInputShow.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
MTerm1/Resource.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConfigTool/ConfigTool.vcxproj
@@ -44,7 +44,7 @@
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <PlatformToolset>v142</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
KLink1/KLink1.vcxproj
@@ -45,14 +45,14 @@
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <PlatformToolset>v142</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <PlatformToolset>v142</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
LCDDisplay/LCDDisplay.rc
Binary files differ
LCDDisplay/LCDDisplay.vcxproj
@@ -45,7 +45,7 @@
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <PlatformToolset>v142</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
LCDDisplay/LCDDisplayTestDlg.cpp
@@ -170,7 +170,10 @@
    return static_cast<HCURSOR>(m_hIcon);
}
void CLCDDisplayTestDlg::DbgLog(CString s1)
{
    ((CEdit*)GetDlgItem(IDC_EDIT_LOG))->ReplaceSel(s1);
}
void CLCDDisplayTestDlg::OnBnClickedButton1()
{
@@ -307,6 +310,47 @@
    }
    m_lcd_display.RedrawWindow();
    CString s1;
    CString s2;
    unsigned char pixels[8][8] = { 0 };
    for (int ch = 0; ch < 128; ch++)
    {
        long long dots = font5_7[ch];
        s1.Format(_T("{"));
        for (int m = 0; m < 7; m++) {
            int line = dots & 0x3f;
            int mask = 1;
            for (int n = 0; n < 5; n++)
            {
                if (line & mask)
                {
                    pixels[m][n] = 1;
                } else pixels[m][n] = 0;
                mask <<= 1;
            }
            dots >>= 6;
        }
        for (int m = 0; m < 5; m++) {
            int line = 0;
            int mask = 1;
            for (int n = 0; n < 7; n++)
            {
                if (pixels[n][m])
                {
                    line |= mask;
                }
                mask <<= 1;
            }
            s2.Format(_T("0x%02X"), line);
            s1 += s2 ;
            if (m < 4) { s1 += _T(","); }
        }
        s1.AppendFormat(_T("}, // %c \r\n"),ch);
        DbgLog(s1);
    }
}
LCDDisplay/LCDDisplayTestDlg.h
@@ -32,6 +32,7 @@
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    void DbgLog(CString s1);
    LCDDisplay1 m_lcd_display;
    afx_msg void OnBnClickedButton1();
    afx_msg void OnBnClickedButton2();
LCDDisplay/resource.h
@@ -15,6 +15,7 @@
#define IDC_BUTTON5                     1005
#define IDC_BUTTON6                     1006
#define IDC_EDIT1                       1007
#define IDC_EDIT_LOG                    1007
#define IDC_CHECK1                      1008
#define IDC_CHECK2                      1009
#define IDC_CHECK3                      1010
MTerm1/0prog3.kpg
@@ -1,5 +1,9 @@
[SYSCFG]
[PROG]
ST    X0
OR    Y0
AN/    X1
OUT    Y0
ST    R0
AN    R1
ST    R2
@@ -18,10 +22,33 @@
ORS
PSHS
AN    R70
AN    R66
SET    R71
POPS
RDS
SET    R72
POPS
SET    R73
ST    R1
ADD2    DT1    DT2
AN>=    DT2    K100
PSHS
SUB3    DT2    K100    DT2
SET    R15
POPS
NOT
RESET    R15
ST    R15
DF
INC    DT3
ST    R01
ST    R2
AN    R3
ST    R5
AN    R6
ORS
ANS
AN    R4
SET    R9
[COMMENT]
SR0    OFF
SR1    ON
MTerm1/IOPoint.cpp
New file
@@ -0,0 +1,215 @@
#include "pch.h"
//IOPOINT.h
#if 0
//File plc.h
#ifndef __PLC8_H
#define __PLC8_H
#define m_nAreRow 100
#define m_nAreCol 16
class CIO:public CObject
{
    DECLARE_SERIAL(CIO);
public:
    virtual void Serialize(CArchive &ar);
    CString name;
    CString addr;
    CString code;
    int Rows;
    int Cols;
    int flag;
    int fiveflag;
    int xpoint;
    int ypoint; CIO();
};
class IOPOINT:public CObject
{
    friend class LIST;
    friend class PLC;
protected:
    CString name; // 元件名称
    CString code; // 元件生成的代码()
    CString addr; // 元件地址(操作数)
    int xpoint,ypoint; // 元件x、y坐标
    int flag; // 上下左右连接关系
    int fiveflag; // 图符的索引号,图符的唯一标记
    BOOL visit; //
IOPOINT *right; IOPOINT *down; IOPOINT *left; IOPOINT *up; IOPOINT *unup; IOPOINT *undown;
public:
    IOPOINT(int x,int y,int fl,CString cd="",CString nm="",CString ad="")
    { name=nm; code=cd; addr=ad; flag=fl; fiveflag=0; visit=FALSE; xpoint=x; ypoint=y; right=0; left=0; up=0; down=0; unup=0; undown=0; }
    IOPOINT() { name=""; code=""; addr=""; flag=0; fiveflag=0; visit=FALSE; xpoint=0; ypoint=0; right=0; left=0; up=0; down=0; unup=0; undown=0; }
    void setname(const CString ioname) { name=ioname; } void setaddr(const CString ioaddr) // 设置地址
    { addr=ioaddr; }
    void setcode(const CString iocode) // 设置生成的指令
    { code=iocode; }
    void setflag(int flg)
    { flag=flg; }
    void setfiveflag(int fivflg)
    { fiveflag=fivflg; }
    void setvisit(BOOL x) { visit=x; }
    void setwhere(int x,int y) { xpoint=x; ypoint=y; }
    void getname(CString *result_name) // 获取元件名称
    { *result_name=name; }
    void getaddr(CString *result_addr) // 获取无件地址
    { *result_addr=addr; }
    void getcode(CString *result_code)
    { *result_code=code; } int getflag()
    { return flag; }
    int getfiveflag() { return fiveflag; }
    int getxpoint() { return xpoint; }
    int getypoint() { return ypoint; }
    void changeimg(int,int,CDC *);
    virtual void setstatu() {}
    virtual void print(int x,int y,CDC *pDC) { changeimg(x,y,pDC); }
    virtual void put_img(int,int,CDC *){}
    virtual int testaddr();
};
class LD :public IOPOINT
{ public:
    LD(int x,int y,int flg,CString cd="LD",CString nm="",CString ad="") :IOPOINT(x,y,flg,cd,nm,ad) {};
    LD():IOPOINT() { setcode("LD"); }
    void put_img(int x,int y,CDC *pDC);
    void print(int x,int y,CDC *pDC);
};
class LDI :public IOPOINT
{
public:
    LDI(int x,int y,int flg,CString cd="LDI",CString nm="",CString ad="") :IOPOINT(x,y,flg,cd,nm,ad) {}
    LDI():IOPOINT() { setcode("LDI"); } void put_img(int x,int y,CDC *pDC);
    void print(int x,int y,CDC *pDC);
};
class OR :public IOPOINT
{
public:
    OR(int x,int y,int flg,CString cd="OR",CString nm="",CString ad="") :IOPOINT(x,y,flg,cd,nm,ad) {}
    OR():IOPOINT() { setcode("OR"); }
    void put_img(int x,int y,CDC *pDC);
    void print(int x,int y,CDC *pDC);
};
class ORI :public IOPOINT {
public:
    ORI(int x,int y,int flg,CString cd="ORI",CString nm="",CString ad="") :IOPOINT(x,y,flg,cd,nm,ad) {}
    ORI():IOPOINT() { setcode("ORI"); }
    void put_img(int x,int y,CDC *pDC);
    void print(int x,int y,CDC *pDC);
};
class HOR :public IOPOINT
{
public:
    HOR(int x,int y,int flg,CString cd="HOR",CString nm="",CString ad="") :IOPOINT(x,y,flg,cd,nm,ad) {}
    HOR():IOPOINT() {}
    int testaddr();
    void print(int x,int y,CDC *pDC);
};
class ERECT :public IOPOINT
{
public:
    ERECT(int x,int y,int flg,CString cd="ERECT",CString nm="",CString ad="") :IOPOINT(x,y,flg,cd,nm,ad) {}
    ERECT():IOPOINT() {}
    int testaddr() { return 0; }
    void print(int x,int y,CDC *pDC);
};
class OUTPOINT :public IOPOINT
{
public:
    OUTPOINT(int x,int y,int flg,CString cd="OUT",CString nm="",CString ad="") :IOPOINT(x,y,flg,cd,nm,ad) {}
    OUTPOINT():IOPOINT() { setcode("OUT"); }
    int testaddr() { return 0; }
    void put_img(int x,int y,CDC *pDC);
    void print(int x,int y,CDC *pDC);
};
class ADDTION:public IOPOINT
{
public:
    ADDTION(int x,int y,int flg,CString cd="",CString nm="",CString ad="") :IOPOINT(x,y,flg,cd,nm,ad) {}
    ADDTION():IOPOINT() {}
    int testaddr();
    void put_img(int x,int y,CDC *pDC);
    void print(int x,int y,CDC *pDC);
};
class LIST:public CObject
{
friend class PLC;
private:
    IOPOINT *root;
public:
    LIST() { root=0; }
    IOPOINT * ANBtest(IOPOINT *p);
    IOPOINT * ANBcompile(IOPOINT *p,IOPOINT *endpoint);
    IOPOINT * ORBtest(IOPOINT *p,IOPOINT *q);
    IOPOINT * ORBcompile(IOPOINT *p);
    int compile(IOPOINT *);
};
class PLC:public CObject
{
friend class CLADDoc;
private:
int Cols;
int Rows;
IOPOINT * point_array[m_nAreRow][m_nAreCol];
LIST list_array[20];
int step;
public:
    IOPOINT * getpoint(int row,int col);
    int getcols();
    int getrows();
    void SetRowCol(int row,int col);
    PLC();
    void getstep();
    int syntax(CString &m_strlist);
    int testpoint(int row,int col);
    void insert_point(IOPOINT *n);
    void remove_point(int x,int y);
    int compiled(CString &m_strlist);
    void newfile();
};
#endif
//IOPOINT.cpp
//FILE:iopoint.CPP
#include "stdafx.h"
#include "iopoint.h"
//extern int CurrentCols;
extern FILE *fp;
extern int CurH;
extern int CurW;
extern CString filename;
IMPLEMENT_SERIAL(CIO,CObject,1)
CIO::CIO()
{ name=""; addr=""; code=""; Rows=0; Cols=0; flag=0; fiveflag=0; xpoint=0; ypoint=0; }
 /* IOPOINT 判断无件地址是否有效 */
int IOPOINT::testaddr()
{ char ch;
if ((addr.GetLength()!=4) || addr[2]>'7' || addr[3]>'7') return 1;
else {
    ch=addr[0];
    switch (ch) {
    case 'X': if (addr<"X000" || addr>"X527") return 1;
            else break;
    case 'Y': if (addr<"Y000" || addr>"Y647") return 1;
            else break;
    case 'M': if (addr<"M000" || addr>"M977") return 1;
            else break;
    case 'C': if (addr<"C060" || addr>"C067" && addr>"C460" || addr>"C467") return 1;
            else break;
    case 'T': if (!((addr>="T050" && addr<="T057") ||(addr>="T450" && addr<="T457") ||(addr>="T550" && addr<="T557") ||(addr>="T650" && addr<="T657") ||(addr>="T700" && addr<="T777"))) return 1;
            else break;
    default: return 1;
        }
    return 0;
    }
}
void IOPOINT::changeimg(int x,int y,CDC *pDC) { int x1,y1,x2,y2; if (down!=NULL) { x1=x+::CurW; y1=y+::CurH-10; x2=x1; y2=y1+::CurH; pDC->MoveTo(x1,y1); pDC->LineTo(x2,y2); if (down->up!=NULL) { x1=x; x2=x1; pDC->MoveTo(x1,y1); pDC->LineTo(x2,y2); } } if (up!=NULL) { x1=x; y1=y+::CurH-10; x2=x1; y2=y1-::CurH; pDC->MoveTo(x1,y1); pDC->LineTo(x2,y2); if (up->down!=NULL) { x1=x+::CurW; x2=x1; pDC->MoveTo(x1,y1); pDC->LineTo(x2,y2); } } if (fiveflag==5) { x1=x+::CurW; y1=y+::CurH-10; x2=x1; y2=y1-::CurH; pDC->MoveTo(x1,y1); pDC->LineTo(x2,y2); } } void LD::put_img(int x,int y,CDC *pDC) { int x1,y1; x1=x; y1=y+::CurH-10; pDC->MoveTo(x1,y1); x1=x1+20; pDC->LineTo(x1,y1); pDC->MoveTo(x1,y1-10); y1=y+::CurH; pDC->LineTo(x1,y1); x1=x1+20; pDC->MoveTo(x1,y1); pDC->LineTo(x1,y1-20); pDC->MoveTo(x1,y1-10); pDC->LineTo(x+::CurW,y1-10); } void LD::print(int x,int y,CDC *pDC) { put_img(x,y,pDC); pDC->SetBkMode(TRANSPARENT); pDC->SetTextAlign(TA_CENTER+TA_BOTTOM); pDC->TextOut(x+::CurW/2,y+40,name); pDC->TextOut(x+::CurW/2,y+60,addr); changeimg(x,y,pDC); } void LDI::put_img(int x,int y,CDC *pDC) { int x1,y1; x1=x; y1=y+::CurH-10; pDC->MoveTo(x1,y1); x1=x1+20; pDC->LineTo(x1,y1); pDC->MoveTo(x1,y1-10); y1=y+::CurH; pDC->LineTo(x1,y1); x1=x1+20; pDC->MoveTo(x1,y1); pDC->LineTo(x1,y1-20); pDC->MoveTo(x1,y1-10); pDC->LineTo(x+::CurW,y1-10); pDC->MoveTo(x1-3,y1-17); pDC->LineTo(x1-17,y1-3); } void LDI::print(int x,int y,CDC *pDC) { put_img(x,y,pDC); pDC->SetBkMode(TRANSPARENT); pDC->SetTextAlign(TA_CENTER+TA_BOTTOM); pDC->TextOut(x+::CurW/2,y+40,name); pDC->TextOut(x+::CurW/2,y+60,addr); changeimg(x,y,pDC); } void OR::put_img(int x,int y,CDC *pDC) { int x1,y1; x1=x; pDC->MoveTo(x1,y-10); y1=y+::CurH-10; pDC->LineTo(x1,y1); x1=x1+20; pDC->LineTo(x1,y1); pDC->MoveTo(x1,y1-10); y1=y+::CurH; pDC->LineTo(x1,y1); x1=x1+20; pDC->MoveTo(x1,y1); pDC->LineTo(x1,y1-20); pDC->MoveTo(x1,y1-10); pDC->LineTo(x+::CurW,y1-10); pDC->LineTo(x+::CurW,y-10); } void OR::print(int x,int y,CDC *pDC) { put_img(x,y,pDC); pDC->SetBkMode(TRANSPARENT); pDC->SetTextAlign(TA_CENTER+TA_BOTTOM); pDC->TextOut(x+::CurW/2,y+40,name); pDC->TextOut(x+::CurW/2,y+60,addr); changeimg(x,y,pDC); } void ORI::put_img(int x,int y,CDC *pDC) { int x1,y1; x1=x; pDC->MoveTo(x1,y-10); y1=y+::CurH-10; pDC->LineTo(x1,y1); x1=x1+20; pDC->LineTo(x1,y1); pDC->MoveTo(x1,y1-10); y1=y+::CurH; pDC->LineTo(x1,y1); x1=x1+20; pDC->MoveTo(x1,y1); pDC->LineTo(x1,y1-20); pDC->MoveTo(x1,y1-10); pDC->LineTo(x+::CurW,y1-10); pDC->MoveTo(x1-3,y1-17); pDC->LineTo(x1-17,y1-3); pDC->MoveTo(x+::CurW,y1-10); pDC->LineTo(x+::CurW,y-10); } void ORI::print(int x,int y,CDC *pDC) { put_img(x,y,pDC); pDC->SetBkMode(TRANSPARENT); pDC->SetTextAlign(TA_CENTER+TA_BOTTOM); pDC->TextOut(x+::CurW/2,y+40,name); pDC->TextOut(x+::CurW/2,y+60,addr); changeimg(x,y,pDC); } void HOR::print(int x,int y,CDC *pDC) { pDC->MoveTo(x,y+::CurH-10); pDC->LineTo(x+::CurW,y+::CurH-10); changeimg(x,y,pDC); } int HOR::testaddr() { return 0; } void ERECT::print(int x,int y,CDC *pDC) { pDC->MoveTo(x+::CurW,y-10); pDC->LineTo(x+::CurW,y+::CurH-10); } void OUTPOINT::put_img(int x,int y,CDC *pDC) { int x1,y1; x1=x+21; y1=y+::CurH-10; pDC->MoveTo(x,y1); pDC->LineTo(x1,y1); CRect rcEllipse(x1,y1-9,x1+18,y1+9); pDC->SelectStockObject(NULL_BRUSH); pDC->Ellipse(rcEllipse); pDC->MoveTo(x1+18,y1); pDC->LineTo(x+::CurW,y1); } void OUTPOINT::print(int x,int y,CDC *pDC) { put_img(x,y,pDC); pDC->SetBkMode(TRANSPARENT); pDC->SetTextAlign(TA_CENTER+TA_BOTTOM); pDC->TextOut(x+::CurW/2,y+40,name); pDC->TextOut(x+::CurW/2,y+60,addr); changeimg(x,y,pDC); } void ADDTION::put_img(int x,int y,CDC *pDC) { pDC->MoveTo(x,y+::CurH-10); pDC->LineTo(x+16,y+::CurH-10); pDC->MoveTo(x+21,y+::CurH-18); pDC->LineTo(x+16,y+::CurH-18); pDC->LineTo(x+16,y+::CurH-1); pDC->LineTo(x+21,y+::CurH-1); pDC->MoveTo(x+37,y+::CurH-1); pDC->LineTo(x+42,y+::CurH-1); pDC->LineTo(x+42,y+::CurH-18); pDC->LineTo(x+37,y+::CurH-18); pDC->MoveTo(x+42,y+::CurH-10); pDC->LineTo(x+::CurW,y+::CurH-10); } void ADDTION::print(int x,int y,CDC *pDC) { put_img(x,y,pDC); pDC->SetBkMode(TRANSPARENT); pDC->SetTextAlign(TA_CENTER+TA_BOTTOM); pDC->TextOut(x+::CurW/2,y+40,name); pDC->TextOut(x+::CurW/2,y+60,addr); pDC->TextOut(x+30,y+77,code); changeimg(x,y,pDC); } int ADDTION::testaddr() { char ch; int i; if (addr.GetLength()>4)// || strlen(name)==0) return 1; for (i=1;i<name.GetLength();i++) if (addr[i]>'7') return 1; switch (flag) { /************************************************************ 8--SET 9--S 10--MC 12--K 18--RST 19--R 11--MCR 13--F 14--PLS 15--END ************************************************************/ case 8: case 9: case 18: case 19: { ch=addr[0]; switch (ch) { case 'Y': if (addr<"Y000" || addr>"Y647") return 1; else break; case 'M': if (addr<"M000" || addr>"M977") return 1; else break; case 'C': if (addr<"C060" || (addr>"C067" && addr<"C460") || addr>"C467") return 1; else break; default: return 1; }//end of switch(ch) break; } case 10: case 11: case 14: { ch=addr[0]; switch (ch) { case 'M': if (addr<"M000" || addr>"M777") return 1; else break; default: return 1; }//end of switch(ch) break; } case 12: { if (addr<"K000" || addr>"K777") return 1; break; } case 13: { if (addr<"F670" || addr>"F673") return 1; break; } case 15: break; default: return 1; }// switch(flag); return 0; } IOPOINT * LIST::ANBtest(IOPOINT *p) { IOPOINT *q; IOPOINT *returnpoint=NULL; BOOL flag; flag=FALSE; while (p->unup!=NULL) { p=p->unup; q=p; while (q->getflag()!=0 && (q->right!=NULL|| q->getfiveflag()==5)) { flag=TRUE; if (q->undown!=NULL) { flag=FALSE; returnpoint=q; break; } q=q->right; } if (flag) break; } return returnpoint; } IOPOINT * LIST::ANBcompile(IOPOINT *p,IOPOINT *endpoint) { // IOPOINT *breakpoint; IOPOINT *returnpoint; IOPOINT *temp; IOPOINT point; int j; BOOL NoAnb; // breakpoint=p; j=0; NoAnb=TRUE; while(1) { if (NoAnb) { switch (p->getflag()) { case 1: if (j>0) fprintf(::fp,"%s/t%s/t/t;%s/n","AND",p->addr,p->name); else fprintf(::fp,"%s/t%s/t/t;%s/n","LD",p->addr,p->name); j++; break; case 2: if (j>0) fprintf(::fp,"%s/t%s/t/t;%s/n","ANI",p->addr,p->name); else fprintf(::fp,"%s/t%s/t/t;%s/n","LDI",p->addr,p->name); j++; break; default: break; }// end of switch (p->getflag()) p->setvisit(TRUE); if (p->down!=NULL) { temp=ORBtest(p,&point); if (temp!=NULL) { returnpoint=ORBcompile(temp); if (returnpoint==endpoint) return returnpoint; else if (returnpoint->down!=NULL) { temp=ORBtest(returnpoint,&point); if (temp!=NULL) { returnpoint=ORBcompile(temp); if (returnpoint==endpoint) return returnpoint; } } } } while (p->visit==TRUE) p=p->right; }// end of if (NoAnb) if (p->unup!=NULL) { temp=ANBtest(p); if (temp!=NULL) { NoAnb=FALSE; returnpoint=ANBcompile(p,temp); if (j>0) fprintf(::fp,"%s/n","ANB"); if (returnpoint->down!=NULL) { temp=ORBtest(returnpoint,&point); if (temp!=NULL) { returnpoint=ORBcompile(temp); if (returnpoint==endpoint) return returnpoint; } } } else NoAnb=TRUE; } while (p->visit==TRUE) p=p->right; }// end of while(1) } IOPOINT * LIST::ORBtest(IOPOINT *p,IOPOINT *q) { q=p->down; do { p=p->down; while ((q->left!=NULL) && (q->left->getflag()!=0) && (q->getfiveflag()!=9) && (q->left->visit!=TRUE)) q=q->left; if (((q->up!=NULL)||(q->getypoint()==0)) &&(q->visit==0) &&(q->getflag()!=0)) return p; q=q->down; }while (q!=NULL); p=NULL; return p; } IOPOINT * LIST::ORBcompile(IOPOINT *p) { IOPOINT *breakpoint; IOPOINT *result; IOPOINT point; IOPOINT *q,*returnpoint; IOPOINT *temp; // int m; int i,j; BOOL NoAnb; i=0; j=1; q=p; NoAnb=TRUE; if (q->getflag()!=6) i++; while ((q->left!=NULL)&&(q->left->getflag()!=0) && (q->getfiveflag()!=9) && (q->left->visit!=TRUE)) { q=q->left; if (q->getflag()!=6) i++; } returnpoint=p; result=p; breakpoint=q; while(1) { if (NoAnb) { switch (q->getflag()) { case 1: if (i>1) { if (j==1) fprintf(::fp,"%s/t%s/t/t;%s/n",q->code,q->addr,q->name); else fprintf(::fp,"%s/t%s/t/t;%s/n","AND",q->addr,q->name); j++; } else fprintf(::fp,"%s/t%s/t/t;%s/n","OR",q->addr,q->name); break; case 2: if (i>1) { if (j==1) fprintf(::fp,"%s/t%s/t/t;%s/n",q->code,q->addr,q->name); else fprintf(::fp,"%s/t%s/t/t;%s/n","ANI",q->addr,q->name); j++; } else fprintf(::fp,"%s/t%s/t/t;%s/n","ORI",q->addr,q->name); break; case 3: case 4: fprintf(::fp,"%s/t%s/t/t;%s/n",q->code,q->addr,q->name); default: break; }//end of switch (q->getflag()) q->setvisit(TRUE); if (q==p && j>1) fprintf(::fp,"%s/n","ORB"); if (q->down!=NULL) { if (q!=p) { temp=ORBtest(q,&point); if (temp!=NULL) result=ORBcompile(temp); } if (q==p) { temp=ORBtest(q,&point); if (temp!=NULL && breakpoint->getypoint()==point.getypoint()) returnpoint=ORBcompile(temp); } } if (q==p) break; else q=q->right; }// end of if (NoAnb) if (q->unup!=NULL) { temp=ANBtest(q); if (temp!=NULL) { NoAnb=0; result=ANBcompile(q,temp); if (j>1) fprintf(::fp,"%s/n","ANB"); while (q->visit==TRUE) if (q==p) break; else q=q->right; if (q==p && q->visit==TRUE) { if (j>1) fprintf(::fp,"%s/n","ORB"); if (result->down!=NULL) { temp=ORBtest(result,&point); if (temp!=NULL && breakpoint->getypoint()==point.getypoint()) returnpoint=ORBcompile(temp); } break; } }// end of (m!=0) else NoAnb=1; }//end of if (q->unup!=NULL) }//end of while (1); (q!=p) return returnpoint; } int LIST::compile(IOPOINT *head) { IOPOINT *p; IOPOINT *temp; IOPOINT *q; IOPOINT *returnpoint; IOPOINT point; int flag; BOOL found; BOOL NoAnb; //int r; int i; if ((fp=fopen(::filename,"a+"))==NULL) return 5; p=head; i=0; NoAnb=TRUE; flag=p->getflag(); found=FALSE; while(1) { while ((flag<7) && (p->right!=NULL)) { if (p->unup!=NULL) { temp=ANBtest(p); if (temp!=NULL) { NoAnb=FALSE; returnpoint=ANBcompile(p,temp); if (i>0) fprintf(::fp,"%s/n","ANB"); i++; while (returnpoint->down!=NULL && (temp=ORBtest(returnpoint,&point))!=NULL) { returnpoint=ORBcompile(temp); } while (p->visit==TRUE) p=p->right; flag=p->getflag(); } else NoAnb=TRUE; } if (NoAnb) { switch (flag) { case 1: if (i==0) fprintf(::fp,"%s/t%s/t/t;%s/n",p->code,p->addr,p->name); else fprintf(::fp,"%s/t%s/t/t;%s/n","AND",p->addr,p->name); i++; break; case 2: if (i==0) fprintf(::fp,"%s/t%s/t/t;%s/n",p->code,p->addr,p->name); else fprintf(::fp,"%s/t%s/t/t;%s/n","ANI",p->addr,p->name); i++; break; default: break; }//switch(flag) p->setvisit(TRUE); if (p->down!=NULL) { temp=ORBtest(p,&point); if (temp!=NULL) { returnpoint=ORBcompile(temp); // while (returnpoint->down!=NULL // && (temp=ORBtest(returnpoint,&point))!=NULL) // { // returnpoint=ORBcompile(temp); // } } } while (p->visit==TRUE) p=p->right; flag=p->getflag(); }//if (NoAnb) }//while ((flag<7) && (p->right!=NULL)) if (flag>=7) { fprintf(fp,"%s/t%s/t/t;%s/n",p->code,p->addr,p->name); p->setvisit(TRUE); } do { if (p->unup!=NULL) { temp=p; while (temp->unup!=NULL) { temp=temp->unup; q=temp; while (q->getflag()!=0 && q->getflag()<7 && q->right!=NULL) q=q->right; if (q->getflag()>=7) { found=TRUE; break; } } if (found) { p=temp; flag=p->getflag(); break; } }// end of if (p->unup!=NULL) p=p->left; }while(p!=NULL && p->left!=NULL); if (!found) break; else found=FALSE; }//end of While(1) fprintf(fp,"/n;***/n/n"); fclose(fp); return 0; } PLC::PLC() { newfile(); Rows=m_nAreRow; Cols=m_nAreCol; } void PLC::newfile() { UINT i,j; for (i=0;i<m_nAreRow;i++) for (j=0;j<m_nAreCol;j++) point_array[i][j]=NULL; for (i=0;i<20;i++) list_array[i].root=0; } void PLC::getstep() { int i,j; int n; BOOL flag; for (i=0,n=0;i<Rows;i++) { flag=TRUE; for (j=0;j<Cols;j++) if ((point_array[i][j] == NULL) || (point_array[i][j]->up!=NULL && j!=0)) { flag=FALSE; break; } if (flag) { list_array[n].root=point_array[i][0]; n++; } } step=n; } int PLC::testpoint(int row,int col) { if (point_array[row][col]==NULL) return 0; else return 1; } void PLC::insert_point(IOPOINT *n) { int i,j; int flag; IOPOINT *temp; i=n->getxpoint(); j=n->getypoint(); if (n->getfiveflag()!=5) { if (point_array[i][j]!=NULL) { flag=point_array[i][j]->getfiveflag(); if (flag!=5 && flag!=9) remove_point(i,j); if (flag==5 || flag==9) { temp=point_array[i][j]; n->setfiveflag(flag); n->left=temp->left; n->right=temp->right; n->up=temp->up; n->down=temp->down; n->unup=temp->unup; n->undown=temp->undown; if (n->up!=NULL) n->up->unup=n; if (n->unup!=NULL) n->unup->up=n; if (n->down!=NULL) n->down->undown=n; if (n->undown!=NULL) n->undown->down=n; delete (temp); } } point_array[i][j]=n; if (j==0) { if ((i>0) && (point_array[i-1][j]!=NULL)) { point_array[i-1][j]->unup=n; n->up=point_array[i-1][j]; } if (point_array[i+1][j]!=NULL) { point_array[i+1][j]->up=n; n->unup=point_array[i+1][j]; } } if (j<Cols-1) { if (point_array[i][j+1] != NULL) { n->right=point_array[i][j+1]; point_array[i][j+1]->left=n; if ((n->right->up !=NULL) && (n->right->up->left !=NULL)) { n->right->up->left->down=n; n->undown=n->right->up->left; } if ((i>0) && (point_array[i][j+1]->getfiveflag()==9) && (point_array[i-1][j]!=NULL)) { point_array[i-1][j]->down=n; n->undown=point_array[i-1][j]; } } if ((point_array[i+1][j+1]!=NULL) && ((point_array[i+1][j+1]->up != NULL) || (point_array[i+1][j+1]->getfiveflag()==9)) && (point_array[i+1][j+1]->left != NULL)) { n->down=point_array[i+1][j]; point_array[i+1][j]->undown=n; } } if (j>0) { if (point_array[i][j-1] != NULL) { n->left=point_array[i][j-1]; point_array[i][j-1]->right=n; if ((n->left->down != NULL) && (n->left->down->right != NULL)) { point_array[i+1][j]->up=n; n->unup=point_array[i+1][j]; } if ((i>0) && ((n->left->getfiveflag()==5) ||(n->left->undown!=NULL)) && (point_array[i-1][j]!=NULL)) { n->up=point_array[i-1][j]; point_array[i-1][j]->unup=n; } } if ((point_array[i+1][j-1]!=NULL) && ((point_array[i+1][j-1]->undown!=NULL) ||(point_array[i+1][j-1]->getfiveflag()==5)) && (point_array[i+1][j]!=NULL)) { n->unup=point_array[i+1][j]; point_array[i+1][j]->up=n; } if ((i>0) && (point_array[i-1][j-1]!=NULL) && (point_array[i-1][j-1]->down != NULL) && (point_array[i-1][j] != NULL)) { n->up=point_array[i-1][j]; point_array[i-1][j]->unup=n; } } //if (j>0) if (point_array[i+1][j]!=NULL && point_array[i+1][j]->getfiveflag()==5) { n->down=point_array[i+1][j]; point_array[i+1][j]->undown=n; } if (point_array[i+1][j]!=NULL && point_array[i+1][j]->getfiveflag()==9) { n->unup=point_array[i+1][j]; point_array[i+1][j]->up=n; } if (point_array[i+1][j]!=NULL && (point_array[i+1][j]->getflag()==3 || point_array[i+1][j]->getflag()==4)) { n->down=point_array[i+1][j]; point_array[i+1][j]->undown=n; point_array[i+1][j]->up=n; n->unup=point_array[i+1][j]; if ((n->left != NULL) && (point_array[i+1][j]->left != NULL)) { n->left->down=point_array[i+1][j]->left; point_array[i+1][j]->left->undown=n->left; } if ((n->right != NULL) && (point_array[i+1][j]->right != NULL)) { point_array[i+1][j]->right->up=n->right; n->right->unup=point_array[i+1][j]->right; } } /* if ((i>0) && ((n->getflag()==3) || (n->getflag()==4))) { if (point_array[i-1][j] != NULL) { n->up=point_array[i-1][j]; point_array[i-1][j]->unup=n; point_array[i-1][j]->down=n; n->undown=point_array[i-1][j]; if ((point_array[i-1][j]->left != NULL) && (n->left != NULL)) { point_array[i-1][j]->left->down=n->left; n->left->undown=point_array[i-1][j]; } if ((n->right != NULL) && (point_array[i-1][j]->right != NULL)) { n->right->up=point_array[i-1][j]->right; point_array[i-1][j]->right->unup=n->right; } } //if (point_array[i-1][j] != NULL) }//if ((i>0) && ((n->getflag()==3) || (n->getflag()==4)))*/ }//if (n->getflag()!=5) else { if (i>0) { if (point_array[i][j]!=NULL) point_array[i][j]->setfiveflag(5); else point_array[i][j]=n; if (j<Cols-1) { if (point_array[i][j+1]!=NULL) { if (point_array[i][j+1]->getfiveflag()!=5) point_array[i][j+1]->setfiveflag(9); point_array[i][j]->right=point_array[i][j+1]; point_array[i][j+1]->left=point_array[i][j]; } else { temp=new IOPOINT; temp->setwhere(i,j+1); temp->setfiveflag(9); point_array[i][j+1]=temp; point_array[i][j]->right=point_array[i][j+1]; point_array[i][j+1]->left=point_array[i][j]; } if ((point_array[i-1][j+1]!=NULL) &&(point_array[i][j]->right!=NULL)) { point_array[i-1][j+1]->unup=point_array[i][j]->right; point_array[i][j]->right->up=point_array[i-1][j+1]; } }// end of if (j<Maxcol-1) if (point_array[i-1][j]!=NULL) { point_array[i-1][j]->down=point_array[i][j]; point_array[i][j]->undown=point_array[i-1][j]; } if ((point_array[i+1][j]!=NULL) && (point_array[i+1][j]->getfiveflag()==5)) { point_array[i][j]->down=point_array[i+1][j]; point_array[i+1][j]->undown=point_array[i][j]; if (j<Cols) { point_array[i][j+1]->unup=point_array[i+1][j+1]; point_array[i+1][j+1]->up=point_array[i][j+1]; } } }//end of if (i>0) }//end of "if(n->getflag()!=5" else } void PLC::remove_point(int x,int y) { int i,j; IOPOINT *temp,*p; i=x; j=y; temp=point_array[i][j]; if (temp==NULL) return; if (temp->getfiveflag()==9) { p=new IOPOINT; p->setfiveflag(9); if (temp->up!=NULL) { p->up=temp->up; p->up->unup=p; } if (temp->unup!=NULL) { p->unup=temp->unup; p->unup->up=p; } if (temp->left!=NULL) { p->left=temp->left; p->left->right=p; } point_array[i][j]=p; } // if (temp->getfiveflag()==9) else { point_array[i][j]=NULL; if (temp->left != NULL) temp->left->right=NULL; if (temp->right != NULL) temp->right->left=NULL; if (temp->up!=NULL) { temp->up->unup=NULL; temp->up=NULL; } if (temp->down!=NULL) { temp->down->undown=NULL; temp->down=NULL; } if (temp->unup!=NULL) { temp->unup->up=NULL; temp->unup=NULL; } if (temp->undown!=NULL) { temp->undown->down=NULL; temp->undown=NULL; } if (temp->getfiveflag()==5) { if (temp->right!=NULL)//j<m_nAreCol-1) { if (temp->right->getfiveflag()!=5) temp->right->setfiveflag(0); int flag=temp->right->getflag(); if (flag==3 || flag==4) temp->right->setflag(flag-2); if (temp->right->up!=NULL) { temp->right->up->unup=NULL; temp->right->up=NULL; } if (temp->right->getflag()==0 && temp->right->getfiveflag()!=5) { p=temp->right; if (p->unup!=NULL) { p->unup->up=NULL; p->unup=NULL; } if (p->down!=NULL) { p->down->undown=NULL; p->down=NULL; } if (p->undown!=NULL) { p->undown->down=NULL; p->undown=NULL; } delete p; point_array[i][j+1]=NULL; } //if (temp->right->getflag()==0) } // if (temp->right!=NULL) if (temp->left!=NULL && temp->left->getfiveflag()==5) { IOPOINT * renew; renew=new IOPOINT; renew->setfiveflag(9); renew->setwhere(i,j); insert_point(renew); } }//if (temp->getfiveflag()==5) }//if (temp->getfiveflag()==9) else delete temp; } int PLC::syntax(CString &m_strlist) { IOPOINT *p; int outflag,topflag,result,flag; int i,j; CString str; result=0; // m_list.ResetContent(); for (i=0;i<step;i++) { outflag=0; topflag=0; p=list_array[i].root; for (j=0;j<Cols;j++) { flag=p->getflag(); if (flag>=7) { outflag++; p=p->right; continue; } if (flag!=6 && outflag) outflag++; if (flag==3 || flag==4 || p->getfiveflag()==5) topflag++; p=p->right; } if (outflag!=1) { result=1; str.Format("第 %d 程序段输出语句错误!/r/n",i+1); m_strlist+=str; } if (topflag) { result=1; str.Format("第 %d 程序段首行含有 %d 个OR、ORI或ERECT结点!/r/n",i+1,topflag); m_strlist+=str; } } CString addr; int fiveflag; for (i=0;i<100;i++) for (j=0;j<Cols;j++) if (point_array[i][j]!=NULL) { flag=point_array[i][j]->getflag(); fiveflag=point_array[i][j]->getfiveflag(); point_array[i][j]->getaddr(&addr); if ((point_array[i][j]->left==NULL) && (point_array[i][j]->up==NULL) && (point_array[i][j]->down==NULL) && (point_array[i][j]->right==NULL)) { result=1; str.Format("第 %d 行,第 %d 列是孤立结点!/r/n",i+1,j+1); m_strlist+=str; } if ((flag==0 && fiveflag!=5 && fiveflag!=9) || flag==100) { result=1; str.Format("第 %d 行,第 %d 列结点类型错误!/r/n",i+1,j+1); m_strlist+=str; } if (addr.GetLength()==0 && flag!=0 && flag!=6 && flag!=12 && flag!=13 && flag!=15) { result=1; str.Format("第 %d 行,第 %d 列结点没进行元器件设置!/r/n",i+1,j+1); m_strlist+=str; } point_array[i][j]->getcode(&addr); if ((flag==12 || flag==13) && addr.GetLength()!=4) { result=1; str.Format("第 %d 行,第 %d 列结点F、K命令错误!/r/n",i+1,j+1); m_strlist+=str; } } return result; } int PLC::compiled(CString &m_strlist) { int i,j; int flag; CString str; getstep(); flag=syntax(m_strlist); if (flag) return flag; if ((fp=fopen(::filename,"w+"))==NULL) { str.Format("文件%s不能建立!/r/n",::filename); m_strlist+=str; return 1; } fclose(fp); for (i=0;i<Rows;i++) for (j=0;j<Cols;j++) if (point_array[i][j]!=NULL) point_array[i][j]->setvisit(FALSE); for (i=0;i<step;i++) { flag=list_array[i].compile(list_array[i].root); if (flag) { str.Format("编译错误!/r/n"); m_strlist+=str; return flag; } } int sum=0; for (i=0;i<Rows;i++) for (j=0;j<Cols;j++) { if (point_array[i][j]!=NULL) { flag=point_array[i][j]->getflag(); if (point_array[i][j]->visit==FALSE && flag!=0 && flag!=6) { str.Format("第 %d 行,第 %d 列结点没有编译!/r/n",i+1,j+1); m_strlist+=str; sum++; if (sum==10) return 1; } } } return sum; } void PLC::SetRowCol(int row, int col) { Rows=row; Cols=col; } int PLC::getrows() { return Rows; } int PLC::getcols() { return Cols; } void CIO::Serialize(CArchive &ar) { CObject::Serialize(ar); if (ar.IsStoring()) { ar<<name; ar<<addr; ar<<code; ar<<Rows; ar<<Cols; ar<<flag; ar<<fiveflag; ar<<xpoint; ar<<ypoint; } else { ar>>name; ar>>addr; ar>>code; ar>>Rows; ar>>Cols; ar>>flag; ar>>fiveflag; ar>>xpoint; ar>>ypoint; } } IOPOINT * PLC::getpoint(int row, int col) { return (point_array[row][col]); }
XXDoc.cpp
/* 菜单编译 —— 生成指令 */ void CLADDoc::OnCompileLad() { // TODO: Add your command handler code here CString pathname=this->GetPathName(); // 获取文件路径 if (pathname=="") { AfxMessageBox("请先保存文件,再进行编译!"); return ; } this->OnSaveDocument(pathname); // 保存文档 ::filename=pathname+this->GetTitle(); int i=::filename.Find('.'); if (i!=-1) ::filename=::filename.Mid(0,i); ::filename+=".plc"; // 保存为PLC后缀 CString str; try{ if (!m_mPlc.compiled(str)) str.Format("编译成功!"); if (err_dlg) { err_dlg->Refresh(str); err_dlg->ShowWindow(SW_RESTORE); } else { err_dlg=new CSyntax(str,AfxGetMainWnd()); err_dlg->CenterWindow(); err_dlg->ShowWindow(SW_SHOW); } err_dlg->UpdateData(FALSE); } catch(...) { POSITION pos=this->GetFirstViewPosition(); CView * pView=this->GetNextView(pos); pView->MessageBox("可能梯形图绘制有错、/n或文件不能建立","编译出错",MB_ICONERROR|MB_OK); } }
#endif
MTerm1/MTerm1.cpp
@@ -576,7 +576,7 @@
    return res;
}
CString & intToString(int num, int digit)
CString intToString(int num, int digit)
{
    static CString Str1;
    if (digit != 0) {
@@ -598,7 +598,29 @@
    return Str1;
}
CString fixToString(int num, int digit, int fracdigit)
{
    static CString Str1;
    if (digit != 0) {
        CString str2;
        str2.Format(_T("%%%dd"), digit);
        Str1.Format(str2, num);
    }
    else {
        Str1.Format(_T("%d"), num);
    }
    int k = Str1.GetLength();
    int j = (k - 1 - fracdigit) / 3;    //逗号个数
    int l = k - fracdigit - j * 3; //起始位置
    for (int i = l; i < k -fracdigit + j; i += 4)
    {
        Str1.Insert(i, _T(","));
    }
    if (fracdigit>0) Str1.Insert(k - fracdigit + j, '.');
    return Str1;
}
CString & intToBinString(int num, int digits)
{
    static CString Str1;
MTerm1/MTerm1.h
@@ -104,7 +104,8 @@
//extern HvSerialPort myHvSerialPort1;
CString & intToString(int num,int digit=0);
CString  intToString(int num,int digit=0);
CString fixToString(int num, int digit = 0, int fracdigit = 0);
CString & intToBinString(int num, int digits = 8);
int get_com_name(CString comx, CString &namebuf);
MTerm1/MTerm1.rc
Binary files differ
MTerm1/MTerm1.vcxproj
@@ -45,9 +45,9 @@
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
    <PlatformToolset>v142</PlatformToolset>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
@@ -259,6 +259,7 @@
    <ClCompile Include="DialogIoComment.cpp" />
    <ClCompile Include="DialogSetCoil.cpp" />
    <ClCompile Include="DialogSetData.cpp" />
    <ClCompile Include="IOPoint.cpp" />
    <ClCompile Include="KMachine.cpp" />
    <ClCompile Include="MTerm1CommDevView.cpp" />
    <ClCompile Include="MTerm1CommTestView.cpp" />
MTerm1/MTerm1.vcxproj.filters
@@ -335,6 +335,9 @@
    <ClCompile Include="MyFormInputShow.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="IOPoint.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="MTerm1.rc">
MTerm1/MTerm1CommDevView.cpp
@@ -549,23 +549,29 @@
    s1.Empty();
    pstWLRunStat  pWLRunStat = (pstWLRunStat)(&pDoc->KWLB);
    s1 += _T("发送数量: ") + intToString(pWLRunStat->sentCount) + _T("\r\n");
    s1 += _T("接收数量: ") + intToString(pWLRunStat->recvCount) + _T("\r\n");
    s1.Format(_T("状态   %04X %04X 步骤 %04X \r\n"), pWLRunStat->Stat, pWLRunStat->curStat, pWLRunStat->runStep);
    s1 += _T("发送时间: ") + intToString(pWLRunStat->lastSendtime) + _T(" uS\r\n");
    s1 += _T("接收时间: ") + intToString(pWLRunStat->lastRecvtime) + _T(" uS\r\n");
    s1 += _T("动作时间: ") + intToString(pWLRunStat->lastActTime) + _T(" uS\r\n");
    s1 += _T("相应时间: ") +  intToString(pWLRunStat->lastAckTime) + _T(" uS\r\n");
    s1 += _T("循环时间: ") + intToString(pWLRunStat->cycleTime,9) + _T(" uS\r\n");
    s1 += _T("延迟:     ") + intToString(pWLRunStat->latancy,9) + _T(" uS\r\n");
    s1.AppendFormat(_T("丢包数量: %d\r\n"), pWLRunStat->LostPackets);
    s1.AppendFormat(_T("连续丢包: %d\r\n"), pWLRunStat->CtnLstPkts);
    s1.AppendFormat(_T("最大连续: %d\r\n"), pWLRunStat->MaxCtnLstPkts);
    s1.AppendFormat(_T("发送错误: %d\r\n"), pWLRunStat->TXErr);
    s1.AppendFormat(_T("接收错误: %d\r\n"), pWLRunStat->RXErr);
    s1 += _T("发送数量: ") + intToString(pWLRunStat->sentCount) + _T("   对方收到: ") + intToString(pWLRunStat->targetRecvdCount) + _T("   差值: ") + intToString(pWLRunStat->sentCount - pWLRunStat->targetRecvdCount)  + _T("\r\n");
    s1 += _T("接收数量: ") + intToString(pWLRunStat->recvCount) + _T("   对方发出: ") + intToString(pWLRunStat->targetSentCount) + _T("   差值: ") + intToString(pWLRunStat->targetSentCount - pWLRunStat->recvCount) + _T("\r\n");
    s1 += _T("发送时间: ") + fixToString(pWLRunStat->lastSendtime,0,1) + _T(" mS\r\n");
    s1 += _T("发完时间: ") + fixToString(pWLRunStat->lastSenttime, 0, 1) + _T("   ") + fixToString(pWLRunStat->lastSenttime - pWLRunStat->lastSendtime, 0, 1) + _T(" mS\r\n");
    s1 += _T("接收时间: ") + fixToString(pWLRunStat->lastRecvtime,0,1) + _T(" mS\r\n");
    s1 += _T("收到时间: ") + fixToString(pWLRunStat->lastRecvdtime, 0, 1)  + _T("   ") + fixToString(pWLRunStat->lastRecvdtime - pWLRunStat->lastRecvtime, 0, 1) + +_T(" mS\r\n");
    s1 += _T("动作时间: ") + fixToString(pWLRunStat->lastActTime,0,1) + _T(" mS\r\n");
    s1 += _T("响应时间: ") +  fixToString(pWLRunStat->lastAckTime,0,1) + _T("   ") + fixToString(pWLRunStat->lastAckTime - pWLRunStat->lastActTime, 0, 1) + _T(" mS\r\n");
    s1 += _T("循环时间: ") + fixToString(pWLRunStat->cycleTime,0,1) + _T(" mS\r\n");
    s1 += _T("延迟:     ") + fixToString(pWLRunStat->latancy,0,1) + _T(" mS\r\n");
    s1.AppendFormat(_T("丢包数量: %d     连续丢包: %d    最大连续  %d\r\n"), pWLRunStat->LostPackets, pWLRunStat->CtnLstPkts, pWLRunStat->MaxCtnLstPkts);
    s1.AppendFormat(_T("发送错误: %d     接收错误: %d    时间 %s mS\r\n"), pWLRunStat->TXErr, pWLRunStat->RXErr, fixToString(pWLRunStat->lastErrTime,0,1));
    s1.AppendFormat(_T("CRC错误:  %d\r\n"), pWLRunStat->CRCErr);
    s1.AppendFormat(_T("本机信号强度: %d dBm  %d dBm\r\n"), pWLRunStat->RSSI, pWLRunStat->SNR);
    s1.AppendFormat(_T("对方信号强度: %d dBm  %d dBm\r\n"), pWLRunStat->tRSSI, pWLRunStat->tSNR);
    s1.AppendFormat(_T("CAD次数:  %d\r\n"), pWLRunStat->CADDoneCount);
    s1.AppendFormat(_T("小错误1: %d     中错误2: %d     大错误3: %d\r\n"), pWLRunStat->Err1Count, pWLRunStat->Err2Count, pWLRunStat->Err3Count);
    s1.AppendFormat(_T("步骤错误1: %d     步骤错误2: %d\r\n"), pWLRunStat->StepErr1, pWLRunStat->StepErr2);
    s1.AppendFormat(_T("本机信号强度: %d dBm  SNR %d dBm\r\n"), pWLRunStat->RSSI, pWLRunStat->SNR);
    s1.AppendFormat(_T("对方信号强度: %d dBm  SNR %d dBm\r\n"), pWLRunStat->tRSSI, pWLRunStat->tSNR);
    SetDlgItemText(IDC_EDIT_MON4, s1);
    //SetRedraw(TRUE);
MTerm1/MTerm1CommDevView.h
@@ -58,6 +58,7 @@
    {
        uint32_t Stat;                            //状态
        uint32_t curStat;                        //当前状态
        uint32_t runStep;                        //工作步骤
        uint32_t sentCount;                    //发送计数
        uint32_t recvCount;                    //接收计数
        uint32_t lastSendtime;            //上次发送时间
@@ -66,6 +67,7 @@
        uint32_t lastRecvdtime;            //上次接收时间
        uint32_t lastActTime;                //上次动作时间
        uint32_t lastAckTime;                //上次应答时间
        uint32_t lastErrTime;                //上次错误时间
        uint32_t latancy;                        //延迟
        uint32_t cycleTime;                    //循环时间
        uint32_t LostPackets;                //丢包计数
@@ -74,10 +76,19 @@
        uint32_t TXErr;                            //发送错误计数
        uint32_t RXErr;                            //接收错误计数
        uint32_t CRCErr;                         //CRC错误计数
        uint32_t CADDoneCount;                //CAD 完成次数
        uint32_t StepErr1;                    //步骤错误1
        uint32_t StepErr2;                    //步骤错误2
        uint32_t Err1Count;                    //微闪报警次数
        uint32_t Err2Count;                    //大闪报警次数
        uint32_t Err3Count;                    //严重丢失信号次数
        int8_t RSSI;                                //信号强度
        int8_t SNR;                                //信噪比
        int8_t tRSSI;                            //对方信号强度
        int8_t tSNR;                            //对方信噪比
        uint32_t targetSentCount;            //对方发送数量
        uint32_t targetRecvdCount;        //对方接受数量
    }stWLRunStat, *pstWLRunStat;
    afx_msg void OnClose();
MTerm1/MTerm1Doc.cpp
@@ -813,17 +813,26 @@
    m_nProgSteps = nProgPos;
    s1.Format(_T("DOC::Trans to Prog "));
    SysLog(s1);
    FindProgPair();
    TransProgToBin();
    return 0;
}
int CMTerm1Doc::FindProgPair()
{
    CString s1;
    // 先扫描分开的程序段
    int stpos[100] = { 0 };
    int nSts = 0;
    int StackDeeps[512] = { 0 };
    int nCurStackDeep = 0;
    // 查找匹配指令和地址
    s1.Format(_T("DOC::Trans to Prog "));
    SysLog(s1);
    //匹配指令(错误,此处匹配指令使用数字
    for (int i = 0; i < m_nProgSteps; i++)
    for (int i = 0; i < m_nProgSteps; i++)
    {
        int nOpType = Progs[i].nOpType1;
        int nParamCount = Progs[i].nParamCount;
@@ -879,10 +888,8 @@
            SysLog(s1);
        }
    }
    TransProgToBin();
    return 0;
}
int CMTerm1Doc::TransTxtToProg(CStringA ProgTxtA)
{
    CString s1;
MTerm1/MTerm1Doc.h
@@ -109,6 +109,29 @@
        int nParamCount;        //参数数量
        stParam Params[3];        //参数们
        int PairTo;                //对应指令
        stProg() {};
        stProg(CStringA sOpStr) {};
        stProg(int nOpType):nOpType1(nOpType) { nParamCount = 0; }
        stProg(int nOpType, CStringA sParamStr):nOpType1(nOpType)
        {
            nParamCount = 1;
            Params[0].sParamStr = sParamStr;
            Params[0].nParamType = 0;
            Params[0].nParamAddr = 0;
        };
        CStringA ToText()
        {
            CStringA s1, s2;
                OpToTxt(nOpType1, s1);
                if (nParamCount > 0) { s1.Append("\t" + Params[0].sParamStr); }
                if (nParamCount > 1) { s1.Append("\t" + Params[1].sParamStr); }
                if (nParamCount > 2) { s1.Append("\t" + Params[2].sParamStr); }
                if (nParamCount > 3) { s1.Append("\t" + Params[3].sParamStr); }
                s1.Append("\r\n");
                s2 += s1;
            return s2;
        }
    };
@@ -167,8 +190,8 @@
    // 操作
public:
    int TxtToOp(CStringA optxt, int* ParamCount, int* ParamType);
    int OpToTxt(int nOp, CStringA & OpTxt);
    static int TxtToOp(CStringA optxt, int* ParamCount, int* ParamType);
    static int OpToTxt(int nOp, CStringA & OpTxt);
    int OpToShowTxt(int nOp, CStringA & OpShowTxt);
    int TxtToCoilType(CStringA Typetxt, int* nCoilType, int* CoilAddr);
@@ -188,6 +211,7 @@
    int TransProgToBin();
    int TransBinToProg();
    int FindProgPair();
    int LoadFromFile(CString sFilePathName);
    int SaveToFile(CString sFilePathName);
@@ -195,6 +219,7 @@
    stProg Progs[2048] = { 0 };
    int ProgTrace[2048] = { 0 };
    int m_nProgSteps = 0;
    stBinProg1 BinProgs[2000];
    int nBinProgSteps = 0;
MTerm1/MTerm1View.cpp
@@ -765,8 +765,8 @@
    else if (nType == typeLine2)
    {    //Draw Line
        //画直竖线
        pDC->MoveTo(x0, y0 + (0.32 * CellTotalHeight));
        pDC->LineTo(x0, y0 - (0.69 * CellTotalHeight));
        pDC->MoveTo(x0, y0 + int(0.32 * CellTotalHeight));
        pDC->LineTo(x0, y0 - int(0.69 * CellTotalHeight));
    }
    else if (nType == typeNO)
    {
@@ -1214,7 +1214,7 @@
{
    CString s1;
    stCell & thecell = Cells[nRow][nCol];
    s1.Format(_T("Cell %d %d Type %02X \r\n"), nRow, nCol, thecell.nType);
    s1.Format(_T("Cell %d %d Type %02X OpType %02X \r\n"), nRow, nCol, thecell.nType,thecell.nOpType);
    s1.AppendFormat(_T(" sCoilName %s sParam %s \r\n"), thecell.sCoilName, thecell.sParam );
    s1.AppendFormat(_T("LeftUp %d leftDn %d "), thecell.bLeftLineUp, thecell.bLeftLineDn);
    DbgLog(s1);
@@ -1498,12 +1498,15 @@
    CString s1;
    s1.Format(_T("Prog Convert"));
     SysLog(s1);
    int r = TransLDSToProg();
    int r = TransLDSToProgAOV();  //TransLDSToProg();
    s1.Format(_T("LDS To Prog result %d"), r);
    SysLog(s1);
///*
    if (r==0) 
    {
    //    m_bModified = 0;
        GetDocument()->FindProgPair();
        GetDocument()->TransProgToBin();
        int j=TransProgToLDS();
        s1.Format(_T("Porg to LDS retuls %d"), j);
        SysLog(s1);
@@ -1514,6 +1517,7 @@
        s1.Format(_T("Error in Prog Convert"));
        SysLog(s1);
    }
//*/
}
void CMTerm1View::OnUpdateProgConvert(CCmdUI *pCmdUI)
@@ -1967,8 +1971,8 @@
    //    StPts[0] = POINT{ 0, 0 };
    POINT EndPt[100];
    POINT StrPt[100];
    int nStrPts = 0;
//    POINT StrPt[100];
//    int nStrPts = 0;
    int nEndPts = 0;
    nSts = 0;
    int nCurLine = 0;
@@ -2066,22 +2070,23 @@
                    }
                    else if (nPairOp == 0) 
                    {
                        if (i > 0 && nOp == pDoc->Progs[i-1].nOpType1)//如果前面也是ST,那就不换行
                        {
//                        if (i > 0 && nOp == pDoc->Progs[i-1].nOpType1)//如果前面也是ST,那就不换行
//                        {
                        }
                        else
                        {
//                        }
//                        else
//                        {
                            nCurLine = ++maxy;
                            cx = 0;
                            cy = nCurLine;
                        }
//                        }
                    }
                }
                stpos[nSts] = i;
                StPts[nSts] = POINT{ cx,cy };
                nSts++;
                Cells[cy][cx].nType = pDoc->Progs[i].nOpType1 == OP_ST ? typeNO : typeNC; //typeNC
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
                Cells[cy][cx].sParam = pDoc->Progs[i].Params[0].sParamStr;
@@ -2136,6 +2141,7 @@
                StPts[nSts] = POINT{ cx,cy };
                nSts++;
                Cells[cy][cx].nType = typeCMP;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sParam = OpName;
                Cells[cy][cx].sCoilName = ShowTxt;
@@ -2154,6 +2160,7 @@
            case OP_AN_:
                Cells[cy][cx].nType = nOp == OP_AN ? typeNO : typeNC; //typeNC
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sParam = pDoc->Progs[i].Params[0].sParamStr;
                Cells[cy][cx].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
@@ -2168,6 +2175,7 @@
            case OP_AN_LE:
            case OP_AN_GE:
                Cells[cy][cx].nType = typeCMP;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sCoilName = ShowTxt;
                Cells[cy][cx + 1].nType = typeExt1;
@@ -2216,27 +2224,28 @@
                StPts[nSts] = POINT{ cx,cy };//+++
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].nType = nOp == OP_OR ? typeNO : typeNC; //typeNC
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
                Cells[cy][cx].sParam = pDoc->Progs[i].Params[0].sParamStr;
                Cells[cy][cx].nDataType = pDoc->Progs[i].Params[0].nParamType;
                Cells[cy][cx].nDataAddr = pDoc->Progs[i].Params[0].nParamAddr;
                cx++;
                //if (cx <= EndPt[nEndPts - 1].x)
                //{    //本行补齐
                //    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;
                //    }
                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++)
                {
@@ -2277,6 +2286,7 @@
                }
                cy = nCurLine;
                Cells[cy][cx].nType = typeCMP;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sCoilName = ShowTxt;
                Cells[cy][cx + 1].nType = typeExt1;
@@ -2317,6 +2327,7 @@
                break;
            case OP_NOT:
                Cells[cy][cx].nType = typeNOT;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].sCoilName = _T("NOT");
                Cells[cy][cx].nProgStep = i;
@@ -2325,12 +2336,14 @@
            case OP_DF:
            case OP_DF_:
                Cells[cy][cx].nType = nOp == OP_DF ? typeDF : typeDF_;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].sCoilName = nOp == OP_DF ? _T("DF") : _T("DF/");
                Cells[cy][cx].nProgStep = i;
                cx++;
                break;
            case OP_ANS:
                /*
                //ANS说明是有环路,整行进行移动(向右)从后向前进行移动
                EndPt[nEndPts].y;
                for (int i = EndPt[nEndPts-1].x ; i > 0; i--)
@@ -2351,12 +2364,19 @@
                Cells[EndPt[nEndPts].y][EndPt[nEndPts-1].x].bLeftLineDn = 1;
                Cells[EndPt[nEndPts].y+1][EndPt[nEndPts-1].x].bLeftLineUp = 1;
                */
                nSts--;
                nEndPts--;
                break;
            case OP_ORS:
                // 当前序列与前面的序列合并。
                //当前序列的开始结束位置
                //EndPt[nEndPts] = POINT{ cx,cy };
                //nEndPts++;
                //StPts[nSts - 1]; EndPt[nEndPts - 1];
                //前一序列的开始结束位置
                StPts[nSts - 1]; EndPt[nEndPts - 1];
                if (nEndPts <= 0)
                {
@@ -2378,16 +2398,20 @@
                    //前一行补齐
                    for (int j = EndPt[nEndPts - 1].x; j < cx; j++)
                    {
                        if (Cells[EndPt[nEndPts - 1].y][j].nType == typeNone)
                        //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;
                for (int j = EndPt[nEndPts - 1].y; j < cy; j++)
                {
                    Cells[j][cx].bLeftLineDn = 1;
                    Cells[j + 1][cx].bLeftLineUp = 1;
                }
                //Cells[cy][cx].bLeftLineUp = 1;
                //Cells[cy-1][cx].bLeftLineDn = 1;
                //光标位置, 前一结束点位置
                nSts--;
@@ -2396,8 +2420,12 @@
                cx = EndPt[nEndPts].x;
                break;
            case OP_PSHS:
                EndPt[nEndPts] = POINT{ cx,cy };
                nEndPts++;
/*
                StrPt[nStrPts] = POINT{ EndPt[nEndPts].x,EndPt[nEndPts].y+1 };
                nStrPts++;
*/
                break;
            case OP_RDS:
                cx = EndPt[nEndPts - 1].x;
@@ -2414,9 +2442,24 @@
                }
                break;
            case OP_POPS:
                cx = EndPt[nEndPts - 1].x;
                for (int j = cx; j < m_CellPerLine; j++) {
                    if (Cells[cy][j].nType != 0)
                    {
                        cy++; j = cx - 1; break;
                    }
                }
                for (int j = EndPt[nEndPts - 1].y; j < cy; j++)
                {
                    Cells[j][cx].bLeftLineDn = 1;
                    Cells[j + 1][cx].bLeftLineUp = 1;
                }
                nEndPts--;
/*
                nStrPts--;
                cy = StrPt[nStrPts].y;
                cx = StrPt[nStrPts].x;
*/
                break;
            case OP_OUT:
            case OP_SET:
@@ -2445,6 +2488,7 @@
                        Cells[cy][j].nType = typeLine1;
                    }
                    Cells[cy][m_CellPerLine - 1].nType = nCellType;
                    Cells[cy][cx].nOpType = nOp;
                    Cells[cy][m_CellPerLine - 1].nProgStep = i;
                    Cells[cy][m_CellPerLine - 1].sParam = pDoc->Progs[i].Params[0].sParamStr;
                    Cells[cy][m_CellPerLine - 1].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
@@ -2454,6 +2498,7 @@
                }
                else {
                    Cells[cy][cx].nType = nCellType;
                    Cells[cy][cx].nOpType = nOp;
                    Cells[cy][cx].nProgStep = i;
                    Cells[cy][cx].sParam = pDoc->Progs[i].Params[0].sParamStr;
                    Cells[cy][cx].sCoilName = pDoc->Progs[i].Params[0].sParamStr;
@@ -2469,6 +2514,7 @@
            case OP_TMX:
            case OP_TMY:
                Cells[cy][cx].nType = typeTM;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sCoilName = ShowTxt;
                Cells[cy][cx + 1].nType = typeExt1;
@@ -2484,6 +2530,7 @@
            case OP_INC:
            case OP_DEC:
                Cells[cy][cx].nType = typeFN1;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sCoilName = ShowTxt;
                Cells[cy][cx + 1].nType = typeExt1;
@@ -2497,6 +2544,7 @@
            case OP_ADD2:
            case OP_SUB2:
                Cells[cy][cx].nType = typeFN2;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sCoilName = ShowTxt;
                Cells[cy][cx + 1].nType = typeExt1;
@@ -2515,6 +2563,7 @@
            case OP_MUL:
            case OP_DIV:
                Cells[cy][cx].nType = typeFN3;
                Cells[cy][cx].nOpType = nOp;
                Cells[cy][cx].nProgStep = i;
                Cells[cy][cx].sCoilName = ShowTxt;
                Cells[cy][cx + 1].nType = typeExt1;
@@ -2535,6 +2584,7 @@
            default:
                break;
            }
            if (cy > maxy) { maxy = cy; }
        }
    }
    catch (const std::exception&)
@@ -2555,6 +2605,999 @@
        }
    */
    needReDraw = 1;
    return 0;
}
int CMTerm1View::AddNode(int nType, int CellX, int CellY, CString sCoilName, int PrevNode)
{
    node& theNode = nodes[nNodeCount];
    theNode.nId = nNodeCount;
    theNode.bEnable = 1;
    theNode.nType = nType;
    theNode.indegree = 0;
    theNode.outdegree = 0;
    theNode.firstOut = 0;
    theNode.firstIn = 0;
    theNode.input = 0;
    theNode.result = 0;
    theNode.nCellX = CellX;
    theNode.nCellY = CellY;
    theNode.CoilName = sCoilName;
    theNode.InProcCount = 0;
    theNode.OutProcCount = 0;
    theNode.OutProcAllDone = 0;
    theNode.prog1.Progs.clear();
    int nOp = Cells[CellY][CellX].nOpType;
    int nCoilType, nCoilAddr;
    if (nType == typeNO)
     {
        CMTerm1Doc::stProg prog0;
        if (nOp >= 1 && nOp <= 255) {
            prog0.nOpType1 = nOp; // OP_AN;
        }
        else if (CellX==0) {
            prog0.nOpType1 = OP_ST; // OP_AN;
        }
        else {
            prog0.nOpType1 = OP_AN; // OP_AN;
        }
        prog0.nParamCount = 1;
        prog0.Params[0].sParamStr = sCoilName;
        CStringA s2A;
        s2A = sCoilName;
        GetDocument()->TxtToCoilType(s2A,&nCoilType,&nCoilAddr);
        prog0.Params[0].nParamType = nCoilType;
        prog0.Params[0].nParamAddr = nCoilAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeNC) {
        CMTerm1Doc::stProg prog0;
        if (nOp >= 1 && nOp <= 255) {
            prog0.nOpType1 = nOp; // OP_AN;
        }
        else if (CellX == 0) {
            prog0.nOpType1 = OP_ST_; // OP_AN;
        }
        else {
            prog0.nOpType1 = OP_AN_; // OP_AN;
        }
        prog0.nParamCount = 1;
        prog0.Params[0].sParamStr = Cells[CellY][CellX].sCoilName;
        CStringA s2A;
        s2A = sCoilName;
        GetDocument()->TxtToCoilType(s2A, &nCoilType, &nCoilAddr);
        prog0.Params[0].nParamType = nCoilType;
        prog0.Params[0].nParamAddr = nCoilAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typePP) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = Cells[CellY][CellX].nOpType;
        prog0.nParamCount = 1;
        prog0.Params[0].sParamStr = sCoilName;
        prog0.Params[0].nParamType = Cells[CellY][CellX].nDataType;
        prog0.Params[0].nParamAddr = Cells[CellY][CellX].nDataAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typePN) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = Cells[CellY][CellX].nOpType;
        prog0.nParamCount = 1;
        prog0.Params[0].sParamStr = sCoilName;
        prog0.Params[0].nParamType = Cells[CellY][CellX].nDataType;
        prog0.Params[0].nParamAddr = Cells[CellY][CellX].nDataAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeNOT) {
        theNode.prog1.Append(CMTerm1Doc::stProg(OP_NOT));
    }
    else if (nType == typeDF) {
        theNode.prog1.Append(CMTerm1Doc::stProg(OP_DF));
    }
    else if (nType == typeDF_) {
        theNode.prog1.Append(CMTerm1Doc::stProg(OP_DF_));
    }
    else if (nType == typeOUT) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = OP_OUT;
        prog0.nParamCount = 1;
        prog0.Params[0].sParamStr = sCoilName;
        CStringA s2A;
        s2A = sCoilName;
        GetDocument()->TxtToCoilType(s2A, &nCoilType, &nCoilAddr);
        prog0.Params[0].nParamType = nCoilType;
        prog0.Params[0].nParamAddr = nCoilAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeSET) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = OP_SET;
        prog0.nParamCount = 1;
        prog0.Params[0].sParamStr = sCoilName;
        CStringA s2A;
        s2A = sCoilName;
        GetDocument()->TxtToCoilType(s2A, &nCoilType, &nCoilAddr);
        prog0.Params[0].nParamType = nCoilType;
        prog0.Params[0].nParamAddr = nCoilAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeRESET) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = OP_RESET;
        prog0.nParamCount = 1;
        prog0.Params[0].sParamStr = sCoilName;
        CStringA s2A;
        s2A = sCoilName;
        GetDocument()->TxtToCoilType(s2A, &nCoilType, &nCoilAddr);
        prog0.Params[0].nParamType = nCoilType;
        prog0.Params[0].nParamAddr = nCoilAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeCMP) {
        CMTerm1Doc::stProg prog0;
        Cells[CellY][CellX];
        prog0.nOpType1 = Cells[CellY][CellX].nOpType;
        prog0.nParamCount = 2;
        prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
        prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
        prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
        prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
        prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
        prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeTM) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = Cells[CellY][CellX].nOpType;
        prog0.nParamCount = 2;
        prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
        prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
        prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
        prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
        prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
        prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeFN1) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = Cells[CellY][CellX].nOpType;;
        prog0.nParamCount = 1;
        prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
        prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
        prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeFN2) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = Cells[CellY][CellX].nOpType;;
        prog0.nParamCount = 2;
        prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
        prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
        prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
        prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
        prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
        prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeFN3) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = Cells[CellY][CellX].nOpType;;
        prog0.nParamCount = 3;
        prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
        prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
        prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
        prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
        prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
        prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
        prog0.Params[2].sParamStr = Cells[CellY][CellX + 3].sParam;
        prog0.Params[2].nParamType = Cells[CellY][CellX + 3].nDataType;
        prog0.Params[2].nParamAddr = Cells[CellY][CellX + 3].nDataAddr;
        theNode.prog1.Append(prog0);
    }
    else if (nType == typeFN4) {
        CMTerm1Doc::stProg prog0;
        prog0.nOpType1 = Cells[CellY][CellX].nOpType;;
        prog0.nParamCount = 4;
        prog0.Params[0].sParamStr = Cells[CellY][CellX + 1].sParam;
        prog0.Params[0].nParamType = Cells[CellY][CellX + 1].nDataType;
        prog0.Params[0].nParamAddr = Cells[CellY][CellX + 1].nDataAddr;
        prog0.Params[1].sParamStr = Cells[CellY][CellX + 2].sParam;
        prog0.Params[1].nParamType = Cells[CellY][CellX + 2].nDataType;
        prog0.Params[1].nParamAddr = Cells[CellY][CellX + 2].nDataAddr;
        prog0.Params[2].sParamStr = Cells[CellY][CellX + 3].sParam;
        prog0.Params[2].nParamType = Cells[CellY][CellX + 3].nDataType;
        prog0.Params[2].nParamAddr = Cells[CellY][CellX + 3].nDataAddr;
        prog0.Params[3].sParamStr = Cells[CellY][CellX + 4].sParam;
        prog0.Params[3].nParamType = Cells[CellY][CellX + 4].nDataType;
        prog0.Params[3].nParamAddr = Cells[CellY][CellX + 4].nDataAddr;
        theNode.prog1.Append(prog0);
    }
    if (PrevNode > 0) {
        AddArc(PrevNode, nNodeCount);
    }
    nNodeCount++;
    return nNodeCount-1;
}
int SearchLastInArc(int nNodeID)
{
    int ArcId = 0;
    return ArcId;
}
int SearchLastOutArc(int nNodeID)
{
        int ArcId = 0;
        return ArcId;
}
int CMTerm1View::AddArc(int nNodeID1, int nNodeID2)
{
    node& theNode1 = nodes[nNodeID1];
    node& theNode2 = nodes[nNodeID2];
    arc& theArc = arcs[nArcCount];
    theArc.nId = nArcCount;
    theArc.bEnable = 1;
    theNode2.firstIn;
    theArc.headNode = nNodeID2;
    theArc.tailNode = nNodeID1;
    theArc.hlinkId = 0;
    theArc.tlinkId = 0;
    theArc.tailvex = &theNode1;
    theArc.headvex = &theNode2;
    theArc.tlink = 0;
    theArc.hlink = 0;
    theNode1.outdegree++;
    theNode2.indegree++;
    //如果顶点已经有 连接 ,将新的弧加到已有弧的后面。
    if (theNode1.firstOut == 0) {
        theNode1.firstOut = &theArc;
    }else {
        arc * p1 = theNode1.firstOut;
        for (; p1->tlink != 0;) {
             p1 = p1->tlink;
        }
        p1->tlink = &theArc;
        p1->tlinkId = nArcCount;
    }
    if (theNode2.firstIn == 0) {
        theNode2.firstIn = &theArc;
    }else{
        arc* p1 = theNode2.firstIn;
        for (; p1->hlink != 0;) {
            p1 = p1->hlink;
        }
        p1->hlink = &theArc;
        p1->hlinkId = nArcCount;
    }
    nArcCount++;
    return nArcCount;
}
int CMTerm1View::MergeParallelNodeWithinVP(int nVPNodeId1, int nVPNodeId2)        //合并两个串联的虚节点之间所有的并行 Node,并行数量可能大于2个。
{
    node& theNode1 = nodes[nVPNodeId1];            //虚节点1
    node& theNode2 = nodes[nVPNodeId2];            //虚节点2
    // 必须前者 与 后者 之间有两条以上 且连续,其中一方为另一方的子集 才能合并。
    // 先找到两者连接的弧
    if (!theNode1.bEnable || !theNode2.bEnable) return -1;
    if (theNode1.outdegree < 2 || theNode2.indegree < 2 ) return -2;
//    if (theNode1.firstOut != theNode2.firstIn) return -3;
//
//  先找到第一个连接
//
    CString s1;
    //先判断两者大小
    int n1 = theNode1.outdegree;
    int n2 = theNode2.indegree;
    if (n1 <= n2) {            //前者是后的的子集
        int n = 0;
        arc* ptheArc1 = theNode1.firstOut;
        while (ptheArc1)
        {    // 取得连接的实节点地址;
            node* pThisNode1 = ptheArc1->headvex;
            // 取得实节点连接的弧;
            arc* ptheArc2 = pThisNode1->firstOut;
            // 取出弧连接的下一个节点, 目标虚节点
            node* pThatNode1 = ptheArc2->headvex;
            // 判断这个点是不是指定的虚节点
            if (pThatNode1 != &theNode2) { return -3; } // 没连接到第二个虚节点
            n++;
            // 继续下一个连接的弧;
            ptheArc1 = ptheArc1->tlink;
        }
        if (theNode1.outdegree != n ) return -2;
        //node& theNode;
        // 第二次,重来一遍,开始合并程序
        stProgSection prog2;
        ptheArc1 = theNode1.firstOut;
        node* pThisNode1 = ptheArc1->headvex;    // 第一个实节点
        stProgSection prog1 = pThisNode1->prog1;
        if (prog1.Progs[0].nOpType1 == OP_AN) { prog1.Progs[0].nOpType1 = OP_ST; }
        prog2 = prog1;                // 取得第一个实节点的程序
        ptheArc1 = ptheArc1->tlink;                //下一个弧
        while (ptheArc1)
        {
            //取得相连的实节点地址
            node* pThisNode2 = ptheArc1->headvex;
            stProgSection prog1 = pThisNode2->prog1;
            if (prog1.Progs[0].nOpType1 == OP_AN) { prog1.Progs[0].nOpType1 = OP_ST; }
            if (prog1.Progs.size() > 1) {
                prog1.Append(CMTerm1Doc::stProg(OP_ORS));
            }
            else {
                if (pThisNode2->nType == typeNC) prog1.Progs[0].nOpType1 = OP_OR_;
                else if (pThisNode2->nType == typeNO) prog1.Progs[0].nOpType1 = OP_OR;
                else prog1.Progs[0].nOpType1 = OP_OR;
            }
            prog2 += prog1;
            // 取得实节点连接的弧;
            arc* ptheArc2 = pThisNode2->firstOut;
            RemoveArc(ptheArc2->nId);                //删除弧
            arc* pTheNextArc = ptheArc1->tlink;        //取得下一个弧并保存
            RemoveArc(ptheArc1->nId);                //删除当前弧
            pThisNode2->bEnable = 0;                //删除实节点
            ptheArc1 = pTheNextArc;
        }
        if (theNode1.nType == -1 && theNode2.nType == -1) { prog2.Append(CMTerm1Doc::stProg(OP_ANS)); }
        pThisNode1->prog1 = prog2;                //将所有程序汇总到第一个实节点
    //    s1 = prog2.ToText(GetDocument());
    //    DbgLog(_T("------ ") + s1);
    }
    else {            // n1> n2  // 后者是前者的子集
        int n = 0;
        arc* ptheArc1 = theNode2.firstIn;
        while (ptheArc1)
        {
            //取得相连的虚节点地址
            // 取得连接的实节点地址;
            node* pThisNode1 = ptheArc1->tailvex;
            // 取得实节点连接的弧;
            arc* ptheArc2 = pThisNode1->firstIn;
            // 取出弧连接的下一个节点
            node* pThatNode1 = ptheArc2->tailvex;
            // 判断这个点是不是指定的虚节点
            if (pThatNode1 != &theNode1) { return -3; } // 没连接到第二个虚节点
            n++;
            // 继续下一个连接的弧;
            ptheArc1 = ptheArc1->hlink;
        }
        if (theNode2.indegree != n) return -1;
        //node& theNode;
        // 第二次,重来一遍,开始合并程序
        stProgSection prog2;
        ptheArc1 = theNode2.firstIn;
        node* pThisNode1 = ptheArc1->tailvex;    // 第一个实节点
        stProgSection prog1 = pThisNode1->prog1;
        if (prog1.Progs[0].nOpType1 == OP_AN) { prog1.Progs[0].nOpType1 = OP_ST; }
        prog2 = prog1;                // 取得第一个实节点的程序
        ptheArc1 = ptheArc1->hlink;
        while (ptheArc1)
        {
            //取得相连的虚节点地址
            node* pThisNode2 = ptheArc1->tailvex;
            stProgSection prog1 = pThisNode2->prog1;
            if (prog1.Progs[0].nOpType1 == OP_AN) { prog1.Progs[0].nOpType1 = OP_ST; }
            if (prog1.Progs.size() > 1) {
                prog1.Append(CMTerm1Doc::stProg(OP_ORS));
            }
            else {
                if (pThisNode2->nType == typeNC) prog1.Progs[0].nOpType1 = OP_OR_;
                else if (pThisNode2->nType == typeNO) prog1.Progs[0].nOpType1 = OP_OR;
                else prog1.Progs[0].nOpType1 = OP_OR;
            }
            prog2 += prog1;
            arc* ptheArc2 = pThisNode2->firstIn;
            RemoveArc(ptheArc2->nId);                //删除弧
            arc* pTheNextArc = ptheArc1->hlink;        //取得下一个弧并保存
            RemoveArc(ptheArc1->nId);                //删除当前弧
            pThisNode2->bEnable = 0;                //删除实节点
            ptheArc1 = pTheNextArc;
        }
        if (theNode1.nType == -1 && theNode2.nType == -1) { prog2.Append(CMTerm1Doc::stProg(OP_ANS)); }
        pThisNode1->prog1 = prog2;                //将所有程序汇总到第一个实节点
    //    s1 = prog2.ToText(GetDocument());
    //    DbgLog(_T("------ ") + s1);
    }
    return 0;
}
int CMTerm1View::RemoveArc(int nArcId)
{
    arc& theArc = arcs[nArcId];
    node& theNode1 = *theArc.tailvex;
    node& theNode2 = *theArc.headvex;
    // 先看 Node1 这边,
    // 首弧
    if (theNode1.firstOut == &theArc) {
        theNode1.firstOut = theArc.tlink;
    }
    else {
        arc* thatArc = theNode1.firstOut;
        while (thatArc->tlink !=0){
            if (thatArc->tlink == &theArc) {
                thatArc->tlink = theArc.tlink;
                break;
            }
            thatArc = thatArc->tlink;
        }
    }
    // 再看 Node2 这边,
    // 首弧
    if (theNode2.firstIn == &theArc) {
        theNode2.firstIn = theArc.hlink;
    }
    else {
        arc* thatArc = theNode2.firstIn;
        while (thatArc->hlink != 0) {
            if (thatArc->hlink == &theArc) {
                thatArc->hlink = theArc.hlink;
                break;
            }
            thatArc = thatArc->hlink;
        }
    }
    theNode1.outdegree--;
    theNode2.indegree--;
    return nArcCount;
}
int CMTerm1View::RemoveNode(int nNodeId)
{
    node& theNode = nodes[nNodeId];
    theNode.bEnable = 0;
    if (theNode.indegree) {
    }
    return nNodeCount;
}
int CMTerm1View::MergeNode(int nNodeId1, int nNodeId2)        //合并两个串联的 实 Node
{
    node& theNode1 = nodes[nNodeId1];
    node& theNode2 = nodes[nNodeId2];
    // 必须前者出度 为1 后者 入度 为1, 且 相连, 才能合并。
    // 先找到两者连接的弧
    if (!theNode1.bEnable || !theNode2.bEnable) return -1;
    if (theNode1.outdegree != 1 || theNode2.indegree != 1) return -2;
    if (theNode1.firstOut != theNode2.firstIn) return -3;
    // 删除两者之间的弧。
    RemoveArc(theNode1.firstOut->nId);
    theNode1.firstOut = 0;
    theNode2.firstIn = 0;
    // 将 Node2 的 出 弧, 转移 到 node1 上
    theNode1.CoilName += _T("  ") + theNode2.CoilName;
    theNode1.firstOut = theNode2.firstOut;
    theNode1.outdegree = theNode2.outdegree;
    theNode1.prog1 += theNode2.prog1;            // 段程序合并
    arc* thatArc = theNode2.firstOut;
    while (thatArc != 0)
    {
        thatArc->tailvex = &theNode1;
        thatArc->tailNode = nNodeId1;
        thatArc = thatArc->tlink;
        theNode2.outdegree--;
    }
    //
    // 现在 Node2 的入度和出度 均为 0, 删除 node2
    RemoveNode(nNodeId2);
    return 0;
}
//  合并从 nNodeId 虚节点发出的 各个单行 Nodes; 直到下一个多输出的虚节点
int CMTerm1View::MergeVPSubSerialNodes(int nNodeId)
{
    node& theNode = nodes[nNodeId];
    arc* theArc = theNode.firstOut;
    while (theArc != 0) {
        // 从当前弧 取出一个顶点
        node * thisNode = theArc->headvex;
        // 从这个顶点,找到下一个顶点
        if (thisNode->outdegree == 1 && thisNode->firstOut != 0) {
            node* thatNode = thisNode->firstOut->headvex;
            while (thatNode->indegree == 1 && thatNode->outdegree <= 1 && thatNode->nType != -2) {
                if (thatNode->nType == typeOUT || thatNode->nType == typeSET || thatNode->nType == typeRESET) {
                    //break;
                }
                MergeNode(thisNode->nId, thatNode->nId);
                if (thatNode->firstOut) thatNode = thatNode->firstOut->headvex;
                else break;
            }
            if (thatNode->nType == -1) { //找到下一个虚顶点
                if (!thatNode->OutProcAllDone) {
                    MergeVPSubSerialNodes(thatNode->nId);    //从虚顶点继续
                }
            }
        }
        // 同一个出发点的 下一条弧
        theArc = theArc->tlink;
    };
    theNode.OutProcAllDone = 1;
    return 0;
}
//  合并从 nNodeId 虚节点发出的 各个单行 Nodes; 直到下一个 多输出的虚节点
int CMTerm1View::MergeVPSerialNodes(int nNodeId)
{
    node& theNode = nodes[nNodeId];
    arc* theArc = theNode.firstOut;
    while (theArc != 0) {
        // 从当前弧 取出一个顶点
        node* thisNode = theArc->headvex;
        // 从这个顶点,找到下一个顶点
        if (thisNode->outdegree == 1 && thisNode->firstOut != 0) {
            node* thatNode = thisNode->firstOut->headvex;
            while (thatNode->nType != -2 && thatNode->indegree ==1 && thatNode->outdegree <= 1) {
                if (thatNode->nType == typeOUT || thatNode->nType == typeSET || thatNode->nType == typeRESET) {
                    //break;
                }
                MergeNode(thisNode->nId, thatNode->nId);
                if (thatNode->firstOut) thatNode = thatNode->firstOut->headvex;
                else break;
            }
            if (thatNode->nType == -1) { //找到下一个虚顶点
                if (!thatNode->OutProcAllDone) {
                    MergeVPSerialNodes(thatNode->nId);    //从虚顶点继续
                }
            }
        }
        // 同一个出发点的 下一条弧
        theArc = theArc->tlink;
    };
    theNode.OutProcAllDone = 1;
    return 0;
}
//从 X,Y 点,向上查找 虚节点,最多终止于 endy;
int CMTerm1View::FindVPNode(int x, int y, int endy)
{
    int nNodeId = 0;
    for (int i = nNodeCount -1 ; i>=1; i--) {
        if (nodes[i].bEnable && nodes[i].nType == -1 && nodes[i].nCellX == x && nodes[i].nCellY <= y &&nodes[i].nCellY >=endy  )
        {
            nNodeId = i; break;
        }
    }
    return nNodeId;
}
int CMTerm1View::ScanVPAOV(int nVPNodeId1, int nVPNodeId2)
{
    MergeParallelNodeWithinVP(nVPNodeId1, nVPNodeId2);
    return 0;
}
int CMTerm1View::ScanAOV1(int nNodeId)
{
    node& theNode = nodes[nNodeId];
    CString s1;
    int nInput = theNode.indegree;
    int nOutput = theNode.outdegree;
    //    s1.Format(_T("%d type %d op %s coil %s  in %d   out %d"), theNode.nId, theNode.nType, theNode.Op, theNode.CoilName, theNode.indegree, theNode.outdegree);
    //    DbgLog(s1);
    if (theNode.InProcCount < theNode.indegree) return 0;
    // 虚拟结点,完成所有输入。
    stProgSection prog2;
    if (theNode.outdegree > 0) {
        //  一直搜索下去,遇到 输入不为0的 虚节点 时 停止,进行下一个迭代
        arc* theArc = theNode.firstOut;
        int allOutputMerged = 1;
        int allOutputSimple = 1;
        for (int i = 0; i < nOutput && theArc != 0; i++) {
            node* thisNode = theArc->headvex;
            thisNode->InProcCount++;
            s1.Format(_T("- %d type %d op %s coil %s  in %d   out %d"), thisNode->nId, thisNode->nType, thisNode->Op, thisNode->CoilName, thisNode->indegree, thisNode->outdegree);
            DbgLog(s1);
            s1 = thisNode->prog1.ToText();
            DbgLog(_T("------ ") + s1);
            arc* thisArc = thisNode->firstOut;
            if (thisNode->outdegree > 0) { allOutputMerged = 0; }
            if (thisNode->nType != typeOUT && thisNode->nType != typeSET && thisNode->nType != typeRESET) { allOutputSimple = 0; }
            while (thisArc) {
                thisNode = thisArc->headvex;
                thisNode->InProcCount++;
                s1.Format(_T("-- %d type %d op %s coil %s  in %d   out %d"), thisNode->nId, thisNode->nType, thisNode->Op, thisNode->CoilName, thisNode->indegree, thisNode->outdegree);
                DbgLog(s1);
                if (thisNode->nType > 0) //thatNode.indegree == 1 && thatNode.outdegree == 1)
                {
                 thisArc = thisNode->firstOut;
                    //    node* thatNode = thisArc->headvex;
                }
                else {
                    ScanVPAOV(nNodeId, thisNode->nId);
                    if (thisNode->InProcCount >= thisNode->indegree) {
                        s1.Format(_T("-> %d type %d op %s coil %s  in %d   out %d"), thisNode->nId, thisNode->nType, thisNode->Op, thisNode->CoilName, thisNode->indegree, thisNode->outdegree);
                        DbgLog(s1);
                        ScanAOV1(thisNode->nId);
                    }
                    break;
                }
            }
            //            if (thatNode.nType > 0) {
            //                prog2.Append(thatNode.prog1);
            //            }
                        //RemoveArc(theArc->nId);
                        // 同一个出发点的 下一条弧
            theArc = theArc->tlink;
        }
        if (theNode.outdegree >= 2 && allOutputMerged) {
            s1.Format(_T(" Merge Output %d  %d  allsimple = %d "), nNodeId,theNode.outdegree,allOutputSimple);
            DbgLog(s1);
            if (allOutputSimple) {
                arc * thisArc = theNode.firstOut;
                node* thisNode = thisArc->headvex;
                thisArc = thisArc->tlink;
                for (int i = 1; i < nOutput && thisArc != 0; i++) {
                    node* thatNode = thisArc->headvex;
                    thisNode->prog1 += thatNode->prog1;
                    arc * tempArc = thisArc->tlink;
                    RemoveArc(thisArc->nId);
                    thisArc = tempArc;
                    RemoveNode(thatNode->nId);
                }
            }
            else {
                arc* thisArc = theNode.firstOut;
                node* thisNode = thisArc->headvex;
                stProgSection prog2;
                prog2.Append(CMTerm1Doc::stProg(OP_PSHS));
                prog2 += thisNode->prog1;
                thisArc = thisArc->tlink;
                for (int i = 1; i < nOutput  && thisArc != 0; i++) {
                    node* thatNode = thisArc->headvex;
                    if (i == nOutput - 1) { // 最后一个
                        prog2.Append(CMTerm1Doc::stProg(OP_POPS));
                    }
                    else {
                        prog2.Append(CMTerm1Doc::stProg(OP_RDS));
                    }
                    prog2 += thatNode->prog1;
                    arc* tempArc = thisArc->tlink;
                    RemoveArc(thisArc->nId);
                    thisArc = tempArc;
                    RemoveNode(thatNode->nId);
                }
                thisNode->prog1 = prog2;
            }
        }
    }
    return 0;
    /*
        node& theNode = nodes[nNodeId];
        arc* theArc = theNode.firstOut;
        while (theArc != 0) {
            // 从当前弧 取出一个顶点
            node* thisNode = theArc->headvex;
            // 从这个顶点,找到下一个顶点
            if (thisNode->outdegree == 1 && thisNode->firstOut != 0) {
                node* thatNode = thisNode->firstOut->headvex;
                while (thatNode->nType != -1) {
                    if (thatNode->nType == typeOUT || thatNode->nType == typeSET || thatNode->nType == typeRESET) {
                        break;
                    }
                    MergeNode(thisNode->nId, thatNode->nId);
                    if (thatNode->firstOut) thatNode = thatNode->firstOut->headvex;
                    else break;
                }
                if (thatNode->nType == -1) { //找到下一个虚顶点
                    if (!thatNode->OutProcAllDone) {
                        MergeSerialNodes(thatNode->nId);    //从虚顶点继续
                    }
                }
            }
            // 同一个出发点的 下一条弧
            theArc = theArc->tlink;
        };
        theNode.OutProcAllDone = 1;
    */
}
/// <summary>
/// 试用 AOV 方式 梯形图转Prog
/// </summary>
/// <returns></returns>
int CMTerm1View::TransLDSToProgAOV()
{
    CMTerm1Doc* pDoc = GetDocument();
    CString s1;
    s1.Format(_T("Trans LDS to PRrog"));
    DbgLog(s1);
    s1.Format(_T("AOV 方式 将梯形图转成prog格式"));
    DbgLog(s1);
    //梯形图 ROW数量
    s1.Format(_T("总计行数 %d"), m_nTotalRow);
    DbgLog(s1);
    s1.Format(_T("Total Lines %d"), m_nTotalRow);
    DbgLog(s1);
    //分段
    int nDivCount = 0;
    //分段 点集合
    int Divs[100] = { 0 };
    for (int i = 0; i < m_nTotalRow+5 ; i++)
    {
        int nRow = i;
        int bConnected = 0;
        //扫描程序,建立十字链表?
        for (int j = 0; j < m_CellPerLine; j++)
        {
            int nCol = j;
            if (Cells[nRow][nCol].bLeftLineDn)
            {
                bConnected = 1;
                //s1.Format(_T("row==%d col==%d 有左下竖线!!!"), nRow, nCol);
                //DbgLog(s1);
                break;
            }
        }
        if (!bConnected)
        {
            //找到一处分界点
            Divs[nDivCount] = i;
            s1.Format(_T("Div at Line %d 是 ::::::::::::分界点"), nRow);
            DbgLog(s1);
            nDivCount++;
        }
    }
    stProgSection allprogs;
    //每段单独处理
    for (int i = 0; i < nDivCount; i++)
    {
        int nStartLine, nEndLine;
        nNodeCount = 0;
        if (i == 0)
        {
            nStartLine = 0;
            nEndLine = Divs[i];
        }
        else
        {
            nStartLine = Divs[i - 1] + 1;
            nEndLine = Divs[i];
        }
        s1.Format(_T("本段行号 起始-终止: %d - %d "), nStartLine, nEndLine);
        DbgLog(s1);
        //s1.Format(_T("Process Line %d - %d "), nStartLine, nEndLine);
        //DbgLog(s1);
        int nCounts[20] = { 0 };
        int nCounts2[20] = { 0 };
        int nCounts3[20] = { 0 };
        s1.Empty();
        stProgSection section1;
        CString s2;
        int PrevNode = 0;
        nNodeCount = 1;        //清理存储的顶点和弧数据。
        nArcCount = 1;
        AddNode(-2, 0, 0, _T("Mother"));        //增加母线顶点
        for (int j = nStartLine; j <= nEndLine; j++) {
            int nPosX = 0;
            PrevNode = 1;        //从母线开始
            s1.Empty();
            for (int k = 0; k < m_CellPerLine; k++) {
                stCell theCell = Cells[j][k];
                int nNextX = 1;
                int nType;
                int bRightLineUp = 0;
                if (k < m_CellPerLine - 1) { bRightLineUp = Cells[j][k + 1].bLeftLineUp; }
                nType = theCell.nType;
                if (nType == typeNone) { PrevNode = 0;  } // 不连接母线;
                if (nType ) {
                    if (nType == typeLine1 && !theCell.bLeftLineUp && !theCell.bLeftLineDn && !bRightLineUp) continue;
                    if (nType == typeExt1 || nType == typeExt2 || nType == typeExt3 || nType == typeExt4) continue;
                    if (k!=0 && theCell.bLeftLineDn && !theCell.bLeftLineUp) {
                        PrevNode = AddNode(-1, k, j, _T("VP"),PrevNode);
                    }
                    if (k != 0 && theCell.bLeftLineUp) {
                        int VPNodeId = 0;
                            VPNodeId = FindVPNode(k , j,  nStartLine);
                        PrevNode = VPNodeId;
                    }
                    switch (nType) {
                    case typeLine1:
                        break;
                    case typeNO:
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeNC:
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName +_T("/"), PrevNode);
                        break;
                    case typePP:
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typePN:
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeNOT:
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeDF:
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeDF_:
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeOUT:
                    case typeSET:
                    case typeRESET:
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeCMP:
                        nNextX = 3;
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeExt1:
                    case typeExt2:
                    case typeExt3:
                        break;
                    case typeTM:
                        nNextX = 3;
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeFN1:
                        nNextX = 2;
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeFN2:
                        nNextX = 3;
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeFN3:
                        nNextX = 4;
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeFN4:
                        nNextX = 5;
                        PrevNode = AddNode(nType, k, j, theCell.sCoilName, PrevNode);
                        break;
                    case typeCoil:
                        break;
                    default:
                        break;
                    }
                    s2 = Cells[j][k].sCoilName;
                    //k += nStep - 1;
                    s1 += s2 + _T(" ") + intToString(nNextX) + _T("  ");
                    if (bRightLineUp) {
                        int VPNodeId = 0;
                            VPNodeId = FindVPNode(k + 1, j, nStartLine);
                        AddArc(PrevNode, VPNodeId);
                        PrevNode = VPNodeId;
                    }
                }
            }
            DbgLog(s1);
        }
        //输出已经生成的 AOV 图 顶点信息
        for (int j = 1; j < nNodeCount; j++) {
            s1.Format(_T("%d    %d %s %s    in %d  out %d"), j, nodes[j].nType,nodes[j].Op, nodes[j].CoilName,nodes[j].indegree,nodes[j].outdegree);
//            DbgLog(s1);
        }
        //输出AOV图的 弧 数据
        for (int j = 1; j < nArcCount; j++) {
            s1.Format(_T("%3d     %2d - %2d "), j, arcs[j].tailNode, arcs[j].headNode);
//            DbgLog(s1);
        }
        for (int n = 1; n < 8; n++) {
            s1.Format(_T("处理步骤 %d "), n);
            DbgLog(s1);
            for (int j = 1; j < nNodeCount; j++) {
                if (nodes[j].bEnable) nodes[j].OutProcAllDone = 0;
            }
            // 处理 AOV 图
            // 从 母线 开始
            //串联归并 // 归并原则, 普通节点,非虚节点, 两个虚节点之间 多个连续的,归并, 非输出。
            MergeVPSubSerialNodes(1);
            // 处理虚节点
            // 虚节点的多输入处理, 单 OR 或者 多 ORS。
            // 虚节点的输出处理,
            // 对于后续还有共同虚节点的输出, 第一个不处理,
            // 第二个,单不处理,多处理 ST, 后面由虚节点再 ORS, ANS。
            // 对于直接输出的,如果后面没有改变的输出, 直接输出不处理。
            // 对于后面还有改变的, PSHS, RDS, POPS
            // 另外,可以后期简化, ST 后紧跟 ORS 的, 简化为 OR。
            // PSHS RDS POPS 后跟不改变的。 简化
            ScanAOV1(1);
            if (nodes[2].outdegree == 0) break;
        }
        // 输出处理完的 AOV 图
        s1.Format(_T("处理完的AOV图"));
        DbgLog(s1);
        for (int j = 2; j < nNodeCount; j++) {
            CStringA s2;
            if (nodes[j].bEnable) {
                s1.Format(_T("%d type %d op %s coil %s  in %d   out %d"), j, nodes[j].nType, nodes[j].Op, nodes[j].CoilName, nodes[j].indegree, nodes[j].outdegree);
                DbgLog(s1);
                s1 = nodes[j].prog1.ToText();
                DbgLog(s1);
            }
        }
        allprogs += nodes[2].prog1;
        nodes[2].prog1.Progs.clear();
    }
    s1.Format(_T("完整的PLC程序 \r\n"));
    s1 += allprogs.ToText();
    DbgLog(s1);
    // 创建 AOV 图
    //输出程序
    int n = (int)allprogs.Progs.size();
    s1.Format(_T("总程序步数 %d "), n);
    DbgLog(s1);
    s1.Format(_T("all prog steps %d "), n);
    DbgLog(s1);
    for (int i = 0; i < n; i++)
    {
        int optype = allprogs.Progs[i].nOpType1;
        allprogs.Progs[i].PairTo = 0;//??????????
        allprogs.Progs[i].nBinStep = i;
        CStringA OpTxtA, OpShowTxtA;
        CString OpTxt, OpShowTxt;
        pDoc->OpToTxt(optype, OpTxtA);
        pDoc->OpToShowTxt(optype, OpShowTxtA);
        OpTxt = OpTxtA;
        OpShowTxt = OpShowTxtA;
        s1.Format(_T("%d %s %s"), optype, OpTxt, OpShowTxt);
        pDoc->Progs[i] = allprogs.Progs[i];
        DbgLog(s1);
    }
    pDoc->m_nProgSteps = n;
    return 0;
}
@@ -2776,7 +3819,7 @@
    int nNextX = 1;//步长(下个起始点移动的距离)
    nCurPosY = nPosY;
    nCurPosX = nPosX;
    int nCoilType, CoilAddr;
//    int nCoilType, CoilAddr;
    CMTerm1Doc* pDoc = GetDocument();
    for (int j = nPosX; j < m_CellPerLine; j += nNextX)
    {
@@ -3235,7 +4278,7 @@
    int nNextX = 0;//步长(到下个线圈起始位置应移动距离
    nCurPosY = nStartLine;
    nCurPosX = nPosX;
    int nCoilType, CoilAddr;
//    int nCoilType, CoilAddr;
    CMTerm1Doc* pDoc = GetDocument();
    for (int j = nPosX; j < nSizeX; j += nNextX)
MTerm1/MTerm1View.h
@@ -53,11 +53,13 @@
        typeExt1,    //23 0x17    //被前面的指令占用的空间
        typeExt2,
        typeExt3,
        typeExt4,
        typeTM=30,        //定时器
        typeFN1=40,        //1个参数的函数
        typeFN2=50,        //2个参数的函数
        typeFN3=60,        //3个参数的函数
        typeTM = 30,        //定时器
        typeFN1 = 40,        //1个参数的函数
        typeFN2 = 50,        //2个参数的函数
        typeFN3 = 60,        //3个参数的函数
        typeFN4 = 70,        //3个参数的函数
        typeCoil=99,
@@ -65,6 +67,7 @@
    struct stCell
    {
        int nType;                //单元类型。
        int nOpType;            //指令码。
        int nProgStep;            //对应程序的步数
        int bFocused = 0;        //热点选中
        int bSelected = 0;        //选中
@@ -90,33 +93,111 @@
        }
    };
    stCell Cells[2000][16] = { 0 };
    struct stProgSection
    {
        std::vector <CMTerm1Doc::stProg> Progs;
        int Append(CMTerm1Doc::stProg prog)    {
        int Append(CMTerm1Doc::stProg prog) {
            Progs.push_back(prog);
            return 0;
        };
        int Append(struct stProgSection progsec){
            int n=(int)progsec.Progs.size();
        int Append(struct stProgSection progsec) {
            int n = (int)progsec.Progs.size();
            for (int i = 0; i < n; i++) {
                Progs.push_back(progsec.Progs[i]);
            }
            return 0;
        };
        int operator+=(const struct stProgSection progsec) {
        int operator+=(const struct stProgSection progsec) {
            Append(progsec);
            return 0;
            return 0;
        };
        int Insert(CMTerm1Doc::stProg prog)    {
        int Insert(CMTerm1Doc::stProg prog) {
            Progs.insert(Progs.begin(), prog);
            return 0;
        }
        CString ToText() {
            CString s1;
            CStringA s2A;
            int n = (int)Progs.size();
            for (int k = 0; k < n; k++) {
                CMTerm1Doc::stProg& prog0 = Progs.at(k);
                s2A = prog0.ToText();
                s1 += s2A;
            }
            return s1;
        }
    };
    std::pair<int, int> popsPoint[100];
    struct arc;
    struct node {
        int nId;
        int bEnable;
        int nType;
        char input;
        char result;
        char indeep;        //输入 深度
        char outdeep;        //输出 深度
        int indegree;        //入度
        int outdegree;        //出度
        int parameter1;
        int parameter2;
        struct arc *firstIn;
        struct arc *firstOut;
        int nCellX;
        int nCellY;
        CString Op;
        CString CoilName;
        int InProcCount;
        int OutProcCount;
        int OutProcAllDone;
        stProgSection prog1;
    };
    struct arc {
        int nId;
        int bEnable;
        int tailNode;
        int headNode;
        int hlinkId;
        int tlinkId;
        struct node* tailvex;
        struct node* headvex;
        struct arc* hlink;
        struct arc* tlink;
        //stProgSection prog1;
    };
    node nodes[1000];
    arc arcs[1000];
    node* rootnode;
    int nNodeCount = 0;
    int nArcCount = 0;
    int AddNode(int nType, int CellX,int CellY, CString sCoilName, int PrevNode=0);
    int AddArc(int nNodeID1, int nNodeID2);
    int RemoveNode(int nIndex);
    int RemoveArc(int nIndex);
    int MergeNode(int nNodeId1, int nNodeId2);
    int MergeVPSubSerialNodes(int nNodeId);
    int MergeParallelNodeWithinVP(int nVPNodeId1, int nVPNodeId2);
    
    int FindVPNode(int x, int y,int endy);
    int TransLDSToProg();
    int TransLDSToProgAOV();
    int ScanAOV1(int nNodeid);
    int ScanVPAOV(int nVPNodeId1, int nVPNodeId2);
    int MergeVPSerialNodes(int nNodeId);
//    int ScanAOV2(int nNodeid);
    int nPSHS = -1;
    bool firstCoil = true;//本段第一个单元格
@@ -292,7 +373,9 @@
    afx_msg void OnProgCancelEdit();
    afx_msg void OnUpdateProgCancelEdit(CCmdUI *pCmdUI);
    afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
    int TransLDSToProg();
    afx_msg void OnInputIoComment();
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    int ScanLDSCells(int nStartLine, int nEndLine, int nPosY, int nPosX, int nLevel, stProgSection & progsec, CString & sProgSec, int &nSteps);
MTerm1/MyDlgBarFuncKey.h
@@ -48,7 +48,7 @@
#define IDC_BUTTON_NOT1                 33408
#define IDC_BUTTON_T                    33501
#define IDC_BUTTON_C                    33502
#define IDC_BUTTON_E                    33503
//#define IDC_BUTTON_E                    33503
#define IDC_BUTTON_UPDOWN1              33507
#define IDC_BUTTON_D                     33701
MTerm1/MyFormInputShow.h
@@ -50,7 +50,7 @@
#define IDC_BUTTON_NOT1                 33408
#define IDC_BUTTON_T                    33501
#define IDC_BUTTON_C                    33502
#define IDC_BUTTON_E                    33503
//#define IDC_BUTTON_E                    33503
#define IDC_BUTTON_UPDOWN1              33507
#define IDC_BUTTON_D                     33701
MTerm1/Resource.h
@@ -645,6 +645,7 @@
#define ID_SHOW_LOG                     33092
#define ID_33093                        33093
#define ID_MENU_SHOWNAV                 33094
#define ID_KEY_X                        33095
#define IDS_STRING101                   33100
#define IDC_BUTTON_AND                  33101
#define IDC_BUTTON_OR                   33102
@@ -689,7 +690,6 @@
#define IDC_BUTTON_NOT1                 33408
#define IDC_BUTTON_T                    33501
#define IDC_BUTTON_C                    33502
#define ID_KEY_X                        33095
#define ID_INDICATOR_SEL_TYPE           59135
#define ID_INDICATOR_MACHINE_TYPE       59142
#define ID_INDICATOR_PROGRAM_POS        59143