home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Internet Business Development Kit / PRODUCT_CD.iso / sqlsvr / odbcsdk / samples / admndemo / admndemo.c next >
Encoding:
C/C++ Source or Header  |  1994-12-07  |  43.4 KB  |  1,554 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:    ADMNDEMO.C
  8. //|        This module contains the main interface modules for SATOOL, including
  9. //|            the MDI client support
  10. //*---------------------------------------------------------------------------------
  11. #include <windows.h>
  12. #include <windowsx.h>
  13. #include <stdlib.h>
  14. #include "w16macro.h"
  15. #include "admndemo.h"
  16. #include "sql.h"
  17. #include "sqlext.h"
  18. #include "ini.h"
  19. #include "dialogs.h"
  20. #include "odbcinst.h"
  21. #include "errcheck.h"
  22. #include "strings.h"
  23. VSZFile;
  24.  
  25.  
  26.  
  27. //*---------------------------------------------------------------------------------
  28. //|    Defines
  29. //*---------------------------------------------------------------------------------
  30. #define HLP_ADMNDEMO 50
  31.  
  32. typedef struct tagCMDLINE {
  33.     BOOL            fOptions;                            // TRUE if there are options
  34.     BOOL            fExit;                                // TRUE if we should exit when done 
  35.     char            szDriverConnect[100];            // String for SQLDriverConnect
  36.     char            szExecuteFile[255];                // File to execute
  37.     BOOL            fTrace;                                // TRUE to trace
  38.     char            szTraceFile[255];                    // File to log ODBC calls
  39.     char            szTerm[10];                            // Stmt terminator for file
  40.     int            cbStmt;                                // Maximum statement length
  41.     } CMDLINE;
  42.  
  43.  
  44. //*---------------------------------------------------------------------------------
  45. //|    Global variables
  46. //*---------------------------------------------------------------------------------
  47. HWND                     hwndFrame, hwndClient, hwndOutput;
  48. HINSTANCE             hInst;
  49. HENV                     henv=NULL;
  50. HMENU                 hMenu=NULL, hSubMenu=NULL;
  51. HICON                    hIcon=NULL, hResultsIcon=NULL, hConnectIcon=NULL;
  52. HFONT                    hSmallEditFont;
  53. RETCODE                 retcode;
  54. int                    iHelpCnt=0;                        // Tracks the 
  55. CHILDINFO FAR *     CreateCI=NULL;
  56. char                     OutStr[MAXBUFF];
  57. char                     szDirName[_MAX_PATH];
  58. char                    szDftFileFilter[MAXBUFF];
  59. CMDLINE                 cl;
  60.  
  61.  
  62. // Following is an array of connections and a global to track the current
  63. lpCHILDINFO            ConnectStructs[MAXCONNECTS];
  64. lpCHILDINFO         lpActiveConn=NULL;
  65. HWND                    hwndCurMDIChild=NULL;
  66.  
  67. extern UWORD                uMenuIDs[NUM_MENU_FLAGS];
  68. extern lpRESULTSINFO        lpActiveResults;
  69.  
  70.  
  71. dCSEG(char)    szFrameClass[]                         = "SAMDI:Frame";
  72. dCSEG(char)    szChildClass[]                            = "SACLASS:1";
  73. dCSEG(char)    szResultsClass[]                        = "SACLASS:2";
  74. dCSEG(char)    szWindowTitle[]                        = "ODBC Admin Demo";
  75. dCSEG(char) szHELPFILE[]                             = "..\\HELP\\ODBCSMPL.HLP";
  76.  
  77. dCSEG(char) szOPENFILE[]                             = "Open File";
  78. dCSEG(char) szSAVEFILE[]                            = "Save File";
  79. dCSEG(char) szUID[]                                    =    "UID=";
  80. dCSEG(char) szDSN[]                                    =    "DSN=";
  81. dCSEG(char) szNewLine[]                                =    "\r\n";
  82. dCSEG(char) szComma[]                                =    ", ";
  83.           
  84. dCSEG(char) szUserAt[]                                =    "%s@%s";
  85. dCSEG(char) szUserAtFile[]                            =    "%s@%s   File: %s";
  86.  
  87.  
  88.  
  89. //*---------------------------------------------------------------------------------
  90. //|    Local functions
  91. //*---------------------------------------------------------------------------------
  92. BOOL WINAPI Init(HANDLE hInstance,   HANDLE hPrevInstance,
  93.           LPSTR  lpszCmdLine, int    CmdShow);
  94. BOOL WINAPI SetUp(LPSTR szCmdLine, CMDLINE FAR * cl);
  95. void WINAPI CleanUp(void);
  96. long EXTFUN WndProc(HWND hwnd, unsigned msg, WORD wParam, LONG lParam);
  97. long EXTFUN PASCAL ChildWndProc(HWND hwnd, unsigned msg, WORD wParam, LONG lParam);
  98. BOOL EXTFUN PASCAL AboutWndProc(HWND hDlg, unsigned msg, WORD wParam, LONG lParam);
  99.  
  100. BOOL WINAPI ParseCommandLine(LPSTR szCmdLine, CMDLINE FAR * cl);
  101. BOOL WINAPI ParseOptionsValues(LPSTR instr, LPSTR szTerm, int cbTerm, int FAR * lpMax);
  102. VOID WINAPI DoConnect(HWND hwnd, DWORD dwData);
  103. BOOL WINAPI Connect(CHILDINFO FAR * ci, HWND hwnd, LPSTR szAutoConnect);
  104. VOID WINAPI DoDisconnect(lpCHILDINFO lpci);
  105. BOOL WINAPI Disconnect(CHILDINFO FAR * ci);
  106. void WINAPI DisplayAbout(HWND hwnd, HINSTANCE hInst);
  107. int  WINAPI DoMain(HANDLE hInstance);
  108. HWND INTFUN GetEditWindow(CHILDINFO FAR * ci);
  109.  
  110.  
  111. // File functions
  112. VOID WINAPI DoFileOpen(lpCHILDINFO lpci);
  113. VOID WINAPI DoFileSave(lpCHILDINFO lpci);
  114. VOID WINAPI DoFileSaveAs(lpCHILDINFO lpci);
  115.  
  116.  
  117.  
  118.  
  119. //*------------------------------------------------------------------------
  120. //| WinMain:
  121. //|     Parameters:
  122. //|         hInstance     - Handle to current Data Segment
  123. //|         hPrevInstance - Handle to previous Data Segment (NULL if none)
  124. //|         lpszCmdLine   - Long pointer to command line info
  125. //|         nCmdShow      - Integer value specifying how to start app.,
  126. //|                            (Iconic [7] or Normal [1,5])
  127. //*------------------------------------------------------------------------
  128. int PASCAL WinMain (HANDLE hInstance,
  129.                     HANDLE hPrevInstance,
  130.                     LPSTR  lpszCmdLine,
  131.                     int    nCmdShow)
  132. {
  133.     int             nReturn;
  134.  
  135.     if (Init(hInstance, hPrevInstance,lpszCmdLine,nCmdShow)) {
  136.         if(!SetUp(lpszCmdLine, &cl))            // Quit on errors
  137.             return 0;
  138.         nReturn = DoMain(hInstance);
  139.         CleanUp();
  140.         }
  141.     return nReturn;
  142. }
  143.  
  144.  
  145. //*---------------------------------------------------------------------------------
  146. //| Init:
  147. //|    This function will take care of initilization for the application.
  148. //| Parms:
  149. //|    in            hInstance                Data segment for this instance
  150. //|    in            hPrevInstance            Data segment for previous instance
  151. //|    in            lpszCmdLine                Command line parameters
  152. //|    in            nCmdShow                    Desired display method
  153. //| Returns:
  154. //|    TRUE        if function was successful
  155. //|    FALSE        if there was an error
  156. //*---------------------------------------------------------------------------------
  157. BOOL WINAPI Init(HANDLE hInstance,   HANDLE hPrevInstance,
  158.           LPSTR  lpszCmdLine, int    nCmdShow)
  159. {
  160.     WNDCLASS wc;
  161.  
  162.  
  163.     // Make sure the .ini file is there before creating anything
  164.     ResolveIniFile();
  165.  
  166.     hInst = hInstance;
  167.  
  168.     if(!hPrevInstance) {
  169.         // Register the Frame Window first
  170.         wc.style = CS_HREDRAW | CS_VREDRAW;
  171.         wc.lpfnWndProc = (WNDPROC)WndProc;
  172.         wc.cbClsExtra = 0;
  173.         wc.cbWndExtra = 0;
  174.         wc.hInstance = hInstance;
  175.         hIcon = wc.hIcon = LoadIcon(hInstance, "BASEICON");
  176.         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  177.         wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
  178.         wc.lpszMenuName = NULL;
  179.         wc.lpszClassName = szFrameClass;
  180.         if(!RegisterClass(&wc)) {
  181.             PostError((LPSTR)szRegisterClassFailed);
  182.             return FALSE;
  183.             }
  184.  
  185.         // Register the child window class
  186.         wc.style = CS_HREDRAW | CS_VREDRAW;
  187.         wc.lpfnWndProc = (WNDPROC)ChildWndProc;
  188.         wc.cbClsExtra = 0;
  189.         wc.cbWndExtra = sizeof(lpCHILDINFO FAR *);
  190.         wc.hInstance = hInstance;
  191.         hConnectIcon = wc.hIcon = LoadIcon(hInstance, "CONNECTICON");
  192.         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  193.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  194.         wc.lpszMenuName = NULL;
  195.         wc.lpszClassName = szChildClass;
  196.         if(!RegisterClass(&wc)) {
  197.             PostError((LPSTR)szRegisterClassFailed);
  198.             return FALSE;
  199.             }
  200.  
  201.         // Register the results output window class
  202.         wc.style = CS_HREDRAW | CS_VREDRAW;
  203.         wc.lpfnWndProc = (WNDPROC)ResultsWndProc;
  204.         wc.cbClsExtra = 0;
  205.         wc.cbWndExtra = sizeof(lpRESULTSINFO);
  206.         wc.hInstance = hInstance;
  207.         hResultsIcon = wc.hIcon = LoadIcon(hInstance, "RSLTICON");
  208.         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  209.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  210.         wc.lpszMenuName = NULL;
  211.         wc.lpszClassName = szResultsClass;
  212.         if(!RegisterClass(&wc)) {
  213.             PostError((LPSTR)szRegisterClassFailed);
  214.             return FALSE;
  215.             }
  216.         }
  217.  
  218.     hMenu = LoadMenu(hInstance, "BASEMENU");
  219.     hSubMenu = GetSubMenu(hMenu, IDM_WINDOW_POS);
  220.  
  221.     hwndFrame = CreateWindow(szFrameClass,
  222.             szWindowTitle,
  223.             WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  224.             CW_USEDEFAULT,
  225.             CW_USEDEFAULT,
  226.             CW_USEDEFAULT,
  227.             CW_USEDEFAULT,
  228.             NULL,
  229.             hMenu,
  230.             hInstance,
  231.             NULL);
  232.  
  233.     hwndClient = GetWindow(hwndFrame, GW_CHILD);
  234.     ShowWindow(hwndFrame, 
  235.             (GetPrivateProfileInt(szSCREEN, szMAX, 0, szLABINI) == 1) 
  236.             ? SW_SHOWMAXIMIZED : nCmdShow);
  237.     UpdateWindow(hwndFrame);
  238.  
  239.     return (BOOL)(hwndFrame!=NULL);
  240. }
  241.  
  242. //*------------------------------------------------------------------------
  243. //| DoMain:
  244. //|     This is the main loop for the application:
  245. //*------------------------------------------------------------------------
  246. int  WINAPI DoMain(HANDLE hInstance)
  247. {
  248.     MSG msg;
  249.     HANDLE hAccel;
  250.  
  251.     Ctl3dRegister(hInstance);
  252.     Ctl3dAutoSubclass(hInstance);
  253.  
  254.     SendMessage(hwndFrame, USER_INITAPP, 0, 0L);
  255.     hAccel = LoadAccelerators(hInstance,"BASEACCELS");
  256.     while(GetMessage(&msg, NULL, 0, 0)) {
  257.         if(!TranslateAccelerator(hwndFrame,hAccel,&msg) &&
  258.             !TranslateMDISysAccel(hwndClient, &msg)) {
  259.             TranslateMessage(&msg);
  260.             DispatchMessage(&msg);
  261.             }
  262.         }
  263.  
  264.     Ctl3dUnregister(hInstance);
  265.  
  266.     return msg.wParam;
  267. }
  268.  
  269.  
  270. //*---------------------------------------------------------------------------------
  271. //| DoCloseDown:
  272. //|    Clean up all of the global windows, handles, etc...   After this function
  273. //|    is called, the application may be killed off.
  274. //| Parms:
  275. //|    hwnd                    The window handle being destoryed, send only on main
  276. //| Returns:              
  277. //|    Nothing
  278. //*---------------------------------------------------------------------------------
  279. VOID WINAPI DoCloseDown(HWND hwnd)
  280. {
  281.     char        szTempBuf[10];
  282.  
  283.     // Close all connection windows
  284.     SendMessage(hwnd, WM_COMMAND, IDM_CLOSEALL, 0L);
  285.  
  286.     // Kill off the help file if we opened it.
  287.     if(iHelpCnt)
  288.         WinHelp(hwnd, szHELPFILE, HELP_QUIT, 0L);
  289.             
  290.     // Save our max/min state
  291.     wsprintf(szTempBuf, "%d", IsZoomed(hwnd));
  292.     WritePrivateProfileString(szSCREEN, szMAX, szTempBuf, szLABINI);
  293.  
  294.     // Destroy GDI objects
  295.     DeleteObject(hSmallEditFont);
  296.  
  297.     DestroyWindow(hwnd);
  298. }
  299.  
  300.  
  301. //*------------------------------------------------------------------------
  302. //| WndProc:
  303. //|     Handle requests for action:
  304. //*------------------------------------------------------------------------
  305. long EXTFUN WndProc(HWND        hwnd,
  306.                                 unsigned msg,
  307.                                 WORD        wParam,
  308.                                 LONG        lParam)
  309. {
  310.     switch(msg) {
  311.         case WM_CREATE:
  312.             {
  313.             LOGFONT                        lf;
  314.             CLIENTCREATESTRUCT            clientcreate;
  315.             
  316.             memset(&lf, 0, sizeof(LOGFONT));
  317.             lf.lfHeight = -10;
  318.             lf.lfWeight = FW_THIN;
  319.             lf.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
  320.             lstrcpy(lf.lfFaceName, szMSSansSerif);
  321.             hSmallEditFont = CreateFontIndirect(&lf);
  322.  
  323.             clientcreate.hWindowMenu = hSubMenu;
  324.             clientcreate.idFirstChild = IDM_FIRSTCHILD;
  325.             hwndClient = CreateWindow("MDICLIENT", NULL,
  326.                     WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | WS_CLIPSIBLINGS,
  327.                     0, 0, 0, 0, hwnd, 
  328.                     (HMENU)(1), hInst,
  329.                     (LPSTR)&clientcreate);
  330.             if(!hwndClient)
  331.                 return -1;
  332.             }
  333.             return 0;
  334.             
  335.             
  336.         // This user message is sent to handle any first steps once the 
  337.         //    application is up and ready for input.  We'll cause a connection
  338.         // to be done.
  339.         case USER_INITAPP:
  340.             SendMessage(hwnd, WM_COMMAND, IDM_CONNECT, 
  341.                         (cl.fOptions) ? (LPARAM)(LPSTR)cl.szDriverConnect : 0L);
  342.             if(lpActiveConn &&
  343.                 *cl.szExecuteFile)
  344.                 ExecuteFile(lpActiveConn, hwnd, cl.szExecuteFile, cl.szTerm, cl.cbStmt);
  345.             if(cl.fExit)
  346.                 SendMessage(hwnd, WM_COMMAND, IDM_EXIT, 0L);
  347.             return 0;
  348.  
  349.  
  350.         // 
  351.         // Hande the WM_INITMENUPOPUP message so that when the user selects
  352.         //        a menu, we enable/disable each item based on our current state.
  353.         //
  354.         case WM_INITMENUPOPUP:
  355.             if(!(BOOL)HIWORD(lParam))            // Not the system menu
  356.                 ResetMenu(hMenu, (int)LOWORD(lParam));
  357.             break;
  358.  
  359.         case WM_COMMAND:
  360.             switch(GET_WM_COMMAND_ID(wParam, lParam)) {
  361.                 //-------------------------------------------------------------------
  362.                 // The F6 key is a virtual key which toggles the cursor 
  363.                 // location from the input/output window.
  364.                 //-------------------------------------------------------------------
  365.                 case IDM_MOVE_WINDOW:
  366.                     {
  367.                     if(lpActiveConn) {
  368.                         DWORD        dwActive=SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0L);
  369. #ifndef WIN32
  370.                         HWND         Active = LOWORD(dwActive);
  371. #else
  372.                         HWND        Active = (HWND)(dwActive);
  373. #endif
  374.                         
  375.                         if(Active != lpActiveConn->hwnd) {
  376.                              SendMessage(hwndClient, WM_MDIACTIVATE, 
  377.                                      (WPARAM)(HWND)lpActiveConn->hwnd, 0L);
  378.                              return 0;
  379.                              }
  380.                         if(GetFocus() == lpActiveConn->hwndIn)
  381.                             SetFocus(lpActiveConn->hwndOut);
  382.                         else
  383.                             SetFocus(lpActiveConn->hwndIn);
  384.                         }
  385.                     }
  386.                     return 0;
  387.  
  388.  
  389.                 //-------------------------------------------------------------------
  390.                 // Connect Menu
  391.                 //-------------------------------------------------------------------
  392.                 case IDM_CONNECT:
  393.                     DoConnect(hwnd, lParam);
  394.                     return 0;
  395.  
  396.                 case IDM_DISCONNECT:
  397.                     DoDisconnect(lpActiveConn);
  398.                     return 0;
  399.             
  400.             case IDM_EXECUTE_FILE:
  401.                 ExecuteFile(lpActiveConn, hwnd, NULL, NULL, 0);
  402.                 return 0;
  403.             
  404.                 case IDM_OPEN:
  405.                     DoFileOpen(lpActiveConn);
  406.                     return 0;
  407.  
  408.                 case IDM_CLOSE:
  409.                     {
  410.                     // zzz:  Check for save if modified
  411.                     szWrite(lpActiveConn->hwndOut, 
  412.                                 GetidsString(idsFileClosed, OutStr, sizeof(OutStr)),
  413.                                 (LPSTR)lpActiveConn->szFile);
  414.  
  415.                     wsprintf((LPSTR)lpActiveConn->szClientTitle, szUserAt,
  416.                                 (LPSTR)lpActiveConn->CurrentUser, (LPSTR)lpActiveConn->CurrentServer);
  417.                     lpActiveConn->hFile = 0;
  418.                     ReleaseMemory(lpActiveConn->szFileBuff);
  419.                     SetWindowText(lpActiveConn->hwnd, lpActiveConn->szClientTitle);
  420.                     }
  421.                     return 0;
  422.  
  423.                 case IDM_SAVE:
  424.                DoFileSave(lpActiveConn);
  425.                     return 0;
  426.  
  427.                 case IDM_SAVEAS:
  428.                     DoFileSaveAs(lpActiveConn);
  429.                     return 0;
  430.  
  431.                 case IDM_EXIT:
  432.                     SendMessage(hwnd, WM_CLOSE, 0, 0L);
  433.                     return 0;
  434.  
  435.  
  436.                 //-------------------------------------------------------------------
  437.                 // Edit Menu
  438.                 //-------------------------------------------------------------------
  439.                 case IDM_UNDO:
  440.                 case IDM_CUT:
  441.                 case IDM_COPY:
  442.                 case IDM_PASTE:
  443.                     {
  444.                     HWND             fhwnd=GetEditWindow(lpActiveConn);
  445.  
  446.                     if(fhwnd)
  447.                         SendMessage(fhwnd, 
  448.                                     (wParam == IDM_CUT) ? WM_CUT : 
  449.                                     (wParam == IDM_COPY) ? WM_COPY : 
  450.                                     (wParam == IDM_PASTE) ? WM_PASTE : WM_UNDO,
  451.                                     0, 0L);
  452.                     }
  453.                     return 0;
  454.  
  455.                 case IDM_SELECT_ALL:
  456.                     {
  457.                     HWND                     fhwnd;
  458.  
  459.                     if(!(fhwnd = GetEditWindow(lpActiveConn)))
  460.                         break;
  461.                     SetFocus(fhwnd);
  462.                     SendMessage(fhwnd, EM_SETSEL, 0, MAKELPARAM(0, -1));
  463.                     }
  464.                     return 0;
  465.  
  466.  
  467.  
  468.                 //-------------------------------------------------------------------
  469.                 // Command Menu
  470.                 //-------------------------------------------------------------------
  471.                 case IDM_EXECUTE_NOW:
  472.                     ExecuteCmds(lpActiveConn, NULL);
  473.                     return 0;
  474.  
  475.                 case IDM_COMMIT:
  476.                 case IDM_ROLLBACK:
  477.                     DoCommitRollback(lpActiveConn, wParam);
  478.                     return 0;
  479.  
  480.  
  481.  
  482.                 //-------------------------------------------------------------------
  483.                 // Pipe Menu
  484.                 //-------------------------------------------------------------------
  485.                 case IDM_PIPE_EDIT:
  486.                     EditPipe(lpActiveConn);
  487.                     return 0;
  488.  
  489.                 case IDM_PIPE_DO:
  490.                     HandlePipe(lpActiveConn, lpActiveResults);
  491.                     return 0;
  492.  
  493.  
  494.  
  495.                 //-------------------------------------------------------------------
  496.                 // Info Menu
  497.                 //-------------------------------------------------------------------
  498.                 case IDM_MANAGE_DSNS:
  499.                     {
  500.                     HWND        fHwnd=GetFocus();
  501.                     
  502.                     SQLManageDataSources(hwnd);
  503.                     if(fHwnd)
  504.                         SetFocus(fHwnd);
  505.                     }
  506.                     return 0;
  507.  
  508.                 case IDM_DATA_TYPES:
  509.                     DisplayODBCDataTypes(lpActiveConn);
  510.                     return 0;
  511.  
  512.                 case IDM_FUNCTIONS:
  513.                     DisplayODBCFunctions(lpActiveConn);
  514.                     return 0;
  515.                     
  516.                 case IDM_DATA_SOURCES:
  517.                     DisplayODBCDataSources(lpActiveConn);
  518.                     return 0;
  519.                     
  520.                 case IDM_ODBC_INFO:
  521.                     DisplayGetInfo(lpActiveConn);
  522.                     return 0;
  523.  
  524.  
  525.  
  526.                 //-------------------------------------------------------------------
  527.                 // Lists Menu
  528.                 //-------------------------------------------------------------------
  529.                 case IDM_TABLES:
  530.                 case IDM_COLUMNS:
  531.                 case IDM_STATISTICS:
  532.                 case IDM_PRIMARY_KEYS:
  533.                 case IDM_FOREIGN_KEYS:
  534.                 case IDM_TABLE_PRIVS:
  535.                 case IDM_COLUMN_PRIVS:
  536.                 case IDM_SPECIAL_COLUMNS:
  537.                 case IDM_PROCEDURES:
  538.                 case IDM_PROC_COLUMNS:
  539.                     DoList(lpActiveConn, wParam);
  540.                     return 0;
  541.  
  542.  
  543.  
  544.                 //-------------------------------------------------------------------
  545.                 // Window Menu
  546.                 //-------------------------------------------------------------------
  547.             case IDM_FONT:
  548.                     PromptForFontName(hwnd);
  549.                 return 0;
  550.                 
  551.                 case IDM_CASCADE:
  552.                     SendMessage(hwndClient, WM_MDICASCADE, 0, 0L);
  553.                     return 0;
  554.  
  555.                 case IDM_TILE:
  556.                     SendMessage(hwndClient, WM_MDITILE, 0, 0L);
  557.                     return 0;
  558.  
  559.                 case IDM_ARRANGE:
  560.                     SendMessage(hwndClient, WM_MDIICONARRANGE, 0, 0L);
  561.                     return 0;
  562.  
  563.                 case IDM_CLOSEALL:
  564.                     {
  565.                     int            idex;
  566.                     int            iNum=NumItems(ConnectStructs);
  567.                     
  568.                     for(idex=0;  idex<iNum;  idex++)
  569.                         if(ConnectStructs[idex] != NULL)
  570.                             DoDisconnect(ConnectStructs[idex]);
  571.                      }
  572.                     return 0;
  573.  
  574.  
  575.  
  576.                 //-------------------------------------------------------------------
  577.                 // Help Menu
  578.                 //-------------------------------------------------------------------
  579.                 case IDM_HELP:
  580.                     iHelpCnt += WinHelp(hwnd, szHELPFILE, HELP_CONTEXT, HLP_ADMNDEMO);
  581.                     return 0;
  582.  
  583.                 case IDM_ABOUT:
  584.                     DisplayAbout(hwnd, hInst);
  585.                     return 0;
  586.                 }
  587.             break;
  588.  
  589.  
  590.         case WM_CLOSE:
  591.             DoCloseDown(hwnd);
  592.             return 0;
  593.             
  594.         case WM_DESTROY:
  595.             PostQuitMessage(0);
  596.             return 0;
  597.  
  598.  
  599.         default:
  600.             break;
  601.         }    
  602.  
  603.     return DefFrameProc(hwnd, hwndClient, msg, wParam, lParam);
  604. }
  605.  
  606.  
  607.  
  608. //*------------------------------------------------------------------------
  609. //| ChildWndProc:
  610. //|     Handle all messages which are received for the MDI child
  611. //|            windows.
  612. //*------------------------------------------------------------------------
  613. long EXTFUN ChildWndProc(HWND        hwnd,
  614.                                 unsigned msg,
  615.                                 WORD        wParam,
  616.                                 LONG        lParam)
  617. {
  618.     switch(msg) {
  619.         //
  620.         // When a successful connection is made, then we are called to
  621.         //        create a window to handle it.  The CHILDINFO structure has
  622.         //        already been allocated.
  623.         //
  624.         case WM_CREATE:
  625.             {
  626.             CREATESTRUCT FAR *         cs;
  627.             MDICREATESTRUCT FAR *     mdi;
  628.             lpCHILDINFO                 lpci;
  629.             
  630.             cs = (CREATESTRUCT FAR *)lParam;
  631.             mdi = (MDICREATESTRUCT FAR *)cs->lpCreateParams;
  632.             lpci = (lpCHILDINFO)mdi->lParam;
  633.  
  634.             SETCIPOINTER(hwnd, lpci);
  635.  
  636.             lpci->hwnd = hwnd;
  637.             lpci->hInst = hInst;
  638.             hwndClient = GetParent(hwnd);
  639.             hwndFrame = GetParent(hwndClient);
  640.             if(!(lpci->hwndIn = CreateWindow("edit", NULL,
  641.                             WS_CHILD | WS_VISIBLE | WS_VSCROLL |
  642.                             WS_BORDER | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 
  643.                             0, 0, 0, 0,
  644.                             hwnd, (HMENU)(3), hInst, NULL)))
  645.                 return -1;
  646.             if(!(lpci->hwndOut = CreateWindow("edit", NULL,
  647.                             WS_CHILD | WS_VISIBLE | WS_VSCROLL |
  648.                             WS_BORDER | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 
  649.                             0, 0, 0, 0,
  650.                             hwnd, (HMENU)(4), hInst, NULL)))
  651.                 return -1;
  652.             
  653.  
  654.             SendMessage(lpci->hwndIn, WM_SETFONT, 
  655.                         (WPARAM)hSmallEditFont, (LPARAM)MAKELONG((WORD)TRUE, 0));
  656.             SendMessage(lpci->hwndOut, WM_SETFONT, 
  657.                         (WPARAM)hSmallEditFont, (LPARAM)MAKELONG((WORD)TRUE, 0));
  658.  
  659.             szWrite(lpci->hwndOut, 
  660.                         GetidsString(idsSuccessConnect, OutStr, sizeof(OutStr)),
  661.                         (LPSTR)lpci->CurrentUser, (LPSTR)lpci->CurrentServer);
  662.             }
  663.             return 0;
  664.             
  665.         //
  666.         // NOTE:  We must break to return DefMDIWndProc in order for the menu to
  667.         //        be redrawn when we maximize the child window.
  668.         //
  669.         case WM_SIZE:
  670.             {
  671.             lpCHILDINFO            lpci;
  672.             int                    di, dot;
  673.             
  674.             lpci = GETCIPOINTER(hwnd);
  675.  
  676.             lpci->dx = LOWORD(lParam);
  677.             lpci->dy = HIWORD(lParam);
  678.             di = lpci->dy * 1 / 2;
  679.             dot = lpci->dy - di;
  680.             MoveWindow(lpci->hwndIn, 0, 0, lpci->dx, di, TRUE);
  681.             MoveWindow(lpci->hwndOut, 0, di, lpci->dx, dot, TRUE);
  682.             }
  683.             break;
  684.  
  685.  
  686.         // 
  687.         // Handle the WM_INITMENUPOPUP message so that when the user selects
  688.         //        a menu, we enable/disable each item based on our current state.
  689.         //
  690.         case WM_INITMENUPOPUP:
  691.             if(!(BOOL)HIWORD(lParam))            // Not the system menu
  692.                 ResetMenu((HMENU)wParam, (int)LOWORD(lParam));
  693.             break;
  694.  
  695.  
  696.         //
  697.         // All messages are handled in the main wnd proc, so pass them back
  698.         //
  699.         case WM_COMMAND:
  700.             {
  701.             UINT            id=GET_WM_COMMAND_ID(wParam, lParam);
  702.             
  703.             if(id >= IDM_CONNECT &&
  704.                 id <= IDM_MOVE_WINDOW)
  705.                 SendMessage(hwndFrame, WM_COMMAND, wParam, lParam);
  706.             }
  707.             break;
  708.         
  709.  
  710.         //
  711.         // The WM_MDIACTIVATE message is received first by the child window
  712.         //        which is losing focus, then by the window which is receiving
  713.         //        focus.
  714.         //
  715.         case WM_MDIACTIVATE:
  716.             {
  717. #ifndef WIN32
  718.             if(wParam) {
  719.                 lpActiveConn = GETCIPOINTER((HWND)LOWORD(lParam));
  720.                 }
  721. #else
  722.             if((HWND)lParam == hwnd) {
  723.                 lpActiveConn = GETCIPOINTER((HWND)lParam);
  724.                 }
  725. #endif
  726.             else
  727.                 lpActiveConn = NULL;
  728.                 
  729.             if(lpActiveConn) {
  730.                 hwndCurMDIChild = lpActiveConn->hwnd;
  731.                 SetFocus(lpActiveConn->hwndIn);
  732.                 }
  733.             }
  734.             return 0;
  735.  
  736.       
  737.         //
  738.         // Check for a system close command.  This is the equivalent of a
  739.         //     Disconnect, so process it as such.
  740.         //
  741.         case WM_SYSCOMMAND:
  742.             {
  743.             if(wParam == SC_CLOSE) {
  744.                 SendMessage(hwnd, WM_COMMAND, IDM_DISCONNECT, 0L);
  745.                 return 0;
  746.                 }
  747.             }
  748.             break;
  749.             
  750.         default:
  751.             break;
  752.         }
  753.  
  754.     return DefMDIChildProc(hwnd, msg, wParam, lParam);
  755. }
  756.  
  757.  
  758.  
  759. //*---------------------------------------------------------------------------------
  760. //| SetUp:
  761. //|    This function handles one-time setup operations for the app.  This includes
  762. //|    allocating an environment handle for ODBC, and processing the command
  763. //|    line.
  764. //| Parms:
  765. //|    szCmdLine            Command line arguments
  766. //|    cl                        Command line strucutre for return
  767. //| Returns:              
  768. //|    FALSE if there was an error
  769. //*---------------------------------------------------------------------------------
  770. BOOL WINAPI SetUp(LPSTR szCmdLine, CMDLINE FAR * cl)
  771. {
  772.     LPSTR    str;
  773.  
  774.    // Load default resource strings
  775.    GetidsString(idsDftFileFilter, szDftFileFilter, sizeof(szDftFileFilter));
  776.    str = (LPSTR)szDftFileFilter;
  777.    while((str = strchr(str, '|')))
  778.        *str++ = '\0';
  779.  
  780.     if(SQL_SUCCESS != SQLAllocEnv(&henv)) {
  781.         szMessageBox(GetActiveWindow(), 
  782.                         MB_ICONEXCLAMATION,
  783.                         (LPSTR)szErrTitle,
  784.                         GetidsString(idsSQLAllocEnvFailed, OutStr, sizeof(OutStr))); 
  785.         return FALSE;
  786.         }
  787.  
  788.     if(!ParseCommandLine(szCmdLine, cl))
  789.         return FALSE;    
  790.     
  791.     if(cl->fTrace) {
  792.         if(SQL_SUCCESS != 
  793.                 (retcode = SQLSetConnectOption(NULL, SQL_OPT_TRACEFILE, 
  794.                                 (UDWORD)(LPSTR)cl->szTraceFile)))
  795.             DisplayErrors(NULL, GetidsString(idsSQLSetConnectOption, OutStr, sizeof(OutStr)),
  796.                         henv, NULL, NULL);
  797.  
  798.         if(SQL_SUCCESS != 
  799.                 (retcode = SQLSetConnectOption(NULL, SQL_OPT_TRACE, TRUE)))
  800.             DisplayErrors(NULL, GetidsString(idsSQLSetConnectOption, OutStr, sizeof(OutStr)),
  801.                         henv, NULL, NULL);
  802.         }
  803.  
  804.     return TRUE;
  805. }
  806.  
  807.  
  808.  
  809.  
  810. //*------------------------------------------------------------------------
  811. //| CleanUp:
  812. //|     Any last-minute application cleanup activities are done here:
  813. //*------------------------------------------------------------------------
  814. void WINAPI CleanUp(void)
  815. {
  816.     retcode = SQLFreeEnv(henv);
  817.  
  818. #ifdef DEBUGGING
  819.     {
  820.     retcode = SQLSetConnectOption(NULL, SQL_OPT_TRACE, FALSE);
  821.     WinAssert(retcode == SQL_SUCCESS, (LPSTR)"SetConnect: SQL_OPT_TRACE");
  822.     }
  823. #endif
  824. }
  825.  
  826.  
  827. //*---------------------------------------------------------------------------------
  828. //| ParseCommandLine:
  829. //|    This function will break down the command line and look for common elements.
  830. //| Parms:
  831. //|    instr                    The input string to look at
  832. //|    cl                        Command line strucutre to store info
  833. //| Returns:              
  834. //|    FALSE on error
  835. //*---------------------------------------------------------------------------------
  836. BOOL WINAPI ParseCommandLine(LPSTR instr, CMDLINE FAR * cl)
  837. {
  838.     LPSTR        str=instr;
  839.     LPSTR        endstr=str;
  840.     
  841.     if(!str)
  842.         return TRUE;
  843.  
  844.    // Assume some defaults
  845.    memset(cl, 0, sizeof(CMDLINE));
  846.     cl->cbStmt = 1000;
  847.     lstrcpy(cl->szTerm, (LPSTR)"\r\n");
  848.     cl->fExit = FALSE;
  849.         
  850.     // Look for each / value.  Spaces are allowed.  Any other character
  851.     // at this level is a syntax error
  852.     while(endstr && *str)
  853.         switch(*str) {
  854.             // We have encountered a command line switch.  See which it is
  855.             case '/':
  856.             case '-':
  857.                 ++str;
  858.                 switch(*str) {
  859.                     // /D[] for driver connection string
  860.                     case 'D':
  861.                     case 'd':
  862.                         ++str;
  863.                         if(*str != '[' ||
  864.                             !(endstr = strchr(str, ']')))
  865.                             goto tokenerr;
  866.                         *endstr = '\0';
  867.                         if(lstrlen(cl->szDriverConnect) > sizeof(cl->szDriverConnect))
  868.                             goto toobig;
  869.                         lstrcpy(cl->szDriverConnect, str + 1);
  870.                         str = endstr + 1;
  871.                         cl->fOptions = TRUE;
  872.                         break;
  873.                         
  874.                     // /F for file name to execute
  875.                     case 'F':
  876.                     case 'f':
  877.                         if((endstr = strchr(++str, ' '))) 
  878.                             *endstr = '\0';
  879.                         if(lstrlen(cl->szExecuteFile) > sizeof(cl->szExecuteFile))
  880.                             goto toobig;
  881.                         lstrcpy(cl->szExecuteFile, str);
  882.                         str = endstr + 1;
  883.                         break;
  884.                         
  885.                     // /O for options
  886.                     case 'O':
  887.                     case 'o':
  888.                         if((endstr = strchr(++str, ' ')))
  889.                             *endstr = '\0';
  890.                         if(!ParseOptionsValues(str, cl->szTerm, sizeof(cl->szTerm), &cl->cbStmt))
  891.                             goto tokenerr;
  892.                         str = endstr + 1;
  893.                         break;
  894.                         
  895.                     // /T for a trace file name
  896.                     case 'T':
  897.                     case 't':
  898.                         if((endstr = strchr(++str, ' ')))
  899.                             *endstr = '\0';
  900.                         if(lstrlen(cl->szTraceFile) > sizeof(cl->szTraceFile))
  901.                             goto toobig;
  902.                         lstrcpy(cl->szTraceFile, str);
  903.                         str = endstr + 1;
  904.                         cl->fTrace = TRUE;
  905.                         break;
  906.                         
  907.                     // /X for exit option
  908.                     case 'X':
  909.                     case 'x':
  910.                         ++str;
  911.                         if(str &&
  912.                             (*str == 'Y' || *str == 'y'))
  913.                             cl->fExit = TRUE;
  914.                         else if(*str == 'N' || *str == 'n')
  915.                             cl->fExit = FALSE;
  916.                         else
  917.                             goto tokenerr;
  918.                         ++str;
  919.                         break;
  920.                         
  921.                     // Not a valid argument, error
  922.                     default:
  923.                         goto tokenerr;
  924.                     }
  925.                 break;    // End of '/' or '-'
  926.             
  927.             case ' ':
  928.                 ++str;
  929.                 break;
  930.                 
  931.             default:
  932.                 goto tokenerr;
  933.             }
  934.     return TRUE;
  935.  
  936. tokenerr:
  937.     szMessageBox(GetActiveWindow(), 
  938.             MB_ICONEXCLAMATION,
  939.             (LPSTR)szErrTitle,
  940.             GetidsString(idsInvalidCmdLine, OutStr, sizeof(OutStr)));
  941.     return FALSE;
  942.     
  943. toobig:
  944.     szMessageBox(GetActiveWindow(), 
  945.             MB_ICONEXCLAMATION,
  946.             (LPSTR)szErrTitle,
  947.             GetidsString(idsCmdLineTooBig, OutStr, sizeof(OutStr)));
  948.     return FALSE;
  949. }
  950.  
  951.  
  952. //*---------------------------------------------------------------------------------
  953. //| ParseOptionsValues:
  954. //|    This function breaks down the /O switch by returning the invidual elements.
  955. //| Parms:
  956. //|    instr                    The string to parse
  957. //|    szTerm                Terminator value
  958. //|    cbTerm                Max for terminator value
  959. //|    lpMax                    Maximum size for statement execution
  960. //| Returns:              
  961. //|    FALSE on error
  962. //*---------------------------------------------------------------------------------
  963. BOOL WINAPI ParseOptionsValues(LPSTR instr, LPSTR szTerm, int cbTerm, int FAR * lpMax)
  964. {
  965.     LPSTR str=instr;
  966.     LPSTR endstr=instr;
  967.     char     cApost = '\'';
  968.    
  969.     // Now look for user specific values
  970.     while(endstr && *str) 
  971.         switch(*str) {
  972.             // Found the terminator
  973.             case 'T':
  974.             case 't':
  975.                 // Could be a Carriage return or a string
  976.                 ++str;
  977.                 if(*str == cApost) {
  978.                     if(!(endstr = strchr(++str, cApost)))
  979.                         return FALSE;
  980.                     *endstr = '\0';
  981.                     if(lstrlen(str) > cbTerm)
  982.                         return FALSE;
  983.                     lstrcpy(szTerm, str);
  984.                     str = endstr + 1;
  985.                     }
  986.                 else if(strncmp(str, "CR", 2) != 0)
  987.                     return FALSE;
  988.                 else {
  989.                     lstrcpy(szTerm, (LPSTR)"\r\n");
  990.                     str += 2;
  991.                     }
  992.                 break;
  993.                 
  994.             // Found the Maximum length value
  995.             case 'M':
  996.             case 'm':
  997.                 ++str;
  998.                 if((endstr = strchr(str, ':')))
  999.                     *endstr = '\0';
  1000.                 *lpMax = lpatoi(str);
  1001.                 if(*lpMax < MINSTMTSIZE ||
  1002.                     *lpMax > MAXSTMTSIZE)
  1003.                     return FALSE;
  1004.                 str = endstr + 1;
  1005.                 break;
  1006.                 
  1007.             // Ignore delimiter
  1008.             case ':':
  1009.                 ++str;
  1010.                 break;
  1011.                 
  1012.             // This is an error
  1013.             default:
  1014.                 return FALSE;
  1015.                 break;
  1016.             }
  1017.     return TRUE;
  1018. }
  1019.  
  1020.  
  1021. //*---------------------------------------------------------------------------------
  1022. //| DoConnect:
  1023. //|    Handle the structures involved in creating a connection window.  Invoke the
  1024. //|    Connect function to do the actual ODBC work.
  1025. //| Parms:
  1026. //|    hwnd                    The parent window handle for the new child
  1027. //|    dwData                Indicates a start code or string.
  1028. //| Returns:              
  1029. //|    Nothing
  1030. //*---------------------------------------------------------------------------------
  1031. VOID WINAPI DoConnect(HWND hwnd, DWORD dwData)
  1032. {
  1033.     lpCHILDINFO            citmp;
  1034.     MDICREATESTRUCT    mdicreate;
  1035.     int                    idex;
  1036.     
  1037.     for(idex=0;  idex<MAXCONNECTS;  idex++)
  1038.         if(!ConnectStructs[idex])
  1039.             break;
  1040.  
  1041.     // See if we have exceeded the max connects
  1042.     if(idex >= MAXCONNECTS) {
  1043.         szMessageBox(hwnd, 
  1044.                 MB_ICONINFORMATION | MB_OK,
  1045.                 (LPSTR)szErrTitle,
  1046.                 GetidsString(idsTooManyConnects, OutStr, sizeof(OutStr)),
  1047.                 MAXCONNECTS); 
  1048.         return;
  1049.         }
  1050.  
  1051.     citmp = (lpCHILDINFO)GetMemory(sizeof(CHILDINFO));
  1052.     if(!citmp)
  1053.         return;
  1054.  
  1055.     memset(citmp, 0, sizeof(CHILDINFO));
  1056.  
  1057.     if(Connect(citmp, hwnd, 
  1058.                 (HIWORD(dwData) == 1) ? NULL : (LPSTR)dwData)) {  // Pass NULL if accelerator used
  1059.         // We are connected, save the handle
  1060.         ConnectStructs[idex] = citmp;
  1061.         
  1062.         // Now fill out the rest
  1063.         citmp->hwndClient = hwndClient;
  1064.         citmp->henv = henv;                            // Keep local copy of global
  1065.     
  1066.         wsprintf((LPSTR)citmp->szClientTitle, szUserAt, (LPSTR)citmp->CurrentUser,
  1067.                     (LPSTR)citmp->CurrentServer);
  1068.         mdicreate.szClass = szChildClass;
  1069.         mdicreate.szTitle = citmp->szClientTitle;
  1070.         mdicreate.hOwner  = hInst;
  1071.         mdicreate.x            = CW_USEDEFAULT;
  1072.         mdicreate.y            = CW_USEDEFAULT;
  1073.         mdicreate.cx        = CW_USEDEFAULT;
  1074.         mdicreate.cy        = CW_USEDEFAULT;
  1075.         mdicreate.style    = (hwndCurMDIChild) ? ((IsZoomed(hwndCurMDIChild)) ? WS_MAXIMIZE : 0) : 0;
  1076.         mdicreate.lParam    = (LPARAM)citmp;
  1077.         SendMessage(hwndClient, WM_MDICREATE, 0,
  1078.                 (LPARAM)(LPMDICREATESTRUCT)&mdicreate);
  1079.         }
  1080.     else {
  1081.         // No connect made, so release all memory
  1082.         retcode = SQLFreeConnect(citmp->hdbc);
  1083.         ReleaseMemory(citmp);
  1084.         }
  1085. }
  1086.  
  1087.  
  1088. //*---------------------------------------------------------------------------------
  1089. //| Connect:
  1090. //|    This function attempts to make a connection.  If the user has specified the
  1091. //|    /D command line option, then we will simply use the connection string.
  1092. //| Parms:
  1093. //|    ci                        Connection window information
  1094. //|    hwnd                    Window handle for any prompting
  1095. //|    szAutoConnect        NULL if prompt, else pointer to szConnStrIn
  1096. //| Returns:              
  1097. //|    FALSE on error
  1098. //*---------------------------------------------------------------------------------
  1099. BOOL WINAPI Connect(CHILDINFO FAR * ci, HWND hwnd, LPSTR szAutoConnect)
  1100. {
  1101.     SWORD         cb;
  1102.     RETCODE        rc;
  1103.     UWORD            fExists;
  1104.     int            idex;
  1105.  
  1106.     if(SQL_SUCCESS != (retcode = SQLAllocConnect(henv, &ci->hdbc))) {
  1107.         szMessageBox(GetActiveWindow(), 
  1108.                 MB_ICONEXCLAMATION | MB_OK,
  1109.                 (LPSTR)szErrTitle,
  1110.                 GetidsString(idsSQLAllocConnectFailed, OutStr, sizeof(OutStr))); 
  1111.         return FALSE;
  1112.         }
  1113.  
  1114.  
  1115.     // Do the connection
  1116.     if(!szAutoConnect)
  1117.         retcode = SQLDriverConnect(ci->hdbc, hwnd, NULL, 0, ci->szConnStrOut, 
  1118.             MAXBUFF, &cb, SQL_DRIVER_COMPLETE);
  1119.     else
  1120.         retcode = SQLDriverConnect(ci->hdbc, hwnd, szAutoConnect, SQL_NTS,
  1121.             ci->szConnStrOut, MAXBUFF, &cb, SQL_DRIVER_NOPROMPT);
  1122.     if(retcode == SQL_NO_DATA_FOUND)
  1123.         return FALSE;
  1124.     else if(retcode == SQL_ERROR) {
  1125.         PrintErrors(ci);
  1126.         return FALSE;
  1127.         }
  1128.  
  1129.     if(RC_SUCCESSFUL(retcode)) {
  1130.         SWORD len;
  1131.  
  1132.         retcode = SQLGetInfo(ci->hdbc, SQL_USER_NAME, ci->CurrentUser,
  1133.                 sizeof(ci->CurrentUser), &len);
  1134.         if(retcode == SQL_ERROR || len == 0)    // Assume driver not capable
  1135.             *ci->CurrentUser = '\0';
  1136.  
  1137.         retcode = SQLGetInfo(ci->hdbc, SQL_DATA_SOURCE_NAME, ci->CurrentServer,
  1138.                 sizeof(ci->CurrentServer), NULL);
  1139.         }
  1140.  
  1141.     if(SQL_SUCCESS != (retcode = SQLAllocStmt(ci->hdbc, &ci->hstmt))) {
  1142.         szMessageBox(GetActiveWindow(), 
  1143.                     MB_ICONEXCLAMATION,
  1144.                     (LPSTR)szErrTitle,
  1145.                     GetidsString(idsSQLAllocEnvFailed, OutStr, sizeof(OutStr))); 
  1146.         return FALSE;
  1147.         }
  1148.  
  1149.     //
  1150.     // Find out what functions are supported and store them in a bitmask
  1151.     //
  1152.     memset(&ci->fFunctions, 0, sizeof(ci->fFunctions));
  1153.     for(idex=0;  idex<NUM_MENU_FLAGS;  idex++) {
  1154.         rc = SQLGetFunctions(ci->hdbc,
  1155.                     uMenuIDs[idex],
  1156.                     &fExists);
  1157.         if(RC_NOTSUCCESSFUL(rc)) {
  1158.             fExists = FALSE;       
  1159.             PrintErrors(ci);
  1160.             }
  1161.  
  1162.         if(fExists)
  1163.             BitSet(ci->fFunctions, idex);
  1164.         }
  1165.     
  1166.     return TRUE;
  1167. }
  1168.  
  1169.  
  1170. int WINAPI GetConnDex(lpCHILDINFO lpci)
  1171. {
  1172.     int idex;
  1173.     
  1174.     for(idex=0;  idex<MAXCONNECTS;  idex++)
  1175.         if(lpci == ConnectStructs[idex])
  1176.             return idex;
  1177.  
  1178.     return -1;    
  1179. }
  1180.  
  1181.  
  1182. //*---------------------------------------------------------------------------------
  1183. //| DoDisconnect:
  1184. //|    Look for the handle passed in and then disconnect it.  The Disconnect function
  1185. //|    is used to do the ODBC portion.
  1186. //| Parms:
  1187. //|    lpci                    Connect window to free
  1188. //| Returns:              
  1189. //|    Nothing
  1190. //*---------------------------------------------------------------------------------
  1191. VOID WINAPI DoDisconnect(lpCHILDINFO lpci)
  1192. {
  1193.     int            idex;
  1194.     
  1195.     idex = GetConnDex(lpci);
  1196.     if(idex == -1)
  1197.         return;
  1198.  
  1199.     if(Disconnect(lpci)) {
  1200.         FreeConnectWindowResults(lpci);
  1201.         SendMessage(hwndClient, WM_MDIDESTROY, (WPARAM)(HWND)lpci->hwnd, 0L);
  1202.         ConnectStructs[idex] = NULL;
  1203.         }
  1204. }
  1205.  
  1206.  
  1207. //*------------------------------------------------------------------------
  1208. //| Disconnect:
  1209. //|     Make a connection to a server.
  1210. //*------------------------------------------------------------------------
  1211. BOOL WINAPI Disconnect(CHILDINFO FAR * ci)
  1212. {
  1213.     if(SQL_SUCCESS != (retcode = SQLFreeStmt(ci->hstmt, SQL_DROP)))
  1214.         DisplayErrors(ci->hwnd, GetidsString(idsSQLFreeStmt, OutStr, sizeof(OutStr)),
  1215.                 ci->henv, ci->hdbc, ci->hstmt);
  1216.     if(SQL_SUCCESS != (retcode = SQLDisconnect(ci->hdbc)))
  1217.         DisplayErrors(ci->hwnd, GetidsString(idsSQLDisconnect, OutStr, sizeof(OutStr)),
  1218.                 ci->henv, ci->hdbc, ci->hstmt);
  1219.     if(SQL_SUCCESS != (retcode = SQLFreeConnect(ci->hdbc)))
  1220.         DisplayErrors(ci->hwnd, GetidsString(idsSQLFreeConnect, OutStr, sizeof(OutStr)),
  1221.                 ci->henv, ci->hdbc, ci->hstmt);
  1222.  
  1223.     ci->hstmt = ci->hdbc = NULL;
  1224.     szWrite(ci->hwndOut,
  1225.               GetidsString(idsDisconnectSuccess, OutStr, sizeof(OutStr)));
  1226.  
  1227.     return TRUE;
  1228. }
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236. //*------------------------------------------------------------------------
  1237. //| DisplayAbout:
  1238. //|     Display the about box for this app.
  1239. //*------------------------------------------------------------------------
  1240. void WINAPI DisplayAbout(HWND hwnd, HINSTANCE hInst)
  1241. {
  1242.     DLGPROC     dlgproc;
  1243.     HWND        fHwnd=GetFocus();
  1244.  
  1245.     dlgproc = MakeProcInstance(AboutWndProc, hInst);
  1246.     if(-1 == DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, dlgproc,
  1247.             (LPARAM)(HINSTANCE FAR * )&hInst))
  1248.         MessageBox(hwnd, "Could not open dialog box.",
  1249.             "About", MB_ICONEXCLAMATION);
  1250.     FreeProcInstance((FARPROC) dlgproc);
  1251.     
  1252.     if(fHwnd)
  1253.         SetFocus(fHwnd);
  1254. }
  1255.  
  1256.  
  1257.  
  1258. //*------------------------------------------------------------------------
  1259. //| AboutWndProc:
  1260. //|     Handle the About messages
  1261. //*------------------------------------------------------------------------
  1262. BOOL EXTFUN AboutWndProc(HWND        hDlg,
  1263.                                         unsigned msg,
  1264.                                         WORD        wParam,
  1265.                                         LONG        lParam)
  1266. {
  1267.     int x=10,y=30;
  1268.     static HINSTANCE FAR *     lpHINST;
  1269.  
  1270.     switch(msg) {
  1271.         case WM_INITDIALOG:
  1272.             lpHINST = (HINSTANCE FAR *)lParam;
  1273.             CenterDialog(hDlg);
  1274.             return TRUE;
  1275.  
  1276.         case WM_COMMAND:
  1277.             SendMessage(hDlg, WM_CLOSE, 0, 0L);
  1278.             return TRUE;
  1279.  
  1280.  
  1281.         case WM_CLOSE:
  1282.             EndDialog(hDlg, FALSE);
  1283.             return TRUE;
  1284.  
  1285.  
  1286.         default:
  1287.             return FALSE;
  1288.         }
  1289. }
  1290.  
  1291.  
  1292.  
  1293. //*------------------------------------------------------------------------
  1294. //| Busy:
  1295. //|     Display the hour glass cursor when we are working
  1296. //|            flag = TRUE means we are busy to so display it
  1297. //|            flag = FALSE means go back to old cursor
  1298. //*------------------------------------------------------------------------
  1299. void Busy(int flag)
  1300. {
  1301.     static HCURSOR    hCursor;                        // Save old cursor handle
  1302.  
  1303.     ShowCursor(FALSE);
  1304.     if(flag)
  1305.         hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1306.     else
  1307.         SetCursor(hCursor);
  1308.     ShowCursor(TRUE);
  1309. }
  1310.  
  1311.  
  1312.  
  1313. //*---------------------------------------------------------------------------------
  1314. //| iLoadString:
  1315. //|    This function will retrieve a string from our resource fork and place it
  1316. //|        in the buffer provided.  If the string is not found, an empty string
  1317. //|        is returned.
  1318. //| Parms:
  1319. //|    in            id                            String number to retrieve
  1320. //|    in            str                        Output string
  1321. //|    in            len                        Lenth of possible output
  1322. //| Returns:              
  1323. //|    Pointer to buffer str
  1324. //*---------------------------------------------------------------------------------
  1325. LPSTR iLoadString(int id, LPSTR str, int len)
  1326. {
  1327.     if(!str ||
  1328.         len <= 0)
  1329.         return str;
  1330.     
  1331.     if(!LoadString(hInst, id, str, len))
  1332.         *str = '\0';
  1333.     return str;
  1334. }
  1335.  
  1336.  
  1337. //*---------------------------------------------------------------------------------
  1338. //| GetEditWindow:
  1339. //|    This function will get the current focus window and verify that it is
  1340. //|    an edit window which is valid for one of the Edit menu items.
  1341. //| Parms:
  1342. //|    lpci                        Connection window information
  1343. //| Returns:              
  1344. //|    Edit window handle if valid, NULL if not valid
  1345. //*---------------------------------------------------------------------------------
  1346. HWND INTFUN GetEditWindow(lpCHILDINFO lpci)
  1347. {
  1348.     HWND hwnd;
  1349.     hwnd = GetFocus();
  1350.  
  1351.     if(hwnd && lpci) {
  1352.         if(hwnd == lpci->hwndIn ||
  1353.             hwnd == lpci->hwndOut)
  1354.             return hwnd;
  1355.         }
  1356.     
  1357.     return NULL;
  1358. }
  1359.  
  1360.  
  1361. //*------------------------------------------------------------------------
  1362. //| CenterDialog:
  1363. //|        Center the dialog over the parent window.  It is possible that
  1364. //|            their is not a parent window, since the Translate DLL was
  1365. //|            never meant to display data.  For this reason, we may just
  1366. //|            center over the entire screen.
  1367. //*------------------------------------------------------------------------
  1368. void WINAPI  CenterDialog(HWND hdlg)
  1369. {
  1370.     RECT  rcParent;                         // Parent window client rect
  1371.     RECT  rcDlg;                            // Dialog window rect
  1372.     int   nLeft, nTop;                      // Top-left coordinates
  1373.     int   cWidth, cHeight;                  // Width and height
  1374.     HWND    hwnd;
  1375.  
  1376.     // Get frame window client rect in screen coordinates
  1377.     if((hwnd = GetParent(hdlg)) == NULL) {
  1378.         rcParent.top = rcParent.left = 0;
  1379.         rcParent.right = GetSystemMetrics(SM_CXFULLSCREEN);
  1380.         rcParent.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
  1381.         }
  1382.     else 
  1383.         GetWindowRect(hwnd, &rcParent);
  1384.  
  1385.     // Determine the top-left point for the dialog to be centered
  1386.     GetWindowRect(hdlg, &rcDlg);
  1387.     cWidth  = rcDlg.right  - rcDlg.left;
  1388.     cHeight = rcDlg.bottom - rcDlg.top;
  1389.     nLeft   = rcParent.left + 
  1390.             (((rcParent.right  - rcParent.left) - cWidth ) / 2);
  1391.     nTop    = rcParent.top  +
  1392.             (((rcParent.bottom - rcParent.top ) - cHeight) / 2);
  1393.     if (nLeft < 0) nLeft = 0;
  1394.     if (nTop  < 0) nTop  = 0;
  1395.  
  1396.     // Place the dialog
  1397.     MoveWindow(hdlg, nLeft, nTop, cWidth, cHeight, TRUE);
  1398.     return;
  1399. }
  1400.  
  1401.  
  1402. //*---------------------------------------------------------------------------------
  1403. //| DoFileOpen:
  1404. //|    Use the commond dialog functions to open a file.
  1405. //| Parms:
  1406. //|    lpci                            Connection window information
  1407. //| Returns:              
  1408. //|    Nothing
  1409. //*---------------------------------------------------------------------------------
  1410. VOID WINAPI DoFileOpen(lpCHILDINFO lpci)
  1411. {
  1412.     OPENFILENAME        ofn;
  1413.     HWND                    fHwnd=GetFocus();
  1414.  
  1415.  
  1416.     // If user has a file open already, verify that we should continue
  1417.     if(lpci->hFile) {
  1418.         if(IDYES == szMessageBox(lpci->hwnd, 
  1419.                             MB_YESNO,
  1420.                             (LPSTR)szOPENFILE,
  1421.                             GetidsString(idsCloseFile, OutStr, sizeof(OutStr)), 
  1422.                             (LPSTR)lpci->szFile))
  1423.             SendMessage(lpci->hwnd, WM_COMMAND, IDM_CLOSE, 0L);
  1424.         else
  1425.             return;
  1426.         }
  1427.         
  1428.     // Now ask to open a file
  1429.     lpci->szFileBuff = (LPSTR)GetMemory(MAXFILEBUFF);
  1430.     if(!lpci->szFileBuff)
  1431.         return;
  1432.  
  1433.     if(!*szDirName)
  1434.         GetWindowsDirectory(szDirName, sizeof(szDirName));
  1435.  
  1436.     // Fill out the struct
  1437.     memset(&ofn, 0, sizeof(OPENFILENAME));
  1438.     lpci->szFile[0] = '\0';
  1439.     ofn.lStructSize =             sizeof(OPENFILENAME);
  1440.     ofn.hwndOwner =                 lpci->hwnd;
  1441.     ofn.lpstrFilter =             szDftFileFilter;
  1442.     ofn.nFilterIndex =             1;
  1443.     ofn.lpstrFile =                 lpci->szFile;
  1444.     ofn.nMaxFile =                 sizeof(lpci->szFile);
  1445.     ofn.lpstrInitialDir =         szDirName;
  1446.     ofn.Flags =                     OFN_HIDEREADONLY | 
  1447.                                             OFN_PATHMUSTEXIST | 
  1448.                                             OFN_FILEMUSTEXIST;
  1449.                                             
  1450.     // Try to open the file
  1451.     if(GetOpenFileName(&ofn)) {
  1452.         if(fHwnd)
  1453.             SetFocus(fHwnd);
  1454.  
  1455.         if(HFILE_ERROR == (lpci->hFile = _lopen(ofn.lpstrFile, OF_READ))) {
  1456.             szMessageBox(lpci->hwnd, 
  1457.                             MB_ICONEXCLAMATION,
  1458.                             (LPSTR)szOPENFILE,
  1459.                             GetidsString(idsOpenFileFailed, OutStr, sizeof(OutStr)), 
  1460.                             (LPSTR)ofn.lpstrFile);
  1461.             return;
  1462.             }
  1463.             
  1464.         lpci->cbFileSize = _lread(lpci->hFile, 
  1465.                     (void FAR *)lpci->szFileBuff, MAXFILEBUFF);
  1466.         _lclose(lpci->hFile);
  1467.         szWrite(lpci->hwndIn, (LPSTR)lpci->szFileBuff);
  1468.         SendMessage(lpci->hwndIn, EM_SETMODIFY, FALSE, 0L);
  1469.         wsprintf((LPSTR)lpci->szClientTitle, szUserAtFile,
  1470.                 (LPSTR)lpci->CurrentUser, (LPSTR)lpci->CurrentServer,
  1471.                 (LPSTR)ofn.lpstrFile);
  1472.         SetWindowText(lpci->hwnd, lpci->szClientTitle);
  1473.         GetNewDirectory(szDirName, ofn.lpstrFile);
  1474.         }
  1475.         
  1476.     if(fHwnd)
  1477.         SetFocus(fHwnd);
  1478. }
  1479.  
  1480.  
  1481. //*---------------------------------------------------------------------------------
  1482. //| DoSave:
  1483. //|    Save the current file.
  1484. //| Parms:
  1485. //|    lpci                            Connection window information
  1486. //| Returns:              
  1487. //|    Nothing
  1488. //*---------------------------------------------------------------------------------
  1489. VOID WINAPI DoFileSave(lpCHILDINFO lpci)
  1490. {               
  1491.     OFSTRUCT            ofs;
  1492.     
  1493.     ofs.cBytes = sizeof(OFSTRUCT);
  1494.     
  1495.     lpci->cbFileSize = GetWindowText(lpci->hwndIn, 
  1496.                     (LPSTR)lpci->szFileBuff, MAXFILEBUFF);
  1497.     if(HFILE_ERROR == (lpci->hFile = 
  1498.                                 OpenFile(lpci->szFile, &ofs, OF_CREATE))) {
  1499.         szMessageBox(lpci->hwnd, 
  1500.                         MB_ICONEXCLAMATION,
  1501.                         (LPSTR)szSAVEFILE,
  1502.                         GetidsString(idsSaveFileFailed, OutStr, sizeof(OutStr)), 
  1503.                         (LPSTR)lpci->szFile);
  1504.         return;
  1505.         }
  1506.         
  1507.     _lwrite(lpci->hFile, (void FAR *)lpci->szFileBuff, lstrlen(lpci->szFileBuff));
  1508.     _lclose(lpci->hFile);
  1509. }
  1510.  
  1511.  
  1512. //*---------------------------------------------------------------------------------
  1513. //| DoFileSaveAs:
  1514. //|    Use the commond dialog functions to save a file.
  1515. //| Parms:
  1516. //|    lpci                            Connection window information
  1517. //| Returns:              
  1518. //|    Nothing
  1519. //*---------------------------------------------------------------------------------
  1520. VOID INTFUN DoFileSaveAs(lpCHILDINFO lpci)
  1521. {
  1522.     OPENFILENAME            ofn;
  1523.     HWND                        fHwnd=GetFocus();
  1524.     char                        szSaveFile[_MAX_PATH];
  1525.  
  1526.     // Fill out struct
  1527.     szSaveFile[0] = '\0';
  1528.     memset(&ofn, 0, sizeof(OPENFILENAME));
  1529.     ofn.lStructSize =             sizeof(OPENFILENAME);
  1530.     ofn.hwndOwner =                 lpci->hwnd;
  1531.     ofn.lpstrFilter =             szDftFileFilter;
  1532.     ofn.nFilterIndex =             1;
  1533.     ofn.lpstrFile =                 szSaveFile;
  1534.     ofn.nMaxFile =                 sizeof(lpci->szFile);
  1535.     ofn.lpstrInitialDir =         szDirName;
  1536.     ofn.Flags =                     OFN_HIDEREADONLY | 
  1537.                                             OFN_PATHMUSTEXIST | 
  1538.                                             OFN_OVERWRITEPROMPT;
  1539.     
  1540.     
  1541.     // See if user selects a file
  1542.     if(GetSaveFileName(&ofn)) {
  1543.         lstrcpy(lpci->szFile, szSaveFile);
  1544.         wsprintf((LPSTR)lpci->szClientTitle, szUserAtFile,
  1545.                 (LPSTR)lpci->CurrentUser, (LPSTR)lpci->CurrentServer,
  1546.                 (LPSTR)szSaveFile);
  1547.         SetWindowText(lpci->hwnd, lpci->szClientTitle);
  1548.         DoFileSave(lpci);
  1549.         }
  1550.  
  1551.     if(fHwnd)
  1552.         SetFocus(fHwnd);
  1553. }
  1554.