📄 explain.cpp
字号:
}
// 存储编辑窗口画面
gettext(1, 1, 80, 25, TextMirror);
if (RunLineNo < 0)
{
// 从编辑状态开始单步调试
// 设置输出坐标位置和执行行号
OutX = OutY = 1;
PreRunLineNo = -1;
// 清屏
SetColor(WHITE, BLACK);
clrscr();
// 存储输出窗口内容
gettext(1, 1, 80, 25, OutMirror);
// 置光标位置
gotoxy(OutX, OutY);
// 得到开始调试的第一条语句的行号
RunLineNo = NextLine(0);
// 前以调试语句为空
PreRunLineNo = -1;
}
else
{
// 在调试状态下继续调试
// 恢复输出窗口内容到屏幕
puttext(1, 1, 80, 25, OutMirror);
// 置光标位置
gotoxy(OutX, OutY);
SetColor(WHITE, BLACK);
// 记下准备执行的行号
PreRunLineNo = RunLineNo;
// 执行当前语句并得到下一条应当执行的语句行号
RunLineNo = NextLine(RunLine(RunLineNo));
// 存储输出窗口的画面
gettext(1, 1, 80, 25, OutMirror);
if (Finished)
{
// 单步执行完毕
// 恢复编辑窗口的画面
puttext(1, 1, 80, 25, TextMirror);
// 置前一次执行的语句行为当前行
TextX = PreRunLineNo;
// 输出编辑窗口垂直滚动条
winEdit.ScrollVertical(TextX);
// 停止调试
StopDebugging();
// 恢复前一个调试行的正常颜色
PrintLine(PreRunLineNo);
SetCursor();
gotoxy(NowY, NowX);
return;
}
}
// 恢复编辑窗口画面
puttext(1, 1, 80, 25, TextMirror);
// 置前一次执行的语句行为当前行
TextX = RunLineNo;
// 输出编辑窗口垂直滚动条
winEdit.ScrollVertical(TextX);
if (TextX < x0 || TextX >= x0 + winEdit.High())
{
// 当前行超出编辑窗口当前屏的范围,需要滚动
// 设置编辑窗口当前屏的首行为当前行的前一行
x0 = TextX - 1;
if (x0 < 0)
{
x0 = 0;
}
// 重新打印编辑窗口当前屏的文本
PrintText(winEdit.Top() + 1);
SetCursor();
}
// 设置光标X坐标
NowX = winEdit.Top() + TextX - x0 + 1;
if (PreRunLineNo >= 0)
{
// 不是单步执行的第一条语句,需要恢复前一条执行语句的颜色
// 重新已正常颜色打印前一条执行语句
PrintLine(PreRunLineNo);
SetCursor();
}
// 以调试状态颜色打印当前语句
DebugLine(RunLineNo);
}
void StepOver()
{
// 单步执行语句,不进入SUB
if (NextLine(0) == -1)
{
// 程序执行完毕,退出
return;
}
// 存储编辑窗口画面
gettext(1, 1, 80, 25, TextMirror);
int PreLine = -1;
if (RunLineNo < 0)
{
// 从编辑状态开始单步调试
// 设置输出坐标位置和执行行号
OutX = OutY = 1;
PreRunLineNo = -1;
// 清屏
SetColor(WHITE, BLACK);
clrscr();
// 存储输出窗口内容
gettext(1, 1, 80, 25, OutMirror);
// 置光标位置
gotoxy(OutX, OutY);
// 得到开始调试的第一条语句的行号
RunLineNo = NextLine(0);
// 前以调试语句为空
PreRunLineNo = -1;
}
else
{
// 在调试状态下继续调试
// 恢复输出窗口内容到屏幕
puttext(1, 1, 80, 25, OutMirror);
// 置光标位置
gotoxy(OutX, OutY);
SetColor(WHITE, BLACK);
char Word[MaxY];
GetPart(Text[RunLineNo]->Line, 1, ' ', Word);
if (strcmp(Word, "GOSUB") == 0)
{
PreLine = RunLineNo;
do
{
// 执行当前语句,并返回下一个要执行的语句行号
// 记下准备执行的行号
PreRunLineNo = RunLineNo;
RunLineNo = NextLine(RunLine(RunLineNo));
} while (NowSub >= 0 && !Finished && !Error);
}
else
{
// 记下准备执行的行号
PreRunLineNo = RunLineNo;
RunLineNo = NextLine(RunLine(RunLineNo));
}
// 存储输出窗口的画面
gettext(1, 1, 80, 25, OutMirror);
if (Finished)
{
// 单步执行完毕
// 恢复编辑窗口的画面
puttext(1, 1, 80, 25, TextMirror);
// 置前一次执行的语句行为当前行
TextX = PreRunLineNo;
// 输出编辑窗口垂直滚动条
winEdit.ScrollVertical(TextX);
// 停止调试
StopDebugging();
// 恢复前一个调试行的正常颜色
PrintLine(PreRunLineNo);
SetCursor();
gotoxy(NowY, NowX);
return;
}
}
// 恢复编辑窗口画面
puttext(1, 1, 80, 25, TextMirror);
// 置前一次执行的语句行为当前行
TextX = RunLineNo;
// 输出编辑窗口垂直滚动条
winEdit.ScrollVertical(TextX);
if (TextX < x0 || TextX >= x0 + winEdit.High())
{
// 当前行超出编辑窗口当前屏的范围,需要滚动
// 设置编辑窗口当前屏的首行为当前行的前一行
x0 = TextX - 1;
if (x0 < 0)
{
x0 = 0;
}
// 重新打印编辑窗口当前屏的文本
PrintText(winEdit.Top() + 1);
SetCursor();
}
// 设置光标X坐标
NowX = winEdit.Top() + TextX - x0 + 1;
if (PreLine >= 0)
{
PreRunLineNo = PreLine;
}
if (PreRunLineNo >= 0)
{
// 不是单步执行的第一条语句,需要恢复前一条执行语句的颜色
// 重新以正常颜色打印前一条执行语句
PrintLine(PreRunLineNo);
SetCursor();
}
// 以调试状态颜色打印当前语句
DebugLine(RunLineNo);
}
void StopDebugging()
{
// 停止调试
if (TempStopNo > -1)
{
// 有临时断点需要清除
// 清除该临时断点
Text[TempStopNo]->Break = false;
TempStopNo = -1;
}
// 设置光标X坐标
NowX = winEdit.Top() + TextX - x0 + 1;
// 清除准备运行的行号
RunLineNo = -1;
// 清除全部变量空间
ClearAll();
}
void Watch()
{
// 监视表达式的值
// 显示监视窗口
winWatch.Show();
// 清理输入窗口内容
SetColor(WHITE, BLUE);
gotoxy(23, 11);
cprintf(" ");
// 存储输入的表达式
char Exp[40];
// 得到用户输入的表达式
winWatch.GetInput(Exp, 8, 24, 34);
while (Exp[0] != '\0')
{
// 用户输入非空
SetColor(WHITE, BLUE);
gotoxy(24, 11);
// 不显示错误信息
NoShown = true;
// 计算表达式的值
int Seat = 0;
double Result = Expression(Exp, Seat);
if (Error)
{
// 发现错误
Error = NoError;
// 输出错误信息
cprintf("Error!");
}
else
{
// 输出表达式的值
cprintf("%g", Result);
}
// 移动光标到表达式末尾
gotoxy(24 + strlen(Exp), 8);
// 等待用户按任意键
int Key;
Receive(Key);
// 清理输入窗口
SetColor(WHITE, BLUE);
gotoxy(23, 11);
cprintf(" ");
// 得到用户输入的表达式
winWatch.GetInput(Exp, 8, 24, 34);
}
// 隐藏监视窗口
winWatch.Hide();
}
void ShowOut()
{
// 显示输出窗口内容
// 存储当前文本窗口画面
gettext(1,1,80,25,TextMirror);
// 显示输出窗口画面到屏幕
puttext(1,1,80,25,OutMirror);
// 隐藏光标
_setcursortype(_NOCURSOR);
// 等待用户输入任意键
int Key;
Receive(Key);
// 恢复文本窗口画面
puttext(1,1,80,25,TextMirror);
}
void SearchPreMark()
{
// 定位前一个带标记的行
for (int i = TextX - 1; i >= 0; i--)
{
if (Text[i]->Mark)
{
// 已找到前一个带标记的行
// 改变当前行为此标记行
TextX = i;
if (x0 <= i && i < x0 + winEdit.High())
{
// 此行在文本窗口的当前屏内
// 计算光标X坐标
NowX = i - x0 + winEdit.Top() + 1;
}
else
{
// 需要翻屏
// 计算光标X坐标
NowX = winEdit.Top() + 1;
// 修改文本窗口首行序号
x0 = i;
// 重新打印文本窗口当前屏
PrintText(winEdit.Top() + 1);
SetCursor();
}
ShowPosition();
winEdit.ScrollVertical(TextX);
SetCursor();
// 跳出循环
break;
}
}
}
void SearchNextMark()
{
// 定位下一个带标记的行
for (int i = TextX + 1; i <= EndLine; i++)
{
if (Text[i]->Mark)
{
// 已找到下一个带标记的行
// 改变当前行为此标记行
TextX = i;
if (x0 <= i && i <= x0 + winEdit.Bottom() - winEdit.Top() - 2)
{
// 此行在文本窗口的当前屏内
// 计算光标X坐标
NowX = i - x0 + winEdit.Top() + 1;
}
else
{
// 需要翻屏
// 计算光标X坐标
NowX = winEdit.Top() + 1;
// 修改文本窗口首行序号
x0 = i;
// 重新打印文本窗口当前屏
PrintText(winEdit.Top() + 1);
SetCursor();
}
ShowPosition();
winEdit.ScrollVertical(TextX);
SetCursor();
// 跳出循环
break;
}
}
}
void HelpEdit()
{
// 显示编辑帮助
// 显示窗口
winHelpOnEdit.Show();
// 等待用户翻屏
winHelpOnEdit.Work();
// 隐藏窗口
winHelpOnEdit.Hide();
}
void HelpSyntax()
{
// 显示语法帮助
// 显示窗口
winHelpOnSyntax.Show();
// 等待用户翻屏
winHelpOnSyntax.Work();
// 隐藏窗口
winHelpOnSyntax.Hide();
}
void Thanks()
{
// 显示感谢
// 显示窗口
winThanks.Show();
// 等待用户按任意键
winThanks.Wait();
// 隐藏窗口
winThanks.Hide();
}
void AboutCBasic()
{
// 显示关于系统
// 显示窗口
winAboutCool.Show();
// 等待用户按任意键
winAboutCool.Wait();
// 隐藏窗口
winAboutCool.Hide();
}
void AboutMe()
{
// 显示关于作者
// 显示窗口
winAboutMe.Show();
// 等待用户按任意键
winAboutMe.Wait();
// 隐藏窗口
winAboutMe.Hide();
}
void HeadZero
(
const unsigned int Number, // 数字
char *Return // 返回的字符串
)
{
// 必要的时候,在数字的前面加'0',凑成两位数,返回字符串
// 将数字转化为字符串
itoa(Number, Return, 10);
if (Number < 10)
{
// 是一位数,需要在前面加'0'
char Temp[3] = "0";
strcat(Temp, Return);
strcpy(Return, Temp);
}
}
void Find()
{
// 在程序中搜索字符串
// 显示搜索窗口
winFind.Show();
// 得到用户输入的字符串
winFind.GetInput(Target, 6, 39, MaxLenOfSearch);
strupr(Target);
// 隐藏搜索窗口
winFind.Hide();
if (Target[0] != '\0')
{
// 输入的字符串非空
// 记下当前位置
StartSearchX = TextX;
StartSearchY = TextY;
// 搜索下一个目标字符串
SearchAgain();
}
}
void SearchAgain()
{
// 搜索下一个目标字符串
if (Target[0] != '\0')
{
// 目标字符串非空
if (StartSearchX == -1)
{
// 此字符串已经搜索过一遍,现在从当前位置继续搜索
StartSearchX = TextX;
StartSearchY = TextY;
}
// 文本行的副本
char Line[MaxY];
// 用于得到开始位置的字符串
char *ptr;
for (int i = StartSearchX; i <= EndLine; i++)
{
// 得到文本行的副本
strcpy(Line, Text[i]->Line);
// 整行全大写,便于搜索目标
strupr(Line);
// 得到目标字符串的开始位置
ptr = strstr(Line, Target);
if (ptr != NULL)
{
// 本行中存在目标字符串
do
{
// 设置文本Y坐标为目标串的开始位置
TextY = strlen(Line) - strlen(ptr);
if (TextY < StartSearchY && TextX == i)
{
// 该目标字符串在开始搜索位的前面,应该找下一个
// 清除当前位,以便搜索下一个
Line[TextY] = ' ';
// 得到目标字符串的开始位置
ptr = strstr(Line, Target);
}
} while (TextX == i && TextY < StartSearchY && ptr != NULL);
if (ptr == NULL)
{
// 当前行没有包含目标字符串,继续下一行
continue;
}
// 改变当前行
TextX = i;
if (TextX > x0 + winEdit.High() - 1)
{
// 目标行在文本窗口当前屏外,需要翻屏
// 设置目标行为文本窗口首行
x0 = TextX;
}
PrintText(winEdit.Top() + 1);
// 设置光标的位置
NowX = TextX - x0 + winEdit.Top() + 1;
NowY = TextY + winEdit.Left() + 1;
// 设置搜索的开始位置
StartSearchX = TextX;
StartSearchY = TextY + 1;
char Word[MaxY];
GetMid(Text[TextX]->Line, TextY, TextY + strlen(Target) - 1, Word);
gotoxy(NowY, NowX);
SetColor(BLUE, WHITE);
cprintf("%s", Word);
gotoxy(NowY, NowX);
int Key;
Receive(Key);
PrintLine(TextX);
SetCursor();
gotoxy(NowY, NowX);
// 寻找成功,返回
return;
}
}
}
// 寻找失败,显示搜索完毕
// 显示窗口
winSearchMessage.Show();
// 等待用户按任意键
winSearchMessage.Wait();
// 隐藏窗口
winSearchMessage.Hide();
// 清除搜索开始位置
StartSearchX = -1;
}
int Ask()
{
// 询问用户是否保存当前文件
// 显示查询窗口
winAsk.Show();
// 存储用户输入
int Key;
do
{
// 等待用户输入
Receive(Key);
if (Key == KeyEsc)
{
// 放弃本次操作
// 隐藏查询窗口
winAsk.Hide();
return Cancel;
}
// 变大写
Key = toupper(Key);
switch (Key)
{
case 'Y':
// 存盘
// 隐藏查询窗口
winAsk.Hide();
return Yes;
case 'N':
// 不存盘
// 隐藏查询窗口
winAsk.Hide();
return No;
}
} while (true);
}
int SaveBeforeRun()
{
// 运行前存盘
if (!Saved)
{
// 当前文件未存盘
if (strcmp(winEdit.Caption(), DefaultFileName) == 0)
{
// 是默认文件名,等待用户重命名
if (SaveAsFile() != Yes)
{
return false;
}
}
else
{
// 直接存盘
SaveFile(winEdit.Caption());
}
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -