QuakeGod
2024-12-24 61deef5cdf96cbfdd6ad45be49e80d597c00ca65
MTerm1/MTerm1Doc.cpp
@@ -1,5 +1,5 @@

// MTerm1Doc.cpp: CMTerm1Doc 类的实现
// MultiTerminal2Doc.cpp: CMTerm1Doc 类的实现
//
#include "pch.h"
@@ -12,17 +12,157 @@
#include "MTerm1Doc.h"
#include "MTerm1View.h"
#include "MTerm1LdsView.h"
#include "MTerm1BldView.h"
#include "MTerm1BnlView.h"
#include "MTerm1CoilView.h"
#include "MTerm1DataView.h"
#include "MTerm1CtrlView.h"
#include "MTerm1TestView.h"
#include "MTerm1ProgTxt.h"
#include "MTerm1CommDevView.h"
#include <propkey.h>
#include "DialogCommSet1.h"
#include "DialogStatusShow.h"
#include "DialogSysRegSet.h"
#include "DialogFactCfg.h"
#include "DialogDateTime.h"
#include "DialogEventLog.h"
//#include "HvSerialPort.h"
#include <functional>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMTerm1Doc
CMTerm1Doc::stTypeNameDef CMTerm1Doc::CoilTypeNameDef[] =
{
   {KLCoilTypeX,"X"},
   {KLCoilTypeY,"Y"},
   {KLCoilTypeR,"R"},
   {KLCoilTypeLX,"LX"},
   {KLCoilTypeLY,"LY"},
   {KLCoilTypeLR,"LR"},
   {KLCoilTypeSR,"SR"},
   {KLCoilTypeC,"C"},
   {KLCoilTypeT,"T"},
   {KLCoilTypeP,"P"},
   {KLCoilTypeE,"E"},
};
int CMTerm1Doc::nCoilTypeDefCount = sizeof(CMTerm1Doc::CoilTypeNameDef) / sizeof(stTypeNameDef);
CMTerm1Doc::stTypeNameDef CMTerm1Doc::DataTypeNameDef[] =
{
   {KLDataTypeDEC,"K"},
   {KLDataTypeHEX,"H"},
   {KLDataTypeWX,"WX"},
   {KLDataTypeWY,"WY"},
   {KLDataTypeWR,"WR"},
   {KLDataTypeDT,"DT"},
   {KLDataTypeWLX,"WLX"},
   {KLDataTypeWLY,"WLY"},
   {KLDataTypeSDT,"SDT"},
   {KLDataTypeWSR,"WSR"},
   {KLDataTypeEV,"EV"},
   {KLDataTypeSV,"SV"},
   {KLDataTypeLD,"LD"},
};
int CMTerm1Doc::nDataTypeDefCount = sizeof(CMTerm1Doc::DataTypeNameDef) / sizeof(stTypeNameDef);
CMTerm1Doc::stOpDef CMTerm1Doc::OpDef[] =
{
   {OP_NOP,"NOP",0},
   {OP_END,"ED",0},
   {OP_ST,"ST",1,KLParamCoil},
   {OP_ST_,"ST/",1,KLParamCoil},
   {OP_AN,"AN",1,KLParamCoil},
   {OP_AN_,"AN/",1,KLParamCoil},
   {OP_OR,"OR",1,KLParamCoil},
   {OP_OR_,"OR/",1,KLParamCoil},
   {OP_NOT,"NOT"},
   {OP_ANS,"ANS"},
   {OP_ORS,"ORS"}
   ,
   {OP_PSHS,"PSHS"},
   {OP_RDS,"RDS"},
   {OP_POPS,"POPS"},
   {OP_OUT,"OUT",1,KLParamCoil},
   {OP_SET,"SET",1,KLParamCoil},
   {OP_RESET,"RESET",1,KLParamCoil},
   {OP_DF,"DF"},
   {OP_DF_,"DF/"},
   {OP_ST_EQ,"ST=",2,KLParamWord,"="},
   {OP_ST_LT,"ST<",2,KLParamWord,"<"},
   {OP_ST_GT,"ST>",2,KLParamWord,">"},
   {OP_ST_LE,"ST<=",2,KLParamWord,"<="},
   {OP_ST_GE,"ST>=",2,KLParamWord,">="},
   {OP_ST_NE,"ST<>",2,KLParamWord,"<>"},
   {OP_AN_EQ,"AN=",2,KLParamWord,"="},
   {OP_AN_LT,"AN<",2,KLParamWord,"<"},
   {OP_AN_GT,"AN>",2,KLParamWord,">"},
   {OP_AN_LE,"AN<=",2,KLParamWord,"<="},
   {OP_AN_GE,"AN>=",2,KLParamWord,">="},
   {OP_AN_NE,"AN<>",2,KLParamWord,"<>"},
   {OP_OR_EQ,"OR=",2,KLParamWord,"="},
   {OP_OR_LT,"OR<",2,KLParamWord,"<"},
   {OP_OR_GT,"OR>",2,KLParamWord,">"},
   {OP_OR_LE,"OR<=",2,KLParamWord,"<="},
   {OP_OR_GE,"OR>=",2,KLParamWord,">="},
   {OP_OR_NE,"OR<>",2,KLParamWord,"<>"},
   {OP_TML,"TML",2,KLParamWord,"TML"},
   {OP_TMR,"TMR",2,KLParamWord,"TMR"},
   {OP_TMX,"TMX",2,KLParamWord,"TMX"},
   {OP_TMY,"TMY",2,KLParamWord,"TMY"},
   {OP_MV,"MV",2,KLParamWord,"MV"},
   {OP_INC,"INC",1,KLParamWord,"+1"},
   {OP_ADD2,"ADD2",2,KLParamWord,"+"},
   {OP_ADD3,"ADD3",3,KLParamWord,"+"},
   {OP_DEC,"DEC",1,KLParamWord,"-1"},
   {OP_SUB2,"SUB2",2,KLParamWord,"-"},
   {OP_SUB3,"SUB3",3,KLParamWord,"-"},
   {OP_MUL,"MUL",3,KLParamWord,"X"},
   {OP_DIV,"DIV",3,KLParamWord,"/"},
};
int CMTerm1Doc::nOpDefCount = sizeof(CMTerm1Doc::OpDef) / sizeof(stOpDef);
IMPLEMENT_DYNCREATE(CMTerm1Doc, CDocument)
BEGIN_MESSAGE_MAP(CMTerm1Doc, CDocument)
   ON_COMMAND(ID_UPLOAD_FROM_PLC, &CMTerm1Doc::OnUploadFromPlc)
   ON_COMMAND(ID_ONLINE, &CMTerm1Doc::OnOnline)
   ON_UPDATE_COMMAND_UI(ID_ONLINE, &CMTerm1Doc::OnUpdateOnline)
   ON_COMMAND(ID_OFFLINE, &CMTerm1Doc::OnOffline)
   ON_UPDATE_COMMAND_UI(ID_OFFLINE, &CMTerm1Doc::OnUpdateOffline)
   ON_COMMAND(ID_PLC_RUN, &CMTerm1Doc::OnPlcRun)
   ON_UPDATE_COMMAND_UI(ID_PLC_RUN, &CMTerm1Doc::OnUpdatePlcRun)
   ON_COMMAND(ID_DOWNLOAD_TO_PLC, &CMTerm1Doc::OnDownloadToPlc)
   ON_UPDATE_COMMAND_UI(ID_DOWNLOAD_TO_PLC, &CMTerm1Doc::OnUpdateDownloadToPlc)
   ON_COMMAND(ID_COMUNICATION_SET, &CMTerm1Doc::OnComunicationSet)
   ON_COMMAND(ID_PLC_SYSREG_SET, &CMTerm1Doc::OnPlcSysregSet)
   ON_COMMAND(ID_MENU_VIEW_LDS, &CMTerm1Doc::OnMenuViewLds)
   ON_COMMAND(ID_MENU_VIEW_BLD, &CMTerm1Doc::OnMenuViewBld)
   ON_COMMAND(ID_MENU_VIEW_BNL, &CMTerm1Doc::OnMenuViewBnl)
   ON_COMMAND(ID_MENU_SHOW_CONSOLE, &CMTerm1Doc::OnMenuShowConsole)
   ON_COMMAND(ID_MENU_COMM_TEST, &CMTerm1Doc::OnMenuCommTest)
   ON_COMMAND(ID_SIMULATE, &CMTerm1Doc::OnSimulate)
   ON_UPDATE_COMMAND_UI(ID_SIMULATE, &CMTerm1Doc::OnUpdateSimulate)
   ON_COMMAND(ID_MENU_STATUS_SHOW, &CMTerm1Doc::OnMenuStatusShow)
   ON_COMMAND(ID_MENU_FACT_CFG, &CMTerm1Doc::OnMenuFactCfg)
   ON_COMMAND(ID_MENU_DATETIME_SET, &CMTerm1Doc::OnMenuDatetimeSet)
   ON_COMMAND(ID_MENU_EVENT_LOG, &CMTerm1Doc::OnMenuEventLog)
END_MESSAGE_MAP()
@@ -32,37 +172,128 @@
{
   // TODO: 在此添加一次性构造代码
   KLink1::stCallBackFuncs callbackfuncs;
//   callbackfuncs.OpenFunc = std::bind(&HvSerialPort::Open, &myHvSerialPort1);
//   callbackfuncs.CloseFunc = std::bind(&HvSerialPort::Close, &myHvSerialPort1);
//   callbackfuncs.ClearBufFunc = std::bind(&HvSerialPort::ClearBuf, &myHvSerialPort1);
//   callbackfuncs.SendPkgFunc = std::bind(&HvSerialPort::Send, &myHvSerialPort1, std::placeholders::_1, std::placeholders::_2);
//   callbackfuncs.RecvPkgFunc = std::bind(&HvSerialPort::Recv, &myHvSerialPort1, std::placeholders::_1, std::placeholders::_2);
//   theApp.MyKLink1.SetCallBackFuncs(&callbackfuncs);
//   StartTime = myHvSerialPort1.GetTimemS();
}
CMTerm1Doc::~CMTerm1Doc()
{
}
/*
int CMTerm1Doc::SendPacket(void * pBuf, int Len)
{
   return myHvSerialPort1.Send((char *)pBuf, Len);
}
int CMTerm1Doc::RecvPacket(void * pBuf, int Len)
{
   int j = 0;
   j = myHvSerialPort1.Recv((char *)pBuf, Len);
   if (j <= 0)
   {
      CString s1;
      s1.Format(_T("Read %d R=%d %s"), Len, j, myHvSerialPort1.m_strResult);
      SysLog(s1);
   }
   return j;
}
*/
/// <summary>
/// 处理新文档的创建事件
/// </summary>
/// <returns></returns>
BOOL CMTerm1Doc::OnNewDocument()
{
   if (!CDocument::OnNewDocument())
   {
      return FALSE;
   }
   // TODO: 在此添加重新初始化代码
   // (SDI 文档将重用该文档)
   //LoadFromFile(_T("0prog1.txt"));
   return TRUE;
}
/// <summary>
/// 处理打开的文档
/// </summary>
/// <param name="lpszPathName">指向要打开的文件路径的指针</param>
/// <returns></returns>
BOOL CMTerm1Doc::OnOpenDocument(LPCTSTR lpszPathName)
{
//   if (!CDocument::OnOpenDocument(lpszPathName))
//      return FALSE;
   CString s1;//日志信息
   s1.Format(_T("OnOpenDocument %s"), lpszPathName);
   SysLog(s1);
   //加载文件内容
   LoadFromFile(lpszPathName);
   return TRUE;
}
/// <summary>
/// 处理保存文档的事件
/// </summary>
/// <param name="lpszPathName">指向要打开的文件路径的指针</param>
/// <returns></returns>
BOOL CMTerm1Doc::OnSaveDocument(LPCTSTR lpszPathName)
{
   // TODO: 在此添加专用代码和/或调用基类
   CString s1;
   s1.Format(_T("OnSaveDocument %s"), lpszPathName);
   SysLog(s1);
   //0912-zxd-Modify
    int result = SaveToFile(lpszPathName);
   return result == 1 ? TRUE : FALSE;
//   return CDocument::OnSaveDocument(lpszPathName);
}
/// <summary>
/// 处理关闭文档的事件
/// </summary>
void CMTerm1Doc::OnCloseDocument()
{
   // TODO: 在此添加专用代码和/或调用基类
//   CString s1;
//   s1.Format(_T("OnCloseDocument %s"));
//   SysLog(s1);
   CDocument::OnCloseDocument();
}
// CMTerm1Doc 序列化
/// <summary>
///  CMTerm1Doc 序列化
/// </summary>
/// <param name="ar"></param>
void CMTerm1Doc::Serialize(CArchive& ar)
{
   CString s1;
   if (ar.IsStoring())
   {
      // TODO: 在此添加存储代码
      ar.GetFile();
      s1.Format(_T("Serialize Saving"));
      SysLog(s1);
   }
   else
   {
      // TODO: 在此添加加载代码
      s1.Format(_T("Serialize Loading"));
      SysLog(s1);
   }
}
@@ -100,6 +331,10 @@
   SetSearchContent(strSearchContent);
}
/// <summary>
/// 设置文档的搜索内容
/// </summary>
/// <param name="value">要搜索内容的字符串值</param>
void CMTerm1Doc::SetSearchContent(const CString& value)
{
   if (value.IsEmpty())
@@ -123,11 +358,17 @@
// CMTerm1Doc 诊断
#ifdef _DEBUG
/// <summary>
/// 验证对象的有效性
/// </summary>
void CMTerm1Doc::AssertValid() const
{
   CDocument::AssertValid();
}
/// <summary>
/// 诊断信息的输出
/// </summary>
/// <param name="dc"></param>
void CMTerm1Doc::Dump(CDumpContext& dc) const
{
   CDocument::Dump(dc);
@@ -135,4 +376,2317 @@
#endif //_DEBUG
// CMTerm1Doc 命令
/// <summary>
/// 加载指定的文件
/// </summary>
/// <param name="sFilePathName">需要加载的文件的路径名</param>
/// <returns></returns>
int CMTerm1Doc::LoadFromFile(CString sFilePathName)
{
   CFile file1;//打开指定的文件
   CFileException e;
   bool r = file1.Open(sFilePathName, CFile::modeRead, &e);
   if (r)
   {
      int l = (int)file1.GetLength();
      CStringA s1A;
      file1.Read(s1A.GetBuffer(l + 2048), l);
      file1.Close();
      s1A.ReleaseBuffer(l);
      TransFileToProg(s1A);//文件内容转换为Prog格式
      UpdateAllViews(NULL);//更新所有的视图,以反映新加载的内容
   }
   return 0;
}
/// <summary>
/// 保存文件
/// </summary>
/// <param name="sFilePathName">需要保存的文件的路径名</param>
/// <returns></returns>
int CMTerm1Doc::SaveToFile(CString sFilePathName)
{
   CString s1;
   CFile file1;
   CFileException e;
   bool r = file1.Open(sFilePathName, CFile::modeCreate|CFile::modeReadWrite, &e);//读写模式打开文件
   if (r)
   {
      CStringA s1A;
      CStringA sSectionNameA;
      //写入系统配置
      GetSectionName(SectionSysCfg, sSectionNameA); //获取系统配置的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());//将获取到的文本内容写入文件
      //写入程序
      GetSectionName(SectionProg, sSectionNameA); //获取程序的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());//获取到的文本内容写入文件
      TransToTxt(s1A);//将程序内容转换为文本格式
      file1.Write(s1A, s1A.GetLength());//将转换后的文本内容写入文件
      //写入注释
      GetSectionName(SectionAnno, sSectionNameA); //获取注释的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());
      //循环遍历所有注释,并将其写入文件
      for (int i = 0; i < nCoilAnnoCount; i++)
      {
         if (mCoilAnnos[i].sAnno.IsEmpty()) { continue; }
         s1 = mCoilAnnos[i].sCoilName + _T("\t") + mCoilAnnos[i].sAnno + _T("\r\n");
         s1A = s1;
         file1.Write(s1A, s1A.GetLength());
      }
      //写入触点监控列表
      GetSectionName(SectionCoilList, sSectionNameA); //获取触点监控列表的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());
      //写入数据监控列表
      GetSectionName(SectionDataList, sSectionNameA); //获取数据监控列表的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());
      file1.Close();
      return 1;
   }
   else//文件打开失败
   {
      return 0;
   }
}
/// <summary>
/// 根据文本匹配类型的Key并返回
/// </summary>
/// <param name="txt"></param>
/// <returns></returns>
int CMTerm1Doc::TxtToSectionType(CStringA txt)
{
   for (int i = 0; i < nSectionDefCount; i++) {
      if (SectionDef[i].SectionName == txt) {
         return SectionDef[i].nSectionType;
      }
   }
   return SectionNone;
}
/// <summary>
/// 根据Key匹配类型的文本,通过txt传递,返回查询执行结果
/// </summary>
/// <param name="nSectionType"></param>
/// <param name="txt"></param>
/// <returns></returns>
int CMTerm1Doc::GetSectionName(int nSectionType, CStringA & txt)
{
   for (int i = 0; i < nSectionDefCount; i++) {
      if (SectionDef[i].nSectionType == nSectionType) {
         txt = SectionDef[i].SectionName;
         return true;
      }
   }
   return false;
}
/// <summary>
///
/// </summary>
/// <param name="nSectionType">Section类型</param>
/// <param name="nSectionLine">行号</param>
/// <param name="nSectionLines">行数</param>
/// <returns></returns>
int CMTerm1Doc::GetSectionPos(int nSectionType, int * nSectionLine, int * nSectionLines)
{
   for (int i = 0; i < nSectionCount; i++) {
      if (Sections[i].nSectionType == nSectionType) {
         *nSectionLine = Sections[i].nSectionLineNo;
         *nSectionLines = Sections[i].nLines;
         return true;
      }
   }
   return false;
}
/// <summary>
/// 文本表示的操作转换为其相应的操作类型、参数数量和参数类型
/// </summary>
/// <param name="optxt">表示操作的字符串</param>
/// <param name="ParamCount">返回与给定操作相对应的参数数量</param>
/// <param name="ParamType">返回与给定操作相对应的参数类型</param>
/// <returns>-1:匹配失败</returns>
int CMTerm1Doc::TxtToOp(CStringA optxt, int* ParamCount, int* ParamType)
{
   for (int i = 0; i < nOpDefCount; i++){
      if (OpDef[i].OpTxt == optxt)   {
         *ParamCount = OpDef[i].nParamCount;
         *ParamType = OpDef[i].nParamType;
         return OpDef[i].nOpType1;
      }
   }
   return -1;
}
/// <summary>
/// 操作类型转换为其相应的文本表示
/// </summary>
/// <param name="nOp">操作类型</param>
/// <param name="OpTxt">操作文本</param>
/// <returns></returns>
int CMTerm1Doc::OpToTxt(int nOp, CStringA & OpTxt)
{
   for (int i = 0; i < nOpDefCount; i++){
      if (OpDef[i].nOpType1 == nOp) {
         OpTxt = OpDef[i].OpTxt;
         return true;
      }
   }
   return false;
}
/// <summary>
/// 操作类型转换为其相应的前台展示文本
/// </summary>
/// <param name="nOp">操作类型</param>
/// <param name="OpShowTxt">前台展示文本</param>
/// <returns></returns>
int CMTerm1Doc::OpToShowTxt(int nOp, CStringA & OpShowTxt)
{
   for (int i = 0; i < nOpDefCount; i++) {
      if (OpDef[i].nOpType1 == nOp) {
         OpShowTxt = OpDef[i].ShowTxt;
         return true;
      }
   }
   return false;
}
/// <summary>
/// 文本转线圈类型
/// </summary>
/// <param name="Typetxt">线圈类型</param>
/// <param name="nCoilType">线圈类型</param>
/// <param name="nCoilAddr">线圈地址</param>
/// <returns></returns>
int CMTerm1Doc::TxtToCoilType(CStringA Typetxt, int* nCoilType, int* nCoilAddr)
{
   Typetxt.MakeUpper();
   for (int i = 0; i < nCoilTypeDefCount; i++)
   {
      if (Typetxt.Find( CoilTypeNameDef[i].TypeTxt)==0) {
         *nCoilType = CoilTypeNameDef[i].nType;
         *nCoilAddr = atoi(Typetxt.Mid(CoilTypeNameDef[i].TypeTxt.GetLength()));
         return true;
         return CoilTypeNameDef[i].nType;
      }
   }
   return false;;
}
/// <summary>
/// 线圈类型转文本
/// </summary>
/// <param name="nType">线圈类型</param>
/// <param name="typeTxt">线圈文本</param>
/// <returns></returns>
int CMTerm1Doc::CoilTypeToTxt(int nType, CStringA & typeTxt)
{
   for (int i = 0; i < nCoilTypeDefCount; i++)
   {
      if (CoilTypeNameDef[i].nType == nType){
         typeTxt = CoilTypeNameDef[i].TypeTxt;
         return true;
      }
   }
   return false;
}
/// <summary>
///
/// </summary>
/// <param name="Typetxt"></param>
/// <param name="nDataType"></param>
/// <param name="nDataAddr"></param>
/// <returns></returns>
int CMTerm1Doc::TxtToDataType(CStringA Typetxt, int * nDataType, int* nDataAddr)
{
   Typetxt.MakeUpper();
   for (int i = 0; i < nDataTypeDefCount; i++)
   {
      if (Typetxt.Find(DataTypeNameDef[i].TypeTxt) == 0) {
         *nDataType = DataTypeNameDef[i].nType;
         *nDataAddr = atoi(Typetxt.Mid(DataTypeNameDef[i].TypeTxt.GetLength()));
         return true;
      }
   }
   *nDataType = KLDataTypeDEC;
   *nDataAddr = atoi(Typetxt);
   return false;
}
/// <summary>
///
/// </summary>
/// <param name="nType"></param>
/// <param name="typeTxt"></param>
/// <returns></returns>
int CMTerm1Doc::DataTypeToTxt(int nType, CStringA & typeTxt)
{
   for (int i = 0; i < nDataTypeDefCount; i++)
   {
      if (DataTypeNameDef[i].nType == nType) {
         typeTxt = DataTypeNameDef[i].TypeTxt;
         return true;
      }
   }
   return false;
}
/// <summary>
/// 获取与特定类型和地址相对应的线圈注释
/// </summary>
/// <param name="nType"></param>
/// <param name="nAddr"></param>
/// <param name="sAnno"></param>
/// <returns></returns>
int CMTerm1Doc::GetAnno(unsigned short nType, unsigned short nAddr, CString & sAnno)
{
   // TODO: 在此处添加实现代码.
   // 二分法 查找。
   // map.
   for (int i = 0; i < nCoilAnnoCount; i++) {
      if (mCoilAnnos[i].nType == nType && mCoilAnnos[i].nAddr == nAddr) {
         sAnno = mCoilAnnos[i].sAnno;
         return 1;
      }
   }
   return 0;
}
/// <summary>
/// 设置或更新特定线圈的注释
/// </summary>
/// <param name="sCoilName"></param>
/// <param name="sAnno"></param>
/// <returns></returns>
int CMTerm1Doc::SetAnno(CString sCoilName, CString sAnno)
{
   // TODO: 在此处添加实现代码.
// 二分法 查找。
// map.
   int bValid = 0;
   int nType = 0, nAddr = 0;
   CStringA s1A;
   s1A = sCoilName;
   if (TxtToCoilType(s1A, &nType, &nAddr) || TxtToDataType(s1A, &nType, &nAddr)) {
      bValid = 1;
   }
   if (!bValid) return false;
   for (int i = 0; i < nCoilAnnoCount; i++) {
      if (mCoilAnnos[i].nType == nType && mCoilAnnos[i].nAddr == nAddr) {
         mCoilAnnos[i].sAnno = sAnno;
         return 1;
      }
   }
   mCoilAnnos[nCoilAnnoCount].nType = nType;
   mCoilAnnos[nCoilAnnoCount].nAddr = nAddr;
   mCoilAnnos[nCoilAnnoCount].sCoilName = sCoilName;
   mCoilAnnos[nCoilAnnoCount].sAnno = sAnno;
   nCoilAnnoCount++;
   return 2;
}
/// <summary>
/// 直接使用类型和地址参数来设置或更新特定线圈的注释
/// </summary>
/// <param name="nType">类型</param>
/// <param name="nAddr">地址</param>
/// <param name="sCoilName">线圈名称</param>
/// <param name="sAnno">线圈注释</param>
/// <returns></returns>
int CMTerm1Doc::SetAnno(unsigned short nType, unsigned short nAddr, CString sCoilName, CString sAnno)
{
   // TODO: 在此处添加实现代码.
// 二分法? 查找。
// map.
   for (int i = 0; i < nCoilAnnoCount; i++) {
      if (mCoilAnnos[i].nType == nType && mCoilAnnos[i].nAddr == nAddr) {
         mCoilAnnos[i].sAnno = sAnno;
         return 1;
      }
   }
   mCoilAnnos[nCoilAnnoCount].nType = nType;
   mCoilAnnos[nCoilAnnoCount].nAddr = nAddr;
   mCoilAnnos[nCoilAnnoCount].sCoilName = sCoilName;
   mCoilAnnos[nCoilAnnoCount].sAnno = sAnno;
   nCoilAnnoCount++;
   return 0;
}
/// <summary>
/// 转换文本行为Prog格式
/// </summary>
/// <param name="txtLines">文本行集合</param>
/// <param name="StartLine">开始行</param>
/// <param name="ProgLines">程序行</param>
/// <returns></returns>
int CMTerm1Doc::TransLinesToProg(const CStringArray & txtLines, int StartLine , int ProgLines)
{
   CString s1;
   int txtLineCount = (int)txtLines.GetSize();
   //读取程序 章节
   int nProgStartLine = 0;
   int nProgLines = 0;
   nProgStartLine = StartLine;
   if (ProgLines == -1) nProgLines = txtLineCount;
   else nProgLines = ProgLines;
   int nProgPos = 0;
   //逐行读取并转化
   for (int i = nProgStartLine; i < nProgStartLine + nProgLines; i++)
   {
      CString sLine;
      sLine = txtLines.GetAt(i);
      //清除空格和制表符
      sLine.Trim();
      sLine.Replace(_T("\t"), _T(" "));
      sLine.Replace(_T("   "), _T(" "));
      sLine.Replace(_T("  "), _T(" "));
      //使用空格分隔字符串,并将其存储在 strarr2 数组中
      CStringArray strarr2;
      DivideStringToArray(sLine, _T(" "), strarr2);
      if (strarr2.GetSize() == 0)
      {
         continue;
      }
      //从数组中提取指令,并将其转换为大写形式
      CString sCmd;
      sCmd = strarr2.GetAt(0);
      sCmd.MakeUpper();
      //使用 TxtToOp 函数将指令文本转换为操作类型。
      CStringA s1A;
      s1A = sCmd;
      int nParamCount, nParamType;
      int nType, nAddr;
      int k = TxtToOp(s1A, &nParamCount, &nParamType);
      if (k >= 0)
      {
         //根据参数类型,使用 TxtToCoilType 或 TxtToDataType 函数将参数文本转换为参数类型和地址
         Progs[nProgPos].nOpType1 = k;
         for (int j = 0; j < 3 && j < nParamCount && j < strarr2.GetSize() - 1; j++)
         {
            s1A = strarr2.GetAt(j + 1);
            s1A.MakeUpper();
            Progs[nProgPos].Params[j].sParamStr = s1A;
            if (nParamType == KLParamCoil) {
               TxtToCoilType(s1A, &nType, &nAddr);
               Progs[nProgPos].Params[j].nParamType = nType;
               Progs[nProgPos].Params[j].nParamAddr = nAddr;
            }
            else if (nParamType == KLParamWord) {
               TxtToDataType(s1A, &nType, &nAddr);
               Progs[nProgPos].Params[j].nParamType = nType;
               Progs[nProgPos].Params[j].nParamAddr = nAddr;
            }
            else {
            }
         }
         Progs[nProgPos].nParamCount = (int)strarr2.GetSize() - 1;
         Progs[nProgPos].PairTo = 0;
         nProgPos++;
      }
   }
   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;
   // 查找匹配指令和地址
   //匹配指令(错误,此处匹配指令使用数字
   for (int i = 0; i < m_nProgSteps; i++)
   {
      int nOpType = Progs[i].nOpType1;
      int nParamCount = Progs[i].nParamCount;
      switch (Progs[i].nOpType1)
      {
      case OP_ST:
      case OP_ST_:
      case OP_ST_EQ:
      case OP_ST_NE:
      case OP_ST_LT:
      case OP_ST_GT:
      case OP_ST_LE:
      case OP_ST_GE:
         nCurStackDeep++;
         s1.Format(_T("St Deep %d pos %d "), nCurStackDeep, i);
         //SysLog(s1);
         stpos[nSts] = i;
         nSts++;
         break;
      case OP_ANS:
      case OP_ORS:
         Progs[stpos[nSts - 1]].PairTo = i; // CMTerm1Doc::OP_ANS;
         s1.Format(_T("Pair deep %d   %d -- %d"), nCurStackDeep, stpos[nSts - 1], i);
         //SysLog(s1);
         nCurStackDeep--;
         nSts--;
         break;
      case OP_PSHS:
         break;
      case OP_POPS:
         break;
         break;
      default:
         break;
      }
      StackDeeps[i] = nCurStackDeep;
   }
   s1.Format(_T("Remaining STs %d \r\n"), nSts);
//   SysLog(s1);
   for (int i = 0; i < nSts; i++) {
      s1.AppendFormat(_T("[%d] %d\t"), i, stpos[i]);
   }
   SysLog(s1);
   s1.Format(_T("Pairs \r\n"));
//   SysLog(s1);
   for (int i = 0; i < m_nProgSteps; i++) {
      int nPairTo = Progs[i].PairTo;
      if (nPairTo > 0) {
         s1.AppendFormat(_T("%d - %d  type:%d\t"), i, nPairTo, Progs[nPairTo].nOpType1);
      }
   }
   SysLog(s1);
   return 0;
}
int CMTerm1Doc::TransTxtToProg(CStringA ProgTxtA)
{
   CString s1;
   CString sProg;
   sProg = ProgTxtA;
   CStringArray txtLines;
   sProg.Replace(_T("\r\n"), _T("\n"));
   sProg.Replace(_T("\r"), _T("\n"));
   DivideStringToArray(sProg, _T("\n"), txtLines);
   TransLinesToProg(txtLines);
   return 0;
}
int CMTerm1Doc::AnnoToTxt(CStringA & AnnoTxtA)
{
   CString s1;
   CStringA s1A;
   CStringA sSectionNameA;
   GetSectionName(SectionAnno, sSectionNameA); //获取注释的文本表示
   s1A = "[" + sSectionNameA + "]\r\n";
   //循环遍历所有注释,并将其写入文件
   for (int i = 0; i < nCoilAnnoCount; i++)
   {
      if (mCoilAnnos[i].sAnno.IsEmpty()) { continue; }
      s1 = mCoilAnnos[i].sCoilName + _T("\t") + mCoilAnnos[i].sAnno + _T("\r\n");
      s1A += s1;
   }
   AnnoTxtA = s1A;
   return AnnoTxtA.GetLength();
}
int CMTerm1Doc::ReadAnnoFromTxt(CStringA AnnoTxtA)
{
   // 读取注释章节
   CString s1;
   CString sProg;
   sProg = AnnoTxtA;
   CStringArray txtLines;
   sProg.Replace(_T("\r\n"), _T("\n"));
   sProg.Replace(_T("\r"), _T("\n"));
   DivideStringToArray(sProg, _T("\n"), txtLines);
   int txtLineCount = (int)txtLines.GetSize();
   nCoilAnnoCount = 0;
   int nAnnoSectionLine = 0;
   int nAnnoStartLine = 1;
   int nAnnoLines = txtLineCount - 1;
//   int bAnnoSection = GetSectionPos(SectionAnno, &nAnnoSectionLine, &nAnnoLines);
//   if (bAnnoSection) { nAnnoStartLine = nAnnoSectionLine + 1; }
   for (int i = nAnnoStartLine; i < nAnnoStartLine + nAnnoLines; i++)
   {
      CString sLine;
      sLine = txtLines.GetAt(i);
      sLine.Trim();
      int DivPos = sLine.Find(_T("\t"));
      if (DivPos < 1) continue;
      CString sCoilName;
      sCoilName = sLine.Left(DivPos);
      sCoilName.MakeUpper();
      CString sAnno;
      sAnno = sLine.Mid(DivPos + 1);
      //      SetAnno(sCoilName, sAnno);
      CStringA s1A;
      s1A = sCoilName;
      int nParamType, nAddr;
      TxtToCoilType(s1A, &nParamType, &nAddr) || TxtToDataType(s1A, &nParamType, &nAddr);
      mCoilAnnos[nCoilAnnoCount].nType = nParamType;
      mCoilAnnos[nCoilAnnoCount].nAddr = nAddr;
      mCoilAnnos[nCoilAnnoCount].sCoilName = sCoilName;
      mCoilAnnos[nCoilAnnoCount].sAnno = sAnno;
      nCoilAnnoCount++;
   }
   return 0;
}
/// <summary>
/// 解析文件为梯形图
/// </summary>
/// <param name="ProgTxtA">文本</param>
/// <returns></returns>
int CMTerm1Doc::TransFileToProg(CStringA ProgTxtA)
{
   CString s1;
   CString sProg;
   sProg = ProgTxtA;
   CStringArray txtLines;
   sProg.Replace(_T("\r\n"), _T("\n"));
   sProg.Replace(_T("\r"), _T("\n"));
   //分割文本字符串
   DivideStringToArray(sProg, _T("\n"), txtLines);
   nSectionCount = 0;
   int nCurSection = 0;
   int txtLineCount = (int)txtLines.GetSize();
   for (int i = 0; i < txtLineCount; i++)
   {
      CString sLine;
      sLine = txtLines.GetAt(i);
      sLine.Trim();
      int nRightBracket;
      if (sLine.Find(_T("[")) == 0 && (nRightBracket = sLine.Find(_T("]"))) > 1)
      {      //找到 [ ] 标志
         if (nSectionCount > 0)
         {
            Sections[nSectionCount - 1].nLines = i - Sections[nSectionCount - 1].nSectionLineNo - 1;
            s1.Format(_T("- Line %d  Section %d Ends, %d Lines"), i, nSectionCount -1 ,Sections[nSectionCount - 1].nLines);
            SysLog(s1);
         }
         CString sSectionName;
         CStringA sSectionNameA;
         sSectionName = sLine.Mid(1, nRightBracket - 1);
         sSectionNameA = sSectionName;
         int theSection = TxtToSectionType(sSectionNameA);
         s1.Format(_T("+ Line %d  Section %d : [%s] type:%d  "), i + 1, nSectionCount, sSectionName, theSection);
         SysLog(s1);
         Sections[nSectionCount].nSectionType = theSection;
         Sections[nSectionCount].nSectionLineNo = i;
         nSectionCount++;
      }
   }
   if (nSectionCount > 0) {
      Sections[nSectionCount - 1].nLines = txtLineCount - Sections[nSectionCount - 1].nSectionLineNo - 1;
      s1.Format(_T("Section Ends at Line %d  Lines %d "), txtLineCount, Sections[nSectionCount - 1].nLines);
      SysLog(s1);
   }
   //读取程序 章节
   int nProgSectionLine = 0;
   int nProgStartLine = 0;
   int nProgLines = 0;
   int bProgSection = GetSectionPos(SectionProg, &nProgSectionLine, &nProgLines);
   if (bProgSection) { nProgStartLine = nProgSectionLine + 1; }
   else { nProgStartLine = 0; nProgLines = txtLineCount; }
   TransLinesToProg(txtLines,nProgStartLine,nProgLines);
   // 读取注释章节
   nCoilAnnoCount = 0;
   int nAnnoSectionLine = 0;
   int nAnnoStartLine = 0;
   int nAnnoLines = 0;
   int bAnnoSection = GetSectionPos(SectionAnno, &nAnnoSectionLine, &nAnnoLines);
   if (bAnnoSection)
   {
      nAnnoStartLine = nAnnoSectionLine + 1;
   }
   for (int i = nAnnoStartLine; i < nAnnoStartLine + nAnnoLines; i++)
   {
      CString sLine;
      sLine = txtLines.GetAt(i);
      sLine.Trim();
      int DivPos = sLine.Find(_T("\t"));
      if (DivPos < 1) continue;
      CString sCoilName;
      sCoilName = sLine.Left(DivPos);
      sCoilName.MakeUpper();
      CString sAnno;
      sAnno = sLine.Mid(DivPos + 1);
//      SetAnno(sCoilName, sAnno);
      CStringA s1A;
      s1A = sCoilName;
      int nParamType,nAddr;
      TxtToCoilType(s1A, &nParamType,&nAddr)
         ||TxtToDataType(s1A, &nParamType, &nAddr);
      mCoilAnnos[nCoilAnnoCount].nType = nParamType;
      mCoilAnnos[nCoilAnnoCount].nAddr = nAddr;
      mCoilAnnos[nCoilAnnoCount].sCoilName = sCoilName;
      mCoilAnnos[nCoilAnnoCount].sAnno = sAnno;
      nCoilAnnoCount++;
   }
   return 0;
}
//文本段在此处组装
int CMTerm1Doc::TransToTxt(CStringA &ProgTxt)
{
   CStringA s1, s2;
   for (int i = 0; i < m_nProgSteps; i++)
   {
      OpToTxt(Progs[i].nOpType1,s1);
      if (Progs[i].nParamCount > 0) { s1.Append("\t" + Progs[i].Params[0].sParamStr); }
      if (Progs[i].nParamCount > 1) { s1.Append("\t" + Progs[i].Params[1].sParamStr); }
      if (Progs[i].nParamCount > 2) { s1.Append("\t" + Progs[i].Params[2].sParamStr); }
      s1.Append("\r\n");
      s2 += s1;
   }
   ProgTxt = s2;
   return 0;
}
int CMTerm1Doc::TransProgToBin()
{
   CString s1;
   stBinProg15* pBinProg15;
   stBinProg2 * pBinProg2;
   stBinProg3 * pBinProg3;
   nBinProgSteps = 0;
   for (int i = 0; i < m_nProgSteps; i++)
   {
      int nOpType = Progs[i].nOpType1;
      Progs[i].nBinStep = nBinProgSteps;
      int nParamType1 = Progs[i].Params[0].nParamType;
      int nParamAddr1 = Progs[i].Params[0].nParamAddr;
      int nParamType2, nParamAddr2;
      int nParamType3, nParamAddr3;
      if (Progs[i].nParamCount > 1) {
         nParamType2 = Progs[i].Params[1].nParamType;
         nParamAddr2 = Progs[i].Params[1].nParamAddr;
      }
      if (Progs[i].nParamCount > 2) {
         nParamType3 = Progs[i].Params[2].nParamType;
         nParamAddr3 = Progs[i].Params[2].nParamAddr;
      }
      switch (nOpType)
      {
      case OP_NONE:
         break;
      //case OP_NOP:
         break;
         //无参数 指令
      case OP_END:
      case OP_NOT:
      case OP_ANS:
      case OP_ORS:
      case OP_PSHS:
      case OP_RDS:
      case OP_POPS:
      case OP_DF:
      case OP_DF_:
         BinProgs[nBinProgSteps].nOp = nOpType;
         nBinProgSteps += 1;
         break;
         // 1参数指令
      case OP_ST:
      case OP_ST_:
      case OP_AN:
      case OP_AN_:
      case OP_OR:
      case OP_OR_:
         BinProgs[nBinProgSteps].nOp = nOpType;
         BinProgs[nBinProgSteps].nParamType = nParamType1;
         BinProgs[nBinProgSteps].nParamAddr = nParamAddr1;
         nBinProgSteps += 1;
         break;
         // 1 参数 输出
      case OP_OUT:
      case OP_SET:
      case OP_RESET:
         BinProgs[nBinProgSteps].nOp = nOpType;
         BinProgs[nBinProgSteps].nParamType = nParamType1;
         BinProgs[nBinProgSteps].nParamAddr = nParamAddr1;
         nBinProgSteps += 1;
         break;
         // 比较指令
      case OP_ST_EQ:
      case OP_ST_NE:
      case OP_ST_LT:
      case OP_ST_GT:
      case OP_ST_LE:
      case OP_ST_GE:
      case OP_AN_EQ:
      case OP_AN_NE:
      case OP_AN_LT:
      case OP_AN_GT:
      case OP_AN_LE:
      case OP_AN_GE:
      case OP_OR_EQ:
      case OP_OR_NE:
      case OP_OR_LT:
      case OP_OR_GT:
      case OP_OR_LE:
      case OP_OR_GE:
         pBinProg2 = (stBinProg2 *)(&BinProgs[nBinProgSteps]);
         BinProgs[nBinProgSteps].nOp = nOpType;
         BinProgs[nBinProgSteps].nParamType = 0;
         BinProgs[nBinProgSteps].nParamAddr = nParamAddr1;
         BinProgs[nBinProgSteps+1].nOp = nParamType1;
         BinProgs[nBinProgSteps+1].nParamType = nParamType2;
         BinProgs[nBinProgSteps+1].nParamAddr = nParamAddr2;
         nBinProgSteps += 2;
         break;
         // 定时器
      case OP_TML:
      case OP_TMR:
      case OP_TMX:
      case OP_TMY:
         pBinProg15 = (stBinProg15 *)(&BinProgs[nBinProgSteps]);
         BinProgs[nBinProgSteps].nOp = nOpType;
         BinProgs[nBinProgSteps].nParamType = nParamAddr1;
         BinProgs[nBinProgSteps].nParamAddr = nParamAddr2;
         BinProgs[nBinProgSteps + 1].nOp = nParamType2;
         BinProgs[nBinProgSteps + 1].nParamType = 0;
         BinProgs[nBinProgSteps + 1].nParamAddr = 0;
         pBinProg15->nOpNum = Progs[i].Params[0].nParamAddr;
         nBinProgSteps += 2;
         break;
         // 1 参数高级指令
      case OP_INC:
      case OP_DEC:
         pBinProg15 = (stBinProg15 *)(&BinProgs[nBinProgSteps]);
         pBinProg15->nOp = nOpType;
         pBinProg15->nOpNum = 0;
         pBinProg15->nParamType1 = nParamType1;
         pBinProg15->nParamAddr1 = nParamAddr1;
         pBinProg15->resvr1 = 0;
         pBinProg15->resvr2 = 0;
         nBinProgSteps += 2;
         break;
         // 2参数高级指令
      case OP_MV:
      case OP_ADD2:
      case OP_SUB2:
         pBinProg2 = (stBinProg2 *)(&BinProgs[nBinProgSteps]);
         pBinProg2->nOp = nOpType;
         pBinProg2->nOpNum = 0;
         pBinProg2->nParamType1 = nParamType1;
         pBinProg2->nParamAddr1 = nParamAddr1;
         pBinProg2->nParamType2 = nParamType2;
         pBinProg2->nParamAddr2 = nParamAddr2;
         nBinProgSteps += 2;
         break;
         // 3 参数高级指令
      case OP_ADD3:
      case OP_SUB3:
      case OP_MUL:
      case OP_DIV:
         pBinProg3 = (stBinProg3 *)(&BinProgs[nBinProgSteps]);
         pBinProg3->nOp = nOpType;
         pBinProg3->nOpNum = 0;
         pBinProg3->nParamType1 = nParamType1;
         pBinProg3->nParamAddr1 = nParamAddr1;
         pBinProg3->nParamType2 = nParamType2;
         pBinProg3->nParamAddr2 = nParamAddr2;
         pBinProg3->nParamType3 = nParamType3;
         pBinProg3->nParamAddr3 = nParamAddr3;
         nBinProgSteps += 3;
         break;
      default:
         break;
      }
   }
   s1.Format(_T("%d steps to %d binSteps "), m_nProgSteps, nBinProgSteps);
   DbgLog(s1);
   return 0;
}
int CMTerm1Doc::TransBinToProg()
{
   CString s1;
   //nBinProgSteps = 0;
   m_nProgSteps = 0;
   stBinProg2* pBinProg2;
   stBinProg15* pBinProg15;
   stBinProg3* pBinProg3;
   CStringA s1A;
   CString s2,s3;
   CStringA s2A, s3A;
   for (int i = 0; i < nBinProgSteps; i++)
   {
      int nOpType = BinProgs[i].nOp;
      int nParamType1 = BinProgs[i].nParamType;
      int nParamAddr1 = BinProgs[i].nParamAddr;
//      int nParamType1 = Progs[i].Params[0].nParamType;
//      int nParamAddr1 = Progs[i].Params[0].nParamAddr;
      int nParamType2, nParamAddr2;
      int nParamType3, nParamAddr3;
      CoilTypeToTxt(nParamType1, s1A);
      s1.Format(_T("%S%d"), s1A, nParamAddr1);
      Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
      Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
      Progs[m_nProgSteps].Params[0].sParamStr = s1;
      switch (nOpType)
      {
      case OP_NONE:
         break;
         //case OP_NOP:
         break;
         //无参数 指令
      case OP_END:
      case OP_NOT:
      case OP_ANS:
      case OP_ORS:
      case OP_PSHS:
      case OP_RDS:
      case OP_POPS:
      case OP_DF:
      case OP_DF_:
         Progs[m_nProgSteps].nOpType1 = nOpType;
         Progs[m_nProgSteps].nParamCount = 0;
         Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
         Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
         //BinProgs[nBinProgSteps].nOp = nOpType;
         m_nProgSteps += 1;
         //nBinProgSteps += 1;
         break;
         // 1参数指令
      case OP_ST:
      case OP_ST_:
      case OP_AN:
      case OP_AN_:
      case OP_OR:
      case OP_OR_:
         Progs[m_nProgSteps].nOpType1 = nOpType;
         Progs[m_nProgSteps].nParamCount = 1;
         Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
         Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
         m_nProgSteps += 1;
         //i += 1;
         break;
         // 1 参数 输出
      case OP_OUT:
      case OP_SET:
      case OP_RESET:
         Progs[m_nProgSteps].nOpType1 = nOpType;
         Progs[m_nProgSteps].nParamCount = 1;
         Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
         Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
         m_nProgSteps += 1;
         //i += 1;
         break;
         // 比较指令
      case OP_ST_EQ:
      case OP_ST_NE:
      case OP_ST_LT:
      case OP_ST_GT:
      case OP_ST_LE:
      case OP_ST_GE:
      case OP_AN_EQ:
      case OP_AN_NE:
      case OP_AN_LT:
      case OP_AN_GT:
      case OP_AN_LE:
      case OP_AN_GE:
      case OP_OR_EQ:
      case OP_OR_NE:
      case OP_OR_LT:
      case OP_OR_GT:
      case OP_OR_LE:
      case OP_OR_GE:
         pBinProg2 = (stBinProg2*)(&BinProgs[i]);
         nParamType1 = pBinProg2->nParamType1;
         nParamAddr1 = pBinProg2->nParamAddr1;
         nParamType2 = pBinProg2->nParamType2;
         nParamAddr2 = pBinProg2->nParamAddr2;
         DataTypeToTxt(nParamType1, s1A);
         s1.Format(_T("%S%d"), s1A, nParamAddr1);
         DataTypeToTxt(nParamType2, s2A);
         s2.Format(_T("%S%d"), s2A, nParamAddr2);
         Progs[m_nProgSteps].nOpType1 = nOpType;
         Progs[m_nProgSteps].nParamCount = 2;
         Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
         Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
         Progs[m_nProgSteps].Params[0].sParamStr = s1;
         Progs[m_nProgSteps].Params[1].nParamType = nParamType2;
         Progs[m_nProgSteps].Params[1].nParamAddr = nParamAddr2;
         Progs[m_nProgSteps].Params[1].sParamStr = s2;
         m_nProgSteps += 1;
         i += 1;
         break;
         // 定时器
      case OP_TML:
      case OP_TMR:
      case OP_TMX:
      case OP_TMY:
         //pBinProg2 = (stBinProg2*)(&BinProgs[i]);
         pBinProg15 = (stBinProg15*)(&BinProgs[i]);
         nParamType1 = 0;
         nParamAddr1 = pBinProg15->nOpNum;
         nParamType2 = pBinProg15->nParamType1;
         nParamAddr2 = pBinProg15->nParamAddr1;
         //nParamAddr2 = pBinProg15->nParamAddr2;
         DataTypeToTxt(nParamType1, s1A);
         s1.Format(_T("%d"), nParamAddr1);
         DataTypeToTxt(nParamType2, s2A);
         s2.Format(_T("%S%d"), s2A, nParamAddr2);
         Progs[m_nProgSteps].nOpType1 = nOpType;
         Progs[m_nProgSteps].nParamCount = 2;
         Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
         Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
         Progs[m_nProgSteps].Params[0].sParamStr = s1;
         Progs[m_nProgSteps].Params[1].nParamType = nParamType2;
         Progs[m_nProgSteps].Params[1].nParamAddr = nParamAddr2;
         Progs[m_nProgSteps].Params[1].sParamStr = s2;
         m_nProgSteps += 1;
         i += 1;
         break;
         // 1 参数高级指令
      case OP_INC:
      case OP_DEC:
         pBinProg15 = (stBinProg15*)(&BinProgs[i]);
         nParamType1 = pBinProg15->nParamType1;
         nParamAddr1 = pBinProg15->nParamAddr1;
         DataTypeToTxt(nParamType1, s1A);
         s1.Format(_T("%S%d"), s1A, nParamAddr1);
         Progs[m_nProgSteps].nOpType1 = nOpType;
         Progs[m_nProgSteps].nParamCount = 1;
         Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
         Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
         Progs[m_nProgSteps].Params[0].sParamStr = s1;
         m_nProgSteps += 1;
         i += 1;
         break;
         // 2参数高级指令
      case OP_MV:
      case OP_ADD2:
      case OP_SUB2:
         pBinProg2 = (stBinProg2*)(&BinProgs[i]);
         nParamType1 = pBinProg2->nParamType1;
         nParamAddr1 = pBinProg2->nParamAddr1;
         nParamType2 = pBinProg2->nParamType2;
         nParamAddr2 = pBinProg2->nParamAddr2;
         DataTypeToTxt(nParamType1, s1A);
         s1.Format(_T("%S%d"), s1A, nParamAddr1);
         DataTypeToTxt(nParamType2, s2A);
         s2.Format(_T("%S%d"), s2A, nParamAddr2);
         Progs[m_nProgSteps].nOpType1 = nOpType;
         Progs[m_nProgSteps].nParamCount = 2;
         Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
         Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
         Progs[m_nProgSteps].Params[0].sParamStr = s1;
         Progs[m_nProgSteps].Params[1].nParamType = nParamType2;
         Progs[m_nProgSteps].Params[1].nParamAddr = nParamAddr2;
         Progs[m_nProgSteps].Params[1].sParamStr = s2;
         m_nProgSteps += 1;
         i += 1;
         break;
         // 3 参数高级指令
      case OP_ADD3:
      case OP_SUB3:
      case OP_MUL:
      case OP_DIV:
         pBinProg3 = (stBinProg3*)(&BinProgs[i]);
         nParamType1 = pBinProg3->nParamType1;
         nParamAddr1 = pBinProg3->nParamAddr1;
         nParamType2 = pBinProg3->nParamType2;
         nParamAddr2 = pBinProg3->nParamAddr2;
         nParamType3 = pBinProg3->nParamType3;
         nParamAddr3 = pBinProg3->nParamAddr3;
         DataTypeToTxt(nParamType1, s1A);
         s1.Format(_T("%S%d"), s1A, nParamAddr1);
         DataTypeToTxt(nParamType2, s2A);
         s2.Format(_T("%S%d"), s2A, nParamAddr2);
         DataTypeToTxt(nParamType3, s3A);
         s3.Format(_T("%S%d"), s3A, nParamAddr3);
         Progs[m_nProgSteps].nOpType1 = nOpType;
         Progs[m_nProgSteps].nParamCount = 3;
         Progs[m_nProgSteps].Params[0].nParamType = nParamType1;
         Progs[m_nProgSteps].Params[0].nParamAddr = nParamAddr1;
         Progs[m_nProgSteps].Params[0].sParamStr = s1;
         Progs[m_nProgSteps].Params[1].nParamType = nParamType2;
         Progs[m_nProgSteps].Params[1].nParamAddr = nParamAddr2;
         Progs[m_nProgSteps].Params[1].sParamStr = s2;
         Progs[m_nProgSteps].Params[2].nParamType = nParamType3;
         Progs[m_nProgSteps].Params[2].nParamAddr = nParamAddr3;
         Progs[m_nProgSteps].Params[2].sParamStr = s3;
         m_nProgSteps += 1;
         i += 2;
         break;
      default:
         break;
      }
   }
   s1.Format(_T("%d binsteps to %d Steps "), nBinProgSteps, m_nProgSteps );
   DbgLog(s1);
   return 0;
}
void CMTerm1Doc::OnUploadFromPlc()
{
   // TODO: 在此添加命令处理程序代码
   int r;
   CString s1;
   if (!m_bOnline) {
      r = Connect();
   //   theApp.MyKLink1.Open();
   }
   if (!m_bOnline) return;
   r = theApp.MyKLink1.ReadRunStat(1,0,0,32,(unsigned short *)&theApp.MyKLink1.KMRunStat);
   USHORT read;
   unsigned short buf1[4096];
   r = theApp.MyKLink1.ReadSysCfgData(1, 0, 0, sizeof(stKMSysCfg), &read, buf1);
   pstKMSysCfg pKMSysCfg = (pstKMSysCfg)buf1;
   pKMSysCfg->nProgBank;
   if (r != 0) {
      AfxMessageBox(_T("读取 PLC 信息失败"));
      return;
   }
//   AfxMessageBox(_T("UploadFrom PLC From Doc"));
   CString s2;
/*
   s2.Format(_T("Cur Programs %d \r\n"), nBinProgSteps);
   unsigned short * pBinBuf2 = (unsigned short *)BinProgs;
   for (int i = 0; i < nBinProgSteps * 2; i += 8) {
      s1.Format(_T("%03X: "), i);
      for (int j = 0; j < 8 && i+j < nBinProgSteps * 2; j++) {
         s1.AppendFormat(_T("%04X "), pBinBuf2[i + j]);
      }
      s2 += s1 + _T("\r\n");
   }
   DbgLog(s2);
*/
   int nBinSteps = pKMSysCfg->nProgSize; //theApp.MyKLink1.KMRunStat.nBinProgSize;
   s1.Format(_T("开始上载程序 大小 %d 步 "), nBinSteps);
   DbgLog(s1);
   USHORT Buf3[2048];
   s2.Empty();
   int nUploadSize = nBinSteps *2;
   int nSteps = 64;
   for (int i = 0; i < nUploadSize; i += nSteps) {
      if (i + nSteps > nUploadSize) { nSteps = nUploadSize - i; }
      s1.Format(_T("上载 %3d to %3d "), i, i + nSteps);
//      DbgLog(s1);
      int r = theApp.MyKLink1.ReadPLCProgram(1, 2, i, nSteps*2 , Buf3+i);
      s1.AppendFormat(_T(" r = %d "), r);
      DbgLog(s1);
      //Update Progress Bar
   }
/*
   s2.Format(_T(" Uploaded from bank 2 \r\n"));
   for (int i = 0; i < nBinSteps * 2; i += 8) {
      s1.Format(_T("%03X: "), i);
      for (int j = 0; j < 8 && i + j < nBinSteps * 2; j++) {
         s1.AppendFormat(_T("%04X "), Buf3[i + j]);
      }
      s2 += s1 + _T("\r\n");
   }
   DbgLog(s2);
*/
   for (int i = 0; i < nBinSteps * 2; i++)
   {
      ((USHORT *)BinProgs)[i] = Buf3[i];
   }
   nBinProgSteps = nBinSteps;
   TransBinToProg();
   FindProgPair();
   int AnnoSize = pKMSysCfg->nAnnoSize;
   if (AnnoSize > 4088) { AnnoSize = 4088; }
   s1.Format(_T("开始上载注释 大小 %d 字节"), AnnoSize);
   DbgLog(s1);
   int nBlockSize = 64;
   UCHAR buf5[4096];
   for (int i = 0; i < AnnoSize; i += nBlockSize)
   {
      if (i + nBlockSize > AnnoSize) { nBlockSize = AnnoSize - i; }
      s1.Format(_T("上载注释 %3d to %3d "), i, i + nBlockSize);
      int r = theApp.MyKLink1.ReadPLCAnno(1, 2, i, nBlockSize, buf5 + i);
      s1.AppendFormat(_T(" r = %d \r\n"), r);
//      for (int j = 0; j < nBlockSize; j++) {
//         s1.AppendFormat(_T("%02X "), buf5[i+ j]);
//      }
      DbgLog(s1);
   }
   CStringA s1A;
   char * p1 = s1A.GetBufferSetLength(4096);
   memcpy(p1, buf5, AnnoSize);
   p1[AnnoSize] = 0;
   s1A.ReleaseBuffer();
   s1 = s1A;
//   DbgLog(s1);
   ReadAnnoFromTxt(s1A);
   UpdateAllViews(NULL);
}
int CMTerm1Doc::DownloadToPLC()
{
   // TODO: 在此处添加实现代码.
   int r;
   CString s1;
   if (!m_bOnline) {
      r=Connect();
   //   theApp.MyKLink1.Open();
   }
   if (!m_bOnline) return 0;
   if (m_bPlcRunning) {
       r = AfxMessageBox(_T("PLC运行中,是否停止以便下载程序?"), MB_YESNO);
       if (r == IDYES) {   StopPLC();}
       else { return 0; }
   }
   // 下载程序
   s1.Format(_T("Start Download Program ..."));
   DbgLog(s1);
   r = theApp.MyKLink1.StartDownloadPLCProgram(1,2,nBinProgSteps * 4);
   s1.Format(_T("Result = %d"),r);
   DbgLog(s1);
   int DownloadSize = nBinProgSteps;
   int Steps = 16;
   for (int i = 0; i < DownloadSize; i += Steps) {
      //int Steps = 16;
      if (i + Steps > DownloadSize) { Steps = DownloadSize - i; }
      int n = 0;
      do {
         s1.Format(_T("Downloading %d to %d "), i, i + Steps);
         DbgLog(s1);
         r = theApp.MyKLink1.DownloadPLCProgram(1, 2, (i) * 4, Steps * 4, (USHORT*)&BinProgs[i]);
         s1.Format(_T("Download r = %d "), r);
         DbgLog(s1);
         n += 1;
         if (n > 10) break;
      } while (r != 0);
      //Update Progress Bar
   }
   s1.Format(_T("Finish Downloading "));
   DbgLog(s1);
   r = theApp.MyKLink1.FinishDownloadPLCProgram(1,2,nBinProgSteps);
   s1.Format(_T("Download Finished  r = %d "), r);
   DbgLog(s1);
   // 下载注释
   CStringA AnnoTxtA;
   int len3 = AnnoToTxt(AnnoTxtA);
   unsigned char buf1[4096];
   if (len3 > 4088) { len3 = 4088; }
   memcpy(buf1, AnnoTxtA.GetBuffer(), len3);
   AnnoTxtA.ReleaseBuffer();
   s1.Format(_T("开始下载注释 ... %d bytes "),len3);
   DbgLog(s1);
   s1 = AnnoTxtA;
   DbgLog(s1);
   r = theApp.MyKLink1.StartDownloadPLCAnno(1, 1, len3);
   int nBlockSize = 64;
   for (int i = 0; i < len3; i += nBlockSize) {
      if (i + nBlockSize > len3) { nBlockSize = len3 - i; }
      s1.Format(_T("Downloading %d to %d "), i, i + nBlockSize);
      DbgLog(s1);
      r = theApp.MyKLink1.DownloadPLCAnno(1, 1,i,nBlockSize,buf1+i);
      s1.Format(_T("Download r = %d "), r);
      DbgLog(s1);
   }
   s1.Format(_T("Finish Downloading 注释"));
   DbgLog(s1);
   r = theApp.MyKLink1.FinishDownloadPLCAnno(1, 1, len3);
   s1.Format(_T("Download Finished  r = %d "), r);
   DbgLog(s1);
   // 下载系统寄存器配置
   //启动运行
   r = AfxMessageBox(_T("程序下载完成,是否启动运行?"), MB_YESNO);
   if (r == IDYES) { StartPLC(); }
   else { return 0; }
   return 0;
}
void CMTerm1Doc::OnDownloadToPlc()
{
   // TODO: 在此添加命令处理程序代码
   DownloadToPLC();
}
void CMTerm1Doc::OnUpdateDownloadToPlc(CCmdUI *pCmdUI)
{
   // TODO: 在此添加命令更新用户界面处理程序代码
}
void CMTerm1Doc::OnOnline()
{
   // TODO: 在此添加命令处理程序代码
   int r;
   if (!m_bOnline)
   {
      r = Connect();
      //theApp.MyKLink1.Open();
   }
   if (!m_bOnline) return;
//   m_bOnline = true;
   UpdateAllViews(NULL, UpdataHint::UpdateStat);
}
void CMTerm1Doc::OnUpdateOnline(CCmdUI *pCmdUI)
{
   // TODO: 在此添加命令更新用户界面处理程序代码
   pCmdUI->SetCheck(m_bOnline == true);
}
void CMTerm1Doc::OnOffline()
{
   // TODO: 在此添加命令处理程序代码
   int r;
   if (m_bOnline)
   {
      r = DisConnect();
      theApp.MyKLink1.Close();
   }
   m_bPlcRunning = false;
   m_bOnline = false;
   UpdateAllViews(NULL, UpdataHint::UpdateStat);
}
void CMTerm1Doc::OnUpdateOffline(CCmdUI *pCmdUI)
{
   // TODO: 在此添加命令更新用户界面处理程序代码
   pCmdUI->SetCheck(m_bOnline == false);
//   pCmdUI->SetCheck(false);
}
void CMTerm1Doc::OnUpdateSimulate(CCmdUI* pCmdUI)
{
   // TODO: 在此添加命令更新用户界面处理程序代码
   pCmdUI->SetCheck(m_bSimulate == true);
}
void CMTerm1Doc::OnUpdatePlcRun(CCmdUI* pCmdUI)
{
   // TODO: 在此添加命令更新用户界面处理程序代码
   pCmdUI->SetCheck(m_bPlcRunning == true);
   if (!m_bPlcRunning)    pCmdUI->SetText(_T("PLC模式[PROG]"));
   else    pCmdUI->SetText(_T("PLC模式[RUN]"));
}
void CMTerm1Doc::OnSimulate()
{
   // TODO: 在此添加命令处理程序代码
   CString s1;
   unsigned short* p1 = (unsigned short *)&BinProgs;
   if (!m_bSimulate) {
      s1.Format(_T("启动PLC模拟\r\n"));
      SysLog(s1);
      m_bSimulate = true;
      s1.Empty();
      for (int i = 0; i < nBinProgSteps; i++) {
         s1.AppendFormat(_T("%04X %04X "), p1[i*2],p1[i*2+1]);
      }
      SysLog(s1);
      s1.Format(_T("Download %d program to sim PLC"),nBinProgSteps);
      SysLog(s1);
      myKMachine1.Download(BinProgs, nBinProgSteps);
      m_bOnline = true;
      myKMachine1.StartPLC();
      s1.Format(_T("Start sim PLC"));
      SysLog(s1);
      StartPLC();
   }
   else {
      StopPLC();
      m_bSimulate = false;
      m_bOnline = false;
   }
   UpdateAllViews(NULL, UpdataHint::UpdateStat);
}
int CMTerm1Doc::StartPLC()
{
   // TODO: 在此处添加实现代码.
   if (m_bSimulate) {
      for (int i = 0; i < KLDataWXCount; i++) {
         KMem.WX[i] = 0;
      }
      for (int i = 0; i < KLDataWYCount; i++) {
         KMem.WY[i] = 0;
      }
      for (int i = 0; i < KLDataWRCount; i++) {
         KMem.WR[i] = 0;
      }
      for (int i = 0; i < KLDataDTCount; i++) {
         KMem.DT[i] = 0;
      }
      for (int i = 0; i < TOTALTIMERS; i++) {
         KMem.Timers[i] = { 0 };
      }
      myKMachine1.nScanCount = 0;
      nScanCount = 0;
      m_bPlcRunning = 1;
   }else {
      theApp.MyKLink1.ChangeMode(1, 1);
      m_bPlcRunning = 1;
   }
   return 0;
}
int CMTerm1Doc::StopPLC()
{
   // TODO: 在此处添加实现代码.
   if (m_bSimulate) {
      m_bPlcRunning = false;
   }
   else {
      theApp.MyKLink1.ChangeMode(1, 0);
      m_bPlcRunning = false;
   }
   return 0;
}
void CMTerm1Doc::OnPlcRun()
{
   // TODO: 在此添加命令处理程序代码
   if (m_bPlcRunning) { StopPLC(); }
   else
   {
      StartPLC();
   }
   UpdateAllViews(NULL, UpdataHint::UpdateStat);
}
int CMTerm1Doc::SetCommParam()
{
   // TODO: 在此处添加实现代码.
   CString s1;
   s1.Format(_T("Doc SetupComm"));
   SysLog(s1);
   theApp.MyKLink1.SetCommParam();
   return 0;
/*
   CDialogCommSet1 dialog1;
   INT_PTR r = dialog1.DoModal();
   if (r == IDOK )
   {
      nComPort=dialog1.m_nComNum;
      nBaud=dialog1.m_nBaudRate;
      ComSettings=dialog1.m_Settings;
      s1.Format(_T("dialog return port %d baud %d setting %S"),
         nComPort, nBaud, ComSettings);
      SysLog(s1);
      m_bCommParamSet = true;
   }
   else
   {
      return -1;
   }
   return 0;
*/
}
int CMTerm1Doc::Connect()
{
   // TODO: 在此处添加实现代码.
   CString s1;
   unsigned short buf1[32];
   int res = theApp.MyKLink1.Connect();
   unsigned short len1;
   int j=theApp.MyKLink1.GetInfo(1, &len1, buf1);
   s1.Format(_T("GetInfo = %d %d \r\n"), j,len1);
   if (j==0 && len1 > 0) {
      for (int i = 0; i < len1/2; i++) {
         s1.AppendFormat(_T("%04X "), buf1[i]);
      }
      s1 += _T("\r\n");
      pKMInfoBlock pinfob = (pKMInfoBlock)buf1;
      s1.AppendFormat(_T(" DeviceType %04X \t "),pinfob->nDeviceTypeVer);
      s1.AppendFormat(_T(" nProgVer %04X \r\n"), pinfob->nProgVer);
      s1.AppendFormat(_T(" nKLinkVer %04X \t"), pinfob->nKLinkVer);
      s1.AppendFormat(_T(" nKBusVer %04X \r\n"), pinfob->nKBusVer);
      s1.AppendFormat(_T(" nCapacity1 %d k \t"), pinfob->nCapacity1);
      s1.AppendFormat(_T(" nCapacity2 %d k\r\n"), pinfob->nCapacity2);
      s1.AppendFormat(_T(" nDInput %d \t"), pinfob->nDInput);
      s1.AppendFormat(_T(" nDOutput %d \r\n"), pinfob->nDOutput);
      s1.AppendFormat(_T(" nAInput %d \t"), pinfob->nAInput);
      s1.AppendFormat(_T(" nAOutput %d \r\n"), pinfob->nAOutput);
      s1.AppendFormat(_T(" nHInput %d   \t"), pinfob->nHInput);
      s1.AppendFormat(_T(" nHOutput %d \r\n"), pinfob->nHOutput);
      s1.AppendFormat(_T(" nExt1 %d \t"), pinfob->nExt1);
      s1.AppendFormat(_T(" nExt2 %d \r\n"), pinfob->nExt2);
      s1.AppendFormat(_T(" nLogSize %d \r\n"), pinfob->nLogSize);
      s1.AppendFormat(_T(" nPorts %d \r\n"), pinfob->nPorts);
      s1.AppendFormat(_T(" nManSize %d \r\n"), pinfob->nManSize);
      s1.AppendFormat(_T(" nAbility %d \r\n"), pinfob->nAbility);
      s1.AppendFormat(_T(" nSwitchBits %d \r\n"), pinfob->nSwitchBits);
   }
   SysLog(s1);
   int r = theApp.MyKLink1.ReadRunStat(1, 0, 0, 32, (unsigned short*)&theApp.MyKLink1.KMRunStat);
   s1.Format(_T("GetRunStat = %d %d \r\n"), r, 32);
   KLink1::stRunStat RunStat1 = theApp.MyKLink1.KMRunStat;
   s1.AppendFormat(_T(" Sign1 %04X \t"), RunStat1.Sign1);
   s1.AppendFormat(_T(" Seq1 %d \r\n"), RunStat1.Seq1);
   s1.AppendFormat(_T(" PowerCount %d \r\n"), RunStat1.PowerCount);
   s1.AppendFormat(_T(" Reserved1 %d \r\n"), RunStat1.Reserved1);
   s1.AppendFormat(_T(" UpTime %d \r\n"), RunStat1.UpTime);
   s1.AppendFormat(_T(" UserData1 %d \r\n"), RunStat1.UserData1);
   s1.AppendFormat(_T(" WorkMode %d \t"), RunStat1.WorkMode);
   s1.AppendFormat(_T(" WorkMode2 %d \r\n"), RunStat1.WorkMode2);
   s1.AppendFormat(_T(" nBinProgBank %d \t"), RunStat1.nBinProgBank);
   s1.AppendFormat(_T(" nBinProgSize %d \r\n"), RunStat1.nBinProgSize);
   s1.AppendFormat(_T(" bLEDFlick %d \r\n"), RunStat1.bLEDFlick);
   s1.AppendFormat(_T(" Reserved2 %d \r\n"), RunStat1.Reserved2);
   s1.AppendFormat(_T(" CRC1 %04X \r\n"), RunStat1.CRC1);
   s1.AppendFormat(_T(" EndSign1 %04X \r\n"), RunStat1.EndSign1);
   SysLog(s1);
   unsigned char value;
   r = theApp.MyKLink1.GetMode(1, 0, &value);
   if (r == KLink1::KL_OK) { m_bPlcRunning = value; }
   s1.Format(_T("PLC Mode = %d"), value);
   SysLog(s1);
//   m_static_connect.SetCtlColor(RGB(0, 255, 0));
/*
   if (!m_bCommParamSet)
   {
      if (SetCommParam()) return -1;
   }
   if (m_bOnline) return 0;
   myHvSerialPort1.m_nPort = nComPort;
   myHvSerialPort1.m_nBaudRate = nBaud;
   myHvSerialPort1.m_Settings = "8,N,1";
   int r = myHvSerialPort1.Open();
   s1.Format(_T("Open %s  = %d"), myHvSerialPort1.m_strResult, r);
   SysLog(s1);
   if (r == myHvSerialPort1.R_OK)
   {
      m_bOnline = true;
//      theApp.MyKLink1.Open();
//      m_static_connect.SetCtlColor(RGB(0, 255, 0));
      return 0;
   }
*/
   m_bOnline = true;
   return 0;
}
int CMTerm1Doc::DisConnect()
{
   // TODO: 在此处添加实现代码.
   if (!m_bOnline) return -1;
//   myHvSerialPort1.Close();
   theApp.MyKLink1.Close();
   m_bOnline = false;
   m_bPlcRunning = false;
   return 0;
}
void CMTerm1Doc::OnComunicationSet()
{
   // TODO: 在此添加命令处理程序代码
   SetCommParam();
}
void CMTerm1Doc::OnPlcSysregSet()
{
   // TODO: 在此添加命令处理程序代码
   CDialogSysRegSet dialog1;
   INT_PTR r = dialog1.DoModal();
   if (r == IDOK)
   {
   }
}
void CMTerm1Doc::OnMenuFactCfg()
{
   // TODO: 在此添加命令处理程序代码
   CDialogFactCfg dialog1;
   INT_PTR r = dialog1.DoModal();
   if (r == IDOK)
   {
   }
}
CView * CMTerm1Doc::FindView(CRuntimeClass * pClass)
{
   CView* pView=NULL;
   POSITION pos = GetFirstViewPosition();
   while (pos != NULL)
   {
      pView = GetNextView(pos);
      if (pView->IsKindOf(pClass))
         break;
   }
   if (!pView->IsKindOf(pClass))
   {
      //AfxMessageBox("Connt Locate the View.");
      return NULL;
   }
   return pView;
}
///*
void CMTerm1Doc::OnMenuViewLds()
{
   // TODO: 在此添加命令处理程序代码
   CString s1;
   CView * pView;
   pView = FindView(RUNTIME_CLASS(CMTerm1View));
   if (pView != NULL) {
      ((CMDIFrameWndEx *)AfxGetMainWnd())->MDIActivate(pView->GetParent());
//      pView->SetActiveWindow();
   }
   else {
      s1 = GetTitle();
      //AfxMessageBox(s1);
      ASSERT_VALID(theApp.pDocTemplate);
      CFrameWnd * pFrame = theApp.pDocTemplate->CreateNewFrame(this, NULL);
      ASSERT_KINDOF(CFrameWnd, pFrame);
      theApp.pDocTemplate->InitialUpdateFrame(pFrame, this);
   }
}
void CMTerm1Doc::OnMenuViewBld()
{
   // TODO: 在此添加命令处理程序代码
   CString s1;
   CView * pView;
   pView = FindView(RUNTIME_CLASS(CMTerm1BldView));
   if (pView != NULL) {
      ((CMDIFrameWndEx *)AfxGetMainWnd())->MDIActivate(pView->GetParent());
//      pView->SetActiveWindow();
   }
   else {
      s1 = GetTitle();
      //AfxMessageBox(s1);
      ASSERT_VALID(theApp.m_pBldViewTemplate);
      CFrameWnd * pFrame = theApp.m_pBldViewTemplate->CreateNewFrame(this, NULL);
      ASSERT_KINDOF(CFrameWnd, pFrame);
      theApp.m_pBldViewTemplate->InitialUpdateFrame(pFrame, this);
   }
}
void CMTerm1Doc::OnMenuViewBnl()
{
   // TODO: 在此添加命令处理程序代码
   CString s1;
   CView * pView;
   pView = FindView(RUNTIME_CLASS(CMTerm1BnlView));
   if (pView != NULL) {
      ((CMDIFrameWndEx *)AfxGetMainWnd())->MDIActivate(pView->GetParent());
//      pView->SetActiveWindow();
   }
   else {
      s1 = GetTitle();
      //AfxMessageBox(s1);
      ASSERT_VALID(theApp.m_pBnlViewTemplate);
      CFrameWnd * pFrame = theApp.m_pBnlViewTemplate->CreateNewFrame(this, NULL);
      ASSERT_KINDOF(CFrameWnd, pFrame);
      theApp.m_pBnlViewTemplate->InitialUpdateFrame(pFrame, this);
   }
}
//*/
void CMTerm1Doc::OnMenuShowConsole()
{
   // TODO: 在此添加命令处理程序代码
   CString s1;
   CView * pView;
   pView = FindView(RUNTIME_CLASS(CMTerm1CtrlView));
   if (pView != NULL) {
      ((CMDIFrameWndEx *)AfxGetMainWnd())->MDIActivate(pView->GetParent());
//      pView->SetActiveWindow();
   }
   else {
      s1 = GetTitle();
      //AfxMessageBox(s1);
      ASSERT_VALID(theApp.m_pCtrlViewTemplate);
      CFrameWnd * pFrame = theApp.m_pCtrlViewTemplate->CreateNewFrame(this, NULL);
      ASSERT_KINDOF(CFrameWnd, pFrame);
       theApp.m_pCtrlViewTemplate->InitialUpdateFrame(pFrame, this);
   }
}
void CMTerm1Doc::OnMenuCommTest()
{
   // TODO: 在此添加命令处理程序代码
/*
   CString s1;
   CView * pView;
   pView = FindView(RUNTIME_CLASS(CMTerm1CommDevView));
   if (pView != NULL) {
      ((CMDIFrameWndEx *)AfxGetMainWnd())->MDIActivate(pView->GetParent());
      //      pView->SetActiveWindow();
   }
   else {
      s1 = GetTitle();
      //AfxMessageBox(s1);
      ASSERT_VALID(theApp.m_pCommDevViewTemplate);
      CFrameWnd * pFrame = theApp.m_pCommDevViewTemplate->CreateNewFrame(this, NULL);
      ASSERT_KINDOF(CFrameWnd, pFrame);
      theApp.m_pCommDevViewTemplate->InitialUpdateFrame(pFrame, this);
   }
*/
}
const unsigned short bitMasks[16] =
{
   0x1 << 0,   0x1 << 1,   0x1 << 2,   0x1 << 3,   0x1 << 4,   0x1 << 5,   0x1 << 6,   0x1 << 7,
   0x1 << 8,   0x1 << 9,   0x1 << 10,   0x1 << 11,   0x1 << 12,   0x1 << 13,   0x1 << 14,   0x1 << 15,
};
inline void SetAddrBit(unsigned short * pW, unsigned char bitAddr)
{
   (*pW) |= bitMasks[bitAddr & 0xf];
}
inline void ResetBit(unsigned short * pW, unsigned char bitAddr)
{
   (*pW) &= ~bitMasks[bitAddr & 0xf];
}
static inline void SetBitValue(unsigned short * pW, unsigned char bitAddr, unsigned char Value)
{
   if (Value) { SetAddrBit(pW, bitAddr); }
   else { ResetBit(pW, bitAddr); }
}
static inline unsigned char GetBitValue(unsigned short W, unsigned char bitAddr)
{
   if (W&bitMasks[bitAddr & 0xf]) return 1;
   else return 0;
}
int CMTerm1Doc::GetCoilValue(int nCoilType, int nCoilAddr)
{
   // TODO: 在此处添加实现代码.
   if (m_bOnline && 0)
   {
      unsigned char value = 0;
      theApp.MyKLink1.ReadBit(1, nCoilType, nCoilAddr, &value);
      return value;
   }
   int nWordAddr = nCoilAddr >> 4;
   int nBitAddr = nCoilAddr & 0x0F;
   switch (nCoilType)
   {
   case KLCoilTypeX:
      if (nCoilAddr >= KLCoilXCount) return 0;
      return GetBitValue(KMem.WX[nWordAddr], nBitAddr);
      break;
   case KLCoilTypeY:
      if (nCoilAddr >= KLCoilYCount) return 0;
      return GetBitValue(KMem.WY[nWordAddr], nBitAddr);
      break;
   case KLCoilTypeR:
      if (nCoilAddr >= KLCoilRCount) return 0;
      return GetBitValue(KMem.WR[nWordAddr], nBitAddr);
      break;
   case KLCoilTypeLX:
      if (nCoilAddr >= KLCoilLXCount) return 0;
      return GetBitValue(KMem.WLX[nWordAddr], nBitAddr);
      break;
   case KLCoilTypeLY:
      if (nCoilAddr >= KLCoilLYCount) return 0;
      return GetBitValue(KMem.WLY[nWordAddr], nBitAddr);
      break;
   case KLCoilTypeT:
      if (nCoilAddr >= KLCoilTCount) return 0;
      return GetBitValue(KMem.WT[nWordAddr], nBitAddr);
      break;
   case KLCoilTypeC:
      if (nCoilAddr >= KLCoilCCount) return 0;
      return GetBitValue(KMem.WC[nWordAddr], nBitAddr);
      break;
   case KLCoilTypeLR:
      if (nCoilAddr >= KLCoilLRCount) return 0;
      return GetBitValue(KMem.WLR[nWordAddr], nBitAddr);
      break;
   case KLCoilTypeSR:
      if (nCoilAddr >= KLCoilSRCount) return 0;
      return GetBitValue(KMem.WSR[nWordAddr], nBitAddr);
      break;
   }
   return 0;
}
int CMTerm1Doc::SetCoilValue(int nCoilType, int nCoilAddr, int nCoilValue)
{
   // TODO: 在此处添加实现代码.
   if (m_bSimulate) {
      return myKMachine1.SetCoilValue(nCoilType, nCoilAddr, nCoilValue);
   }else
   if (m_bOnline)
   {
      unsigned char value =nCoilValue;
      int res = 0;
      res = theApp.MyKLink1.WriteBit(1, nCoilType, nCoilAddr, value);
      return res;
   }
   int nWordAddr = nCoilAddr >> 4;
   int nBitAddr = nCoilAddr & 0x0F;
   switch (nCoilType)
   {
   case KLCoilTypeX:
      if (nCoilAddr >= KLCoilXCount) return 0;
      SetBitValue(&KMem.WX[nWordAddr], nBitAddr, nCoilValue);
      break;
   case KLCoilTypeY:
      if (nCoilAddr >= KLCoilYCount) return 0;
      SetBitValue(&KMem.WY[nWordAddr], nBitAddr, nCoilValue);
      break;
   case KLCoilTypeR:
      if (nCoilAddr >= KLCoilRCount) return 0;
      SetBitValue(&KMem.WR[nWordAddr], nBitAddr, nCoilValue);
      break;
   case KLCoilTypeLX:
      if (nCoilAddr >= KLCoilLXCount) return 0;
      SetBitValue(&KMem.WLX[nWordAddr], nBitAddr, nCoilValue);
      break;
   case KLCoilTypeLY:
      if (nCoilAddr >= KLCoilLYCount) return 0;
      SetBitValue(&KMem.WLY[nWordAddr], nBitAddr, nCoilValue);
      break;
   case KLCoilTypeT:
      if (nCoilAddr >= KLCoilTCount) return 0;
      SetBitValue(&KMem.WT[nWordAddr], nBitAddr, nCoilValue);
      break;
   case KLCoilTypeC:
      if (nCoilAddr >= KLCoilCCount) return 0;
      SetBitValue(&KMem.WC[nWordAddr], nBitAddr, nCoilValue);
      break;
   case KLCoilTypeLR:
      if (nCoilAddr >= KLCoilLRCount) return 0;
      SetBitValue(&KMem.WLR[nWordAddr], nBitAddr, nCoilValue);
      break;
   case KLCoilTypeSR:
      if (nCoilAddr >= KLCoilSRCount) return 0;
      SetBitValue(&KMem.WSR[nWordAddr], nBitAddr, nCoilValue);
      break;
   }
   if (m_bOnline)
   {
//      theApp.MyKLink1.WriteBit(1, nCoilType, nCoilAddr, nCoilValue);
   }
   return 0;
}
int CMTerm1Doc::GetVarData(int nDataType, int nDataAddr)
{
   // TODO: 在此处添加实现代码.
   unsigned short nCount;
   if (m_bOnline && 0)
   {
      unsigned short value[20];
      unsigned short svalue = 0;
      if (nDataType == KLDataTypeDEC || nDataType == KLDataTypeHEX){
         return nDataAddr;
      }
      theApp.MyKLink1.ReadDataWord(1,  nDataType, nDataAddr, 2, &nCount, value);// (unsigned char *)&KMem.DT[nDataAddr]);
      svalue = value[0];
      return svalue;
   }
   switch (nDataType)
   {
   case KLDataTypeDEC:
   case KLDataTypeHEX:
      return nDataAddr;
      break;
   case KLDataTypeWX:
      if (nDataAddr >= KLDataWXCount) return 0;
      return KMem.WX[nDataAddr];
      break;
   case KLDataTypeWY:
      if (nDataAddr >= KLDataWYCount) return 0;
      return KMem.WY[nDataAddr];
      break;
   case KLDataTypeWR:
      if (nDataAddr >= KLDataWRCount) return 0;
      return KMem.WR[nDataAddr];
      break;
   case KLDataTypeWLX:
      if (nDataAddr >= KLDataWLCount) return 0;
      return KMem.WLX[nDataAddr];
      break;
   case KLDataTypeWLY:
      if (nDataAddr >= KLDataWLCount) return 0;
      return KMem.WLY[nDataAddr];
      break;
   case KLDataTypeDT:
      if (nDataAddr >= KLDataDTCount) return 0;
      return (signed short)KMem.DT[nDataAddr];
      break;
   case KLDataTypeSDT:
      if (nDataAddr >= KLDataSDTCount) return 0;
      return KMem.SDT[nDataAddr];
      break;
   case KLDataTypeWSR:
      if (nDataAddr >= KLCoilLRCount) return 0;
      return KMem.WSR[nDataAddr];
      break;
   case KLDataTypeSV:
      if (nDataAddr >= KLDataSVCount) return 0;
      return KMem.SV[nDataAddr];
      break;
   case KLDataTypeEV:
      if (nDataAddr >= KLDataEVCount) return 0;
      return KMem.EV[nDataAddr];
      break;
   case KLDataTypeLD:
      if (nDataAddr >= KLDataLDCount) return 0;
      return KMem.DT[nDataAddr];
      break;
   case KLDataSysCfg:
      if (nDataAddr >= KLCoilSRCount) return 0;
      return KMem.SDT[nDataAddr];
      break;
   case KLDataTypeFlash:
      if (nDataAddr >= KLCoilSRCount) return 0;
      return KMem.SDT[nDataAddr];
      break;
   case KLDataTypeTest:
      if (nDataAddr >= KLCoilSRCount) return 0;
      return KMem.SDT[nDataAddr];
      break;
   }
   return 0;
}
int CMTerm1Doc::SetVarData(int nDataType, int nDataAddr, int nDataValue)
{
   // TODO: 在此处添加实现代码.
   if (m_bSimulate) {
      return myKMachine1.SetVarData(nDataType, nDataAddr, nDataValue);
   }else
   if (m_bOnline)
   {
//      unsigned char value[20];
      unsigned short svalue[10];
      svalue[0]=nDataValue;
      int res = 0;
      res = theApp.MyKLink1.WriteDataWord(1, nDataType, nDataAddr, 2, svalue);
      return res;
   }
   switch (nDataType)
   {
//   case KLDataTypeDEC:
//   case KLDataTypeHEX:
//      break;
   case KLDataTypeWX:
      if (nDataAddr >= KLDataWXCount) return 0;
      KMem.WX[nDataAddr] = nDataValue;
      break;
   case KLDataTypeWY:
      if (nDataAddr >= KLDataWYCount) return 0;
      KMem.WY[nDataAddr] = nDataValue;
      break;
   case KLDataTypeWR:
      if (nDataAddr >= KLDataWRCount) return 0;
      KMem.WR[nDataAddr] = nDataValue;
      break;
   case KLDataTypeWLX:
      if (nDataAddr >= KLDataWLCount) return 0;
      KMem.WLX[nDataAddr] = nDataValue;
      break;
   case KLDataTypeWLY:
      if (nDataAddr >= KLDataWLCount) return 0;
      KMem.WLY[nDataAddr] = nDataValue;
      break;
   case KLDataTypeDT:
      if (nDataAddr >= KLDataDTCount) return 0;
      KMem.DT[nDataAddr] = nDataValue;
      break;
   case KLDataTypeSDT:
      if (nDataAddr >= KLDataSDTCount) return 0;
      KMem.SDT[nDataAddr] = nDataValue;
      break;
   case KLDataTypeWSR:
      if (nDataAddr >= KLCoilLRCount) return 0;
      KMem.WSR[nDataAddr] = nDataValue;
      break;
   case KLDataTypeSV:
      if (nDataAddr >= KLDataSVCount) return 0;
      KMem.SV[nDataAddr] = nDataValue;
      break;
   case KLDataTypeEV:
      if (nDataAddr >= KLDataEVCount) return 0;
      KMem.EV[nDataAddr] = nDataValue;
      break;
   case KLDataTypeLD:
      if (nDataAddr >= KLDataLDCount) return 0;
      KMem.DT[nDataAddr] = nDataValue;
      break;
   case KLDataSysCfg:
      if (nDataAddr >= KLCoilSRCount) return 0;
      KMem.SDT[nDataAddr] = nDataValue;
      break;
   case KLDataTypeFlash:
      if (nDataAddr >= KLCoilSRCount) return 0;
      KMem.SDT[nDataAddr] = nDataValue;
      break;
   case KLDataTypeTest:
      if (nDataAddr >= KLCoilSRCount) return 0;
      KMem.SDT[nDataAddr] = nDataValue;
      break;
   }
   return 0;
}
int CMTerm1Doc::AddMonitorCoil(int nCoilType, int nCoilAddr, int nCount)
{
   // TODO: 在此处添加实现代码.
   return 0;
}
int CMTerm1Doc::AddMonitorData(int nDataType, int nDataAddr, int nDataCount)
{
   // TODO: 在此处添加实现代码.
   return 0;
}
int CMTerm1Doc::ClearMonitor()
{
   // TODO: 在此处添加实现代码.
   return 0;
}
int CMTerm1Doc::DoPLCMonitor()
{
   // TODO: 在此处添加实现代码.
   CString s1;
   if (m_bSimulate) {
      int nDataType = theApp.MyKLink1.KLDataTypeWX;
      int nDataAddr = 0;
      int nDataCount = 4;
//      int res;
      for (int i = 0; i < nDataCount; i++) {
         KMem.WX[i] = myKMachine1.KMem.WX[i];
      }
      nDataType = theApp.MyKLink1.KLDataTypeWY;
      nDataAddr = 0;
      nDataCount = 4;
      for (int i = 0; i < nDataCount; i++) {
         KMem.WY[i] = myKMachine1.KMem.WY[i];
      }
      nDataType = theApp.MyKLink1.KLDataTypeWLX;
      nDataAddr = 0;
      nDataCount = 4;
      for (int i = 0; i < nDataCount; i++) {
         KMem.WLX[i] = myKMachine1.KMem.WLX[i];
      }
      nDataType = theApp.MyKLink1.KLDataTypeWLY;
      nDataAddr = 0;
      nDataCount = 4;
      for (int i = 0; i < nDataCount; i++) {
         KMem.WLY[i] = myKMachine1.KMem.WLY[i];
      }
      nDataType = theApp.MyKLink1.KLDataTypeWR;
      nDataAddr = 0;
      nDataCount = 10;
      for (int i = 0; i < nDataCount; i++) {
         KMem.WR[i] = myKMachine1.KMem.WR[i];
      }
      nDataType = theApp.MyKLink1.KLDataTypeDT;
      nDataAddr = 0;
      nDataCount = 128;
      for (int i = 0; i < nDataCount; i++) {
         KMem.DT[i] = myKMachine1.KMem.DT[i];
      }
      nDataType = theApp.MyKLink1.KLDataTypeSV;
      nDataAddr = 0;
      nDataCount = 40;
      for (int i = 0; i < nDataCount; i++) {
         KMem.SV[i] = myKMachine1.KMem.SV[i];
      }
      //res = theApp.MyKLink1.ReadDataWord(1, nDataCount, nDataType, nDataAddr, KMem.SV);// (unsigned char *)&KMem.DT[nDataAddr]);
      nDataType = theApp.MyKLink1.KLDataTypeEV;
      nDataAddr = 0;
      nDataCount = 40;
      for (int i = 0; i < nDataCount; i++) {
         KMem.EV[i] = myKMachine1.KMem.EV[i];
      }
//      res = theApp.MyKLink1.ReadDataWord(1, nDataCount, nDataType, nDataAddr, KMem.EV);// (unsigned char *)&KMem.DT[nDataAddr]);
   }else if (m_bOnline)
   {
      if (theApp.MyKLink1.m_nContinueErrCount > 10) {
         DisConnect();
      }
      int nDataType = theApp.MyKLink1.KLDataTypeWX;
      int nDataAddr = 0;
      int nDataCount = 16;
      unsigned short nCount;
      int res;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.WX);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataType = theApp.MyKLink1.KLDataTypeWY;
      nDataAddr = 0;
      nDataCount = 16;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.WY);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataType = theApp.MyKLink1.KLDataTypeWLX;
      nDataAddr = 0;
      nDataCount = 8;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.WLX);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataType = theApp.MyKLink1.KLDataTypeWLY;
      nDataAddr = 0;
      nDataCount = 8;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.WLY);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataType = theApp.MyKLink1.KLDataTypeWR;
      nDataAddr = 0;
      nDataCount = 16;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.WR);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataType = theApp.MyKLink1.KLDataTypeWSR;
      nDataAddr = 0;
      nDataCount = 10;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.WSR);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataType = theApp.MyKLink1.KLDataTypeDT;
      nDataAddr = 0;
      nDataCount = 64;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.DT);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataAddr = 64;
      nDataCount = 64;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, &KMem.DT[64]);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataType = theApp.MyKLink1.KLDataTypeSV;
      nDataAddr = 0;
      nDataCount = 64;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.SV);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
      nDataType = theApp.MyKLink1.KLDataTypeEV;
      nDataAddr = 0;
      nDataCount = 64;
      res = theApp.MyKLink1.ReadDataWord(1, nDataType, nDataAddr, nDataCount, &nCount, KMem.EV);// (unsigned char *)&KMem.DT[nDataAddr]);
      if (res != theApp.MyKLink1.KL_OK) {
         s1.Format(_T("R:= %d %s  \r\n"), res, theApp.MyKLink1.m_resultStr);
         SysLog(s1);
      }
   }
   return 0;
}
void CMTerm1Doc::OnTimer(UINT_PTR nIDEvent)
{
   CString s1;
//   s1.Format(_T("Doc::OntTimer"));
//   SysLog(s1);
   if (m_bSimulate && m_bPlcRunning)
   {
      //ProcessPLCProg(Progs, m_nProgSteps);
      myKMachine1.ProcPLC();
      // update PLC Stat
   }
}
void CMTerm1Doc::OnMenuStatusShow()
{
   // TODO: 在此添加命令处理程序代码
   CDialogStatusShow dialog1;
   INT_PTR r = dialog1.DoModal();
   if (r == IDOK)
   {
   }
}
void CMTerm1Doc::OnMenuDatetimeSet()
{
   // TODO: 在此添加命令处理程序代码
   CDialogDateTime dialog1;
   INT_PTR r = dialog1.DoModal();
   if (r == IDOK)
   {
   }
}
void CMTerm1Doc::OnMenuEventLog()
{
   // TODO: 在此添加命令处理程序代码
   CDialogEventLog dialog1;
   INT_PTR r = dialog1.DoModal();
   if (r == IDOK)
   {
   }
}