Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här exemplet visar avancerade funktioner i MicrosoftTablet PC Automation-programmets programmeringsgränssnitt (API) som används för handskrift igenkänning.
Den innehåller följande:
- Räkna upp de installerade igenkännarna
- Skapa en identifierarkontext med en specifik språkigenkänning
- Seriekoppling av identifieringsresultat med en strecksamling
- Samla strecksamlingar i en anpassad samling inom objektet InkDisp
- Serialisera pennantecknings objekt till och hämta dem från en fil med ink-serialiserat format (ISF) fil
- Ange indataguider för identifierare
- Använda synkron och asynkron igenkänning
Pennanteckningsrubriker
Inkludera först rubrikerna för Tablet PC Automation-gränssnitt. Dessa installeras med Microsoft Windows XP Tablet PC Edition Software Development Kit (SDK).
#include <msinkaut.h>
#include <msinkaut_i.c>
Filen EventSinks.h definierar gränssnitten IInkEventsImpl och IInkRecognitionEventsImpl.
#include "EventSinks.h"
Räkna upp installerade identifierare
Programmets LoadMenu-metod fyller i menyn Skapa nya linjer med tillgängliga identifierare. En InkRecognizers har skapats. Om egenskapen Språk för ett InkRecognizers-objekt inte är tomt, är identifieraren en textigenkännareoch värdet för egenskapen Namn läggs till på menyn.
// Create the enumerator for the installed recognizers
hr = m_spIInkRecognizers.CoCreateInstance(CLSID_InkRecognizers);
...
// Filter out non-language recognizers by checking for
// the languages supported by the recognizer - there is not
// any if it is a gesture or object recognizer.
CComVariant vLanguages;
if (SUCCEEDED(spIInkRecognizer->get_Languages(&vLanguages)))
{
if ((VT_ARRAY == (VT_ARRAY & vLanguages.vt)) // it should be an array
&& (NULL != vLanguages.parray)
&& (0 < vLanguages.parray->rgsabound[0].cElements)) // with at least one element
{
// This is a language recognizer. Add its name to the menu.
CComBSTR bstrName;
if (SUCCEEDED(spIInkRecognizer->get_Name(&bstrName)))
...
}
}
Skapa en bläckuppsamlare
Programmets OnCreate-metod skapar ett InkCollector- objekt, ansluter det till dess händelsekälla och aktiverar ink-samling.
// Create an ink collector object.
hr = m_spIInkCollector.CoCreateInstance(CLSID_InkCollector);
// Establish a connection to the collector's event source.
hr = IInkCollectorEventsImpl<CMultiRecoApp>::DispEventAdvise(m_spIInkCollector);
// Enable ink input in the m_wndInput window
hr = m_spIInkCollector->put_hWnd((long)m_wndInput.m_hWnd);
hr = m_spIInkCollector->put_Enabled(VARIANT_TRUE);
Skapa en identifierarkontext
Programmets CreateRecoContext-metod skapar och initierar en ny identifierarkontext och konfigurerar guiderna som stöds av det associerade språket. Metoden IInkRecognizer objektets CreateRecognizerContext skapar ett IInkRecognizerContext2- objekt för språket. Vid behov ersätts den gamla identifierarkontexten. Kontexten är ansluten till dess händelsekälla. Slutligen kontrolleras egenskapen för identifierarkontexten för att se vilka guider den stöder.
// Create a recognizer context
CComPtr<IInkRecognizerContext2> spNewContext;
if (FAILED(pIInkRecognizer2->CreateRecognizerContext(&spNewContext)))
return false;
// Replace the current context with the new one
if (m_spIInkRecoContext != NULL)
{
// Close the connection to the recognition events source
IInkRecognitionEventsImpl<CMultiRecoApp>::DispEventUnadvise(m_spIInkRecoContext);
}
m_spIInkRecoContext.Attach(spNewContext.Detach());
// Establish a connection with the recognizer context's event source
if (FAILED(IInkRecognitionEventsImpl<CMultiRecoApp>::DispEventAdvise(m_spIInkRecoContext)))
...
// Set the guide if it's supported by the recognizer and has been created
int cRows = 0, cColumns = 0;
InkRecognizerCapabilities dwCapabilities = IRC_DontCare;
if (SUCCEEDED(pIInkRecognizer->get_Capabilities(&dwCapabilities)))
...
Samla in linjer och visa igenkänningsresultat
Applikationens OnStroke-metod uppdaterar InkStrokes av bläckinsamlaren, avbryter befintliga asynkrona igenkänningsbegäranden och skapar en igenkänningsbegäran i igenkännarkontexten.
// Add the new stroke to the current collection
hr = m_spIInkStrokes->Add(pIInkStroke);
if (SUCCEEDED(hr))
{
// Cancel the previous background recognition requests
// which have not been processed yet
m_spIInkRecoContext->StopBackgroundRecognition();
// Ask the context to update the recognition results with newly added strokes
// When the results are ready, the recognizer context returns them
// through the corresponding event RecognitionWithAlternates
CComVariant vCustomData;
m_spIInkRecoContext->BackgroundRecognize(vCustomData);
}
Programmets OnRecognition-metod skickar resultatet av igenkänningsbegäran till utdatafönstrets UpdateString-metod.
// Update the output window with the new results
m_wndResults.UpdateString(bstrRecognizedString);
Ta bort streck och igenkänningsresultat
Programmets OnClear-metod tar bort alla "strokes" och igenkänningsresultat från objektet InkDisp och tömmer fönstren. Identifierarkontextens association med dess InkStrokes samling tas bort.
// Detach the current stroke collection from the recognizer context and release it
if (m_spIInkRecoContext != NULL)
m_spIInkRecoContext->putref_Strokes(NULL);
m_spIInkStrokes.Release();
// Clear the custom strokes collection
if (m_spIInkCustomStrokes != NULL)
m_spIInkCustomStrokes->Clear();
// Delete all strokes from the Ink object
// Passing NULL as a stroke collection pointer means asking to delete all strokes
m_spIInkDisp->DeleteStrokes(NULL);
// Get a new stroke collection from the ink object
...
// Ask for an empty collection by passing an empty variant
if (SUCCEEDED(m_spIInkDisp->CreateStrokes(v, &m_spIInkStrokes)))
{
// Attach it to the recognizer context
if (FAILED(m_spIInkRecoContext->putref_Strokes(m_spIInkStrokes)))
...
}
Ändra identifierarkontexter
Programmets OnNewStrokes-metod anropas när användaren väljer en igenkännare i menyn Skapa nya streck. Den aktuella InkStrokes är sparad. Om en annan språkigenkänning har valts skapas en ny identifierarkontext. Sedan kopplas en ny InkStrokes- till den nya identifierarkontexten.
// Save the current stroke collection if there is any
if (m_spIInkRecoContext != NULL)
{
// Cancel the previous background recognition requests
// which have not been processed yet
m_spIInkRecoContext->StopBackgroundRecognition();
// Let the context know that there'll be no more input
// for the attached stroke collection
m_spIInkRecoContext->EndInkInput();
// Add the stroke collection to the Ink object's CustomStrokes collection
SaveStrokeCollection();
}
...
// If a different recognizer was selected, create a new recognizer context
// Else, reuse the same recognizer context
if (wID != m_nCmdRecognizer)
{
// Get a pointer to the recognizer object from the recognizer collection
CComPtr<IInkRecognizer> spIInkRecognizer;
if ((m_spIInkRecognizers == NULL)
|| FAILED(m_spIInkRecognizers->Item(wID - ID_RECOGNIZER_FIRST,
&spIInkRecognizer))
|| (false == CreateRecoContext(spIInkRecognizer)))
{
// restore the cursor
::SetCursor(hCursor);
return 0;
}
// Update the status bar
m_bstrCurRecoName.Empty();
spIInkRecognizer->get_Name(&m_bstrCurRecoName);
UpdateStatusBar();
// Store the selected recognizer's command id
m_nCmdRecognizer = wID;
}
Den anropar sedan StartNewStrokeCollection, som skapar en tom InkStrokes och kopplar den till identifierarkontexten.
Spara strecksamlingen för en identifierarkontext
Programmets SaveStrokeCollection-metod söker efter en befintlig identifierarkontext och slutför igenkänningen av den aktuella linjesamlingen. Sedan läggs samlingen InkStrokes till i CustomStrokes- för bläckobjektet.
if (m_spIInkRecoContext != NULL)
{
if (SUCCEEDED(m_spIInkStrokes->get_Count(&lCount)) && 0 != lCount)
{
CComPtr<IInkRecognitionResult> spIInkRecoResult;
InkRecognitionStatus RecognitionStatus;
if (SUCCEEDED(m_spIInkRecoContext->Recognize(&RecognitionStatus, &spIInkRecoResult)))
{
if (SUCCEEDED(spIInkRecoResult->SetResultOnStrokes()))
{
CComBSTR bstr;
spIInkRecoResult->get_TopString(&bstr);
m_wndResults.UpdateString(bstr);
}
...
}
}
// Detach the stroke collection from the old recognizer context
m_spIInkRecoContext->putref_Strokes(NULL);
}
// Now add it to the ink's custom strokes collection
// Each item (stroke collection) of the custom strokes must be identified
// by a unique string. Here we generate a GUID for this.
if ((0 != lCount) && (m_spIInkCustomStrokes != NULL))
{
GUID guid;
WCHAR szGuid[40]; // format: "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
if (SUCCEEDED(::CoCreateGuid(&guid))
&& (::StringFromGUID2(guid, szGuid, countof(szGuid)) != 0))
{
CComBSTR bstrGuid(szGuid);
if (FAILED(m_spIInkCustomStrokes->Add(bstrGuid, m_spIInkStrokes)))
...