65.9K
CodeProject 正在变化。 阅读更多。
Home

文本编辑器: 基础中的基础

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (6投票s)

2009 年 5 月 9 日

CPOL

7分钟阅读

viewsIcon

35346

downloadIcon

2882

这是一个基于 Edit 控件的简单文本编辑器

Newpad_Source_Code

引言

简单的文本编辑器是程序员在职业生涯之初编写的第一个应用程序。创建编辑器的最简单方法是使用 Microsoft Windows 编辑控件。该控件同时支持双字节的 Unicode 字符集和单字节的 ANSI 字符集。Microsoft Windows 记事本是所有 Windows 版本中都包含的常用纯文本编辑器。

我想提请您注意我的新程序 Newpad,它是一个类似于 Microsoft Windows 记事本的简单文本编辑器。该程序用于学习编辑器设计原理,并且代表了一个完整的软件产品。我希望它对那些编写过处理文本文件的应用程序的人会有所帮助。此项目包含几个有用的函数,可以访问文本文件并与编辑控件进行交互。

Newpad 是一个组织完善的完整产品,包含帮助文档、安装程序、源代码和文档。在本文中,我将简要介绍项目的本质和特点。由于篇幅有限,不可能详细概述其所有方面。有关详细信息,您可以查看 zip 包中的项目源代码。

项目中值得关注的内容

  • 错误处理和调试
  • 通用窗口创建和操作技术
  • 创建和自定义对话框
  • 自定义“保存文件”对话框
  • 注册表操作
  • 创建工具栏和状态栏及其操作
  • 通过程序发送电子邮件
  • 通用编辑控件操作技术(文本操作、缓冲区访问、字符串搜索、打印、处理控件中的插入符位置等)

Newpad 概述

用户界面

从用户角度来看,Newpad 具有一些与记事本不同的显著特点,使其更加用户友好。简而言之,您可以使用它和记事本一样,但 Newpad 和记事本之间存在一些区别。从用户角度来看,这些区别是:

  1. Newpad 具有工具栏,而记事本没有。

    您可以通过点击“视图”菜单,然后点击您想要显示或隐藏的工具栏名称来显示或隐藏 Newpad 的工具栏和状态栏。

  2. Newpad 可以打开并正确显示包含 UNIX 和 Macintosh 样式的行尾符的文件,但记事本不能。

    当 Newpad 打开文件时,它会自动区分行尾符的样式。Newpad 正确显示 Windows 和 UNIX 样式的行尾符文件。但是,如果您想保存文件,Newpad 将保留原有的格式。

  3. 记事本即使在缺少字节顺序标记的情况下也能检测 Unicode 文件。Newpad 始终检查 Unicode 文件中的字节顺序标记。

Using the Code

构建环境

您可以在 zip 压缩包中找到该程序的源代码。它包含一个 Microsoft Visual Studio 2008 解决方案文件。但是,您可以随意使用源代码并创建自己的项目文件。Newpad 也可以使用 Visual C++ 6.0 正确重新编译。Newpad 是一个经典的 C 应用程序,只使用 Win API 调用。目前,只有英语和俄语版本的资源脚本可用。

调试版本的特殊之处

在项目的调试版本中,您会发现一个用于库 NpDebug.dll 的附加项目。它为项目提供高级错误处理,并可能对您的应用程序有用。该库导出了几个函数,用于在程序调试版本中出现断言时向开发人员发送电子邮件消息。SimpleAssert 函数显示一个简单的对话框,告知用户有关断言的信息,而无法发送反馈消息。AdvancedAssert 函数显示一个对话框,告知用户有关发生的断言,并提供通过电子邮件向开发人员发送消息的选项。SendMail 是另一个有用的函数,它执行通过当前 Windows 电子邮件设置发送消息的操作。它由 AdvancedAssert 函数调用,但也可以独立使用。该函数使用 Windows MAPI 环境,并在调用 MAPI 函数后检查返回值。

关于超级链接控件

该程序使用自己的超级链接控件类似物。任何对话框上的任何按钮都可以转换为此控件。我的超级链接控件是通过替换按钮的窗口过程来实现的。DrawHyperlinkControl 函数绘制超级链接条目。当新的窗口过程处理 WM_PAINT 消息时会调用它。OpenHyperLink 函数执行您可以为超级链接设置的操作。

关于对话框的一个有趣特性

我介绍一个有趣的对话框功能,可用于 GPL 许可下的免费软件应用程序。您需要填写 PRODUCT_INFORMATION 结构字段,并将结构指针传递给 AboutFreewareDialog 函数。此函数将显示一个对话框,其中包括一个带有图标和格式化文本的横幅、简短的 GPL 片段以及指向完整 GPL 文本的超级链接。当然,您可以根据需要自定义所有这些。

项目参考

函数

如上所述,由于 Newpad 是一个完整的产品,因此不可能在短文中详细概述其所有方面。请查看程序的源代码以详细了解这些功能。

int ReadTextFile(HANDLE hFile, LPTSTR* ppszText, 
	LPDWORD pdwTextLength, LPUINT pnEndcoding, LPUINT pnEOL); 

参数

[in] hFile 文件句柄必须已使用 GENERIC_READ 权限创建。
[out] *ppszText 指向一个缓冲区,该缓冲区接收从文件中读取的文本。此值不能为 NULL
[out] pdwTextLength 指向一个 DWORD 值,该值将返回文本缓冲区的长度。
[out] pnEndcoding 指向一个 UINT 值,该值将返回文本的编码。
[out] pnEOL 指向一个 UINT 值,该值将返回文本的行尾标记。

返回值

如果函数成功,则返回值为 1。如果函数失败,则返回值为 0

int WriteTextFile(HANDLE hFile, LPCWSTR pwcText, 
		DWORD dwTextLegth, UINT nEncoding, UINT nEOL); 

参数

[in] hFile 要读取的文件的句柄。文件句柄必须已使用 GENERIC_WRITE 访问权限创建。
[in] pwcText 指向包含要写入文件的文本的 Unicode 缓冲区的指针。
[in] dwTextLegth 文本长度(以字节为单位)。
[in] nEncoding 文本编码。
[in] nEOL 行尾标记。

返回值

如果函数成功,则返回值为 1。如果函数失败,则返回值为 0

如果您想详细了解项目的其他函数,则必须查看源代码。

您可以使用 CRT 调试库和 NpDebug 库来调试此应用程序。您需要包含相应的头文件 crtdbg.hnpdebug.h,并定义以下宏之一

#define ASSERT(s) _ASSERTE(s) or #define ASSERT(s) NP_ASSERT(s)

消息

程序中有两个地方未使用普通的“消息处理”。一是用于查找替换对话框的附加消息,二是出现在自定义“保存文件”对话框中的消息。

在第一种情况下,我们使用

uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING); 

来注册新消息。之后,IsFindReplaceMsg 函数会检查消息,如果它是来自查找替换无模式对话框的消息,则返回 TRUE。我们在 main 消息循环中使用此函数(有关详细信息,请参阅 Newpad.c 中的 WinMain)。

为了以不同的编码保存文本文件,我们使用了一个自定义的“文件保存”对话框。我们处理发送到“文件保存”自定义对话框的钩子对话框过程的 WM_NOTIFY 消息通知。但是,钩子过程中的新消息处理程序(有关详细信息,请参阅 NpFiles.c 中的 MyHookProc)是空的。

Notifications

我们在 Newpad 主窗口过程中处理来自编辑控件的通知消息,以更新状态栏上的插入符位置消息。此外,当鼠标指针固定在编辑器窗口中时,我们替换编辑控件窗口过程来执行此任务。

结构体

FRDLG 结构保存有关在查找替换对话框中出现的 string 的信息。结构的第一个成员是 Windows FINDREPLACE 结构变量,第二个是搜索 string,第三个是替换 string

EDITUI 结构保存描述工具栏、状态栏和自动换行用户界面的布尔字段。

EDITSTATE 结构管理查找替换对话框的用户界面。它的第一个成员是指向 FRDLG 结构的指针。其他成员描述了标准的 Windows 查找替换对话框用户控件。

TEXTDOC 结构描述一个文本文档。此结构中的成员是:字节顺序标记、文本文件编码、行尾标记和文件名。

常量

大多数常量都放在头文件中,以便您可以根据需要进行修改。

结论

我一直在努力以更易读的方式编写代码。程序的创建对我来说是一次很好的学习经历。我从“平淡无奇的打印”一步步完成了这个完整的应用程序。现在,我希望它能对那些刚开始学习编程的人有所帮助。对于读者来说,您对这个程序的所有反馈和愿望都很重要。如果您想提出建议、报告错误或提出其他功能需求,请写信至 alexshag@mail.ru

© . All rights reserved.