Overview of the Pen API Functions
Overview of the Pen API

The Pen API contains the functions, messages, data structures, data types, statements, and files you need to create programs and device drivers that run with Windows for Pen Computing.

There are six categories of API functions. The following table briefly describes each group. Each of these categories is discussed in more detail following this table.

API Category	Description
Pen interface	Adds pen functionality to applications.
Pen data	Manipulates the pen data memory block (accessed with the HPENDATA structure), the primary mechanism for passing the information captured from the pen between an application and other applications and recognizers.
Custom recognizer	Functions to be provided by the recognizer component. The application does not call these functions directly.
Pen module	Functions called by pen drivers and recognizers to manipulate data coming from the pen driver.
Pen driver	Functions provided by pen drivers.
Display driver (inking)	Functions provided by display drivers.
Dictionary	Functions provided by a custom dictionary.


Pen Interface Functions

There are three methods for creating a pen application. One method is to use the ProcessWriting function, which simplifies the process of collecting handwritten input.

The following paragraphs discuss the two remaining methods.

Using a Recognizer Within a Window

This method uses a recognizer within a window to generate handwriting entry and recognition behavior. The RC Manager invokes the recognizer for the application. The procedure is as follows:

1.	Install a custom recognizer (if appropriate), using InstallRecognizer.

2.	When pen input begins, initialize the RC data structure.

3.	Call the recognizer.

4.	Receive the recognized data in a Windows message.

5.	Process the data with your program.

6.	When finished, unload the custom recognizer (if appropriate).

Using the Pen Controls

The hedit control completely replaces the default edit class of Windows. In addition to the normal edit control functionality, hedit supports direct handwriting input. That is, in an hedit control, you can mix keyboard, mouse, and pen input.

The bedit control is an entirely new edit class that implements boxed input. The bedit control also accepts keyboard and mouse input.

Function Subcategories

The Pen Interface functions install and call recognizers, create handwriting edit controls, and unload recognizers when completed.

There are five subcategories of functions in the Pen Interface category:

*	Virtual Event Layer

*	Recognition

*	Symbol Manipulation

*	Training

*	Utility

Virtual Event Layer

The Virtual Event Layer subcategory provides the mechanism for sending virtual mouse or keyboard events to Windows. The following table describes the functions in this subcategory.

Function	Description
AtomicVirtualEvent	Blocks out physical pen events while posting virtual events
PostVirtualKeyEvent	Sends a virtual key code event to Windows
PostVirtualMouseEvent	Sends a virtual mouse event to Windows
Recognition

The Recognition subcategory provides the mechanism for initializing, installing, and unloading the recognizer; for recognizing data; and for correcting errors. The following table describes the functions in this subcategory.

Function	Description
CorrectWriting	Displays Edit Text Window.
EmulatePen	Emulates text I-beam. In general, you should use ProcessWriting or hedit controls instead.
ExecuteGesture	Converts a gesture to a set of keystrokes that the user has mapped.
InitRC	Initializes recognition context for the recognizer.
InstallRecognizer	Loads a specified recognizer.
IsPenAware	Checks application's capability of handling pen events.
ProcessWriting	Runs high-level recognition services.
Recognize	Begins sampling pen data from the tablet and converts the input to recognized symbols.
RecognizeData	Converts pen data stored in a buffer to recognized symbols.
RegisterPenApp	Modifies the behavior of an edit control within an application to behave as an hedit control.
SetRecogHook	Installs or removes a recognition hook.
ShowKeyboard	Displays or hides the on-screen keyboard.
UninstallRecognizer	Unloads a specified recognizer.
Symbol Manipulation

The Symbol Manipulation subcategory provides the mechanism for converting symbols to characters.

A symbol value is a 32-bit value which represents a glyph (such as a character or a gesture) recognized by a recognizer. This is sometimes referred to as a symbol. A symbol string is a null-terminated array of symbols.A symbol graph is a compact representation of the alternatives recognized.

The following table describes the functions in this subcategory.

Function	Description
CharacterToSymbol	Converts an ANSI string to an array of symbol values.
GetSymbolCount	Returns the number of possible symbol strings that can be generated from the symbol graph.
EnumSymbols	Enumerates strings of symbols from a symbol graph.
FirstSymbolFromGraph	Returns the array of symbols that is the most likely interpretation of a specific symbol graph.
GetSymbolMaxLength	Gets the length of the longest symbol string generated from the symbol graph.
SymbolToCharacter	Converts an array of symbols to an ANSI string.
Training

The Training subcategory provides the mechanism for training the ink to improve recognition. The following table describes the functions in this subcategory.

Function	Description
TrainContext	Informs the recognizer that the raw data input represents the symbol value results.
TrainInk	Informs the recognizer that the raw data input represents the symbol value results.
Utility

The Utility subcategory provides a variety of functions for general maintenance, coordinate conversion, and low-level functions. The following table describes the functions in this subcategory.

Function	Description
BoundingRectFromPoints	Returns the bounding rectangle of an array of points.
DPtoTP	Converts display coordinates to tablet coordinates.
GetGlobalRC	Gets the current default settings for the specified recognition context. Normally, an application gets this information at RC initialization time. However, if you need to query these values at some other time, use GetGlobalRC.
GetMessageExtraInfo	Windows function used to extract extra information passed along with mouse event messages.
GetPenAsyncState	Gets the barrel button state of the pen.
GetVersionPenWin	Gets the version number.
SetGlobalRC	Sets default settings for the specified recognition context. This function should only be called from the pen control panel program.
SetPenHook	Captures low-level pen events.
TPtoDP	Converts tablet coordinates to display coordinates.


PenData Functions

The HPENDATA handle to the pen data memory block is the primary mechanism for passing the information captured from the pen between an application and other applications and recognizers.

The pen data functions manipulate the pen data memory block. The following table describes the functions in this category.

Function	Description
AddPointsPenData	Adds an array of new points and OEM data to an existing pen data memory block.
BeginEnumStrokes	Initializes the pen data memory block.
CompactPenData	Performs various memory saving operations on the pen data memory block
CreatePenData	Allocates memory for a new pen data memory block and initializes its header
DestroyPenData	Frees up memory associated with a pen data memory block
DrawPenData	Displays the ink in an hDC
DuplicatePenData	Creates a second copy of the given pen data memory block
EndEnumStrokes	Unlocks the specified memory block
GetPenDataInfo	Gets the status information for the pen data memory block
GetPenDataStroke	Gets the raw data for a stroke stored in the pen data memory block
GetPointsFromPenData	Returns an array of points from the pen data memory block
MetricScalePenData	Converts pen data points to one of the supported metric modes
OffsetPenData	Offsets pen data points by a specified amount
ResizePenData	Stretches or shrinks the physical size of the pen data memory block


Custom Recognizer
Custom Recognizer Functions

The recognizer component is replaceable. Vector refers to the recognition of a sequence of pen-location data points collected as the pen is moving. The other method of recognition, bitmap, refers to optical character recognition (OCR) techniques, which accept an image of the characters to be recognized as input. This method of recognition is not supported by the Pen API but it is possible to write an OCR application under Windows.

The following table describes the functions that must be supplied in an OEM recognizer DLL.

Function	Description
CloseRecognizer	Called when the recognizer is uninstalled by an application
ConfigRecognizer	Sets recognizer-specific parameters
InitRecognizer	Gives the recognizer a chance to do any initialization before receiving the first request for recognition
RecognizeDataInternal	Begins sampling pen data stored in the buffer and converts the input to recognized symbols
RecognizeInternal	Begins sampling pen data from the tablet and converts the input to recognized symbols
TrainContextInternal	At the DLL recognition level, informs the recognizer that the raw data input represents the symbol value results using contextual information
TrainInkInternal	At the DLL recognition level, informs the recognizer that the raw data input represents the symbol value results
Any recognizer will also make extensive use of the Pen Module functions described in the next section. The Pen Module functions provide the means of capturing and manipulating pen data in the recognition process.

A recognizer may also allow another module to examine the results of recognition before the results are sent to the application


Pen Module
Pen Module Functions

The pen module is the component of the RC Manager that the pen driver calls to enter new events. The pen module is responsible for buffering events and generating the appropriate Windows mouse events.

A pen module operates in two modes, pen collection mode and mouse mode. The module is initialized in mouse mode. The RC Manager handles the switching of the two modes.

The pen module functions fall into two sets. One set consists of the data collection and pen information functions called by recognizers and applications. The other set consists of the functions called by the pen driver.

Function	Description
AddPenEvent	Adds a pen event to the pen module for later processing. Called by a pen driver.
EndPenCollection	Forces an end to pen data collection mode. Called by a recognizer.
GetPenHwData	Gets data from the internal pen buffer. Called by a recognizer.
GetPenHwEventData	Gets pen data associated with a range of specified mouse events. Called by an application.
IsPenEvent	Checks to see if the given mouse event was generated by the pen driver. Called by an application.
ProcessPenEvent	Tells the pen module to process any pending pen events. Called by a pen driver.
UpdatePenInfo	Updates the PENINFO data structure. This function is called only by the pen driver when a PENINFO value changes. Called by a pen driver.


Pen Driver Functions

A pen driver provides the same functionality as the mouse driver in the system, and it provides additional support needed for recognition. A pen driver is free to do any low-level filtering necessary to correct for hardware problems. This includes correcting for pen skip (pen up and down actions due to contact bounce), removing duplicate points, and smoothing jitter. The pen driver is loaded as an installable device driver under Windows version 3.1.

The pen driver provides two types of functionality:

* 	The hardware-specific code necessary to convert the tablet's data into the standard pen format

* 	The APIs to examine the capabilities of the tablet and modify some of its behavior

The following minimum assumptions apply to the tablet and pen supported by the system:

*	The tablet should have a sampling resolution of at least 200 dots per inch. A minimal sampling rate of 120 samples per second is required.

*	A barrel button is recommended. The barrel button does not need to be located physically on the pen, but the handling of any barrel events should be in the pen driver.

*	The ability to detect the position of the pen when it is not in contact with the tablet surface is strongly recommended.

A pen device can provide capabilities in addition to these minimum requirements. Besides capturing the (x,y) data, a pen device can support as many as eight more types of input data: pressure (force), height, angle, and others. This optional information is passed in with the (x,y) data with each pen packet.

All pen driver functionality is implemented with installable driver messages. A pen driver must also support the standard installable device driver messages.


Display Driver Functions

The definition of a Windows display driver has been expanded to support "inking." Inking is drawing done by the display driver at interrupt time. The mechanisms for managing inking are very similar to those used for managing a cursor, the other Windows mechanism for drawing on the screen at interrupt time without calling the Windows Graphic Device Interface.

The InkReady function tells the display driver that ink is ready to be drawn. This API is never called directly by an application.

A pen display driver must also define a new pen cursor type, IDC_PEN (value 32631).


Dictionary Functions

When the recognizer has finished attempting to identify the input, it returns a symbol graph to the RC Manager. If the application has requested the NULL dictionary, it generates a symbol string from the symbol graph. Otherwise, the RC Manager invokes a specified set of dictionary modules to perform further processing.

You can build your own custom dictionary with the DictionaryProc function.


AddPenEvent

Action

Adds a pen event to the pen module for later processing

Module

PenModule

Called By

Pen driver

Syntax

mov  	si, offset PenPacket

call   	dword ptr lpfnAddPenEvent

Comments

The basic unit of communication between the pen driver and Windows is a pen packet. A pen packet contains all of the information about a single logical event: (x,y) coordinate position, button states, and any optional information such as pressure or barrel rotation. Many physical events -- interrupts -- may be needed to construct a single logical event.

On entry, DS:SI should point to a pen packet.

The PENPACKET structure is defined in the TABLET.INC file. The definition is shown in the following code fragment.

; PENPACKET - what drivers should use to communicate with

; PenWin.Dll

;

PENPACKET struc

wTabletX	dw	0	; X in tablet coordinates

wTabletY	dw	0	; Y in tablet coordinates

wPDK	dw	0	; various status bits for packet

rgwOemData	dw	MAXOEMDATAWORDS dup (0)	; OEM info like pressure

PENPACKET ends

This function adds the pen packet at ds:[si] to a safe internal location in the pen module.  This function is not reentrant.  Once the pen packet has been added to the pen module, the ProcessPenEvent function will process any pending pen events.  ProcessPenEvent can be reentered.

A pen driver should construct a pen packet with tablet interrupts disabled, call AddPenEvent, re-enable tablet interrupts, and then call ProcessPenEvent.

Return Value

None

See Also

ProcessPenEvent


AddPointsPenData

Action

Adds a set of data points to the pen data structure

Module

RC Manager

Called By

Recognizer, Application

Syntax

C:

HPENDATA   AddPointsPenData(hpendata, lpPnt,  lpvOemData, lpsiNew)

PASCAL:

function AddPointsPenData(hPenData: THPenData; lpPnt: PPoint;

  lpvOemData: Pointer; lpsiNew: PStrokeInfo): THPenData;

Parameter	Type	Description
hpendata	HPENDATA	Handle to pen data structure.
lpPnt	LPPOINT	New data points to be added to structure. Zero points may be added to force a change of pen state or to set a new pen state.
lpvOemData	LPVOID	OEM data (can be sett to NULL if there is no additional OEM data). This is interpreted as indicated in the pen data header.
lpsiNew	LPSTROKEINFO	Header for new stroke data. Contains the count of points from lpPnt to be added.
Comments

In use, a call to GetPenHwEventData gets the lpsiNew and lpvOemData values. A subsequent call to AddPointsPenData adds these points to the pen data structure.

AddPointsPenData does not scale the data points. It is the caller's responsibility to ensure the proper scaling.

If adding the points to be added represent the same pen up or down stae, the data is appended to the last stroke. Otherwise a new stroke is added.

Return Value

AddPointsPenData returns a handle to the pen data structure. Normally, this is the same handle that was originally passed to the function. NULL is returned on an error. The size of hpendata is limited to 64K.

See Also

CreatePenData, GetPenHwData, GetPenHwEventData


AtomicVirtualEvent

Action

Locks out pen packets

Module

RC Manager

Called By

System applications (Pen Palette)

Syntax

C:

void   AtomicVirtualEvent(fBegin)

PASCAL:

procedure AtomicVirtualEvent(fBegin: Bool);

Parameter	Type	Description
fBegin	BOOL	Sets TRUE to begin lockout. Sets FALSE to end lockout.
Comments

This function is used by the Pen Palette or a similar virtual keyboard program to lock out pen packets while the application is posting simulated key or mouse events. For example, the following code fragment posts a mouse click:

AtomicVirtualEvent( TRUE );

PostVirtualMouseEvent( VWM_MOUSELEFTDOWN, xPos, yPos );

PostVirtualMouseEvent( VWM_MOUSEMOVE, xPos, yPos );

PostVirtualMouseEvent( VWM_MOUSELEFTUP, xPos, yPos );

AtomicVirtualEvent( FALSE );

Calling AtomicVirtualEvent with a TRUE value blocks out input from physical devices until they are freed with a FALSE call. Therefore, a call to AtomicVirtualEvent(FALSE) should quickly follow.

Return Value

None

See Also

PostVirtualKeyEvent, PostVirtualMouseEvent


BeginEnumStrokes

Action

Locks an HPENDATA data structure in memory in preparation to enumerating strokes

Module

RC Manager

Called By

Application

Syntax

C:

LPPENDATA  BeginEnumStrokes(hpendata)

PASCAL:

function BeginEnumStrokes(hPenData: THPenData): PPenDataHeader;

Parameter	Type	Description
hpendata	HPENDATA	Handle to pen data structure
Comments

This function should be called before GetPenDataStroke. The returne value from BeginEnumStrokes can be used in the GetPenDataStroke function. The HPENDATA locked using BeginEnumStrokes must be unlocked using EndEnumStrokes.

Return Value

A far pointer of type LPPENDATA. This function will return NULL if hpendata is compressed or if the handle could not be locked.

See Also

EndEnumStrokes, GetPenDataStroke


BoundingRectFromPoints

Action

Returns the bounding rectangle specified by the given points

Module

RC Manager

Called By

Application, recognizer

Syntax

C:

void  BoundingRectFromPoints(lpPnt, cPnt, lprectBound)

PASCAL:

procedure BoundingRectFromPoints(lpPnt: PPoint; cPnt: Integer;

  lpRectBound: PRect);

Parameter	Type	Description
lpPnt	LPPOINT	Pointer to an array of points
cPnt	int	Count of points
lprectBound	LPRECT	Pointer to bounding rectangle containing lpPnt points
Comments

Paramater validation does nothing if lpPnt or lprectBound are invalid pointer values.

Return Value

Returns bounding rectangle in lprectBound. The rectangle is set to an empty rectangle if cPnt is zero.

See Also

DPtoTP


CharacterToSymbol

Action

Converts an ANSI string to an array of symbol values

Module

RC Manager

Called By

Application

Syntax

C:

int  CharacterToSymbol(lpstr, cSyv, lpsyv)

PASCAL:

function CharacterToSymbol(lpstr: PStr; cSyv: Integer; lpsyv: PSYV): Integer;

Parameter	Type	Description
lpstr	LPSTR	Pointer to a null-terminated ANSI string
cSyv	int	Count of maximum symbols lpsyv can hold
lpsyv	LPSYV	Pointer to symbol values buffer
Comments

Conversion proceeds until a NULL byte is found in lpstr or lpsyv has been filled with cSyv symbols. A NULL byte is converted to SYV_NULL.

Return Value

Returns the number of characters converted

See Also

SymbolToCharacter


CloseRecognizer

Action

Informs the recognizer that it is being unloaded by an application

Module

Recognizer

Called By

RC Manager

Syntax

C:

void  CloseRecognizer()

PASCAL:

procedure CloseRecognizer;

Comments

This function is called when an application uninstalls a recognizer by a call to UninstallRecognizer.

Because multiple applications can load a given recognizer, it is the recognizer's responsibility to maintain a use count to determine whether a given CloseRecognizer call is being made because the last application is unloading.

Because an application may abnormally end without unloading a recognizer, the use count may be invalid. An alternate strategy is to perform all necessary closing operations -- for example, saving newly trained prototypes -- on each call to this function.

This function is in the recognizer and is not called directly by an application.

Return Value

None

See Also

InitRecognizer, InstallRecognizer, UninstallRecognizer


CompactPenData

Action

Compacts the pen data based on specified trim options

Module

RC Manager

Called By

Application

Syntax

C:

HPENDATA  CompactPenData(hpendata, wTrimOptions)

PASCAL:

function CompactPenData(hPenData: THPenData; wTrimOptions: Word): THPenData;

Parameter	Type	Description
hpendata	HPENDATA	Pen data
wTrimOptions	UINT	Data-trimming options
Comments

CompactPenData trims the pen data in hpendata based on the wTrimOptions parameter.

The following table lists the trim options.

Trim options	Meaning
PDTT_DEFAULT	Reallocates memory block to fit the data; does not trim the data. If you call CompactPenData with this trim option and the call GlobalSize(hpendata), you can get the size of the data file to be saved. This data can be written out like any other block of binary data.
PDTT_ALL	Removes the PENINFO structure from the header; throws out all data from up points (points collected when the pen is not in contact with the tablet) and removes OEM data and collinear points.
PDTT_COLINEAR	Removes successive identical points and colinear points from the pen data. After the operation is performed, PDTS_NOCOLINEAR is set in the wPndts field of the pendata header. The colinear points can be removed with very little loss of recognition accuracy. If the colinear points are removed before the points are scaled to display coordinates, there may be some slight change in visual image.
PDTT_COMPRESS	Compresses the data without losing any information. Once the data has been compressed, the compressed hpendata can be passed as a parameter only to the following functions: CompactPenData, GetPenDataInfo, DuplicatePenData. This is the best compression currently provided by the CompactPenData function that retains the ability for an application to come back later and recognize the ink.
PDTT_DECOMPRESS	Decompresses the data. You cannot use this option with any other trim options. Compression will restore the data completely.
PDTT_OEMDATA	Removes OEM data. (That is, data other than x,y coordinates such as pressure.) This option will not effect delayed recognition unless a recognizer is being used that expressly requires OEM data.  For example, signature recognizers often user pressure information.
PDTT_PENINFO	Removes the PENINFO structure from the header. Use this option if there is no OEM data associated with the data points or if the application will not be using any of thie OEM data. This option will have no effect on the pen data for delayed recognition.
PDTT_UPPOINTS	Throws out all data from up points (points collected when the pen is not in contact with the tablet). This option will have no effect on delayed recognition, but it should not be necessary the majority of the time since up points are not a part of  standard pen data anyway.
Return Value

If successful, this function returns an HPENDATA handle to the PENDATA structure. Otherwise, it returns NULL. CompactPenData may fail and return NULL in low memory situations if compression or decompression is requested.

The PDTS_ bits are set in the wPdts field in the PENDATA header to indicate which operations have been performed.

See Also

CreatePenData


ConfigRecognizer

Action

Sets recognizer-specific parameters

Module

Recognizer

Called By

System applications (Pen Palette, Control Panel, and so on)

Syntax

C:

UINT  ConfigRecognizer(wConfigRecog, wParam, lParam)

PASCAL:

function ConfigRecognizer(wConfigRecog: Word; wParam: Word;

  lParam: Longint ): Word;

Parameter	Type	Description
wConfigRecog	UINT	Specifies recognizer subfunction.
wParam	UINT	See descriptions following.
lParam	LONG	Far pointer to buffer.
Comments

This function provides various initializations and query functions.

The value of wConfigRecog determines what function is performed.

Recognizer subfunction	Meaning
WCR_DEFAULT	This subfunction returns TRUE if the recognizer is capable of being a default recognizer. A default recognizer must support the standard character set as well as the gestures.
WCR_CONFIGDIALOG	This subfunction informs the recognizer to open a dialog box to set any recognizer-specific parameters. (This is analogous to DEVMODE in printer drivers, which is called when a user requests a printer setup.) Some examples of the type of settings a recognizer may choose to implement are whether or not to allow cursive input, how much to depend on stroke order, and how rapidly to modify prototypes based on the user's own style. The lParam parameter points to the name of the currently selected user in the Control Panel. Beccause the global RC may not yet have been updated, this may not be the same as the user in the global RC. The wParam parameter is used by the recognizer as the parent window for any dialog boxes it displays. The return value is always TRUE. A recognizer may also choose to implement this as a NULL procedure consisting of just a return statement.
WCR_PRIVATE	Values above WCR_PRIVATE have a recognizer-dependent meaning.
WCR_QUERY	This subfunction returns TRUE if the recognizer supports a configuration dialog.
WCR_QUERYLANGUAGE	The wParam parameter is not used. The lParam parameter points to a null-terminated language string. For a description of the language strings, see the documentation for the lpLanguage field of the RC structure. The return value is TRUE if the recognizer supports the language. Otherwise it is FALSE.
WCR_RCCHANGE	The lParam parameter points to the new default RC structure. An application that loads nondefault recognizers should call this subfunction for each recognizer it has loaded in response to a WM_GLOBALRCCHANGE message. The return value is TRUE. A recognizer may support only certain RC fields at the global level such as language or user.
WCR_RECOGNAME	This subfunction treats the lParam parameteras a far pointer to a buffer that is filled with an identification string from the recognizer. The wParam parameter is the size of the buffer to fill. The identification string is a short description of the recognizer that the Control Panel presents to the user. A sample string is "US English character set, cursive & print." The return value is always TRUE.
WCR_TRAIN	This subfunction returns TRAIN_NONE if the recognizer does not support training. A return value of TRAIN_DEFAULT indicates support for the default trainer. A return value of TRAIN_CUSTOM indicates that the recognizer also provides its own custom trainer. A return value of TRAIN_BOTH indicates support for both kinds of training.
WCR_TRAINCUSTOM	If the recognizer responds TRAIN_CUSTOM or TRAIN_BOTH in response to WCR_TRAIN, it will receive a WCR_TRAINCUSTOM message when it is time to display it's own training system. The format for calling this subfunction is: ConfigRecognizer(WCR_TRAINCUSTOM, hwnd, lprcresult) The hwnd parameter is a handle to the requesting window; the trainer uses this as the parent window for a dialog box, for example.  If there has been a recent recognition, a pointer to it will be passed in the lParam field, although this may be null.
WCR_TRAINDIRTY	The recognizer returns TRUE if the recognizer needs to save training. Th recognizer returns FALSE if no training occurred, if the recognizer does not use a database for training, if the recognizer saves as it works, or if the recognizer cannot revert the training. The format for this subfunction call is: ConfigRecognizer(WCR_TRAINDIRTY,0,0).
WCR_TRAINMAX	The recognizer returns the maximum number of SYVs that it can train for any given shape. It should return 0 if it can train any number of characters.
WCR_TRAINSAVE	The trainer calls ConfigRecognizer  ( WCR_TRAINSAVE, TRAIN_SAVE, 0 ) when it is time to save the database. This will happen when the user closes the trainer. After this call, the recognizer should return TRUE if it can successfully save the database; otherwise, it should return FALSE. The trainer calls ConfigRecognizer ( WCR_TRAINSAVE, TRAIN_REVERT, 0 ) before it discards any changes made to the database that have not yet been saved to disk (that is, revert to saved).  This will happen when the user cancels the changes. Again, the recognizer should return TRUE if it is successful.
WCR_USERCHANGED	Notifies the recognizer that a user has changed.  The lParam parameter points to the name of the user that is affected.  The modification is indicated by the wParam parameter. Currently, only one modification notification is sent to a recognzer. A wParam value of CRUC_REMOVE indicates that the user is being removed from the user list.  If the recognizer has saved any files or settings for the user, they should be deleted in response to this notification.  If the recognizer receives this message with a new user, it should do nothing.  The return value is 0.
WCR_VERSION	The function returns version number. The low-order byte of the return value specifies the major (version) number. The high-order byte specifies the minor (revision) number.
Return Value

The return value is described in the preceding table for each WCR_ value.


CorrectWriting

Action

Sends text to the edit text dialog for modification.

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  CorrectWriting(hwnd, lpBuf, cbBuf, lprc, dwCwrFlags, dwReserved)

PASCAL:

function CorrectWriting(hw:HWnd; lpBuf:PChar; cbBuf: Word; lprc: PRC;

  dwCwrFlags: Longint; dwReserved: Longint): Bool;

Parameter	Type	Description
hwnd	HWND	Handle to the window that is the owner of the correction dialog.
lpBuf	LPSTR	Text to be corrected.
cbBuf	UINT	Number of characters (greater than 1) in lpBuf. This should include space for the NULL terminator of the string.
lprc	LPRC	Pointer to RC structure for context or NULL.
dwCwrFlags	DWORD	Translation and style flags. NULL is the default.
dwReserved	DWORD	Reserved for future use. NULL is the default.
Comments

An application calls CorrectWriting to send text to the edit text dialog. Normally, this would be in response to receiving the SYV_CORRECT gesture.

The hwnd parameter contains a Windows handle to the window that will be used as the owner of the dialog created for correction. The edit text dialog will be application-modal based on the hwnd parameter.

The lpBuf parameter contains the text to be corrected. It is zero-terminated with maximum size of cbBuf. The corrected text is also returned in lpBuf. As a general rule, the lpBuf parameter should allow for growth by a factor of two or more -- or some maximum size that is dependent on the field of entry.

If lprc is not NULL, the following fields from lprc are used as the context for correction. If the field in lprc has a default value, it will not override the corrector's default value.

• lpfnYield	• lpUser
• lpLanguage	• rglpdf
• wTryDictionary	• clErrorLevel
• alc	• alcPriority
• rgbfAlc	• dwDictParam
• dwRecognizer	• hrec
The dwCwrFlags parameter may be any combination of the following. The default value of NULL indicates that none of these translation flags are to be applied.

Subfunction	Meaning
CWR_STRIPLF	Removes the LF characters
CWR_STRIPCR	Removes the CR characters
CWR_STRIPTAB	Removes the tab characters
CWR_SINGLELINEEDIT	CWR_STRIPLF | CS_STRIPCR | CWR_STRIPTAB
CWR_TITLE	If this flag is set, dwReserved is interpreted as an LPSTR pointer to a null-terminated caption string.
If the user chooses OK from the correction dialog box, and if any of the dwCwrFlags (except CWR_TITLE) are set, then the dwCwrFlags characters are removed from the buffer before the text is returned to the application.

Return Value

This function returns TRUE if the OK button is pressed in the Edit Text dialog box. Otherwise, it returns FALSE. If FALSE is returned, the application should leave the text unchanged in the original application.


CreatePenData

Action

Creates a PENDATA structure

Module

RC Manager

Called By

Application, recognizer

Syntax

C:

HPENDATA  CreatePenData(lppeninfo, cbOemData, wPdtScale, gmemFlags)

PASCAL:

function CreatePenData(lpPenInfo: PPenInfo; cbOemData: Integer;

  wPdtScale: Word; gmemFlags: Word): THPenData;

Parameter	Type	Description
lppeninfo	LPPENINFO	Far pointer to tablet information for filling the HPENDATA structure. If this is NULL, the current tablet settings are used.
cbOemData	int	Width of OEM data packet. If this value is greater than or equal to zero, the OEM data will override whatever is contained in the PENINFO structure.
wPdtScale	UINT	Data scaling metric value.
gmemFlags	UINT	Parameter for specifyiing the flags passed to the Windows GlobalAlloc function when memory for the HPENDATA object is created. The gmemFlags parameter should be 0 or GMEM_DDESHARE.
Comments

The following table lists the wPdtScale values. These scaling values are also used in the API function MetricScalePenData and in the wPdts field of PENDATAHEADER.

The scaling values do not behave in the same way as the Windows terms of the same name. For example, in the Windows GDI, a line 1 inch long in MM_HIENGLISH will not necessarily be an inch long on the screen, because the GDI does not know the size of the monitor.  However, with PDTS_HIENGLISH in MetricScalePenData, an application can assume that a line drawn an inch long really is an inch long.

Scaling value	Meaning
PDTS_LOMETRIC	Each logical unit is mapped to 0.01 mm. Positive x is to the right; positive y is down.
PDTS_HIMETRIC	Each logical unit is mapped to 0.001 mm. Positive x is to the right; positive y is down.
PDTS_HIENGLISH	Each logical unit is mapped to 0.001 inch. Positive x is to the right; positive y is down.
PDTS_TABLET	Data points are in tablet units.
PDTS_ARBITRARY	The application has done its own scaling of the data point.
PDTS_STANDARDSCALE	The standard scaling metric is equivalent to PDTS_HIGHENGLISH.
Return Value

This function returns a handle to the pen data memory block that was created. The HPENDATA data type is returned to the recognizer to represent raw data. On creation, the pen data memory block contains no point.

If successful, this function returns an HPENDATA handle to the PENDATA structure. Otherwise, it returns NULL. It returns NULL on a memory allocation failure.

See Also

DestroyPenData


DestroyPenData

Action

Frees up memory associated with an hpendata memory block

Module

RC Manager

Called By

Application, recognizer

Syntax

C:

#define DestroyPenData(hpendata) (GlobalFree (hpendata) == NULL)

PASCAL:

function DestroyPenData(hPenData: THPenData): Boolean;

begin

  DestroyPenData := GlobalFree(hPenData) = 0;

end;

Comments

The DestroyPenData macro uses the Windows GlobalFree function to free up memory associated with the specified hpendata memory block.

Return Value

This function returns TRUE if the macro is successful. Once memory is freed, the hpendata handle is no longer valid.

See Also

CreatePenData


DictionaryProc

Action

Entry point into dictionary module.

Module

Dictionary

Called By

RC Manager

Syntax

C:

int FAR PASCAL  DictionaryProc(dirq, lpIn,  lpOut, cbMax, dwContext, dwData)

Parameter	Type	Description
dirq	int	Dictionary subfunction number. See the dictionary subfunction table following.
lpIn	LPVOID	Input parameter (type dependent on dirq).
lpOut	LPVOID	Output parameter (type dependent on dirq).
cbMax	int	Size of lpOut buffer.
dwContext	DWORD	Reserved for future implementation.
dwData	DWORD	Dictionary-specific data.
Comments

This is the only exported function required in any dictionary DLL.

The process of loading dictionaries and identifying entry points is handled in the same way as any other DLL. That is, you just use the LoadLibrary and GetProcAddress API functions under Windows.

Dictionary Subfunction Table (dirq Parameter)

The following table lists the dictionary subfunctions.

DIRQ subfunction	Meaning
DIRQ_QUERY	This subfunction queries the dictionary. The lpIn parameter is a far pointer to an integer containing a DIRQ_ value. It returns TRUE if the dictionary supports the subfunction; otherwise, it returns FALSE.
DIRQ_STRING	This subfunction looks for the existence of a string. The lpIn parameter points to a SYV_NULL-terminated array of symbol values. If a match for the string is found, cbmax symbols from lpIn are returned in lpOut. If not successful, DIRQ_STRING returns zero. Otherwise, it returns the number of symbols copied to lpOut. SYV_NULL terminates the output buffer if enough space is available. The return count does not include SYV_NULL. The lpIn parameter can be NULL. NULL can be used as a signal to the dictionary to return any deferred match. Note that a dictionary implementation does not have to be a simple look-up. For example, a dictionary function can be written to determine if the input matches the format for a social security number.
DIRQ_SUGGEST	This subfunction is provided so that applications can use the same dictionaries for spell checking as for handwriting recognition. The lpIn parameter is a pointer to a symbol string. Symbol strings terminated by SYV_NULL are placed in lpOut. The end is marked by two successive SYV_NULLs. The return value is the count of alternatives placed in lpOut. A dictionary implementation can be written so that, if the word being looked up is in the dictionary, DIRQ_SUGGEST always returns FALSE or, alternatively, the contentx of lpIn in lpOut.
DIRQ_SYMBOLGRAPH	This subfunction is provided so that dictionaries can examine the whole symbol graph before each enumeration is passed in individually. The lpIn parameter contains a far pointer to the symbol graph. The other parameters are the same as those in DIRQ_STRING. Before enumerating, DIRQ_SYMBOLGRAPH checks each dictionary once to see if any dictionary is prepared to handle the whole symbol graph. The check takes place if RCO_SUGGEST is on.
DIRQ_USER	Values greater than DIRQ_USER (that is, >4096) can be used for private calls to the dictionary DLL. Each dictionary may define its own values.
Other DIRQ_ values are defined for adding words, deleting words, and saving dictionaries. These are discussed in the OEM Dictionary Module section, later in this listing. However, only the subfunctions in the preceding list are called by the DictionarySearch API which is in the RC Manager.

A dictionary called with a subfunction number it does not support should return FALSE. A dictionary must support: DIRQ_OPEN, DIRQ_CLOSE, DIRQ_QUERY, DIRQ_STRING, DIRQ_INIT, DIRQ_CLEANUP, and DIRQ_DESCRIPTION.

NULL Dictionary

The NULL dictionary provides the minimum mapping functionality from a symbol graph to a symbol string. The resulting string is the best enumeration as returned by FirstSymbolFromGraph.

DictionarySearch Function

When the recognizer has attempted to identify the input, it returns a symbol graph. If the application has requested the NULL dictionary, it generates a symbol string from the symbol graph. Otherwise, the RC Manager calls the DictionarySearch function.

If the RCRESULT field hSyv is not NULL, the RC Manager assumes that the dictionary has already filled it in. This means the recognizer can perform the dictionary processing itself. Once the recognizer has completed its dictionary processing, it simply sets hSyv in RCRESULT to a non-NULL value. The recognizer must set hSyv to NULL every time if it is not performing the dictionary processing.

Word Definitions and Validation

If you build a dictionary, you determine the rules for identifying which words to validate. For example, the symbol graph may contain punctuation or other symbol values not in the character set supported by the dictionary. A dictionary can strip out punctuation and perform the look-up, or it can just fail on words containing symbols outside the dictionary's supported character set.

Unless RCO_NOSPACEBREAK is set in the RC structure, the symbol strings passed to the dictionaries are divided at white-space characters.

A symbol graph passed to a dictionary may include a space as an option. For example, the symbol graph "fat{space|null}cat" represents two possible strings: "fat cat" and "fatcat." These are passed in as two words.

The RC Manager passes a parameter into the dictionary to provide access to dictionary functionality not directly supported. The dwDictParam parameter is set by an application and passed on to the dictionary by the RC Manager. For example, a dictionary may request that the application pass in a pointer to a structure containing the sentence to which the results of the recognition will be added, as well as an indication of where in the sentence the new characters are to be added.

Spell Checking

Spell checking should be handled in the normal ways by the application using handwriting input. Dictionary modules can also be used by the recognizer for spell checking. However, to avoid outguessing the user, the recognizer does not attempt corrections based on spelling errors except when DIRQ_SUGGEST is specified. For example, if the user writes "seperate," the recognizer will not report "separate" -- unless it indicates that the second "e" could be an "a."  However, the application is free to take the result returned by the RC Manager and perform spell checking on it.

OEM Dictionary Module

The dictionary module provides a way of loading in DLLs as dictionaries and establishing a default dictionary to look through. Loading dictionaries and identifying entry points is handled in the same way that printer drivers use the Windows LoadLibrary and GetProcAddress functions.

DIRQ subfunction	Meaning
DIRQ_ADD	Adds a word to the word list. The lpOut parameter is the word (SYV string) to add. The lpIn parameter is a handle to the word list returned by DIRQ_OPEN. DIRQ_ADD returns 1 if the word if successfully added. Otherwise, it returns 0.
DIRQ_CLOSE	Closes or discards a word list. The lpIn parameter is a pointer to the handle previously received after a successful DIRQ_OPEN. DIRQ_CLOSE returns 1 if successful. Otherwise, it returns 0. The dictionary DLL determines whether to save all of the changes made through DIRQ_ADD, DIRQ_DELETE, and DIRQ_FLUSH before closing a word list.
DIRQ_CONFIGURE	Opens the dictionary DLL's private configuration dialog. This can be used to establish which word lists to use with the given dictionary DLL. The lpIn parameter points to a window handle to be used as the parent of the dialog box. DIRQ_CONFIGURE returns 1 if the user makes a change.
DIRQ_COPYRIGHT	Returns in lpOut a maximum of cbMax characters of a copyright notice for the dictionary DLL. This subfunction returns TRUE if lpOut is not empty. The description should not exceed 255 bytes.
DIRQ_DELETE	Deletes a word from the word list. The lpOut parameter is the word (SYV array) to delete. The lpIn parameter is a word list handle.  DIRQ_DELETE returns 1 if the word is successfully deleted.
DIRQ_DESCRIPTION	Returns in lpOut a description string for the dictionary DLL. This description is used by the Control Panel. The description should not exceed 80 bytes.
DIRQ_FLUSH	Deletes all words in a word list. The lpIn parameter points to the handle of the word list.
DIRQ_OPEN	Loads a word list. The lpIn parameter points to a string specifying the word list to load. It can be a full path or any other implementation-dependent method of identifying individual word lists. Dictionary word list files are dependent on the particular dictionary implementation. Dictionary implementation determines whether successive loads are merged or replace one another.  If the subfunction is successful, the lpOut parameter points to the handle to the word list for subsequent use. DIRQ_OPEN returns TRUE if successful.
DIRQ_QUERY	Queries the dictionary. The lpIn parameter points to an integer representing a DIRQ_ value.  DIRQ_QUERY returns TRUE if the dictionary supports the subfunction.
DIRQ_RCCHANGE	Enables dictionaries to respond to a change in their environment -- for example, a .INI change of current language. This subfunction is also used to allow a change in any other parameter in the supplied RC. It is the responsibility of an application to call this subfunction for all nondefault dictionaries it loads. It is analogous to the WCR_RCCHANGE subfunction of ConfigRecognizer. The lpIn parameter points to the new global RC. Language dictionary DLLs can unload the currently loaded language dictionary and load the new language dictionary in response to this call. How or whether to respond to this call is determined by the DLL implementation.
DIRQ_SETWORDLISTS	Sets the user/language word lists to search through in DIRQ_STRING, DIRQ_SUGGEST, and DIRQ_SYMBOLGRAPH commands. If the function is not successful because of incorrect handles, the old search lists are retained. The lpIn parameter contains an array of handles obtained by using DIRQ_OPEN. The cMax parameter is the count of handles in the array. DIRQ_SETWORDLISTS returns TRUE if successful.
User Dictionary DLL

The User Dictionary DLL (USERDICT.DLL) supports a user-defined set of words, with the following DIRQ_ values.

•	DIRQ_ADD

•	DIRQ_CLOSE

•	DIRQ_DELETE

•	DIRQ_DESCRIPTION

•	DIRQ_OPEN

•	DIRQ_QUERY

•	DIRQ_SETWORDLISTS

•	DIRQ_STRING

On initialization (in LibMain), the user dictionary DLL loads all of the user dictionaries (to a maximum of 6) in the [UserDict] section of the PENWIN.INI file.

The PENWIN.INI file might look like the following:

[UserDict]

c:\pensdk\bin\names.dic=

c:\states.dic=

Each task can open a maximum of 6 word lists, so as many as 6 word lists can be set up for default searching. If a task performs a DIRQ_SEARCH without first using a DIRQ_OPEN or a DIRQ_SETWORDLIST, the input buffer will be searched for a match in the default dictionaries.

The word lists are a list of strings, one string per line, listed in alphabetic order. A user dictionary can be created using a word processor. The word-list file should not have any other formatting information and should not be terminated by a ^Z character.

Language Dictionary DLL

The Language Dictionary DLL (MAINDICT.DLL) is a multilingual dictionary that currently allows one dictionary to be loaded at a time.

MAINDICT.DLL supports the following DIRQ_ subfunctions:

•	DIRQ_CLEANUP

•	DIRQ_CLOSE

•	DIRQ_COPYRIGHT

•	DIRQ_DESCRIPTION

•	DIRQ_INIT

•	DIRQ_OPEN

•	DIRQ_QUERY

•	DIRQ_RCCHANGE

•	DIRQ_SETWORDLISTS

•	DIRQ_STRING

•	DIRQ_SUGGEST

•	DIRQ_INIT

•	DIRQ_CLEANUP

•	DIRQ_COPYRIGHT

On initialization (with LibMain), MAINDICT.DLL loads the current language dictionaries based on the sLanguage keyword in PENWIN.INI.

The following table lists the implementation for each DIRQ_ subfunction within MAINDICT.DLL. Only those subfunctions with additional details beyond the descriptions given previously are described.

DIRQ subfunction	Description
DIRQ_CLEANUP	This subfunction is provided so that dictionaries can do any cleaning up before termination. The RC manager calls dictionary DLLs with this message before unloading the dictionary DLL.
DIRQ_CLOSE	Closes a language word list. The lpIn parameter is a pointer to the handle received after a successful DIRQ_OPEN. DIRQ_CLOSE returns TRUE if the close is successful.
DIRQ_COPYRIGHT	This subfunction returns the copyright string, if one is available, into the buffer specified by lpOut. The size of the buffer is cbMax. It returns TRUE if a copyright string was returned; otherwise it returns FALSE. Dictionaries should be able to respond to this message at all times.
DIRQ_INIT	This subfunction is provided so that dictionaries can do any initialization (such as loading a default word list). The RC manager calls the dictionary DLLs with this subfunction before using them for spell checking during the recognition process. A dictionary DLL may get two or more consecutive DIRQ_INIT messages before getting any DIRQ_CLEANUP messages. You should keep a count of the DIRQ_INIT calls which is incremented and decemented for each DIRQ_INIT or DIRQ_CLEANUP subfunction use.
DIRQ_OPEN	Opens a language word list. The lpIn parameter is a pointer to a three-letter language code for the language word list to be loaded. These codes are listed later in this section. The lpOut parameter returns the handle to the language word list. Other parameters are not used. The function returns TRUE if the open is sucessful; otherwise, it returns FALSE. The handle returned on a successful open can later be used for setting the word lists to search through. For more information, see DIRQ_SETWORDLISTS, later in this listing. Version 1.0 of MAINDICT.DLL can deal with only one language at a time.
DIRQ_RCCHANGE	Responds by loading a new language dictionary if the current language has changed and the dictionary is not already loaded.
DIRQ_SETWORDLISTS	Sets the language word lists to search through in DIRQ_STRING and DIRQ_SUGGEST commands. If the function is not successful due to incorrect handles, the old search lists are retained. The lpIn parameter is (int FAR *) containing an array of handles obtained by doing DIRQ_OPEN. The cMax parameter is the count of handles in the array. Returns TRUE if successful.
DIRQ_STRING	If the calling task has not made any open calls to DIRQ_OPEN or its search list is empty, the DLL searches through the current language dictionary. Otherwise, it goes through the search lists in sequence. Under Windows 3.1, you can set or change the current language, using the Control Panel.
Language Codes for DIRQ_OPEN

The following are the three-letter language codes that lpIn can point to when you open a language word list. They are the same as those allowed under Windows, version 3.1.

• NLD (Dutch)	• ITA (Italian)
• ENG (International English)	• NOR (Norwegian)
• FRC (French Canadian)	• PTG (Portuguese)
• FRA (French)	• ESP (Spanish)
• DEU (German)	• SVE (Swedish)
• ISL (Icelandic; not yet supported)	• ENU (American English)
• ESN (Modern Spanish)	• DAN (Danish)
• FIN (Finnish)
To load the language word list, the DLL looks for keyword XXXMain= where XXX represents any of the three-letter language codes under the [MainDict] section in PENWIN.INI . If the keyword is found, the DLL tries to open the file indicated. Otherwise, it looks for MSSP_YY.LEX in the BIN directory. Note that multilingual searches are costly in terms of time and memory.

The "YY" letters stand for the following language-specific two-letter codes:

• NL (Dutch)	• NN (Norwegian)
• BR (English)	• PB (Portuguese)
• FC (French Canadian)	• SP (Spanish)
• FR (French)	• SW (Swedish)
• GE (German)	• AM (American English)
• IT (Italian)
See Also

DictionarySearch


DictionarySearch

Action

Performs the requested dictionary search

Module

RC Manager

Called By

Application, RC Manager, recognizer

Syntax

C:

BOOL DictionarySearch(lprc, lpsye, cSye, lpsyv, cSyvMax)

PASCAL:

function DictionarySearch(lprc: PRC; lpsye: PSYE; cSye: Integer; lpsyv: PSYV; cSyvMax: Integer): Bool;

Parameter	Type	Description
lprc	LPRC	Pointer to the RC structure to be used in the search.
lpsye	LPSYE	Pointer to an array of symbol elements that constitute the symbol graph.
cSye	int	Number of SYEs in the array.
lpsyv	LPSYV	Output buffer of SYVs. This parameter contains the return results of the dictionary search.
cSyvMax	int	Size of the output buffer.
Comments

The DictionarySearch function takes the symbol graph in lpsye, does a dictionary search based on the options set in lprc, and returns the result as an array of SYVs in the buffer pointed to by lpsyv. The function returns the number of SYV elements copied, limited by the maximum specified in the cSyvMax parameter. A SYV_NULL value is always appended at the end, and therefore lpsyv must have enough space for csyvMax+1 SYV elements.

This function first passes in the symbol graph with DIRQ_SYMBOLGRAPH to all the dictionaries in the rglpdf array in the lprc structure. If none succeeds, the function  enumerates the symbol graph in lpsye and searches through all of the dictionary functions for a match. The caller can get suggestions by setting the RCO_SUGGEST flag in the lRcOptions field in lprc. When this flag is set and no enumeration is found in any of the dictionaries in the rglpdf array, the DictionarySearch function tries to get a suggestion from the dictionaries on the path. It takes the first suggestion offered by any dictionary and returns that as the result of the search. If there are no suggestions, the function returns the best enumeration.

The best enumeration is obtained using the FirstSymbolFromGraph function.

If the option RCO_NOSPACEBREAK is set in the lRcOptions field of lprc, the function treats the entire lpsye array as a single symbol graph. If this flag is not set, the function breaks down the input symbol graph into tokens delimited by white space, performs the search sequence on each of them, and assembles the result in the lpsyv array.

This function uses the EnumSymbols function for enumeration and the wTryDictionary field in lprc to specify the maximum number of enumerations to search through for each symbol graph token.

Return Value

The DictionarySearch function  returns TRUE if any enumeration is found in a dictionary. It returns FALSE if a NULL dictionary was requested or none of the enumerations was found in any dictionary.

See Also

DictionaryProc


DPtoTP

Action

Converts an array of points in display coordinates to tablet coordinates

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  DPtoTP(lpPnt, cPnt)

PASCAL:

function DPtoTP(lpPnt: PPoint; cPnt: Integer): Bool;

Parameter	Type	Description
lpPnt	LPPOINT	Pointer to an array of points
cPnt	int	Count of points
Comments

Because of possible rounding errors, the DPtoTP and TPtoDP functions are not guaranteed to be complete inverses of each other. It is the caller's responsibility to avoid overflow by not passing in points beyond limits of the current physical display.

Return Value

DPtoTP returns TRUE.

See Also

TPtoDP


DrawPenData

Action

Displays the the pen data in the specified device context.

Module

RC Manager

Called By

Application

Syntax

C:

void  DrawPenData(hdc, lprect, hpendata)

PASCAL:

procedure DrawPenData(DC: HDC; lprect: PRect; hPenData: THPenData);

Parameter	Type	Description
hdc	HDC	Device context
lprect	LPRECT	Bounding rectangle for ink, in client coordinates
hpendata	HPENDATA	Handle to pen data memory block.
Comments

DrawPenData draws the pen data specified by hpendata into the device context specified by hdc. The hdc value may also specify a Windows metafile handle.

The application using DrawPenData is reponsible for either scaling the data points or setting the mapping appropriately if lprect is NULL.

If lprect is not NULL, the points are scaled into lprect as the drawing is done. Internally, a non-destructive use of SetViewportExt/SetViewPortOrg and SetWindowOrg/SetWindowExt will be used to render the pen data in the device context within the bounds of the provided rectangle. You will have to pre-compute the proper pen width (assuming it is other than 1 of course) before calling this function with a non-null lprect to account for the scaling that is going to occur.

DrawPenData draws the ink in the rectangle relative to the upper-left corner of the window. It ignores any changes that have been made to the HDC's origin by previous calls to the Windows functions SetWindowOrg or SetViewportOrg. If the origin has changed, the rectangle passed to DrawPenData must be offset by the appropriate amount.

The PENDATA structure has no graphic attributes  -- such as ink width or color -- associated with it.

If the ink is to be drawn with a width of greater than 1 pixel the currently selected pen must be set to the appropriate width (in client coordinates if a mapping mode is set in the DC) for the proper width to result. For example, if the mapping mode has been set to MM_HIENGLISH, then the pen width will have to be set to a number appropriate for the desired width in HIENGLISH units to preserve the proper scale of the ink. This scaling is only an issue when the ink width is greater than 1.

Because of aliasing effects, DrawPenData may not draw the exact same pixels that were originally inked. If an exact reproduction is required you should use RedisplayPenData.

Return Value

None. If hpendata is NULL, DrawPenData does nothing.

See Also

CreatePenData, DuplicatePenData, RedisplayPenData


DuplicatePenData

Action

Creates a copy of the pen data

Module

RC Manager

Called By

Application

Syntax

C:

HPENDATA  DuplicatePenData(hpendata, gmemFlags)

PASCAL:

function DuplicatePenData(hPenData:THPenData; gmemFlags: Word): THPenData;

Parameter	Type	Description
hpendata	HPENDATA	Data to be duplicated
gmemFlags	UINT	Memory-allocation flag
Comments

The DuplicatePenData function duplicates the data specified by the hpendata parameter by creating a second pen data memory block..

The gmemFlags parameter specifies the flags to be passed to the Windows GlobalAlloc function when memory for the pen data memory block is created. The gmemFlags parameter is connected with GMEM_MOVEABLE by an OR operator when the global heap data is allocated.

Return Value

If successful, this function returns an HPENDATA handle to the duplicate PENDATA structure. Otherwise, it returns NULL. It will return NULL on a failure to allocate memory.

See Also

CreatePenData, DestroyPenData


EmulatePen

Action

Emulates a pen in applications that do not use the standard Windows I-beam cursor in text areas.

Module

RC Manager

Called By

Application

Syntax

C:

void  EmulatePen (fPen)

PASCAL:

procedure EmulatePen(fPen: Bool);

Parameter	Type	Description
fPen	BOOL	Flag to set pen emulation. TRUE turns on pen emulation; FALSE turns it off.
Comments

EmulatePen enables applications that do not use the I-beam to get I-beam functionality over text fields in the application. Call this function with fPen set to TRUE whenever the cursor is over a text window in the application. When the cursor leaves that area, call this function with fPen set to FALSE. If fPen has been set to TRUE and the Pen Palette is currently running, then a tap of the pen will enable the Pen Palette to process the pen input for ther active application. If the Pen Palette is not present, calling EmulatePen has no effect.

Note

EmulatePen might not be supported in future versions of Windows for Pen Computing. This function is intended to aid those developers using Windows software development tools that have not been updated for pen functionality and that do not give the developers access to Windows handles or other Window APIs. Most applications can use ProcessWriting or hedit controls instead.

Return Value

None

See Also

ProcessWriting


EndEnumStrokes

Action

Unlocks the specified memory block

Module

RC Manager

Called By

Application

Syntax

C:

#define EndEnumStrokes (hpendata) GlobalUnlock (hpendata)

PASCAL:

procedure EndEnumStrokes(hPenData: THPenData);

Comments

The EndEnumStrokes macro uses the Windows GlobalUnlock function to unlock the global memory block specified by the hpendata parameter. This macro should be called when the application has completed with the GetPenDataStroke function. The buffer filled by a call to GetPenDataStroke will not be valid after a call to EndEnumStrokes.

Return Value

The function returns NULL if the macro is successful. Once this has been called, any pointers returned by GetPenDataStroke are invalid.

See Also

BeginEnumStrokes, GetPenDataStroke


EndPenCollection

Action

Forces an end to pen collection mode

Module

RC Manager

Called By

Recognizer

Syntax

C:

BOOL  EndPenCollection(recEnd)

PASCAL:

function EndPenCollection(recEnd: TRec): Bool;

Parameter	Type	Description
recEnd	REC	Error code parameter
Comments

The EndPenCollection function is called by a recognizer or the RC Manager. The recognizer calls this function to stop collection. This may occur, for example, if the recognizer runs out of memory.

The error code parameter, recEnd, will be returned by GetPenHwData on some future call. Since data might still be available when this call is made, the caller should continue to call GetPenHwData until the return value indicates that pen mode has ended.

Return Value

EndPenCollection returns TRUE if the call succeeds. The call will fail if the pen is down when the call is made and recEnd is not negative. If the call fails, the pen module remains in the collection mode. This function returns FALSE if it is not currently in collection mode.


EnumSymbols

Action

Enumerates strings from a symbol graph in order of most probable to least probable.

Module

RC Manager

Called By

RC Manager, application

Syntax

C:

UINT  EnumSymbols(lpsyg, wMaxStr, lpEnumFunc, lvData)

PASCAL:

function EnumSymbols(lpsyg: PSYG; wMaxStr: Word; lpEnumFunc: TEnumProc; lvData: Pointer): Word;

Parameter	Type	Description
lpsyg	LPSYG	Pointer to symbol graph
wMaxStr	UINT	Maximum number of strings to enumerate
lpEnumFunc	FARPROC	Pointer to enumeration function
lvData	LPVOID	Application-specific data
Comments

The EnumSymbols function enumerates all strings of symbols -- to a maximum defined by wMaxStr -- that can be generated from the symbol graphlpsyg. The lpEnumFunc parameter is a pointer to the enumeration function called with each enumeration.

To generate all the symbols from a symbol graph, set wMaxStr equal to GetSymbolCount(lpsyg).

EnumFunc

int FAR PASCAL  EnumFunc(lpsyv, csyv, lvData)

Parameter	Type/Description
lpsyv	LPSYV Symbol string
csyv	int Count of symbols in string
lvData	FAR VOID * Pointer passed in from EnumSymbols
EnumFunc is a placeholder for an application-supplied name. This function must be EXPORTed in the module definition file. EnumFunc should return 0 to stop enumeration.

Return Value

EnumSymbols returns the number of strings enumerated.

See Also

FirstSymbolFromGraph, SYG structure


ExecuteGesture

Action

Executes a gesture

Module

RC Manager

Called By

System application (Pen Palette)

Syntax

C:

BOOL  ExecuteGesture(hwnd, syv, lprcresult)

PASCAL:

function ExecuteGesture(hw: HWnd; syv: TSYV; lprcresult: PRCResult): Bool;

Parameter	Type	Description
hwnd	HWND	Window handle
syv	SYV	Gesture to map
lprcresult	LPRCRESULT	Pointer to the RCRESULTS structure
Comments

This function attempts to convert the gesture in syv to a set of keystrokes that the user has mapped using the Gesture Mapper. The hwnd parameter specifies the application that will receive the mapped gesture. If no mapping exists, ExecuteGesture tries to get the default mapping of the gesture. If a mapping is found, one of three things happens:

•	The gesture is sent to the system queue as a set of keystrokes.

•	The mapping is placed in the lpsyv element of the RCRESULTS structure.

•	The mapping is placed in the lpsyv element as another gesture if it maps to some standard key sequences.

In general, ExecuteGesture is called once to get the mapping. If necessary, it is called a second time to send the mapped keystrokes to the application.

If lprcresult is NULL, the result is always sent as keystrokes. If lprcresult is not NULL, the type conversion is indicated by the flags in the wResultsType element of lprcresult. If it is translated to an ANSI string, the RCRT_GESTURETRANSLATED flag is set. If it is translated to another gesture, the RCRT_GESTURETRANSLATED and RCRT_GESTURE flags are set. If neither of these two translations is true, the translation is to a set of virtual key codes, and the RCRT_GESTURETOKEYS and RCRT_ALREADYPROCESSED flags are set.

To send the results of a mapping, call ExecuteGesture with the RCRT_GESTURETOKEYS flag set in the wResultsType field in the RCRESULT structure. The function will send the virtual keys that have been placed in lpsyv as symbol values to the system as keystrokes. Once the keys have been sent, ExecuteGesture resets the flag.

If the result of the mapping is one of the keystrokes listed below, then the keystrokes are replaced by the corresponding symbol gesture.

Keystrokes	Gesture
CTRL + INS	SYV_COPY
SHIFT + INS	SYV_PASTE
ALT + BACKSPACE	SYV_UNDO
SHIFT + DEL	SYV_CUT

When a gesture is mapped to virtual keys and the keys are inserted into the lpsyv element of the lprcresult parameter passed in, each element in the lpsyv array is of the type SYV with the following format:

•	The HIWORD is set to SYVHI_VKEY.

•	If the LOWORD has the most significant bit cleared, the LOBYTE contains the virtual keycode as defined in WINDOWS.H. The HIBYTE has CONTROL, ALT, or SHIFT bits set. For example, 0x00060441 means an SYV for ALT+A, 0x00060270 means CTRL+F1, and 0x0006012D means SHIFT+INS.

•	If the LOWORD has the most significant bit set, the lower three nibbles contain binary coded decimal numbers indicating an ALT+NUMPAD combination. For example, 0x00068199 means an SYV for an ALT+NUMPAD combination that translates to ANSI code 199.

Return Value

This function returns TRUE if the given gesture is mapped to text, keystrokes or another gesture.


FirstSymbolFromGraph

Action

Places into lpsyv the array of symbols that is the likeliest interpretation of the symbol graph

Module

RC Manager

Called By

Application

Syntax

C:

void  FirstSymbolFromGraph(lpsyg, lpsyv, cSyvMax, lpcSyv)

PASCAL:

procedure FirstSymbolFromGraph(lpsyg: PSYG; lpsyv: PSYV; cSyvMax: Integer; lpcSyv: PInteger);

Parameter	Type	Description
lpsyg	LPSYG	Symbol graph.
lpsyv	LPSYV	Array of symbols.
cSyvMax	int	Buffer size.
lpcSyv	LPINT	Number of symbols returned in lpsyv. This value is 0 if lpsyg is empty. It is -1 if the buffer is not large enough to hold the results.
Comments

The array of symbols is identical to the first string returned to the EnumFunc procedure of EnumSymbols.

Return Value

None

See Also

EnumSymbols


GetGlobalRC

Action

Queries the current default settings and fills the RC structure with the global values

Module

RC Manager

Called By

System applications (Control Panel)

Syntax

C:

UINT  GetGlobalRC(lprc, lpDefRecog, lpDefDict, cbDefDictMax)

PASCAL:

function GetGlobalRC(lprc: PRC; lpDefRecog: PChar; lpDefDict: PChar; cbDefDictMax: Integer): Word;

Parameter	Type	Description
lprc	LPRC	Pointer to RC structure.
lpDefRecog	LPSTR	Buffer in which the default recognizer module name is returned. This must be 128 bytes long.
lpDefDict	LPSTR	Buffer in which the default dictionary path is returned. This ends with double zero byte values.
cbDefDictMax	int	Size of lpDefDict buffer to be filled.
Comments

GetGlobalRC fills the RC structure with global values. Values that have no default settings -- for example, the bounding rectangle -- are set to zero.

An application does not need to call this function to use the default values. When an application initializes an RC structure using InitRC, the system default values are set as the values for the structure fields. Any of the parameters lprc, lpDefRecog, or lpDefDict may be NULL to indicate that the caller is not interested in the value.

This function returns the actual current values for RC fields. The InitRC function returns the default values; these include placeholder values for some RC fields.

Return Value

The following table lists the possible return values:

Value	Meaning
GGRC_OK	Successful completion without any errors.
GGRC_PARAMERROR	One or more invalid parameters weredetected. The call to GetGlobalRC has no effect.
GGRC_DICTBUFTOOSMALL	The size of the lpDefDict buffer is not large enough to contain the entire dictionary path. The buffer is filled with as many complete dictionary module names as allowed by the size. The list is terminated by a NULL string.
See Also

InitRC, SetGlobalRC


GetMessageExtraInfo

Action

Gets extra information associated with a mouse message

Module

Windows (USER.EXE)

Called By

RC Manager, application

Syntax

C:

LONG  GetMessageExtraInfo()

Comments

The Windows 3.1 GetMessageExtraInfo function is called in response to a mouse message to retrieve the extra information passed along with the event. The following paragraphs describe pen-specific information.

If the message was generated by a pen driver, the low word of the return value contains the wEventRef value and the high word contains the shift states of the barrel buttons (the PDK_ values). The wEventRef value can be used as the parameter to Recognize or GetPenHwEventData to reference the tablet data.

If the message was not generated by a pen driver, the return value of GetMessageExtraInfo should be zero. However, because this value was undefined in previous versions of Windows, it may not be zero. The IsPenEvent function can test the value to determine if it is a pen event even if the long value is nonzero. All devices and emulators that guarantee compatibility with stylus use will set the long value to zero. For other messages, the value is undefined.

Because of the manner in which Windows coalesces mouse messages, an application is guaranteed to get only the most recent position of the mouse during a move -- and not necessarily all the intervening positions. Although this is more than acceptable for most uses of the mouse, it can cause problems with recognition efforts.

The pen module maintains a circular buffer of the pen events. As each event is received from the pen driver, it is placed in the buffer as well as entered into the system message queue as a mouse message. Along with the mouse message, two other pieces of information are tagged to the message: the state of the pen driver barrel buttons and a reference to the raw pen event (an index into the buffer).


GetPenAsyncState

Action

Gets the barrel button state of the pen

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  GetPenAsyncState(wPDK)

PASCAL:

function GetPenAsyncState(wPDK: Word): Bool;

Parameter	Type	Description
wPDK	UINT	PDK_ value.
Comments

The wPDK parameter is one of the PDK_ values for the barrel buttons. The following table lists the PDK_ values.

Constant	Value	Meaning
PDK_BARREL1	0x0002	Set if barrel button #1 is depressed
PDK_BARREL2	0x0004	Set if barrel button #2 is depressed
PDK_BARREL3	0x0008	Set if barrel button #3 is depressed
Return Value

This function returns TRUE if the given barrel state is down when the call is made.


GetPenDataInfo

Action

Returns the header and pen information from the pen data memory block.

Module

RC Manager

Called By

Application, RC Manager, Recognizer

Syntax

C:

BOOL  GetPenDataInfo(hpendata, lppendataheader, lppeninfo, dwReserved)

PASCAL:

function GetPenDataInfo(hPenData: THPenData; lppendataheader: PPenDataHeader;

  lpPenInfo: PPenInfo; dwReserved: Longint): Bool;

Parameter	Type	Description
hpendata	HPENDATA	Raw pen data
lppendataheader	LPPENDATAHEADER	Buffer for the information contained in the pen data type structure header
lppeninfo	LPPENINFO	Pointer to the PENINFO structure. May be NULL.
dwReserved	DWORD	Reserved for future use.
Comments

Applications can use this routine to get the header and pen information in the pen data memory block. If lppeninfo is non-NULL and the pen data does not contain pen information, the contetnts of lppeninfo are not changed.

The amount of data allocated is contained in lppendataheader ->cbSizeUsed.

Return Value

This function returns TRUE if successful. The returned data is placed in lppendataheader. GetPenDataInfo returns FALSE if invalid parameters were used or it cannot lock HPENDATA.


GetPenDataStroke

Action

Returns a pointer to the data

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  GetPenDataStroke(lppendata, wStroke, lplpPoint, lplpvOem, lpsi)

PASCAL:

function GetPenDataStroke(lppendata: PPenDataHeader; wStroke: Word; lplpPoint: PPoint; lplpvOem: Pointer; lpsi: PStrokeInfo ): Bool;

Parameter	Type	Description
lppendata	LPPENDATA	Pen data to be enumerated. This parameter is the value returned by a previous call to the BeginEnumStrokes function.
wStroke	UINT	Which stroke to get. The number of the stroke is zero-based.
lplpPoint	LPPOINT FAR *	Pointer to the data. You should be careful about modifying the data in your application. This pointer becomes invalid when you call EndEnumStrokes.
lplpvOem	LPVOID FAR *	OEM data block. If lplpvOem is NULL, no OEM data is returned. If it is not NULL, lplpvOem points to the OEM data block. The format of the OEM data is specified by the peninfo field in the PENDATAHEADER structure.
lpsi	LPSTROKEINFO	Contains a pointer to the STROKEINFO structure to be filled.
Comments

The GetPenDataStroke function returns a pointer in lplpPoint to the pen data associated with the stroke at the position specified by wStroke.

The data is an array of POINTS.

You must call BeginEnumStrokes before calling GetPenDataStroke. After the last call to GetPenDataStroke, you must call EndEnumStrokes.

Once EndEnumStrokes is called, the points contained in lplpPoint and lplpvOem are no longer valid.

Return Value

GetPenDataStroke returns TRUE if the call succeeds. If the stroke requested is out of range, it returns FALSE.

See Also

BeginEnumStrokes, EndEnumStrokes


GetPenHwData

Action

Fetches data from the internal pen buffer

Module

RC Manager

Called By

Recognizer

Syntax

C:

REC  GetPenHwData(lpPnt, lpvOemData, cPntMax, wTimeOut, lpsi)

PASCAL:

function GetPenHwData(lpPnt: PPoint; lpvOemData: Pointer; cPntMax: Integer; wTimeOut: Word; lpsi: PStrokeInfo): TRec;

Parameter	Type	Description
lpPnt	LPPOINT	Buffer to fill with pen event data.
lpvOemData	LPVOID	Buffer to fill with OEM-specific data (an array of OEM words). This can be NULL if no data is required.
cPntMax	int	Maximum number of samples to return.
wTimeOut	UINT	GetPenHwData returns REC_TIMEOUT if wTimeOut msecs have elapsed since the last time pen down data was added to the queue.
lpsi	LPSTROKEINFO	Stroke information, including the count of points and point state. Also included is the time stamp of the first point returned in the buffer. It is expressed in milliseconds since the start of collection mode.
Comments

The GetPenHwData function fetches data from the internal pen buffer. It should only be called by the recognizer.

The first call to this function returns the data pointed to by the rc.wEventRef passed to Recognize. Subsequent calls return data immediately following the previously returned data.

GetPenHwData returns (in lpsi) the stroke information. In addition, GetPenHwData returns in lpPnt points which represent either all pen-down or all pen-up points. In other words, on a single call, GetPenHwData will stop filling the buffer when the next point to add is not in the same state as the previous point. Consecutive calls may return points of the same state if there is not enough room in the return buffer or if the data was not yet available.

The lpPnt parameter must be at least sizeof(POINT)*cPntMax and lpvOemData must be NULL or cbOemData*cPntMax in size to avoid overflow. (The cbOemData parameter is defined in the PENINFO structure using the function). If no data is available, lpsi->cPnt == 0 and the return value is REC_OK.

The collection of data ends with a nonzero return value.

Return Value

GetPenHwData returns the following values.

Value	Meaning
REC_OK	The call is successful. The lpPnt parameter contains lpsi.cPnt points of valid data. The lpsi.cPnt parameter may equal zero if no data is currently available.
REC_OVERFLOW	The driver buffer has overflowed, with possible loss of data. The lpPnt data is not valid.
REC_ABORT	Recognition was halted by a call to EndPenCollection with this value. The lpPnt data is not valid.
REC_NOCOLLECTION	Pen collection mode has not been set.
REC_PARAMERROR	An invalid parameter has been passed to GetPenHwData.
REC_TERMBOUND	The call was ended because of a hit test outside the bounding rectangle. The lpPnt parameter is filled with the point causing the stop.
REC_TERMEX	The call was ended because of a hit test inside the exclusion rectangle. The lpPnt parameter is filled with the point causing the stop.
REC_TERMPENUP	The call was ended on pen up. The lpPnt parameter is filled with the pen-up point that ended the recognition.
REC_TERMRANGE	The call was ended because the pen left the proximity range. The lpPnt data is not valid.
REC_TERMTIMEOUT	The call was ended on time out.
REC_TERMOEM	Values >= 512 are reserved for termination reasons specific to the recognizer.
See Also

AddPointsPenData, EndPenCollection, STROKEINFO structure


GetPenHwEventData

Action

Gets the pen data associated with events wEventRefBeg through wEventRefEnd

Module

RC Manager

Called By

Application

Syntax

C:

REC  GetPenHwEventData(wEventRefBeg, wEventRefEnd, lpPnt, lpvOemData, cPntMax, lpsi)

PASCAL:

function GetPenHwEventData(wEventRefBeg: Word; wEventRefEnd: Word;lpPnt: PPoint; lpvOemData: Pointer; cPntMax: Integer; lpsi: PStrokeInfo): TRec;

Parameter	Type	Description
wEventRefBeg	UINT	Beginning pen event.
wEventRefEnd	UINT	Ending pen event.
lpPnt	LPPOINT	Buffer to fill with (x,y) data.
lpvOemData	LPVOID	Buffer to fill with OEM-specific data. This can be NULL if no data is required.
cPntMax	int	Maximum number of samples to return.
lpsi	LPSTROKEINFO	Filled with stroke information including the count of points and point state. Also included is the time stamp of the first point returned in the buffer, recorded in milliseconds since Windows startup.
Comments

This function fetches all data collected from the pen event wEventRefBeg through the pen event wEventRefEnd, excluding the final point. If wEventRefBeg equals wEventRefEnd, GetPenHwEventData fetches the pen event associated with wEventRefBeg.

The values for wEventRefBeg and wEventRefEnd are obtained from a call to GetMessageExtraInfo.

Unlike GetPenHwData, this function can be called directly from an application.

Return Value

The following table lists the values returned by GetPenHwEventData.

Value	Meaning
REC_OK	The buffer was successfully filled.
REC_BUFFERTOOSMALL	The cPntMax buffer is not large enough.
REC_PARAMERROR	An invalid parameter has been passed to GetPenHwEventData
If REC_BUFFERTOOSMALL is returned, no data is returned and the cPnt field of lpsi contains the number of points between wEventRefBeg and wEventRefEnd. If REC_OK is returned, lpcPnt contains the number of valid points placed in lpPnt.

See Also

GetPenHwData, GetMessageExtraInfo.


GetPointsFromPenData

Action

Gets the specified data points

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  GetPointsFromPenData(hpendata, wStroke, wPnt, cPnt, lppoint)

PASCAL:

function GetPointsFromPenData(hPenData: PPenDataHeader; wStroke, wPnt, cPnt: Word;lppoint: PPoint): Bool;

Parameter	Type	Description
hpendata	HPENDATA	Handle to pen data structure
wStroke	UINT	Which stroke to get
wPnt	UINT	Beginning point in wStroke
cPnt	UINT	Number of points to get
lppoint	LPPOINT	Buffer to fill
Comments

The GetPointsFromPenData function copies the points between wPnt and wPnt + cPnt in the stroke specified by wStroke to the buffer lppoint.

If wStroke is greater than the number of strokes in hppendata, GetPointsFromPenData returns the points from the last stroke. If the count of points to return is 1 and wPnt is beyond the last point in the stroke, GetPointsFromPenData returns the last point in the stroke.

Return Value

GetPointsFromPenData returns TRUE if the call succeeds. If you are asking for points that are out of range, it returns FALSE.

See Also

GetPenDataStroke


GetSymbolCount

Action

Returns the number of symbol string enumerations possible in a symbol graph

Module

RC Manager

Called By

Application

Syntax

C:

int  GetSymbolCount(lpsyg)

PASCAL:

function GetSymbolCount(lpsyg: PSYG): Integer;

Parameter	Type	Description
lpsyg	LPSYG	Pointer to symbol graph
Return Value

This function returns the number of possible symbol strings that can be generated from the symbol graph. Returns -1 for any graph that can generate more than 32,767 symbol strings.

For example, if the symbol graph lpsyg is "ex { a | u } mple," a call to GetSymbolCount returns the value 2, because two symbol strings can be generated ("example" and "exumple").

See Also

EnumSymbols, FirstSymbolFromGraph, GetSymbolMaxLength


GetSymbolMaxLength

Action

Gets the length of the longest symbol string

Module

RC Manager

Called By

Application

Syntax

C:

int  GetSymbolMaxLength(lpsyg)

PASCAL:

function GetSymbolMaxLength(lpsyg: PSYG): Integer;

Parameter	Type	Description
lpsyg	LPSYG	Pointer to the symbol graph
Return Value

This function returns the number of symbols in the longest symbol string that can be generated from the symbol graph. For example, if the symbol graph lpsyg  is "ab {c | de } f" a call to GetSymbolMaxLength returns 5 because the longest string is "abdef."

See Also

EnumSymbols, FirstSymbolFromGraph


GetVersionPenWin

Action

Gets the version number of Windows for Pen Computing

Module

RC Manager

Called By

Application

Syntax

C:

UINT  GetVersionPenWin()

PASCAL:

function GetVersionPenWin: Word;

Return Value

The low-order byte of the return value specifies the major (version) number. The high-order byte specifies the minor (revision) number.


InitRC

Action

Fills an RC structure with the default values

Module

RC Manager

Called By

Application

Syntax

C:

void  InitRC(hwnd, lprc)

PASCAL:

procedure InitRC(hw: HWnd; lprc: PRC);

Parameter	Type	Description
hwnd	HWND	Window handle
lprc	LPRC	Pointer to RC structure
Comments

InitRC fills an RC structure with the default values.The resulting RC structure is a valid RC structure that can be passed to Recognize.  Although an application can change any of these values, it should be careful about changing those items that can be set by the user through the Control Panel.

The InitRC sets the bounding rectangle to the client area of hwnd. The bounding rectangle set by InitRC is valid only until the window is resized or moved, when it becomes invalid.Therefore, an application cannot use InitRC once and then use the rectBound field in the resulting RC without modification. If the window handle hwnd is NULL, then the bounding rectangle and rc.hwnd are left unitialized. The rc.hwnd field must be set to a valid window before Recognize or RecognizeData is called.

Values not listed in the following table are set to the value in the global RC structure. Some of the global default values can be modified by the user in the Control Panel.

RC structure field	Value
rc.alc	ALC_DEFAULT. That is, use the complete alphabet and gestures. The exact character set is recognizer-dependent.
rc.lRcOptions	0
rc.hwnd	hwnd (the argument)
rc.wResultMode	RRM_COMPLETE
rc.rectBound	(0,0,0,0); or client rectangle of hwnd if hwnd is not NULL
rc.lPcm	PCM_ADDDEFAULTS
rc.rectExclude	(0,0,0,0)
rc.guide	(0,0,0,0,0,0,0)
rc.wRcOrient	RCOR_NORMAL
rc.wRcDirect	RCD_DEFAULT
Those values that can change through the system Control Panel are filled with values indicating that the system default should be used. These placeholder values are RC_WDEFAULT or RC_LDEFAULT, depending on whether the field is a UINT or LONG value. During the processing of ProcessWriting, Recognize or RecognizeData, these values are replaced with the current system defaults before the RC structure is passed to the recognizer.

If the PCM_ADDDEFAULTS flag is set in rc.lPcm, the values of the lPcm field in the global RC are combined with the current rc.lPcm values with OR operators at the time the recognizer is called.

If the high bit is set in rc.wRcPreferences, the values of the wRcPreferences field in the global RC are combined with the current rc.wRcPreferences values with OR operators at the time the recognizer is called.

RC structure field	Default value
rc.hrec	RC_WDEFAULT
rc.lpfnYield	RC_LDEFAULT
rc.lpUser	RC_LDEFAULT
rc.wCountry	RC_WDEFAULT
rc.wIntlPreferences	RC_WDEFAULTFLAGS
rc.lpLanguage	RC_LDEFAULT
rc.rglpdf	RC_LDEFAULT
rc.wTryDictionary	100
rc.clErrorLevel	RC_WDEFAULT
rc.wTimeOut	RC_WDEFAULT
rc.wRcPreferences	RC_WDEFAULTFLAGS
rc.nInkWidth	RC_WDEFAULT
rc.rgbInk	RC_LDEFAULT
rc.alcPriority	ALC_NOPRIORITY
rc.rgbfAlc	Array initialized to zero
The RC structure pointed to in the RCRESULTS structure is a copy of the original RC structure passed in as a parameter to Recognize. In this copy, the default values are replaced; all coordinates are in tablet coordinates, and the lRcOptions field have the RCO_TABLETCOORD flag set.

Return Value

None

See Also

Recognize, RecognizeData


InitRecognizer

Action

Gives the recognizer a chance to do any initialization before receiving the first request for recognition

Module

Recognizer

Called By

RC Manager

Syntax

C:

BOOL  InitRecognizer(lprc)

PASCAL:

function InitRecognizer(lprc: PRC): Bool;

Parameter	Type	Description
lprc	LPRC	Long pointer to RC structure
Comments

InitRecognizer is called when the recognizer is loaded by a call to InstallRecognizer after the DLL's LibMain but before any other function in the recognizer's DLL. It is called with a copy of the global RC.

Applications should not call this function directly but should call InstallRecognizer instead.

Return Value

Returns FALSE if the load fails. The recognition load can fail if the recognizer requires resources that are not available -- for example, a pressure-sensitive pen. It is the recognizer's responsibility to post any error messages on failure.

See Also

CloseRecognizer, InstallRecognizer, SetGlobalRC


InstallRecognizer

Action

Loads a specified recognizer

Module

RC Manager

Called By

Application

Syntax

C:

HREC  InstallRecognizer(lpszRecogName)

PASCAL:

function InstallRecognizer(lpszRecogName: PChar): THRec;

Parameter	Type	Description
lpszRecogName	LPSTR	Recognizer module name to load. If lpszRecogName is NULL, the default recognizer is loaded. Windows does this automatically on initialization.
Comments

The recognizer's name is the name of the DLL to be loaded. The standard rules for searching for a DLL are used. The procedure fails if the library can't be found, the load fails, or the loaded DLL is not a valid recognizer. The load may also fail if the recognizer requires services that are not provided by the current pen driver (for example, pressure).

After the recognizer is loaded, InitRecognizer is called by the RC Manager. An application should not load the default recognizer. All recognizers installed by an application must be uninstalled by a call to UninstallRecognizer before the application terminates.

If an application loads a recognizer with a call to LoadLibrary instead of InstallRecognizer, only the ConfigRecognizer function in the recognizer can be called.

Return Value

The return value is a handle to a recognizer to be used in the RC structure. InstallRecognizer returns NULL on an error.

See Also

InitRecognizer, UninstallRecognizer


IsPenAware

Action

Checks the capability of an application to handle pen events

Module

RC Manager

Called By

System Application

Syntax

C:

UINT  IsPenAware()

PASCAL:

function IsPenAware: Word;

Comments

This function is called to determine what handwriting events are handled by the application for the current task. The information returned is the registration flags previously set by a call to the RegisterPenApp function.

Return Value

This function returns the registration flags word set by a previous call to the RegisterPenApp function. If RegisterPenApp has not been called previously, IsPenAware returns zero.

See Also

RegisterPenApp


IsPenEvent

Action

Checks to see if a mouse event was generated by the pen driver

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  IsPenEvent(message, lExtraInfo)

PASCAL:

function IsPenEvent(Message: Word; lExtraInfo: Longint): Bool;

Parameter	Type	Description
message	UINT	Windows mouse message being queried
lExtraInfo	LONG	Value returned by GetMessageExtraInfo for the given message.
Note

Mouse drivers that have not been updated to be compatible with pens may produce an event that cannot be distinguished from a real pen event. This has a very low-probability of occurring.

Return Value

This function returns TRUE if the given mouse event was generated by the pen driver. All other messages return FALSE.


MetricScalePenData

Action

Converts pen data points to one of the supported metric modes

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  MetricScalePenData(hpendata, wPdts)

PASCAL:

function MetricScalePenData(hPenData: THPenData; wPdts: Word): Bool;

Parameter	Type	Description
hpendata	HPENDATA	Pen data points to be converted
wPdts	UINT	Scaling metric to be used with the data
Comments

The MetricScalePenData function scales the points in hpendata according to the scaling values given by the wPdts parameter.

The following table lists the wPdts scaling values.

Scaling value	Meaning
PDTS_LOMETRIC	Each logical unit is mapped to 0.1 mm. Positive x is to the right; positive y is down.
PDTS_HIMETRIC	Each logical unit is mapped to 0.01 mm. Positive x is to the right; positive y is down.
PDTS_HIENGLISH	Each logical unit is mapped to 0.001 inch. Positive x is to the right; positive y is down. This is equivalent to PDTS_STANDARDSCALE.
PDTS_DISPLAY	This parameter scales the data, using DPtoTP. The pen data memory block will be left in display coordinates. Strictly speaking this is not a metric scale.
To use the PDTS_DISPLAY scale type, the current scale of the data must be in PDTS_STANDARDSCALE units.  The PDTS_DISPLAY scale also assumes that the desired tablet-to-display ratio is equal to the current ratio for the display and tablet.

The effect of this call is similar to using the TPtoDP function on the array of points. A recognizer may not accurately recognize the resulting data.

As with the other scales, the PDTS_DISPLAY is set in wPndts field of the pendata header. If data is in PDTS_DISPLAY scale, MetricScalePenData cannot be called to scale it back to the other metric scales.

No overflow checks are done. Because of rounding errors, the conversion of scalings is not perfectly reversible.

All recognizers must recognize points that have been scaled to PDTS_STANDARDSCALE (equivalent to PDTS_HIENGLISH).

Return Value

MetricScalePenData returns TRUE if successful; it returns FALSE if hpendata is in a compressed state or if the data is not already in one of the metric modes -- for example, if the data is in PDTS_ARBITRARY mode.

See Also

OffsetPenData, ResizePenData


OffsetPenData

Action

Offsets pen data points by a specified amount

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  OffsetPenData(hpendata, dx, dy)

PASCAL:

function OffsetPenData(hPenData: THPenData; dx, dy: Integer): Bool;

Parameter	Type	Description
hpendata	HPENDATA	Handle to pen data memory block.
dx	int	x-axis offset: amount to move left or right. To move left, the dx value must be negative.
dy	int	y-axis offset; amount to move up or down. To move up, the dy value must be negative.
Comments

For every point in hpendata dx is added to the x-coordinate and dy is added to the y-coordinate. No overflow checks are done.

Return Value

OffsetPenData returns TRUE if successful, FALSE if hpendata is in a compressed state.

See Also

MetricScalePenData, ResizePenData


PostVirtualKeyEvent

Action

Posts a virtual key code event to Windows

Module

RC Manager

Called By

System applications (Pen Palette)

Syntax

C:

void  PostVirtualKeyEvent(vk, fUp)

PASCAL:

procedure PostVirtualKeyEvent(vk: Word; fUp: Bool);

Parameter	Type	Description
vk	UINT	Virtual key
fUp	BOOL	Key transition -- FALSE for down,TRUE for up
Comments

This function does not check the virtual key code for errors.

You can post repeating keys by calling PostVirtualKeyEvent consecutively with fUp FALSE; end this by a single call with fUp set to TRUE.

The events are posted to the system message queue and can be received by the application with the input focus using GetMessage and PeekMessage calls.

Return Value

None

See Also

AtomicVirtualEvent, PostVirtualMouseEvent


PostVirtualMouseEvent

Action

Posts a virtual mouse code event to Windows

Module

RC Manager

Called By

System applications (Pen Palette)

Syntax

C:

void  PostVirtualMouseEvent(wMouseFlag, xPos, yPos)

PASCAL:

procedure PostVirtualMouseEvent(wMouseFlag: Word; xPos, yPos: Integer);

Parameter	Type	Description
wMouseFlag	UINT	Mouse flag
xPos	int	The x position in screen coordinates
yPos	int	The y position in screen coordinates
Comments

The x and y positions are absolute positions in screen coordinates. Note that the x and y values should not exceed the screen resolution limits. Values greater than the maximum resolution in X direction (usually 640) and max resoultion Y direction (usually 480) will overflow.

The wMouseFlag parameter is one of the values in the following table.

Constant	Value
VWM_MOUSEMOVE	0x0001
VWM_MOUSELEFTDOWN	0x0002
VWM_MOUSELEFTUP	0x0004
VWM_MOUSERIGHTDOWN	0x0008
VWM_MOUSERIGHTUP	0x0010
The VWM_MOUSELEFTDOWN and VWM_MOUSELEFTUP constants are set only to mark a transition in state. The VWM_MOUSEMOVE constant is set if the cursor changes positions. A move and button transition can be entered in the same event by connecting the correct flags with OR operators.

The events are posted to the system message queue and can be received by the application with the input focus using GetMessage and PeekMessage calls.

Because of the way Windows interprets mouse messages, the caller must be careful about the order in which events are sent to the system. A message that represents both a button state transition and a move will generate first a Windows event for the button transition at the current cursor location and then a move to the new location. If the expected result is a move to a new location and then a button transition, this requires two separate calls to PostVirtualMouseEvent.

When posting events, the caller should bracket the calls by calls to AtomicVirtualEvent, which is used to lock out pen packets while the application is posting simulated mouse events. For example, the following code fragment posts a mouse event:

AtomicVirtualEvent( TRUE );

/*  PostVirtualMouseEvent calls go here */

AtomicVirtualEvent( FALSE );

GetMessageExtraInfo will return 0 for any messages generated with this function.

Return Value

None

See Also

AtomicVirtualEvent, GetMessageExtraInfo, PostVirtualKeyEvent


ProcessPenEvent

Action

Tells the pen module to process any pending pen events

Module

RC Manager

Called By

Pen driver

Syntax

C:

call  dword ptr lpfnProcessPenEvent

Comments

The ProcessPenEvent function tells the pen module to process any queued pen events that have been added with the AddPenEvent function.  This function is reentrant, and can be called with all interrupts (including tablet interrupts) enabled.

Processing a pen packet may involve graphics operations, copying large amounts of memory, calling numerous Windows APIs, and other time-consuming operations. Therefore, it is recommended that a pen driver enable the tablet interrupts before the call to ProcessPenEvent.

A pen driver should construct a pen packet with tablet interrupts disabled, call AddPenEvent, re-enable tablet interrupts, and then call ProcessPenEvent.

Return Value

None

See Also

AddPenEvent


ProcessWriting

Action

Processes handwriting

Module

RC Manager

Called By

Application

Syntax

C:

REC  ProcessWriting(hwnd, lprc)

PASCAL:

function ProcessWriting(hw: HWnd; lprc: PRC): TRec;

Parameter	Type	Description
hwnd	HWND	Window to receive messages. This parameter must not be NULL.
lprc	LPRC	Pointer to RC structure to use for recognition. This parameter can be NULL.
Comments

The ProcessWriting function is provided to simplify the task of converting an existing application to take advantage of handwriting input -- both gestures and characters. This function is similar to Recognize except that, in addition, ProcessWriting takes care of inking, removing the ink, and converting the results message to standard Windows messages.

Depending on the existing code in an application, ProcessWriting may not be suitable for making an application pen-aware. This function can also limit the power of a pen interface. In addition, the ProcessWriting function exacts a rather large performance and memory penalty when dealing with large or full-screen writing areas.

The hwnd parameter is the window to receive messages. It cannot be NULL. The lprc parameter is the RC structure to use for recognition. If the lprc parameter is an RC, the results mode field is ignored and the recognition terminates on RRM_COMPLETE.

If lprc is NULL, a default RC structure is created for the application. The default RC structure contains all the system defaults. In addition, the inking is constrained to the client area of hwnd. Otherwise, lprc>rectBound is used to constrain the inking.

The ProcessWriting function is normally called on the mouse-click message WM_LBUTTONDOWN or at other times with a non-NULL lprc that contains a valid wEventRef.

On a call to Recognize or ProcessWriting, during a WM_LBUTTONDOWN message, the application does not receive the corresponding pen up message.

After the writing is completed, the ink is removed before any messages are sent to hwnd. After the ink is removed, the screen is updated, hwnd receives a WM_RCRESULT message. If the application processes this message, it should return a nonzero value. If the application returns 0 (DefWindowProc will return 0 for this message), ProcessWriting performs the default conversion of the results message to standard Windows messages.

By default, when an application receives a WM_RCRESULT as a result of a ProcessWriting call, the lprcresult->hpendata value is NULL. If you want to have the hpendata returned, set the RCO_SAVEHPENDATA flag in the rc.lRcOptions field. If this is done, the caller must free hpendata.

If an application returns FALSE to the WM_RCRESULT message, the application receives the Windows messages shown below. The messages are sent rather than posted. If the application returns TRUE to the WM_RCRESULT message, no further messages are sent.

Result	Messages to hwnd
SYV_BACKSPACE	WM_LBUTTONDOWN followed by WM_LBUTTONUP at the hotspot of the gesture followed by WM_CHAR of backspace.
SYV_CLEAR	WM_CLEAR
SYV_CLEARWORD	WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, WM_LBUTTONUP at the same point followed by WM_CLEAR
SYV_COPY	WM_COPY
SYV_CORRECT	WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, WM_LBUTTONUP at the hotspot of the gesture followed by WM_COPY; then the Edit Text dialog is activated and it pulls text from the Clipboard. This uses existing selection if any is present. The previous contents of the Clipboard are lost.
SYV_CUT	WM_CUT
SYV_EXTENDSELECT	WM_LBUTTONDOWN followed by WM_LBUTTONUP at the hotspot of the gesture. The MK_SHIFT flag is set for the wParam of these messages.
SYV_PASTE	WM_LBUTTONDOWN followed by WM_LBUTTONUP at the hotspot of the gesture. WM_PASTE.
SYV_RETURN	WM_LBUTTONDOWN followed by WM_LBUTTONUP at the hotspot of the gesture followed by WM_CHAR of RETURN.
SYV_SPACE	WM_LBUTTONDOWN followed by WM_LBUTTONUP at the hotspot of the gesture followed by WM_CHAR of SPACE.
SYV_TAB	WM_LBUTTONDOWN followed by WM_LBUTTONUP at the hotspot of the gesture followed by WM_CHAR of TAB.
SYV_UNDO	WM_UNDO
text	One WM_CHAR message per character of text.
all other results	No messages.
Return Value

The ProcessWriting function returns values less than 0 if the application should treat the event as a mouse event instead of a pen event. Return values less than zero will occur if the event did not come from a pen or the user did a press-and-hold action (REC_POINTEREVENT), or an error such as out of memory occurred.

See Also

InitRC, Recognize, RC structure, RCRESULT structure


Recognize

Action

Begins sampling pen data and converts tablet input to recognized symbols

Module

RC Manager

Called By

Application

Syntax

C:

REC  Recognize(lprc)

PASCAL:

function Recognize(lprc: PRC): TRec;

Parameter	Type	Description
lprc	LPRC	Recognition parameters
Comments

This is the primary recognition function. An application calls Recognize to begin recognition on some pen event identified by lprc ->wEventRef. The lprc parameter contains the parameters that control the recognition. Results are sent through the WM_RCRESULT message to the window indicated in lprc. All results messages are sent before this function returns. Multiple result messages may be sent if the application asks for results to be sent to the application before all input has been completed (as indicated by rc.wResultMode).

Recognize should be called in response to a WM_LBUTTONDOWN message.

On a call to Recognize or ProcessWriting, the application will not receive the corresponding pen up message.

Return Value

The following table lists the possible return values. Any of the return values from GetPenHwData may also be returned by this function.

The value REC_OK is used in the wParam of the WM_RCRESULT message to indicate more data is coming. Return values greater than zero signal normal successful completion. Return values less than 0 indicate abnormal termination. Return values less than REC_DEBUG are reserved for return values from debugging versions of the system or recognizer. If an application creates a condition that would be caught in a debugging version while running a nondebugging version, the results are undefined.

Each of the values listed below can be the wParam value of the WM_RCRESULT message or the return value for Recognize. The wParam value of the last WM_RCRESULT message generated by a call to Recognize will be the return value of Recognize. Some error conditions such as REC_OOM or REC_NOTABLET will be returned without any WM_RCRESULT message generated.

Value	Meaning
REC_OK	This result message to be followed by other results before Recognize terminates. This is a valid wParam value for WM_RCRESULT but it can never be the return value for Recognize.
REC_ABORT	Recognition stopped by a call to EndPenCollection with this value. The lpPnt data is not valid.
REC_BADHPENDATA	Returned if hpendata in lprc cannot be locked or has an invalid header. This value is also returned if hpendata has no data in it or if the data is in an incorrect scale or compressed.
REC_BUFFERTOOSMALL	Returned by GetPenHwEventData.
REC_BUSY	Returned if another task is currently performing recognition.
REC_DONE	Returned by RecognizeData upon normal completion.
REC_NOINPUT	Returned by RecognizeData if the buffer contains no data or returned by Recognize if recognition ended before any data was collected. For example, a pen down occurred outside the bounding rectangle before any data was collected.
REC_NOTABLET	Tablet not physically present.
REC_OOM	Out-of-memory error.
REC_OVERFLOW	Data overflow during execution of the call.
REC_POINTEREVENT	Returned if the user makes contact with the tablet surface and lifts the pen before the pen tip travels a short distance. This value is also returned if the user does a press-and-hold action. That is, the pen makes contact with the tablet and holds the position for a short period of time. This return value indicates that the application should begin selection actions rather than inking or recognition. If this is returned no WM_RCRESULT message is generated and no ink will be displayed.
REC_TERMBOUND	Terminated because of a hit test outside the bounding rectangle. The rcresult.pntEnd field is filled with the point causing the stop.
REC_TERMEX	Terminated because of a hit test inside the exclusion rectangle. The rcresult.pntEnd field is filled with the point causing the stop.
REC_TERMOEM	Values >= reserved for recognizer-specific termination reasons.
REC_TERMPENUP	Terminated on pen up. The rcresult.pntEnd field is filled with the pen up point that terminated recognition.
REC_TERMRANGE	Terminated because the pen left the proximity range.
REC_TERMTIMEOUT	Terminated on time-out. (The pen was up continuously for a given amount of time.)
Debugging Values

All of the values listed in the following table are in the debug version only. No WM_RCRESULT message was generated if these values were returned by Recognize.

Value	Meaning
REC_DEBUG	All debugging return values are less than this.
REC_ALC	Invalid enabled alphabet.
REC_BADEVENTREF	Returned when the wEventRef field in the lprc structure is invalid.
REC_CLVERIFY	Invalid verification level.
REC_DICT	Invalid dictionary parameters.
REC_ERRORLEVEL	Invalid error level.
REC_GUIDE	Invalid GUIDE structure.
REC_HREC	Invalid recognition handle.
REC_HWND	Invalid handle to window to send results to.
REC_INVALIDREF	Invalid data reference parameter.
REC_LANGUAGE	This value is returned by the recognizer when the lpLanguage field contains a language which is not supported by the recognizer. Call ConfigRecognizer withWCR_QUERYLANGUAGE sub-function to determine whether a particular language is supported.
REC_NOCOLLECTION	Returned by GetPenHwData if collection mode has not been set.
REC_OEM	Error values below this (below -1024) are specific to the recognizer.
REC_PCM	Invalid lPcm parameter. There is no way for the recognition to end.
REC_RECTBOUND	Invalid rectangle.
REC_RECTEXCLUDE	Invalid rectangle.
REC_RESULTSMODE	Unsupported results mode requested.
See Also

InitRC, RecognizeData, RC structure


RecognizeData

Action

Converts the data in hpendata to recognized symbols

Module

RC Manager

Called By

Application

Syntax

C:

REC  RecognizeData(lprc, hpendata)

PASCAL:

function RecognizeData(lprc: PRC; hPenData: THPenData): TRec;

Parameter	Type	Description
lprc	LPRC	Pointer to RC structure
hpendata	HPENDATA	Buffer containing pen data memory
Comments

This function recognizes data in hpendata and returns the results to lprc->hwnd. It is similar to Recognize; the difference is that the input data comes from the parameter instead of the tablet driver.

Parameters regarding the end of recognition in the RC structure are ignored.

RecognizeData can return REC_BUSY if the recognizer is not reentrant.

A recognizer is not guaranteed to return the same results for identical input. This is because persistent states, such as current average size of writing or the position of the baseline, can affect recognition results. In addition, training may change the prototypes against which the data is being compared.

RecognizeData attempts to convert hpendata to PDTS_STANDARDSCALE if it is not already in standard scale. If the conversion fails -- for example, because the data was in an application-specific scale PDTS_ARBITRARY -- the data is still passed on to the recognizer. A recognizer may return an error code (REC_BADHPENDATA) on data in a scale it cannot handle or attempt to recognize.

Return Value

RecognizeData returns REC_DONE on completion, or an error code if an error occurs. The error codes are identical to those for Recognize. REC_BADHPENDATA is also returned on compressed HPENDATA.

See Also

InitRC, Recognize


RecognizeDataInternal

Action

At the DLL recognition level, converts hpendata to recognized symbols

Module

Recognizer

Called By

RC Manager

Syntax

C:

REC  RecognizeDataInternal(lprc, hpendata, lpFuncResults)

PASCAL:

function RecognizeDataInternal(lprc: PRC; hPenData: THPenData; lpfuncresults: TFuncResults): TRec;

Parameter	Type	Description
lprc	LPRC	Recognition parameters
hpendata	HPENDATA	Pen data structure
lpFuncResults	FARPROC	Pointer to function
Comments

This function is similar to RecognizeInternal; the diffference is that data for recognition is provided as a parameter instead of being read from the pen driver. This function is called by an application's call to RecognizeData.

Return Value

Same as Recognize.

See Also

Recognize, RecognizeInternal


RecognizeInternal

Action

Begins sampling pen data and converts tablet input to recognized symbols

Module

Recognizer

Called By

RC Manager

Syntax

C:

REC RecognizeInternal(lprc, lpFuncResults)

PASCAL:

function RecognizeInternal(lprc: PRC; lpfuncresults: TFuncResults): TRec;

Parameter	Type	Description
lprc	LPRC	Recognition parameters
lpFuncResults	FARPROC	Pointer to function
Comments

This function is called in the DLL when an application calls Recognize.The RecognizeInternal function is in the recognizer and cannot be called directly by an application.

RecognizeInternal calls (*lpFuncResults)() with a result in an RCRESULT structure. The rules governing which results to send from the recognizer to the RC Manager and when to send them are the same as the rules that govern the sending of results from the RC Manager to the application.This procedure does not return until (*lpFuncResults)() has been called for the last time.

If lprcresult->hSyv is NULL, the RC Manager assumes that the recognizer has already performed dictionary processing; otherwise, the RC Manager takes the responsibility. The recognizer should set the field lprcresult->hSyv to NULL every time to indicate that it has peformed dictionary processing. The RC Manager is responsible for freeing hSyv. It changes lprcresult so that a recognizer will reset all fields on each call to lpFuncResults to the appropriate values. The RC Manager modifies the wResultType, cSyv, and hSyv fields.

lpFuncResults

int (* lpfnFuncResults)(lprcresult, wParam)

Parameter	Type	Description
lprcresult	LPRCRESULT	Pointer to the RCRESULTS structure.
wParam	UINT	The wParam parameter has the same meaning as wParam in the WM_RCRESULT message.
The following table lists the return values for lpFuncResults.

Return value	Meaning
0	Continues default processing.
1	Message processed; further processing on this message stopped (for ProcessWriting).
REC_ABORT	Aborts recognition. If RRM is set for multiple messages per recognizer call, this stops further recognition attempts. It is not applicable to ProcessWriting.
<0	Aborts recognition and returns the value from Recognize.
Return Value

Same as Recognize

See Also

RecognizeDataInternal


RedisplayPenData

Action

Redraws the pen data in the same manner as originally inked

Module

RC Manager

Called By

RC Manager, application

Syntax

C:

BOOL   RedisplayPenData(hDC, hpendata, lpDelta lpExt, nInkWidth, rgbColor)

PASCAL:

function RedisplayPenData(DC:HDC; hPenData: THPenData; lpDelta: PPoint; lpExt: PPoint; nInkWidth: Integer; rgbColor: Longint): Bool;

Parameter	Type	Description
hDC	HDC	Handle to the device context in which to draw the ink. (Mapping mode assumed to be MM_TEXT)
hpendata	HPENDATA	Handle to the pen data memory block to be displayed. The pen data must be scaled to either PDTS_STANDARDSCALE or PDTS_DISPLAY.
lpDelta	LPPOINT	An offset in logical units which is subtracted from the pen data points to position the ink.  If lpDelta is NULL, there is no offset.
lpExt	LPPOINT	Extents in logical units for scaling. If lpExt is NULL, no scaling is performed.
nInkWidth	int	Width of the ink to be drawn (1-15). If nInkWidth is -1, the ink width specified in the nInkWidth field in hpendata is used for drawing.
rgbColor	DWORD	RGB value of the color to draw the ink. If rgbColor is 0xFFFFFFFF, the ink color specified in the rgbInk field in hpendata is used for drawing.
Comments

RedisplayPenData displays the data specified by hpendata in the device context specified by the hDC parameter with a width specified by nInkWidth and of color rgbColor. The nInkWidth and rgbColor values override the pen currently selected for the hDC.

If the mapping mode of hDC is not MM_TEXT, two problems can occur:

•	RedisplayPenData uses TPtoDP to prepare the pen data points for rendering. After this, the points are in MM_TEXT coordinates which assumes an MM_TEXT device conext for display. If the device context is in some other mapping modethe ink coordinates will not be correct. Even if you use the ink scaling functions to bypass this problem, you would still encounter rounding error problems between the two scalings.

•	No matter what pre-scaling is done, you will have rounding errors when converting between modes. The ink will still shift slightly when repainted.

For any rendering into an hDC that represents anyting other than a display hDC, DrawPenData should be used.This is because RedisplayPenData makes assumptions that are not optimal for other devices such as printers or metafiles. RedisplayPenData provides the ability to perfectly recreate original inking.

To perfectly recreate inking, an application must follow one of two procedures:

•	On receipt of a WM_RCRESULT message, convert the hpendata to display coordinates using MetricScalePenData, offset the pen data by the display coordinates of the window containing the ink. To display, call RedisplayPenData with lpDelta and lpExt set to NULL and the mapping mode of the hDC set to MM_TEXT.

•	On receipt of a WM_RCRESULT message, the application must remember the display coordinate of the upper-left hand corner of the client area of the window that contains the ink. To display, call RedisplayPenData with lpDelta set to this saved coordinate and lpExt set to NULL and the mapping mode of the hDC set to MM_TEXT.

The lpDelta parameter contains offsets in the current mapping mode of the device context hDC that should be subtraced from all ink coordinates before they are rendered.

Since the pen data has the origin of (0,0) based on the display upper-left corner, you need to move from a screen relative position to a decice context relative position. Subtract the origin of the device context in screen coordinates from the object currently residing in screen coordinate space.

The lpDelta argument allows the application to render ink in a window relative manner instead of a screen relative manner.  An application should call the Windows function ClientToScreen() for (0,0) to find the proper screen coordinates to be placed in the *lpOrg POINT structure.  Once this is done, the pen data will be rendered at the appropriate location in window coordinates.  If lpDelta is NULL then no offset for the data is assumed.

The lpExt argument specifies the extents into which the data should be scaled.  If extents are provided data will be scaled into a rectangle described by lpDelta and lpExt.  The values of x and y in lpExt and lpDelta are in the mapping mode of the device context to which the data will be rendered.

Return Value

The RedisplayPenData function returns TRUE if succesful, FALSE if it fails because of invalid parameters.

See Also

DrawPenData


RegisterPenApp

Action

Used by pen-enhanced applications to notify the RC Manager that the application edit controls are replaced with hedit controls

Module

RC Manager

Called By

Application

Syntax

void  RegisterPenApp(wFlags, fRegister)

procedure RegisterPenApp(wFlags: Word; fRegister: Bool);

Parameter	Type	Description
wFlags	UINT	Registration flags for recognizer to determine whether or not application is pen-enhanced.
fRegister	BOOL	Sets TRUE to register pen-enhanced application. To unregister the application, this value is set to FALSE.
Comments

The RegisterPenApp function makes it possible to replace all edit controls in an application with hedits.  This simplifies the task of making an application pen aware and making that same application run under both Windows for Pen Computing and regular Windows.

The only registration flag currently supported is RPA_DEFAULT. Other values are reserved for future use. The RC Manager will use the IsPenAware function to determine the flags set.

The application should call RegisterPenApp before any edit controls or combo dropdown controls are created. The function should also be called with fRegister set to FALSE before the application ends.

Return Value

None

See Also

IsPenAware


ResizePenData

Action

Resizes pen data

Module

Recognizer

Called By

Application

Syntax

C:

BOOL  ResizePenData(hpendata, lprect)

PASCAL:

function ResizePenData(hPenData: THPenData;  lprect: PRect): Bool;

Parameter	Type	Description
hpendata	HPENDATA	Handle to pen data memory block
lprect	LPRECT	Bounding rectangle
Comments

This function is used to change the physical size of the object without changing the meaning of the measurements. Use the MetricScalePenData function to convert the data to one of the supported metric modes of measurement.

ResizePenData physically resizes the data in hpendata to the bounding rectangle dimensions given by the lprect parameter. Data from hpendata is mapped to the new rectangle. If lprect is NULL, this function just recalculates the bounding rectangle (the rectBound element in the PENDATAHEADER structure).

For example, assume that the current object is a square and is at location (1500, 1600) with PDTS_HIMETRIC scaling, and you need to double the size. To accomplish this, set the lprect should be set to (500, 600, 2500, 2600).

Return Value

ResizePenData returns TRUE if successful.

See Also

OffsetPenData, MetricScalePenData


SetGlobalRC

Action

Sets the current default settings for the RC structure

Module

RC Manager

Called By

System applications (Pen Palette, Control Panel, and others)

Syntax

C:

UINT  SetGlobalRC(lprc, lpDefRecog, lpDefDict)

PASCAL:

function SetGlobalRC(lprc: PRC; lpDefRecog: PChar; lpDefDict: PChar): Word;

Parameter	Type	Description
lprc	LPRC	Pointer to RC structure.
lpDefRecog	LPSTR	Default recognizer module name (maximum 128 bytes).
lpDefDict	LPSTR	Default dictionary path. The list should end with double zero bytes.
Comment

Because the default RC values are shared among all applications on the system, they should be changed only through the Control Panel. Whenever a change is made to the global RC values, the WM_GLOBALRCCHANGE message is sent to all top-level windows. The wParam and lParam values are not used; they are set to zero.

Any of the parameters may be NULL to indicate that the caller does not want the value changed.

The standard rules for searching a DLL are used for the recognizer and each one of the dictionaries.

SetGlobalRC uses only certain fields of the RC structure passed in through the lprc parameter. These are:

• wRcPreferences	• lpUser
• wCountry	• wIntlPreferences
• lpLanguage	• wTryDictionary
• clErrorLevel	• wTimeOut
• wRcDirect	• nInkWidth
• rgbInk	• the PCM_TIMEOUT and PCM_RANGE bits of lPcm

When InitRecognizer is called for a new recognizer from within the SetGlobalRC call, the RC structure that is passed in contains the new values for all fields except hrec and rglpdf; no new recognizer and dictionaries have been set up at this point.

When an application receives a WM_GLOBALRCCHANGE message, it should call ConfigRecognizer with a WCR_RCCHANGE subfunction request. This should be done for all recognizers that the application has loaded. This does not include the default recognizer. The RC Manager will call the ConfigRecognizer function in the new default recognizer with a WCR_RCCHANGE subfunction request.

In a similar way, an application should also call DictionaryProc with a DIRQ_RCCHANGE subfunction request for any dictionaries it has loaded. This does not include dictionaries on the default path.  The RC Manager will call the DictionaryProc function in the new default dictionaries with a DIRQ_RCCHANGE subfunction request.

SetGlobalRC does not save the RCP_MAPCHAR flag in the wRcPreferences field of the RC structure to the PENWIN.INI file. The RCP_MAPCHAR flag is reflected in the global RC for the current session only.

Return Value

SetGlobalRC returns the value SGRC_OK if successful. If an error occurs, the return values consists of one or more of the other SGRC_ flags  combined with the bitwise OR operation.

The following table lists the SGRC_ values.

Value	Meaning
SGRC_OK	There are no errors. No other flags are set.
SGRC_USER	An invalid user name was found in the supplied RC structure lprc. The call to SetGlobalRC has no effect.
SGRC_PARAMERROR	One or more invalid parameters were detected. The call to SetGlobalRC has no effect.
SGRC_RC	The supplied recognition context lprc has entries, other than the user name, that containing invalid settings for a global recognition context. The supplied recognition context is ignored.
SGRC_RECOGNIZER	The supplied recognizer module name, DefRecog,is invalid or the recognizer could not be loaded. The supplied recognizer module name is ignored.
SGRC_DICTIONARY	The supplied dictionary path, lpDefDict, s invalid or some dictionaries on the path could not be loaded. The supplied dictionary path is ignored.
SGRC_INIFILE	An error was encountered while saving the new global recognition context settings to initialization file PENWIN.INI. The new settings will be lost after rebooting Windows.
See Also

GetGlobalRC


SetPenHook

Action

Installs and removes a pen packet hook

Module

RC Manager

Called By

System applications (Pen Palette)

Syntax

C:

BOOL  SetPenHook(hkpOp, lpfn)

PASCAL:

function SetPenHook(hkpOp: THKP; lptn: TRawHook): Bool;

Parameter	Type	Description
hkpOp	HKP	Operation to be performed
lpfn	LPFNRAWHOOK	Function to handle pen packets
Comments

This function is called by any routine that needs to examine, modify, or cancel pen packets as they arrive.

The operation parameter, hkpOp, determines whether the hook is set or removed. The following table lists the HKP_ values.

Value	Meaning
HKP_SETHOOK	Installs a hook
HKP_UNHOOK	Removes function from hook list
Return Value

The function returns FALSE if it is unable to set or remove the hook.

PenHookCallBack is a callback function that examines, modifies, or cancels a pen packet. Each callback is run at interrupt time on every pen packet.

PenHookCallBack

BOOL lpfn PenHookCallBack(lppp)

Parameter	Type	Description
lppp	LPPENPACKET	Pointer to the pen packet that is being processed
Return Value

The callback function returns FALSE to cancel the processing of this pen packet.

See Also

SetRecogHook


SetRecogHook

Action

Installs and removes recognition hook

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  SetRecogHook(whrHook, hkpPosition, hwndHook)

PASCAL:

function SetRecogHook(whrHook: Word; hkpPosition: Word; HWndHook: HWnd): Bool;

Parameter	Type	Description
whrHook	UINT	Hook parameter
hkpOp	UINT	Operation to be performed
hwndHook	HWND	Handle to a window
Comments

This function enables an application to examine the results of recognition before they are sent to the target application.

The operation parameter, hkpOp, determines whether the hook is set or removed. The following table lists the HKP_ values.

Value	Meaning
HKP_SETHOOK	Installs a hook
HKP_UNHOOK	Removes function from hook list
The hook parameter, whrHook, determines the scope of the hook. The following table lists the HWR_ values.

Value	Meaning
HWR_RESULTS	The hook window receives a WM_HOOKRCRESULT message before a WM_RCRESULT message is sent to the target window.
HWR_APPWIDE	The hook window receives a WM_HOOKRCRESULT message before a WM_RCRESULT message is sent to the target window if the target window belongs to the same task as the window that set an HWR_APPWIDE hook. This is useful for implementing application-wide gestures. The HForm sample application demonstrates a typical use of this feature. The RCRT_ALREADYPROCESSED flag is set in the wResultsType field of the results structure sent with WM_RCRESULT if an application-wide hook has already processed the data.

The hook message is: WM_HOOKRCRESULT. The wParam and lParam parameters are the same as for the WM_RCRESULT message.

If the windows procedure that receives the the WM_HOOKRESULT message returns FALSE, the WM_HOOKRESULT message will not be sent to any of the remaining hooks in the chain.

Note

No drawing should occur during the processing of the WM_HOOKRESULT and before recognition is complete. Drawing at these times could cause timing problems, with ink reappearing in formerly invisible controls as they are redrawn.

Return Value

The function returns FALSE if it is unable to set or remove the hook.

See Also

SetPenHook


ShowKeyboard

Action

Displays or hides the on-screen keyboard

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  ShowKeyboard(hwnd, wCommand, lpPnt, lpSKBInfo)

PASCAL:

function ShowKeyboard(Handle: HWnd; wCommand: Word; lpPnt: PPoint; lpSKBInfo: PSKBInfo): Bool;

Parameter	Type	Description
hwnd	HWND	Handle to window invoking the on-screen keyboard.
wCommand	UINT	Command request.
lpPnt	LPPOINT	Pointer to initial keyboard position in screen coordinates or NULL.
lpSKBInfo	LPSKBINFO	Pointer to SKBINFO structure to be filled with values for current keyboard. This parameter is ignored if NULL. If lpSKBInfo->hwnd is NULL, no on-screen keyboard has been loaded yet.
Comments

The function displays or hides the on-screen keyboard. The wCommand argument specifies the action to be taken.

Command Request	Meaning
SKB_HIDE	Hides the on-screen keyboard. This request may not actually hide the keyboard if another application is also using it. The command decrements the use count for the keyboard. SKB_HIDE automatically loads the on-screen keyboard if it is not already present.
SKB_QUERY	Returns the current state of the keyboard in lpSKBInfo without invoking a new keyboard state. This command does not automatically load the on-screen keyboard.
SKB_SHOW	Shows the on-screen keyboard in a restored state at the most recently used screen location. This command increments a window-use count similar to that used by WinHelp. SKB_SHOW automatically loads the on-screen keyboard if it is not present.
The SKB_SHOW command can be connected by an OR operator with any of the command or keypad requests listed in the two tables below.

Command request used  with SKB_SHOW	Meaning
SKB_CENTER	Centers the keyboard on the display. This command has higher priority than SKB_MOVE.
SKB_MINIMIZE	Displays the on-screen keyboard in a minimized state. This command may be used with SKB_CENTER or SKB_MOVE. If it is used with SKB_MOVE, the location specified will be used when the keyboard is restored.
SKB_MOVE	Moves the keyboard to the location specified by lpPnt. If lpPnt is NULL, the keyboard will be centered instead. If it is not NULL, lpPnt specifies a pointer to the x and y screen coordinates of the upper-left corner of the restored keyboard.
Keypad request used  with SKB_SHOW	Meaning
SKB_BASIC	Switches keyboard to partial keyboard with no extended keys.
SKB_FULL	Switches keyboard to full 101-key display.
SKB_NUMPAD	Switches keyboard to partial keyboard of ESC, TAB, SHIFT, and numeric pad only.
Only one of SKB_BASIC, SKB_FULL or SKB_NUMPAD can be used at any one time.

If lpSKBInfo is specified for SKB_SHOW or SKB_HIDE, the structure returned contains values that were active before any action requested by the current command.

Any user action on the keyboard itself overrides the function requests. That is, if the user closes the on-screen keyboard, all registered applications become unregistered. If the user minimizes the keyboard, the active SKBInfo structure is changed to reflect the new state.

Registration information for 20 window handles is tracked by the function. If one application displays the keyboard and then another one does, both applications must request that the keyboard be hidden before it actually goes away.

Whenever the keyboard display changes (for example, position, visibility, keypad visibility, restored or minimized changes), a WM_SKB message is posted to all top-level windows on the desktop. The wParam value is SKN_CHANGED and the HIWORD of lParam is a combination of one or more of the following: SKN_POSCHANGED, SKN_VISCHANGED, SKN_PADCHANGED, SKN_MINCHANGED, SKN_TERMINATED. The LOWORD value is the window handle of the keyboard.

Button Bitmaps

The following three bitmaps are provided for owner-drawn pushbuttons that can be used to invoke the on-screen keyboard. The application will handle WM_DRAWITEM and other button-related code. On-screen keyboard pushbuttons should behave like other standard buttons (for example, the Minimize button) and invoke their action on button up.

#define OBM_SKBBTNUP  	32767

#define OBM_SKBBTNDOWN	32766

#define OBM_SKBBTNDISABLED	32765

The up bitmap, for example, can be loaded as follows:

HANDLE hDLL = GetSystemMetrics(SM_PENWINDOWS);

HBITMAP hBitmap = LoadBitmap(hDLL,

MAKEINTRESOURCE(OBM_SKBBTNUP));

The application must call the DeleteObject function to delete each bitmap handle returned by the LoadBitmap function.

The button should be left in the up state after it is released; that way, if the user closes the keyboard, the button will be up the next time the keyboard is opened.

The following code segment can be used to get the current keyboard and restore the current state:

#include <penwin.h>

{

if (ShowKeyboard(hwnd, SKB_SHOW, NULL, NULL))  // nonzero: no error

{

// do some actions

ShowKeyboard(hwnd, SKB_HIDE, NULL, NULL);

}

else

UserErrMsg("Unable to use Screen Keyboard");

}

The following code segment can be used to move the keyboard and then put it back:

{

SKBINFO skbinfo;

WORD wCommand = SKB_SHOW | SKB_MOVE;

POINT pnt;

pnt.x = wSKBLeft;    // init

pnt.y = wSKBTop;

// Show the keyboard

ShowKeyboard(hwnd, wCommand, &pnt, &skbinfo);

.

.	// Other code

.

// Now restore the keyboard

if (skbinfo.fVisible)

wCommand = SKB_SHOW | SKB_MOVE | (skbinfo.fMinimized?

SKB_MINIMIZED: 0);

else

wCommand = SKB_HIDE;

ShowKeyboard(hwnd, wCommand, (LPPOINT)(&skbinfo.rect), NULL);

}

Return Value

ShowKeyboard returns TRUE if successful. Otherwise, it returns FALSE.


SymbolToCharacter

Action

Converts an array of SYVs to an ANSI string

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  SymbolToCharacter(lpsyv, cSyv, lpstr, lpnConv)

PASCAL:

function SymbolToCharacter(lpsyv: PSYV; cSyv: Integer; lpstr: PStr; lpnConv: PInteger): Bool;

Parameter	Type	Description
lpsyv	LPSYV	Array of symbols.
cSyv	int	Count of symbols.
lpstr	LPSTR	ANSI string buffer. The buffer should be big enough to hold at least cSyv number of ANSI characters (including SYV_NULL).
lpnConv	LPINT	If not NULL, lpnConv contains the number of symbols converted. If NULL, this parameter is ignored.
Comments

This function takes in an array of SYVs and a count of how many SYVs to convert. The buffer lpstr should be big enough to hold the total number of converted bytes. For ANSI characters, this value will be cSyv bytes. For double-byte characters (Kanji, for example), this value will be (2 * cSyv) bytes.

The SymbolToCharacter function converts, at most, cSyv number of SYVs from lpsyv and places them in the lpstr buffer. The conversion proceeds until a SYV_NULL value is encountered or until cSyv symbols have been converted. A SYV_NULL is converted to "\0". The actual number of symbols converted is returned in lpnConv if lpnConv is not NULL.

Return Value

SymbolToCharacter returns FALSE if it encounters one or more symbols that cannot be converted to ANSI. Otherwise, it returns TRUE.

See Also

CharacterToSymbol


TPtoDP

Action

Converts an array of points from tablet coordinates to screen coordinates

Module

RC Manager

Called By

Application

Syntax

C:

BOOL  TPtoDP(lpPnt, cPnt)

PASCAL:

function TPtoDP(lpPnt: PPoint; cPnt: Integer): Bool;

Parameter	Type	Description
lpPnt	LPPOINT	Array of points
cPnt	int	Number of points
Comments

The conversion will fail if some tablet points lie outside the region mapped to the screen.

Because of rounding errors, the DPtoTP and TPtoDP functions are not guaranteed to be complete inverses of each other.

Return Value

TPtoDP returns FALSE if not all points can be converted.

See Also

DPtoTP


TrainContext

Action

Gives the recognizer a previous recognition result which may contain errors plus the correct interpretation of the raw data

Module

RC Manager

Called By

System applications (Pen Palette)

Syntax

C:

BOOL  TrainContext(lprcresult, lpyse, csye, lpsyc, csyc)

PASCAL:

function TrainContext(lprcresult: PRCResult; lpsye: PSYE; cSye: Integer; lpsyc: PSYC; cSyc: Integer): Bool;

Parameter	Type	Description
lprcresult	LPRCRESULT	Pointer to the RCRESULT structure containing the hpendata which contains the raw data and the recognizer's original interpretation of that data.
lpsye	LPSYE	An array of SYEs that specify the correct interpretation of the raw data. The lpyse->iSyc values index the SYCs in the lpsyc parameter.
csye	int	The number of SYEs in the lpsye array.
lpsyc	LPSYC	An array of SYCs that establish the mapping between the raw data and the characters in the hpendata field of the lprcresult parameter.
csyc	int	The number of SYCs in the lpsyc array.
Comments

TrainContext is called by an application with a recognition result that may contain mistakes along with a correct interpretation so that the recognizer may learn from the mistake in order to improve subsequent recognition. A second, simpler training function is provided by TrainInk.

TrainContext calls the recognizer-supplied function TrainContextInternal in the recognizer DLL identified by lprcresult->lprc->hrec . A custom recognizer must provide this function, as well as TrainInkInternal, but it may simply return FALSE if the recognizer does not support this type of training.

When a training application is able to provide contextual information, such as segmentation suggestions to the recognizer, it uses the TrainContext function. The trainer incorporated in the Pen Palette uses this function for training.

The lprcresult parameter points to an RCRESULT structure that contains the results of a previous recognition. The raw data is also contained in the hpendata field of lprcresult. The lprcresult parameter must be non-NULL.

In addition to providing the incorrect interpretation of the data (by means of the symbol graph, the lpsyg field in lprcresult), a more detailed, correct interpretation is also provided by the SYEs and SYCs.  Because the correct interpretation is passed by SYEs, it is possible to suggest segmentation boundaries to the recognizer. Suppose, for example, that a user writes "lc," and the recognizer interprets it as "k." A trainer would call TrainContext using, first, an array of SYCs that point to the ink of the "lc" and, second, the two SYEs with the SYV values "l" and "c."These two SYEs share the same index into the lpsyc array, indicating that both use the ink that was interpreted as "k."

Segmentation errors can be corrected in the other direction as well.  Suppose, for example, the user writes "k" and the recognizer interprets it as "lc." A trainer could call TrainContext, using a single SYE with SYV equal to "k" and an array of SYCs that incorporate the ink the recognizer had previously assigned to the "l" and the "c."

To train several SYVs to a single piece of ink (for example, a long stroke that is an "he" ligature), there will be two consecutive SYEs -- one for the "h" and one for the "e." Both SYEs will have the same iSyc field; this means that these SYEs both point to the same ink. A recognizer will need to take this into consideration to avoid training the two characters separately and using the same ink for both; that would result in having "he" trained as "he he."

Custom Training

A recognizer may supply its own custom training dialogs. An application should check to see if the recognizer supports custom training by calling ConfigRecognizer with the WCR_TRAIN subfunction.

Return Value

TrainContext returns TRUE if the ink could be trained; otherwise, it returns FALSE.

The trainer does not display an error message if TrainInk or TrainContext returns FALSE.  Error messages that occur when training fails are the responsibility of the recognizer.

See Also

ConfigRecognizer, TrainContextInternal, TrainInk, SYC, SYE structures


TrainContextInternal

Action

At the DLL recognition level, TrainContextInternal gives the recognizer a previous recognition result which may contain errors plus the correct interpretation of the raw data

Module

Recognizer

Called By

RC Manager

Syntax

C:

BOOL TrainContextInternal(lprcresult, lpsye, csye, lpsyc, csyc)

PASCAL:

function TrainContextInternal(lprcresult: PRCResult; lpsye: PSYE; cSye: Integer; lpsyc: PSYC; cSyc: Integer): Bool;

Parameter	Type	Description
lprcresult	LPRCRESULT	Pointer to the RCRESULT structure containing the hpendata which contains the raw data and the recognizer's original interpretation of that data.
lpsye	LPSYE	An array of SYEs that specify the correct interpretation of the raw data. The lpyse->iSyc values index the SYCs in the lpsyc parameter.
csye	int	The number of SYEs in the lpsye array.
lpsyc	LPSYC	An array of SYCs that establish the mapping between the raw data and the characters in the hpendata field of the lprcresult parameter.
csyc	int	The number of SYCs in the lpsyc array.
Comments

TrainContextInternal is the function in the recognizer DLL that performs the TrainContext function. A custom recognizer must provide this function, as well as TrainInkInternal, but it may simply return FALSE if the recognizer does not support this type of training.

A recognizer that cannot make use of contextual information can instead translate this function into a call to the simpler training function TrainInkInternal. The lprc argument for TrainInkInternal can be taken directly from the lprcresult. To create the hpendata argument, use CreatePenData to create a new HPENDATA structure; next, step through the SYEs of lpsye, using GetPenDataStroke to get a copy of the strokes for the characters to be trained from the hpendata field of lprcresult; finally, use AddPointsPenData to insert the pen data into the new HPENDATA structure. The lpsyv argument for TrainInk can be generated from the syv fields of the SYEs.

Saving Training

The recognizer is responsible for saving the results of any training. Two appropriate times to save this information are:

•	in response to a WCR_TRAINSAVE subfunction request in ConfigRecognizer

•	in response to a WCR_RCCHANGE subfunction request in ConfigRecognizer

Return Value

TrainContextInternal returns TRUE if the ink could be trained; otherwise, it returns FALSE.

See Also

TrainContext, TrainInk, TrainInkInternal, SYC, SYE structures


TrainInk

Action

Gives the recognizer raw data and a correct interpretation of the data.

Module

RC Manager

Called By

System applications (Pen Palette, Control Panel, and others)

Syntax

C:

BOOL  TrainInk(lprc, hpendata, lpsyv)

PASCAL:

function TrainInk(lprc: PRC; hPenData: THPenData; lpsyv: PSYV): Bool;

Parameter	Type	Description
lprc	LPRC	Pointer to the RC structure.
hpendata	HPENDATA	Pen data to train. This parameter must be non-NULL.
lpsyv	LPSYV	An array of SYVs that is terminated by SYV_NULL.  This parameter must be non-NULL.
Comments

TrainInk is called by an application with raw data along with a correct interpretation so that the recognizer may learn to improve subsequent recognition. A second, more complex training function is provided by TrainContext.

TrainInk is called by an application to access the TrainInkInternal function in the recognizer DLL.  A custom recognizer must provide this function, as well as TrainContextInternal, but it may simply return FALSE if the recognizer does not support this type of training.

TrainInk provides the lowest level of basic shape training.  It effectively says to the recognizer,"Take the ink in hpendata and give it the meaning in lpsyv." The recognizer should interpret the ink to meet that request.

In the most common case, lpsyv contains a single character, and the recognizer will train a new shape based on the ink and that character. In other cases, multiple SYVs may be passed, indicating that the ink represents multiple characters.  The recognizer must decide whether to simply add a new shape with a multiple-SYV meaning or segment the ink into separate shapes for each SYV.

If the application passes NULL in the lprc parameter, the RC Manager substitutes a pointer to the global RC structure before passing it on to the recognizer.

The recognizer identified by lprc->hrec is called. If lprc is NULL or if lprc->hrec is RC_WDEFAULT, the recognizer in the global RC is called.

An application should check to see if the recognizer supports training by calling ConfigRecognizer with the WCR_TRAIN subfunction.

Return Value

TrainInk returns TRUE if the ink described by hpendata could be trained; otherwise, it returns FALSE.

The trainer will not display an error message if TrainInk or TrainContext returns FALSE.  Error messages that occur when training fails are the responsibility of the recognizer.

See Also

ConfigRecognizer, TrainContext, TrainContextInternal, TrainInkInternal


TrainInkInternal

Action

At the DLL recognition level, TrainInkInternal informs the recognizer that the raw data input represents the symbol value results.

Module

Recognizer

Called By

RC Manager

Syntax

C:

BOOL  TrainInkInternal(lprc, hpendata, lpsyv)

PASCAL:

function TrainInkInternal(lprc: PRC; hPenData: THPenData; lpsyv: PSYV): Bool;

Parameter	Type	Description
lprc	LPRC	Pointer to the RC structure. This parameter must be non-NULL.
hpendata	HPENDATA	Pen data to train.
lpsyv	LPSYV	An array of SYVs terminated by SYV_NULL.
Comments

TrainInkInternal is the function in the recognizer DLL that is called by the TrainInk function with raw data along with a correct interpretation so that the recognizer may learn to improve subsequent recognition. A custom recognizer must provide this function, as well as TrainContextInternal, but it may simply return FALSE if the recognizer does not support this type of training.

Saving Training

The recognizer is responsible for saving the results of any training. Two appropriate times to save this information are:

•	in response to a WCR_TRAINSAVE subfunction request in ConfigRecognizer

•	in response to a WCR_RCCHANGE subfunction request in ConfigRecognizer

See the description of TrainInk for details on using this function for context-free training.

Return Value

TrainInkInternal returns TRUE if the ink described by hpendata could be trained; otherwise, it returns FALSE.

See Also

TrainContext, TrainContextInternal, TrainInk


UninstallRecognizer

Action

Unloads the specified recognizer

Module

RC Manager

Called By

Application

Syntax

C:

void  UninstallRecognizer(hrec)

PASCAL:

procedure UninstallRecognizer(HRec: THRec);

Parameter	Type	Description
hrec	HREC	Recognizer handle
Comments

Windows maintains a use count so that the library is not actually unloaded until all callers of InstallRecognizer in the given library have called this function. This function should be called by any application one time for every call made to InstallRecognizer.

Before attempting to unload the library, CloseRecognizer is called within the recognizer.

It is not necessary to uninstall the default recognizer. An application must uninstall all recognizers that it explicitly loads, however.

Return Value

None

See Also

InstallRecognizer


UpdatePenInfo

Action

Called by the pen driver any time a PENINFO value changes

Module

RC Manager

Called By

Pen driver

Syntax

C:

void  UpdatePenInfo(lppeninfo)

PASCAL:

procedure UpdatePenInfo(lpPenInfo: PPenInfo);

Parameter	Type	Description
lppeninfo	LPPENINFO	Pointer to the PENINFO structure
Comments

A PENINFO value could change if the driver parameters are altered by the configuration dialog. When this happens, the pen driver must call UpdatePenInfo to notify the RC Manager of the change.

Return Value

None


BOXLAYOUT

Use the BOXLAYOUT structure to specify some of the characteristics of a bedit control. The GUIDE structure specifies the rest. The HE_GETLAYOUT and HE_SETLAYOUT wParam values of the WM_HEDITCTL message can be used to get and set the BOXLAYOUT structure for a bedit control.

C:

typedef struct

{

int cyCusp;	// Height of the box in pixels when BXS_RECT is specified;

// height of the cusp in pixels otherwise (in comb style).

int cyEndCusp;	// Height of cusps at either extreme in pixels.

UINT style;	// Style of box edit control;

// a combination of the BXS_ flags.

DWORD rgbText;	// Color of the text, -1 = color of window text.

DWORD rgbBox;	// Color of boxes, -1 = color of window frame.

DWORD rgbSelect;	// Color of selection, -1 = color of window text.

} BOXLAYOUT, FAR *LPBOXLAYOUT;

PASCAL:

type

  PBoxLayout = ^TBoxLayout;

  TBoxLayout = record

    cyCusp: Integer;

    cyEndCusp: Integer;

    Style: Word;

    rgbText: Longint;

    rgbBox: Longint;

    rgbSelect: Longint;

  end;

The following table lists the default values for the BOXLAYOUT structure.

Field	Default value
cyCusp	Equivalent in pixels of BXD_CUSPHEIGHT dialog units
cyEndCusp	Equivalent in pixels of BXD_ENDCUSPHEIGHT dialog units
style	0 for a single-line boxed edit control; BXS_ENDTEXTMARK for a multiline boxed edit control
rgbText	-1 (Color of window text is used)
rgbBox	-1 (Color of window frame is used)
rgbSelect	-1 (Color of window text is used)
The following table lists the values for the BXS_ style flags.

BXS_ Flags for Style Field	Meaning
BXS_RECT	If this flag is set, rectangular boxes are used; otherwise, combs are used.
BXS_ENDTEXTMARK	If this flag is set, an end-of-text marker is displayed in the control.


GUIDE

Use the GUIDE structure to specify the characteristics of any guidelines used in the writing area.

C:

typedef struct

{

int xOrigin;	// Position of left edge of first box

// in screen coordinates.

int yOrigin;	// Position of top edge of first box

// in screen coordinates.

int cxBox;	// Width of boxes.

int cyBox;	// Height of boxes.

int cxBase;	// Offset of the visible edge of the baseline

// within the box from the edge of the box.

int cyBase;	// Offset of the baseline for writing

// from the top of the box

int cHorzBox;	// Count of columns of boxes.

int cVertBox;	// Count of rows of boxes.

int cyMid;	// Offset from baseline to midline.

// Zero if not present.

}

GUIDE, FAR * LPGUIDE;	// Guidelines for recognizer.

PASCAL:

type

  PGuide = ^TGuide;

  TGuide = record

    xOrigin: Integer;

    yOrigin: Integer;

    cxBox: Integer;

    cyBox: Integer;

    cxBase: Integer;

    cyBase: Integer;

    cHorzBox: Integer;

    cVertBox: Integer;

    cyMid: Integer;

  end;

The GUIDE structure is a part of the RC structure.

If the application has drawn guidelines on the screen on which the user is expected to write, the application should set the values in the GUIDE structure to inform the recognizer. The GUIDE structure is for the recognizer's use only. Setting the GUIDE structure does not, by itself, draw any visual clues on the display. It is the responsibility of the application or the control to draw the visual clues. The visual look of a boxed edit control is determined by the BOXLAYOUT and GUIDE structures together.

The xOrigin and yOrigin fields are screen coordinates of the top-left corner of the area to write in. The cyBox and cxBox fields are the height and width of the individual boxes to write in. The cHorzBox and cVertBox fields are the number of columns and rows. A baseline within the box can be indicated by setting cyBase. Setting cyBase to zero indicates no baseline is given. The cxBase field can indicate a horizontal displacement of the edge of the guideline from the edge of the box where writing can be expected to start.

If only horizontal lines are present, cxBox will be zero. In this case, only yOrigin, cyBox, cyBase, and cyMid will be valid. If both vertical and horizontal lines are present (boxed input), the RCO_BOXED flag must be set in the lRcOptions field of the RC structure.

Writing need not be restricted to inside boxes. Inking is still restricted to rc.rectBound only. If there is a midline (shown in the bottom row of boxes in Figure 10-2), its height above the baseline is given by cyMid. This is zero if no midline exists.

In the RC structure, these values will be converted to tablet coordinates before they are passed on to the recognizer. With an orientation of RCOR_LEFT or RCOR_RIGHT, the roles of cHorzBox and cVertBox are reversed.

The InitRC function sets all elements of the GUIDE structure to 0.

For boxed input, the result message contains an index to the box containing the first input character. This is numbered in row-major order, zero-based.

To change a standard bedit, first do a HE_GETRC subfunction request of WM_HEDITCTRL to get the GUIDE structure. Make any changes needed and then use HE_SETRC to inform the bedit control of the changes.

For best recognition results, the pair-wise ratios of cxBox, cyBox and cyBase should be the similar to the default ratios.


OEMPENINFO

C:

typedef struct

{

UINT wPdt; 	// Pen data type.

UINT wValueMax;	// Largest value returnable by device.

UINT wDistinct;	// Number of distinct readings possible.

} OEMPENINFO;

PASCAL:

type

  POEMPenInfo = ^TOEMPenInfo;

  TOEMPenInfo = record

    wPdt: Word;

    wValueMax: Word;

    wDistinct: Word;

  end;

The OEMPENINFO structure contains a description of the additional OEM information that the hardware can generate. It is a part of the PENINFO structure.

Besides capturing the (x,y) data, a pen device has the option of supporting a number of other types of input data: pressure, height, angle, and so on. A pen driver can capture up to six other types of data. An application can access this data through the GetPenHwData function.

Each event from the pen generates a position as well as information on any of the other types of data. The width of this optional data is cbOemData bytes. Each type of data is one word wide. The type of data in the nth word of the Oem data packet is given by the nth element of the OEMPENINFO field in the PENINFO structure. PDT_NULL indicates no data. Values above PDT_OEMSPECIFIC are reserved for private use by drivers for data types not currently defined as standard. The wValueMax parameter is the largest value that can be returned by the device for that data type. The wResolution parameter is the number of distinct readings the device can take between 0 and wMaxValue.

The constants that specify OEM-specific data are listed in the following table.

Constant	Value
PDT_NULL	0
PDT_PRESSURE	1
PDT_HEIGHT	2
PDT_ANGLEXY	3
PDT_ANGLEZ	4
PDT_BARRELROTATION	5
PDT_OEMSPECIFIC	16
The units for height are .01 cm.

The units for the angle measure are in tenths of a degree. Zero for AngleZ indicates that the pen is perpendicular to the writing surface. Zero for AngleXY indicates that the pen is parallel with the side, running from the top to the bottom of the writing surface. The zero position for barrel rotation is device-dependent.

As an example, consider a device that can sense height and AngleZ. It can sense 256 levels of height in a range from 0 to 10 centimeters and has a resolution of 1 degree on the angle of the pen. The rgOemPenInfo for this device would look like this:

peninfo.cbOemData = 4

peninfo.rgOemPenInfo[MAXOEMDATAWORDS] = {

{PDT_HEIGHT, 1000, 256},

{PDT_ANGLEZ, 1800, 180},

{PDT NULL, 0, 0},

{PDT_NULL, 0, 0},

{PDT_NULL, 0, 0},

{PDT_NULL, 0, 0} };

This optional information is saved by the pen driver in the same manner as the (x,y) data. There must be a one-to-one correspondence between the OEM event data and the (x,y) data.


PENDATAHEADER

C:

typedef struct

{

UINT wVersion;	// Pen data format version

UINT cbSizeUsed;	// Size of pen data memory block

UINT cStrokes;	// Number of strokes (each pen up and

// pen down run is a single stroke)

UINT cPnt;	// Total count of points

UINT cPntStrokeMax;	// Length of longest stroke in points

RECT rectBound;	// Coordinates of bounding rectangle of down points

UINT wPndts;	// State of the various PDTS_ bits

int nInkWidth; 	// Ink width

DWORD rgbInk; 	// Ink color

}

PENDATAHEADER, FAR * LPPENDATAHEADER;

PASCAL:

type

  PPenDataHeader = ^TPenDataHeader;

  TPenDataHeader = record

    wVersion: Word;

    cbSizeUsed: Word;

    cStrokes: Word;

    cPnt: Word;

    cPntStrokeMax: Word;

    rectBound: TRect;

    wPndts: Word;

    nInkWidth: Integer;

    rgbInk: Longint;

  end;

Use the PENDATAHEADER structure in conjunction with the GetPenDataHeader function. The structure describes the specified pen data memory block.

If data is collected outside the bounding rectangle, the rectBound field reflects this. This means that rcresult.rectBoundInk is outside the rectangle and does not truly reflect the bounds of the ink on the screen. However, it does reflect the size of the object if it is to be drawn in a different window.

The following table lists the PDTS_ values for the wPndts field.

PDTS_ bits for wPndt	Meaning
PDTS_ARBITRARY	The application has done its own scaling of the data point.
PDTS_COMPRESS2NDDERIV	The second derivative between points is stored.
PDTS_COMPRESSED	The data is compressed.
PDTS_COMPRESSMETHOD	Bits have been saved to encode which compression scheme is used.
PDTS_DISPLAY	Each logical unit is equivalent to a display pixel.  Positive x is to the right; positive y is down.
PDTS_HIENGLISH	Each logical unit is mapped to 0.001 inch. Positive x is to the right; positive y is down.
PDTS_HIMETRIC	Each logical unit is mapped to 0.001 mm. Positive x is to the right; positive y is down.
PDTS_LOMETRIC	Each logical unit is mapped to 0.01 mm. Positive x is to the right; positive y is down.
PDTS_NOOEMDATA	No OEM data is present.
PDTS_NOPENINFO	The PENINFO structure has been trimmed from the header.
PDTS_NOUPPOINTS	The data points on pen up have been removed.
PDTS_SCALEMASK	This value refers to the bits used to mask scaling.
PDTS_SCALEMAX	This value represents the maximum scaling allowed.
PDTS_STANDARDSCALE	The standard scaling metric is equivalent to PDTS_HIENGLISH. Standard recognizers will scale to this.


PENINFO

C:

#define MAXOEMDATAWORDS  6

typedef struct

{

UINT cxRawWidth;	// Max X coordinate & width of tablet in 0.001 inches

UINT cyRawHeight;	// Max Y coordinate & height of tablet in 0.001 inches

UINT wDistinctWidth;	// Number of distinct X values tablet returns

UINT wDistinctHeight;	// Number of distinct Y values tablet returns

int nSamplingRate;	// Samples/second

int nSamplingDist;	// Minimum distance moved in either direction

   // to generate a new pen event

LONG lPdc;	// Pen device capabilities

int cPens;	// Number of pens supported

int cbOemData;	// Width of OEM data packet

OEMPENINFO rgoempeninfo[MAXOEMDATAWORDS];	// Supported OEM data types

UINT rgwReserved[8]; 	// For internal use

}

PENINFO, FAR *LPPENINFO;

PASCAL:

type

  PPenInfo = ^TPenInfo;

  TPenInfo = record

    cxRawWidth: Word;

    cyRawHeight: Word;

    wDistinctWidth: Word;

    wDistinctHeight: Word;

    nSamplingRate: Integer;

    nSamplingDist: Integer;

    lPdc: Longint;

    cPens: Integer;

    cbOemData: Integer;

    rgoempeninfo: array[0..MaxOEMDataWords - 1] of TOEMPenInfo;

    rgwReserved: array[0..7] of Word;

  end;

The DRV_GetPenInfo pen driver message fills the PENINFO structure with the current pen parameters. DRV_GetPenInfo returns FALSE if a tablet is not physically present. If this occurs, the peninfo field may not be present.

The following table lists the PDC_ values for the lPdc field.

Value	Meaning
PDC_BARREL1	Barrel button 1 is present.
PDC_BARREL2	Barrel button 2 is present.
PDC_BARREL3	Barrel button 3 is present.
PDC_INTEGRATED	The display and the digitizer share the same surface.
PDC_INVERT	The pen can detect that the other end of the pen is in contact with the tablet.
PDC_PROXIMITY	The pen position can be detected without the tip's being in contact with the tablet.
PDC_RANGE	The pen can generate an event upon leaving or entering the detection range.
PDC_RELATIVE	The physical device is a relative motion device only.
The PENINFO Fields

The following paragraphs discuss the PENINFO fields, listed in the order in which they appear in the preceding structure.

cxRawWidth, cxRawHeight

C:

UINT cxRawWidth;

UINT cyRawHeight;

PASCAL:

cxRawWidth: Word;

cyRawHeight: Word;

The cxRawWidth and cyRawHeight fields describe the physical tablet dimensions in thousandths of an inch. Theses values also specify the maximum x and y table coordinates.

wDistinctWidth, wDistinctHeight

C:

UINT wDistinctWidth;

UINT wDistinctHeight;

PASCAL:

wDistinctWidth: Word;

wDistinctHeight: Word;

The wDistinctWidth and wDistinctHeight fields specify the number of distinct values that the hardware can detect. For example if a tablet is 8 inches wide and has a resolution of 1/500 of an inch, cxRowWidth is 8000 and wDistinctWidth is 4000, because the tablet hardware can return 4000 distinct x values which range from 0 to 8,000.

nSamplingRate

C:

int nSamplingRate;

PASCAL:

nSamplingRate: Integer;

The nSamplingRate field specifies the number of times per second that the pen hardware is sampled. This rate can be adjusted with the DRV_SetSamplingRate pen driver message.

nSamplingDist

C:

int nSamplingDist;

PASCAL:

nSamplingDist: Integer;

The nSamplingDist field specifies the distance in distinct tablet units a pen must travel before a new pen event is generated.  This distance can be adjusted with the DRV_SetSamplingDistance pen driver message.

lPdc

C:

LONG lPdc;

PASCAL:

lPdc: Longint;

The lPdc field is the combination (OR operator) of all of the PDC_ (pen device capabilities) bits that describe the tablet capabilities.

cPens

C:

int cPens;

PASCAL:

cPens: Integer;

The cPens field specifies the number of pens that tablet can support.

cbOemData

C:

int cbOemData;

PASCAL:

cbOemData: Integer;

The cbOemData field specifies the width, in bytes, of the additional OEM data that is passed in each pen packet. For example, if a tablet supports pressure and angle Z information, this is two additional words of OEM information, so cbOemData is 4.

rgoempeninfo

C:

OEMPENINFO rgoempeninfo[MAXOEMDATAWORDS];

PASCAL:

rgoempeninfo: array[0..MaxOEMDataWords - 1] of TOEMPenInfo;

The rgoempeninfo field is an array of OEMPENINFO structures. Each structure describes one word of additional OEM data contained in each pen packet.

rgwReserved

C:

UINT rgwReserved[8];

PASCAL:

rgwReserved: array[0..7] of Word;

This array is reserved for future use.


PENPACKET

#define MAXOEMDATAWORDS   6

typedef struct

{

UINT wTabletX;	// X in raw coordinates.

UINT wTabletY;	// Y in raw coordinates.

UINT wPdk;	// State bits.

UINT rgwOemData[MAXOEMDATAWORDS];	// OEM-specific data.

}

PENPACKET, FAR * LPPENPACKET;

The basic unit of communication between the pen driver and Windows is a pen packet. A pen packet contains all of the information about a single logical event: (x,y) coordinate position, button states, and any optional information such as pressure or barrel rotation. Many physical events -- interrupts -- may be needed to construct a single logical event.

The PENPACKET structure is formally defined in the TABLET.INC file. The following code fragment contains the definition.

; PENPACKET - what drivers should use to communicate with

; PenWin.Dll

;

C:

PENPACKET struc

wTabletX	dw	0;	X in tablet coordinates

wTabletY	dw	0;	Y in tablet coordinates

wPDK	dw	0;	various status bits for packet

rgwOemData	dw	MAXOEMDATAWORDS dup (0);	OEM info like pressure

PENPACKET ends

PASCAL:

type

  PPenPacket = ^TPenPacket;

  TPenPacket = record

    wTabletX: Word;

    wTabletY: Word;

    wPDK: Word;

    rgwOemData: array[0..MaxOEMDataWords - 1] of Word;

  end;

The rgwOemData field contains the real-time values associated with the pen data types described in the OEMPENINFO structure.


RC

The core of the recognition process is the RC (Recognition Context) structure. Although there are a large number of parameters in the RC structure, an application will only have to deal with a few of them. The application uses the InitRC function to set the default values and then adjusts certain parameters before making one of the Recognize calls.

C:

typedef struct

{

HREC hrec;	// Handle of recognizer to use.

HWND hwnd;	// Window to send results to.

UINT wEventRef;	// Data reference indicating first

// point to use in recognition.

UINT wRcPreferences;	// Preferences.

LONG lRcOptions;	// Options.

RCYIELDPROC lpfnYield;	// Procedure called during yield.

BYTE lpUser[cbRcUserMax]; 	// Current writer.

UINT wCountry;	// Country code.

UINT wIntlPreferences;	// RCIP_ Flags

char lpLanguage[cbRcLanguageMax];	// language strings.

LPDF rglpdf[MAXDICTIONARIES]; 	// List of dictionary functions.

UINT wTryDictionary;	// Maximum enumerations to search.

CL clErrorLevel;	// Level at which recognizer should reject input.

ALC alc;	// Enabled alphabet.

ALC alcPriority;	// Prioritizes the ALC_ codes used to enable alphabets.

BYTE rgbfAlc[cbRcrgbfAlcMax];	// Bit field for enabled characters.

UINT wResultMode;	// When to send (ASAP or when recognition complete).

// Control of recognition completion.

UINT wTimeOut;	// Time-out threshold in milliseconds

// (after this time, stop recognition).

LONG lPcm;	// Flags for ending recognition.

RECT rectBound;	// Bounding rectangle for inking.

RECT rectExclude;	// Pen down inside this ends recognition.

GUIDE guide;	// Define guidelines for recognizer.

UINT wRcOrient;	// Orientation of writing relative to

// tablet coordinates.

UINT wRcDirect;	// Direction of writing.

int nInkWidth;	// Ink width.  0 (no ink) to 15.

COLORREF rgbInk;	// Color of ink.

DWORD dwAppParam;	// For use by application.

DWORD dwDictParam;	// For use by application to be

// passed on to dictionaries.

DWORD dwRecognizer;	// For use by an application to pass

// information to recognizer.

UINT rgwReserved[cwRcReservedMax];  // Reserved for future

//  use by Windows.

}

RC, FAR * LPRC;	// Recognition context.

PASCAL:

type

  PRC = ^TRC;

  TRC = record

    HRec: THRec;

    hw: HWnd;

    wEventRef: Word;

    wRcPreferences: Word;

    lRcOptions: Longint;

    lpfnYield: TRCYieldProc;

    lpUser: array[0..cbRcUserMax-1] of Byte;

    wCountry: Word;

    wIntlPreferences: Word;

    lpLanguage: array[0..cbRcLanguageMax-1] of Char;

    rglpdf: array[0..MaxDictionaries-1] of TDF;

    wTryDictionary: Word;

    clErrorLevel: TCL;

    alc: TALC;

    alcPriority: TALC;

    rgbfAlc: array[0..cbRcrgbfAlcMax-1] of Byte;

    wResultMode: Word;

    wTimeOut: Word;

    lPcm: Longint;

    rectBound: TRect;

    rectExclude: TRect;

    guide: TGuide;

    wRcOrient: Word;

    wRcDirect: Word;

    nInkWidth: Integer;

    rgbInk: TColorRef;

    dwAppParam: Longint;

    dwDictParam: Longint;

    dwRecognizer: Longint;

    rgwReserved: array[0..cwRcReservedMax-1] of Word;

  end;

The RC Fields

The following paragraphs discuss the RC fields, listed in the order in which they appear in the preceding structure.

rc.hrec

C:

HREC hrec;

PASCAL:

HRec: THRec;

The hrec field is the handle of the recognizer to use. This value should be set to the value returned by a previous call to InstallRecognizer or RC_WDEFAULT for the default recognizer.

If hrec is NULL, the null recognizer is used. WM_RCRESULT messages are generated -- as with a real recognizer -- but the wResultsType field of RCRESULT is set to RCRT_NORECOG, and the hSyv and lpSyv fields are set to NULL.

rc.hwnd

C:

HWND hwnd;

PASCAL:

hw: HWnd;

The hwnd field specifies the window to send recognition results to. This field cannot be NULL. Also, the mouse capture will be set to this window to clear the queue of pending mouse messages that were meant for recognition.

rc.wEventRef

C:

UINT wEventRef;

PASCAL:

wEventRef: Word;

The value for wEventRef indicates which tablet data to begin recognition with.

InitRC sets this field to RC_WDEFAULT. If Recognize is called during the processing of the mouse message (such as WM_LBUTTONDOWN), triggering recognition, the application need take no other action.

If an application wants to start recognition on some other Windows event, it should save the wEventRef from the appropriate mouse message (using GetMessageExtraInfo) and place this value in wEventRef before calling Recognize.

This field is not used on calls to RecognizeData.

rc.wRcPreferences

C:

UINT wRcPreferences;

PASCAL:

wRcPreferences: Word;

The wRcPreferences field specifies the user preferences as a combination of RCP_ constants described in the following table.

Value	Meaning
RCP_LEFTHAND	User writes with left hand. The default assumption is right-handed.
RCP_MAPCHAR	This value tells the recognizer to fill in segmentation information in the lpsyc field. This cannot be set by the user, because there is no Control Panel access to this value. It is set if training is enabled.
rc.lRcOptions

C:

LONG lRcOptions;

PASCAL:

lRcOptions: Longint;

The lRcOptions  field specifies various options for recognition. It is a logical OR combination of any of the RCO_ constants.

rc.lpfnYield

C:

RCYIELDPROC lpfnYield;

PASCAL:

lpfnYield: TRCYieldProc;

The lpfnYield field is a callback function used by the recognizer before it yields. The application sets this to NULL for no yield processing. Recognition can often take more than a few seconds, and therefore, a recognizer should periodically call the yield function to yield control to other Windows tasks. The default yield function is:

BOOL FAR PASCAL StandardYieldFunction()

{

Yield( );

return 1;

}

If Recognize or RecognizeData is called with rc.lpfnYield set to RC_LDEFAULT, then the default yield function is called. If the rc.lpfnYield field is not NULL, the recognizer will call lpfnYield every time before it yields.

rc.lpUser

C:

#define cbRcUserMax	32

BYTE lpUser[cbRcUserMax];

PASCAL:

lpUser: array[0..cbRcUserMax-1] of Byte;

The lpUser field specifies the name of the current writer. The current writer is used to specify any custom prototype sets that might be available to the recognizer.

If the lpUser field is NULL, it means that the recognizer will use the standard prototype set -- the prototype set as it existed before anyone modified it (through training, for example).

rc.wCountry

C:

UINT wCountry;

PASCAL:

wCountry: Word;

The wCountry field contains the country code. The values for country code are the same as the values used by the International item of the Control Panel for the iCountry field in the [intl] section of the WIN.INI file.

rc.wIntlPreferences

C:

UINT wIntlPreferences;

PASCAL:

wIntlPreferences: Word;

The wIntlPreferences field contains a combination of various RCIP_ flags.

Currently the only RCIP_ flag is RCIP_ALLANSICHAR. This flag specifes that the user intends to use the entire ANSI character set. A recognizer should examine this flag to decide which characters to enable for recognition.

If nothing is set, then only characters from the current language or languages are enabled.

rc.lpLanguage

C:

#define cbRcLanguageMax	44;

char lpLanguage[cbRcLanguageMax];

PASCAL:

lpLanguage: array[0..cbRcLanguageMax-1] of Char;

The lpLanguage field is a list of language strings. Each string is zero-terminated, and the list ends in the NULL string.

The set of values for each language string is the same as the set used by the International item of the Control Panel for the sLanguage field in the [intl] section of the WIN.INI file.

A recognizer should implement recognition of the ANSI character set and then use this information during recognition to limit a match to the appropriate subset.

This field holds strictly optional information -- a recognizer may choose to ignore it. By definition, the character set implied by a language string is the set of characters that can be generated from the country-specific keyboard without using the ALT+numeric keypad combinations. It will still be possible to enter ANSI characters outside the given language through the use of the on-screen keyboard and ALT+numeric keypad combinations.

rc.rglpdf

C:

#define MAXDICTIONARIES 16

LPDF rglpdf[MAXDICTIONARIES]

PASCAL:

rglpdf: array[0..MaxDictionaries-1] of TDF;

The dictionary path field, rglpdf, specifies which dictionaries are called by the RC Manager to convert symbol graphs into strings.

If rglpdf[0] is NULL, the NULL dictionary path is used. The NULL dictionary path indicates that the first enumeration from the symbol graph is used as the best enumeration. The array of dictionary functions is NULL-terminated. During recognition, each dictionary function will be called in the order they appear.

rc.wTryDictionary

C:

UINT wTryDictionary;

PASCAL:

wTryDictionary: Word;

The wTryDictionary field specifies the maximum number of enumerations that are generated from the symbol graph during dictionary processing on the results of recognition.

The minimum number allowed is 1, and the maximum is 4096. The default value is 100.

rc.clErrorLevel

C:

CL clErrorLevel;

PASCAL:

clErrorLevel: TCL;

Recognition accuracy is defined as the percentage of times that the recognizer accurately assigns a symbol to an input. There is no penalty or gain if the recognizer does not attempt a match and returns "unknown." This value can range from 0 to 100.

There are situations in which a higher accuracy rating is preferable despite an increased number of unknown results. For example, in a forms application, the social security field must be correctly recognized. If the recognizer is unsure, it can get the application to reprompt the user for the input (or a portion of it). At other times, it is preferable that the recognizer make a guess, no matter how wild, in order to limit the number of unknown results. For example, while taking notes in a meeting, the user may not care whether all of the results are transcribed perfectly.

The clErrorLevel field allows the application to signal its preference to the recognizer. Recognizers should report the "unknown" symbol for any symbol having a confidence level below clErrorLevel.

rc.alc

C:

typedef LONG ALC;

ALC alc;

PASCAL:

alc: TALC;

The alc field is used to define the enabled alphabet for any RC structure. The enabled alphabet is defined using the ALC_ constants.  Any of the ALC_ constants can be combined together to form the set of characters you want.

The actual characters enabled are language-dependent. For example, if the user has requested French language support, "è" would be included in the lowercase alphabet. Likewise, "£" is included in place of "$" on British systems if the ALC_MONETARY is set.

Setting the RCIP_ALLANSICHAR flag in the wIntlPreferences field of the RC structure enables all characters of the appropriate set regardless of the language setting.

A recognizer that recognizes characters other than ANSI can ignore this field. If you want an application to pass character subset information to private non-ANSI recognizers, you can use the dwRecognizer field.

A recognizer will not return a symbol value outside the specified subset. However, a recognizer does not have to force a match to the subset; it can return "unknown" if a suitable match is not found.

rc.alcPriority

C:

ALC alcPriority

PASCAL:

alcPriority: TALC;

The alcPriority field prioritizes the ALC_ codes used to enable alphabets. It does this by telling the recognizer in which order to list options in the symbol graph -- alphanumeric or numeric.

The alcPriority field uses the same ALC_ codes used in the alc field. The bits set in alcPriority should be a subset of those set in alc. Bit sets in the alcPriority that are not also set in the alc field have no effect.

A recognizer can recognize a glyph that belongs to more than one enabled ALC_ subset. For example, the "l" glyph can be the letter "l" in the ALC_LCALPHA subset or the number "1" in the ALC_NUMERIC subset. The alcPriority field specifies that the recognizer should return those interpretations that are in the subsets indicated in alcPriority first. If no interpretations are in any of the alcPriority sets, or no priority fields are set, the recognizer will return all possibilites within the enabled sets.

For example, suppose the user writes a symbol that looks like a "q" or a "9." The symbol graph generated contains {q | 9 }. The alcPriority field determines the exact look of the symbol graph.

If alcPriority = ALC_ALPHA, the recognizer should return { q | 9 ) in the symbol graph. If alcPriority = ALC_NUMERIC, the recognizer should return { 9 | q ) in the symbol graph.

Note that alcPriority does not affect the dictionary processing directly.

The recognizer does not implement ALC_USEBITMAP in the alcPriority field for version 1.0. Note that alcPriority is implemented for the alc field.

rc.rgbfAlc

C:

#define cbRcrgbfAlcMax	32

BYTE rgbfAlc[cbRcrgbfAlcMax];

PASCAL:

rgbfAlc: array[0..cbRcrgbfAlcMax-1] of Byte;

The rgbfAlc field is the bitfield used for enabled characters.

If ALC_USEBITMAP is set, the 256-bit bitfield in rc.rgbfAlc is used to indicate which characters from the ANSI character set are currently enabled. Character 0 is the low bit of the low-order byte in the array. Characters indicated thus are connected by OR operators to any characters enabled using the other ALC_ codes. A "1" set in a bit array indicates that the character is enabled.

As an example, to enable the character '$' the fifth bit of byte four is set:

rgbfAlc[4] |= 0x10

A recognizer that recognizes characters other than ANSI can ignore this field. If an application wants to pass character subset information to private non-ANSI recognizers, it can use the dwRecognizer field of the RC structure.

A set of macros simplifies user setting and testing the rgbfAlc bits for the RC specified by lprc. The ANSI macros listed below set (bit=1), reset (bit=0) or test (TRUE if bit==1, else FALSE) the appropriate bits in lprc->rgbfAlc corresponding to the index i, which is the ANSI value to use. The lprc is a pointer to the RC structure containing the rgbfAlc[] array.

Macro	Usage
SetAlcBitAnsi(lprc,i)	Sets the bit specified by i in rgbfAlc of lprc to 1.
ResetAlcBitAnsi(lprc,i)	Resets the bit specified by i in rgbfAlc of lprc to 0.
IsAlcBitAnsi(lprc,i)	Returns TRUE if the bit specified by i in rgbfAlc of lprc is set.
Only the IsAlcBitAnsi macro returns a value (BOOL). The return values of the other macros are undefined.

Setting bits in rc.rgbfAlc[] also requires combining ALC_USEBITMAP by an OR operator with rc.alc for the bits to have meaning. The bits are used in addition to other alc settings. For example, adding ALC_NUMERIC does not also set the bits in rc.rgbfAlc that correspond to '0' through '9'. Thus to recognize octal numbers (the set 0 to 7), the following code may be used:

RC rc;

int i;

rc.alc = ALC_USEBITMAP;     /* note no ALC_NUMERIC */

for (i = (int)'0'; i <= (int)'7'; i++)

SetAlcBitAnsi(&rc, i);

rc.wResultMode

C:

UINT wResultMode;

PASCAL:

wResultMode: Word;

The wResultMode field specifies the timing and granularity of the results messages to be sent back to the specified window. The following times are defined.

Value	Meaning
RRM_WORD	The granularity is set at a word boundary. As soon as the recognizer sees a word break, it can send all symbols up to the point of the word break.
RRM_NEWLINE	The granularity is set at a new line. As soon as the recognizer sees a line break, it can send the result up to that point.
RRM_COMPLETE	When recognition is completed by one of the methods (for example, time-out or barrel button), the results message is sent just before Recognize returns.
RRM_STROKE	The granularity is set at the stroke level. A result message is sent at each stroke. This is used in the NULL recognizer.
RRM_SYMBOL	The granularity is set at the symbol level. A result message is sent at each symbol. In the recognizer, this is implemented only for boxed input. Default dictionary processing is disabled when this value is used.
Future versions may implement other results modes.

A recognizer is free to send the messages any time after the requested time (defined in the preceding order), but it cannot send any messages sooner. because of recognizer constraints, a recognizer may combine intermediate results messages. For example, if an application requests RRM_WORD, the recognizer may choose to return results on a line-by-line basis instead.

Results sent at a word boundary do not have to be sent strictly one word at a time. The requirements are as follows:

•	The raw data returned must be contiguous and must begin with a pen down and end with a pen up.

•	The "word" returned may contain spaces. This is useful if a space was resolved only by dictionary look-up. For example, "fat{space | NULL}cat" would be resolved into two words, "fat cat." This is also necessary if the raw data for successive words overlaps.

•	The recognizer should not send a word until it knows how the word will be followed. If the word is to be followed by a word on essentially the same line, the word should be space-terminated. If the word is followed by text on a new line, it should append a soft newline symbol. The key point is that the recognizer must make it possible for the application to detect word and line spacing so it can display the recognized text appropriately.

•	Once a word has been sent, the recognizer cannot change the results because of the late arrival of more strokes.

The rules for returning results with RRM_NEWLINE are similar:

•	The new line should be included with the symbol graph in the result.

•	Once a word has been sent, the recognizer cannot change the results because of the late arrival of more strokes.

rc.wTimeOut

C:

UINT wTimeOut;

PASCAL:

wTimeOut: Word;

The wTimeOut field specifies the time-out threshold. After the time-out threshold has passed, the recognizer stops the recognition process.

Time-out occurs if more than wTimeOut milliseconds elapse between the most recent pen up and the next pen down. If time-out occurs, the recognition context is closed. Closing a recognition context means no more data is accepted -- the existing data is processed, and the results are sent to the application.

This value is ignored if rc.lPcm does not enable time-out.

In general, applications should use the value set by the user with the Control Panel. This value can be set by setting this field to RC_WDEFAULT.

The maximum value allowed is 65,534 milliseconds. If wTimeOut is set to FFFF (that is, 65,535), the system level value is used.

rc.lPcm

rc.rectBound

rc.rectExclude

C:

LONG lPcm;

RECT rectBound;

RECT rectExclude;

PASCAL:

lPcm: Longint;

rectBound: TRect;

rectExclude: TRect;

These three fields of the RC structure set the conditions for ending recognition.

The lPcm field sets the flags for ending recognition. The two rect fields specify inclusive and exclusive rectangles for inking. The rectangle values are in screen coordinates. The rectangle values can be in tablet coordinates if RCO_TABLETCOORD is set. RCO_TABLETCOORD cannot be used with ProcessWriting.

When RCRESULT is returned, the rectBound and rectExclude values are converted from screen to tablet coordinates and the RCO_TABLETCOORD flag is set.

Only pen events within rectBound are collected as part of the recognition context. If  PCM_RECTBOUND is set in rc.lPcm, the first pen down outside the rectangle will close the context. Dragging the pen outside the rectangle after starting inside will not close the context; the data is still collected outside the rectangle.

If PCM_RECTEXCLUDE is set in rc.lPcm, any pen down event within rectExclude will close the context.

The event that ends pen collection mode -- event outside the bounding rectangle or inside the exclusion -- is entered into Windows as a mouse event. For hit-testing the rectangles, the top and left borders are included, but not the right or bottom borders.

The bounding rectangle set by InitRC is valid only until the window is resized or moved. If the window is moved or sized, the application should respecify the rectBound field in the RC structure.

The following table lists the values for lPcm.

Value	Meaning
PCM_ADDDEFAULTS	If this bit is set, the default ending conditions set in the Global RC are connected by OR operators to the values set by the application. This bit is set by InitRC so that Control Panel settings for time-out and proximity will be considered during the subsequent call to Recognize.
PCM_INVERT	Ends recognition on pen inversion (a pen tap with the opposite end -- that is, the blunt end of the pen).
PCM_PENUP	Ends pen collection mode if pen is not in contact with the screen (that is, the pen tip is no longer pressed).
PCM_RANGE	Ends pen collection mode if the pen leaves the detection range.
PCM_RECTBOUND	Ends on pen down outside the bounding rectangle.
PCM_RECTEXCLUDE	Ends on pen down inside the exclusion rectangle.
PCM_TIMEOUT	Ends on time-out.
rc.guide

C:

GUIDE guide;

PASCAL:

guide: TGuide;

The guide field is a structure of the GUIDE type. It contains information that specifies the placement of guidelines in the writing area for the recognizer's use.

rc.wRcOrient

C:

UINT wRcOrient;

PASCAL:

wRcOrient: Word;

The wRcOrient field specifies the orientation of the tablet. The RCOR_ constants are used to establish the tablet orientation.

rc.wRcDirect

C:

UINT wRcDirect;

PASCAL:

wRcDirect: Word;

The wRcDirect field informs the recognizer of the direction of writing. There are both primary and secondary directions. For example, English is written from left to right (primary) and then down the page (secondary). Chinese is often written top down (primary) and then right to left across the page (secondary).

The high byte of the direction indicates primary direction; the low byte, secondary direction. A recognizer can choose to ignore this word and support only the natural direction of the given language. The default value is determined by the recognizer.

Not all recognizers will respond to this field.

rc.nInkWidth, rc.rgbInk

C:

int nInkWidth;

COLORREF rgbInk;

PASCAL:

nInkWidth: Integer;

rgbInk: TColorRef;

These two fields specify the ink width and color to be used during inking.

The nInkWidth field is the thickness, in pixels, of the pen to use during inking. If this value is 0, no ink will be drawn. The current maximum value allowed is 15. The default is the ink width set in the global RC.

The rgbInk field is the color to use for inking. If this is not a solid color, it will be mapped to the closest solid color. The default is the ink color set in the global RC.

rc.dwAppParam, rc.dwRecognizer

C:

DWORD dwAppParam;

DWORD dwRecognizer;

PASCAL:

dwAppParam: Longint;

dwRecognizer: Longint;

These two fields are analogous to the dwDictParam field.

The dwAppParam value is provided for use by the application and passed to the application by way of the lprc field in the RCRESULT structure.

The dwRecognizer value is passed to the recognizer specified in rc.hrec. Applications can use this to pass information to a private recognizer for functionality not directly supported.

These values are set to zero (0) by InitRC and should remain zero if they are not used by the application or recognizer.

rc.dwDictParam

C:

DWORD dwDictParam;

PASCAL:

dwDictParam: Longint;

This parameter is set by an application and passed on to the dictionary by the RC Manager. It is intended to provide for dictionary functionality not directly supported. For example, a dictionary can request the application to pass in a pointer to a structure that contains the sentence. You can use this information to extend the dictionary functionality. For example, you can use this to highlight misspelled words.

If it is not used by the application, dwDictParam should be left to the value (0) set by InitRC.

rc.rgwReserved[cwRcReservedMax]

C:

UINT rgwReserved[cwRcReservedMax];

PASCAL:

rgwReserved: array[0..cwRcReservedMax-1] of Word;

The rgwReserved field, used internally, is reserved for future use. Applications should not change the values set by InitRC for this field.


RCRESULT

A new message, WM_RCRESULT, has been added to Windows to support handwriting. This message is sent to the specified window when the recognizer has a result to return.

The wParam of the message is the reason recognition ended (one of the REC_ codes). It is REC_OK if more results are sent; otherwise, it is the same value for the last message as that returned by Recognize or RecognizeData. The lParam parameter is a far pointer to an RCRESULT structure.

All of the data in the RCRESULT structure is in tablet coordinates.

C:

typedef struct

{

SYG syg;	// Symbol graph.

UINT wResultsType;

// The next three values are filled in by the RC Manager

// and the recognizer.

int cSyv;	// Count of symbols. This is 0 if not able to

// recognize results or no recognition is requested.

LPSYV lpsyv;	// Recognized symbols.  NULL-terminated.

// Count in cSyv does not include NULL.

HANDLE hSyv;	// Global shared handle out of which

// lpSyv was allocated.

int nBaseLine;	// Baseline of input writing.

// 0 if not calculated or unknown.

int nMidLine;	// Midline of input writing.

HPENDATA hpendata;	// pen data memory block

RECT rectBoundInk;	// ink data bounds

POINT pntEnd;	// point which terminated recognition

LPRC lprc;	// Recognition context used.

}

RCRESULT, FAR * LPRCRESULT;	// Recognition result

PASCAL:

type

  PRCResult = ^TRCResult;

  TRCResult = record

    syg: TSYG;

    wResultsType: Word;

    cSyv: Integer;

    lpsyv: PSYV;

    HSyv: THandle;

    nBaseLine: Integer;

    nMidLine: Integer;

    hPenData: THPenData;

    rectBoundInk: TRect;

    pntEnd: TPoint;

    lprc: PRC;

  end;

The following table elaborates on the RCRESULT fields. All of the fields are allocated with GMEM_SHARE so they can be passed between processes.

RCRESULT field	Description
syg	This field contains the raw results returned by the recognizer. These include the various possible interpretations of the pen input, the mapping of the results to the raw data, and locations of any hot spots if the result was a gesture.  The syg.lpsyc field is not valid unles RCP_MAPCHAR was set in the RC structure when Recognize or RecognizeData was called.
wResultsType	The values for this field are listed in the table following. The values can be connected by OR operators. They are not mutually exclusive.
lpsyv	This field contains the symbols that are recognized.  An application should use these values to display the text or gestures recognized.  The lpsyv field is the result of any dictionary search on the SYG or further postprocessing. It is NULL if the NULL recognizer is used.
hpendata	This field contains the raw data captured during inking.
rectBoundInk	This is the bounding rectangle of the ink drawn during recognition. It is in coordinates of the window that receives the results. If the user attempts to draw ink outside rc.rectbound, it will not be displayed. However, rcresult.rectBoundInk will be calculated as if the ink were drawn. If data is collected outside the bounding rectangle, the rectBound field of PENDATAHEADER will reflect this. (Note that only down points are reflected in rectBound.)  However, this means that a portion of rectBoundInk will lie outside the rc.rectBound rectangle. The actual ink drawn lies in the intersection of rectBoundInk and the rc.rectBound rectangle. Before calculating the intersection, convert rectBoundInk from tablet to screen coordinates. The bounding rectangle includes the width of the ink drawn.
pntEnd	If recognition ended on a tap outside the bounding rectangle or inside the exclusive rectangle, pntEnd contains the coordinates of those points in display coordinates.
lprc	This is the RC used by recognition. Any default values (RC_WDEFAULT or RC_LDEFAULT) are replaced by the correct default value.
When the recognizer fills the wResultType variable in the RCRESULT structure, it should choose the appropriate RCRT_ value. The following list is meant to help clarify the options. The recognizer should never have to set RCRT_ALREADYPROCESSED, RCRT_GESTURETOKEYS, or RCRT_GESTURETRANSLATED.

Value	Meaning
RCRT_DEFAULT	The recognition was successful; the RCRESULT structure contains valid information. This typically occurs with text that the recognizer has no problem recognizing. This value can be connected by OR operators to RCRT_GESTURE, RCRT_PRIVATE, and RCRT_UNIDENTIFIED.
RCRT_ALREADYPROCESSED	This flag is set by a hook or the Gesture Manager if the result has already been acted upon. If an application receives a result with this bit already set, it should just erase the ink and perform no other processing. An application-wide hook or the Gesture Manager may set this flag. The Hform sample application demonstrates its use. RCRT_ALREADYPROCESSED can be connected by OR with RCRT_GESTURE, RCRT_NORECOG, RCRT_PRIVATE, and RCRT_UNIDENTIFIED.
RCRT_GESTURE	The result is a gesture symbol. RCRT_GESTURE is not usually combined by OR with anything.
RCRT_GESTURETOKEYS	The Gesture Manager translated the gesture to a set of virtual keys. The keys may represent such things as function or navigation keys.
RCRT_GESTURETRANSLATED	The Gesture Manager translated the gesture to an ANSI text string.
RCRT_NORECOG	Nothing is recognized; the only data in the RCRESULT structure is the raw data in the pen data format. No recognition was attempted. RCRT_NORECOG is not usually combined by OR with anything.
RCRT_NOSYMBOLMATCH	Nothing is recognized. The ink drawn does not match any enabled symbols.
RCRT_PRIVATE	The results have a unique meaning to the recognizer, or they are in a special format. This flag can be connected by OR with RCRT_UNIDENTIFIED.
RCRT_UNIDENTIFIED	The result contains unidentified results.The RCRT_UNIDENTIFIED bit was set, indicating that  some piece of the user's input was not found in the recognizer's database. The RCRESULT structure still contains valid information, but not all of it was recognized. This flag can be connected by OR with RCRT_PRIVATE.


RECTOFS

In addition to having the basic characteristics of an edit control, an hedit or bedit control must make allowances for the input of handwriting. The client rectangle often needs to be adjusted to a larger size to allow for easier writing.

For example, the Delete gesture typically extends above the selected text it is deleting. If the gesture were arbitrarily clipped off at the edge of the client window, recognition accuracy would suffer. Likewise, restricting handwriting input to stay within the lines could also hinder recognition accuracy. To correct this, rectangle offsets are used in the hedit and bedit controls to make the writing area slightly larger than the client window size of a normal edit control. The HE_SETINFLATE and HE_GETINFLATE wParam values of the WM_HEDITCL message are used for this purpose. These messages use a RECTOFS structure as a parameter. The values in the RECTOFS structure are added to the corresponding client area to create the bounding rectangle for the ink.

The inflation does not need to be symmetrical in every direction.

C:

typedef struct

{

int dLeft;

int dTop;

int dRight;

int dBottom;

} RECTOFS;	// Rectangle offsets

RECTOFS FAR * LPRECTOFS;

PASCAL:

type

  PRectOfs = ^TRectOfs;

  TRectOfs = record

    dLeft: Integer;

    dTop: Integer;

    dRight: Integer;

    dBottom: Integer;

  end;


SKBINFO

The SKBINFO structure stores the current on-screen keyboard information. You use it with the ShowKeyboard function.

C:

typedef struct

{

HWND hwnd;	// handle to SKB window

UINT nPad;	// current pad view

BOOL fVisible;	// Visible status

BOOL fMinimized; 	   // Minimized status

RECT rect;	// Restored keyboard rectangle

DWORD dwReserved; 	// Reserved for future use

}

SKBINFO, FAR *LPSKBINFO;

PASCAL:

type

  PSKBInfo = ^TSKBInfo;

  TSKBInfo = record

    handle: HWnd;

    nPad: Word;

    fVisible: Bool;

    fMinimized: Bool;

    hect: TRect;

    dwReserved: Longint;

  end;

The following table describes the SKBINFO structure fields.

Field	Description
hwnd	Handle to the on-screen keyboard window.
nPad	Current view of the keypad (full, basic or numeric pad).
fVisible	If TRUE, the on-screen keyboard is available and visible.
fMinimized	If TRUE, the on-screen keyboard is minimized.
rect	The screen coordinates of the restored keyboard rectangle.


STROKEINFO

The STROKEINFO structure serves two main purposes. First, it is returned by the GetPenHwData and GetPenHwEventData functions with each piece of new data from the tablet. Second, it is used in the pen data functions (AddPointsPenData and GetPenDataStroke) as a header for each stroke. In both cases, it serves to contain information about a sequence of data from the tablet.

C:

typedef struct

{

UINT cPnt;	// Count of points in stroke.

UINT cbPnts;	// Count of bytes used for stroke.

UINT wPdk;	// State of stroke.

DWORD dwTick;	// Time of stroke.

}

STROKEINFO, FAR * LPSTROKEINFO;	// Stroke header.

PASCAL:

type

  PStrokeInfo = ^TStrokeInfo;

  TStrokeInfo = record

    cPnt: Word;

    cbPnts: Word;

    wPDK: Word;

    dwTick: Longint;

  end;

The following table describes the STROKEINFO structure fields.

Field	Description
cPnt	Number of points in the stroke.
cbPnts	Used internally to contain length of compressed data. Applications should ignore this value.
wPdk	Contains information about the state of the stroke. The wPdk field is one or more of the PDK_ bits.
dwTick	Time in milliseconds since the first point in the pen data was collected from the tablet.  If an application is creating its own pen data memory block.and the timing of the stroke is not important, this field should be set to zero for all strokes.


SYG, SYE, SYC, and SYV

Upon completion of recognition, a recognizer returns a symbol graph, an SYG structure as a field of the RCRESULT structure. A symbol graph is a representation of the possible interpretations identified by the recognizer. The RC Manager processes the symbol graph using the dictionary path to identify the best interpretation. This best interpretation is returned in the results message along with the symbol graph.

A symbol value is a 32-bit value which represents a glyph (such as a character or a gesture) recognized by a recognizer. This is sometimes referred to as a symbol. A symbol string is a null-terminated array of symbols.

Each element of the symbol graph, an SYE, contains information about the recognized character -- for example, bounding rectangle and hot spots.

The SYC structure maps SYEs back to the corresponding raw data. If two or more consecutive SYEs map to the same SYC, they represent an indivisible unit; for example, the user teaches the system a "th" with the crossbar of the "t" connected to the "h"). SYCs are used primarily for training.

In general, an application does not use the symbol graph directly. Instead, it should use the lprcresult->hSyv field which contains a symbol string that represents the best interpretation from the symbol graph.

SYEs and SYCs work together with the HPENDATA memory block to identify strokes and meanings for ink. The following table lists the basic functions of these three structures.

Structure	Meaning
HPENDATA	Contains raw data information: strokes, pen up, pen down, points, and so on.
SYC	A symbol character map. SYCs delimit strokes in HPENDATA. A single shape can be identified by one or more SYCs. Each SYC identifies a starting stroke, an ending stroke, a starting point, and an ending point. A flag also indicates whether subsequent SYCs in the array contain additional strokes for the shape.  (This feature is used for delayed strokes, such as "T" crossings.)
SYE	A symbol element. An SYE contains a symbol, which can be a character, gesture, or string. The symbol is denoted by an SYV. The SYE contains an index into an array of SYCs; this array identifies the raw data that makes up the symbol. It is possible for several SYEs to use the same SYCs. The SYCs contain indexes into the raw data.
SYV	A symbol value.
SYG	A symbol graph.
Therefore, a set of SYEs and SYCs, together with an HPENDATA structure, is sufficient to define ink and specify how that ink should be interpreted. The two training functions, TrainContext and TrainInk, use this information in training.

SYE (Symbol Element)

C:

typedef struct

{

SYV syv;	// Symbol value.

LONG lRecogVal;	// Reserved for use by recognizer.

CL cl;	// Confidence level of symbol value.

int iSyc; 	// Either the index into the SYC array

// or iSycNull if no ink is associated

// with the SYE

}

SYE, FAR * LPSYE; 	// Symbol graph element.

PASCAL:

type

  PSYE = ^TSYE;

  TSYE = record

    syv: TSYV;

    lRecogVal: Longint;

    cl: TCL;

    iSyc: Integer;

  end;

SYG (Symbol Graph)

C:

#define MAXHOTSPOT 8

typedef struct

{

POINT rgpntHotSpots[MAXHOTSPOT];	// Hot spots.

int cHotSpot;	// Number of valid hot spots in array.

int nFirstBox;	// If RCO_BOXED set, this contains

// the index to the box of the first

// character in the results. The index is

// in row-major order.

LONG lRecogVal;	// Reserved for use by recognizer.

LPSYE lpsye;	// Nodes of symbol graph.

int cSye;	// Number of SYEs in symbol graph.

LPSYC lpsyc;

int cSyc;

}

SYG, FAR * LPSYG;	// Symbol graph.

PASCAL:

type

  PSYG = ^TSYG;

  TSYG = record

    rgpntHotSpots: array[0..MaxHotSpot-1] of TPoint;

    cHotSpot: Integer;

    nFirstBox: Integer;

    lRecogVal: Longint;

    lpsye: PSYE;

    cSye: Integer;

    lpsyc: PSYC;

    cSyc: Integer;

  end;

If a single entity recognized by the recognizer is mapped to a string of several symbol values, the recognizer creates multiple SYEs. This is the case for recognizers that can recognize highly stylized sequences of characters -- for example, "ing" -- in which the individual characters are not necessarily recognized.

Note

The nFirstBox field has no meaning for gestures. A gestures is applied to the location indicated by its hot spot.

SYC (Symbol Correspondence)

C:

typedef struct

{

UINT wStrokeFirst;	// First stroke, inclusive.

UINT wPntFirst;	// First point in first stroke, inclusive.

UINT wStrokeLast;	// Last stroke, inclusive.

UINT wPntLast;	// Last point in last stroke, inclusive. Set

// to wPntAll for all points.

BOOL fLastSyc;	//TRUE: no more SYCs follow for current SYE.

}

SYC, FAR *LPSYC;

PASCAL:

type

  PSYC = ^TSYC;

  TSYC = record

    wStrokeFirst: Word;

    wPntFirst: Word;

    wStrokeLast: Word;

    wPntLast: Word;

    fLastSyc: Bool;

  end;


ALC_ Values
ALC_Values (Alphabet Code)

rc.alc typedef LONG ALC;	// Alphabet code.

To enable a subset of the active character set, the application can use OR operators with any of the following values and set the result in the alc field of the RC structure. The actual characters enabled depend on the language and the wIntlPreferences specified in the RC structure . For example, if the user has requested French language support, "è" would be included in the lowercase alphabet. Likewise, "£" is included in place of "$" on British systems.

Value	Definition
ALC_ALL	All text written (excludes ALC_USEBITMAP and ALC_RESERVED).
ALC_ALPHA	Alphabetic (both lower and uppercase).
ALC_ALPHANUMERIC	Alphanumeric (letters and numbers).
ALC_DBCS	Returns characters in the double byte encoding (that is, UNICODE).
ALC_DEFAULT	Default value; uses complete set of recognizable characters and gestures. The set of these is defined by the recognizer. It is the set of characters at or above ALC_SYSMINIMUM that the recognizer can accurately distinguish.  If an application sets rc.alc to ALC_DEFAULT, and the recognizer is an alphanumeric system recognizer, it must at least support ALC_SYSMINIMUM as a default. ALC_DEFAULT should be the same character set as the complete character set for the given language minus the ALC_OTHER characters.
ALC_GESTURE	Gesture glyphs.
ALC_HIRAGANA	Enables Hiragana characters.
ALC_KANJI	Enables Kanji characters.
ALC_KATAKANA	Enables Katakana characters.
ALC_LCALPHA	Lowercase alphabetic.
ALC_MATH	The following characters: % ^ * ( ) - + = { } < > , / .
ALC_MONETARY	, (comma), . (period), and  $ (dollar sign). Optionally, the monetary characters can vary according to the recognizer and language setting to include, for example, the  symbols ¢ (cent sign), ¥ (yen sign), and £ (pound sterling).
ALC_NONPRINT	Nonprinting characters: space, tab, return, control characters, glyphs.
ALC_NOPRIORITY	The default value for rc.alcPriority. This value means the application has no preference for one type of symbol over another.
ALC_NUMERIC	0 through 9.
ALC_OEM	Bits reserved for recognizer capabilities specific to the original equipment manufacturer (OEM).
ALC_OTHER	@ # | _  (underline) , ~ (tilde) and square brackets [ ]. That is, all other symbols not included in ALC_ALPHANUMERIC, ALC_MONETARY, ALC_MATH, and ALC_PUNC.
ALC_PUNC	The following characters: \ ! - ; ' " ? ( ) & . , :
ALC_RESERVED	Reserved for future use.
ALC_SYSMINIMUM	Minimum set of characters needed for Roman alphabet system recognizers: ALC_ALPHANUMERIC | ALC_PUNC | ALC_WHITE | ALC_GESTURE.
ALC_UCALPHA	Uppercase alphabetic.
ALC_USEBITMAP	See the explanation following this table.
ALC_WHITE	White space. If this value is not included in the rc.alc field, the recognizer should ignore any white space left between characters. Thus, ALC_WHITE is included in the ALC_DEFAULT. For example, in the zip code field of the Hform sample application, where ALC_NUMERIC | ALC_GESTURE is set, the user does not have to worry about getting any extraneous spaces.
If ALC_USEBITMAP is set, the 256-bit bitfield in rc.rgbfAlc is used to indicate which characters from the ANSI character set are currently enabled. Character 0 is the low bit of the low-order byte in the array. Characters thus indicated are connected by OR operators with any characters enabled, using the other ALC_ codes. A "1" set in a bit array indicates that the character is enabled.

If the character enabled in the rc.rgbfAlc bitfield is a foreign character, you should also specify the language of the character in the rc.lpLanguage field.

For Asian languages other than Japanese, refer to the appropriate subsets within the language: phonetic symbols for words within the language, phonetic symbols for words outside the language, and native pictographs. For example, in Korean, ALC_HANGUEL equals ALC_KATAKANA, and ALC_HANJA equals ALC_KANJI.

For Kanji and other Asian encodings, different effects are possible depending on the state of ALC_DCBS. These effects are described in the following table.

Character in	ALC_DBCS = 0	ALC_DBCS = 1
ALC_HIRAGANA	N/A	0x82a0 - 0x82f2
ALC_KATAKANA	0xa1 - 0xdf	0x8340 - 0x8396
ALC_KANJI	N/A	Kanji character (Shift JIS Level 1 Kanji)
A recognizer will not return a symbol value outside the specified subset. However, a recognizer does not have to force a match to the subset but can instead return "unknown" if a suitable match is not found.

You can set the ALC value for an hedit or bedit control in a dialog by inserting a special string in the .RC file's CONTROL statement. This string is of the form "ALC<xxxx>" where xxxx represents a case-independent hexadecimal ALC code, without any preceding "0x" qualifier. Normal window text may be appended after this ALC entry.

The following code sample is an example of this entry:

CONTROL "ALC<402c>Dollars", IDD_PAID, "hedit", ES_LEFT | ... etc

The ALC<402c> value will be stripped out, and Dollars will be left as window text. In this example, 402c is the hexadecimal equivalent of ALC_NUMERIC | ALC_PUNC | ALC_MONETARY | ALC_GESTURE.

The following example allows only Kanji characters, Katakana characters, and gestures; there is no initial window text specified:

CONTROL "ALC<74000>", IDD_J, "hedit", ES_LEFT | ... etc


BXD_ Values
BXD_Values (Boxed Edit Control)

The BXD_ values define the initial dimensions of the various components of a boxed edit control. These are constants defined in terms of dialog units. They are converted to pixel dimensions by the boxed edit control before use.

The following table lists the BXD_ values.

Constant	Value	Definition
BXD_CELLWIDTH	11	Initial value for cxBox in GUIDE structure after conversion from dialog units to pixels
BXD_CELLHEIGHT	15	Initial value for cyBox in GUIDE structure after conversion from dialog units to pixels
BXD_BASEHEIGHT	12	Initial value for cyBase in GUIDE structure after conversion from dialog units to pixels
BXD_BASEHORZ	0	Initial value for cxBase in GUIDE structure after conversion from dialog units to pixels
BXD_CUSPHEIGHT	2	Initial value for cyCusp in BOXLAYOUT structure after conversion from dialog units to pixels
BXD_ENDCUSPHEIGHT	4	Initial value for cyEndCusp in BOXLAYOUT structure after conversion from dialog units to pixels


HN_ Notification Messages

The parent window of an hedit or bedit window receives the same notification messages (EN_*) as the parent of an edit window. The parent window receives a WM_COMMAND message. The wParam parameter contains the control ID. The lParam parameter contains the edit window handle in its low-order word and the message ID in the high-order word.

The following table lists notification messages specific to hedit and bedit controls.

Notification Message	Meaning
HN_DELAYEDRECOGFAIL	Delayed recognition has failed. The attempted recognition was initiated by an application through an HE_STOPINKMODE message or by the user tapping on a control. See also HE_GETRCRESULTCODE in the table of WM_HEDITCTL messages.
HN_ENDREC	The current recognition context has closed. The call to the recognizer for recognition has terminated.
HN_RCRESULT	The hedit or bedit control has received a WM_RCRESULT message from the recognizer.
HN_RCRESULT is sent within a WM_COMMAND message to the parent application after the dictionary processing of the SYG. Any result returned for HN_RCRESULT by the application is ignored. The application is free to modify the RCRESULT to force an end to the processing or some other action.

The application can retrieve the actual pointer to the RCRESULT using:

lprcr = (LPRCRESULT) SendMessage( hwndHedit, WM_HEDITCTL,

 HE_GETRCRESULT, 0L );

This pointer is valid only during the processing of the HN_RCRESULT message. It is also the actual RCRESULT -- not a copy -- so any changes to it have an effect on the hedit or bedit control.


IDC_ Values
IDC_ Values (Display Cursor)

Any pen display driver must define the following new cursor type.

Name	Value	Description
IDC_PEN	32631	Default pen. Pen points in the northwest compass direction.
IDC_ALTSELECT	32501	Upside-down standard arrow used for tap and hold selection.
You can use the tap and hold cursor with the following code:

HANDLE hPenDLL = GetSystemMetrics( SM_PENWINDOW):

if( hPenDLL )

SetCursor( LoadCursor( hPenDLL, IDC_ALTSELECT));

You can also preload the handle and use it instead of calling LoadCursor every time.


PCM_ Values
PCM_ Values (Pen Collection Mode Values)

Pen collection can be stopped on any of the following conditions set by the
PCM_ values in the lPcm field of the RC structure.

Value	Meaning
PCM_ADDDEFAULTS	If the PCM_ADDDEFAULTS flag is set in rc.lPcm, the values of rc.lPcm are combined with the OR operators to the rcGlobal.Pcm values at the time the recognizer is called.
PCM_INVERT	Stops recognition on pen inversion (a pen tap with the blunt  end of the pen).
PCM_PENUP	Stops when the pen leaves the tablet contact.
PCM_RANGE	Stops when the pen leaves the tablet proximity range.
PCM_RECTBOUND	Stops when the pen is placed down outside the inclusion rectangle. The inclusion rectangle is specified in the rectBound field of the RC structure.
PCM_RECTEXCLUDE	Stops when the pen is placed down inside the exclusion rectangle. The exclusion rectangle is specified in the rectExclude field of the RC structure.
PCM_TIMEOUT	Stops at time-out. The time-out value is specified in the wTimeOut field of the RC structure.


PDC_ Values
PDC_ Values (Pen Device Capabilities)

The following table lists the values for the lPdc field of the PENINFO structure.

Value	Meaning
PDC_BARREL1	Barrel button 1 is present.
PDC_BARREL2	Barrel button 2 is present.
PDC_BARREL3	Barrel button 3 is present.
PDC_INTEGRATED	The display and the digitizer share the same surface.
PDC_INVERT	The pen can detect that the other end of the pen is in contact with the tablet.
PDC_PROXIMITY	The pen position can be detected even when the tip is not in contact with the tablet.
PDC_RANGE	The pen can generate an event when it leaves or enters the proximity range.
PDC_RELATIVE	The pen driver can generate only relative coordinates.


PDK_ Values
PDK_ Values (Pen Driver State Bits)

The pen driver passes along information that the mouse event is being generated by a pen driver and the current state of any barrel buttons. This information is passed along in the wPdk field of the PENPACKET and STROKEINFO structure. The following table lists the PDK_ values.

Constant	Value	Meaning
PDK_BARREL1	0x0002	Set if barrel button 1 is depressed.
PDK_BARREL2	0x0004	Set if barrel button 2 is depressed.
PDK_BARREL3	0x0008	Set if barrel button 3 is depressed.
PDK_DOWN	0x0001	Set if the pen is in contact with the tablet.
PDK_DRIVER	0x8000	Set if generated by a pen driver (as opposed to a mouse driver).
PDK_INVERTED	0x0080	Set if the other end of the pen is being used as the tip.
PDK_OUTOFRANGE	0x4000	Set if the driver detects the pen leaving the range of detection. If set, other information in the packet is invalid.
PDK_TRANSITION	0x0010	Has meaning only if set by GetPenHwData. This bit is set if the first point in the sequence being returned is in a different pen tip state (up or down) from the previous points returned by GetPenHwData. If this bit is set on a call to AddPointsPenData, a new stroke will be created even if the previous call to AddPointsPenData appended points of the same pen state. By default, a contiguous call to AddPointsPenData adding points of the same state as the previous call appends the points to the last stroke instead of creating a new stroke.
Bits 8 through 11 are used to indicate which physical pen generated the event. Pens are numbered starting at 0. Other bits are reserved.


PDT_ Values
PDT_ Values (OEM-Specific Data)

Constant	Value
PDT_NULL	0
PDT_PRESSURE	1
PDT_HEIGHT	2
PDT_ANGLEXY	3
PDT_ANGLEZ	4
PDT_BARRELROTATION	5
PDT_OEMSPECIFIC	16


PDTS_ Values
PDTS_ Values (Data Scaling Values)

Constant	Value
PDTS_ARBITRARY	The application has performed its own scaling of the data point.
PDTS_DISPLAY	Each logical unit is mapped to a display pixel.  Positive x is to the right; positive y is down.
PDTS_HIENGLISH	Each logical unit is mapped to 0.001 inch. Positive x is to the right; positive y is down.
PDTS_HIMETRIC	Each logical unit is mapped to 0.001 mm. Positive x is to the right; positive y is down.
PDTS_LOMETRIC	Each logical unit is mapped to 0.01 mm. Positive x is to the right; positive y is down.
PDTS_STANDARDSCALE	The standard scaling metric is equivalent to PDTS_HIENGLISH.
PDTS_TABLET	The data points are in tablet units.


RCD_ Values
RCD_ Values (Writing Direction)

C:

rc.wRcDirect;

PASCAL:

wRcDirect: Word;

The wRcDirect field informs the recognizer of the direction of writing. There are both primary and secondary directions. For example, English is written from left to right (primary) and then down the page (secondary). Chinese is often written from the top down (primary) and then right to left across the page (secondary).

The high byte of the direction indicates primary direction; the low byte indicates secondary direction. A recognizer can choose to ignore this word and support only the natural direction of the given language. The default value is determined by the recognizer. The following table lists the RCD_ values.

Value	Meaning
RCD_DEFAULT	Default value
RCD_BT	Bottom to top
RCD_LR	Left to right
RCD_RL	Right to left
RCD_TB	Top to bottom
For example, the value for normal English writing direction is defined as follows:

#define wRcDirectRoman  ((RCD_LR<<8) | RCD_TB)


RCO_ Values
RCO_Values (Recognition Option)

C:

rc.lRcOptions;

PASCAL:

lRcOptions: Longint;

Specifies various options for recognition. This field is a logical OR of any of the following values. The following table lists the RCO_ values.

Value	Meaning
RCO_BOXED	Set if the writer is expected to write in boxes and the GUIDE structure contains valid data.
RCO_COLDRECOG	Set in results messages if the result is coming from cold recognition.
RCO_DISABLEGESMAP	Disables gesture mapping during the Recognize function call.
RCO_NOFLASHCURSOR	No flash cursor feedback.
RCO_NOFLASHUNKNOWN	If set in the RC structure and nothing was recognized, the cursor will not momentarily change to the question-mark shape.
RCO_NOHIDECURSOR	If set, doesn't remove cursor while inking.
RCO_NOHOOK	Prevents application-wide and system-wide hooks from being called.
RCO_NOPOINTEREVENT	If set, the RC Manager will not try to recognize a pointer event but passes on all data to the recognizer. This is useful, for example, if the application has installed a shape recognizer so the user can enter dots of ink. If the NULL recognizer is selected into the RC, RCO_NOPOINTEREVENT is assumed to be set.
RCO_NOSPACEBREAK	If set, indicates that the results passed back from the recognizer should be passed on to the dictionaries without breaking at space boundaries.
RCO_SAVEALLDATA	Saves all the pen data in the RCRESULT structure which is generated by the tablet, including any data for pen up and optional data such as pressure. By default, only data used by the recognizer is saved. The recognizer collects all pen data from first to last down stroke, including up strokes in between, and any available OEM data for each stroke.
RCO_SAVEHPENDATA	Saves the pen data. If this is set, the recognizer does not delete the data when the application returns from WM_RCRESULT. It is the application's responsibility to free the pen data.
RCO_SUGGEST	If set, the following actions take place. After all dictionaries have been unsuccessfully searched with strings from the symbol graph, each dictionary is called with DIRQ_SUGGEST to allow the dictionaries to make suggestions. If still no string is identified by a dictionary, the NULL dictionary is used to create a symbol string from the symbol graph.
RCO_TABLETCOORD	If set, indicates that the fields representing coordinate values in the RC structure are in tablet coordinates instead of screen coordinates. This can be used to collect recognition data on the portion of the tablet not mapped to the screen.


RCOR_ Values
RCOR_Values (Tablet Orientation)

C:

rc.wRcOrient;

PASCAL:

wRcOrient: Word;

The wRcOrient field specifies the orientation of the tablet. Orientation should not be confused with direction of writing. Orientation can be useful in a charting program that allows the user to label the vertical axis.

The orientation does not affect the raw data that gets passed back in the RCRESULT structure. Internally to the recognizer, however, the orientation is used to direct the transformation of tablet coordinates to ideal coordinates used for recognition. The following table lists the RCOR_ values.

Constant	X coordinate	Y coordinate
RCOR_NORMAL	X = X'	Y = Y'
RCOR_LEFT	X = yMax - Y'	Y = X'
RCOR_RIGHT	X = Y'	Y = xMax - X'
RCOR_UPSIDEDOWN	X = xMax - X'	Y = yMax - Y'
As with the preceding values, direction is provided as a clue to the recognizer. A recognizer may attempt to identify the direction of writing by itself.


RCP_ Values
RCP_Values (User Preferences)

C:

WORD wRcPreferences;

PASCAL:

wRcPreferences: Word;

The wRcPreferences field specifies the user preferences as a combination of RCP_ constants, as described in the following table.

Constant	Meaning
RCP_LEFTHAND	User writes with left hand.
RCP_MAPCHAR	Tells the recognizer to fill in segmentation information in the lpsyc field. This value cannot be set by the user (there is no Control Panel access to this value). RCP_MAPCHAR is used by the Trainer.


RCRT_ Values
RCRT_Values (Results Type)

C:

rcresult.wResultsType

PASCAL:

wResultsType: Word;

The wResultsType field can contain any of the following values.

Value	Meaning
RCRT_ALREADYPROCESSED	Set by a hook or the Gesture Manager if the result has already been acted upon. If an application receives a result with this bit already set, it should erase the ink and perform no other processing. An application-wide hook or the Gesture Manager can set this flag. The Hform sample application demonstrates its use.
RCRT_GESTURE	Result is a gesture symbol.
RCRT_GESTURETOKEYS	Gesture Manager translated the gesture to a set of virtual keys.
RCRT_GESTURETRANSLATED	Gesture Manager translated the gesture to an ANSI text value.
RCRT_NORECOG	Nothing recognized; only the data is returned. No recognition was attempted.
RCRT_NOSYMBOLMATCH	Nothing recognized. The ink drawn did not match any enabled symbols.
RCRT_PRIVATE	Recognizer-specific symbol recognized.
RCRT_UNIDENTIFIED	Result contained unidentified results.

The code below shows an example of how to use RCRT_ values:

if ((lpr->wResultsType & (RCRT_NOSYMBOLMATCH |

RCRT_ALREADYPROCESSED | RCRT_NORECOG |

RCRT_PRIVATE ) ) == 0 )

{

// A gesture or chracter

if (lpr->wResultsType & RCRT_GESTURE)

{

// Handle Gesture

... code ...

}

else

{

// Character results

... code ...

}

}

else

{

// Handle special cases as necessary.  In general,

// should just ignore.  This is what hedits do.

... code ...

}

}


REC_ Values
REC_ Values (Recognition Functions)

The following return values are used as return values from Recognize, RecognizeData, ProcessWriting, GetPenHwEventData, and GetPenHwData. They are also returned as the wParam value of the WM_RCRESULT message. Return values less than REC_DEBUG are provided for debugging purposes only and represent abnormal termination.

Value	Meaning
REC_OK	This result message to be followed by other results before Recognize terminates. This is a valid wParam value for WM_RCRESULT but it can never be the return value for Recognize.
REC_ABORT	Recognition stopped by a call to EndPenCollection with this value. The lpPnt data is not valid.
REC_BADHPENDATA	Returned if hpendata in lprc cannot be locked or has an invalid header. This value is also returned if hpendata has no data in it or if the data is in an incorrect scale or compressed.
REC_BUFFERTOOSMALL	Returned by GetPenHwEventData.
REC_BUSY	Returned if another task is currently performing recognition.
REC_DONE	Returned by RecognizeData upon normal completion.
REC_NOINPUT	Returned by RecognizeData if the buffer contains no data or returned by Recognize if recognition ended before any data was collected. For example, a pen down occurred outside the bounding rectangle before any data was collected.
REC_NOTABLET	Tablet not physically present.
REC_OOM	Out-of-memory error.
REC_OVERFLOW	Data overflow during execution of the call.
REC_POINTEREVENT	Returned if the user makes contact with the tablet surface and lifts the pen before the pen tip travels a short distance. This value is also returned if the user does a press-and-hold action. That is, the pen makes contact with the tablet and holds the position for a short period of time. REC_POINTEREVENT indicates that the application should begin selection actions rather than inking or recognition. If this is returned no WM_RCRESULT message is generated and no ink will be displayed.
REC_TERMBOUND	Recognition ended because of a hit test outside the bounding rectangle. The rcresult.pntEnd field is filled with the point causing the stop.
REC_TERMEX	Recognition ended because of a hit test inside the exclusion rectangle. The rcresult.pntEnd field is filled with the point causing the stop.
REC_TERMOEM	Values >= 512 reserved for recognizer-specific termination reasons.
REC_TERMPENUP	Recognition ended on pen up. The rcresult.pntEnd field is filled with the pen up point that terminated recognition.
REC_TERMRANGE	Recognition ended because the pen left the proximity range.
REC_TERMTIMEOUT	Recognition ended on time-out. (The pen was up continuously for a given amount of time.)
Debugging Values

All of the values listed in the following table are in the debug version only. No WM_RCRESULT message was generated if these values were returned by Recognize.

Value	Meaning
REC_DEBUG	All debugging return values are less than or equal to this.
REC_ALC	Invalid enabled alphabet.
REC_BADEVENTREF	Returned when the wEventRef field in the lprc structure is invalid.
REC_CLVERIFY	Invalid verification level.
REC_DICT	Invalid dictionary parameters.
REC_ERRORLEVEL	Invalid error level.
REC_GUIDE	Invalid GUIDE structure.
REC_HREC	Invalid recognition handle.
REC_HWND	Invalid handle to window to send results to.
REC_INVALIDREF	Invalid data reference parameter.
REC_LANGUAGE	Returned by the recognizer when the lpLanguage field contains a language that is not supported by the recognizer. Call ConfigRecognizer with the WCR_QUERYLANGUAGE subfunction to determine whether or not a particular language is supported.
REC_NOCOLLECTION	Returned by GetPenHwData if collection mode has not been set.
REC_OEM	Error values below this (below -1024) are specific to the recognizer.
REC_PCM	Invalid lPcm parameter. There is no way for the recognition to end.
REC_RECTBOUND	Invalid rectangle.
REC_RECTEXCLUDE	Invalid rectangle.
REC_RESULTMODE	Unsupported results mode requested.


SYV_ Values
SYV_ Values (Symbol)

C:

typedef LONG SYV;	// Symbol value

Each glyph a recognizer can identify has an associated symbol value. It is this value that is returned to the application by the recognizer.

The high-order and low-order words of a symbol value have the following meanings.

High-order word	Low-order word
0	System symbols.
1	ANSI character code.
2	Gestures.
3	Shift JIS Level 1 (Kanji).
4	Shapes.
5	Unicode.
6	Virtual keys.
7-0x7EFF	Reserved for future use.
0x7F00-0x7FFF	Recognizer-specific symbols.
>=0x8000	Character code for given code page. The low 15 bits of the high-order word indicate the code page.
Recognizers for the European market should return symbol values using ANSI and gesture symbol values. (ANSI is the native character set for Windows in the European market). For the Japanese market, recognizers can use Shift JIS Level 1 and gestures. When writing a recognizer, bear in mind that symbol values outside these ranges cannot be interpreted by all Windows applications.

System Symbol Values

Value	Meaning
SYV_BEGINOR	Begins a list of choices; in this document, displayed as an opening brace character: {
SYV_EMPTY	Empty.
SYV_ENDOR	Ends a list of choices. In this document, displayed as a closing brace character: }
SYV_NULL	NULL terminator.
SYV_OR	Separator for list of choices; in this document, displayed as a vertical bar: |
SYV_SOFTNEWLINE	Translated to a space by the SymbolToCharacter function. When breaking strings into words, DictionarySearch treats SYV_SOFTNEWLINE as a space.
SYV_SPACENULL	Used in a symbol graph to indicate an alternative to a space.
SYV_UNKNOWN	Unrecognized glyph.
Gesture Symbol Values

All system recognizers are expected to recognize a special set of glyphs used as commands.

The Win 3 Equivalent column shows the Windows 3.0 mouse and keyboard equivalents.

Name	Value	Description	Win 3 Equivalent
. . .	00-0x00FF	Command gesture given. The low byte specifies which ANSI character was modified by the command gesture.	Nonstandard (usually CTRL+key)
SYV_BACKSPACE	0x00020008	Deletes character under gesture and sets insertion point.	BACKSPACE
SYV_CLEAR	0x0002FFD5	Clears the selection.	DEL
SYV_CLEARWORD	0x0002FFDD	Deletes word or object under gesture.	Double-click, DEL
SYV_COPY	0x0002FFDA	Copies selection to Clipboard.	CTRL+INS
SYV_CORRECT	0x0002FFDF	Corrects selection or word under gesture.
SYV_CUT	0x0002FFDB	Cuts selection and places on Clipboard.	SHIFT+DEL
SYV_EXTENDSELECT	0x0002FFD8	For linear selection (text), selects all text between current insertion point and point of extend selection gesture. For nonlinear selection (objects), adds object under gesture to selection.	SHIFT+mouse click
SYV_PASTE	0x0002FFDC	Pastes selection at point indicated by hotspot of paste gesture.	Click (place insertion point) followed by SHIFT+INS
SYV_RETURN	0x0002000D	Enters RETURN key.	Click, RETURN
SYV_SPACE	0x00020020	Adds space character.	Click, SPACEBAR
SYV_TAB	0x00020009	Enters TAB.	Click, TAB
SYV_UNDO	0x0002FFD9	Undoes previous action.	ALT+ BACKSPACE
SYV_USER	0x0002FFDE	Any circle gesture.
Circle Gesture Symbol Values

The circle gestures consist of the alphabetic characters surrounded, in each instance, by a circle. The characters may be uppercase or lowercase letters. Gestures can be mapped to specific user actions by means of the Gesture Manager.

The following table lists the SYV_ values for the circle gestures. The intervening values correspond to the letters between "a" and "z":

Constant	Value	Meaning
SYV_CIRCLELOA	0x000224d0	Lowercase "a" circle gesture
SYV_CIRCLELOZ	0x000224e9	Lowercase "z" circle gesture
SYV_CIRCLEUPA	0x000224b6	Uppercase "A" circle gesture
SYV_CIRCLEUPZ	0x000224cf	Uppercase "Z" circle gesture


WM_GLOBALRCCHANGE
WM_GLOBALRCCHANGE Message

Whenever a change is made to the global RC values, the WM_GLOBALRCCHANGE message is sent to all top-level windows. The wParam and lParam values are not used; they are set to zero.

When an application receives a WM_GLOBALRCCHANGE message, it should call ConfigRecognizer with a WCR_RCCHANGE subfunction request for all recognizers the application has loaded (excluding the default recognizer).

Similarly, an application should call DictionaryProc with a DIRQ_RCCHANGE subfunction request for all dictionaries the application has loaded (excluding the default dictionaries).


WM_HEDITCTL Messages

Any control message (EM_*) that can be sent to an edit control can also be sent to an hedit window. Most EM_* control messages are also supported by bedit controls. Refer to the section on bedit for the exceptions. In addition, a single new message, WM_HEDITCTL, has been added for hedit and bedit controls.:

lRet = SendMessage(hwndEdit, WM_HEDITCTL, HE_xxx, lParam);

The message function is indexed by wParam, the values by lParam. The following table gives the different values for wParam and lParam, as well as the return values. All HE_ messages are common to both hedit and bedit controls except as noted. In a bedit control, each cell contains one logical character. In a bedit control, carriage return (CR) and line-feed (LF) bytes together form one logical character.

wParam value	lParam value	Returns (BOOL)
HE_CHAROFFSET (bedit only)	Converts logical character position of a character in the control to byte offset to the character. Both the logical character position and the byte offset are zero-based. The LOWORD contains the logical character position. The HIWORD is reserved and must be set to zero.	If the supplied logical character position is less than the total number of logical characters in the control, the LOWORD of the return value contains the byte offset and the HIWORD is zero. Otherwise, the LOWORD contains the length of text in bytes and the HIWORD contains 0xFFFF.
HE_CHARPOSITION (bedit only)	Converts byte offset in the text buffer of the control to logical character position which contains the byte specified by the byte offset. Both the byte offset and the logical character position are zero-based. The LOWORD contains the byte offset. The HIWORD is reserved and must be set to zero.	If the supplied byte offset is less than the length of the text in bytes, the LOWORD of the return value contains the logical character position and the HIWORD is zero. Otherwise, the LOWORD contains the total number of logical characters in the text of the control and the HIWORD contains 0xFFFF.
HE_DEFAULTFONT (bedit only)	Switches the font of the bedit control to the default font that bedit selects at the time of creation. If the LOWORD of lParam is nonzero, the control is repainted.	Undefined.
HE_GETBOXLAYOUT  (bedit only)	Points to the BOXLAYOUT structure, which is filled with the current BOXLAYOUT for the control.	Undefined.
HE_GETINFLATE	LPRECTOFS  filled with current value.	TRUE if successful.
HE_GETINKHANDLE	Unused.	The LOWORD contains a handle to the captured ink. If NULL, the control is not in ink mode. Applications need to duplicate this handle, because it is no longer valid after the control is destroyed.
HE_GETRC	LPRCPointer to the RC structure to fill with current values.	TRUE if successful.
HE_GETRCRESULT	Unused.	Pointer to an RCRESULT structure received by the control. This message can be sent only during the processing of an HN_RCRESULT notification. Any modifications the application makes to the RCRESULT it receives directly affect the RCRESULT used by the control. The pointer to RCRESULT is valid only during the processing of the HN_RCRESULT notification.
HE_GETRCRESULTCODE	Unused.	Returns the value returned by the last delayed recognition. It can be called only in response to an HN_DELAYEDRECOGFAIL, HN_RCRESULT or HN_ENDREC notification.
HE_GETUNDERLINE (hedit only)	Unused.	TRUE if underline mode is set.
HE_SETBOXLAYOUT  (bedit only)	Points to the BOXLAYOUT structure to be set.	TRUE if successful.
HE_SETINFLATE	LPRECTOFS  specifies the adjustments to the client rectangle of the control window to specify the size of the writing window.	TRUE if successful, FALSE if an invalid window rectangle is specified.
HE_SETINKMODE	Starts the collection of inking. The LOWORD is the initial HPENDATA. It can be NULL. If initial HPENDATA is supplied, it must be relative to the top-left corner of the client rectangle of the control.	TRUE if successful.
HE_SETRC	LPRC pointer to the RC structure to set.	TRUE if successful. For details about the fields ignored or overridden in the RC, see the discussion following this table.
HE_SETUNDERLINE (hedit only)	The LOWORD  is TRUE to set the underline and FALSE to reset it. Note that to use underline mode with hedit controls, the WS_BORDER style bit must be turned off.	The current underline mode.
HE_STOPINKMODE	Stops the collection of ink. If the LOWORD is HEP_RECOG, it performs recognition and displays text. If the LOWORD is HEP_NORECOG (zero), it removes the ink without performing recognition. If the LOWORD is HEP_WAITFORTAP, it performs recognition on the next tap in the control.	TRUE if successful.

Before using HE_SETBOXLAYOUT, HE_SETINFLATE or HE_SETRC wParam values, it is often useful to retrieve the current structure associated with the control use the HE_GETBOXLAYOUT, HE_GETINFLATE or HE_GETRC wParam values. You should then change the fields of interest in the retrieved structure. This reduces the risk of inadvertent changes in the fields of the structure that are not of interest.

Note that, with the HE_SETRC wParam value, certain fields in the RC are overridden or ignored in hedit and bedit controls. For the following fields, values are calculated by the control when necessary; when set by the application with a call to HE_SETRC, however, the values for these fields are ignored:

•	rc.hwnd

•	rc.rectBound

•	rc.wResultMode

•	rc.wEventRef

•	rc.lRcOptions

•	rc.lPcm

With rc.lRcOptions, the RCO_TABLETCOORD is always forced off. If the application sets RCO_SAVEHPENDATA, it must process the HN_RCRESULT to get the result and free the hpendata.

With rc.lPcm, the PCM_RECTBOUND is always set, and PCM_RECTEXCLUDE is always cleared.

In addition, for bedit controls the values set by the user for the following fields are ignored or overridden:

•	rc.guide.xOrigin

•	rc.guide.yOrigin

•	rc.guide.cHorzBox

•	rc.guide.cVertBox

•	rc.lRcOptions

•	rc.wRcOrient

Note that with rc.lRcOptions, RCO_BOXED is always forced on. With rc.wRcOrient, only RCOR_NORMAL is supported.

•	rc.wResultMode

Using the RRM_SYMBOL value for wResultMode in bedit controls disables all default dictionary processing. An application may perform dictionary processing on its own by getting the recognition results during the processing of HN_RCRESULT notification and calling the DictionarySearch function.


WM_RCRESULT Message

The WM_RCRESULT message is generated as a result of a call to ProcessWriting, Recognize, or RecognizeData.

The wParam parameter of the message contains the reason the recognition ended (one of the REC_ codes). It is REC_OK if more results are to be sent; otherwise, it is the same value returned by Recognize or RecognizeData. The lParam parameter is a far pointer to an RCRESULT structure.

If the input consists of multiple lines, nBaseLine and nMidLine in the RCRESULT structure are set to the value for the first line. If the input has a vertical writing direction, the value of nBaseLine represents the left alignment edge.

Any far pointers passed in the RCRESULT structure are valid only while processing the message. This is the application's chance to save the information about the raw data. After this message is sent, the recognizer is free to destroy its copy of the raw data.

The last WM_RCRESULT message for a recognition context is sent before Recognize returns and any other messages are sent to the application.

If the application returns 1, the RC Manager should perform no further processing. If the application returns REC_ABORT, the recognition is ended; no more results will be sent for this context. If the application returns 0, it means the application did not process the RCRESULT message; the RC Manager should perform any further default processing. This distinction is relevant only to ProcessWriting.


WM_SKB Message

The WM_SKB message is posted to all windows when the on-screen keyboard changes (for example, position, visibility, keypad visibility, restored or minimized changes). Clients and other applications can use this message to monitor its state.

The wParam value is SKN_CHANGED and the LOWORD value of lParam is the window handle of the keyboard. The HIWORD of lParam is a combination of one or more of the following values listed below.

Value	Meaning
SKN_MINCHANGED	The on-screen keyboard has been minimized or restored.
SKN_PADCHANGED	The keypad display of the on-screen keyboard has changed.
SKN_POSCHANGED	The position of the on-screen keyboard has changed.
SKN_TERMINATED	The on-screen keyboard has been closed.
SKN_VISCHANGED	The on-screen keyboard has been shown or hidden.