字符自动完成示例

自动完成示例演示了如何使用识别应用程序编程接口 (API) 实现日语字符自动完成。

此示例使用以下功能:

  • 使用 墨迹收集器
  • 使用 识别器上下文

初始化墨迹收集器和识别器上下文

InkCollectorInkRecognizerContext 对象声明为可引发事件的类。

Dim WithEvents ic As InkCollector
Dim WithEvents rc As InkRecognizerContext

窗体的 Load 事件处理程序创建墨迹收集器,将墨迹收集器关联到图片框,并启用墨迹收集。 然后,事件处理程序加载默认的日语识别器,并初始化识别器上下文的 Guide 和 Strokes 属性。

Private Sub Form_Load()
   ' Set the ink collector to work in the small frame window
    Set ic = New InkCollector    ic.hWnd = fraBox.hWnd    ic.Enabled = True
    
    ' Get the Japanese recognizer
    LoadRecognizer

    ' Initialize the recognizer context
    Dim Guide As New InkRecognizerGuide
    Dim FrameRectangle As New InkRectangle
    Dim Top As Long
    Dim Bottom As Long
    Dim Left As Long
    Dim Right As Long
    Top = 0
    Left = 0
    Bottom = fraBox.ScaleHeight
    Right = fraBox.ScaleWidth
    ic.Renderer.PixelToInkSpace Me.hdc, Top, Left
    ic.Renderer.PixelToInkSpace Me.hdc, Bottom, Right
    FrameRectangle.Bottom = Bottom
    FrameRectangle.Top = Top
    FrameRectangle.Left = Left
    FrameRectangle.Right = Right
    Guide.Columns = 1
    Guide.Rows = 1
    Guide.Midline = -1 ' Do not use midline
    Guide.DrawnBox = FrameRectangle
    Guide.WritingBox = FrameRectangle
    Set rc.Guide = Guide
    
    ' Set the strokes collection on the recognizer context
    Set ink = ic.ink    Set rc.Strokes = ic.ink.Strokes
End Sub

加载默认日语识别器

调用 InkRecognizer 的GetDefaultRecognizer 方法以检索日语的默认识别器。 接下来,检查 IInkRecognizer 对象的 Languages 属性,以确定识别器是否支持日语。 如果存在,则使用识别器 CreateRecognizerContext 方法为表单生成识别器上下文。

Private Sub LoadRecognizer()
    On Error GoTo NoRecognizer
    ' Get a Japanese recognizer context
    Dim recos As New InkRecognizers
    Dim JapaneseReco As IInkRecognizer
    Set JapaneseReco = recos.GetDefaultRecognizer(&H411)
    If JapaneseReco Is Nothing Then
        MsgBox "Japanese Recognizers are not installed on this system. Exiting."
        End
    End If
    
    ' Check that this is indeed a Japanese recognizer
    Dim IsJapanese As Boolean
    Dim lan As Integer
    IsJapanese = False
    For lan = LBound(JapaneseReco.Languages) To UBound(JapaneseReco.Languages)
        If JapaneseReco.Languages(lan) = &H411 Then
            IsJapanese = True
        End If
    Next lan
    If Not IsJapanese Then
        MsgBox "Japanese Recognizers are not installed on this system. Exiting."
        End
    End If
    Set rc = JapaneseReco.CreateRecognizerContext
    Exit Sub
NoRecognizer:
    MsgBox "Japanese Recognizers are not installed on this system. Exiting."
    End
End Sub

处理笔划事件

Stroke 事件处理程序首先停止识别器上下文中的背景识别。 然后,它将新笔划添加到识别器上下文的 Strokes 属性。 最后,它设置识别器上下文的 InkRecognizerCharacterAutoCompletionMode 属性,并为三个字符自动完成模式中的每一种调用识别器上下文的 BackgroundRecognizeWithAlternates 方法。 BackgroundRecognizeWithAlternates 方法调用的 CustomData 参数用于标识在 RecognitionWithAlternates 事件中返回的识别结果。

Private Sub ic_Stroke(ByVal Cursor As MSINKAUTLib.IInkCursor, ByVal Stroke As MSINKAUTLib.IInkStrokeDisp, Cancel As Boolean)

    ' Stop the unfinished recognition processes
    rc.StopBackgroundRecognition

    ' Add the new stroke
    rc.Strokes.Add Stroke

    ' Get a result for all three CAC modes
    rc.CharacterAutoCompletionMode = IRCACM_Full rc.BackgroundRecognizeWithAlternates 0 rc.CharacterAutoCompletionMode = IRCACM_Prefix rc.BackgroundRecognizeWithAlternates 1 rc.CharacterAutoCompletionMode = IRCACM_Random rc.BackgroundRecognizeWithAlternates 2
End Sub

使用备用事件处理识别

RecognitionWithAlternates 事件的处理程序首先检查 RecognitionStatus 参数。 如果识别时出错,事件处理程序将忽略识别结果。 否则,事件处理程序会将 RecognitionResult 参数添加到相应的图片框中,并保存结果字符串。 CustomData 参数在对 BackgroundRecognizeWithAlternates 方法的调用中设置,并标识识别器上下文使用的字符自动完成模式。

Private Sub rc_RecognitionWithAlternates(ByVal RecognitionResult As MSINKAUTLib.IInkRecognitionResult, ByVal vCustomParam As Variant, ByVal RecognitionStatus As MSINKAUTLib.InkRecognitionStatus)
    ' Get the alternates from the recognition result
    ' and display them in the right place
    Dim ResultString As String
    Dim alts As IInkRecognitionAlternates
    Dim alt As IInkRecognitionAlternate
        
    On Error GoTo EndFunc

    If RecognitionStatus = IRS_NoError Then
        ' Fill a string with all the characters for this CAC mode
        Set alts = RecognitionResult.AlternatesFromSelection
        For Each alt In alts
            ResultString = ResultString + alt.String
        Next alt
        ' Display the string
        Dim r As RECT
        r.Left = 0
        r.Top = 0
        r.Right = 1000
        r.Bottom = 1000
        PctResult(vCustomParam).Cls
        DrawText PctResult(vCustomParam).hdc, StrPtr(ResultString), Len(ResultString), r, 0
        If vCustomParam = 0 Then
            FullCACText = ResultString
        Else
            If vCustomParam = 1 Then
                PrefixCACText = ResultString
            Else
                If vCustomParam = 2 Then
                    RandomCACText = ResultString
                End If
            End If
        End If
    End If
    Exit Sub
EndFunc:
    MsgBox Err.Description
End Sub

绘制窗体

Paint 事件处理程序清除结果图片框,并将保存的识别结果添加到其中。

删除笔划

窗体的 CmdClear_Click 方法处理 Clear 命令。 如果 InkCollector 当前正在收集墨迹,则会显示一个消息框并忽略该命令。 否则,事件处理程序会停止背景识别,清除识别器上下文的 Strokes 属性,并从窗体的 InkDisp 对象中删除笔划。 然后,事件处理程序将重新绘制墨迹收集器所关联的图片框,并清除识别字符串和图片框。

If Not (ic.CollectingInk) Then

    ' Stop the unfinished recognition processes
    rc.StopBackgroundRecognition

    ' ...
    Set rc.Strokes = Nothing

    ' Delete all the strokes from the ink object
    ic.Ink.DeleteStrokes strokesToDelete

    ' Refresh the window
    fraBox.Refresh

    ' refresh the recognizer context
    Set rc.Strokes = ic.Ink.Strokes

    ' Clear the result strings
    FullCACText = ""
    PrefixCACText = ""
    RandomCACText = ""

    ' Clear the result windows
    PctResult(0).Cls
    PctResult(1).Cls
    PctResult(2).Cls

Else
    MsgBox "Cannot clear ink while the ink collector is busy."
End If