⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 explain.cpp

📁 c语言写的VB编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////
//                                                //
//    Explain.cpp                                 //
//    解释模块                                    //
//    处理用户发出的全部请求并指向相应处理模块    //
//    包括菜单、快捷键                            //
//    最后更新时间:2004年4月23日11:31            //
//                                                //
////////////////////////////////////////////////////



#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <dir.h>
#include <io.h>

#include "Explain.h"

Window winFind(4, 20, 9, 41 + MaxLenOfSearch, true, false);
Window winAboutMe(7, 15, 18, 65, true, false);
Window winAboutCool(6, 23, 18, 59, true, false);
Window winThanks(7, 31, 14, 48, true, false);
Window winHelpOnSyntax(5, 10, 19, 71);
Window winHelpOnEdit(5, 10, 19, 71);
Window winWatch(5, 20, 13, 60, true, false);
Window winGetFileName(8, 20, 12, 60, true, false);
Window winAsk(8, 25, 12, 55, true, false);
Window winSearchMessage(7, 26, 11, 54, true, false);
List lstOpenFile(3, 61, 22, 76);

void Explain
	(
	const int MenuNo,	// 菜单序号
	const int ItemNo	// 菜单项序号
	)
{
	// 解释模块

	switch (MenuNo)
	{
	case MenuFile:
		// 菜单File

		switch (ItemNo)
		{
		case ItemNew:
			// 菜单项New
			// 打开新文件

			if (!Saved)
			{
				// 没有存盘
				winAsk.Clear();
				winAsk.Add(" Do you want to save(Y/N)?");

				if (Ask() == Yes)
				{
					// 要存盘
					SaveFile(winEdit.Caption());
				}
			}

			// 打开新文件
			NewFile(DefaultFileName);

			break;
		case ItemOpen:
			// 菜单项Open
			// 打开一个已存在的文件或建立一个新文件

			// 打开文件
			OpenFile();

			break;
		case ItemSave:
			// 菜单项Save
			// 将当前文件存盘

			if (strcmp(winEdit.Caption(), DefaultFileName)==0)
			{
				// 当前文件是默认文件

				// 需要另存为
				SaveAsFile();
			}
			else if (!Saved)
			{
				// 当前文件修改过

				// 以编辑窗口标题为文件名存盘
				SaveFile(winEdit.Caption());

				if (Error)
				{
					Error = NoError;
				}
			}

			break;
		case ItemSaveAs:
			// 菜单项SaveAs
			// 另存为,需要输入文件名

			// 另存为
			SaveAsFile();

			break;
		case ItemPrint:
			// 菜单项Print
			// 输出到打印机
            
			// 打印文件
			PrintFile();

			break;
		case ItemQuit:
			// 菜单项Quit

			if (!Saved)
			{
				winAsk.Clear();
				winAsk.Add(" Quit without save (Y/N)?");
				switch (Ask())
				{
				case Yes:
					// 退出系统
					Quit();

					break;
				case No:
				case Cancel:
					break;
				}
			}
			break;
		}
		break;
	case MenuEdit:
		// 菜单Edit
		switch (ItemNo)
		{
		case ItemFind:
			// 菜单项Find
			// 要求输入目标字符串,并搜索下一个

			// 输入并搜索
			Find();

			break;
		case ItemSearchAgain:
			// 菜单项SearchAgain
			// 搜索下一个目标字符串

			// 搜索
			SearchAgain();

			break;
		case ItemStandardize:
			// 菜单项Standardize
			// 对当前文件的每一行进行标准化

			// 标准化全部
			Standardize();

			break;
		case ItemStandLine:
			// 菜单项StandardizeLine
			// 标准化当前行

			// 标准化当前行
			StandardizeLine(TextX);

			break;
		case ItemMark:
			// 菜单项Mark
			// 添加或删除当前行的标记

			if (LengthOf(TextX) > 0)
			{
				// 当前行非空

				// 切换当前行标记
				Text[TextX]->Mark = true + false - Text[TextX]->Mark;
			}

			// 重新打印当前行文本
			PrintLine(TextX);

			SetCursor();

			break;
		case ItemPrevious:
			// 菜单项PreviousMark
			// 定位前一个标记行

			// 搜索前一个标记行的位置
			SearchPreMark();

			break;
		case ItemFollowing:
			// 菜单项FollowingMark
			// 定位下一个标记行

			// 搜索下一个标记行的位置
			SearchNextMark();

			break;
		case ItemClearMark:
			// 菜单项ClearAllMark
			// 清除所有标记

			for (int i = 0; i <= EndLine; i++)
			{
				Text[i]->Mark = false;
			}

			// 重新打印编辑窗口当前屏文本
			PrintText(winEdit.Top() + 1);

			SetCursor();

			break;
		}
		break;
	case MenuRun:
		// 菜单Run
		switch (ItemNo)
		{
		case ItemGoToCursor:
			// 菜单项GoToCursor
			// 执行到光标处

			if (LengthOf(TextX) > 0)
			{
				// 当前行非空

				if (!SaveBeforeRun())
				{
					break;
				}

				if (!Text[TextX]->Break)
				{
					// 当前行没有断点

					// 对当前行设置临时断点
					Text[TextX]->Break = true;

					// 记下当前行序号,执行完毕后恢复原设置
					TempStopNo = TextX;
				}
			}
			else
			{
				// 当前行为空,本次操作无效

				break;
			}

			// 没有Break,当前行非空的情况下,将继续执行下面Run部分的代码

		case ItemRun:
			// 菜单项Run
			// 执行当前程序

			if (!SaveBeforeRun())
			{
				break;
			}

			// 对文件进行标准化
			Standardize();

			// 记录下当前屏幕画面
			gettext(1, 1, 80, 25, TextMirror);

			// 执行
			RunProgram();

			if (!Error)
			{
				// 恢复执行前的屏幕画面
				puttext(1, 1, 80, 25, TextMirror);
			}

			if (Error)
			{
				// 执行中发现错误

				// 清除全部变量表
				ClearVar();

				// 重置错误代码
				Error = NoError;

				// 闪烁显示错误行(即当前行)
				textcolor(LIGHTRED + BLINK);
				gotoxy(winEdit.Left() + 1, winEdit.Top() + TextX - x0 + 1);
				cprintf("%s ", Text[TextX]->Line);

				// 重新打印编辑窗口垂直滚动条
				winEdit.ResetVertical();

				// 等待按任意键继续
				int Key;
				Receive(Key);

				// 去掉错误行(当前行)的闪烁
				PrintLine(TextX);

				// 输出编辑窗口垂直滚动条
				winEdit.ScrollVertical(TextX);

				SetCursor();

                // 停止调试
				StopDebugging();
			}
			else if (Finished)
			{
				// 程序正常执行完毕

				// 停止调试
				StopDebugging();
			}
			else
			{
				// 程序中有断点

				if (TempStopNo > -1)
				{
					// 设置过临时断点,在GoToCursor中使用的

					// 清除临时断点
					Text[TempStopNo]->Break = false;
					TempStopNo = -1;
				}

				// 置断点行为当前行
				if (RunLineNo >= 0)
				{
					TextX = RunLineNo;
				}

				if (TextX < x0 || TextX >= x0 + winEdit.High())
				{
					// 当前行不在编辑窗口的当前屏

					// 设置编辑窗口的首行为当前行的前一行
					x0 = TextX - 1;

					// 重新打印编辑窗口的当前屏
					PrintText(winEdit.Top() + 1);

					SetCursor();
				}

				// 以单步调试方式打印当前行,等待单步调试或继续执行
				DebugLine(RunLineNo);

				// 设置光标位置
				NowX = winEdit.Top() + TextX - x0 + 1;
			}
			break;
		case ItemStopDebugging:
			// 菜单项StopDebugging

			if (RunLineNo > -1)
			{
				// 程序已经开始运行了

				// 当前执行行先减1,方便PrintLine中打印时正常输出当前调试行的状态
				RunLineNo--;
				PrintLine(RunLineNo + 1);
				RunLineNo++;

				SetCursor();

				// 停止调试
				StopDebugging();
			}
			break;
		case ItemStepInto:
			// 菜单项StepInto
			// 单步调试,进入Sub

			if (!Saved)
			{
				if (!SaveBeforeRun())
				{
					break;
				}

				Standardize();

				RunLineNo = -1;

				PrintText(winEdit.Top() + 1);

				SetCursor();
			}

			if (RunLineNo < 0)
			{
				// 程序还没有开始调试

				// 检查整个程序的语法
				CheckSyntax();

				if (Error)
				{
					// 有语法错误

					// 重置错误代码
					Error = NoError;

					return;
				}

				CreateTable();

				if (Error)
				{
					Error = NoError;
					return;
				}

				// 清除全部变量空间
				ClearAll();
			}

			window(1, 1, 80, 25);

			StepInto();

			if (Error)
			{
				// 有运行错误

				// 清除全部变量表
				ClearVar();

				// 重置错误代码
				Error = NoError;

				// 停止调试
				StopDebugging();

				// 重新打印编辑窗口的当前屏
				PrintText(winEdit.Top() + 1);

				SetCursor();
			}

			break;
		case ItemStepOver:
			// 菜单项StepOver
			// 单步调试,不进入Sub

			if (!Saved)
			{
				if (!SaveBeforeRun())
				{
					break;
				}

				Standardize();

				RunLineNo = -1;

				PrintText(winEdit.Top() + 1);

				SetCursor();
			}

			if (RunLineNo < 0)
			{
				// 程序还没有开始调试

				// 检查整个程序的语法
				CheckSyntax();

				if (Error)
				{
					// 有语法错误

					// 重置错误代码
					Error = NoError;

					return;
				}

				CreateTable();

				if (Error)
				{
					Error = NoError;
					return;
				}

				// 清除全部变量空间
				ClearAll();
			}

			window(1, 1, 80, 25);

			// 单步调试
			StepOver();

			if (Error)
			{
				// 有运行错误

				// 清除全部变量表
				ClearVar();

				// 重置错误代码
				Error = NoError;

				// 停止调试
				StopDebugging();

				// 重新打印编辑窗口的当前屏
				PrintText(winEdit.Top() + 1);

				SetCursor();
			}
			break;
		case ItemOutput:
			// 菜单项Output
			// 看程序输出窗口

			// 看输出
			ShowOut();

			break;
		}
		break;
	case MenuDebug:
		// 菜单Debug

		switch (ItemNo)
		{
		case ItemBreak:
			// 菜单项Break
			// 添加或删除当前行的断点

			if (LengthOf(TextX) > 0)
			{
				// 当前行非空

				// 切换当前行的断点
				Text[TextX]->Break = true + false - Text[TextX]->Break;
			}

			// 重新打印当前行
			PrintLine(TextX);

			SetCursor();

			break;
		case ItemClearBreak:
			// 菜单项ClearAllBreak
			// 清楚程序中的所有断点

			for (int i = 0; i <= EndLine; i++)
			{
				Text[TextX]->Break = false;
			}
			
			// 重新打印编辑窗口的当前屏文本
			PrintText(winEdit.Top() + 1);

			SetCursor();

			break;
		case ItemWatch:
			// 菜单项Watch
			// 监视表达式的值

			// 打开监视
			Watch();

			break;
		}
		break;
	case MenuHelp:
		// 菜单Help

		switch (ItemNo)
		{
		case ItemHelpEdit:
			// 菜单项HelpOnEdit
			// 关于编辑使用的帮助

			// 打开帮助窗口
			HelpEdit();

			break;
		case ItemHelpSyntax:
			// 菜单项HelpOnSyntax
			// 关于语法的帮助

			// 打开帮助窗口
			HelpSyntax();

			break;
		case ItemAboutCBasic:
			// 菜单项AboutCoolBasic
			// 关于CoolBasic语言解释器

			// 打开关于窗口
			AboutCBasic();

			break;
		case ItemThanks:
			// 菜单项Thanks
			// 作者感谢的话

			// 打开感谢窗口
			Thanks();

			break;
		case ItemAboutMe:
			// 菜单项AboutMe
			// 作者的信息

			// 打开作者信息窗口
			AboutMe();

			break;
		}
	}

	// 切换系统状态为编辑状态
	ChangeMode(EditMode);

	gotoxy(NowY,NowX);
}

void ClearLine()
{
	// 清空所有动态申请的文本行

	for (int i = 0; i <= TotRoomLine; i++)
	{
		delete Text[i];
	}

	// 重置动态文本行数量
	TotRoomLine = -1;
}

void NewFile
	(
	const char Name[MaxLenOfFileName]	// 文件名
	)
{
	// 打开新的文件

	// 编辑窗口首行置0
	x0 = 0;

	// 文本坐标在左上角
	TextX = 0;
	TextY = 0;

	// 光标在编辑窗口左上角
	NowX = winEdit.Top() + 1;
	NowY = winEdit.Left() + 1;

	// 默认为插入模式
	ShowInsert(true);

	// 当前文件未改动
	ShowSaved(true);

	// 文本只有一行
	EndLine = 0;

	// 设置编辑窗口文本高度
	winEdit.SetTotHigh(0);

	// 没有当前要运行的行
	RunLineNo = -1;

	// 不显示错误窗口标志
	NoShown = false;

	// 重置编辑窗口垂直滚动条
	winEdit.ResetVertical();

	// 清空动态文本行
	ClearLine();

	// 申请一行文本空间
	NewLine();

	// 设置编辑窗口标题,即当前文件名
	winEdit.SetTitle(Name);

	// 清空编辑窗口内容
	winEdit.ClearText();

	// 刷新编辑窗口标题
	winEdit.RefreshTitle();

	PrintLine(1);

	// 输出光标位置
	ShowPosition();

	SetCursor();
}

void OpenFile()
{
	// 打开文件

	if (!Saved)
	{
		// 当前文件没有存盘
		// 询问用户是否存盘

		winAsk.Clear();
		winAsk.Add(" Do you want to save(Y/N)?");

		switch (Ask())
		{
		case Yes:
			// 存储当前文件

			// 以编辑窗口标题为文件名存储文件
			int Return = SaveFile(winEdit.Caption());

			if (Return == No)
			{
				// 用户取消,返回
				return;
			}

			break;
		case No:
			break;
		case Cancel:
			// 用户放弃存储

			return;
		}
	}

	// 清空打开文件列表内容
	lstOpenFile.Clear();

	// 在搜索文件名时用到的文件指针
	FILE *stream;

	// 在得到文件信息时使用的文件指针
	ftime ft;

	// 在底部信息栏显示的文件信息(日期,时间,大小)
	char Mess[List::MaxLenOfMessage];

	// 先添加新建文件用到的列表元素
	lstOpenFile.Add("<New File> ", "Press here to create a new file");

	// 文件块结构
	struct ffblk ffblk;

	// 搜索成功标志
	int Done;

	// 在当前文件夹中搜索源文件
	Done = findfirst("*.BAS", &ffblk, 0);

	while (!Done)
	{
		// 搜索到一个源文件

		// 搜索到的文件名
		char Name[List::MaxLenOfItem];

		// 临时存储字符串(月,日,小时,分钟,秒),用于在不足两位时在前面补“0”
		char Month[3];
		char Day[3];
		char Hour[3];
		char Minute[3];
		char Sec[3];

		// 得到该文件的日期和时间信息
		stream = fopen(ffblk.ff_name,"r");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -