📄 window.cpp
字号:
////////////////////////////////////////////
// //
// Window.cpp //
// 窗口类的实现 //
// 包括编辑窗口、各种对话框、信息框 //
// 最后更新时间:2004年4月23日11:35 //
// //
////////////////////////////////////////////
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include "ErrorVal.h"
#include "Window.h"
Window::Window(const int Top, const int Left, const int Bottom, const int Right, const int BlackSign, const int VerSign)
{
// 初始化窗口
// 设置窗口的左上角坐标
x0 = Top;
y0 = Left;
// 设置窗口的右下角坐标
x1 = Bottom;
y1 = Right;
// 设置垂直滚动条标志
VerticalSign = VerSign;
// 设置阴影标志
Black = BlackSign;
Clear();
}
Window::~Window()
{
}
void Window::SetColor(const int FrameColor1, const int FrameColor2, const int TextColor1, const int TextColor2)
{
// 设置颜色
// 设置边框的前景色
FrameForeground = FrameColor1;
// 设置边框的背景色
FrameBackground = FrameColor2;
// 设置文本的前景色
TextForeground = TextColor1;
// 设置文本的背景色
TextBackground = TextColor2;
}
void Window::SetTitle(const char Name[MaxLenOfTitle])
{
// 设置标题
if (Name[0] != '\0')
{
// 标题非空
// 改变标题
strcpy(Title, Name);
}
}
void Window::SetTotHigh(const int New)
{
// 设置文本高度
// 改变文本高度
TotHigh = New;
}
void Window::Show()
{
// 显示窗口
// 隐藏光标
_setcursortype(_NOCURSOR);
// 设置颜色,使用外部函数,非方法
::SetColor(FrameForeground, FrameBackground);
// 打印下边框,上边框在刷新标题时会打印
for (int i = Left() + 1; i <= Right() - 1; i++)
{
PrintChar(Bottom(), i, 205);
}
// 打印左右边框
for (i = Top() + 1; i <= Bottom() - 1; i++)
{
PrintChar(i, Left(), 186);
PrintChar(i, Right(), 186);
}
// 打印4个角
PrintChar(Top(), Left(), 201);
PrintChar(Top(), Right(), 187);
PrintChar(Bottom(), Left(), 200);
PrintChar(Bottom(), Right(), 188);
// 刷新标题
RefreshTitle();
if (Black)
{
// 需要打印阴影
// 设置颜色
::SetColor(LIGHTGRAY, BLACK);
// 打印窗口右侧阴影
for (i = Top() + 1; i <= Bottom() + 1; i++)
{
PrintChar(i, Right() + 1, 32);
PrintChar(i, Right() + 2, 32);
}
// 打印窗口底部阴影
for (i = Left() + 1; i <= Right(); i++)
{
PrintChar(Bottom() + 1, i, 32);
}
}
if (VerticalSign)
{
// 需要垂直滚动条
// 设置颜色
::SetColor(CYAN, LIGHTBLUE);
// 在右侧打印滑轨
for (i = Top() + 2; i <= Bottom() - 2; i++)
{
PrintChar(i, Right(), 177);
}
// 设置颜色
::SetColor(BLUE, CYAN);
// 打印上下箭头指示
PrintChar(Top() + 1, Right(), 30);
PrintChar(Bottom() - 1, Right(), 31);
// 打印游标
PrintChar(Top() + 2, Right(), 254);
}
// 设置颜色
::SetColor(TextForeground, TextBackground);
// 文本区清屏
window(Left() + 1, Top() + 1, Right() - 1, Bottom() - 1);
clrscr();
// 恢复全屏窗口
window(1, 1, 80, 25);
// 输出文本
ScrollText(0);
}
void Window::Work()
{
// 窗口工作状态,允许用户上下滚屏
// 用户输入
int Key;
// 当前文本区的第一行序号
int FirstLine = 0;
// 初始化游标位置
VerticalPos = Top() + 2;
// 设置颜色
::SetColor(TextForeground, TextBackground);
do
{
// 等待用户输入
Receive(Key);
switch (Key)
{
case KeyUp:
// 输入的是上键
if (FirstLine > 0)
{
// 可以向上滚动
// 改变首行序号
FirstLine--;
// 滚动文本
ScrollText(FirstLine);
// 滚动游标
ScrollVertical(FirstLine);
}
break;
case KeyDown:
// 输入的是下键
if (FirstLine < TotLine - High() + 3)
{
// 可以向下滚动
// 改变首行序号
FirstLine++;
// 滚动文本
ScrollText(FirstLine);
// 滚动游标
ScrollVertical(FirstLine);
}
break;
case KeyPageDown:
// 是向下翻屏键
// 改变当前元素序号
FirstLine += High() - 3;
if (FirstLine > TotLine - High() + 3)
{
// 越界
// 最后一个为当前元素
FirstLine = TotLine - High() + 3;
}
// 滚动文本
ScrollText(FirstLine);
// 滚动垂直滚动条
ScrollVertical(FirstLine);
break;
case KeyPageUp:
// 是向下翻屏键
// 改变当前元素序号
FirstLine -= High() - 3;
if (FirstLine < 0)
{
// 越界
// 第一个为当前元素
FirstLine = 0;
}
// 滚动文本
ScrollText(FirstLine);
// 滚动垂直滚动条
ScrollVertical(FirstLine);
break;
case KeyHome:
// 到第一个元素
if (FirstLine > 0)
{
// 当前不在第一个元素
// 设置首行序号
FirstLine = 0;
// 滚动文本
ScrollText(FirstLine);
// 滚动垂直滚动条
ScrollVertical(FirstLine);
}
break;
case KeyEnd:
// 到最后一个元素
if (FirstLine < TotLine - High() + 3)
{
// 修改首行序号
FirstLine = TotLine - High() + 3;
// 滚动文本
ScrollText(FirstLine);
// 滚动垂直滚动条
ScrollVertical(FirstLine);
}
break;
}
} while (Key != KeyEsc);
}
void Window::Wait()
{
// 等待用户输入任意键
int Key;
Receive(Key);
}
void Window::Add(const char NewLine[MaxLenOfLine])
{
// 添加文本行
TotLine++;
if (TotLine < MaxLine)
{
strcpy(Line[TotLine], NewLine);
}
else
{
ShowError(ErrorSerious, -1, "Too many lines in current window.");
}
}
void Window::Hide()
{
// 隐藏窗口
// 恢复窗口覆盖部分的编辑文本
for (int i = Top(); i <= Bottom(); i++)
{
PrintLine(i + ::x0 - 3);
}
if (Black)
{
// 有阴影,再恢复阴影部分的编辑文本
PrintLine(Bottom() + ::x0 - 2);
}
}
void Window::ScrollText(const int Start)
{
// 滚动文本
// 设置颜色
::SetColor(TextForeground, TextBackground);
for (int i = Start; i <= Start + TotLine && i - Start <= High() - 3; i++)
{
// 打印文本行
gotoxy(Left() + 2, i - Start + Top() + 2);
cprintf("%s", Line[i]);
}
}
void Window::ScrollVertical(const int Now)
{
// 滚动游标
// 设置颜色
::SetColor(CYAN, LIGHTBLUE);
window(1, 1, 80, 25);
// 删除原来的游标
PrintChar(VerticalPos, Right(), 177);
if (TotHigh == 0)
{
// 无文本时,游标在最顶部
VerticalPos = Top() + 2;
}
else
{
// 计算新的游标位置
VerticalPos = (double)(High() - 2) / TotHigh * Now + Top() + 2;
}
if (VerticalPos > Bottom() - 2)
{
// 游标位置大于滑轨底部,则置最底端
VerticalPos = Bottom() - 2;
}
// 设置颜色
::SetColor(BLUE, CYAN);
// 打印新的游标
PrintChar(VerticalPos, Right(), 254);
}
void Window::ResetVertical()
{
// 重置游标
window(1, 1, 80, 25);
// 设置颜色
::SetColor(CYAN, LIGHTBLUE);
for (int i = Top() + 2; i <= Bottom() - 2; i++)
{
// 打印滑轨
PrintChar(i, Right(), 177);
}
// 设置颜色
::SetColor(BLUE, CYAN);
// 置游标于最顶端
VerticalPos = Top() + 2;
// 打印游标
PrintChar(VerticalPos, Right(), 254);
}
void Window::ClearText()
{
// 清除文本区内容
window(Left() + 1, Top() + 1, Right() - 1, Bottom() - 1);
::SetColor(TextForeground, TextBackground);
clrscr();
window(1, 1, 80, 25);
}
void Window::RefreshTitle()
{
// 刷新标题
// 设置颜色
::SetColor(FrameForeground, FrameBackground);
// 打印上部边框
gotoxy(Left() + 1, Top());
for (int i = Left() + 1; i <= Right() - 1; i++)
{
cprintf("%c", 205);
}
// 打印标题
gotoxy((Right() - Left() - strlen(Title)) / 2 + Left(), Top());
cprintf(" %s ", Title);
}
void Window::GetInput(char *Return, const int x, const int Left, const int MaxLen)
{
// 等待用户的输入
// 清空返回字符串
Return[0]='\0';
// 打印输入条
gotoxy(Left - 1, x);
::SetColor(WHITE, BLUE);
for (int i = 0; i < MaxLen + 1; i++)
{
cprintf(" ");
}
// 放置光标位置
gotoxy(Left, x);
// 打开光标
_setcursortype(_NORMALCURSOR);
// 用户输入字符的当前位置
int Len=-1;
// 用户输入的字符
int Key;
do
{
// 等待用户输入
Receive(Key);
switch (Key)
{
case KeyBackSpace:
// 输入的是退格键
if (Len >= 0)
{
// 可以删除最后一位字符
// 删除最后一位
Return[Len] = '\0';
// 清除最后一位的输出
PrintChar(x, Len + Left, ' ');
// 改变长度
Len--;
// 重置光标
gotoxy(Len + Left + 1, x);
}
break;
case KeyEsc:
// 输入的是ESC
// 清空输入
Return[0]='\0';
// 返回
return;
case KeyEnter:
// 回车键
// 删除前部和后部的空格
ClearHeadBlank(Return);
ClearTailBlank(Return);
return;
default:
// 普通字符
Key = (char)Key;
if (Len < MaxLen && isprint(Key))
{
// 接受一个字符
Len++;
// 将该字符添加到返回字符串的末尾
strcat(Return," ");
Return[Len] = Key;
// 输出该字符
PrintChar(x, Len + Left, Key);
}
}
} while (true);
}
void Window::Clear()
{
// 设置垂直滚动条游标位置
VerticalPos = Top() + 2;
// 文本高度清零
TotHigh = 0;
// 无文本行
TotLine = -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -