| Flow-of-Control During RecognitionLast reviewed: January 5, 1995Article ID: Q75040 | 
| The information in this article applies to: 
 
 SUMMARYThe text below provides an overview of recognition processing in the Microsoft Windows for Pen Computing environment. It discusses the specific steps that occur within an application during recognition, and outlines how each element in the recognition context (RC) structure and RCRESULT structure are set. The first part of the article discusses, in very general terms, the flow-of-control through the system. The second half of the article outlines the flags and variables checked by each component as control passes from the application through the system into the recognizer and back again. This article does not cover the intricacies of hedit or bedit controls; it only outlines what happens within the system when an application makes a call to the InitRC and Recognize functions. This article should be read in conjunction with the "Microsoft Windows for Pen Computing: Programmer's Reference" manual. Note that this article does not discuss the responsibilities of a recognizer or of the dictionary. Each of these components can be replaced; therefore, the actions of these components may vary slightly from one version to another. DISCLAIMER: The information presented in the article was gathered from version 1.0 of the Windows for Pen Computing software. The process outlined in this article is not guaranteed to be the process in any future release. Microsoft provides the information below only for educational purposes and reserves the right to change this process at any time. 
 MORE INFORMATION
 BACKGROUND ASSUMPTIONSThis article uses only the simplest sample code to keep the discussion as general as possible. The sample code discussed in this article is a modification of the Generic sample application provided with the Microsoft Windows Software Development Kit (SDK). Specifically, make the following three additions to the GENERIC.C file: 
 INTRODUCTIONFrom the standpoint of an application, there are three main steps in the recognition process: 
 
 THE SPECIFIC STEPSThe following text treats the three-step process discussed above in more detail. The process is now broken into ten steps: 
 Recognize function, passing in the RC structure that controls the recognition process. 7 through 10. After the application processes the WM_RCRESULT message, there are no additional function calls. Control passes through each of the functions called in steps 1 through 6 during the return process to allow the functions to perform any required housekeeping.The following text discusses each of the ten steps above in depth: 
 The InitRC function copies the global RC structure held by the system into a local variable within the application. This RC structure contains all the information needed to perform recognition. If the user has not modified the global RC structure, the values listed in the following table will be copied into the local RC structure. The values that the user can change using the Control Panel are labeled with the letters "CP" following the description. 
    hrec             = NULL            // Default recognizer; CP
   hwnd             = NULL            // Result window; set by InitRC
   wEventRef        = RC_WDEFAULT     // Eventref; fixed default
   wRcPreferences   = 0               // No RCP flags; CP
   lRcOptions       = 0               // No RCO flags; fixed default
   lpfnYield        = NULL            // Null yield callback
   lpUser           = {0,0}           // Default user; CP
   lpLanguage       = {0,0}           // Default language; CP
   rglpdf           = {LPDFNULL}      // Default dictionary path; CP
   clTryDictionary  = 0               // Default dictionary level; CP
   clErrorLevel     = 0               // Default error level; CP
   alc              = ALC_DEFAULT     // Fixed default
   alcPriority      = ALC_NOPRIORITY
   rgbfAlc          = {0, 0}          // Bit field for enabled characters
   wResultMode      = RRM_COMPLETE    // Fixed default
   wTimeOut         = 1000            // Time Out; CP
   lPcm             = PCM_TIMEOUT     // CP
   rectBound        = {0,0,0,0}       // Bounding rect; set by InitRC
   rectExclude      = {0,0,0,0}       // Exclude rect; fixed default
   guide            = {0,0,0,0,0,0,0,0,0} // Guidelines; fixed default
   wRcOrient        = RCOR_NORMAL     // Text orientation; fixed default
   wRcDirect        = RCD_DEFAULT     // Text direction; fixed default
   bInkWidth        = 1               // Ink width; CP
   rgbInk           = 0L              // Ink color; CP
   dwAppParam       = 0L
   dwDictParam      = 0L
   dwRecognizer     = 0L              // No default
   rgwReserved      = {0,0,0,0,0,0,0,0} // Fixed default
An application can verify the values for each of these variables by
examining the RC structure returned by InitRC.InitRC copies the global RC to a local variable and also initializes a small set of variables to RC_LDEFAULT or RC_WDEFAULT. These two default values instruct the Recognize function to use the current default settings defined in the Control Panel for a given variable. If an application overrides a default setting, the Recognize function will not receive the most current system setting for that value. (NOTE: According to the PENWIN.H header file, the values of RC_WDEFAULT and RC_LDEFAULT are 0xFFFF and 0xFFFFFFFF, respectively. The value for RC_WDEFAULTFLAGS is 0x8000.) The following four steps take place when an application calls InitRC: 
    a. The global RC structure is copied to a local variable.
   b. The hwnd field is set to the value of the hwnd parameter passed in
      to the InitRC function.
   c. The local RC structure is modified as follows:
         lprc->hrec            = RC_WDEFAULT;
         lprc->wRcPreferences  = RC_WDEFAULT;
         lprc->lpUser          = RC_LDEFAULT;
         lprc->lpLanguage      = RC_LDEFAULT;
         lprc->rglpdf          = RC_LDEFAULT;
         lprc->lPcm            = PCM_ADDDEFAULTS;
         lprc->wTryDictionary  = RC_WDEFAULT;
         lprc->clErrorLevel    = RC_WDEFAULT;
         lprc->wTimeOut        = RC_WDEFAULT;
         lprc->nInkWidth       = RC_WDEFAULT;
         lprc->rgbInk          = RC_LDEFAULT;
         lprc->wCountry        = RC_WDEFAULT;
         lprc->wIntlPreferences= RC_WDEFAULTFLAGS;
   d. If the hwnd parameter is not NULL, the client area of he window is
      retrieved, converted the window coordinates to screen coordinates,
      and stored the coordinates in the rectBound field of the RC
      structure. Set the lPcm field to PCM_RECTBOUND.
The logical place for an application to initiate the recognition process is during the processing of the WM_LBUTTONDOWN message. The application calls the Recognize function and passes in the address of the RC structure initialized by InitRC. 
 To control the recognition process, Recognize requires only a pointer to an application-specified RC structure. Upon receiving control, the Recognize function performs the following twenty steps: 
    a. Validates the Guide Structure and returns REC_GUIDE error if it is
      not valid.
   b. Creates a local copy of the RC structure passed to it.
   c. Validates the hwnd field. The REC_HWND error is returned if
      validation fails.
   d. If the RCO_TABLETCOORD flag is not set in the lRcOptions field, and
      the application specifies cold recognition, then Recognize converts
      the values of the rc.rectBound structure, rc.rectExclude structure,
      and rc.Guide structure into tablet coordinates from screen
      coordinates. If the application does not specify cold recognition,
      then Recognize sets only the rectBound and rectExclude structures.
      If the application set the PCM_RECTBOUND flag in the RC structure,
      Recognize creates a clipping rectangle for the rectBound member.
      Similarly, if the application set the PCM_RECTEXCLUDE flag in the RC
      structure, Recognize creates a clipping rectangle for the rectExclude
      member.
   e. Checks the lPcm field for the PCM_ADDDEFAULTS flag. If this flag is
      set, fills the RC structure with the default lPcm values from the
      most current global RC structure.
   f. If the lPcm field does not contain PCM_TIMEOUT, sets the TimeOut
      field to zero. Otherwise, if lPcm is set to RC_WDEFAULT, puts the
      wTimeOut value found in the most current global RC structure in this
      position. If neither flag is set, does not modify the wTimeOut field.
   g. If the wEventRef field is set to RC_WDEFAULT, the Recognize function
      retrieves the "extra" information associated with the most recent
      mouse message from the system.
   h. If Recognize is called from RecognizeData, sets the cold recognition
      flag, RCO_COLDRECOG.
   i. If the RCO_COLDRECOG flag is not set, determines that the pen is or
      is not in contact with the tablet. If the pen is in contact with the
      tablet, then verifies that the RC structure has valid values for
      rectBound and rectExclude, and determines that the point is or is not
      in either the rectBound or rectExclude rectangle.
   j. Checks each of the following fields to see if it contains either
      RC_WDEFAULT or RC_LDEFAULT. If so, Recognize copies the value found
      in the corresponding position in the current global RC structure into
      the local RC structure. At this step, Recognize introduces the
      current values, which are controlled by the Control Panel, into the
      RC structure.
       - nInkWidth
       - rgbInk
       - hrec
       - wRcPreferences
       - wTryDictionary
       - clErrorLevel
       - lpfnYield
       - lpUser
       - lpLanguage
       - rglpdf
       - wCountry
       - wIntlPreferences
   k. Checks for RCO_NOPOINTEREVENT. If pointer events are allowed,
      determines that the pen is acting like a mouse or like a pen. If the
      user "taps" or "presses and holds" the pen, the recognizer returns
      the REC_POINTEREVENT value. Otherwise, the user "presses and moves"
      the pen, which initiates pen functionality.
   l. Verifies that the dynamic-link library (DLL) specified in the hrec
      field exported the RecognizeInternal function. If this call fails,
      Recognize returns the error code REC_HREC.
   m. If the value in the ink width field is greater than zero, initializes
      inking.
   n. Makes an internal call to set up the terminating conditions. Fields
      used in this process include: lPcm, rectBound, and rectExclude. If
      Recognize cannot create a terminating condition, it returns the error
      code REC_PCM.
   o. Puts the pen in collection mode. If the call fails, Recognize returns
      the error code REC_BADEVENTREF.
   p. Turns off Mouse Trails, if enabled.
   q. Checks lRcOptions for the RCO_NOHIDECURSOR flag. If this flag is not
      set, Recognize calls ShowCursor to hide the cursor.
   r. Enables inking.
   s. Removes any mouse messages currently in queue.
   t. Calls the RecognizeInternal function with the RC structure and the
      address of the ResultsFunction.
Most of the work of the recognition process occurs here. This function gathers the raw data, builds the PenData data structure, interprets the raw data, builds the symbol graph, and returns the RCRESULT structure to the ResultsFunction. NOTE: This function is the heart of the recognizer. RecognizeInternal is a replaceable component that may vary slightly between versions. The flags and variables that are typically referenced by the recognizer depend upon the recognizer being used. Therefore, that information is not included here. 
 In the ResultsFunction, the system can make any necessary modifications to the values in the RCRESULT structure before it is returned to the application that called Recognize. This function checks flags, calls the DictionarySearch function, performs any gesture mapping, and then sends the WM_RCRESULT message to the application. The seven specific steps are listed below: 
    a. If the value of the syg.lpsye member of the RCRESULT structure is
      NULL, the ResultsFunction sets the cSyv and lpsyv variables to zero.
      Also, if the syg.lpsye is NULL and hSyv was created by the
      ResultsFunction , then the ResultsFunction sets hSyv to NULL as well.
      Otherwise, the ResultsFunction performs the following three steps:
      1) If the value of syg.hSyv is NULL, allocates memory for the symbol
         array. Otherwise, the ResultsFunction assumes that the recognizer
         has performed dictionary processing.
      2) Calls the DictionarySearch routine. For more information about
         dictionary processing, refer to the "Programmer's Reference"
         manual or search in the Microsoft Knowledge Base on the following
         words:
            prod(penwin) and dictionary
      3) Records the length of the symbol string returned by the
         DictionarySearch function in the cSyv variable. This length does
         not include the NULL that terminates the SYV.
   b. If the following four conditions are met, the ResultsFunction
      calculates the value of the rectBound variable from the PenData
      structure. The ResultsFunction converts this value to client
      coordinates and stores it in the rectBoundInk field.
      1) The results are not generated from cold recognition (the
         RCO_COLDRECOG flags was not set).
      2) The ink width for the data is greater than zero (nInkWidth > 0).
      3) A PenData structure exists (getPenDataHeader returned success).
      4) The PenData structure is not empty.
   c. If RCO_SAVEALLDATA is set and data is present, then the
      ResultsFunction will reallocate the memory with Pen Windows as the
      owner to prevent the memory from being discarded if Pen Windows frees
      the recognizer DLL.
   d. The ResultsFunction checks to see if it must call the gesture mapper.
      If so, it modifies the SYV array in the RCRESULT structure to
      represent the mapped string of characters or key strokes that the
      user defined with the gesture mapper in the Pen Palette. If the
      following two conditions are met, the ResultsFunction calls the
      internal gesture mapper:
      1) The wResultsType field of the RCRESULT structure has the
         RCRT_GESTURE bit set.
      2) If the RCO_DISABLGESMAP bit in the lRcOptions member of the RC
         structure is not set, the gesture mapper maps the gesture into the
         SYG structure in the RCRESULTS structure. If the mapping is
         performed, the gesture mapper sets the RCRT_ALREADYPROCESSED flag
         and either the RCRT_GESTURETOKEYS or RCRT_GESTURETRANSLATED flag,
         depending on type of mapping.
   e. If the RCRT_NOSYMBOLMATCH flag is set in the wResultsType field, and
      the RCO_NOFLASHUNKNOWN flag is not set, the ResultsFunction flashes
      the question mark cursor to inform the user that nothing was
      recognized. If the wResultsType field contains RCRT_GESTURE, the
      application did not disable the cursor flash by setting the
      RCO_NOFLASHCURSOR flag, and lpsyv is not NULL, then if lpsyv points
      to SYV_COPY, the cursor temporarily changes to a COPY cursor to
      indicate that a copy operation is taking place; otherwise, the cursor
      does not change. This step is designed to give the user some visual
      feedback when the system might not otherwise react.
   f. If RCO_NOHOOK is not set in the lRcOptions field, the ResultsFunction
      returns the results to the function that set the hook. An application
      can set a hook by calling the SetRecogHook function.
   g. The system sends the WM_RCRESULT message to the original calling
      application.
When the application receives the WM_RCRESULT message, it can copy anything from the RCRESULT structure into local variables for future reference. The application must copy any data to save it. All memory allocated by the system and the recognizer is freed in the following steps. 
 After the application processes the WM_RCRESULT message, control returns to the ResultsFunction to perform two steps: 
    a. The ResultsFunction checks the wResultsType field to see if the
      RCRT_GESTURETOKEYS flag is set. If so, it passes the gesture-mapped
      key strokes to the system. Otherwise, the ResultsFunction assumes
      that the application either processed the information or does not
      want it processed.
   b. If the handle to the symbol graph, hSyv in the RCRESULT structure, is
      not NULL and belongs to the system, the ResultsFunction frees that
      memory.
At this point, the application has processed the WM_RCRESULT message and copied any information critical to its operations. Perform whatever cleanup is required and return to Recognize. 
 Recognize checks the lRcOptions field. If the RCO_NOHIDECURSOR bit is set, Recognize shows the cursor using ShowCursor and returns control to the application. If Mouse Trails is set (select the Mouse icon in the Control Panel and check the Mouse Trails check box), Recognize reenables the Mouse Trails option. 
 The application completes the processing of the WM_LBUTTONDOWN message. Process the return value from Recognize. NOTE: The application will not receive a WM_LBUTTONUP message after calling Recognize. The system places this message into the message queue of the calling application early in the recognition process to work with Windows. Shortly thereafter, Recognize removes this message from the queue. 
 | 
| Additional reference words: 1.00 
 © 1998 Microsoft Corporation. All rights reserved. Terms of Use. |