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

📄 window.cpp

📁 c语言写的VB编译器
💻 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 + -