QuakeGod
2023-10-20 6fa60de2b0d0237054aa7571191df0f291838031
MTerm1/MTerm1Doc.cpp
@@ -51,6 +51,8 @@
   {KLCoilTypeSR,"SR"},
   {KLCoilTypeC,"C"},
   {KLCoilTypeT,"T"},
   {KLCoilTypeP,"P"},
   {KLCoilTypeE,"E"},
};
int CMTerm1Doc::nCoilTypeDefCount = sizeof(CMTerm1Doc::CoilTypeNameDef) / sizeof(stTypeNameDef);
@@ -204,43 +206,65 @@
}
*/
/// <summary>
/// 处理新文档的创建事件
/// </summary>
/// <returns></returns>
BOOL CMTerm1Doc::OnNewDocument()
{
   if (!CDocument::OnNewDocument())
   {
      return FALSE;
   }
   // TODO: 在此添加重新初始化代码
   // (SDI 文档将重用该文档)
//   LoadFromFile(_T("0prog1.txt"));
   //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;
   // TODO:  在此添加您专用的创建代码
   CString s1;
   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);
   SaveToFile(lpszPathName);
   return TRUE;
   //0912-zxd-Modify
    int result = SaveToFile(lpszPathName);
   return result == 1 ? TRUE : FALSE;
//   return CDocument::OnSaveDocument(lpszPathName);
}
/// <summary>
/// 处理关闭文档的事件
/// </summary>
void CMTerm1Doc::OnCloseDocument()
{
   // TODO: 在此添加专用代码和/或调用基类
@@ -250,8 +274,10 @@
   CDocument::OnCloseDocument();
}
// CMTerm1Doc 序列化
/// <summary>
///  CMTerm1Doc 序列化
/// </summary>
/// <param name="ar"></param>
void CMTerm1Doc::Serialize(CArchive& ar)
{
   CString s1;
@@ -304,6 +330,10 @@
   SetSearchContent(strSearchContent);
}
/// <summary>
/// 设置文档的搜索内容
/// </summary>
/// <param name="value">要搜索内容的字符串值</param>
void CMTerm1Doc::SetSearchContent(const CString& value)
{
   if (value.IsEmpty())
@@ -327,11 +357,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);
@@ -339,11 +375,14 @@
#endif //_DEBUG
// CMTerm1Doc 命令
/// <summary>
/// 加载指定的文件
/// </summary>
/// <param name="sFilePathName">需要加载的文件的路径名</param>
/// <returns></returns>
int CMTerm1Doc::LoadFromFile(CString sFilePathName)
{
   // TODO: 在此处添加实现代码.
   CFile file1;
   CFile file1;//打开指定的文件
   CFileException e;
   bool r = file1.Open(sFilePathName, CFile::modeRead, &e);
   if (r)
@@ -353,64 +392,80 @@
      file1.Read(s1A.GetBuffer(l + 2048), l);
      file1.Close();
      s1A.ReleaseBuffer(l);
      TransFileToProg(s1A);
      UpdateAllViews(NULL);
      TransFileToProg(s1A);//文件内容转换为Prog格式
      UpdateAllViews(NULL);//更新所有的视图,以反映新加载的内容
   }
   return 0;
}
/// <summary>
/// 保存文件
/// </summary>
/// <param name="sFilePathName">需要保存的文件的路径名</param>
/// <returns></returns>
int CMTerm1Doc::SaveToFile(CString sFilePathName)
{
   // TODO: 在此处添加实现代码.
   CString s1;
   CFile file1;
   CFileException e;
   bool r = file1.Open(sFilePathName, CFile::modeReadWrite, &e);
   bool r = file1.Open(sFilePathName, CFile::modeReadWrite, &e);//读写模式打开文件
   if (r)
   {
      CStringA s1A;
      CStringA sSectionNameA;
      //写入系统配置
      GetSectionTxt(SectionSysCfg, sSectionNameA); //
      GetSectionTxt(SectionSysCfg, sSectionNameA); //获取系统配置的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());
      file1.Write(s1A, s1A.GetLength());//将获取到的文本内容写入文件
      //写入程序
      GetSectionTxt(SectionProg, sSectionNameA); //
      GetSectionTxt(SectionProg, sSectionNameA); //获取程序的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());
      file1.Write(s1A, s1A.GetLength());//获取到的文本内容写入文件
      TransToTxt(s1A);
      file1.Write(s1A, s1A.GetLength());
      TransToTxt(s1A);//将程序内容转换为文本格式
      file1.Write(s1A, s1A.GetLength());//将转换后的文本内容写入文件
      //写入注释
      GetSectionTxt(SectionAnno, sSectionNameA); //
      GetSectionTxt(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");
         s1 = mCoilAnnos[i].sCoilName + _T("\t") + mCoilAnnos[i].sAnno + _T("\r\n");
         s1A = s1;
         file1.Write(s1A, s1A.GetLength());
      }
      //写入触点监控列表
      GetSectionTxt(SectionCoilList, sSectionNameA); //
      GetSectionTxt(SectionCoilList, sSectionNameA); //获取触点监控列表的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());
      //写入数据监控列表
      GetSectionTxt(SectionDataList, sSectionNameA); //
      GetSectionTxt(SectionDataList, sSectionNameA); //获取数据监控列表的文本表示
      s1A = "[" + sSectionNameA + "]\r\n";
      file1.Write(s1A, s1A.GetLength());
      file1.Close();
      return 1;
   }
   return 0;
   else//文件打开失败
   {
      return 0;
   }
}
/// <summary>
/// 根据文本匹配类型的Key并返回
/// </summary>
/// <param name="txt"></param>
/// <returns></returns>
int CMTerm1Doc::TxtToSection(CStringA txt)
{
   for (int i = 0; i < nSectionDefCount; i++) {
@@ -421,6 +476,12 @@
   return SectionNone;
}
/// <summary>
/// 根据Key匹配类型的文本,通过txt传递,返回查询执行结果
/// </summary>
/// <param name="nSectionType"></param>
/// <param name="txt"></param>
/// <returns></returns>
int CMTerm1Doc::GetSectionTxt(int nSectionType, CStringA & txt)
{
   for (int i = 0; i < nSectionDefCount; i++) {
@@ -432,6 +493,13 @@
   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++) {
@@ -444,6 +512,13 @@
   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++){
@@ -455,6 +530,13 @@
   }
   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++){
@@ -466,6 +548,12 @@
   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++) {
@@ -477,6 +565,13 @@
   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();
@@ -492,6 +587,12 @@
   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++)
@@ -504,6 +605,13 @@
   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();
@@ -521,6 +629,12 @@
}
/// <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++)
@@ -533,6 +647,13 @@
   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: 在此处添加实现代码.
@@ -547,6 +668,12 @@
   return 0;
}
/// <summary>
/// 设置或更新特定线圈的注释
/// </summary>
/// <param name="sCoilName"></param>
/// <param name="sAnno"></param>
/// <returns></returns>
int CMTerm1Doc::SetAnno(CString sCoilName, CString sAnno)
{
   // TODO: 在此处添加实现代码.
@@ -575,6 +702,14 @@
   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: 在此处添加实现代码.
@@ -593,6 +728,14 @@
   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;
@@ -607,27 +750,41 @@
   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;
      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++)
         {
@@ -644,7 +801,7 @@
               Progs[nProgPos].Params[j].nParamType = nType;
               Progs[nProgPos].Params[j].nParamAddr = nAddr;
            }
            else {
            else {
            }
         }
@@ -653,6 +810,8 @@
         nProgPos++;
      }
   }
   m_nProgSteps = nProgPos;
   // 先扫描分开的程序段
   int stpos[100] = { 0 };
@@ -662,7 +821,10 @@
   // 查找匹配指令和地址
   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;
      switch (Progs[i].nOpType1)
@@ -700,8 +862,10 @@
      }
      StackDeeps[i] = nCurStackDeep;
   }
   s1.Format(_T("Remaining STs %d"), nSts);
   SysLog(s1);
   for (int i = 0; i < nSts; i++) {
      s1.Format(_T("[%d] %d "), i, stpos[i]);
      SysLog(s1);
@@ -789,6 +953,11 @@
   return 0;
}
/// <summary>
/// 解析文件为梯形图
/// </summary>
/// <param name="ProgTxtA">文本</param>
/// <returns></returns>
int CMTerm1Doc::TransFileToProg(CStringA ProgTxtA)
{
   CString s1;
@@ -798,6 +967,7 @@
   sProg.Replace(_T("\r\n"), _T("\n"));
   sProg.Replace(_T("\r"), _T("\n"));
   //分割文本字符串
   DivideStringToArray(sProg, _T("\n"), txtLines);
   nSectionCount = 0;
@@ -811,7 +981,8 @@
      int nRightBracket;
      if (sLine.Find(_T("[")) == 0 && (nRightBracket = sLine.Find(_T("]"))) > 1)
      {      //找到 [ ] 标志
         if (nSectionCount > 0) {
         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);
@@ -821,6 +992,7 @@
         sSectionName = sLine.Mid(1, nRightBracket - 1);
         sSectionNameA = sSectionName;
         int theSection = TxtToSection(sSectionNameA);
         s1.Format(_T("+ Line %d  Section %d : [%s] type:%d  "), i + 1, nSectionCount, sSectionName, theSection);
         SysLog(s1);
         Sections[nSectionCount].nSectionType = theSection;
@@ -852,7 +1024,10 @@
   int nAnnoLines = 0;
   int bAnnoSection = GetSectionPos(SectionAnno, &nAnnoSectionLine, &nAnnoLines);
   if (bAnnoSection) { nAnnoStartLine = nAnnoSectionLine + 1; }
   if (bAnnoSection)
   {
      nAnnoStartLine = nAnnoSectionLine + 1;
   }
   for (int i = nAnnoStartLine; i < nAnnoStartLine + nAnnoLines; i++)
   {
@@ -886,6 +1061,8 @@
   return 0;
}
//文本段在此处组装
int CMTerm1Doc::TransToTxt(CStringA &ProgTxt)
{
   CStringA s1, s2;
@@ -1828,7 +2005,7 @@
   }
}
//*/
void CMTerm1Doc::OnMenuShowConsole()
{
   // TODO: 在此添加命令处理程序代码
@@ -1845,7 +2022,7 @@
      ASSERT_VALID(theApp.m_pCtrlViewTemplate);
      CFrameWnd * pFrame = theApp.m_pCtrlViewTemplate->CreateNewFrame(this, NULL);
      ASSERT_KINDOF(CFrameWnd, pFrame);
      theApp.m_pCtrlViewTemplate->InitialUpdateFrame(pFrame, this);
       theApp.m_pCtrlViewTemplate->InitialUpdateFrame(pFrame, this);
   }
}