让我们写一个 Win32 文本编辑器吧 - 1. 简介
Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475
让我们写一个 Win32 文本编辑器吧 - 1. 简介
在之前的一篇文章 《曾经我认为C语言就是个弟弟》 中,我们通过使用
Windows
系统自带的EDIT
控件,创建了一个简单的文本编辑器。而且在文章的最后,还承诺要不使用EDIT
控件,自己制作一个十六进制编辑器。后来想到,既然十六进制编辑器都做了,作为一个程序员,不如写一个文本编辑器吧,既可以编辑二进制,又可以编辑文本,岂不美哉。
由于实现一个编辑器的复杂性相对比较大,一篇内容肯定完不成。所以,这里决定将整个过程作为一个系列来编辑。
本篇是系列的第一篇。在本篇文章中,将会对我们期望获得的结果进行简单的描述,并进行基础代码框架进行构建。
本文主要包含两个部分,如下:
- 项目简介
在项目简介部分,将会对我们要实现的目标编辑器的样子,以及使用方法进行介绍。同时,也会对本系列接下来的文章要讨论的主题进行大致说明。
- 基础代码框架搭建
在代码框架搭建部分,将会对项目的创建,设置进行说明。并编辑我们的基础代码。
1. 项目简介
a. 目标
在
Windows11
中,已经将记事本的编辑控件由EDIT
替换为RichEditD2DPT
,详情参考Windows 11 Notepad
。但是由于关于RichEditD2DPT
控件的描述太少,不知道其具体的用方法。
所以,这里我们以EDIT
控件的接口为准,并实现附加功能。
在此,我们的目标是:通过 C
语言,调用 Win32
接口,生成一个文本编辑器。目标编辑器除了实现和 Windows
提供的默认文本编辑器 EDIT
的所有消息处理,还提供如下功能:
- 可以设置字体颜色
对于
EDIT
控件,虽然可以设置其文本字体,但是没有设置颜色的方法。
- 可以编辑比较大的文件
对于平时的文件编辑器来说,编辑小文件基本上都差不多,但是当遇到比较大的文件时(比如1G),很可能无能为力,甚至卡死。
所以,既然我们要做一个新的编辑器,自然要考虑大文件的编辑问题。
- 采取
Direct Write
方式实现,而不是和普通的编辑器一样,通过GDI
。
做此选择的原因,除了因为
Direct Write
支持颜色之外,还有一些其它优点,详情可以点击Direct Write
进行参考。
- 支持
EDIT控件
的所有消息。
为了使得旧
Win32
代码更好的使用本编辑器,所有EDIT
控件支持的操作,本项目都应该支持。
- 处理
\r\n
此选择和
Windows 11
中的选择具有相同的理由,为了更好的处理换行。
- 支持撤销操作/恢复上一步操作
在编辑文本时,难免会想恢复到不久之前的版本,撤销操作允许你做到这个。而当你后悔撤销的时候,也应该能够恢复到最新版本,恢复上一步允许你做到重新执行你之前的操作。
- 支持
Unicode
编码 - 可以设置注解
在编辑时,尤其是要编辑二进制文件时,我们有时候可能要对某个字节,或某段文本进行注解。我们的编辑器允许提供一个注解结构,以在显示文档时,可以进行注解显示。
- 可以进行二进制文件编辑。
二进制编辑虽然不常用,但是,不能在需要用的时候找不到。所以,这里提供了二进制编辑功能。此功能和注解相结合,就可以进行辅助二进制文件的分析。
b. 目标编辑器的样子
作为一个现代的编辑器,我们希望它有一般编辑器都应该有的能力,下面是一个编辑器的例子:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pMKKh1AI-1649006016279)(https://img2022.cnblogs.com/blog/456172/202204/456172-20220403204453442-1758134648.png)]
不难看到,作为一个编辑器,应该支持行号,高亮,多字体,滚动条等内容。这在我们的编辑器中,都将一一实现,并详细描述实现过程。
c. 项目结构
对于本项目来说,一共包含两个子项目,如下:
- vicapp:
用于对编辑器控件进行调用的样例程序 - vitality-controls:
编辑器控件的实现项目,将作为一个DLL
文件提供给调用者。
d. 参考链接
代码地址:https://github.com/vitalitylee/vitality-controls
2. 基础代码框架搭建
接下来,我们详细说明整个项目的构建过程。
a. 打开 Visual Studio
,并点击创建新项目
如下:
b. 在创建新项目
对话框中,选择空项目,并点击下一步
,如下:
c. 在配置新项目
对话框中,设置项目内容,如下:
d. 右键项目vitality-conrols
,并点击属性,弹出属性
对话框,如下:
e. 在常规
选项卡中,设置配置类型为 动态库
,如下:
f. 一次点击配置属性
->链接器
->系统
,并设置子系统
为窗口
,如下:
g. 鼠标右键源文件
文件夹,选择添加
->新建项
,弹出添加新项
对话框,如下:
注意,这里添加
.c
文件,而不是.cpp
。
h. 输入 DLL
的入口代码,如下:
#include BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul\_reason\_for\_call,LPVOID lpReserved
)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}
i. 添加预处理声明
再次打开项目 vitality-controls
的属性页面,不难发现,比添加源文件之前,左侧多了一个C/C++
节点,左侧依次选择配置属性
->C/C++
->预处理器
选项,在右侧的预处理器定义
中,添加 VITALITY_CONTROLS_EXPORTS
声明,最终的值应为_DEBUG;VITALITY_CONTROLS_EXPORTS;_CONSOLE;%(PreprocessorDefinitions)
,如下图所示:
j. 添加接口声明文件
为了在两个项目中公用一套代码,新建的.h
文件,放置在了解决方案根目录下的shared-include
目录下,如下:
k. 修改接口代码
向新建的vitality-controls.h
文件中,输入如下代码:
#pragma once#ifdef VITALITY\_CONTROLS\_EXPORTS
#define VIC\_API \_\_declspec(dllexport)
#else
#define VIC\_API \_\_declspec(dllimport)
#endif // VITALITY\_CONTROLS\_EXPORTS#include VIC_API void vic\_prints(const char* str);
并向main.c
中添加新建的vitality-controls.h
文件引用,并添加vic_prints
函数实现,修改后代码如下:
#include #include "../../shared-include/vitality-controls.h"BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul\_reason\_for\_call,LPVOID lpReserved
)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}VIC_API void vic\_prints(const char* str) {puts(str);
}
l. 生成接口
鼠标右键解决方案,并点击重新生成解决方案
快捷菜单,如下:
最终,你将得到一个编译好的vitality-controls.dll
文件,如下:
m. 查看导出函数是否正常导出
点击操作系统的开始
菜单,并点击Developer Command Prompt for VS XXXX
,其中XXXX
随着你使用的Visual Studio
版本不同而不同,本文中使用的版本为Visual Studio 2022
。
所以,显示如下:
点击菜单后,会出现命令行窗口,在窗口中输入命令cd/d [path]
切换到目标文件所在目录,其中[path]
为你生成的目标 DLL
的所在目录,如:
切换到目标目录,就可以使用dumpbin
查看导出函数。在命令行中输入dumprin /exports vitality-controls.dll
,看到如下内容,说明你生成成功了:
n. 新建测试项目
右键解决方案
, 点击菜单添加
->新建项目
,根据之前的步骤,添加一个新建项目 vicapp
,添加主文件vicapp-main.c
,并输入如下代码:
#include "../../shared-include/vitality-controls.h"int main(int argc, char** argv) {vic_prints("hello vic.");return 0;
}
如下所示:
o. 设置启动项目
右键 vicapp
项目,并点击设为启动项目
菜单,如下:
设置完成后,点击启动按钮,将默认启动启动项目
。
p. 添加项目引用
为了可以使得 vicapp
程序能够引用到 vitality-controls.dll
目标文件,需要设置两个项目之间的引用关系。
右键点击 vicapp
项目,点击快捷菜单添加
->引用
,弹出添加引用
对话框,如下:
p. 运行程序
点击Visual Studio
的本地 Windows 调试器
按钮,程序将启动,并输出 hello vic.
,如下:
至此,我们项目的基础结构已经搭建完成。
下篇文章,我们将首先实现控件的初始化,以及控件展示功能,并讨论一下我们之后的项目计划,敬请期待。
让我们写一个Win32文本编辑器吧
系列文章,其代码对应项目vitality-controls
,主要对一个文本编辑器的实现过程进行说明。
如果要获取到实时更新,欢迎微信扫描下方二维码,关注微信公众号编程之路漫漫
,码途求知己,天涯觅一心。
让我们写一个 Win32 文本编辑器吧 - 1. 简介相关推荐
- Python: pyqt5 自己写一个窗口文本编辑器
PyQt5是Digia的一套Qt5应用框架与python的结合,同时支持2.x和3.x.Qt库由Riverbank Computing开发,是最强大的GUI库之一. >>> 今天,我 ...
- java web编辑器插件_UEditer 是一个富文本编辑器,可以作为 插件放到javaweb项目中使用,很好用~ Develop 238万源代码下载- www.pudn.com...
文件名称: UEditer下载 收藏√ [ 5 4 3 2 1 ] 开发工具: Java 文件大小: 19833 KB 上传时间: 2015-03-19 下载次数: 0 提 供 者: 陈琳杰 ...
- 使用PySimpleGUI模块,写一个正则表达式的编辑器
总流程 分析需求 代码实现 代码说明 1. self.rule 2. self.columns和self.rule_button 3. self.window_location 下步改进 1. sel ...
- linux系统中vi/vim文本编辑器的使用简介
linux系统中vi/vim文本编辑器的使用简介 1. vi/vim简介 vi/vim 是linux系统中最基本的编辑器,类似于windows系统中的记事本,几乎所有的linux开发版本都内置了v ...
- 原生js写一个简单的编辑器
js原生写的编辑器,主要是使用document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)来实现的 如果该指令不被支持或停用将会 ...
- 在mac上用文本编辑器写python_五大文本编辑器。Mac OS X最佳文本编辑器应用
五大适用于Mac修订的文本编辑器 文本编辑是开发人员生活中非常重要的一部分.这对于习惯于面面俱到的环境的Mac开发人员而言更加明显.对于他们来说存在一系列不同的优质软件之选.以下我们为其介绍了Mac版 ...
- 在mac上用文本编辑器写python_Mac开源文本编辑器CotEditor
coteditor for mac版是一款适用于macOS系统的轻量级文本编辑器,可以用于编辑纯文本文件,如网页(HTML,CSS),程序源代码(Python,Ruby,Perl等),结构化文本(Ma ...
- vue-electron 写一个markdown文章编辑器(一)
缘起 以前看过一篇帖子,很多写作爱好者讨论写作时用什么markdown编辑器好,可惜当时我连markdown是何物都不知道,事后百度才明白是一种新的写作方式,语法很是简单,操作很是方便,让我这个只知道 ...
- 在html页面写一个富文本框
第一步:获取到富文本框的这个文件,链接地址:https://ckeditor.com/cke4/builder (1)里面有几个选择,看你需求自己进行选择,然后鼠标一直拖到最下面,开始下载包 下面我只 ...
最新文章
- python中api是指什么_python中API接口是什么
- Python 用 if __name__ == ‘__main__‘:语句来控制代码是被直接运行还是导包执行
- Java并发编程—为什么wait/notify操作要先获取到锁?
- Java Code Geeks Andygene Web原型
- redis续期_面试官:Redis分布式锁如何解决锁超时问题的?
- Docker 安装MongoDB 以及 相关配置文件、数据文件映射
- poj1163 数字三角形 (动态规划)
- JQuery控制只能输入带二位小数的数字
- Ajax提交数据判断员工编号是否存在,及自动填充与员工编号所对应的员工姓名。...
- JWTToken在线编码生成
- @override注解_Spring中的各种注解深入理解
- FFmpeg编码详细流程
- 基于NoSQL的租房(链家)信息数据分析(附代码)
- 关于灰鸽子和黑软的一些看法
- (转)Windows gcc(MinGW32)配置-慢!!!
- flv转mp4选项设置
- Tracup丨什么是敏捷产品管理?
- java下载m3u8转ts合成mp4
- 关于Junit测试出现Class not found: “ “这个问题如何解决
- 事件2 有源码 可以随意进行练习哈 太棒了 一起加油 一起成长
热门文章
- RNN的神奇之处(The Unreasonable Effectiveness of Recurrent Neural Networks)
- Linux 之ubuntu 文本阅读器打开text 乱码
- 文字逐个加载动画-(vue-typed-js用法)
- [转载]Apache Beehive——Workshop运行时的发展
- kafka性能参数和压力测试
- 理想、激情、生存———位技术管理人员的20年工作经历和感悟(2)
- 二维码,如何设计创意二维码
- 幽门螺旋杆菌的治疗要多久?来听消化内科医生怎么说吧
- Android的页面布局
- openGL--透视投影的原理和实现