home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bde / inventry.pak / ENGINE.C next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  41.6 KB  |  1,229 lines

  1. // BDE - (C) Copyright 1994 by Borland International
  2.  
  3. #include "inventry.h"
  4.  
  5. //======================================================================
  6. //  Name:   DbInit()
  7. //
  8. //  Input:  None.
  9. //
  10. //  Return: DBIERR_NONE if the engine initializes successfully.
  11. //
  12. //  Description:
  13. //          This function starts up the engine.
  14. //======================================================================
  15. DBIResult
  16. DbInit (void)
  17. {
  18.     DBIResult   rslt;   // Return value from IDAPI funcions.
  19.     pCHAR       pszMessage;
  20.     
  21.     // Initialize the engine
  22.     CHKERR(DbiInit(NULL));
  23.  
  24.     // Enable trace info if the debugging layer is enabled.
  25.     DbiDebugLayerOptions(DEBUGON | OUTPUTTOFILE, "INVENTRY.INF");
  26.  
  27.     rslt = DbiSetPrivateDir(szPrivDirectory);
  28.     if (rslt == DBIERR_DIRBUSY)
  29.     {
  30.         pszMessage = (pCHAR)malloc(((DBIMAXMSGLEN * 3) + 1) * sizeof(char));
  31.         if (pszMessage)
  32.         {
  33.             sprintf(pszMessage, "Directory is busy. Make certain no .LCK"
  34.                     " files exist in the %s directory and that the IDAPI"
  35.                     " DLLs are unloaded (Reboot Windows).",
  36.                     szPrivDirectory);
  37.             WinMsg(pszMessage, MB_ICONHAND, MB_OK);
  38.             free(pszMessage);
  39.         }
  40.         return rslt;
  41.     }
  42.  
  43.     CHKERR(rslt);
  44.  
  45.     // Return success of the operation
  46.     //   Note that the CHKERR macro will return from this function
  47.     //   if an error occurs.
  48.     return DBIERR_NONE;
  49. }
  50.  
  51. //======================================================================
  52. //  Name:   DbExit()
  53. //
  54. //  Input:  None.
  55. //
  56. //  Return: DBIERR_NONE if the engine closes successfully.
  57. //
  58. //  Description:
  59. //          This function shuts down the engine.
  60. //======================================================================
  61. DBIResult
  62. DbExit (void)
  63. {
  64.     // Turn off outputting trace information
  65.     DbiDebugLayerOptions(0, NULL);
  66.  
  67.     // Edit IDAPI
  68.     CHKERR(DbiExit());
  69.  
  70.     // Return the success of the operation
  71.     //   Note that the DBIErr macro will return from this function if
  72.     //   an error occurs.
  73.     return DBIERR_NONE;
  74. }
  75.  
  76. //======================================================================
  77. //  Name:   GetTable(phDb, phCur)
  78. //
  79. //  Input:  phDb    - Pointer to a database handle
  80. //          phCur   - Pointer to the cursor handle
  81. //
  82. //  Return: DBIERR_NONE if the database and table open without error.
  83. //
  84. //  Description:
  85. //          This function opens a database and a table.
  86. //======================================================================
  87. DBIResult
  88. GetTable (phDBIDb phDb, phDBICur phCur)
  89. {
  90.     // Open a standard database handle
  91.     CHKERR(DbiOpenDatabase(NULL, NULL, dbiREADWRITE, dbiOPENSHARED,
  92.                            NULL, 0, NULL, NULL, phDb));
  93.  
  94.     // Set the directory for the table handle
  95.     CHKERR(DbiSetDirectory(*phDb, (pCHAR)szTblDirectory));
  96.  
  97.     // Open the table to acquire a cursor on the table.
  98.     CHKERR(DbiOpenTable(*phDb, (pCHAR)szTblName, (pCHAR)szTblType,
  99.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  100.                         xltFIELD, FALSE, NULL, phCur));
  101.  
  102.     // Return the success of opening the table
  103.     //   Note that the DBIErr macro will cause the error value
  104.     //   to be returned to the calling function.
  105.     return DBIERR_NONE;
  106. }
  107.  
  108. //======================================================================
  109. //  Name:   CreateTable(phDb, phCur)
  110. //
  111. //  Input:  phDb    - Pointer to the database handle
  112. ///         phCur   - Pointer to the cursor handle
  113. //
  114. //  Return: DBIERR_NONE if the database and table open without error.
  115. //
  116. //  Description:
  117. //          This function opens a database and creates a table.
  118. //======================================================================
  119. DBIResult
  120. CreateTable (phDBIDb phDb, phDBICur phCur)
  121. {
  122.     CRTblDesc   crTblDsc;           // Table Descriptor
  123.     BOOL        bOverWrite = TRUE;  // Overwrite, yes/no flag
  124.  
  125.     // Set the directory for the database handle
  126.     CHKERR(DbiOpenDatabase(NULL, NULL, dbiREADWRITE, dbiOPENSHARED,
  127.                            NULL, 0, NULL, NULL, phDb));
  128.  
  129.     CHKERR(DbiSetDirectory(*phDb, (pCHAR)szTblDirectory));
  130.  
  131.     // Initialize the table descriptor.
  132.     memset(&crTblDsc, 0, sizeof(CRTblDesc));
  133.     strcpy(crTblDsc.szTblName, szTblName);
  134.     strcpy(crTblDsc.szTblType, szTblType);
  135.     crTblDsc.iFldCount     = uNumFields;
  136.     crTblDsc.pfldDesc      = fldDesc;
  137.     crTblDsc.iIdxCount     = uNumIndexes;
  138.     crTblDsc.pidxDesc      = idxDesc;
  139.     crTblDsc.iValChkCount  = uNumVchks;
  140.     crTblDsc.pvchkDesc     = VchkDesc;
  141.  
  142.     // Fixup the VCHKDesc array before creating the table.
  143.     CreateVchk(uNumFields, uNumVchks, fldDesc, VchkDesc);
  144.  
  145.     CHKERR(DbiCreateTable(*phDb, bOverWrite, &crTblDsc));
  146.  
  147.     // Open the table to acquire a cursor to the newly created table.
  148.     CHKERR(DbiOpenTable(*phDb, (pCHAR)szTblName, (pCHAR)szTblType,
  149.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  150.                         xltFIELD, FALSE, NULL, phCur));
  151.  
  152.     // Return the success of opening the table
  153.     //   Note that the DBIErr macro will return from this function
  154.     //   if an error occurs.
  155.     return DBIERR_NONE;
  156. }
  157.  
  158. //======================================================================
  159. //  Name:   AddRecord(hCur, *pString, Add)
  160. //
  161. //  Input:  hCur    - Handle to the cursor
  162. //          pString - Pointer to a record structure
  163. //          Add     - If TRUE: the record is inserted.
  164. //                    If FALSE: the record pointed to by the cursor
  165. //                              is overwritten by the data in the record
  166. //                              structure.
  167. //
  168. //  Return: DBIERR_NONE if the record was inserted or overwritten
  169. //          successfully.
  170. //
  171. //  Description:
  172. //          This function adds a record to the table pointed at by the
  173. //          cursor.
  174. //======================================================================
  175. DBIResult
  176. AddRecord (hDBICur hCur, RecordType *pString, BOOL Add)
  177. {
  178.     DBIResult   rslt;               // Return value from IDAPI functions
  179.     pBYTE       pRecBuf=NULL;       // Record buffer
  180.     CURProps    TblProps;           // Table Properties
  181.     UINT16      j=1;                // Field loop counter
  182.     DATE        date;               // Date
  183.     INT16       ItemId;             // Item Id
  184.     FLOAT       In_Stock;           // Items in stock
  185.     FLOAT       Cost;               // Cost of the item
  186.  
  187.     // Get the properties of the cursor: size of the record is what is
  188.     //   needed in this case.
  189.     CHKERR_CLEANUP(DbiGetCursorProps(hCur, &TblProps));
  190.  
  191.     // Allocate memory for the record.
  192.     if((pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize))== NULL)
  193.     {
  194.         WinMsg("You have run out of memory!", MB_ICONHAND, MB_OK);
  195.         CLEANUP(DBIERR_NOMEMORY);
  196.     }
  197.  
  198.     if(!Add)
  199.     {
  200.         // Get the record.
  201.         CHKERR_CLEANUP(DbiGetRecord(hCur, dbiWRITELOCK, pRecBuf, NULL));
  202.     }
  203.     else
  204.     {
  205.         // Make sure we're starting with a clean record buffer.
  206.         CHKERR_CLEANUP(DbiInitRecord(hCur, pRecBuf));
  207.     }
  208.  
  209.     // Fill each field with the structure's data.
  210.     ItemId = atoi(pString->ItemId);
  211.     CHKERR_CLEANUP(DbiPutField(hCur, j++, pRecBuf, (pBYTE)&ItemId));
  212.     CHKERR_CLEANUP(DbiPutField(hCur, j++, pRecBuf,
  213.                    (pBYTE)pString->Building));
  214.     CHKERR_CLEANUP(DbiPutField(hCur, j++, pRecBuf, (pBYTE)pString->Item));
  215.     In_Stock = atof(pString->In_Stock);
  216.     CHKERR_CLEANUP(DbiPutField(hCur, j++, pRecBuf, (pBYTE)&In_Stock));
  217.     Cost = atof(pString->Cost);
  218.     CHKERR_CLEANUP(DbiPutField(hCur, j++, pRecBuf, (pBYTE)&Cost));
  219.  
  220.     // Only write date if items are on order.
  221.     if (strcmpi(pString->DateD, szNoneOnOrder))
  222.     {
  223.         // Set the date by parsing the date string found in the record
  224.         //   structure.
  225.         SetDate(&date, pString->DateD);
  226.  
  227.         // Put the date into the record buffer.
  228.         CHKERR_CLEANUP(DbiPutField(hCur, j++, pRecBuf, (pBYTE)&date));
  229.     }
  230.     else
  231.     {
  232.         j++; // Increment field counter.
  233.     }
  234.  
  235.     // Open the BLOb.  You must open a blob before you can read or
  236.     //   write a BLOb.
  237.     CHKERR_CLEANUP(DbiOpenBlob(hCur, pRecBuf, j, dbiREADWRITE));
  238.  
  239.     // Put the BLOb into the record buffer.  We need to add one for
  240.     //   the NULL termination used in the string.
  241.     CHKERR_CLEANUP(DbiPutBlob(hCur, pRecBuf, j, 0,
  242.                               (UINT32)strlen(pString->Message) + 1,
  243.                               (pBYTE)pString->Message));
  244.  
  245.     // If Add then insert the record.
  246.     if(Add)
  247.     {
  248.         // Insert the record.
  249.         rslt = DbiInsertRecord(hCur, dbiWRITELOCK, pRecBuf);
  250.         if(rslt == DBIERR_NONE)
  251.         {
  252.             // Release the record lock.  
  253.             CHKERR_CLEANUP(DbiRelRecordLock(hCur, FALSE));
  254.         }
  255.         else
  256.         {
  257.             // Release the record lock.  
  258.             DbiRelRecordLock(hCur, FALSE);
  259.             if (rslt == DBIERR_KEYVIOL)
  260.             {
  261.                 WinMsg("Cannot add a duplicate record", MB_ICONHAND, MB_OK);
  262.                 CLEANUP(rslt);
  263.             }
  264.             CHKERR_CLEANUP(rslt);
  265.         }
  266.     }
  267.  
  268.     // Otherwise we are going to overwrite the record.
  269.     else
  270.     {
  271.         // Overwrite the record, and release the lock once we have
  272.         //   modified the record.
  273.         rslt = DbiModifyRecord(hCur, pRecBuf, TRUE);
  274.         if(rslt != DBIERR_NONE)
  275.         {
  276.             // Release the record lock.  
  277.             DbiRelRecordLock(hCur, FALSE);
  278.             CHKERR_CLEANUP(rslt);
  279.         }
  280.     }
  281.  
  282.     // NOW YOU MUST FREE the blob.
  283.     CHKERR_CLEANUP(DbiFreeBlob(hCur, pRecBuf, j));
  284.     free(pRecBuf);
  285.  
  286.     // Return the success of the operation
  287.     //   Note that the DBIErr macro will return from this function
  288.     //   if an error occurs.
  289.     return DBIERR_NONE;
  290.  
  291. CleanUp:
  292.     if(pRecBuf)
  293.     {
  294.         free(pRecBuf);
  295.     }
  296.     DbiFreeBlob(hCur, pRecBuf, j);
  297.     return GlobalDBIErr;
  298. }
  299.  
  300. //======================================================================
  301. //  Name:   SetDate(Date, pString)
  302. //
  303. //  Input:  Date    - Date to set
  304. //          pString - Date in MM/DD/YY form
  305. //
  306. //  Return: DBIERR_NONE if the string holds a valid date..
  307. //
  308. //  Description:
  309. //          This function puts the date that is in the pString into the
  310. //          Date variable.
  311. //======================================================================
  312. DBIResult
  313. SetDate (pDATE Date, pCHAR pString)
  314. {
  315.     UINT16      uMonth;     // Month portion of the date
  316.     UINT16      uDay;       // Day portion of the date
  317.     UINT16      uYear;      // Year portion of the date
  318.     char        cMonth[3];  // Used in formatting string
  319.     char        cDay[3];    // Used in formatting string
  320.     char        cYear[5];   // Used in foramtting string
  321.  
  322.     // Get the first two month's numbers (the first two numbers).
  323.     strncpy(cMonth, pString, 2);
  324.     cMonth[2] = 0;
  325.     uMonth = atoi(cMonth);
  326.  
  327.     // Skip the separator.
  328.     strncpy(cDay, pString + 3, 2);
  329.     cDay[2] = 0;
  330.     uDay = atoi(cDay);
  331.  
  332.     // Skip second separator.
  333.     strncpy(cYear, pString + 6, 4);
  334.     uYear = atoi(cYear);
  335.  
  336.     if ((uMonth != 0) && (uDay != 0) && (uYear != 0))
  337.     {
  338.         CHKERR(DbiDateEncode(uMonth, uDay, uYear, Date));
  339.     }
  340.     else
  341.     {
  342.         Date = 0;
  343.     }
  344.  
  345.     // Return the success of the operation
  346.     //   Note that the DBIErr macro will return from this function
  347.     //   if an error occurs.
  348.     return DBIERR_NONE;
  349. }
  350.  
  351. //======================================================================
  352. //  Name:   GetData(hCur, *pRecord)
  353. //
  354. //  Input:  hCur    - Handle to the cursor
  355. //          pRecord - Record buffer
  356. //
  357. //  Return: DBIERR_NONE if the record buffer is allocated and the data
  358. //          is read successfully.
  359. //
  360. //  Description:
  361. //          This function gets the data pointed to by hCur and puts it
  362. //          into the record structure.
  363. //======================================================================
  364. DBIResult
  365. GetData (hDBICur hCur, RecordType *pRecord)
  366. {
  367.     DBIResult   rslt;           // Return value from IDAPI functions
  368.     CURProps    TblProps;       // Properties of the table
  369.     pBYTE       pRecBuf = NULL; // Buffer to contain the record
  370.  
  371.     // Get the properties of the table so that we can create the correct
  372.     //   buffer size for the record.  We will read the record into the
  373.     //   buffer and then we will pull the field from the buffer.
  374.     CHKERR_CLEANUP(DbiGetCursorProps(hCur,&TblProps));
  375.  
  376.     // Create the record buffer.  The size comes from the proporty
  377.     //   recsize.
  378.     if((pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize))==NULL)
  379.     {
  380.         CLEANUP(DBIERR_NOMEMORY);
  381.     }
  382.  
  383.     // Initialize the record buffer.
  384.     CHKERR_CLEANUP(DbiInitRecord(hCur, pRecBuf));
  385.  
  386.     // Get the current reocord with a READLOCK.
  387.     rslt = DbiGetRecord(hCur, dbiREADLOCK, pRecBuf, 0);
  388.  
  389.     // If there was no current rec, get the current rec.
  390.     if (rslt == DBIERR_NONE)
  391.     {
  392.         // Fill the structure with the present record pointed to by hCur.
  393.         CHKERR_NODISPLAY(FillRec(hCur, pRecBuf, pRecord));
  394.         // Now free the record lock on this record ONLY.
  395.         CHKERR_CLEANUP(DbiRelRecordLock(hCur, FALSE));
  396.     }
  397.     else
  398.     {
  399.         // Check if the table is empty.
  400.         if(!(AtBOF(hCur) && AtEOF(hCur)))
  401.         {
  402.             CHKERR_CLEANUP(rslt);
  403.         }
  404.     }
  405.  
  406.     free(pRecBuf);
  407.  
  408.     // Return the success of the operation
  409.     //   Note that the DBIErr macro will return from this function
  410.     //   if an error occurs.
  411.     return DBIERR_NONE;
  412.  
  413. CleanUp:
  414.     if(pRecBuf)
  415.     {
  416.         free(pRecBuf);
  417.     }
  418.     return GlobalDBIErr;
  419. }
  420.  
  421. //======================================================================
  422. //  Name:   FillRec(hCur, pRecBuf, *pString)
  423. //
  424. //  Input:  hCur    - Handle to the cursor
  425. //          pRecBuf - Record buffer
  426. //          pString - Where to store data from the table
  427. //
  428. //  Return: DBIERR_NONE if the database and table open without error.
  429. //
  430. //  Description:
  431. //          This function adds a record to the table pointed at by the
  432. //          cursor.
  433. //======================================================================
  434. DBIResult
  435. FillRec (hDBICur hCur, pBYTE pRecBuf, RecordType *pString)
  436. {
  437.     UINT16      j=1;                    // Field counter
  438.     UINT16      uDay;                   // Day part of the date
  439.     UINT16      uMonth;                 // Month part of the date
  440.     INT16       iYear;                  // Year part of the date
  441.     UINT32      uActual;                // Total amount read from blob
  442.     UINT32      BlobSize;               // Size of blob
  443.     BOOL        bEmpty;                 // Is field empty variable
  444.     CHAR        szTemp[FLDLENGTH] ="";  // Temporary variable for reading
  445.                                         //   data
  446.  
  447.     INT16       ItemId;                 // Item ID
  448.     FLOAT       In_Stock;               // Number in Stock
  449.     FLOAT       Cost;                   // Cost of the item
  450.  
  451.     // Get each field from the table and place into the data structure
  452.     CHKERR(DbiGetField(hCur, j++, pRecBuf, (pBYTE)&ItemId, &bEmpty));
  453.     sprintf(pString->ItemId, "%d", ItemId);
  454.     CHKERR(DbiGetField(hCur, j++, pRecBuf, (pBYTE)pString->Building,
  455.                        &bEmpty));
  456.     CHKERR(DbiGetField(hCur, j++, pRecBuf, (pBYTE)pString->Item,
  457.                        &bEmpty));
  458.     CHKERR(DbiGetField(hCur, j++, pRecBuf, (pBYTE)&In_Stock, &bEmpty));
  459.     sprintf(pString->In_Stock, "%.0lf", In_Stock);
  460.     CHKERR(DbiGetField(hCur, j++, pRecBuf, (pBYTE)&Cost, &bEmpty));
  461.     sprintf(pString->Cost, "%.2lf", Cost);
  462.  
  463.     CHKERR(DbiGetField(hCur, j++, pRecBuf, (pBYTE)szTemp, &bEmpty));
  464.  
  465.     // Check if any items are on order.
  466.     if ((bEmpty) || !strcmp(szTemp, ""))
  467.     {
  468.         strcpy(pString->DateD, szNoneOnOrder);
  469.     }
  470.     else
  471.     {
  472.         CHKERR(DbiDateDecode(*(DATE *)szTemp, &uMonth, &uDay, &iYear));
  473.         // Format the date to MM\DD\YYYY format.
  474.         wsprintf(pString->DateD, "%02u-%02u-%02u", uMonth, uDay, iYear);
  475.     }
  476.  
  477.     CHKERR(DbiOpenBlob(hCur, pRecBuf, j, dbiREADWRITE));
  478.  
  479.     // Get the size of the blob so that you can allocate the
  480.     //   correct amount of memory.  The BlobSize variable is a UINT32.
  481.     CHKERR(DbiGetBlobSize(hCur, pRecBuf, j, &BlobSize));
  482.  
  483.     CHKERR(DbiGetBlob(hCur, pRecBuf, j, 0, BlobSize,
  484.                      (pBYTE)pString->Message, &uActual));
  485.  
  486.     CHKERR(DbiFreeBlob(hCur, pRecBuf, j));
  487.  
  488.     // Return the success of the operation
  489.     //   Note that the DBIErr macro will return from this function
  490.     //   if an error occurs.
  491.     return DBIERR_NONE;
  492. }
  493.  
  494. //======================================================================
  495. //  Name:   GoBottom(hCur, MoveRec)
  496. //
  497. //  Input:  hCur        - Handle to the Cursor
  498. //          MoveRec     - Select last item in the table?
  499. //
  500. //  Return: DBIERR_NONE if DbiSetToEnd is successful.
  501. //
  502. //  Description:
  503. //          This function moves to the bottom of the table, and moves one
  504. //          record back if MoveRec (BOOL) is TRUE.
  505. //======================================================================
  506. DBIResult
  507. GoBottom (hDBICur hCur, BOOL MoveRec)
  508. {
  509.     DBIResult   rslt;   // Return value from IDAPI functions
  510.     
  511.     rslt = CHKERR(DbiSetToEnd(hCur));
  512.     if ((MoveRec) && (rslt == DBIERR_NONE))
  513.     {
  514.         rslt = GetPrevRec(hCur);
  515.     }
  516.     return rslt;
  517. }
  518.  
  519. //======================================================================
  520. //  Name:   GoTop(hCur, MoveRec)
  521. //
  522. //  Input:  hCur        - Handle to the Cursor
  523. //          MoveRec     - Select the first record in the table
  524. //
  525. //  Return: DBIERR_NONE if DbiSetToBegin is successful.
  526. //
  527. //  Description:
  528. //          This function moves to the top of the table, and moves one
  529. //          record forward if MoveRec (BOOL) is TRUE.
  530. //======================================================================
  531. DBIResult
  532. GoTop (hDBICur hCur, BOOL MoveRec)
  533. {
  534.     DBIResult   rslt;   // Return value from IDAPI functions
  535.  
  536.     rslt = CHKERR(DbiSetToBegin(hCur));
  537.     if ((MoveRec) && rslt == DBIERR_NONE)
  538.     {
  539.         rslt = GetNextRec(hCur);
  540.     }
  541.     return rslt;
  542. }
  543.  
  544. //======================================================================
  545. //  Name:   GetNextRec(hCur)
  546. //
  547. //  Input:  hCur    - Handle to the cursor.
  548. //
  549. //  Return: DBIERR_NONE if DbiGetNextRecord is successful.
  550. //
  551. //  Description:
  552. //          This function moves one record forward.
  553. //======================================================================
  554. DBIResult
  555. GetNextRec (hDBICur hCur)
  556. {
  557.     DBIResult rslt;
  558.  
  559.     rslt = DbiGetNextRecord(hCur, dbiNOLOCK, NULL, 0);
  560.  
  561.     return rslt;
  562. }
  563.  
  564. //======================================================================
  565. //  Name:   GetPrevRec(hCur)
  566. //
  567. //  Input:  hCur    - Handle to the cursor.
  568. //
  569. //  Return: DBIERR_NONE if DbiGetPrevRec is successful.
  570. //
  571. //  Description:
  572. //          This function moves one record backwards.
  573. //======================================================================
  574. DBIResult
  575. GetPrevRec (hDBICur hCur)
  576. {
  577.     DBIResult rslt;
  578.     rslt = DbiGetPriorRecord(hCur, dbiNOLOCK, NULL, 0);
  579.     return rslt;
  580. }
  581.  
  582. //======================================================================
  583. //  Name:   AtEOF(hCur)
  584. //
  585. //  Input:  hCur        - Handle to the cursor
  586. //
  587. //  Return: TRUE:   If the cursor is at the End Of File (EOF).
  588. //          FALSE:  If the cursor is not at the EOF.
  589. //
  590. //  Description:
  591. //          This function moves one record forward to test if the cursor
  592. //          is at the EOF, and then moves back to put the cursor at the
  593. //          place it was before the start of this function.
  594. //======================================================================
  595. BOOL
  596. AtEOF (hDBICur hCur)
  597. {
  598.     DBIResult   rslt;       // Return value from IDAPI functions
  599.     BOOL        RetVal;     // At EOF? True/False
  600.  
  601.     // Check if we are at the end of the table.
  602.     rslt = DbiGetNextRecord(hCur, dbiNOLOCK, NULL, 0);
  603.     if(rslt == DBIERR_EOF)
  604.     {
  605.         RetVal = TRUE;
  606.     }
  607.     else
  608.     {
  609.         RetVal = FALSE;
  610.     }
  611.  
  612.     // Put the cursor back to where it was before entering this function.
  613.     DbiGetPriorRecord(hCur, dbiNOLOCK, NULL, 0);
  614.  
  615.     return RetVal;
  616. }
  617.  
  618. //======================================================================
  619. //  Name:   AtBOF(hCur)
  620. //
  621. //  Input:  hCur        - Handle to the cursor 
  622. //
  623. //  Return: TRUE:   If the cursor is at the Beginning Of File (BOF).
  624. //          FALSE:  If the cursor is not at the BOF.
  625. //
  626. //  Description:
  627. //          This function moves one record backwards to test if the cursor
  628. //          is at the BOF.  Then it moves the cursor one record forward to
  629. //          put it back to where it was originally.
  630. //======================================================================
  631. BOOL
  632. AtBOF (hDBICur hCur)
  633. {
  634.     DBIResult   rslt;   // Return value from IDAPI functions
  635.     BOOL        RetVal; // At BOF? True/False
  636.  
  637.     // Check if we are at the end of the table.
  638.     rslt = DbiGetPriorRecord(hCur, dbiNOLOCK, NULL, 0);
  639.     if(rslt == DBIERR_BOF)
  640.     {
  641.         RetVal = TRUE;
  642.     }
  643.     else
  644.     {
  645.         RetVal = FALSE;
  646.     }
  647.     // Put the cursor back to where it was before entering this function.
  648.     DbiGetNextRecord(hCur, dbiNOLOCK, NULL, 0);
  649.  
  650.     return RetVal;
  651. }
  652.  
  653. //======================================================================
  654. //  Name:   CloseDb(phDb)
  655. //
  656. //  Input:  phDb        - Pointer to the Database Handle
  657. //
  658. //  Return: DBIERR_NONE if the table closed successfully.
  659. //
  660. //  Description:
  661. //          This function closes the table based upon the table pointer
  662. //          that was passed into the function.
  663. //======================================================================
  664. DBIResult
  665. CloseDb (phDBIDb phDb)
  666. {
  667.     // Close the database
  668.     CHKERR(DbiCloseDatabase(phDb));
  669.     
  670.     // Return the success of the operation
  671.     //   Note that the DBIErr macro will return from this function
  672.     //   if an error occurs.
  673.     return DBIERR_NONE;
  674. }
  675.  
  676. //======================================================================
  677. //  Name:   SetupIndex(phCur, IndexNum)
  678. //
  679. //  Input:  phCur       - Pointer to the cursor handle
  680. //          IndexNum    - Which index
  681. //
  682. //  Return: DBIERR_NONE if the index descriptor memory is allocated and if
  683. //          the index switch was successful.
  684. //
  685. //  Description:
  686. //          This function switches to an index based upon the index array
  687. //          that is used to create the table, and the IndexNum that is
  688. //          passed into the function.  The IndexNum corresponds to an
  689. //          element in the array.
  690. //======================================================================
  691. DBIResult
  692. SetupIndex (phDBICur phCur, UINT16 IndexNum)
  693. {
  694.     // Switch indexes - note that Paradox tables cannot switch to the
  695.     //   primary index by name, so must use the index Id, which
  696.     //   is allways 0 for the primary index. The name of secondary indexes
  697.     //   is used because the index Id of secondary indexes can change.
  698.     if (!IndexNum)
  699.     {
  700.         CHKERR(DbiSwitchToIndex(phCur, NULL, NULL, IndexNum,
  701.                                 TRUE));
  702.     }
  703.     else
  704.     {
  705.         CHKERR(DbiSwitchToIndex(phCur, idxDesc[IndexNum].szName,
  706.                                 NULL, TRUE, TRUE));
  707.     }
  708.  
  709.     // Return the success of the operation
  710.     //   Note that the DBIErr macro will return from this function
  711.     //   if an error occurs.
  712.     return DBIERR_NONE;
  713. }
  714.  
  715. //======================================================================
  716. //  Name:   SetIndex(phCur, IndexNum)
  717. //
  718. //  Input:  phCur       - Pointer to the cursor handle
  719. //          IndexNum    - Which index
  720. //
  721. //  Return: DBIERR_NONE if SetupIndex was successful.
  722. //
  723. //  Description:
  724. //          This function runs SetupIndex and moves the new cursor to the
  725. //          first record in the table.
  726. //======================================================================
  727. DBIResult
  728. SetIndex (phDBICur phCur, UINT16 uNum)
  729. {
  730.     DBIResult rslt;     // Return value from IDAPI functions
  731.  
  732.     // Move to the top of the table and move forward one record past the
  733.     //   crack.
  734.     GoTop(*phCur, TRUE);
  735.     SetupIndex(phCur, uNum);
  736.  
  737.     // Again move to the first record of the table so that the first
  738.     //   record is displayed when the dialog box is displayed.
  739.     rslt = GoTop(*phCur, TRUE);
  740.     return rslt;
  741. }
  742.  
  743. //======================================================================
  744. //  Name:   GetIndexNum(hCur)
  745. //
  746. //  Input:  hCur        - Handle to the cursor 
  747. //
  748. //  Return: The present index number based upon the index array (UINT16).
  749. //
  750. //  Description:
  751. //          This function returns the index number that corresponds to
  752. //          the index found in the index array (idxDesc).
  753. //======================================================================
  754. UINT16
  755. GetIndexNum (hDBICur hCur)
  756. {
  757.     UINT16      i=0;
  758.     INT16       uNum=500;       // set it to a value it can never reach.
  759.     pIDXDesc    MyDesc = NULL;  // Index Descriptor.
  760.  
  761.     if ((MyDesc = (pIDXDesc)malloc(sizeof(IDXDesc) * 1)) == NULL)
  762.     {
  763.         CLEANUP(DBIERR_NOMEMORY);
  764.     }
  765.  
  766.     // Get information about the current indexe
  767.     CHKERR_CLEANUP(DbiGetIndexDesc(hCur, 0, MyDesc));
  768.  
  769.     // Check if the primary index is the current index - primary index
  770.     //   does not have a name.
  771.     if (MyDesc->iIndexId == 0)
  772.     {
  773.         free(MyDesc);
  774.         return 0;
  775.     }
  776.  
  777.     // Loop until you found a match or until the maximum number of indexes
  778.     //   that are open on this table.
  779.     while(i<uNumIndexes && (uNum!=0))
  780.     {
  781.         // Compare the current name with the names we know.  If it matches
  782.         //   then return that element number of the index array.
  783.         uNum=strcmp(MyDesc->szName, idxDesc[i].szName);
  784.         i++;
  785.     }
  786.  
  787.     free(MyDesc);
  788.  
  789.     // return the current index number.
  790.     return i-1;
  791.  
  792. CleanUp:
  793.     if(MyDesc)
  794.     {
  795.         free(MyDesc);
  796.     }
  797.     return GlobalDBIErr;
  798. }
  799.  
  800. //======================================================================
  801. //  Name:   DeleteRec(hCur)
  802. //
  803. //  Input:  hCur        - Handle to the cursor
  804. //
  805. //  Return: DBIERR_NONE if the record is successfully deleted.
  806. //
  807. //  Description:
  808. //          This function deletes the record that is pointed to by the
  809. //          cursor.
  810. //======================================================================
  811. DBIResult
  812. DeleteRec (hDBICur hCur)
  813. {
  814.     // Lock the record before deleting.
  815.     CHKERR(DbiGetRecord(hCur, dbiWRITELOCK, NULL, 0));
  816.  
  817.     // Delete the record.
  818.     CHKERR(DbiDeleteRecord(hCur, NULL));
  819.  
  820.     // Return the success of the operation
  821.     //   Note that the DBIErr macro will return from this function
  822.     //   if an error occurs.
  823.     return DBIERR_NONE;
  824. }
  825.  
  826. //======================================================================
  827. //  Name:   SetRange(*pHighRec, *pLowRec, bHighInclude, bLowInclude,
  828. //                   hCur, bHighEmpty, bLowEmpty)
  829. //
  830. //  Input:  pHighRec        - Values of the high value record
  831. //          pLowRec         - Values of the locw value record
  832. //          bHighInclude    - Include the high value in the range
  833. //          bLowInclude     - Include the low value in the range
  834. //          hCur            - Handle to the cursor
  835. //          bHighEmpty      - Is the high value empty
  836. //          bLowEmpty       - Is the low value empty
  837. //
  838. //  Return: DBIERR_NONE if the range is successfully set, and the memory
  839. //          is successfully allocated for the high and low record buffers.
  840. //
  841. //  Description:
  842. //          This function sets the range.  To do so it needs the high and
  843. //          low values.  So we pass them inside of pHighRec and pLowRec.
  844. //          Then we need to know if these range values are to be included
  845. //          in the range set.  That is done by using the two booleans
  846. //          bHighInclude and bLowInclude.  Finally we need to pass a NULL
  847. //          pointer to the set range function if the user set no upper or
  848. //          lower range.  So we look at bHighEmpty and bLowEmpty.  If
  849. //          either of them are FALSE we do not allocate memory for the
  850. //          record buffers that are used in the range setting.  If one is
  851. //          TRUE then we allocate memory for the pRecBuf and copy the
  852. //          RecordType pointer data into it.
  853. //======================================================================
  854. DBIResult
  855. SetRange (RecordType *pHighRec, RecordType *pLowRec, BOOL bHighInclude,
  856.           BOOL bLowInclude, hDBICur hCur, BOOL bHighEmpty, BOOL bLowEmpty)
  857. {
  858.     CURProps    TblProps;           // Properties of the table
  859.     pBYTE       pHighRecBuf = NULL; // Record containing the high value
  860.     pBYTE       pLowRecBuf = NULL;  // Record containing the low value
  861.  
  862.     // Get the properties of the table so that we can create the correct
  863.     //   buffer size for the record. 
  864.     CHKERR_CLEANUP(DbiGetCursorProps(hCur,&TblProps));
  865.  
  866.     if(!bHighEmpty)
  867.     {
  868.         if((pHighRecBuf = (pBYTE) malloc(TblProps.iRecBufSize))==NULL)
  869.         {
  870.             CLEANUP(DBIERR_NOMEMORY);
  871.         }
  872.         CHKERR_CLEANUP(DbiInitRecord(hCur, pHighRecBuf));
  873.  
  874.         // Copy the value into the pRecBuf.
  875.         CHKERR_NODISPLAY(FillBuf(hCur, pHighRecBuf, pHighRec));
  876.     }
  877.     // Create the Low record buffer.  The size comes from the property
  878.     //   recsize.
  879.     if(!bLowEmpty)
  880.     {
  881.         if((pLowRecBuf = (pBYTE) malloc(TblProps.iRecBufSize))==NULL)
  882.         {
  883.             CLEANUP(DBIERR_NOMEMORY);
  884.         }
  885.         CHKERR_CLEANUP(DbiInitRecord(hCur, pLowRecBuf));
  886.  
  887.         // Copy the value into the pRecBuf.
  888.         CHKERR_NODISPLAY(FillBuf(hCur, pLowRecBuf, pLowRec));
  889.     }
  890.  
  891.     // Set the range.  The record buffers hold the low and high range
  892.     //   field values.  Since we are using buffers rather than using a
  893.     //   direct pair of strings we set the second parameter to FALSE.
  894.     //   The two booleans are set by the check boxes in the range dialog
  895.     //   box.  They describe whether the range value will be included
  896.     //   inside the answer set.
  897.     CHKERR_CLEANUP(DbiSetRange(hCur, FALSE, 0, 0, pLowRecBuf, bLowInclude,
  898.                        0, 0, pHighRecBuf, bHighInclude));
  899.  
  900.     // Free the record buffers.
  901.     if(!bLowEmpty)
  902.     {
  903.         free(pLowRecBuf);
  904.     }
  905.     if(!bHighEmpty)
  906.     {
  907.         free(pHighRecBuf);
  908.     }
  909.  
  910.     // Return the success of the operation
  911.     //   Note that the DBIErr macro will return from this function
  912.     //   if an error occurs.
  913.     return DBIERR_NONE;
  914.  
  915. CleanUp:
  916.     if(!bLowEmpty)
  917.     {
  918.         free(pLowRecBuf);
  919.     }
  920.     if(!bHighEmpty)
  921.     {
  922.         free(pHighRecBuf);
  923.     }
  924.     return GlobalDBIErr;
  925. }
  926.  
  927. //======================================================================
  928. //  Name:   FillBuf(hCur, pRecBuf, *pString)
  929. //
  930. //  Input:  hCur        - Handle to the cursor
  931. //          pRecBuf     - Record buffer 
  932. //          pStirng     - Pointer to a Record structure
  933. //
  934. //  Return: DBIErr_NONE if the PutFields are all successful.
  935. //
  936. //  Description:
  937. //          This function takes the relevent data from the record
  938. //          structure and puts it into a record buffer that IDAPI
  939. //          understands.
  940. //======================================================================
  941. DBIResult
  942. FillBuf (hDBICur hCur, pBYTE pRecBuf, RecordType *pString)
  943. {
  944.     INT16       ItemId;
  945.     double      In_Stock;
  946.     double      Cost;
  947.  
  948.     // Fill each field with the structure's data.
  949.     ItemId = atoi(pString->ItemId);
  950.     CHKERR(DbiPutField(hCur, 1, pRecBuf, (pBYTE)&ItemId));
  951.     CHKERR(DbiPutField(hCur, 2, pRecBuf, (pBYTE)pString->Building));
  952.     CHKERR(DbiPutField(hCur, 3, pRecBuf, (pBYTE)pString->Item));
  953.     In_Stock = atof(pString->In_Stock);
  954.     CHKERR(DbiPutField(hCur, 4, pRecBuf, (pBYTE)&In_Stock));
  955.     Cost = atof(pString->Cost);
  956.     CHKERR(DbiPutField(hCur, 5, pRecBuf, (pBYTE)&Cost));
  957.  
  958.     return DBIERR_NONE;
  959. }
  960.  
  961. //======================================================================
  962. //  Name:   Search(hCur, uCond, cKey)
  963. //
  964. //  Input:  hCur        - Handle to the cursor
  965. //          uCond       - Search condition
  966. //          cKey        - Key to search for
  967. //
  968. //  Return: DBIERR_NONE if the search is successful.
  969. //
  970. //  Description:
  971. //          This function searches the first field of an index for the
  972. //          value passed in cKey. Note that this function only supports
  973. //          the field types: fldINT16, fldFLOAT, and fldZSTRING.
  974. //======================================================================
  975. DBIResult
  976. Search (hDBICur hCur, DBISearchCond uCond, pBYTE cKey)
  977. {
  978.     DBIResult   rslt;           // Return value from IDAPI functions
  979.     CURProps    TblProps;       // Properties of the table
  980.     IDXDesc     idxDesc;        // Index Descriptor.
  981.     pFLDDesc    pFldDesc = NULL;// Field Descriptor
  982.     INT16       iFldNum;        // Field Number
  983.  
  984.     FLOAT       fTemp;
  985.     INT16       iTemp;
  986.     pBYTE       pRecBuf = NULL;
  987.  
  988.     // Get information about the current index.
  989.     CHKERR_CLEANUP(DbiGetIndexDesc(hCur, 0, &idxDesc));
  990.  
  991.     // Determine the first field of the Index.
  992.     iFldNum = idxDesc.aiKeyFld[0];
  993.  
  994.     // Get information about the cursor - needed to determine the number
  995.     //   of fields in the table.
  996.     CHKERR_CLEANUP(DbiGetCursorProps(hCur, &TblProps));
  997.  
  998.     // Allocate a Field descriptior large enough to contain information
  999.     //   about all fields in the table.
  1000.     if((pFldDesc = (pFLDDesc) malloc(sizeof(FLDDesc) * TblProps.iFields))
  1001.        == NULL)
  1002.     {
  1003.         WinMsg("Out of memory!", MB_ICONHAND, MB_OK);
  1004.         CLEANUP(DBIERR_NOMEMORY);
  1005.     }
  1006.  
  1007.     // Get the field descriptors - needed to determine the type of the
  1008.     // first field of the index.
  1009.     CHKERR_CLEANUP(DbiGetFieldDescs(hCur, pFldDesc));
  1010.  
  1011.     // Create the key buffer.  The size comes from the proporty recsize.
  1012.     if((pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize))==NULL)
  1013.     {
  1014.         WinMsg("Out of memory!", MB_ICONHAND, MB_OK);
  1015.         CLEANUP(DBIERR_NOMEMORY);
  1016.     }
  1017.  
  1018.     // Initialize the record buffer.
  1019.     CHKERR_CLEANUP(DbiInitRecord(hCur, pRecBuf));
  1020.  
  1021.     // Write the data to the record buffer.
  1022.     switch(pFldDesc[iFldNum - 1].iFldType)
  1023.     {
  1024.         case fldINT16:
  1025.             iTemp = atoi((pCHAR)cKey);
  1026.             CHKERR_CLEANUP(DbiPutField(hCur, iFldNum, pRecBuf,
  1027.                            (pBYTE)&iTemp));
  1028.             break;
  1029.         case fldFLOAT:
  1030.             fTemp = atof((pCHAR)cKey);
  1031.             CHKERR_CLEANUP(DbiPutField(hCur, iFldNum, pRecBuf,
  1032.                            (pBYTE)&fTemp));
  1033.             break;
  1034.         case fldZSTRING:
  1035.             CHKERR_CLEANUP(DbiPutField(hCur, iFldNum, pRecBuf,
  1036.                            (pBYTE)cKey));
  1037.             break;
  1038.         default:
  1039.             WinMsg("Operation currently not supported", MB_ICONHAND, MB_OK);
  1040.             CLEANUP(DBIERR_NOTSUPPORTED);
  1041.     }
  1042.  
  1043.     // Perform the actual search on the table.
  1044.     rslt = DbiSetToKey(hCur, uCond, FALSE, 0, 0, pRecBuf);
  1045.  
  1046.     // Display an error message if an error other than Record not Found
  1047.     //   is detected.
  1048.     if ((rslt != DBIERR_NONE) && (rslt != DBIERR_RECNOTFOUND))
  1049.     {
  1050.         CHKERR_CLEANUP(rslt);
  1051.     }
  1052.     else
  1053.     {
  1054.         // If keySEARCHEQ was NOT used then there will be no error.
  1055.         //   Therefore we need to check if there was an error. If we
  1056.         //   are at the end of the table then there was no record found.
  1057.         if(AtEOF(hCur))
  1058.         {
  1059.             rslt = DBIERR_RECNOTFOUND;
  1060.         }
  1061.     }
  1062.     
  1063.     free(pRecBuf);
  1064.     free(pFldDesc);
  1065.  
  1066.     return rslt;
  1067.  
  1068. CleanUp:
  1069.     if(pRecBuf)
  1070.     {
  1071.         free(pRecBuf);
  1072.     }
  1073.     if(pFldDesc)
  1074.     {
  1075.         free(pFldDesc);
  1076.     }
  1077.     return GlobalDBIErr;
  1078. }
  1079.  
  1080. //======================================================================
  1081. //  Name:   ResetRange(hCur)
  1082. //
  1083. //  Input:  hCur        - Handle to the cursor
  1084. //
  1085. //  Return: DBIERR_NONE if the range is successfully reset.
  1086. //
  1087. //  Description:
  1088. //          This function clears any range settings.  The outcome is that
  1089. //          all records will be visable to the user.
  1090. //======================================================================
  1091. DBIResult
  1092. ResetRange (hDBICur hCur)
  1093. {
  1094.     // Reset the range - all records
  1095.     CHKERR(DbiResetRange(hCur));
  1096.  
  1097.     // Return the success of the operation
  1098.     //   Note that the DBIErr macro will return from this function
  1099.     //   if an error occurs.
  1100.     return DBIERR_NONE;
  1101. }
  1102.  
  1103. //======================================================================
  1104. //  Name:   DateEncode(mon, day, year, pTempDate)
  1105. //
  1106. //  Input:  mon         - Month
  1107. //          day         - Day
  1108. //          year        - Year
  1109. //          pTempDate   - Pointer to the DATE variable that is to be
  1110. //                          encoded
  1111. //
  1112. //  Return: DBIERR_NONE if the date is successfully encoded.
  1113. //
  1114. //  Description:
  1115. //          This function takes in the date, month, and year and encodes
  1116. //          them into the DATE pointer with the DateEncode function.
  1117. //======================================================================
  1118. DBIResult
  1119. DateEncode (UINT16 mon, UINT16 day, UINT16 year, pDATE pTempDate)
  1120. {
  1121.     DBIResult rslt;     // Return value from IDAPI functions
  1122.  
  1123.     // Check the result of the date encode and return it.
  1124.     rslt = DbiDateEncode(mon, day, year, pTempDate);
  1125.  
  1126.     return rslt;
  1127. }
  1128.  
  1129. //=====================================================================
  1130. //  Code:   CreateVchk(uNumFields, uNumVchks, fldDesc, VchkDesc);
  1131. //
  1132. //  Input:  uNumFields  - Number of fields
  1133. //          uNumVchks   - Number of validity checks
  1134. //          fldDesc     - Field descriptor
  1135. //          VchkDesc    - Validity descriptor
  1136. //
  1137. //  Return: None.  However, the VchkDesc is modified.
  1138. //
  1139. //  Description:
  1140. //          This function will take in a Validity Check structure and
  1141. //          change the number fields so that they are compatible with
  1142. //          the manner in which IDAPI wants to see them.
  1143. //=====================================================================
  1144. void
  1145. CreateVchk (UINT16 uNumFields, UINT16 uNumVchks, pFLDDesc fldDesc,
  1146.             pVCHKDesc VchkDesc)
  1147. {    
  1148.     UINT16      i=0;                // Used for iteration purposes.
  1149.     UINT16      j=0;                // Used for iteration purposes.
  1150.     INT16       iNumber;            // Used to hold the number to be put
  1151.                                     //   into the VC.
  1152.     BOOL        bFlag = FALSE;      // Used inside of VC loop.
  1153.  
  1154.     // Loop through all the fields and check if it has a VC associated to
  1155.     //   it. If it does then check if the field is a INT16 - if it is convert
  1156.     //   the VC values that are not NULL to numbers that IDAPI wants to see.
  1157.  
  1158.     for(i=0; i<uNumFields; i++)
  1159.     {
  1160.         // Check if the field is an INT16 field and then check if it has a
  1161.         //   Validity Check associated with it.
  1162.         if(fldDesc[i].iFldType == fldINT16)
  1163.         {
  1164.             // Reset the variables for each iteration.
  1165.             j=0;
  1166.             bFlag = FALSE;
  1167.             while(j<uNumVchks && !bFlag)
  1168.             {
  1169.                 // Check if the current field (i+1) has a VC associated
  1170.                 //   with it.
  1171.                 if(VchkDesc[j].iFldNum == (i+1))
  1172.                 {
  1173.                     // Since we found a VC associated with the field - set
  1174.                     //   the BOOL variable to TRUE - so that we get out of
  1175.                     //   the loop.
  1176.                     bFlag = TRUE;
  1177.  
  1178.                     // If the VC Structure has a MinVal for this field
  1179.                     //   then convert it.
  1180.                     if(VchkDesc[j].bHasMinVal)
  1181.                     {
  1182.                         // Get the number that you want to use.
  1183.                         iNumber = atoi((pCHAR)VchkDesc[j].aMinVal);
  1184.  
  1185.                         // Clear the string so that we can change it.
  1186.                         memset(VchkDesc[j].aMinVal, '\0',
  1187.                                strlen((pCHAR)VchkDesc[j].aMinVal));
  1188.  
  1189.                         // Set the new value into the structure.
  1190.                         memmove(VchkDesc[j].aMinVal, &iNumber, 2);
  1191.                     }
  1192.  
  1193.                     // If the VC Structure has a MaxVal for this field
  1194.                     //   then convert it.
  1195.                     if(VchkDesc[j].bHasMaxVal)
  1196.                     {
  1197.                         // Get the number that you want to use.
  1198.                         iNumber = atoi((pCHAR)VchkDesc[j].aMaxVal);
  1199.  
  1200.                         // Clear the string so that we can change it.
  1201.                         memset(VchkDesc[j].aMaxVal, '\0',
  1202.                                strlen((pCHAR)VchkDesc[j].aMaxVal));
  1203.  
  1204.                         // Set the new value into the structure.
  1205.                         memmove(VchkDesc[j].aMaxVal, &iNumber, 2);
  1206.                     }
  1207.  
  1208.                     // If the VC Structure has a DefVal for this field
  1209.                     //   then convert it.
  1210.                     if(VchkDesc[j].bHasDefVal)
  1211.                     {
  1212.                         // Get the number that you want to use.
  1213.                         iNumber = atoi((pCHAR)VchkDesc[j].aDefVal);
  1214.  
  1215.                         // Clear the string so that we can change it.
  1216.                         memset(VchkDesc[j].aDefVal, '\0',
  1217.                                strlen((pCHAR)VchkDesc[j].aDefVal));
  1218.  
  1219.                         // Set the new value into the structure.
  1220.                         memmove(VchkDesc[j].aDefVal, &iNumber, 2);
  1221.                     }
  1222.                 }   // Close of the if(VC)
  1223.                  // Increment j so that we can go through the VC array.
  1224.                 j++;
  1225.              }   // Close of the while loop
  1226.           }   // Close of the if (number field)
  1227.      }   // Close of for loop
  1228. }
  1229.