【自制C/C++小项目JuLongEditor】使用Windows控制台API来制作一个简单的文本编辑器

2023-11-16

2023年8月22日,周二下午

昨天花了一个下午和晚上来制作的,

实现了一些基本的功能,

但由于代码只有130行,所以存在很多不足之处


GitHub:GitHub - JuLongZhiLu/JuLongEditor: C/C++小项目,使用Windows控制台API来制作一个简单的文本编辑器,只有130行代码


#include <windows.h>
#include <conio.h>
using namespace std;

//设置编辑器的能容纳的文本大小,最多10行80列
const int MAX_ROWS = 10;
const int MAX_COLS = 80;

CHAR_INFO buffer[MAX_ROWS][MAX_COLS];//二维字符数组,用来构成文本
COORD cursorPos;//专门坐标位置的数据结构
CONSOLE_SCREEN_BUFFER_INFO csbi;//控制台屏幕缓冲区信息

//初始化二维字符数组
void initBuffer() {
	for (int i = 0; i < MAX_ROWS; i++) {
		for (int j = 0; j < MAX_COLS; j++) {
			buffer[i][j].Char.AsciiChar = ' ';
			buffer[i][j].Attributes = FOREGROUND_BLUE;
		}
	}
}

//初始化坐标数据结构
void initCursor() {
	cursorPos.X = 0;
	cursorPos.Y = 0;
}

//把构成文本的二维数组打印到控制台
void drawBuffer(HANDLE console) {
	SMALL_RECT rect;
	rect.Top = 0;
	rect.Left = 0;
	rect.Bottom = MAX_ROWS - 1;
	rect.Right = MAX_COLS - 1;

	WriteConsoleOutputA(console, (CHAR_INFO*)buffer, { MAX_COLS, MAX_ROWS }, { 0, 0 }, &rect);
}

//处理键盘按键
void ProcessKeys(int key, HANDLE console) {
	if (key == 0 || key == 224) {  //如果是方向键和删除键
		key = _getch();
		switch (key) {
		case 72: // 上
			if (cursorPos.Y != 0)
				cursorPos.Y--;
			SetConsoleCursorPosition(console, cursorPos);//移动光标到指定位置
			break;
		case 80: // 下
			cursorPos.Y++;
			SetConsoleCursorPosition(console, cursorPos);//移动光标到指定位置
			break;
		case 75: // 左
			if (cursorPos.X != 0)
				cursorPos.X--;
			if (cursorPos.Y != 0 && cursorPos.X == 0)
				cursorPos.Y--;
			SetConsoleCursorPosition(console, cursorPos);
			break;
		case 77: // 右
			if (cursorPos.X != MAX_COLS)//如果一行的字符数没超过最大列数,那么光标就右移一位
				cursorPos.X++;
			else
			{
				cursorPos.X = 0;//如果超过了,就换行
				cursorPos.Y++;
			}
			SetConsoleCursorPosition(console, cursorPos);
			break;
		case 83: //删除键
			buffer[cursorPos.Y][cursorPos.X - 1].Char.AsciiChar = ' ';
			buffer[cursorPos.Y][cursorPos.X - 1].Attributes = FOREGROUND_BLUE;
			if (cursorPos.X != 0)
				cursorPos.X--;
			if (cursorPos.Y != 0 && cursorPos.X == 0)
				cursorPos.Y--;
			SetConsoleCursorPosition(console, cursorPos);
			drawBuffer(console);
			break;
		}
	}
	else if (key == 13) {//如果是换行键
		cursorPos.X = 0;
		cursorPos.Y++;
		SetConsoleCursorPosition(console, cursorPos);	//在输出设备上定位光标
	}
	else if (key == 8) {  // 如果是回退键(Backspace键)
		buffer[cursorPos.Y][cursorPos.X - 1].Char.AsciiChar = ' ';
		buffer[cursorPos.Y][cursorPos.X - 1].Attributes = FOREGROUND_BLUE;
		if (cursorPos.X != 0)
			cursorPos.X--;
		if (cursorPos.Y != 0 && cursorPos.X == 0)
			cursorPos.Y--;
		SetConsoleCursorPosition(console, cursorPos);
		drawBuffer(console);
	}
	else {//如果是输入文本
		buffer[cursorPos.Y][cursorPos.X].Char.AsciiChar = (char)key;
		buffer[cursorPos.Y][cursorPos.X].Attributes = FOREGROUND_BLUE;
		drawBuffer(console);
		cursorPos.X++;
		SetConsoleCursorPosition(console, cursorPos);
		drawBuffer(console);
	}
}

void input(HANDLE console) {

	while (true)
	{
		GetConsoleScreenBufferInfo(console, &csbi);	//获取屏幕缓冲的光标位置,然后把当前光标位置赋给COORD
		cursorPos.X = csbi.dwCursorPosition.X;			//得到坐标x的值
		cursorPos.Y = csbi.dwCursorPosition.Y;			//y值

		if (_kbhit()) {
			int key = _getch();
			ProcessKeys(key, console);
		}
	}
}

int main() {
	initBuffer();
	initCursor();
	HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
	input(console);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【自制C/C++小项目JuLongEditor】使用Windows控制台API来制作一个简单的文本编辑器 的相关文章

  • 在C语言中使用“void”

    我很困惑为什么我们需要通过void转换为 C 函数 int f void return 0 versus int f return 0 什么是正确的做法以及为什么 In C int f 是一种老式的声明 它说f需要固定但未指定数量和类型的参
  • 具有子列表属性映射问题的自动映射器

    我有以下型号 Models public class Dish Required public Int64 ID get set Required public string Name get set Required public str
  • asp.net 文本框文本模式数字,仅允许数字

    我只是想知道 ASP NET 中是否有一种方法只允许文本框中的数字textmode number 当我使用这个时
  • 我的线程图像生成应用程序如何将其数据传输到 GUI?

    Mandelbrot 生成器的缓慢多精度实现 线程化 使用 POSIX 线程 Gtk 图形用户界面 我有点失落了 这是我第一次尝试编写线程程序 我实际上并没有尝试转换它的单线程版本 只是尝试实现基本框架 到目前为止它是如何工作的简要描述 M
  • 使用具有现有访问令牌的 Google API .NET 客户端

    用例如下 移动应用程序正在通过 Google 对用户进行身份验证 并且在某些时候 我们需要将用户的视频发布到他的 YouTube 帐户 出于实际原因 实际发布应该由后端完成 已经存储在那里的大文件 由于用户已经通过应用程序的身份验证 因此应
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 使用post方法将多个参数发送到asp.net core 3 mvc操作

    使用 http post 方法向 asp net mvc core 3 操作发送具有多个参数的 ajax 请求时存在问题 参数不绑定 在 dot net 框架 asp net web api 中存在类似的限制 但在 asp net mvc
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • 在非活动联合成员上使用“std::addressof”是否定义明确[重复]

    这个问题在这里已经有答案了 下面的代码是尝试实现constexpr的版本offsetof在 C 11 中 它可以在 gcc 7 2 0 和 clang 5 0 0 中编译 这取决于申请std addressof工会非活跃成员的成员 这是明确
  • 在 C 中使用 GNU automake 中的解析器

    我是 GNU autotools 的新手 在我的项目中使用了 lex 和 yacc 解析器 将它们作为 makefile am 中的源代码会产生以下错误 配置 in AC CHECK PROGS YACC bison yacc none i
  • 当我“绘制”线条时,如何将点平均分配到 LineRenderer 的宽度曲线?

    我正在使用线条渲染器创建一个 绘图 应用程序 现在我尝试使用线条渲染器上的宽度曲线启用笔压 问题在于 AnimationCurve 的 时间 值 水平轴 从 0 标准化为 1 因此我不能在每次添加位置时都在其末尾添加一个值 除非有一个我不知
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • 为什么拆箱枚举会产生奇怪的结果?

    考虑以下 Object box 5 int int int box int 5 int nullableInt box as int nullableInt 5 StringComparison enum StringComparison
  • strcmp 给出分段错误[重复]

    这个问题在这里已经有答案了 这是我的代码给出分段错误 include
  • 双精度类型二维多维数组的 pinvoke 编组作为 c# 和 c++ 之间的输入和输出

    我有以下我正在尝试解决的双物质类型的 2d 多维数组的 c 和 c pinvoke 编组 我已经查看了以下热门内容以获得我目前拥有的内容使用双精度数组进行 P Invoke 在 C 和 C 之间编组数据 https stackoverflo
  • 用于 C# XNA 的 Javascript(或类似)游戏脚本

    最近我准备用 XNA C 开发另一个游戏 上次我在 XNA C 中开发游戏时 遇到了必须向游戏中添加地图和可自定义数据的问题 每次我想添加新内容或更改游戏角色的某些值或其他内容时 我都必须重建整个游戏或其他内容 这可能需要相当长的时间 有没

随机推荐