在现代软件开发中,文本编辑器是不可或缺的工具之一。它允许用户创建、编辑和保存文本文件。本文将介绍如何使用WTL(Windows Template Library)构建一个简单的文本编辑器。WTL是一个用于创建Windows应用程序的C++库,它提供了一套丰富的类和函数,使得开发Windows应用程序变得更加容易。
在开始之前,需要确保开发环境已经搭建好。以下是搭建环境所需的步骤:
通过WTL项目向导创建C++项目,可以选择文档视图的基类。CEdit
和CRichEditCtrl
都可以作为简单文本编辑器的基类。CRichEditCtrl
类是Windows ActiveX控件richedt20.dll
的WTL包装,而CEdit
是基于Windows API的WTL实现。对于简单的文本编辑器程序,CEdit
类是一个足够的起点。所需做的就是将CEdit
的功能丰富到一个简单的文本编辑器。
通过WTL项目向导创建的初始项目提供了一个基本的程序框架。作为一个完整的可执行程序,它提供了基本的GUI,包括窗口、菜单、工具栏、工作区和状态栏,以及用户友好的入口点来自定义其程序行为。
可以在工作区输入文本,但输入的结果不能保存,程序也不能打开现有的文本文件。原因是默认的文件打开/保存行为是空的。首先向程序添加文件打开和保存功能,如下所示:
HANDLE hFile = ::CreateFile(sPath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (INVALID_HANDLE_VALUE == hFile)
return false;
DWORD dwSizeLow = GetFileSize(hFile, 0);
char *pbBuff = (char*)malloc(dwSizeLow+1);
DWORD pcb = 0;
DWORD dwRet = ::ReadFile(hFile, pbBuff, dwSizeLow, (LPDWORD)&pcb, NULL);
pbBuff[dwSizeLow] = '\0';
::CloseHandle(hFile);
ATLASSERT(::IsWindow(m_hWnd));
::SendMessage(m_hWnd, WM_SETTEXT, 0, (LPARAM)pbBuff);
delete pbBuff;
HANDLE hFile = ::CreateFile(sPath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0);
if (INVALID_HANDLE_VALUE == hFile)
return false;
ATLASSERT(::IsWindow(m_hWnd));
DWORD dwSizeLow = ::GetWindowTextLength(m_hWnd);
char *pbBuff = (char*)malloc(dwSizeLow+1);
::SendMessage(m_hWnd, WM_GETTEXT, (WPARAM)dwSizeLow, (LPARAM)pbBuff);
pbBuff[dwSizeLow] = '\0';
DWORD pcb = 0;
DWORD dwRet = ::WriteFile(hFile, pbBuff, dwSizeLow, (LPDWORD)&pcb, NULL);
::CloseHandle(hFile);
CEdit
类支持基本的文本编辑操作,可以在工作区输入文本并复制/粘贴/剪切文本。然而,CEdit
的编辑操作是在其内部数据结构上进行的。由于文本编辑程序需要执行一些自定义操作,因此基于自己的数据结构实现基本的编辑操作。
使用STL的vector
和string
来存储内容。
#include
#include
vector m_contents;
每个string
包含一行文本,默认情况下,使用两个字符'\r' '\n'来结束一行并开始新行。而CEdit
类将内容视为一个长的字符序列。如果在工作区选择文本,CEdit
函数GetSel()
将返回当前选择的位置。必须将GetSel()
函数获得的位置映射到m_contents
中的位置。
当编辑器通过WM_CHAR
消息捕获用户输入的字符时,CEdit
类将其保存到其内部数据结构中,并在工作区反映出来。然而,可以通过重叠或扩展函数"OnChar"来自定义程序行为,以处理WM_CHAR
消息。
WM_KEYDOWN
消息用于处理"插入"字符VK_INSERT
。每次按下VK_INSERT
键时,编辑模式应该在"插入"模式和"替换"模式之间切换。