home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / HFORM / HFORM.C_ / HFORM.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  22.0 KB  |  699 lines

  1. /************************************************************
  2.  
  3.     PROGRAM:    HFORM.C
  4.  
  5.     PURPOSE:
  6.     
  7.         A program demonstrating the handwriting edit control
  8.         (Hedit).
  9.  
  10.     COMMENTS:
  11.  
  12.         HFORM has several edit fields, typical of a generic
  13.         form application (name, address, city, etc.).  The
  14.         application registers itself as a pen aware application
  15.         so that the edit controls will be replaced by hedit
  16.         controls.
  17.  
  18.         This application will run under Win 3.0.  When running
  19.         under Win 3.0, the edit control functionality will be
  20.         present.  The boxed edit field and the picture field
  21.         will not be present.
  22.  
  23.         The Delay Recognition menu, when checked, will cause
  24.         ink to be captured in the inking field.  When the
  25.         menu item is unchecked, the first tap in the field
  26.         will cause recognition.  After that, the field will
  27.         behave like a normal HEDIT control.
  28.  
  29.         HFORM has an accelerator gesture (circle-'D') which
  30.         automatically brings up the sample dialog box.
  31.  
  32. ************************************************************/
  33.  
  34. #define WIN31
  35. #include <windows.h>
  36. #include <penwin.h>
  37. #include "hfres.h"
  38. #include "hform.h"
  39.  
  40. #define Unused(x)       x       /* To prevent CS5.1 warning message */
  41.  
  42.  
  43. /* Initialization of globals */
  44.  
  45. char *  szHformClass        = "HformSampleClass";
  46. char *  szHformWnd          = "Hform Sample";
  47. BOOL fDelayRecog = FALSE;  /* Set to true if just capture ink */ 
  48. BOOL fAppwideHookSet;
  49. BOOL fHookIsSet = FALSE;
  50. char *  szHookErr           = "Could not set hook";
  51. HANDLE hPenWin = NULL;
  52. BOOL (FAR PASCAL *SetAppRecogHook)(UINT, UINT, HWND);
  53. HANDLE hAccel;                 /* Menu Accelerator Table */ 
  54. HANDLE hwndMain;               /* Parent window to all fields */ 
  55. #define  cFieldsMax 7
  56. #define  cFormWidth 180    /* In dialog units */ 
  57. #define  cFormHeight 220   /* In dialog units */ 
  58.  
  59. static FIELD rgfield[cFieldsMax] =  
  60.     {
  61.     {"Name:",       6,   8,  44,   8, 128, 10, 0, ALC_DEFAULT, FIELDEDIT, NULL},
  62.     {"Address:",    6,  24,  44,  24, 128, 10, 0, ALC_DEFAULT, FIELDEDIT, NULL},
  63.     {"City:",       6,  40,  44,  40,  84, 10, 0, ALC_DEFAULT, FIELDEDIT, NULL},
  64.     {"Zip:",      132,  40, 147,  40,  25, 10, 0, ALC_NUMERIC | ALC_GESTURE, FIELDEDIT, NULL},
  65.     {"Notes:",      6,  56,  44,  54, 130, 40, WS_BORDER | ES_MULTILINE , ALC_DEFAULT, FIELDEDIT, NULL},
  66.     {"Tel #:",      6, 102,  44,  98, BXD_CELLWIDTH*10+1, BXD_CELLHEIGHT, 0, ALC_NUMERIC | ALC_GESTURE, FIELDBEDIT, NULL},
  67.     {"Directions:", 6, 120,  44, 118, 130, 70, WS_BORDER | ES_MULTILINE, ALC_DEFAULT, FIELDPIC, NULL}
  68.     };
  69.  
  70.  
  71. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  72.                         LPSTR lpszCommandLine, int cmdShow)
  73. /***************************************************************
  74.  
  75. FUNCTION:   WinMain(hInstance, hPrevInstance, lpszCommandLine, cmdShow)
  76.  
  77. PURPOSE:
  78.     
  79.     Main Windows application function.
  80.  
  81. ***************************************************************/
  82.     {
  83.     MSG msg;
  84.     VOID (FAR PASCAL *RegisterPenApp)(UINT, BOOL) = NULL;
  85.  
  86.     Unused(lpszCommandLine); 
  87.     if (!hPrevInstance)
  88.         {
  89.         if (!FInitApp(hInstance))
  90.             {
  91.             return 1;
  92.             }
  93.         }
  94.  
  95.    /* If running on a Pen Windows system, register this app so all
  96.         EDIT controls in dialogs are replaced by HEDIT controls.
  97.         (Notice the CONTROL statement in the RC file is "EDIT",
  98.         RegisterPenApp will automatically change that control to
  99.         an HEDIT. */ 
  100.  
  101.     if ((hPenWin = GetSystemMetrics(SM_PENWINDOWS)) != NULL)
  102.         {
  103.        /* We do this fancy GetProcAddress simply because we don't
  104.             know if we're running Pen Windows. */ 
  105.         if ( ((FARPROC)RegisterPenApp = GetProcAddress(hPenWin, "RegisterPenApp"))!= NULL)
  106.             (*RegisterPenApp)(RPA_DEFAULT, TRUE);
  107.         (FARPROC)SetAppRecogHook = GetProcAddress(hPenWin, "SetRecogHook");
  108.         }
  109.  
  110.     if (FInitInstance(hInstance, hPrevInstance, cmdShow))
  111.         {
  112.         while (GetMessage((LPMSG)&msg,NULL,0,0) )
  113.             {
  114.             /* Check for menu accelerator message */ 
  115.             if (!TranslateAccelerator(hwndMain, hAccel, &msg))
  116.                 {
  117.                 TranslateMessage((LPMSG)&msg);
  118.                 DispatchMessage((LPMSG)&msg);
  119.                 }
  120.             }
  121.         }
  122.     else
  123.         msg.wParam = 0;
  124.  
  125.    /* Unregister this app */ 
  126.     if (RegisterPenApp != NULL)
  127.             (*RegisterPenApp)(RPA_DEFAULT, FALSE);
  128.  
  129.     return msg.wParam;
  130.     }
  131.  
  132.  
  133.  
  134. BOOL NEAR PASCAL FInitApp(HANDLE hInstance)
  135. /***************************************************************
  136.  
  137. FUNCTION:   FInitApp(hInstance)
  138.  
  139. PURPOSE:
  140.     
  141.     Initialize application data and register window class.
  142.     To be called only once.
  143.  
  144.     Returns FALSE if function could not register window class.
  145.     TRUE if successful.
  146.  
  147. ***************************************************************/
  148.     {
  149.     WNDCLASS    wc;
  150.     HCURSOR hcursor;
  151.     
  152.     hcursor = LoadCursor(NULL, IDC_ARROW);
  153.  
  154.     /* Register Main window class */
  155.  
  156.     wc.hCursor = hcursor;
  157.     wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(iconHform));
  158.     wc.lpszMenuName = MAKEINTRESOURCE(menuMain);
  159.     wc.lpszClassName = (LPSTR)szHformClass;
  160.     wc.hbrBackground = (HBRUSH)COLOR_WINDOW+1;
  161.     wc.hInstance = hInstance;
  162.     wc.style = CS_VREDRAW | CS_HREDRAW ;
  163.     wc.lpfnWndProc = HformWndProc;
  164.     wc.cbClsExtra = 0;
  165.     wc.cbWndExtra = 0;
  166.  
  167.     return RegisterClass((LPWNDCLASS) &wc);
  168.     }
  169.  
  170.  
  171. BOOL NEAR PASCAL FInitInstance(HANDLE hInstance, HANDLE hPrevInstance,
  172.                                         int cmdShow)
  173. /***************************************************************
  174.  
  175. FUNCTION:   FInitInstance(hInstance, hPrevInstance, cmdShow)
  176.  
  177. PURPOSE:
  178.     
  179.     Initialize all data structures for program instance and create
  180.     the necessary windows.
  181.  
  182.     Returns TRUE if successsful, FALSE if failed.
  183.  
  184. ***************************************************************/
  185.     {
  186.     int i;
  187.     LONG    lT              = GetDialogBaseUnits();
  188.     int cxDlgBase   = LOWORD(lT);
  189.     int cyDlgBase   = HIWORD(lT);
  190.  
  191.     Unused(hPrevInstance);
  192.  
  193.     /* Convert field coordinates to window coordinates */
  194.  
  195.     for (i = 0; i < cFieldsMax; i++)
  196.         {
  197.         rgfield[i].xStatic = (rgfield[i].xStatic * cxDlgBase)/4;
  198.         rgfield[i].yStatic = (rgfield[i].yStatic * cyDlgBase)/8;
  199.         rgfield[i].xEdit = (rgfield[i].xEdit * cxDlgBase)/4;
  200.         rgfield[i].yEdit = ((rgfield[i].yEdit-(hPenWin ? 0 : 2)) * cyDlgBase)/8;
  201.         rgfield[i].cxEdit = (rgfield[i].cxEdit * cxDlgBase)/4;
  202.         rgfield[i].cyEdit = ((rgfield[i].cyEdit+(hPenWin ? 0 : 2)) * cyDlgBase)/8;
  203.         }
  204.  
  205.     /* Create Main window */
  206.  
  207.     if (hwndMain = CreateWindow((LPSTR)szHformClass, 
  208.         (LPSTR)szHformWnd,    
  209.         WS_CLIPCHILDREN | WS_OVERLAPPED | WS_SYSMENU,
  210.         CW_USEDEFAULT, 0, (cFormWidth*cxDlgBase)/4, (cFormHeight*cyDlgBase)/8,
  211.         (HWND)NULL,
  212.         (HWND)NULL,
  213.         (HANDLE)hInstance,
  214.         (LPSTR)NULL
  215.         ))
  216.  
  217.         {
  218.  
  219.         hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDHFORM));
  220.  
  221.         if (hPenWin && SetAppRecogHook)
  222.             {
  223.            /* Set a hook so our app window can get recognition results
  224.                 before the HEDIT control does.  We do this for an 
  225.                 accelerator gesture. */ 
  226.             if(!(fHookIsSet = (*SetAppRecogHook)(HWR_APPWIDE, HKP_SETHOOK, hwndMain)))
  227.                 {
  228.                 MessageBox(NULL, szHookErr, szHformWnd, MB_ICONSTOP|MB_OK);
  229.                 DestroyWindow(hwndMain);
  230.                 hwndMain = NULL;
  231.                 }
  232.             }
  233.  
  234.         ShowWindow(hwndMain, cmdShow);
  235.         UpdateWindow(hwndMain);
  236.         }
  237.  
  238.    /* If not running under Pen Win, disable delayed recognition option */ 
  239.     if (hwndMain != NULL && !hPenWin)
  240.         EnableMenuItem(GetMenu(hwndMain), miDelayRecog, MF_GRAYED|MF_BYCOMMAND);
  241.  
  242.  
  243.     return hwndMain != NULL;
  244.     }
  245.  
  246.  
  247.  
  248.  
  249.  
  250. LONG FAR PASCAL __export HformWndProc(HWND hwnd, UINT message,
  251.                WPARAM wParam, LPARAM lParam)
  252. /***************************************************************
  253.  
  254. FUNCTION:   HformWndProc(hwnd, message, wParam, lParam)
  255.  
  256. PURPOSE:
  257.     
  258.     Windows procedure for application's parent window.
  259.  
  260. ***************************************************************/
  261.     {
  262.     int     i;
  263.     LONG    lRet    = 0L;
  264.  
  265.     static HWND hwndFocusField = NULL;
  266.  
  267.     switch (message)
  268.         {
  269.         case WM_CREATE:
  270.             /* Create fields */
  271.  
  272.             if (!FCreateForm(hwnd))
  273.                 {
  274.                 lRet = 1L;  /* Failed */
  275.                 break;  
  276.                 }
  277.  
  278.             /* Initialize focus to first edit control */
  279.  
  280.             hwndFocusField = rgfield[0].hwnd;
  281.             SetFocus(hwndFocusField);
  282.             break;
  283.  
  284.         case WM_COMMAND:
  285.             {
  286.             /* Edit control commands */
  287.  
  288.             if (HIWORD(lParam) == EN_SETFOCUS)
  289.                 {
  290.                 /* Field focus is being set */
  291.     
  292.                 hwndFocusField = LOWORD(lParam);
  293.                 break;
  294.                 }
  295.  
  296.             /* Menu commands */
  297.  
  298.             switch (wParam)
  299.                 {
  300.                 case miExit:
  301.                     DestroyWindow(hwnd);
  302.                     break;
  303.  
  304.                 case miClearAll:
  305.                     for (i = 0; i < cFieldsMax; i++)
  306.                         {
  307.                         if (rgfield[i].hwnd != NULL)
  308.                             {
  309.                            /* Clear picture.  Forces edit back into picture mode */ 
  310.                             if (rgfield[i].wFieldType==FIELDPIC && fDelayRecog)
  311.                                 SendMessage(rgfield[i].hwnd, WM_HEDITCTL, HE_SETINKMODE , (LONG)0L);
  312.                             else 
  313.                                 SendMessage(rgfield[i].hwnd, WM_SETTEXT, 0, (LONG)(LPSTR)"");
  314.                             }
  315.                         }
  316.                     SetFocus(rgfield[0].hwnd);
  317.                     break;
  318.  
  319.                 case miSampleDlg:
  320.                     SampleDialog(hwnd);
  321.                     break;
  322.  
  323.                 case miDelayRecog:
  324.                     fDelayRecog = !fDelayRecog;
  325.                     ModifyMenu (GetMenu(hwndMain), miDelayRecog, MF_BYCOMMAND|MF_STRING, miDelayRecog, (LPSTR)(fDelayRecog ? szRecog : szDelay));
  326.                     {
  327.                     SetFocus(rgfield[0].hwnd);
  328.                     for (i = 0; i < cFieldsMax; i++)
  329.                         {
  330.                         if (rgfield[i].hwnd != NULL && rgfield[i].wFieldType==FIELDPIC)
  331.                             {
  332.                             if (fDelayRecog)
  333.                                 {
  334.                                /* Place control in delayed recognition mode */ 
  335.                                 SendMessage(rgfield[i].hwnd, WM_HEDITCTL, HE_SETINKMODE , (LONG)0L);
  336.                                 }
  337.                             else
  338.                                 {
  339.                                /* Send message to hedit to recognize data */ 
  340.                                 SendMessage(rgfield[i].hwnd, WM_HEDITCTL, HE_STOPINKMODE , (LONG)HEP_RECOG);
  341.                                 }
  342.                             }
  343.                         }
  344.                     }
  345.                     break;
  346.  
  347.                 case miNextField:
  348.                    /* Focus on the next field */ 
  349.                     ProcessFieldChange(hwndFocusField, (WORD) chNextField);
  350.                     break;
  351.  
  352.                 case miPrecField:
  353.                    /* Set Focus on the preceeding field */ 
  354.                     ProcessFieldChange(hwndFocusField, (WORD) chPrecField);
  355.                     break;
  356.  
  357.                 default:
  358.                     break;
  359.                 }
  360.             break;
  361.             }
  362.  
  363.         case WM_PAINT:
  364.             {
  365.             PAINTSTRUCT ps;
  366.             HDC         hdc;
  367.  
  368.             hdc = BeginPaint(hwnd, &ps);
  369.             SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  370.             SetBkMode(hdc, TRANSPARENT);
  371.  
  372.             for (i = 0; i < cFieldsMax; i++)
  373.                 {
  374.                 PFIELD pfield = &rgfield[i];
  375.  
  376.                 TextOut(hdc, pfield->xStatic, pfield->yStatic, pfield->szTitle,
  377.                     lstrlen(pfield->szTitle));
  378.                 }
  379.  
  380.             EndPaint(hwnd, &ps);
  381.             break;
  382.             }
  383.         case WM_HOOKRCRESULT:      /* getting recognition results */ 
  384.             {
  385.             LPRCRESULT lpr = (LPRCRESULT)lParam;
  386.             SYV syv;
  387.             WORD wResultsType = lpr->wResultsType;
  388.  
  389.             /* Does this result contain:
  390.              a gesture which has been translated by the gesture mapper
  391.              or an untranslated gesture */
  392.  
  393.             if(wResultsType & (RCRT_GESTURE|RCRT_GESTURETRANSLATED|RCRT_GESTURETOKEYS))
  394.                 {
  395.                 /* Get it from the results returned by the recognizer
  396.                    lpr->lpsyv contains results which could have been
  397.                    translated by the gesture mapper
  398.                    Hence we get the original recognition results */
  399.  
  400.                 syv = lpr->syg.lpsye->syv;
  401.  
  402.                /* This is an example of an accelerator gesture.  The
  403.                     user writes a circle with a 'D' (or 'd') inside,
  404.                     and we look for this gesture.  
  405.  
  406.                     However, if the user through the gesture mapper has mapped
  407.                     circle d to something else, then we don't need to do
  408.                     anything here. */
  409.  
  410.                 if(syv == SyvAppGestureFromLoAnsi('d')
  411.                     || syv == SyvAppGestureFromUpAnsi('D'))
  412.                     {
  413.                     PostMessage(hwnd, WM_COMMAND, miSampleDlg, 0L);
  414.  
  415.                    /* Let target window know result has already been acted upon */ 
  416.  
  417.                     SetAlreadyProcessed(lpr);
  418.  
  419.                     lRet = 1L;
  420.                     }
  421.                 }
  422.             }
  423.             break;
  424.  
  425.         case WM_SETFOCUS:
  426.             SetFocus(hwndFocusField);
  427.             break;
  428.  
  429.         case WM_DESTROY:
  430.             {
  431.             if (hPenWin)
  432.                 {
  433.                 if(SetAppRecogHook && fHookIsSet)
  434.                     (*SetAppRecogHook)(HWR_APPWIDE, HKP_UNHOOK, hwnd);
  435.                 }
  436.  
  437.             PostQuitMessage(0);
  438.             break;
  439.             }
  440.  
  441.         default:
  442.             lRet = DefWindowProc(hwnd, message, wParam, lParam);
  443.             break;
  444.         }
  445.  
  446.     return lRet;
  447.     }
  448.  
  449.  
  450. BOOL NEAR PASCAL FCreateForm(HWND hwndParent)
  451. /***************************************************************
  452.  
  453. FUNCTION:   FCreateForm(hwndParent)
  454.  
  455. PURPOSE:
  456.     
  457.     This function creates the fields.
  458.  
  459.     Returns TRUE is successful, FALSE if field hedit window could
  460.     not be created.
  461.  
  462. ***************************************************************/
  463.     {
  464.     int     i;
  465.     RC  rcin;
  466.     LONG        lT      = GetDialogBaseUnits();
  467.     int     cx      = LOWORD(lT)/2;
  468.     int     cy      = HIWORD(lT)/2;
  469.     RECTOFS rectofs;
  470.  
  471.     for (i = 0; i < cFieldsMax; i++)
  472.         {
  473.         PFIELD pfield = &rgfield[i];
  474.         DWORD dwStyle = WS_VISIBLE | WS_CHILD | (hPenWin ? 0L : WS_BORDER) | pfield->dwEditStyle;
  475.  
  476.         switch (pfield->wFieldType)
  477.             {
  478.         case FIELDPIC:
  479.         case FIELDEDIT:
  480.             /* Create Hedit window. */
  481.             /* If running on a Pen Windows system, this app will have
  482.                 been registered, so all EDIT controls will be changed to
  483.                 HEDIT controls */
  484.  
  485.             pfield->hwnd = CreateWindow(
  486.                     (LPSTR)"edit",
  487.                     (LPSTR)NULL,
  488.                     dwStyle,
  489.                     pfield->xEdit,
  490.                     pfield->yEdit,
  491.                     pfield->cxEdit,
  492.                     pfield->cyEdit,
  493.                     hwndParent, 
  494.                     (HMENU)NULL,
  495.                     GetWindowWord(hwndParent, GWW_HINSTANCE),
  496.                     (LPSTR)NULL);
  497.  
  498.             break;
  499.  
  500.         case FIELDBEDIT:     /* Comb field */ 
  501.             pfield->hwnd = CreateWindow(
  502.                     (LPSTR)(hPenWin ? "bedit" : "edit"),
  503.                     (LPSTR)NULL,
  504.                     dwStyle,
  505.                     pfield->xEdit,
  506.                     pfield->yEdit,
  507.                     pfield->cxEdit,
  508.                     pfield->cyEdit,
  509.                     hwndParent, 
  510.                     (HMENU)NULL,
  511.                     GetWindowWord(hwndParent, GWW_HINSTANCE),
  512.                     (LPSTR)NULL);
  513.             break;
  514.         }
  515.             
  516.         if (!pfield->hwnd)
  517.             {
  518.             continue;
  519.             }
  520.  
  521.         /* Set RC preferences for this edit control */
  522.  
  523.         if (hPenWin)
  524.             {
  525.             if (SendMessage(pfield->hwnd, WM_HEDITCTL, HE_GETRC, (LONG)((LPRC)&rcin)))
  526.                 {
  527.                 rcin.alc = pfield->alc;
  528.                 SendMessage(pfield->hwnd, WM_HEDITCTL, HE_SETRC, (LONG)((LPRC)&rcin));
  529.                 }
  530.  
  531.             /* Change default inflation rectangle offset so it is 
  532.                 half the base dialog unit for each respective axis. */
  533.  
  534.             rectofs.dLeft = -cx;
  535.             rectofs.dTop = -cy;
  536.             rectofs.dRight = cx;
  537.             rectofs.dBottom = cy;
  538.             SendMessage(pfield->hwnd, WM_HEDITCTL, HE_SETINFLATE, (LONG)((LPRECTOFS)&rectofs));
  539.  
  540.            /* If no border, put under line in. */ 
  541.             if ((pfield->dwEditStyle & ES_MULTILINE) == 0 && pfield->wFieldType==FIELDEDIT)
  542.                 SendMessage(pfield->hwnd, WM_HEDITCTL, HE_SETUNDERLINE, (LONG)(1));
  543.             }
  544.  
  545.         }
  546.  
  547.     return TRUE;
  548.     }
  549.  
  550.  
  551. VOID NEAR PASCAL SampleDialog(HWND hwnd)
  552. /***************************************************************
  553.  
  554. FUNCTION:   SampleDialog()
  555.  
  556. PURPOSE:
  557.     
  558.     Brings up a sample dialog containing an EDIT (not HEDIT) control.
  559.     If we're running under Pen Windows system, then RegisterPenApp
  560.     has been called, in which case the EDIT will act like an HEDIT.
  561.  
  562. ***************************************************************/
  563.     {
  564.     FARPROC lpSampleDlg;
  565.     HANDLE hinstance=GetWindowWord(hwnd, GWW_HINSTANCE);
  566.  
  567.     lpSampleDlg = MakeProcInstance((FARPROC) SampleDlgProc, hinstance);
  568.     DialogBox(hinstance, "SampleH", hwnd, lpSampleDlg);
  569.     FreeProcInstance(lpSampleDlg);
  570.     }
  571.  
  572.  
  573. HANDLE FAR PASCAL __export SampleDlgProc(HWND hdlg, WORD message, WORD wParam, LONG lParam)
  574. /***************************************************************
  575.  
  576. FUNCTION:   SampleDlgProc(hdlg, message, wParam, lParam)
  577.  
  578. PURPOSE:
  579.     
  580.     Dialog window procedure.
  581.  
  582. ***************************************************************/
  583.     {
  584.     char szDlgString[cbSzDlgMax];
  585.  
  586.     Unused(lParam);
  587.  
  588.     switch (message)
  589.         {
  590.         case WM_COMMAND:
  591.             {
  592.             switch (wParam)
  593.                 {
  594.             case IDOK:
  595.                     *szDlgString = 0;
  596.                     GetDlgItemText(hdlg, IDC_EDIT, szDlgString, cbSzDlgMax);
  597.                     if (*szDlgString != 0)
  598.                         {
  599.                     EndDialog(hdlg, 1);
  600.                 return TRUE;
  601.                         }
  602.                     break;  /* Don't end dialog with empty box */
  603.  
  604.             case IDCANCEL:
  605.                EndDialog(hdlg, 0);
  606.                     return TRUE;
  607.                 }
  608.             }
  609.             break;
  610.  
  611.       case WM_INITDIALOG:       
  612.         SetDlgItemText(hdlg, IDC_EDIT, "Sample Name");
  613.             /* Set focus to edit field and select all text */
  614.         SetFocus(GetDlgItem(hdlg, IDC_EDIT));
  615.             SendDlgItemMessage(hdlg, IDC_EDIT, EM_SETSEL, 0, MAKELONG(0,-1)); 
  616.         break;
  617.         }
  618.     return FALSE;
  619.     }
  620.  
  621.     
  622. BOOL NEAR PASCAL ProcessFieldChange (HWND hwndFocusField,  WORD wParam) 
  623. /***************************************************************
  624.  
  625. FUNCTION:   ProcessFieldChange (HWND hwndFocusField,  WORD wParam)
  626.  
  627. PURPOSE:
  628.     
  629.     Set the focus on either the next or previous field based on
  630.     the value of wParam. wParam is can be set to chNextField or
  631.     chPrecField.  The hwndFocusField parameter is assigned the value
  632.     of the newly focused field.
  633.  
  634.     Returns TRUE if successful, FALSE otherwise. 
  635.  
  636. ***************************************************************/
  637.     {
  638.     int i, inc, iCount;
  639.     WORD wRet = FALSE;
  640.     LONG lInkData;
  641.     
  642.     if ((wParam != chNextField) && (wParam != chPrecField))
  643.         return FALSE;
  644.  
  645.     inc = wParam == chPrecField ? cFieldsMax-1 : 1;
  646.     i = (IFromHwnd(hwndFocusField)+inc) %(cFieldsMax);
  647.  
  648.  
  649.     /*
  650.         To determine if an hedit is in cold recognition mode, send a GETINKHANDLE
  651.         message to the control. If the loword of the return code is NULL, then the
  652.         control is not in   cold recognition mode, and the focus can be set. If it
  653.         is in cold mode, skip over it and check the next field.
  654.         iCount is used to break the loop if all fields are in cold mode.
  655.     */
  656.  
  657.     iCount=0;
  658.     while (iCount<cFieldsMax && !wRet)
  659.         {
  660.         if (!LOWORD(SendMessage(rgfield[i].hwnd, WM_HEDITCTL, HE_GETINKHANDLE,(LONG)(LPSTR)&lInkData)))
  661.             {
  662.             hwndFocusField = rgfield[i].hwnd;
  663.             SetFocus(hwndFocusField);
  664.             wRet = TRUE;
  665.             }
  666.         else
  667.             i = (i+inc) %(cFieldsMax);       /* Calculate the next field */ 
  668.         iCount++;
  669.         }
  670.  
  671.     return wRet;
  672.     }
  673.  
  674.  
  675.  
  676. int NEAR PASCAL IFromHwnd(HWND hwnd)
  677. /***************************************************************
  678.  
  679. FUNCTION:   IFromHwnd(HWND hwnd)
  680.  
  681. PURPOSE:
  682.     
  683.     Returns the index into the rgfield which corresponds to
  684.     the entry containing parameter hwnd.
  685.  
  686.     Returns 0 if a match is not found.
  687.  
  688. ***************************************************************/
  689.     {
  690.     register int i;
  691.     LPFIELD lpfield;
  692.  
  693.     for (lpfield = rgfield, i = 0; i < cFieldsMax; i++, lpfield++)
  694.         if (lpfield->hwnd == hwnd)
  695.             return i;
  696.  
  697.     return 0;    /* default on err */ 
  698.     }
  699.