高级识别示例
高级识别示例演示用于手写识别的 Microsoft 平板电脑自动化应用程序编程接口 (API) 的高级功能。
它包括以下功能:
- 枚举已安装的识别器
- 使用特定语言创建识别器上下文
- 使用识别器对象
- 设置识别事实和单词列表
- 使用指南提高识别质量
- 动态背景识别
- 手势识别
使用的接口包括: IInkRecognizer、 IInkRecoContext、 IInkRecognitionResult、 IInkRecognitionGuide、 IInkWordList、 IInkGesture、 IInkCollector、 IInkDisp、 IInkRenderer、 IInkDrawingAttributes、 IInkStrokes 和 IInkStroke。
墨迹和项目标头
首先,包括平板电脑自动化接口的标头。 这些随平板电脑电脑平台 SDK 一起安装。 TpcError.h 文件包含平板电脑 API 错误代码定义。
#include <msinkaut.h>
#include <msinkaut_i.c>
#include <TpcError.h>
EventSinks.h 文件定义 IInkEventsImpl 和 IInkRecognitionEventsImpl 接口,并设置 RecognitionWithAlternates、 Stroke 和 Gesture 事件。
#include "EventSinks.h"
ChildWnds.h 文件包含类 CInkInputWnd 和 CRecoOutputWnd 的定义,这些类派生自 ATL 的 CWindowImpl,用于创建示例的子窗口。
#include "ChildWnds.h"
AdvReco.h 文件声明 CAdvRecoApp 类,该类是此示例的应用程序窗口类。
#include "AdvReco.h"
初始化应用程序窗口
窗口的 Run
方法设置 CAdvRecoApp 对象,加载窗口的菜单和图标,为默认识别器创建 InkRecognizerContext 对象,并启动窗口的消息循环。
窗口的 OnCreate 方法处理 WM_CREATE 事件并创建子窗口。 InkCollector 对象连接到墨迹收集器的事件源,并在输入窗口中启用墨迹输入。 然后,它将创建 InkRecognizerGuide 对象,并使用墨迹收集器的 Renderer 属性将识别引导框矩形转换为墨迹空间。 最后, OnCreate 方法创建 InkWordList 对象。
处理墨迹收集器事件
窗口的 OnStroke 方法处理墨迹收集器的 Stroke 事件。 新的 IInkStrokeDisp 对象将添加到墨迹收集器的 Ink 属性的 InkStrokes 中。
窗口的 OnGesture 方法处理墨迹收集器的 手势 事件。 OnGesture 方法首先使用最高置信度手势标识手势,并检查窗口是否支持此特定手势。 如果支持手势,则手势的边界框将失效,因为手势将从笔划集合中删除。 如果不支持手势,则 取消手势 事件,这会导致墨迹收集器引发 Stroke 事件。 最后,更新结果窗口。
处理识别器上下文事件
窗口的 OnRecognitionWithAlternates 方法处理识别器上下文的 RecognitionWithAlternates 事件。 OnRecognitionWithAlternates 方法在结果窗口中显示识别结果。
处理菜单命令
窗口的 OnRecognizer 方法处理“识别器”菜单上的命令。 如果选择了 Default 命令,则 InkRecognizers 的 GetDefaultRecognizer 方法用于检索默认识别器;否则,将检索所选识别器。 然后,创建并使用识别器上下文,并更新菜单和状态栏。
窗口的 OnFactoidWordlist 方法处理 Factoid 菜单上的“使用 Wordlist”命令。 识别器上下文的 Strokes 属性设置为 NULL 以重置识别器上下文。 如果“使用 Wordlist”选项处于关闭状态,则识别器上下文的 WordList 属性设置为 NULL;否则,识别器上下文的 WordList 属性设置为在 OnCreate 方法中创建的 InkWordList。 最后,将墨迹收集器的 InkStroke 重新附加到识别器上下文,调用识别器上下文的 BackgroundRecognizeWithAlternates 方法,并更新菜单。
窗口的 OnFactoid 方法处理 Factoid 菜单上的 factoid 命令。 它首先将识别器上下文的 Strokes 属性设置为 NULL,将识别器上下文的 Factoid 属性设置为所选 factoid,并将墨迹收集器的 InkStroke 重新分配给识别器上下文。 如果识别器上下文支持 Factoid 对象,则会调用识别器上下文的 BackgroundRecognizeWithAlternates 方法;否则,将显示错误消息。 最后,更新菜单和状态栏。
窗口的 OnGuide 方法处理 “指南 ”菜单上的命令。 如果识别器上下文支持参考线选项, OnGuide 方法将识别器上下文的 Strokes 属性设置为 NULL,将识别器上下文的 Guide 属性设置为所选参考线设置,将墨迹收集器的 InkStroke 重新分配给识别器上下文,并调用识别器上下文的 BackgroundRecognizeWithAlternates 方法。 否则,将显示错误消息。 最后,更新输入窗口、菜单和状态栏。
窗口的 OnMode 方法处理“ 模式 ”菜单上的命令。 它会禁用墨迹收集器、更新墨迹收集器的 CollectionMode 属性、更新菜单以及显示或隐藏手势列表。 最后,启用墨迹收集器。
窗口的 OnRecognize 方法处理墨迹菜单上的 “识别 ”命令。 它调用识别器上下文的 EndInkInput 方法,防止墨迹添加到识别器上下文。 这有时是必要的,因为并非所有识别器都支持部分识别。 然后,它会调用识别器上下文的 Recognize 方法,并将结果传递给窗口的 OnRecognitionWithAlternates 方法。 最后, 将墨迹收集器的 InkStroke 重新分配到识别器上下文。
窗口的 OnClear 方法处理“墨迹”菜单上的“清除”命令。 它从墨迹收集器的 Ink 属性中删除笔划,释放旧的笔划集合,并为墨迹收集器的 Ink 属性创建一个新笔划集合,并将新的笔划集合附加到识别器上下文。
窗口的 OnExit 方法处理 Ink 菜单上的 Exit 命令,并引发 WM_CLOSE 事件。
帮助器方法
窗口的 LoadMenu 方法从窗口的 Run 方法调用,并将支持的识别器列表和受支持的事实列表添加到菜单中。 首先,它检索 InkRecognizer。 然后,它会循环访问可用的识别器,并仅选择在 语言 属性中具有语言列表的识别器,并将其添加到 “识别器 ”菜单。 最后,它会使用定义为全局常量的 factoid 列表填充 Factoid 菜单。
当用户选择新的 识别器 时,将从窗口的 OnRecognizer 方法调用窗口的 UseRecognizer 方法。 它创建识别器上下文,将旧上下文与识别器事件接收器分离,清除并释放旧上下文,并将新上下文附加到识别器事件接收器。
然后, UseRecognizer 方法检查识别 器的功能属性 ,该属性返回 InkRecognizerCapabilities 值。 如果识别器支持行输入,则会启用“指南”菜单上的“行”命令。 如果识别器支持装箱输入,则会启用 Box 命令。 如果识别器不支持免费输入,则禁用 None 命令。 如果当前指南选择不受支持,则会更新识别器上下文和菜单的 Guide 属性。
然后, UseRecognizer 方法尝试设置识别器上下文的 WordList 和 Factoid 属性。 如果识别器不支持任一设置,则使用默认值并更新菜单。
最后,UseRecognizer 方法将墨迹收集器的 InkDisp 对象的 Strokes 属性附加到识别器上下文,将输出窗口的字体更改为识别器语言支持的字体,重置输出窗口,并通过调用识别器上下文的 BackgroundRecognizeWithAlternates 方法更新识别结果。
窗口的 GetGestureName 方法从窗口的 OnGesture 方法调用。 它会搜索手势并返回手势名称的索引,该名称存储在 AdvReco.rc 文件的字符串表中。