home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / odbc / admndemo / dialogs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-08  |  20.8 KB  |  533 lines

  1. //*---------------------------------------------------------------------------------
  2. //|  ODBC System Administrator
  3. //|
  4. //|  This code is furnished on an as-is basis as part of the ODBC SDK and is
  5. //|  intended for example purposes only.
  6. //|
  7. //|   Title:   DIALOGS.C
  8. //|      This module contains the dialog procs which are used to display
  9. //|         catalog function arguements and display the results.  Note that
  10. //|         the best way to determine the size of the arguements would be
  11. //|         to use SQLGetInfo, however, due to ease of coding, the values
  12. //|         have been hard-coded to constants.
  13. //*---------------------------------------------------------------------------------
  14. #include <windows.h>
  15. #include "admndemo.h"
  16. #include "dialogs.h"
  17. #include "sql.h"
  18. #include "sqlext.h"
  19. #include "execute.h"
  20. #include "info.h"
  21. #include "results.h"
  22. #include "strings.h"
  23.  
  24. VSZFile;
  25. #define CHKNULL(str)  (*str ? str : NULL)
  26.  
  27.  
  28. //*---------------------------------------------------------------------------------
  29. //|   Local function prototypes
  30. //*---------------------------------------------------------------------------------
  31. BOOL ShowCatalogResults(CHILDINFO FAR * ci, LPSTR szTitle);
  32. BOOL EXTFUN CatalogWndProc(HWND hDlg, unsigned msg, WPARAM wParam, LPARAM lParam);
  33.  
  34.  
  35. //*---------------------------------------------------------------------------------
  36. //|   Global variables
  37. //*---------------------------------------------------------------------------------
  38. extern char OutStr[MAXBUFF];
  39.  
  40.  
  41. //
  42. // The following set of defines and host vars are used to create a common
  43. // dialog handler for each of the catalog function dialogs.  This makes
  44. // the code size smaller while still handling each catalog functions
  45. // parameters.  It also allows for sharing of values from one function
  46. // to another.
  47. //
  48. #define CAT_LAST         256
  49. #define CAT_QUALIFIER      1
  50. #define CAT_TABLE          2
  51. #define CAT_OWNER          4
  52. #define CAT_TYPE           8
  53. #define CAT_COLUMN        16
  54. #define CAT_QUALIFIER2    32
  55. #define CAT_OWNER2        64
  56. #define CAT_TABLE2       128
  57. #define CAT_PROCS        256
  58. char szQualifierVal[MAX_QUALIFIER];
  59. char szTableVal[MAX_NAME];
  60. char szOwnerVal[MAX_OWNER];
  61. char szTypeVal[MAX_NAME];
  62. char szColumnVal[MAX_NAME];
  63. char szQualifierVal2[MAX_QUALIFIER];
  64. char szOwnerVal2[MAX_OWNER];
  65. char szTableVal2[MAX_NAME];
  66. char szProcsVal[MAX_NAME];
  67.  
  68. struct {
  69.    int         mMask;                        // Bit mask value
  70.    int         id;                           // Edit control id
  71.    LPSTR       szStr;                        // Buffer location
  72.    int         cbMax;                        // Maximum size
  73.    } CatalogVals[] = {
  74. // mMask                id                      szStr                   cbMax
  75. // -------------------  ---------------------   ----------------------- ------------------------
  76.    CAT_QUALIFIER,       IDE_QUALIFIER,          (LPSTR)szQualifierVal,  MAX_QUALIFIER,
  77.    CAT_TABLE,           IDE_TABLE,              (LPSTR)szTableVal,      MAX_NAME,
  78.    CAT_OWNER,           IDE_OWNER,              (LPSTR)szOwnerVal,      MAX_OWNER,
  79.    CAT_TYPE,            IDE_TYPE,               (LPSTR)szTypeVal,       MAX_NAME,
  80.    CAT_COLUMN,          IDE_COLUMN,             (LPSTR)szColumnVal,     MAX_NAME,
  81.    CAT_QUALIFIER2,      IDE_QUALIFIER2,         (LPSTR)szQualifierVal2, MAX_QUALIFIER,
  82.    CAT_OWNER2,          IDE_OWNER2,             (LPSTR)szOwnerVal2,     MAX_OWNER,
  83.    CAT_TABLE2,          IDE_TABLE2,             (LPSTR)szTableVal2,     MAX_NAME,
  84.    CAT_PROCS,           IDE_PROCEDURE,          (LPSTR)szProcsVal,      MAX_NAME,
  85.    };
  86.  
  87. dCSEG(char) szTablesTitle[]               =  "Tables";
  88. dCSEG(char) szColumnsTitle[]              =  "Columns";
  89. dCSEG(char) szStatistics[]                =  "Statistics";
  90. dCSEG(char) szPrimaryKeys[]               =  "Primary Keys";
  91. dCSEG(char) szForeignKeys[]               =  "Foreign Keys";
  92. dCSEG(char) szTablePrivs[]                =  "Table Privileges";
  93. dCSEG(char) szColumnPrivs[]               =  "Column Privileges";
  94. dCSEG(char) szSpecialCols[]               =  "Special Columns";
  95. dCSEG(char) szProcsTitle[]                =  "Procedures";
  96. dCSEG(char) szProcCols[]                  =  "Procedure Columns";
  97. dCSEG(char) szCOLON[]                     =  ":";
  98.  
  99.  
  100. struct {
  101.    int               idMenu;                    // Menu identifier
  102.    int               iDialogName;               // ID of dialog
  103. // DLGWNDPROC        dlgProc;                   // Dialog procedure
  104.    LPSTR             szDlgTitle;                // Title of the dialog
  105.    UINT              mask;                      // Mask for this dialog
  106.    } Dialogs[] = {
  107. // idMenu                  iDialogName                szDlgTitle              mask
  108. // ---------------------   ------------------         ----------------------- -------------------------------------------------
  109.    IDM_TABLES,             IDD_SQLTABLES,             (LPSTR)szTablesTitle,   CAT_QUALIFIER | CAT_OWNER | CAT_TABLE | CAT_TYPE,
  110.    IDM_COLUMNS,            IDD_SQLCOLUMNS,            (LPSTR)szColumnsTitle,  CAT_QUALIFIER | CAT_OWNER | CAT_TABLE | CAT_COLUMN,
  111.    IDM_STATISTICS,         IDD_SQLSTATISTICS,         (LPSTR)szStatistics,    CAT_QUALIFIER | CAT_OWNER | CAT_TABLE,
  112.    IDM_PRIMARY_KEYS,       IDD_SQLPRIMARYKEYS,        (LPSTR)szPrimaryKeys,   CAT_QUALIFIER | CAT_OWNER | CAT_TABLE,
  113.    IDM_FOREIGN_KEYS,       IDD_SQLFOREIGNKEYS,        (LPSTR)szForeignKeys,   CAT_QUALIFIER | CAT_OWNER | CAT_TABLE | CAT_QUALIFIER2 | CAT_OWNER2 | CAT_TABLE2,
  114.    IDM_TABLE_PRIVS,        IDD_SQLTABLEPRIVILEGES,    (LPSTR)szTablePrivs,    CAT_QUALIFIER | CAT_OWNER | CAT_TABLE,
  115.    IDM_COLUMN_PRIVS,       IDD_SQLCOLUMNPRIVILEGES,   (LPSTR)szColumnPrivs,   CAT_QUALIFIER | CAT_OWNER | CAT_TABLE | CAT_COLUMN,
  116.    IDM_SPECIAL_COLUMNS,    IDD_SQLSPECIALCOLUMNS,     (LPSTR)szSpecialCols,   CAT_QUALIFIER | CAT_OWNER | CAT_TABLE,
  117.    IDM_PROCEDURES,         IDD_SQLPROCEDURES,         (LPSTR)szProcsTitle,    CAT_QUALIFIER | CAT_OWNER | CAT_PROCS,
  118.    IDM_PROC_COLUMNS,       IDD_SQLPROCEDURECOLUMNS,   (LPSTR)szProcCols,      CAT_QUALIFIER | CAT_OWNER | CAT_PROCS | CAT_COLUMN,
  119.    };
  120.  
  121. //
  122. // This structure is used to control the catalog fucntions
  123. //
  124. typedef struct tagCATALOGINFO {
  125.    HINSTANCE         hInst;               // Instance handle for this app
  126.    CHILDINFO FAR *   ci;                  // Child info
  127.    int               id;                  // Dialog id to indicate function
  128.    LPSTR             szDlgTitle;          // Title for the dialog
  129.    UINT              mask;                // Dialog control mask
  130. // For SQLStatistics
  131.    UWORD             fUnique;
  132.    UWORD             fAccuracy;
  133. // For SQLSpecialColumns
  134.    UWORD             fColType;
  135.    UWORD             fScope;
  136.    UWORD             fNullable;
  137.    } CATALOGINFO;
  138.  
  139. //
  140. // A prototype for radio button controls
  141. //
  142. typedef struct tagIDXINFO {
  143.    int               idxVal;
  144.    int               fType;
  145.    } IDXINFO;
  146.  
  147. //
  148. // For SQLStatistics, fUnqiue parameter
  149. //
  150. struct {
  151.    int               idxVal;                    // Dialog item number
  152.    int               fType;                     // SQL constant equivalent
  153.    } StatsfUnique[] = {
  154. // idxVal                        fType
  155. // --------------------------    ---------------------------------
  156.    IDX_INDEX_UNIQUE,             SQL_INDEX_UNIQUE,
  157.    IDX_INDEX_ALL,                SQL_INDEX_ALL,
  158.    };
  159.  
  160. //
  161. // For SQLStatistics, fAccuracy parameter
  162. //
  163. struct {
  164.    int               idxVal;                    // Dialog item number
  165.    int               fType;                     // SQL constant equivalent
  166.    } StatsfAccuracy[] = {
  167. // idxVal                        fType
  168. // --------------------------    ---------------------------------
  169.    IDX_ENSURE,                   SQL_ENSURE,
  170.    IDX_QUICK,                    SQL_QUICK,
  171.    };
  172.  
  173. //
  174. // For SQLSpecialColumns, fColType parameter
  175. //
  176. struct {
  177.    int               idxVal;                    // Dialog item number
  178.    int               fType;                     // SQL constant equivalent
  179.    } SpecColsfColType[] = {
  180. // idxVal                        fType
  181. // --------------------------    ---------------------------------
  182.    IDX_BEST_ROWID,               SQL_BEST_ROWID,
  183.    IDX_ROWVER,                   SQL_ROWVER,
  184.    };
  185.  
  186. //
  187. // For SQLSpecialColumns, fNullable parameter
  188. //
  189. struct {
  190.    int               idxVal;                    // Dialog item number
  191.    int               fType;                     // SQL constant equivalent
  192.    } SpecColsfNullable[] = {
  193. // idxVal                        fType
  194. // --------------------------    ---------------------------------
  195.    IDX_NO_NULLS,                 SQL_NO_NULLS,
  196.    IDX_NULLABLE,                 SQL_NULLABLE,
  197.    };
  198.  
  199. //
  200. // For SQLSpecialColumns, fScope parameter
  201. //
  202. struct {
  203.    int               idxVal;                    // Dialog item number
  204.    int               fType;                     // SQL constant equivalent
  205.    } SpecColsfScope[] = {
  206. // idxVal                        fType
  207. // --------------------------    ---------------------------------
  208.    IDX_SCOPE_CURROW,             SQL_SCOPE_CURROW,
  209.    IDX_SCOPE_TRANSACTION,        SQL_SCOPE_TRANSACTION,
  210.    IDX_SCOPE_SESSION,            SQL_SCOPE_SESSION,
  211.    };
  212.  
  213.  
  214.  
  215.  
  216. //*---------------------------------------------------------------------------------
  217. //| GetRadioValue:
  218. //|   This function will examine a group of radio buttons based on the control
  219. //|   structure and see which is checked.  When found, that value is returned.
  220. //| Parms:
  221. //|   hDlg           Window handle of dialog with control
  222. //|   stct           Radio control structure
  223. //|   cbNum          How many items in control structure
  224. //| Returns:
  225. //|   The value for the item checked
  226. //*---------------------------------------------------------------------------------
  227. int GetRadioValue(HWND hDlg, IDXINFO FAR * stct, int cbNum)
  228. {
  229.    int   dex;
  230.    for(dex=0;  dex<cbNum;  dex++)
  231.       if(IsDlgButtonChecked(hDlg, stct[dex].idxVal))
  232.          return(stct[dex].fType);
  233.    return 0;
  234. }
  235.  
  236.  
  237. //*---------------------------------------------------------------------------------
  238. //| ShowCatalogResults:
  239. //|   This function will display the results set returned by a catalog
  240. //|   function.
  241. //| Parms:
  242. //|   in       ci                   CHILDINFO information
  243. //|   in       szTitle              Title for the results set
  244. //| Returns:
  245. //|   Nothing.
  246. //*---------------------------------------------------------------------------------
  247. BOOL ShowCatalogResults(CHILDINFO FAR * ci, LPSTR szTitle)
  248. {
  249.    RESULTSSET FAR *  rs;
  250.    int               cbCols;
  251.  
  252.    if(!(cbCols = GetNumResultsCols(ci->hstmt)))
  253.       return TRUE;
  254.    if(cbCols == 0) {
  255.       szWrite(ci->hwndOut, GetidsString(idsNoDataFound, OutStr, sizeof(OutStr)));
  256.       return TRUE;
  257.    }
  258.    rs = GetConnectWindowResultsNode(ci);
  259.    if(!CreateResultsSet(rs, ci->hwndClient, ci->hInst,
  260.                         cbCols, szTitle))
  261.       return TRUE;
  262.    SetMetaDataFromSql(ci->hwndOut, ci->hstmt, rs, cbCols);
  263.    if(!CreateResultsWindow(ci, rs))
  264.       return TRUE;
  265.    FetchAllRecordsToResults(ci->hwndOut, ci->hstmt, rs, cbCols, TRUE);
  266.    SQLFreeStmt(ci->hstmt, SQL_CLOSE);
  267.  
  268.    return FALSE;
  269. }
  270.  
  271.  
  272. //*---------------------------------------------------------------------------------
  273. //| DoList:
  274. //|   This function will display a selection dialog for the catalog functions
  275. //|   then process the request.
  276. //| Parms:
  277. //|   in       ci                   CHILDINFO information
  278. //|   in       idMenuSelection      Menu value
  279. //| Returns:
  280. //|   Nothing.
  281. //*---------------------------------------------------------------------------------
  282. void DoList(CHILDINFO FAR * ci, int idMenuSelection)
  283. {
  284.    static BOOL             fInit;            // Have we called before
  285.    CATALOGINFO             cati;
  286.    CATALOGINFO FAR *       lpcati=&cati;
  287.    int                     dex;
  288.    HWND                    fHwnd=GetFocus();
  289.  
  290.    // Clean up all buffers on first catalog function
  291.    if(!fInit) {
  292.       for(dex=0;  dex<NumItems(CatalogVals);  dex++)
  293.          memset(CatalogVals[dex].szStr, 0, CatalogVals[dex].cbMax);
  294.       fInit = TRUE;
  295.    }
  296.  
  297.    // Find the dialog
  298.    for(dex=0;  dex<NumItems(Dialogs) &&
  299.        Dialogs[dex].idMenu != idMenuSelection;  dex++);
  300.  
  301.    // Collect information for the dialog proc
  302.    cati.hInst = ci->hInst;
  303.    cati.id = idMenuSelection;
  304.    cati.ci = ci;
  305.    cati.szDlgTitle = Dialogs[dex].szDlgTitle;
  306.    cati.mask = Dialogs[dex].mask;
  307.  
  308.    // Display the dialog
  309.    if(-1 == DialogBoxParam(cati.hInst,
  310.                            MAKEINTRESOURCE(Dialogs[dex].iDialogName),
  311.                            ci->hwnd,
  312.                            (DLGPROC) CatalogWndProc, (LPARAM)(CATALOGINFO FAR *)lpcati))
  313.       MessageBox(NULL, "Could not open dialog box.",
  314.                  "DoList", MB_ICONEXCLAMATION);
  315.  
  316.    if(fHwnd)
  317.       SetFocus(fHwnd);
  318. }
  319.  
  320.  
  321.  
  322. //*---------------------------------------------------------------------------------
  323. //| DoCatalogFunction:
  324. //|   The caller should have prepared all the information we need, so we will
  325. //|   simply invoke the function they want to run.
  326. //|
  327. //| Parms:
  328. //|   cati     CATALOGINFO
  329. //| Returns:
  330. //|   Nothing
  331. //*---------------------------------------------------------------------------------
  332. void DoCatalogFunction(CATALOGINFO FAR * cati)
  333. {
  334.    char                 szTitle[MAXBUFF];
  335.    RETCODE              retcode;
  336.    CHILDINFO FAR *      ci=cati->ci;
  337.  
  338.    SQLFreeStmt(ci->hstmt, SQL_CLOSE);
  339.  
  340.    switch(cati->id) {
  341.      case IDM_TABLES:
  342.       if (!*szTableVal &&
  343.           ((!*szOwnerVal && strcmp(szQualifierVal, "%") == 0)||
  344.            (!*szQualifierVal && strcmp(szOwnerVal, "%") == 0)))
  345.          retcode = SQLTables(ci->hstmt,
  346.                              szQualifierVal, SQL_NTS,
  347.                              szOwnerVal, SQL_NTS,
  348.                              szTableVal, SQL_NTS,
  349.                              szTypeVal, SQL_NTS);
  350.       else
  351.          retcode = SQLTables(ci->hstmt,
  352.                              CHKNULL(szQualifierVal), SQL_NTS,
  353.                              CHKNULL(szOwnerVal), SQL_NTS,
  354.                              CHKNULL(szTableVal), SQL_NTS,
  355.                              CHKNULL(szTypeVal), SQL_NTS);
  356.       break;
  357.  
  358.      case IDM_COLUMNS:
  359.       retcode = SQLColumns(ci->hstmt,
  360.                            CHKNULL(szQualifierVal), SQL_NTS,
  361.                            CHKNULL(szOwnerVal), SQL_NTS,
  362.                            CHKNULL(szTableVal), SQL_NTS,
  363.                            CHKNULL(szColumnVal), SQL_NTS);
  364.       break;
  365.  
  366.      case IDM_STATISTICS:
  367.       retcode = SQLStatistics(ci->hstmt,
  368.                               CHKNULL(szQualifierVal), SQL_NTS,
  369.                               CHKNULL(szOwnerVal), SQL_NTS,
  370.                               CHKNULL(szTableVal), SQL_NTS,
  371.                               cati->fUnique,
  372.                               cati->fAccuracy);
  373.       break;
  374.  
  375.      case IDM_PRIMARY_KEYS:
  376.       retcode = SQLPrimaryKeys(ci->hstmt,
  377.                                CHKNULL(szQualifierVal), SQL_NTS,
  378.                                CHKNULL(szOwnerVal), SQL_NTS,
  379.                                CHKNULL(szTableVal), SQL_NTS);
  380.       break;
  381.  
  382.      case IDM_FOREIGN_KEYS:
  383.       retcode = SQLForeignKeys(ci->hstmt,
  384.                                CHKNULL(szQualifierVal), SQL_NTS,
  385.                                CHKNULL(szOwnerVal), SQL_NTS,
  386.                                CHKNULL(szTableVal), SQL_NTS,
  387.                                CHKNULL(szQualifierVal2), SQL_NTS,
  388.                                CHKNULL(szOwnerVal2), SQL_NTS,
  389.                                CHKNULL(szTableVal2), SQL_NTS);
  390.       break;
  391.  
  392.      case IDM_TABLE_PRIVS:
  393.       retcode = SQLTablePrivileges(ci->hstmt,
  394.                                    CHKNULL(szQualifierVal), SQL_NTS,
  395.                                    CHKNULL(szOwnerVal), SQL_NTS,
  396.                                    CHKNULL(szTableVal), SQL_NTS);
  397.       break;
  398.  
  399.      case IDM_COLUMN_PRIVS:
  400.       retcode = SQLColumnPrivileges(ci->hstmt,
  401.                                     CHKNULL(szQualifierVal), SQL_NTS,
  402.                                     CHKNULL(szOwnerVal), SQL_NTS,
  403.                                     CHKNULL(szTableVal), SQL_NTS,
  404.                                     CHKNULL(szColumnVal), SQL_NTS);
  405.       break;
  406.  
  407.      case IDM_SPECIAL_COLUMNS:
  408.       retcode = SQLSpecialColumns(ci->hstmt,
  409.                                   cati->fColType,
  410.                                   CHKNULL(szQualifierVal), SQL_NTS,
  411.                                   CHKNULL(szOwnerVal), SQL_NTS,
  412.                                   CHKNULL(szTableVal), SQL_NTS,
  413.                                   cati->fScope,
  414.                                   cati->fNullable);
  415.       break;
  416.  
  417.      case IDM_PROCEDURES:
  418.       retcode = SQLProcedures(ci->hstmt,
  419.                               CHKNULL(szQualifierVal), SQL_NTS,
  420.                               CHKNULL(szOwnerVal), SQL_NTS,
  421.                               CHKNULL(szProcsVal), SQL_NTS);
  422.       break;
  423.  
  424.      case IDM_PROC_COLUMNS:
  425.       retcode = SQLProcedureColumns(ci->hstmt,
  426.                                     CHKNULL(szQualifierVal), SQL_NTS,
  427.                                     CHKNULL(szOwnerVal), SQL_NTS,
  428.                                     CHKNULL(szProcsVal), SQL_NTS,
  429.                                     CHKNULL(szColumnVal), SQL_NTS);
  430.       break;
  431.  
  432.      default:
  433.       break;
  434.    }
  435.  
  436.    if(retcode != SQL_SUCCESS) {
  437.       PrintErrors(ci, SQL_HANDLE_STMT);
  438.       return;
  439.    }
  440.  
  441.    lstrcpy((LPSTR)szTitle, (LPSTR)ci->szClientTitle);
  442.    lstrcat((LPSTR)szTitle, (LPSTR)szCOLON);
  443.    lstrcat((LPSTR)szTitle, (LPSTR)cati->szDlgTitle);
  444.    if(ShowCatalogResults(ci, (LPSTR)szTitle))
  445.       return;
  446. }
  447.  
  448.  
  449. //*------------------------------------------------------------------------
  450. //| CatalogWndProc:
  451. //|   This windows procedure handles all of the catalog function messages.
  452. //|   Many things such as setting/getting text values are table driven.
  453. //|   This reduces overall code size significantly.
  454. //| Parms:
  455. //|   in       Standard window parms
  456. //| Returns:
  457. //|   Depends on message
  458. //*------------------------------------------------------------------------
  459. BOOL EXTFUN CatalogWndProc(HWND hDlg, unsigned msg, WPARAM wParam, LPARAM lParam)
  460. {
  461.    static CATALOGINFO FAR *   cati;
  462.    int                        dex;
  463.  
  464.    switch(msg) {
  465.      case WM_INITDIALOG:
  466.       cati = (CATALOGINFO FAR *)lParam;
  467.       CenterDialog(hDlg);
  468.  
  469.       // Set all default values for edit controls
  470.       for(dex=0;  dex<NumItems(CatalogVals);  dex++)
  471.          if(cati->mask & CatalogVals[dex].mMask) {
  472.             SetWindowText(GetDlgItem(hDlg, CatalogVals[dex].id),
  473.                           CatalogVals[dex].szStr);
  474.             SendMessage(GetDlgItem(hDlg, CatalogVals[dex].id), EM_LIMITTEXT,
  475.                         CatalogVals[dex].cbMax, 0L);
  476.          }
  477.       // Special case for dialogs with options
  478.       if(cati->id == IDM_STATISTICS) {
  479.          CheckRadioButton(hDlg, IDX_INDEX_UNIQUE, IDX_INDEX_ALL, IDX_INDEX_UNIQUE);
  480.          CheckRadioButton(hDlg, IDX_ENSURE, IDX_QUICK, IDX_ENSURE);
  481.       }
  482.       else if(cati->id == IDM_SPECIAL_COLUMNS) {
  483.          CheckRadioButton(hDlg, IDX_BEST_ROWID, IDX_ROWVER, IDX_BEST_ROWID);
  484.          CheckRadioButton(hDlg, IDX_NO_NULLS, IDX_NULLABLE, IDX_NO_NULLS);
  485.          CheckRadioButton(hDlg, IDX_SCOPE_CURROW, IDX_SCOPE_SESSION, IDX_SCOPE_CURROW);
  486.       }
  487.  
  488.       return TRUE;
  489.  
  490.  
  491.      case WM_COMMAND:
  492.       switch(GET_WM_COMMAND_ID(wParam, lParam)) {
  493.         case IDOK:
  494.          {
  495.             Busy(TRUE);
  496.             for(dex=0;  dex<NumItems(CatalogVals);  dex++)
  497.                if(cati->mask & CatalogVals[dex].mMask)
  498.                   GetText(GetDlgItem(hDlg, CatalogVals[dex].id),
  499.                           CatalogVals[dex].szStr);
  500.             // Special case for dialogs with options
  501.             if(cati->id == IDM_STATISTICS) {
  502.                cati->fUnique = GetRadioValue(hDlg, (IDXINFO FAR *)StatsfUnique, NumItems(StatsfUnique));
  503.                cati->fAccuracy = GetRadioValue(hDlg, (IDXINFO FAR *)StatsfAccuracy, NumItems(StatsfAccuracy));
  504.             }
  505.             else if(cati->id == IDM_SPECIAL_COLUMNS) {
  506.                cati->fColType = GetRadioValue(hDlg, (IDXINFO FAR *)SpecColsfColType,
  507.                                               NumItems(SpecColsfColType));
  508.                cati->fScope = GetRadioValue(hDlg, (IDXINFO FAR *)SpecColsfScope,
  509.                                             NumItems(SpecColsfScope));
  510.                cati->fNullable = GetRadioValue(hDlg, (IDXINFO FAR *)SpecColsfNullable,
  511.                                                NumItems(SpecColsfNullable));
  512.             }
  513.             DoCatalogFunction(cati);
  514.  
  515.             Busy(FALSE);
  516.             EndDialog(hDlg, IDOK);
  517.          }
  518.          return TRUE;
  519.  
  520.         case IDCANCEL:
  521.          SendMessage(hDlg, WM_CLOSE, 0, 0L);
  522.          EndDialog(hDlg, IDCANCEL);
  523.          return TRUE;
  524.       }
  525.       return TRUE;
  526.  
  527.      default:
  528.       return FALSE;
  529.    }
  530.    return FALSE;
  531. }
  532.  
  533.