📄 explain.cpp
字号:
////////////////////////////////////////////////////
// //
// 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 + -