马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一、软件安装
Visual Studio 2022
Visual Studio 2022 是微软提供的强大集成开发情况(IDE),广泛用于C/C++、C#、Python等多种编程语言的开发。它提供了很多强大的工具,资助开发者编写、调试和优化代码。
1.下载 Visual Studio 2022:访问Visual Studio 官网
2.点击 Download Visual Studio,选择 Community Edition(免费)或其他版本,根据需求选择。
2.安装 Visual Studio:运行下载的安装步伐,启动 Visual Studio 安装步伐。
在安装界面选择 Desktop development with C++,开发 C++ 步伐所需的工作负载。
可以根据必要选择其他组件,好比 Windows 10 SDK、C++ CMake tools 等,资助进行图形和图像处置惩罚的开发,完成安装后,启动 Visual Studio 2022,选择 Create a new project 来创建新的C++项目。(不会安装的可以搜一下干系教程)
安装 EasyX 图形库
1.下载 EasyX 图形库:EasyX官网,根据必要选择符合版本。
2.安装 EasyX:
二、结果演示
1.界面样式
2.读入文件
3.查找
4.插入文字
5.更换
三、代码实现
Text.h:该文件是 Text.cpp 的头文件,声明了文本操作干系的结构体和函数接口。
- Node 结构体:表现链表中的一个字符节点。包含字符内容、字符在屏幕上的位置、是否为平凡字符、是否被选中等信息。
- Text 结构体:表现文本内容,包含头指针、尾指针和当前光标位置。
- File 结构体:表现文件,包含文件路径和文本内容。
- 函数声明:如 readFile()、writeFile()、insertText()、deleteCharacter() 等。
- #pragma once
- /*
- 该模块用于文本的操作
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdbool.h>
- // 该结构体表示链表结点
- typedef struct Node Node;
- struct Node {
- char content[3]; // 表示一个普通字符或中午字符
- int rect[4]; // 字符在屏幕上所占的区域
- bool normal; // 是否是普通字符
- bool selected; // 是否被选中
- Node* next;
- Node* prev;
- };
- // 该结构体表示文本
- typedef struct Text Text;
- struct Text {
- Node* head; // 头指针
- Node* tail; // 尾指针
- Node* cursor; // 当前指针位置
- };
- // 该结构体表示文件
- typedef struct File File;
- struct File {
- char path[256]; // 文件的路径
- Text* text; // 文件的内容
- };
- // 读入文件
- bool readFile(char* path);
- // 写入文件
- void writeFile();
- // 新建文件
- bool createFile(char* path);
- // 保存文件
- bool saveFile(char* path);
- // 获取当前文件
- File* getCurrentFile();
- // 释放相关内存
- void freeResources();
- // 插入文字
- void insertText(char* mContent);
- // 删除字符
- void deleteCharacter(bool isAfter);
- // 重置选中标志
- void resetSelected();
- // 查找字符串
- void findString(char* searchText);
- // 替换字符串
- void replaceString(char* srcText, char* dstText);
复制代码 Text.cpp:实现了文本内容的管理与操作,包罗文件的读取、生存、文本的插入、删除、查找和更换等。它利用了链表结构来构造文本内容。
- readFile():
- 读取指定路径的文件,并将文件内容分析为字符。读取的字符根据其字节数判定是平凡字符还是中文字符,并将其存储到链表中。
- 利用 fread() 函数按字节读取文件内容,若字符为平凡字符,则将其存储在 content[] 中,若为中文字符,则按两个字节读取。
- writeFile():
- 将当前内存中的文本内容(链表结构)生存到文件中。通过 fopen() 打开文件,并逐个节点将文本内容写入。
- createFile():
- 创建新文件并为其分配内存。调用 writeFile() 生存当前文件内容,释放内存,创建新文件,并初始化新的文本结构。
- insertText():
- 在当前光标位置插入文本。通过 appendString() 函数将新的文本插入到链表的对应位置。
- deleteCharacter():
- 删除当前光标位置的字符。通过检查光标的位置(isAfter 参数决定删除前或后字符)来删除指定的字符节点。
- findString():
- 查找指定的字符串,并将找到的部门高亮表现。通过遍历链表中的节点,并检查每个节点的 content 是否与目的字符串匹配。
- replaceString():
- 查找并更换文本中的指定字符串。通过遍历链表查找目的字符串,若找到则更换为指定的新字符串。
- #include "Text.h"
- // 在某个节点后添加字符串
- void appendString(Node** beforeNode, char* mContent, bool modifyBeforeNode);
- // 当前的文件
- static File* curFile = NULL;
- // 为新文件分配内容
- static void initFile(File* file, char* path) {
- strcpy(curFile->path, path);
- curFile->text = (Text*)calloc(1, sizeof(Text));
- curFile->text->head = (Node*)calloc(1, sizeof(Node));
- curFile->text->tail = (Node*)calloc(1, sizeof(Node));
- curFile->text->head->next = curFile->text->tail;
- curFile->text->tail->prev = curFile->text->head;
- curFile->text->cursor = curFile->text->head;
- }
- // 释放文件占用的内存
- static void destroyFile(File** file) {
- while ((*file)->text->head->next != (*file)->text->tail) {
- Node* node = (*file)->text->head->next;
- (*file)->text->head->next = node->next;
- free(node);
- }
- free((*file)->text->head);
- free((*file)->text->tail);
- free(*file);
- *file = NULL;
- }
- // 在Text中添加一个Node
- static void insertNode(Node* beforeNode, char content[], bool normal) {
- Node* node = (Node*)calloc(1, sizeof(Node));
- strcpy(node->content, content);
- node->normal = normal;
- node->selected = false;
- node->next = beforeNode->next;
- node->prev = beforeNode;
- beforeNode->next->prev = node;
- beforeNode->next = node;
- }
- // 读入文件
- bool readFile(char* path) {
- // 确保文件存在
- FILE* file = fopen(path, "rb");
- if (!file) {
- return false;
- }
-
- // 保存当前文件
- writeFile();
- // 释放内存
- if (curFile) {
- destroyFile(&curFile);
- }
- // 为新文件分配内存
- curFile = (File*)calloc(1, sizeof(File));
- initFile(curFile, path);
- // 读取新的文件
- char byte;
- char content[3] = {0};
- bool normal;
- while (fread(&byte, 1, 1, file) == 1) {
- if (byte >= 0) {
- // 这是普通字符
- content[0] = byte;
- if (byte == '\r') {
- char nextByte;
- fread(&nextByte, 1, 1, file);
- content[1] = nextByte;
- normal = false;
- }
- else {
- content[1] = '\0';
- normal = true;
- }
- }
- else {
- // 这是中文,其占2个字节
- char nextByte;
- fread(&nextByte, 1, 1, file);
- content[0] = byte;
- content[1] = nextByte;
- normal = false;
- }
- // 添加当前普通字符或者中文字符到文件的文本中
- insertNode(curFile->text->tail->prev, content, normal);
- }
- fclose(file);
- return true;
- }
- // 写入文件
- void writeFile() {
- if (!curFile) return;
-
- // 把新内容写入文件
- FILE* fp = fopen(curFile->path, "w");
- Node* node = curFile->text->head->next;
- while (node != curFile->text->tail) {
- fprintf(fp, "%s", node->content);
- node = node->next;
- }
- fclose(fp);
- }
- // 新建文件
- bool createFile(char* path) {
- // 保存当前文件
- writeFile();
- // 释放内存
- if (curFile) {
- destroyFile(&curFile);
- }
- FILE* fp = fopen(path, "w");
- if (!fp) return false;
- fclose(fp);
- // 为新文件分配内存
- curFile = (File*)calloc(1, sizeof(File));
- initFile(curFile, path);
- return true;
- }
- // 保存文件
- bool saveFile(char* path) {
- if (!curFile) return false;
- // 把内容写入新的文件
- FILE* fp = fopen(path, "w");
- if (!fp) return false;
- Node* node = curFile->text->head->next;
- while (node != curFile->text->tail) {
- fprintf(fp, "%s", node->content);
- node = node->next;
- }
- fclose(fp);
- return true;
- }
- // 获取当前文件
- File* getCurrentFile() {
- return curFile;
- }
- // 释放相关内存
- void freeResources() {
- if (curFile) {
- destroyFile(&curFile);
- }
- }
- // 插入文字
- void insertText(char* mContent) {
- if (!curFile || !mContent || strlen(mContent) == 0) return;
- // 添加字符串到当前指针后面
- appendString(&curFile->text->cursor, mContent, true);
- }
- // 删除当前字符
- void deleteCharacter(bool isAfter) {
- if (curFile) {
- if (isAfter) {
- // 删除指针后面的字符
- Node* node = curFile->text->cursor->next;
- if (node != curFile->text->tail) {
- curFile->text->cursor->next = node->next;
- node->next->prev = curFile->text->cursor;
- free(node);
- }
- }
- else {
- // 删除指针指向的字符
- Node* node = curFile->text->cursor;
- if (node != curFile->text->head) {
- curFile->text->cursor = node->prev;
- curFile->text->cursor->next = node->next;
- node->next->prev = curFile->text->cursor;
- free(node);
- }
- }
- }
- }
- // 重置选中标志
- void resetSelected() {
- if (!curFile) return;
- Node* node = curFile->text->head->next;
- while (node != curFile->text->tail) {
- node->selected = false;
- node = node->next;
- }
- }
- // 查找字符串
- void findString(char* searchText) {
- if (!curFile) return;
- char content[3] = { 0 };
- char byte;
- size_t len = strlen(searchText);
- Node* curNode = curFile->text->head->next;
- while (curNode != curFile->text->tail) {
- Node* tmpNode = curNode;
- bool isFound = true;
- // 查找子串
- for (int i = 0; i < len && tmpNode != curFile->text->tail; i++) {
- byte = searchText[i];
- if (byte >= 0) {
- // 这是普通字符
- content[0] = byte;
- if (byte == '\r') {
- char nextByte = searchText[++i];
- content[1] = nextByte;
- }
- else {
- content[1] = '\0';
- }
- }
- else {
- // 这是中文,其占2个字节
- char nextByte = searchText[++i];
- content[0] = byte;
- content[1] = nextByte;
- }
- // 判断两个字符是否相同
- if (strcmp(tmpNode->content, content) != 0) {
- isFound = false;
- break;
- }
- tmpNode = tmpNode->next;
- }
- if (isFound) {
- // 设置对应的字符序列为选中
- Node* node = curNode;
- while (node != tmpNode) {
- node->selected = true;
- node = node->next;
- }
- }
- curNode = curNode->next;
- }
- }
- // 在某个节点后添加字符串
- void appendString(Node** beforeNode, char* mContent, bool modifyBeforeNode) {
- int i = 0;
- char byte;
- bool normal;
- char content[3] = { 0 };
- size_t len = strlen(mContent);
- Node* prev = *beforeNode;
- while (i < len) {
- byte = mContent[i];
- if (byte >= 0) {
- // 这是普通字符
- content[0] = byte;
- if (byte == '\r') {
- char nextByte = mContent[++i];
- content[1] = nextByte;
- normal = false;
- }
- else {
- content[1] = '\0';
- normal = true;
- }
- }
- else {
- // 这是中文,其占2个字节
- char nextByte = mContent[++i];
- content[0] = byte;
- content[1] = nextByte;
- normal = false;
- }
- // 添加当前普通字符或者中文字符到该指针后面
- insertNode(prev, content, normal);
- prev = prev->next;
- if (modifyBeforeNode) {
- *beforeNode = prev;
- }
- i++;
- }
- }
- // 替换字符串
- void replaceString(char* srcText, char* dstText) {
- if (!curFile) return;
- char content[3] = { 0 };
- char byte;
- size_t len = strlen(srcText);
- Node* curNode = curFile->text->head->next;
- while (curNode != curFile->text->tail) {
- Node* tmpNode = curNode;
- bool isFound = true;
- // 查找子串
- for (int i = 0; i < len && tmpNode != curFile->text->tail; i++) {
- byte = srcText[i];
- if (byte >= 0) {
- // 这是普通字符
- content[0] = byte;
- if (byte == '\r') {
- char nextByte = srcText[++i];
- content[1] = nextByte;
- }
- else {
- content[1] = '\0';
- }
- }
- else {
- // 这是中文,其占2个字节
- char nextByte = srcText[++i];
- content[0] = byte;
- content[1] = nextByte;
- }
- // 判断两个字符是否相同
- if (strcmp(tmpNode->content, content) != 0) {
- isFound = false;
- break;
- }
- tmpNode = tmpNode->next;
- }
- if (isFound) {
- // 首先删除原字符串
- Node* beforeNode = curNode->prev;
- while (beforeNode->next != tmpNode) {
- Node* node = beforeNode->next;
- beforeNode->next = node->next;
- node->next->prev = beforeNode;
- free(node);
- }
- curNode = tmpNode;
- // 添加替换字符串
- appendString(&beforeNode, dstText, false);
- }
- else {
- curNode = curNode->next;
- }
- }
- }
复制代码 Editor.h:是 Editor.cpp 的头文件,声明了文本编辑器干系的函数接口,确保其他文件可以大概调用 Editor.cpp 中定义的函数。
声明了文本编辑器干系的函数,如:
- initTextEditor():初始化编辑器。
- runTextEditor():运行编辑器的主循环。
- destroyTextEditor():烧毁编辑器。
- #pragma once
- /*
- 该模块用于显示文本编辑器的界面和用户交互
- */
- // 初始化文本编辑器
- void initTextEditor();
- // 运行文本编辑器
- void runTextEditor();
- // 销毁文本编辑器
- void destroyTextEditor();
复制代码 Editor.cpp:文本编辑器的核心,负责创建并表现图形界面,同时处置惩罚文件操作、文本编辑、用户输入变乱等。它利用 EasyX 图形库来绘制窗口和菜单,支持文件的读写操作、文本的插入与删除、文本的查找和更换。
- initTextEditor():
- 初始化文本编辑器,创建窗口并设置配景致。
- 利用 initgraph() 函数来初始化窗口,setbkcolor() 设置配景致为白色,SetWindowText() 设置窗口的标题为 "文本编辑器"。
- 还通过 readResources() 函数加载图像资源(如 editor.png),并设置图形界面的直线样式。
- runTextEditor():
- 启动文本编辑器的主循环。在这个循环中,步伐不绝更新窗口,扫除设备并重新绘制全部组件(如菜单和文当地域)。
- 处置惩罚键盘变乱(如删除字符)和鼠标点击变乱(如选择菜单项):
- 键盘变乱:当按下删除键(VK_BACK)时,删除当前光标位置的字符。
- 鼠标变乱:检测鼠标点击的地域,根据用户点击的菜单项执行不同操作,如读入文件、写入文件、新建文件等。
- drawWindow():
- 用于绘制编辑器窗口,包罗配景图像、菜单地域和文当地域。
- 利用 putimage() 函数绘制配景图像,并调用 drawMenu() 和 drawText() 来绘制菜单和文当地域。
- drawMenu():
- 绘制顶部的菜单地域,包罗文件操作(如读入、写入、生存等)和文本编辑操作(如插入文本、查找、更换)。
- 利用 outtextxy() 函数绘制菜单项文本,并用 roundrect() 绘制按钮。
- InsertText():
- 提示用户输入要插入的文字,并调用 insertText() 函数将文字插入到当前光标位置。
- FindString():
- 查找字符串。调用 findString() 函数查找指定的字符串并将找到的文本高亮表现。
- ReplaceString():
- 更换字符串。通过 replaceString() 函数,查找指定的原字符串并将其更换为新字符串。
- #include "Editor.h"
- #include <graphics.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdbool.h>
- #include <time.h>
- #include <math.h>
- #include "Text.h"
- // 窗口大小
- static int WINDOW_WIDTH = 1000;
- static int WINDOW_HEIGHT = 700;
- // 设置每帧的时间
- static double FPS = 30;
- static double PER_FRAME_TIME = 1000.0 / FPS;
- // 查找字符串
- static char searchText[256] = {0};
- // 原字符串
- static char sourceText[256] = { 0 };
- // 替换字符串
- static char replaceText[256] = { 0 };
- // 设置菜单区域的位置
- static int MENU_LEFT_TOP[] = { 10, 80 };
- static int MENU_RIGHT_BOTTOM[] = { 900, 220 };
- static int PADDING[] = {50, 16};
- // 读入文件菜单位置
- static int READ_FILE_MENU[] = { MENU_LEFT_TOP[0] + PADDING[0], MENU_LEFT_TOP[1] + PADDING[1],
- MENU_LEFT_TOP[0] + PADDING[0] + 104, MENU_LEFT_TOP[1] + PADDING[1] + 25 };
- // 写入文件菜单位置
- static int WRITE_FILE_MENU[] = { READ_FILE_MENU[2] + PADDING[0], MENU_LEFT_TOP[1] + PADDING[1],
- READ_FILE_MENU[2] + PADDING[0] + 104, MENU_LEFT_TOP[1] + PADDING[1] + 25 };
- // 新建文件菜单位置
- static int CREATE_FILE_MENU[] = { WRITE_FILE_MENU[2] + PADDING[0], MENU_LEFT_TOP[1] + PADDING[1],
- WRITE_FILE_MENU[2] + PADDING[0] + 104, MENU_LEFT_TOP[1] + PADDING[1] + 25 };
- // 保存文件菜单位置
- static int SAVE_FILE_MENU[] = { CREATE_FILE_MENU[2] + PADDING[0], MENU_LEFT_TOP[1] + PADDING[1],
- CREATE_FILE_MENU[2] + PADDING[0] + 104, MENU_LEFT_TOP[1] + PADDING[1] + 25 };
- // 退出菜单位置
- static int EXIT_MENU[] = { SAVE_FILE_MENU[2] + PADDING[0], MENU_LEFT_TOP[1] + PADDING[1],
- SAVE_FILE_MENU[2] + PADDING[0] + 52, MENU_LEFT_TOP[1] + PADDING[1] + 25 };
- // 编辑文件菜单位置
- static int EDIT_FILE_MENU[] = { MENU_LEFT_TOP[0] + PADDING[0], READ_FILE_MENU[3] + PADDING[1],
- MENU_LEFT_TOP[0] + PADDING[0] + 104, READ_FILE_MENU[3] + PADDING[1] + 25 };
- // 插入菜单位置
- static int INSERT_TEXT_MENU[] = { MENU_LEFT_TOP[0] + PADDING[0], EDIT_FILE_MENU[3] + PADDING[1],
- MENU_LEFT_TOP[0] + PADDING[0] + 104, EDIT_FILE_MENU[3] + PADDING[1] + 25 };
- // 查找文本位置
- static int SEARCH_TEXT[] = { EDIT_FILE_MENU[2] + PADDING[0], READ_FILE_MENU[3] + PADDING[1],
- EDIT_FILE_MENU[2] + PADDING[0] + 208, READ_FILE_MENU[3] + PADDING[1] + 25 };
- // 查找菜单位置
- static int FIND_MENU[] = { SEARCH_TEXT[2] + PADDING[0], READ_FILE_MENU[3] + PADDING[1],
- SEARCH_TEXT[2] + PADDING[0] + 52, READ_FILE_MENU[3] + PADDING[1] + 25 };
- // 清除高亮菜单位置
- static int CLEAR_MENU[] = { FIND_MENU[2] + PADDING[0], READ_FILE_MENU[3] + PADDING[1],
- FIND_MENU[2] + PADDING[0] + 104, READ_FILE_MENU[3] + PADDING[1] + 25 };
- // 原文本位置
- static int SOURCE_TEXT[] = { EDIT_FILE_MENU[2] + PADDING[0], FIND_MENU[3] + PADDING[1],
- EDIT_FILE_MENU[2] + PADDING[0] + 208, FIND_MENU[3] + PADDING[1] + 25 };
- // 替换文本位置
- static int REPLACE_TEXT[] = { SOURCE_TEXT[2] + PADDING[0], FIND_MENU[3] + PADDING[1],
- SOURCE_TEXT[2] + PADDING[0] + 208, FIND_MENU[3] + PADDING[1] + 25 };
- // 替换菜单位置
- static int REPLACE_MENU[] = { REPLACE_TEXT[2] + PADDING[0], FIND_MENU[3] + PADDING[1],
- REPLACE_TEXT[2] + PADDING[0] + 52, FIND_MENU[3] + PADDING[1] + 25 };
- // 文本区域位置
- static int TEXT_AREA[] = { 10, MENU_RIGHT_BOTTOM[1] + PADDING[1],
- WINDOW_WIDTH-20, WINDOW_HEIGHT - 20 };
- // 图片资源
- static IMAGE editorImage;
- // 读取图片资源
- static void readResources();
- // 绘制窗口
- static void drawWindow();
- // 绘制菜单区域
- static void drawMenu();
- // 绘制文本区域
- static void drawText();
- // 读入文件
- static void ReadFile();
- // 写入文件
- static void WriteFile();
- // 新建文件
- static void CreateNewFile();
- // 保存文件
- static void SaveFile();
- // 插入文字
- static void InsertText();
- // 查找
- static void FindString();
- // 清除输入
- static void ClearInput();
- // 替换
- static void ReplaceString();
- // 更新文件指针位置
- static void updateCursor(int x, int y);
- // 初始化文本编辑器
- void initTextEditor() {
- // 创建窗口
- initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);
- setbkcolor(RGB(255, 255, 255));
- // 设置窗口名称
- HWND hWnd = GetHWnd();
- SetWindowText(hWnd, "文本编辑器");
- // 读取图片资源
- readResources();
- // 设置直线样式
- LINESTYLE style;
- style.thickness = 2;
- setlinestyle(&style);
- }
- // 运行文本编辑器
- void runTextEditor() {
- bool exitCode = false;
- while (!exitCode) {
- int startTime = clock();
- // 双缓冲
- BeginBatchDraw();
- cleardevice();
- // 绘制窗口
- drawWindow();
- EndBatchDraw();
- // 处理消息
- static ExMessage msg;
- while (peekmessage(&msg, EM_KEY | EM_MOUSE)) {
- // 键盘按下事件
- if (msg.message == WM_KEYDOWN) {
- if (msg.vkcode == VK_BACK) {
- // 删除指针指向的字符
- deleteCharacter(false);
- }
- else if (msg.vkcode == VK_DELETE) {
- // 删除指针后面的字符
- deleteCharacter(true);
- }
- }
- // 鼠标左键按下事件
- else if (msg.message == WM_LBUTTONDOWN) {
- int x = msg.x;
- int y = msg.y;
- // 点击了读入文件按钮
- if (x > READ_FILE_MENU[0] && x < READ_FILE_MENU[2] &&
- y > READ_FILE_MENU[1] && y < READ_FILE_MENU[3]) {
- ReadFile();
- }
- // 点击了写入文件按钮
- else if (x > WRITE_FILE_MENU[0] && x < WRITE_FILE_MENU[2] &&
- y > WRITE_FILE_MENU[1] && y < WRITE_FILE_MENU[3]) {
- WriteFile();
- }
- // 点击了创建文件按钮
- else if (x > CREATE_FILE_MENU[0] && x < CREATE_FILE_MENU[2] &&
- y > CREATE_FILE_MENU[1] && y < CREATE_FILE_MENU[3]) {
- CreateNewFile();
- }
- // 点击了保存文件按钮
- else if (x > SAVE_FILE_MENU[0] && x < SAVE_FILE_MENU[2] &&
- y > SAVE_FILE_MENU[1] && y < SAVE_FILE_MENU[3]) {
- SaveFile();
- }
- // 点击了退出按钮
- else if (x > EXIT_MENU[0] && x < EXIT_MENU[2] &&
- y > EXIT_MENU[1] && y < EXIT_MENU[3]) {
- // 释放相关内存
- freeResources();
- exitCode = true;
- break;
- }
- // 点击了插入文字按钮
- else if (x > INSERT_TEXT_MENU[0] && x < INSERT_TEXT_MENU[2] &&
- y > INSERT_TEXT_MENU[1] && y < INSERT_TEXT_MENU[3]) {
- InsertText();
- }
- // 点击了查找按钮
- else if (x > FIND_MENU[0] && x < FIND_MENU[2] &&
- y > FIND_MENU[1] && y < FIND_MENU[3]) {
- FindString();
- }
- // 点击了清楚高亮按钮
- else if (x > CLEAR_MENU[0] && x < CLEAR_MENU[2] &&
- y > CLEAR_MENU[1] && y < CLEAR_MENU[3]) {
- ClearInput();
- }
- // 点击了替换按钮
- else if (x > REPLACE_MENU[0] && x < REPLACE_MENU[2] &&
- y > REPLACE_MENU[1] && y < REPLACE_MENU[3]) {
- ReplaceString();
- }
- // 点击了文本区域
- else if (x > TEXT_AREA[0] && x < TEXT_AREA[2] &&
- y > TEXT_AREA[1] && y < TEXT_AREA[3]) {
- updateCursor(x, y);
- }
- // 输入查找字符串
- else if (x > SEARCH_TEXT[0] && x < SEARCH_TEXT[2] &&
- y > SEARCH_TEXT[1] && y < SEARCH_TEXT[3]) {
- InputBox(searchText, 255, "输入查找字符串:");
- }
- // 输入原字符串
- else if (x > SOURCE_TEXT[0] && x < SOURCE_TEXT[2] &&
- y > SOURCE_TEXT[1] && y < SOURCE_TEXT[3]) {
- InputBox(sourceText, 255, "输入原字符串:");
- }
- // 输入替换字符串
- else if (x > REPLACE_TEXT[0] && x < REPLACE_TEXT[2] &&
- y > REPLACE_TEXT[1] && y < REPLACE_TEXT[3]) {
- InputBox(replaceText, 255, "输入替换字符串:");
- }
- }
- }
- // 控制每帧时间
- int duration = clock() - startTime;
- if (duration < PER_FRAME_TIME) {
- Sleep(PER_FRAME_TIME - duration);
- }
- }
- }
- // 销毁文本编辑器
- void destroyTextEditor() {
- closegraph();
- }
- // 读取图片资源
- static void readResources() {
- loadimage(&editorImage, "editor.png");
- }
- // 绘制窗口
- static void drawWindow() {
- // 绘制编辑器图片
- putimage(0, 0, &editorImage);
- // 绘制菜单区域
- drawMenu();
- // 绘制文本区域
- drawText();
- }
- // 绘制菜单区域
- static void drawMenu() {
- // 设置字体
- LOGFONT f;
- gettextstyle(&f);
- f.lfHeight = 25;
- _tcscpy(f.lfFaceName, _T("黑体"));
- f.lfQuality = ANTIALIASED_QUALITY;
- f.lfWeight = 800;
- settextstyle(&f);
- settextcolor(RGB(0, 0, 0));
- // 绘制文件编辑器的菜单
- setlinecolor(RGB(0, 0, 0));
- rectangle(MENU_LEFT_TOP[0], MENU_LEFT_TOP[1], MENU_RIGHT_BOTTOM[0], MENU_RIGHT_BOTTOM[1]);
- // 读入文件菜单
- outtextxy(READ_FILE_MENU[0], READ_FILE_MENU[1], "读入文件");
- roundrect(READ_FILE_MENU[0], READ_FILE_MENU[1], READ_FILE_MENU[2], READ_FILE_MENU[3], 5, 5);
- // 写入文件菜单
- outtextxy(WRITE_FILE_MENU[0], WRITE_FILE_MENU[1], "写入文件");
- roundrect(WRITE_FILE_MENU[0], WRITE_FILE_MENU[1], WRITE_FILE_MENU[2], WRITE_FILE_MENU[3], 5, 5);
- // 新建文件菜单
- outtextxy(CREATE_FILE_MENU[0], CREATE_FILE_MENU[1], "新建文件");
- roundrect(CREATE_FILE_MENU[0], CREATE_FILE_MENU[1], CREATE_FILE_MENU[2], CREATE_FILE_MENU[3], 5, 5);
- // 保存文件菜单
- outtextxy(SAVE_FILE_MENU[0], SAVE_FILE_MENU[1], "保存文件");
- roundrect(SAVE_FILE_MENU[0], SAVE_FILE_MENU[1], SAVE_FILE_MENU[2], SAVE_FILE_MENU[3], 5, 5);
- // 退出菜单
- outtextxy(EXIT_MENU[0], EXIT_MENU[1], "退出");
- roundrect(EXIT_MENU[0], EXIT_MENU[1], EXIT_MENU[2], EXIT_MENU[3], 5, 5);
- // 编辑文件菜单
- outtextxy(EDIT_FILE_MENU[0], EDIT_FILE_MENU[1], "编辑文件");
- // 插入菜单
- outtextxy(INSERT_TEXT_MENU[0], INSERT_TEXT_MENU[1], "插入文字");
- roundrect(INSERT_TEXT_MENU[0], INSERT_TEXT_MENU[1], INSERT_TEXT_MENU[2], INSERT_TEXT_MENU[3], 5, 5);
- // 查找菜单
- outtextxy(FIND_MENU[0], FIND_MENU[1], "查找");
- roundrect(FIND_MENU[0], FIND_MENU[1], FIND_MENU[2], FIND_MENU[3], 5, 5);
- // 清除输入菜单
- outtextxy(CLEAR_MENU[0], CLEAR_MENU[1], "清除输入");
- roundrect(CLEAR_MENU[0], CLEAR_MENU[1], CLEAR_MENU[2], CLEAR_MENU[3], 5, 5);
- // 替换菜单
- outtextxy(REPLACE_MENU[0], REPLACE_MENU[1], "替换");
- roundrect(REPLACE_MENU[0], REPLACE_MENU[1], REPLACE_MENU[2], REPLACE_MENU[3], 5, 5);
- // 设置字体
- gettextstyle(&f);
- f.lfHeight = 18;
- _tcscpy(f.lfFaceName, _T("宋体"));
- f.lfQuality = ANTIALIASED_QUALITY;
- f.lfWeight = 800;
- settextstyle(&f);
- settextcolor(RGB(0, 0, 0));
- // 查找文本
- if (strlen(searchText) > 0) {
- outtextxy(SEARCH_TEXT[0], SEARCH_TEXT[1]+3, searchText);
- }
- roundrect(SEARCH_TEXT[0], SEARCH_TEXT[1], SEARCH_TEXT[2], SEARCH_TEXT[3], 5, 5);
- // 原文本
- if (strlen(sourceText) > 0) {
- outtextxy(SOURCE_TEXT[0], SOURCE_TEXT[1] + 3, sourceText);
- }
- roundrect(SOURCE_TEXT[0], SOURCE_TEXT[1], SOURCE_TEXT[2], SOURCE_TEXT[3], 5, 5);
- // 替换文本
- if (strlen(replaceText) > 0) {
- outtextxy(REPLACE_TEXT[0], REPLACE_TEXT[1] + 3, replaceText);
- }
- roundrect(REPLACE_TEXT[0], REPLACE_TEXT[1], REPLACE_TEXT[2], REPLACE_TEXT[3], 5, 5);
- }
- // 绘制文本区域
- static void drawText() {
- // 设置字体
- LOGFONT f;
- gettextstyle(&f);
- f.lfHeight = 20;
- f.lfWeight = 600;
- _tcscpy(f.lfFaceName, _T("宋体"));
- f.lfQuality = ANTIALIASED_QUALITY;
- settextstyle(&f);
- settextcolor(RGB(0, 0, 0));
- // 显示文本区域框
- rectangle(TEXT_AREA[0], TEXT_AREA[1], TEXT_AREA[2], TEXT_AREA[3]);
- // 显示文件内容
- File* file = getCurrentFile();
- if (!file) return;
- int leftX = TEXT_AREA[0] + 5;
- int x = leftX;
- int y = TEXT_AREA[1] + 5;
- int w = textwidth("a");
- int h = f.lfHeight;
- Node* node = file->text->head->next;
- // 设置头指针的位置
- file->text->head->rect[0] = TEXT_AREA[0]+4;
- file->text->head->rect[1] = y;
- file->text->head->rect[2] = TEXT_AREA[0]+4;
- file->text->head->rect[3] = y;
- // 如果文件是空的,则在开头显示指针
- if (node == file->text->tail) {
- line(node->prev->rect[2], node->prev->rect[1], node->prev->rect[2], node->prev->rect[1] + h);
- return;
- }
- while (node != file->text->tail) {
- // 设置字符所占的区域
- node->rect[0] = x;
- node->rect[1] = y;
- node->rect[2] = x + (node->normal ? w : w*2);
- node->rect[3] = y + h;
- // 判断是否需要换行
- if (strcmp(node->content, "\r\n") == 0 || strcmp(node->content, "\n") == 0
- || node->rect[2] >= TEXT_AREA[2]) {
- // 需要换行,更新位置
- x = leftX;
- y += f.lfHeight;
- node->rect[0] = x;
- node->rect[1] = y;
- node->rect[2] = x + (node->normal ? w : w * 2);
- node->rect[3] = y + h;
- }
- if (strcmp(node->content, "\r\n") != 0 && strcmp(node->content, "\n") != 0) {
- // 如果字符被选中,则更改颜色
- if (node->selected) {
- setcolor(RED);
- }
- else {
- setcolor(BLACK);
- }
- // 显示该字符
- outtextxy(node->rect[0], node->rect[1], node->content);
- // 更新x值
- x = node->rect[2];
- }
- // 绘制当前位置指针
- if (file->text->cursor == node->prev) {
- line(node->prev->rect[2], node->prev->rect[1], node->prev->rect[2], node->prev->rect[1] + h);
- }
- else if (file->text->cursor == node && node->next == file->text->tail) {
- line(node->rect[2], node->rect[1], node->rect[2], node->rect[1] + h);
- }
- node = node->next;
- }
- }
- // 更新文件指针位置
- static void updateCursor(int x, int y) {
- File* file = getCurrentFile();
- if (!file) return;
- // 设置文件指针到最靠近鼠标的文字的位置(距离不能超过26)
- int minDistance = INT_MAX;
- Node* node = file->text->head->next;
- while (node != file->text->tail) {
- if (x > node->rect[0] && x < node->rect[2] &&
- y > node->rect[1] && y < node->rect[3]) {
- file->text->cursor = node;
- break;
- }
- else {
- // 判断该文字是否更加靠近鼠标点击的位置
- int dx = (node->rect[0] + node->rect[2]) / 2 - x;
- int dy = (node->rect[1] + node->rect[3]) / 2 - y;
- double dist = sqrt(dx * dx + dy * dy);
- if (dist < 26 && dist < minDistance) {
- minDistance = dist;
- file->text->cursor = node;
- }
- }
- node = node->next;
- }
- }
- // 读入文件
- static void ReadFile() {
- // 提示用户输入文件路径
- char path[256];
- InputBox(path, 255, "输入文件路径:");
- // 读入文件内容
- if (!readFile(path)) {
- MessageBox(GetHWnd(), "该文件不存在", "提示", MB_OK);
- }
- }
- // 写入文件
- static void WriteFile() {
- if (getCurrentFile()) {
- writeFile();
- MessageBox(GetHWnd(), "内容已被写入文件", "提示", MB_OK);
- }
- }
- // 新建文件
- static void CreateNewFile() {
- // 提示用户输入文件路径
- char path[256];
- InputBox(path, 255, "输入文件路径:");
- // 创建新的文件
- if (!createFile(path)) {
- MessageBox(GetHWnd(), "创建文件失败", "提示", MB_OK);
- }
- }
- // 保存文件
- static void SaveFile() {
- // 提示用户输入文件路径
- char path[256];
- InputBox(path, 255, "输入文件路径:");
- if (!saveFile(path)) {
- MessageBox(GetHWnd(), "保存文件失败", "提示", MB_OK);
- }
- else {
- MessageBox(GetHWnd(), "文件已被保存", "提示", MB_OK);
- }
- }
- // 插入文字
- static void InsertText() {
- // 提示输入要插入的文字
- char content[256];
- InputBox(content, 255, "输入要插入的文字:");
- // 把该文字插入指针所在位置
- insertText(content);
- }
- // 查找
- static void FindString() {
- resetSelected();
- if (strlen(searchText) > 0) {
- findString(searchText);
- }
- }
- // 清除输入
- static void ClearInput() {
- memset(searchText, 0, sizeof(searchText));
- memset(sourceText, 0, sizeof(sourceText));
- memset(replaceText, 0, sizeof(replaceText));
- // 重置选中标志
- resetSelected();
- }
- // 替换
- static void ReplaceString() {
- if (strlen(sourceText) > 0 && strlen(replaceText) > 0) {
- replaceString(sourceText, replaceText);
- }
- }
复制代码 Main.cpp:步伐的入口文件,紧张用于启动文本编辑器的初始化、运行和烧毁。
main():
- 步伐启动时起首调用 initTextEditor() 函数初始化文本编辑器。
- 接着调用 runTextEditor() 启动文本编辑器的主循环,答应用户进行各种操作(如文件操作、文本编辑等)。
- 末了通过 destroyTextEditor() 烧毁编辑器,释放资源。
- #include "Editor.h"
- int main() {
- // 初始化文本编辑器
- initTextEditor();
- // 运行文本编辑器
- runTextEditor();
- // 销毁文本编辑器
- destroyTextEditor();
- return 0;
- }
复制代码
|