home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a039 / 3.ddi / WINSAMP.ZIP / WFONEDEX.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-11  |  18.4 KB  |  726 lines

  1. #include "wfonedex.h"
  2. #include "pxengine.h"
  3.  
  4. #include <ctype.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7.  
  8. RECORDHANDLE recHandle;      /* Record buffer */
  9. RECORDHANDLE SaveRecHandle;  /* Save Record buffer */
  10. TABLEHANDLE tblHandle;       /* Table handle */
  11.  
  12. char *names[] = {
  13.     "Last Name",
  14.     "First Name",
  15.     "Address",
  16.     "City",
  17.     "State",
  18.     "ZIP Code",
  19.     "Phone Number",
  20.     "Date Last Phoned",
  21.     "Notes"
  22. };
  23.  
  24. char *types[] = {
  25.     "A15",
  26.     "A15",
  27.     "A40",
  28.     "A15",
  29.     "A15",
  30.     "N",
  31.     "A20",
  32.     "D",
  33.     "A120"
  34. };
  35.  
  36. /* Number of fields */
  37. int nfields = sizeof( names ) / sizeof( char* );
  38.  
  39. /* Field handles to be used in primary key. */
  40. FIELDHANDLE fldHandles[] = { 1, 2 };
  41.  
  42.  
  43. extern int TableIsOpen = FALSE; /* Table is open */
  44.  
  45.  
  46. /*******************************************************************************
  47.  
  48.     Function:
  49.  
  50.         int Init( void );
  51.  
  52.     Arguments:
  53.         None
  54.  
  55.     Description:
  56.         Initializes the Paradox environment,
  57.         creates a new fonedex database if one does not already exist,
  58.         creates a primary index on the last and first name fields of
  59.         the table, and opens the table.
  60.  
  61.     Returns:
  62.         0 if successful and 1 if not.
  63.  
  64. ******************************************************************************/
  65.  
  66. int Init( void )
  67. {
  68.     int bExist;                 /* Used to determine table already exists. */
  69.  
  70.     /* Initialize the engine. */
  71.     if ( Error( PXWinInit( szAppName, PXSHARED ) ) )
  72.         return 1;
  73.  
  74.     /* Create a new table if one does not already exist. */
  75.     Error( PXTblExist( DATAFILE, &bExist ) );
  76.     if ( ! bExist ) {
  77.         /* Try and create it */
  78.         if ( Error( PXTblCreate( DATAFILE, nfields, names, types ) ) )
  79.             return 1;
  80.  
  81.         /* Successful create, Now add Primary Index */
  82.         if ( Error( PXKeyAdd( DATAFILE, sizeof( fldHandles ) /
  83.                   sizeof( FIELDHANDLE ), fldHandles, PRIMARY ) ) )
  84.             return 1;
  85.  
  86.     }
  87.  
  88.     return OpenFonedex();
  89. }
  90.  
  91.  
  92. /*******************************************************************************
  93.  
  94.     Function:
  95.  
  96.         int OpenFonedex( void );
  97.  
  98.     Arguments:
  99.         None
  100.  
  101.     Description:
  102.         Opens the table, and allocates and empties a
  103.         record buffer.
  104.  
  105.     Returns:
  106.         1 if the Fonedex could not be opened as expected.
  107.         0 if successful.
  108.  
  109. ******************************************************************************/
  110.  
  111. int OpenFonedex( void )
  112. {
  113.     /* Attempt to open the table. */
  114.     if ( Error( PXTblOpen( DATAFILE, &tblHandle, 0, TRUE ) ) )
  115.           return 1;
  116.  
  117.     /* Allocate a record buffer. */
  118.     if ( Error( PXRecBufOpen( tblHandle, &recHandle ) ) )
  119.           return 1;
  120.     if ( Error( PXRecBufOpen( tblHandle, &SaveRecHandle ) ) )
  121.           return 1;
  122.  
  123.     TableIsOpen = TRUE;
  124.  
  125.     /* Empty the current record buffer */
  126.     if ( Error( PXRecBufEmpty( recHandle ) ) )
  127.         return 1;
  128.     if ( Error( PXRecBufEmpty( SaveRecHandle ) ) )
  129.         return 1;
  130.  
  131.     return 0;
  132. }
  133.  
  134.  
  135. /*******************************************************************************
  136.  
  137.     Function:
  138.  
  139.         int CloseFonedex( void );
  140.  
  141.     Arguments:
  142.         None
  143.  
  144.     Description:
  145.         Closes the fonedex table if opened.
  146.  
  147.     Returns:
  148.         TRUE if the table was closed;
  149.         FALSE if the table could not be closed.
  150.  
  151. ******************************************************************************/
  152.  
  153. int CloseFonedex( void )
  154. {
  155.     int iBufError,    /* Used to determine Error closing Record Buffer */
  156.         iSavBufError, /* Used to determine Error closing Save Buffer */
  157.         iTblError;    /* Used to determine Error closing Table */
  158.  
  159.     if ( !TableIsOpen )
  160.     {
  161.           Message( "Close Fonedex: Table was not open." );
  162.           return FALSE;
  163.     }
  164.  
  165.     /* Set open flag to FALSE */
  166.     TableIsOpen = FALSE;
  167.  
  168.     /* Free the record buffer. */
  169.     iBufError = Error( PXRecBufClose( recHandle ) );
  170.     iSavBufError = Error( PXRecBufClose( SaveRecHandle ) );
  171.  
  172.     /* Close the table. */
  173.     iTblError = Error( PXTblClose( tblHandle ) );
  174.  
  175.     /*  return FALSE upon error closing Table */
  176.     if ( iTblError )
  177.           return FALSE;
  178.  
  179.     /*  return FALSE upon error closing Record Buffer */
  180.     if ( ( iBufError ) || ( iSavBufError ) )
  181.           return FALSE;
  182.  
  183.     return TRUE;
  184. }
  185.  
  186.  
  187. /*******************************************************************************
  188.  
  189.     Function:
  190.  
  191.         int Search( int FieldNumber, char *Buffer, int mode );
  192.  
  193.     Arguments:
  194.         hWnd            handle to window which is parent of any message
  195.                            boxes that result from the search.
  196.         FieldNumber     Field number selected
  197.         Buffer          string which is search input of field
  198.         mode            search mode (SEARCHFIRST or SEARCHNEXT)
  199.  
  200.     Description:
  201.         Search on the field corresponding to FieldNumber and display
  202.         record if found.
  203.  
  204.     Returns:
  205.         TRUE if the search succeeds (a record is found such that
  206.         the field determined by FieldNumber matches the contents of
  207.         Buffer);
  208.         FALSE if the search fails.
  209.  
  210. ******************************************************************************/
  211.  
  212. int Search( int FieldNumber, char *Buffer, int mode )
  213. {
  214.     /* Refresh the database in case anyone else has updated it */
  215.     PXNetTblRefresh( tblHandle );
  216.  
  217.     /* Translate input field to search on */
  218.     /* If that fails, or ... */
  219.     if ( ( PutData( FieldNumber, Buffer ) != PXSUCCESS ) ||
  220.         /* If no match found, or ... */
  221.         ( PXSrchFld( tblHandle, recHandle, FieldNumber, mode ) != PXSUCCESS ) ||
  222.         /* If you cannot get the record found, return FALSE */
  223.         ( Error( PXRecGet( tblHandle, recHandle ) ) ) )
  224.     {
  225.         DisplayRecord();
  226.         return FALSE;   /* Return if search cannot go on */
  227.     }
  228.     /* Put new record into save record */
  229.     Error( PXRecBufCopy( recHandle, SaveRecHandle ) );
  230.     DisplayRecord();
  231.     return TRUE;
  232. }
  233.  
  234.  
  235. /*******************************************************************************
  236.  
  237.     Function:
  238.  
  239.         int ProcessRecord( void );
  240.  
  241.     Arguments:
  242.         None.
  243.  
  244.     Description:
  245.         Locks the record and calls IsRecordChanged and UpdateRecord.
  246.  
  247.     Returns:
  248.         TRUE if the records differ;
  249.         FALSE otherwise.
  250.  
  251. ******************************************************************************/
  252.  
  253. int ProcessRecord( void )
  254. {
  255.  
  256.     static LOCKHANDLE lckHandle;
  257.     int iLock,
  258.         iUpdate;
  259.  
  260.     /* Lock the record */
  261.     iLock = PXNetRecLock( tblHandle, &lckHandle );
  262.     if ( iLock == PXERR_TABLEEMPTY )
  263.     {  
  264.          MessageBox( hDlgModeless, "Could Not Update Current Record", 
  265.              "Update Failed:  Empty Table", MB_OKCANCEL | MB_DEFBUTTON2 );
  266.          return FALSE;
  267.     }
  268.  
  269.     if ( iLock == PXERR_RECDELETED )
  270.     {
  271.         iUpdate = MessageBox( hDlgModeless, "Another User has Deleted the Record",
  272.              "Insert Record", MB_OKCANCEL | MB_DEFBUTTON2 );
  273.         if ( iUpdate == IDOK )
  274.         {
  275.              /* Insert Record */   
  276.              SetRecord();
  277.              if ( Error ( PXRecInsert( tblHandle, recHandle ) ) )
  278.              {
  279.                   Message( "Insert failed: PXRecInsert failed." );
  280.                   return FALSE;
  281.              }
  282.              Error( PXRecBufCopy ( recHandle, SaveRecHandle ) );
  283.              return TRUE;
  284.         }
  285.         else
  286.         {
  287.              /* Update the Dialog Box with New Record */
  288.              DisplayRecord();
  289.              return FALSE;
  290.         }
  291.     }
  292.  
  293.     if ( iLock )
  294.     {
  295.         Message( "Update failed: Could not lock current record." );
  296.         return FALSE;
  297.     }
  298.  
  299.    if ( IsRecordChanged() )
  300.    {
  301.         iUpdate = MessageBox( hDlgModeless, "Another User has Modified the Record",
  302.              "Update Record", MB_OKCANCEL | MB_DEFBUTTON2 );
  303.         if ( iUpdate != IDOK )
  304.         {
  305.              /* Update the Dialog Box with New Record */
  306.              DisplayRecord();
  307.              Error( PXNetRecUnlock( tblHandle, lckHandle ) );
  308.              return FALSE;
  309.         }
  310.    }
  311.  
  312.     UpdateRecord();
  313.  
  314.     /* And unlock record */
  315.     if ( Error( PXNetRecUnlock( tblHandle, lckHandle ) ) )
  316.          return FALSE;
  317.  
  318.     return TRUE;
  319.  
  320. }
  321.  
  322.  
  323. /*******************************************************************************
  324.  
  325.     Function:
  326.  
  327.         void UpdateRecord( void );
  328.  
  329.     Arguments:
  330.         None
  331.  
  332.     Description:
  333.         Updates the current record in a Fonedex table.
  334.  
  335.     Returns:
  336.         None
  337.  
  338. ******************************************************************************/
  339.  
  340. void UpdateRecord( void )
  341. {
  342.  
  343.     int rc;
  344.  
  345.     SetRecord();
  346.  
  347.     /* Update it */
  348.     if (Error( PXRecUpdate( tblHandle, recHandle ) ) )
  349.     {
  350.         Message( "Update failed: PXRecUpdate failed." );
  351.         return;
  352.     }
  353.     Error( PXRecBufCopy ( recHandle, SaveRecHandle ) );
  354.  
  355. }
  356.  
  357.  
  358. /*******************************************************************************
  359.  
  360.     Function:
  361.  
  362.         int IsRecordChanged( void );
  363.  
  364.     Arguments:
  365.         None
  366.  
  367.     Description:
  368.         Determines whether original record read from the table is different
  369.         from record in the table.
  370.  
  371.     Returns:
  372.         TRUE if the records differ;
  373.         FALSE otherwise.
  374.  
  375. ******************************************************************************/
  376.  
  377. int IsRecordChanged( void )
  378. {
  379.     int nFlds;
  380.     int rc;
  381.     int i;
  382.     char buf1[MAXFIELDSIZE];
  383.     char buf2[MAXFIELDSIZE];
  384.  
  385.     /* If the current record could not be retrieved (eg, the table is empty
  386.        or another user deleted the record), return fail; in particular,
  387.        FondexDlgProc will interpret this as a sign not to attempt to
  388.        update the table.
  389.        If the record could not be gotten, display an error message (unless
  390.        the table is empty). */
  391.     rc = PXRecGet( tblHandle, recHandle );
  392.     if ( rc == PXERR_TABLEEMPTY )
  393.         return FALSE;
  394.     if ( rc )
  395.     {
  396.         Error( rc );
  397.         return FALSE;
  398.     }
  399.  
  400.     /*  Determine number of fields in a record */
  401.     Error( PXRecNFlds( tblHandle, &nFlds ) );
  402.  
  403.     for ( i = 1; i <= nFlds; i++ )
  404.     {
  405.         /* Get string from field in Original record. */
  406.         GetData( SaveRecHandle, i, buf1 );
  407.         /* Get string from field in table's current record. */
  408.         GetData( recHandle, i, buf2 );
  409.         /* If any field differs, return TRUE. */
  410.         if ( strcmp( buf1, buf2 ) )
  411.             return TRUE;
  412.     }
  413.     return FALSE;
  414. }
  415.  
  416.  
  417. /*******************************************************************************
  418.  
  419.     Function:
  420.  
  421.         void DisplayRecord( void );
  422.  
  423.     Arguments:
  424.         None
  425.  
  426.     Description:
  427.         Displays the current record in a dialog box.  This function
  428.         assumes hDlgModeless is the handle to a dialog box which is currently
  429.         the top window and which has items corresponding to a fonedex record.
  430.  
  431.     Returns:
  432.         None
  433.  
  434. ******************************************************************************/
  435.  
  436. void DisplayRecord( void )
  437. {
  438.     char buf[MAXFIELDSIZE];
  439.     int i;
  440.     int rc;
  441.  
  442.     rc = PXRecGet( tblHandle, recHandle );
  443.     Error( PXRecBufCopy( recHandle, SaveRecHandle ) );
  444.     /* If the table is empty, display an empty record. */
  445.     if ( rc != PXSUCCESS ) {
  446.         if ( rc == PXERR_TABLEEMPTY ) {
  447.             if ( ( Error( PXRecBufEmpty( recHandle ) ) ) ||
  448.                      ( Error( PXRecBufEmpty ( SaveRecHandle ) ) ) )
  449.                 return;
  450.         }
  451.         else
  452.             return;
  453.     }
  454.     for ( i = IDD_LASTNAMEEDIT; i <= IDD_NOTESEDIT; i++ )
  455.     {
  456.         if ( GetData( recHandle, i - IDD_FIRST + 1, buf ) != PXSUCCESS )
  457.             return;
  458.         SetDlgItemText( hDlgModeless, i, buf );
  459.     }
  460. }
  461.  
  462.  
  463. /*******************************************************************************
  464.  
  465.     Function:
  466.  
  467.         void SetRecord( void );
  468.  
  469.     Arguments:
  470.         None
  471.  
  472.     Description:
  473.         Sets the fields of the record buffer identified by recHandle to the
  474.         values in the edit controls of the dialog box.  This function
  475.         assumes hDlgModeless is the handle to the dialog box which is currently
  476.         the top window and which has items corresponding to a fonedex record.
  477.  
  478.     Returns:
  479.         None
  480.  
  481. ******************************************************************************/
  482.  
  483. void SetRecord( void )
  484. {
  485.     char buf[MAXFIELDSIZE];
  486.     int i;
  487.  
  488.     for ( i = IDD_LASTNAMEEDIT; i <= IDD_NOTESEDIT; i++ )
  489.     {
  490.         GetDlgItemText( hDlgModeless, i, buf, MAXFIELDSIZE );
  491.         PutData( i - IDD_FIRST + 1, buf );
  492.     }
  493. }
  494.  
  495.  
  496. /******************************************************************************
  497.  
  498.     Function:
  499.  
  500.         void BlankDisplayedRecord( void );
  501.  
  502.     Arguments:
  503.         None
  504.  
  505.     Description:
  506.         Display a blank record.
  507.  
  508.     Returns:
  509.         None
  510.  
  511. ******************************************************************************/
  512.  
  513. void BlankDisplayedRecord( void )
  514. {
  515.     int i;
  516.  
  517.     /* Blank out fields in display */
  518.     for ( i = IDD_LASTNAMEEDIT; i <= IDD_NOTESEDIT; i++ )
  519.     {
  520.         SetDlgItemText( hDlgModeless, i, "" );
  521.     }
  522. }
  523.  
  524.  
  525. /*******************************************************************************
  526.  
  527.     Function:
  528.  
  529.         int GetData( RECORDHANDLE rechandle, FIELDHANDLE fh, char s[] );
  530.  
  531.     Arguments:
  532.         rechandle               recordhandle of record
  533.         FieldNumber             field number to retrieve data
  534.         s                       string where data is stored
  535.  
  536.     Description:
  537.         Retrieves in a string format any valid Paradox type.
  538.  
  539.     Returns:
  540.         PXSUCCESS  No errors retrieving data
  541.         FAIL     Error retrieving data
  542.  
  543. ******************************************************************************/
  544.  
  545. int GetData( RECORDHANDLE rechandle, FIELDHANDLE fh, char s[] )
  546. {
  547.     long theDate;
  548.     int month, day, year;
  549.     double theValue;
  550.     short theShort;
  551.     int isBlank;
  552.  
  553.     /* if this field is blank, we want to return a blank string */
  554.     if ( !Error( PXFldBlank( rechandle, fh, &isBlank ) ) )
  555.     {
  556.         if ( isBlank )
  557.         {
  558.             s[0] = '\0';
  559.             return PXSUCCESS;
  560.         }
  561.     }
  562.     else
  563.         return FAIL;
  564.  
  565.     switch( types[fh-1][0] )
  566.     {
  567.         case 'a':
  568.         case 'A':
  569.             if ( Error( PXGetAlpha( rechandle, fh, BUFSIZ, s ) ) )
  570.                 return FAIL;
  571.             break;
  572.         case 'd':
  573.         case 'D':
  574.             if ( !Error( PXGetDate( rechandle, fh, &theDate ) ) )
  575.             {
  576.                 PXDateDecode( theDate, &month, &day, &year );
  577.                 sprintf( s, "%d/%d/%d", month, day, year );
  578.             }
  579.             else
  580.                 return FAIL;
  581.             break;
  582.         case 'n':
  583.         case 'N':
  584.             if ( !Error( PXGetDoub( rechandle, fh, &theValue ) ) )
  585.                 sprintf( s, "%5.0lf", theValue );
  586.             else
  587.                 return FAIL;
  588.             break;
  589.         case '$':
  590.             if ( !Error( PXGetDoub( rechandle, fh, &theValue ) ) )
  591.                 sprintf( s, "%4.2lf", theValue );
  592.             else
  593.                 return FAIL;
  594.             break;
  595.         case 's':
  596.         case 'S':
  597.             if ( !Error( PXGetShort( rechandle, fh, &theShort ) ) )
  598.                 sprintf( s, "%d", theShort );
  599.             else
  600.                 return FAIL;
  601.             break;
  602.     }
  603.     return( PXSUCCESS );
  604. }
  605.  
  606.  
  607. /*******************************************************************************
  608.  
  609.     Function:
  610.  
  611.         int PutData( FIELDHANDLE fh, char *s );
  612.  
  613.     Arguments:
  614.         FieldNumber             field number to store data
  615.         s                       string to be stored
  616.  
  617.     Description:
  618.         Stores a string in any valid Paradox type.
  619.  
  620.     Returns:
  621.         PXSUCCESS  No errors storing data
  622.         FAIL     Error storing data
  623.  
  624. ******************************************************************************/
  625.  
  626. int PutData( FIELDHANDLE fh, char *s )
  627. {
  628.     long theDate;
  629.     int month, day, year;
  630.     double theValue;
  631.     short theShort;
  632.  
  633.     /* If the field is blank, put a blank into the record buffer. */
  634.     if ( !strcmp( s, "" ) ) {
  635.         if ( Error( PXPutBlank( recHandle, fh ) ) )
  636.             return FAIL;
  637.         else
  638.             return PXSUCCESS;
  639.     }
  640.     switch( types[fh-1][0] )
  641.     {
  642.         case 'a':
  643.         case 'A':
  644.             if ( Error( PXPutAlpha( recHandle, fh, s ) ) )
  645.                 return FAIL;
  646.             break;
  647.  
  648.         case 'D':
  649.         case 'd':
  650.             sscanf( s, "%d/%d/%d", &month, &day, &year );
  651.             if ( ( Error( PXDateEncode( month, day, year, &theDate ) ) ) ||
  652.                  ( Error( PXPutDate( recHandle, fh, theDate ) ) ) )
  653.                 return FAIL;
  654.             break;
  655.  
  656.         case '$':
  657.         case 'N':
  658.         case 'n':
  659.             sscanf( s, "%lf", &theValue );
  660.             if ( Error( PXPutDoub( recHandle, fh, theValue ) ) )
  661.                 return FAIL;
  662.             break;
  663.         case 'S':
  664.         case 's':
  665.             sscanf( s, "%d", &theShort );
  666.             if ( Error( PXPutShort( recHandle, fh, theShort ) ) )
  667.                 return FAIL;
  668.             break;
  669.     }
  670.  
  671.     return( PXSUCCESS );
  672. }
  673.  
  674.  
  675. /*******************************************************************************
  676.  
  677.     Function:
  678.  
  679.         int Error( int rc );
  680.  
  681.     Arguments:
  682.         rc                  return code from a PX... function
  683.  
  684.     Description:
  685.         Prints error message if an error has occurred.
  686.  
  687.     Returns:
  688.         current error code
  689.  
  690. ******************************************************************************/
  691.  
  692. int Error( int rc )
  693. {
  694.     char MessageBuffer[128];
  695.  
  696.     if ( rc != PXSUCCESS ) {
  697.         sprintf( MessageBuffer, "FONEDEX: %s", PXErrMsg( rc ) );
  698.         MessageBox( hDlgModeless, MessageBuffer, NULL, MB_OK | MB_ICONHAND );
  699.     }
  700.  
  701.     return rc;
  702. }
  703.  
  704.  
  705. /******************************************************************************
  706.  
  707.     Function:
  708.  
  709.         void Message( char *message );
  710.  
  711.     Arguments:
  712.         message             String to be printed in message box.
  713.  
  714.     Description:
  715.         Prints message in a message box.
  716.  
  717.     Returns:
  718.         None
  719.  
  720. ******************************************************************************/
  721.  
  722. void Message( char *message )
  723. {
  724.     MessageBox( hDlgModeless, message, "Message", MB_OK | MB_ICONASTERISK );
  725. }
  726.