拼写检查编辑控件(使用 HunSpell)
一个具有最新、可国际化拼写检查功能的 CEdit 控件。
引言
在看到 Matthew Gullett 的 拼写检查引擎 和 Steve King 的 CSpellEdit 控件 后,我受到启发编写了这个控件。
我喜欢 CSpellEdit 的简洁性,但它与 CEdit 控件的集成在 CFPSSpellingEditCtrl 中感觉更好,所以我将两者结合起来,更新了使用的拼写检查引擎为 Hunspell 而不是 MySpell,添加了用户词典代码,并尽可能将其通用化。
用法
要使用此编辑框,有三个步骤:
- 将 Hunspell 添加到您的解决方案
- 将 CHSpellEdit 添加到您的解决方案(作为 DLL)或项目(作为静态代码)
- 在您的应用程序中使用 CHSpellEdit。
第一部分:将 Hunspell 添加到您的解决方案
为满足 LGPL 的要求,这些说明将 Hunspell 构建为一个 DLL,以确保安全。
- 从 SourceForge 获取最新版本的 Hunspell 源代码。将其解压到一个方便的目录。将 src\hunspell 目录复制到您的解决方案中一个方便的位置,并将 src\win_api 目录复制到相同的位置。(这两个目录需要位于同一级别。)
您还需要从同一网站获取一个词典(除非您的计算机上已安装了 Mozilla Firefox 或 OpenOffice.org,即使如此,您也可能希望为您的程序提供一个词典),并将 en_US.dic 和 en_US.aff 文件(或您选择的语言的相应文件)放在下面提到的目录之一中。**注意** Hunspell 可以使用 MySpell 兼容的词典。
- 应用 hunspell-1.2.1-dllbuild.patch。如果需要,应用 hunspell-1.2.1-vc70.patch 或 hunspell-1.2.1-vc71.patch。
(只有在您选择更新 Hunspell 源代码时才需要执行第 1 步和第 2 步。如果您不更新,则将演示项目中的 hunspell 和 win_api 目录复制到您的解决方案中一个方便的位置。)
- 将 libhunspell.vcproj 添加到您的解决方案。
- 使您的 Debug 版本使用 Hunspell 的 Debug_dll 版本,Release 版本使用 Hunspell 的 Release_dll 版本。
[使用 Visual Studio .NET 2003 中的“生成”>“配置管理器”来完成此操作。]
在此处选择 2a 或 2b 进行接下来的 3 个步骤。
将 CHSpellEdit 添加到您的解决方案(作为 DLL)或项目(作为静态代码)
第二部分 2a:将 CHSpellEdit 作为静态代码添加到您的项目中
- 将 HSpell*.c 和 HSpell*.h 文件复制到您项目的目录中,并将它们添加到您的项目中。
- 使您的项目依赖于 libhunspell。
- 编辑您的 stdafx.h 文件,确保它至少定义了
WINVER
、_WIN32_WINNT
和 _WIN32_IE 为 0x0500,以及_WIN32_WINDOWS
为 0x0410。如果您不执行此步骤,HSpellEdit.h 将会因 C1189 错误而停止(它会命中 #error 行)。这是为了防止后续出现其他编译错误。
该代码利用了 Windows 98、Windows 2000 和/或 Windows ME 的可用功能,但并非必需。然而,要使用这些功能,需要设置这些定义。
第二部分 2b:将 CHSpellEdit DLL 添加到您的解决方案
- 将 HSpellEdit 目录复制到您的项目中一个方便的位置,并将 HSpellEdit_dll.vcproj 添加到您的解决方案。
- 使您的项目依赖于 HSpellEdit_dll。(HSpellEdit_dll 需要依赖于 libhunspell。)
- 在您的项目的 Release 和 Debug 版本中都添加处理器定义 HSPELLEDIT_DLL。
第三部分:在您的应用程序中使用 CHSpellEdit
- 在包含您的
CWinApp
派生类的InitInstance
(和ExitInstance
)例程的 .cpp 文件中,以及在定义将使用 CHSpellEdit 的对话框类的任何 .h 文件中,添加#include "HSpellEdit.h"
。 - 在调用
CWinApp::SetRegistryKey()
之后,在您的CWinApp
派生类的InitInstance
成员中调用CHSpellEdit::Initialize(this)
。 - 在您的
CWinApp
派生类的ExitInstance
成员中调用CHSpellEdit::Terminate()
。(在对话框应用程序中,您可以在调用DoModal
之后但在InitInstance
退出之前,在InitInstance
中调用它。) - 定义一个 CHSpellEdit 变量,并将其附加到您的编辑框。(在您的
DoDataExchange
例程中,应该有一个DDX_Control
调用,引用您的编辑框 ID 和您的 CHSpellEdit 变量。如果先前已有 CEdit 变量,只需将其更改为 CHSpellEdit 变量。) - 在您的“关于”框或同等界面中注明相关人员。(我不要求署名,但如果您这样做会很好。我的更改属于下面的许可证。但是,Matthew Gullett 要求署名,因此为了满足所有法律要求,您可能需要注明他。)
/* LICENSE:
* This code is absolutely free to use and modify. The code is provided
* "as is" with no expressed or implied warranty. The author accepts no
* liability if it causes any damage to your computer, causes your pet to
* fall ill, increases baldness or makes your car start emitting strange
* noises when you start it up.
* This code has no bugs, just undocumented features!
*/
对用户的要求
HSpellEdit 对您的用户提出的唯一要求是,如果他们运行的是 Windows 95 或 Windows NT 4.0,则必须安装一个更新版本(优于 4.71)的 SHFolder.dll。获取美式英语版本的 URL 在代码中相应位置的注释中。HSpellEdit.cpp 会检测用户的 Windows 版本并相应地退化。不依赖任何需要 Windows 98、Me 或 2000 的代码,但在这些操作系统可用时会使用利用其功能的代码。
您需要在字符串表中创建 IDS_HSPELLEDIT_SHFOLDER_ERROR
来定义 SHFolder.dll 检查失败时使用的消息。如果不存在,将使用默认消息。
使用注意事项
-
如果您使用 DLL,请确保您为 DLL 使用的任何
IDS_HSPELLEDIT_*
字符串使用相同的编号。DLL 提供美式英语的字符串,但这些字符串可以被您的应用程序覆盖或翻译。您可能希望为翻译的字符串指定一个其他语言的字符串表,我将很感激您将翻译发送给我。 -
三个预处理器定义会影响词典文件的查找
预处理器定义
HSPELLEDIT_NO_REGISTRY_CHECK
会关闭将路径信息加载和保存到注册表的操作。预处理器定义
HSPELLEDIT_NO_EXTERNAL_PROGRAMS_CHECK
会关闭从 OpenOffice.org 2.3、2.2、2.0 或 Mozilla Firefox 2.0.0.0 或更高版本的注册表项加载路径信息的操作。(它们按此顺序尝试。)预处理器定义
HSPELLEDIT_NO_SELFREF_CHECK
会关闭检查可执行文件目录(及其子目录“dic”)以查找词典文件的操作。以下是检查目录的顺序:
- 注册表中指定的目录。
- 可执行文件目录。*
- 可执行文件目录下的 dic 子目录。*
CSIDL_COMMON_APPDATA
目录*
[此目录仅在运行 Windows ME 或 Windows 2000 或更高版本时检查。]CSIDL_APPDATA
目录- OpenOffice.org 词典位置。*
- Mozilla Firefox 词典位置。*
标记为 * 的位置不用于查找用户词典,用户词典将在
CSIDL_APPDATA
中创建(如果不存在)。如果没有常规词典,将不会发生拼写检查,但您的程序将正常工作。
如果 A) 程序位于 C:\Program Files\HSpellEditTest,B) 用户名为“Curtis”,运行的是美式英语版 Windows XP,C) 安装了 OpenOffice 2.3 和 Mozilla Firefox 2.0,则将搜索以下目录:
B) 用户名为“Curtis”,运行的是美式英语版 Windows XP
C) OpenOffice 2.3 和 Mozilla Firefox 2.0 已安装
是这些:- 注册表中指定的目录。
- C:\Program Files\HSpellEditTest\
- C:\Program Files\HSpellEditTest\dic\
- C:\Documents and Settings\All Users\Application Data\
- C:\Documents and Settings\Curtis\Application Data\
- C:\Program Files\OpenOffice.org 2.3\share\dict\ooo\
- C:\Program Files\Mozilla Firefox\dictionaries\
要使 HSpellEdit 可用,您选择的语言必须在其中一个目录中同时拥有 .dic 和 .aff 文件。
如果某个特定目录中没有您的语言,HSpellEdit 将按降序检查您语言的其他子语言(顺序由 Windows 指定,HSpellEdit 不指定),然后默认使用美式英语(en_US),之后再继续检查下一个目录。
找到词典后,其位置将保存到注册表中,除非定义了
HSPELLEDIT_NO_REGISTRY_CHECK
。如果您正在为使用 HSpellEdit 的程序编写安装程序,最好将您的词典放在位置 4 和 5,而不是位置 2 或 3。
-
要国际化菜单,请将这些常量放入字符串表中:
IDS_HSPELLEDIT_SUGGESTIONS IDS_HSPELLEDIT_NO_SUGGESTIONS IDS_HSPELLEDIT_ADD IDS_HSPELLEDIT_IGNORE
只有当 MFC 没有为您选择的语言定义这些常量时,您才需要将它们添加到字符串表中。(如果 MFC 为您的语言定义了这些常量,它们将位于 MFC71xxx.dll 中,其中 xxx 是三字母语言代码,并且在 MFC 源文件 atlmfc\src\mfc\l.xxx\prompts.rc 中。)
ID_EDIT_CUT ID_EDIT_COPY ID_EDIT_PASTE ID_EDIT_SELECT_ALL ID_EDIT_UNDO
- HShellEdit DLL 导出与 shell32.dll、shlwapi.dll、comctl32.dll 和 sholder.dll 相同的 DllGetVersion 调用,因此您可以通过相同的方式获取 DLL 的版本。
关注点
我尝试允许在“最少特权要求”的情况下使用,这就是为什么 CSIDL_APPDATA(除极端限制情况外应可写)被用作存储词典的地点之一。
历史
- 版本 0.90
初始发布