让我们写一个 Win32 文本编辑器吧 - 1. 简介

由于实现一个编辑器的复杂性相对比较大,一篇内容肯定完不成。所以,这里决定将整个过程作为一个系列来编辑。

本篇是系列的第一篇。在本篇文章中,将会对我们期望获得的结果进行简单的描述,并进行基础代码框架进行构建。

本文主要包含两个部分,如下:

在项目简介部分,将会对我们要实现的目标编辑器的样子,以及使用方法进行介绍。同时,也会对本系列接下来的文章要讨论的主题进行大致说明。

在代码框架搭建部分,将会对项目的创建,设置进行说明。并编辑我们的基础代码。

1. 项目简介

a. 目标

在此,我们的目标是:通过 C 语言,调用 Win32 接口,生成一个文本编辑器。目标编辑器除了实现和 Windows 提供的默认文本编辑器 EDIT所有消息处理,还提供如下功能:

  1. 可以设置字体颜色

  2. 可以编辑比较大的文件

  3. 采取Direct Write方式实现,而不是和普通的编辑器一样,通过 GDI

  4. 支持 EDIT控件 的所有消息。

  5. 处理\r\n

  6. 支持撤销操作/恢复上一步操作

  7. 支持 Unicode 编码

  8. 可以设置注解

  9. 可以进行二进制文件编辑。

b. 目标编辑器的样子

作为一个现代的编辑器,我们希望它有一般编辑器都应该有的能力,下面是一个编辑器的例子:
![](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 ,并点击创建新项目如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

b. 在创建新项目对话框中,选择空项目,并点击下一步,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

c. 在配置新项目对话框中,设置项目内容,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

d. 右键项目vitality-conrols,并点击属性,弹出属性对话框,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

e. 在常规选项卡中,设置配置类型为 动态库,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP
让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

f. 一次点击配置属性->链接器->系统,并设置子系统窗口,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP
让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

g. 鼠标右键源文件文件夹,选择添加->新建项,弹出添加新项对话框,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP
让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

h. 输入 DLL 的入口代码,如下:

#include <Windows.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;
}

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

i. 添加预处理声明

再次打开项目 vitality-controls 的属性页面,不难发现,比添加源文件之前,左侧多了一个C/C++节点,左侧依次选择配置属性->C/C++->预处理器选项,在右侧的预处理器定义中,添加 VITALITY_CONTROLS_EXPORTS声明,最终的值应为_DEBUG;VITALITY_CONTROLS_EXPORTS;_CONSOLE;%(PreprocessorDefinitions),如下图所示:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

j. 添加接口声明文件

为了在两个项目中公用一套代码,新建的.h文件,放置在了解决方案根目录下的shared-include目录下,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

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 <stdio.h>

VIC_API void vic_prints(const char* str);

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

并向main.c中添加新建的vitality-controls.h文件引用,并添加vic_prints函数实现,修改后代码如下:

#include <Windows.h>

#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);
}

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

l. 生成接口

鼠标右键解决方案,并点击重新生成解决方案快捷菜单,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

最终,你将得到一个编译好的vitality-controls.dll文件,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

m. 查看导出函数是否正常导出

点击操作系统的开始菜单,并点击Developer Command Prompt for VS XXXX,其中XXXX随着你使用的Visual Studio 版本不同而不同,本文中使用的版本为Visual Studio 2022

所以,显示如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

点击菜单后,会出现命令行窗口,在窗口中输入命令cd/d [path]切换到目标文件所在目录,其中[path]为你生成的目标 DLL 的所在目录,如:
让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

切换到目标目录,就可以使用dumpbin查看导出函数。在命令行中输入dumprin /exports vitality-controls.dll,看到如下内容,说明你生成成功了:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

n. 新建测试项目

右键解决方案, 点击菜单添加->新建项目,根据之前的步骤,添加一个新建项目 vicapp,添加主文件vicapp-main.c,并输入如下代码:

#include "../../shared-include/vitality-controls.h"

int main(int argc, char** argv) {
	vic_prints("hello vic.");
	return 0;
}

如下所示:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

o. 设置启动项目

右键 vicapp 项目,并点击设为启动项目菜单,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

设置完成后,点击启动按钮,将默认启动启动项目

p. 添加项目引用

为了可以使得 vicapp 程序能够引用到 vitality-controls.dll 目标文件,需要设置两个项目之间的引用关系。

右键点击 vicapp 项目,点击快捷菜单添加->引用,弹出添加引用对话框,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP
让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

p. 运行程序

点击Visual Studio本地 Windows 调试器按钮,程序将启动,并输出 hello vic.,如下:

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

至此,我们项目的基础结构已经搭建完成。

下篇文章,我们将首先实现控件的初始化,以及控件展示功能,并讨论一下我们之后的项目计划,敬请期待。

让我们写一个Win32文本编辑器吧 系列文章,其代码对应项目vitality-controls,主要对一个文本编辑器的实现过程进行说明。

如果要获取到实时更新,欢迎微信扫描下方二维码,关注微信公众号编程之路漫漫,码途求知己,天涯觅一心。

让我们写一个 Win32 文本编辑器吧 - 1. 简介-LMLPHP

04-04 09:01