home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / oledb / qurydemo / main.cpp next >
Encoding:
C/C++ Source or Header  |  1998-03-12  |  52.3 KB  |  1,832 lines

  1. //-----------------------------------------------------------------------------
  2. // Microsoft OLE DB QURYDEMO Sample
  3. // Copyright (C) 1995-1998 Microsoft Corporation
  4. //
  5. // @doc
  6. //
  7. // @module MAIN.CPP
  8. //
  9. //-----------------------------------------------------------------------------------
  10. /*
  11.     PROGRAM: QURYDEMO
  12.     ========
  13.  
  14.     PURPOSE:
  15.     ========    
  16.     demonstrates a simple MDI application that allows a user to
  17.     simultaneously connect to multiple hetrogeneous databases
  18.     and perform SQL queries to get results.
  19.  
  20.     FUNCTIONS:
  21.     ==========
  22.     WinMain() - main routine
  23.     MainWndProc() - processes Main Application Window messages
  24.     MDIChildProc() - processes MDI child window messages
  25.     ToolbarProc() - processes tool bar messages
  26.     StatusbarProc() - processes Status bar messages
  27.     ConnectDlgProc() - processes Connection Dialog box messages
  28.     DisconnectDlgProc() - processes Disconnect Dialog box messages
  29.     AboutDlgProc() - processes messages for About dialog box
  30.     MDIChildDlgProc() - process messages for dummy child dialog box in MDI window
  31.     DrawBitmap() - draws bitmaps for toolbuttons
  32.  
  33.     COMMENTS:
  34.     =========
  35.     Created by Microsoft Corporation.
  36. */
  37.  
  38. #define STRICT
  39.  
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <time.h>
  43.  
  44. #include <windows.h>
  45. #include <windowsx.h>
  46.  
  47. #ifdef CTL3D
  48. #include "ctl3d.h"
  49. #endif
  50.  
  51. #include "oledb.h"
  52. #include "oledberr.h"
  53.  
  54. #include "qurydemo.h"  
  55.  
  56. // Globals
  57. HWND        hWndFrame;          // Main Frame Window handle
  58. HWND        hWndCrsrList;       // hdbc(s) combobox on the tool bar
  59. HWND        hWndStmtList;       // hstmt(s) combobox on the tool bar
  60. HWND        hWndMDIClient;      // MDI Client window handle
  61. HWND        hWndActiveChild;    // Current active MDI Child window
  62. HINSTANCE    hAppInstance;       // Application instance
  63.  
  64. int            iTimex;             // Time box (on the status bar) width
  65. int            iDatex;             // Date box (on the status bar) width
  66. HWND        hWndToolbar;        // Toolbar window handle
  67. HWND        hWndStatusbar;      // status bar handle
  68. WORD        wStatusText;        // Status text state
  69. RECT        rectStatusText;     // Text box on the status bar
  70.  
  71. // Locals.
  72. void FillPrompt(HWND hWnd);
  73.  
  74.  
  75. /*
  76.     FUNCTION: WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  77.     COMMENTS: Application Entry Routine.
  78.           Register Classes. Create Main Window and MDI Child Window.
  79.           Process Main Message Loop.
  80. */
  81. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  82. {
  83.     MSG            msg;                    //msg structure
  84.     WNDCLASS    wc;                        //class structure
  85.     HICON        hMainIcon;                //App Icon
  86.     HICON        hMDIChildIcon;            //MDI Child Icon
  87.     HWND        hWndMDIChild;            //temp MDI Child Window Handle
  88.     char        szBuffer[MAXBUFLEN+1];    //temp string buffer to check class name
  89.     BOOL        bDialogMessage = FALSE;    //temp boolean to check dilogbox msgs
  90.     HACCEL        hAccel;                    //accelerator table handle
  91.  
  92.     hAppInstance = hInstance;
  93.  
  94.     // Check if application is already running, if
  95.     // so make it active and bring it in focus
  96.     if (hWndFrame = FindWindow(OLEDBFRAMECLASS, NULL))
  97.     {
  98.         hWndFrame = GetLastActivePopup(hWndFrame);
  99.         if (IsIconic(hWndFrame))
  100.             OpenIcon(hWndFrame);
  101.         else
  102.             BringWindowToTop(hWndFrame);
  103.         ACTIVATEWINDOW(hWndFrame);
  104.         return (FALSE);
  105.     }
  106.  
  107.     // Initialize OLEDB Interface
  108.     if (!InitEnvironment())
  109.     {
  110.         MessageBox(hWndFrame, INITERROR, EXECERROR, MB_OK|MB_ICONHAND);
  111.         return (FALSE);
  112.     }
  113.  
  114.     // Register window classes for the application - Main Window Class
  115.     wc.style            = 0;
  116.     wc.lpfnWndProc        = MainWndProc;
  117.     wc.cbClsExtra        = 0;
  118.     wc.cbWndExtra        = 0;
  119.     wc.hInstance        = hAppInstance;
  120.     wc.hIcon            = hMainIcon = LoadIcon(hAppInstance, APPICON);
  121.     wc.hCursor            = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
  122.     wc.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE+1);
  123.     wc.lpszMenuName        = QURYDEMOMENU;
  124.     wc.lpszClassName    = OLEDBFRAMECLASS;
  125.  
  126.     if (!RegisterClass(&wc))
  127.     {
  128.         MessageBox(hWndFrame, CLASSERROR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
  129.         return (FALSE);
  130.     }
  131.         
  132.     // register Toolbar Class
  133.     wc.hIcon            = (HICON)NULL;
  134.     wc.lpszMenuName        =  NULL;
  135.     wc.lpfnWndProc        = ToolbarProc;
  136.     wc.lpszClassName    = OLEDBTOOLCLASS;
  137.  
  138.     if (!RegisterClass(&wc))
  139.     {
  140.         MessageBox(hWndFrame, CLASSERROR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
  141.         return (FALSE);
  142.     }
  143.         
  144.     // register Statusbar Class
  145.     wc.lpfnWndProc        = StatusbarProc;
  146.     wc.lpszClassName    = OLEDBSTATUSCLASS;
  147.  
  148.     if (!RegisterClass(&wc))
  149.     {
  150.         MessageBox(hWndFrame, CLASSERROR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
  151.         return (FALSE);
  152.     }
  153.  
  154.     // register MDI Child Window Class
  155.     wc.hIcon             = hMDIChildIcon = LoadIcon(hAppInstance, QUERYWINDOWICON);
  156.     wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
  157.     wc.cbWndExtra        = CBWNDEXTRA;
  158.     wc.lpszClassName    = OLEDBMDICLASS;
  159.     wc.lpfnWndProc        = MDIChildProc;
  160.  
  161.     if (!RegisterClass(&wc))
  162.     {
  163.         MessageBox(hWndFrame, CLASSERROR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL);
  164.         return (FALSE);
  165.     }
  166.  
  167.     // create Main window and the MDI Client window
  168.     if (!(hWndFrame = CreateWindow(OLEDBFRAMECLASS, APPTITLE, WS_OVERLAPPEDWINDOW, 
  169.                 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  170.                 (HWND)NULL, (HMENU)NULL, hAppInstance, NULL)))
  171.     {
  172.         MessageBox(hWndFrame, CREATEMAINERR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL); 
  173.         return (FALSE);
  174.     }
  175.  
  176.     ShowWindow(hWndFrame, nCmdShow);
  177.     UpdateWindow(hWndFrame);
  178.  
  179. #ifdef CTL3D
  180.     // register 3D controls
  181.     Ctl3dRegister(hAppInstance);
  182.     Ctl3dAutoSubclass(hAppInstance);
  183. #endif
  184.  
  185.     // load accelerators
  186.     hAccel = LoadAccelerators(hAppInstance, APPACCELERATOR);
  187.     
  188.     // acquire and dispatch messages until a WM_QUIT message is received
  189.     while (GetMessage(&msg, (HWND)NULL, 0, 0))
  190.     {           
  191.         
  192.         // check for App accelerators
  193.         if (TranslateAccelerator(hWndFrame, hAccel, &msg))
  194.             continue;
  195.             
  196.         // check for MDI accelerators
  197.         if (TranslateMDISysAccel(hWndMDIClient, &msg))
  198.             continue;
  199.                                             
  200.         // each MDI Child has a modeless dialog in its client area
  201.         // to provide tab controls. Check for Modeless Dialog msgs.
  202.         for (hWndMDIChild = GetWindow(hWndMDIClient, GW_CHILD); hWndMDIChild; hWndMDIChild = GetWindow(hWndMDIChild, GW_HWNDNEXT))
  203.         {
  204.             GetClassName(hWndMDIChild, szBuffer, MAXBUFLEN);
  205.             if (strcmp(szBuffer, OLEDBMDICLASS))
  206.                 continue;
  207.             if (IsDialogMessage((HWND)GetWindowLong(hWndMDIChild, GWLAPP_HDLG), &msg))
  208.             {
  209.                 bDialogMessage = TRUE;
  210.                 break;
  211.             }
  212.         }
  213.         
  214.         if (bDialogMessage)
  215.         {
  216.             bDialogMessage = FALSE;
  217.             continue;
  218.         }
  219.                 
  220.         // if the message does not need special processing, dispatch it
  221.         TranslateMessage(&msg);
  222.         DispatchMessage(&msg);
  223.     }
  224.  
  225. #ifdef CTL3D
  226.     // unregister 3D controls
  227.     Ctl3dUnregister(hAppInstance);
  228. #endif
  229.  
  230.     // Free memory used by OLEDB interface
  231.     FreeEnvironment();
  232.  
  233.     // free Icon resources
  234.     if (hMainIcon)
  235.         DestroyIcon(hMainIcon);
  236.     
  237.     if (hMDIChildIcon)
  238.         DestroyIcon(hMDIChildIcon);
  239.  
  240.     return (msg.wParam);
  241. }
  242.  
  243. /*
  244.     FUNCTION: MainWndProc(HWND hWnd, UINT     message, WPARAM wParam, LPARAM lParam)
  245.     COMMENTS: Windows Callback procedure to handle Window messages.
  246.               Menu Commands and System Command messages are handled by
  247.               this main window.
  248. */
  249. long CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  250. {
  251.     switch (message)
  252.     {
  253.     static int    iToolY;         //remember Toolbar height for resize
  254.     static int    iStatusY;       //remember Statusbar height for resize
  255.  
  256.         case WM_CREATE:
  257.         {
  258.             CLIENTCREATESTRUCT    ccs;        //MDIclient window structure
  259.             HDC                    hDC;        //Device Context handle
  260.             SIZE                sizeBar;    //Size of a text bar
  261.             RECT                rectCombo;  //Size of combo box
  262.  
  263.             // Create child windows
  264.                 //1. combobox to display connections - DSN, SESSION
  265.                 //2. combobox to display HSTMT on current SESSION
  266.                 //3. Toolbar to put toolbuttons
  267.                 //4. Statusbat to display current action, date and time
  268.                 //5. MDI Client Window to process MDI children
  269.                 
  270.             hWndCrsrList = CreateWindow(COMBOBOXCLASS, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
  271.                 WS_VSCROLL | CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL, 5, 2, 180, 150, hWnd,
  272.                 (HMENU)IDW_CRSRLIST, hAppInstance, NULL);
  273.  
  274.             hWndStmtList = CreateWindow(COMBOBOXCLASS, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
  275.                 WS_VSCROLL | CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL, 190, 2, 150, 150, hWnd,
  276.                 (HMENU)IDW_COMMANDLIST, hAppInstance, NULL);
  277.  
  278.             hWndToolbar = CreateWindow(OLEDBTOOLCLASS, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
  279.                 0, 0, 0, 0, hWnd, (HMENU)IDW_TOOLBAR, hAppInstance, NULL);
  280.  
  281.             hWndStatusbar = CreateWindow(OLEDBSTATUSCLASS, NULL, WS_CHILD | WS_VISIBLE |
  282.                 WS_CLIPSIBLINGS, 0, 0, 0, 0, hWnd, (HMENU)IDW_STATUSBAR, hAppInstance, NULL);
  283.  
  284.             ccs.hWindowMenu = GetSubMenu(GetMenu(hWnd), WINDOWMENUPLACE);
  285.             ccs.idFirstChild = IDM_MDICHILD;
  286.  
  287.             hWndMDIClient = CreateWindow(MDICLIENTCLASS, NULL, WS_CHILD | WS_CLIPSIBLINGS |
  288.                 WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE, 0, 0, 0, 0, hWnd,
  289.                 (HMENU)IDW_MDICLIENT, hAppInstance, (LPSTR)&ccs);
  290.  
  291.             // check to see if any of the above window creation failed
  292.             if (!hWndCrsrList || !hWndStmtList || !hWndToolbar || !hWndStatusbar || !hWndMDIClient)
  293.             {
  294.                 MessageBox(hWnd, CREATEMAINERR, EXECERROR, MB_OK|MB_ICONHAND|MB_TASKMODAL); 
  295.                 PostMessage(hWnd, WM_CLOSE, 0, 0);
  296.                 break;
  297.             }
  298.  
  299.             // calculate proper text height for tool and status bars
  300.             GetWindowRect(hWndStmtList, &rectCombo);
  301.             iToolY = rectCombo.bottom - rectCombo.top + TOOLBARMARGINY;
  302.  
  303.             if (hDC = GetDC(hWndStatusbar))
  304.             {
  305.                 GetTextExtentPoint(hDC, ALPHABETS, strlen(ALPHABETS), &sizeBar);
  306.                 ReleaseDC(hWndStatusbar, hDC);
  307.                 iStatusY = sizeBar.cy + STATUSBARMARGINY;
  308.             }
  309.             else
  310.             {
  311.                 iStatusY = 0;
  312.                 DestroyWindow(hWndStatusbar);
  313.             }
  314.         
  315.             break;
  316.         }
  317.         
  318.         // Limit minimum size of the main window
  319.         case WM_GETMINMAXINFO:
  320.         
  321.             ((MINMAXINFO FAR*)lParam)->ptMinTrackSize.x = 
  322.                 max(MINWIDTH, rectStatusText.right-rectStatusText.left+iTimex+iDatex+14);
  323.             ((MINMAXINFO FAR*)lParam)->ptMinTrackSize.y = MINHEIGHT;
  324.             break;
  325.         
  326.         // Resize children
  327.         case WM_SIZE:
  328.         {
  329.             WORD    wWidth = LOWORD(lParam);    //width of rectangle
  330.             WORD    wHeight = HIWORD(lParam);    //height of rectangle
  331.  
  332.             MoveWindow(hWndToolbar, 0, 0, wWidth, iToolY, TRUE);
  333.             MoveWindow(hWndStatusbar, 0, wHeight-iStatusY, wWidth, iStatusY, TRUE);
  334.             InvalidateRect(hWndStatusbar, NULL, TRUE);
  335.             MoveWindow(hWndMDIClient, 0, iToolY, wWidth, wHeight-iStatusY-iToolY, TRUE);
  336.             break;
  337.         }
  338.         
  339. #ifdef CTL3D
  340.         // Inform 3D controls of color change                
  341.         case WM_SYSCOLORCHANGE:
  342.  
  343.             Ctl3dColorChange();
  344.             break;
  345. #endif        
  346.         // Close comboboxes if dropped down
  347.         case WM_SYSCOMMAND:
  348.  
  349.             SendMessage(hWndCrsrList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
  350.             SendMessage(hWndStmtList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
  351.             return (DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam));
  352.         
  353.         // Initialize popup menus
  354.         case WM_INITMENUPOPUP:
  355.         {
  356.             int    iMenuId;        //Menu ID being processed
  357.             int    nItems;         //# of menu items
  358.             int    nPos;           //Menu Position
  359.  
  360.             // Ignore the msg if it is for a system menu
  361.             if (HIWORD(lParam))
  362.                 break;
  363.             
  364.             // Go through the menu items for current popup menu
  365.             // and enable/disable menu item, if required
  366.             nItems = GetMenuItemCount((HMENU)wParam);
  367.             for (nPos = 0; nPos < nItems; nPos++)
  368.                 switch (iMenuId = GetMenuItemID((HMENU)wParam, nPos))
  369.                 {
  370.                     case IDM_DISCONNECT:
  371.                     case IDM_NEW:
  372.             
  373.                         EnableMenuItem( (HMENU)wParam, iMenuId, MF_BYCOMMAND|
  374.                                         ((SendMessage(hWndCrsrList, CB_GETCOUNT, 0, 0) > 0)?
  375.                                         MF_ENABLED:MF_GRAYED) );
  376.                         break;
  377.             
  378.                     case IDM_QUERY:
  379.                     case IDM_TILE:
  380.                     case IDM_CASCADE:
  381.                     case IDM_ICONS:
  382.                     case IDM_CLOSEALL:
  383.  
  384.                     case IDM_ASSERTIONS:
  385.                     case IDM_CATALOGS:
  386.                     case IDM_CHARACTER_SETS:
  387.                     case IDM_CHECK_CONSTRAINTS:
  388.                     case IDM_COLLATIONS:
  389.                     case IDM_COLUMN_DOMAIN_USAGE:
  390.                     case IDM_COLUMN_PRIVILEGES:
  391.                     case IDM_COLUMNS:
  392.                     case IDM_CONSTRAINT_COLUMN_USAGE:
  393.                     case IDM_CONSTRAINT_TABLE_USAGE:
  394.                     case IDM_FOREIGN_KEYS:
  395.                     case IDM_INDEXES:
  396.                     case IDM_KEY_COLUMN_USAGE:
  397.                     case IDM_PRIMARY_KEYS:
  398.                     case IDM_PROCEDURE_COLUMNS:
  399.                     case IDM_PROCEDURE_PARAMETERS:
  400.                     case IDM_PROCEDURES:
  401.                     case IDM_PROVIDER_TYPES:
  402.                     case IDM_REFERENTIAL_CONSTRAINTS:
  403.                     case IDM_SCHEMATA:
  404.                     case IDM_SQL_LANGUAGES:
  405.                     case IDM_STATISTICS:
  406.                     case IDM_TABLE_CONSTRAINTS:
  407.                     case IDM_TABLE_PRIVILEGES:
  408.                     case IDM_TABLES:
  409.                     case IDM_TRANSLATIONS:
  410.                     case IDM_USAGE_PRIVILEGES:
  411.                     case IDM_VIEW_COLUMN_USAGE:
  412.                     case IDM_VIEW_TABLE_USAGE:
  413.                     case IDM_VIEWS:
  414.  
  415.                         EnableMenuItem( (HMENU)wParam, iMenuId, MF_BYCOMMAND|
  416.                                         (GetWindow(hWndMDIClient, GW_CHILD)?
  417.                                         MF_ENABLED:MF_GRAYED) );
  418.                         break;
  419.             
  420.                     default:
  421.                         break;
  422.                 }
  423.             break;
  424.         }
  425.         
  426.         // Update status bar to reflect menu selection
  427.         case WM_MENUSELECT:
  428.         {
  429.             int        iMenuFlag;                 //Check menu type
  430.             HMENU    hMenu;                   //Menu Handle
  431.             char    szMenuName[MAXBUFLEN+1]; //Menu Name 
  432.  
  433.             // store Menuitem ID as a state value for text display
  434.             wStatusText = GET_WM_MENUSELECT_CMD(wParam, lParam);
  435.  
  436.             // process popup menus ie non menuitem selections
  437.             iMenuFlag = GET_WM_MENUSELECT_FLAGS(wParam, lParam);
  438.  
  439.             // if the selected menu is a system popup menu
  440.             // else if the selected menu is a popup menu check menu names
  441.             // OR check if it is a control popup menu of maximized MDI Child window
  442.             if (wStatusText && (iMenuFlag & MF_SYSMENU) && (iMenuFlag & MF_POPUP))
  443.                 wStatusText = IDM_POPUPAPPSYS;
  444.             else if (wStatusText && (iMenuFlag & MF_POPUP))
  445.             {
  446.                 hMenu = (HMENU)wStatusText;
  447.                 GetMenuString(hMenu, 0, szMenuName, MAXBUFLEN, MF_BYPOSITION);
  448.                 if (!strcmp(szMenuName, MENUITEMCONNECT))
  449.                     wStatusText = IDM_POPUPLOGIN;
  450.                 else if (!strcmp(szMenuName, MENUITEMQUERY))
  451.                     wStatusText = IDM_POPUPQUERY;
  452.                 else if (!strcmp(szMenuName, MENUITEMTILE))
  453.                     wStatusText = IDM_POPUPSCHEMA;
  454.                 else if (!strcmp(szMenuName, MENUITEMTYPES))
  455.                     wStatusText = IDM_POPUPWINDOW;
  456.                 else if (!strcmp(szMenuName, MENUITEMAPPHELP))
  457.                     wStatusText = IDM_POPUPHELP;
  458.                 else if (GetMenuString(hMenu, SC_NEXTWINDOW, szMenuName, MAXBUFLEN, MF_BYCOMMAND)>0)
  459.                     wStatusText = IDM_POPUPMDISYS;
  460.                 else
  461.                     wStatusText = 0;
  462.             }
  463.  
  464.             // invalidate status bar for repaint
  465.             InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
  466.             break;
  467.         }
  468.         
  469.         // Process menu commands
  470.         case WM_COMMAND:
  471.  
  472.         switch (GET_WM_COMMAND_ID(wParam, lParam))
  473.         {
  474.             case IDM_INITIALIZE: // bring up connect dialog & do connect processing
  475.                 DialogBox(hAppInstance, INITDIALOG, hWnd, ConnectDlgProc);
  476.                 break;
  477.                                                 
  478.             case IDM_DISCONNECT: // bringup disconnect dlg and do disconnects
  479.                 DialogBox(hAppInstance, DISCONNECTDIALOG, hWnd, DisconnectDlgProc);
  480.                 break;
  481.  
  482.             case IDM_QUERY: // process execute query request
  483.             
  484.                 ExecuteQuery();
  485.                 break;
  486.  
  487.             case IDM_ASSERTIONS: // Execute DBSCHEMA_ASSERTIONS request
  488.             
  489.                 GetSchemaRowset(DBSCHEMA_ASSERTIONS);
  490.                 break;
  491.  
  492.             case IDM_CATALOGS: // Execute DBSCHEMA_CATALOGS request
  493.             
  494.                 GetSchemaRowset(DBSCHEMA_CATALOGS);
  495.                 break;
  496.  
  497.             case IDM_CHARACTER_SETS: // Execute DBSCHEMA_CHARACTER_SETS request
  498.             
  499.                 GetSchemaRowset(DBSCHEMA_CHARACTER_SETS);
  500.                 break;
  501.  
  502.             case IDM_CHECK_CONSTRAINTS: // Execute DBSCHEMA_CHECK_CONSTRAINTS request
  503.             
  504.                 GetSchemaRowset(DBSCHEMA_CHECK_CONSTRAINTS);
  505.                 break;
  506.  
  507.             case IDM_COLLATIONS: // Execute DBSCHEMA_COLLATIONS request
  508.             
  509.                 GetSchemaRowset(DBSCHEMA_COLLATIONS);
  510.                 break;
  511.  
  512.             case IDM_COLUMN_DOMAIN_USAGE: // Execute DBSCHEMA_COLUMN_DOMAIN_USAGE request
  513.             
  514.                 GetSchemaRowset(DBSCHEMA_COLUMN_DOMAIN_USAGE);
  515.                 break;
  516.  
  517.             case IDM_COLUMN_PRIVILEGES: // Execute DBSCHEMA_COLUMN_PRIVELEGES request
  518.             
  519.                 GetSchemaRowset(DBSCHEMA_COLUMN_PRIVILEGES);
  520.                 break;
  521.  
  522.             case IDM_COLUMNS: // Execute DBSCHEMA_COLUMNS request
  523.             
  524.                 GetSchemaRowset(DBSCHEMA_COLUMNS);
  525.                 break;
  526.  
  527.             case IDM_CONSTRAINT_COLUMN_USAGE: // Execute DBSCHEMA_CONSTRAINT_COLUMN_USAGE request
  528.             
  529.                 GetSchemaRowset(DBSCHEMA_CONSTRAINT_COLUMN_USAGE);
  530.                 break;
  531.  
  532.             case IDM_CONSTRAINT_TABLE_USAGE: // Execute DBSCHEMA_CONSTRAINT_TABLE_USAGE request
  533.             
  534.                 GetSchemaRowset(DBSCHEMA_CONSTRAINT_TABLE_USAGE);
  535.                 break;
  536.  
  537.             case IDM_FOREIGN_KEYS: // Execute DBSCHEMA_FOREIGN_KEYS request
  538.             
  539.                 GetSchemaRowset(DBSCHEMA_FOREIGN_KEYS);
  540.                 break;
  541.  
  542.             case IDM_INDEXES: // Execute DBSCHEMA_INDEXES request
  543.                 
  544.                 GetSchemaRowset(DBSCHEMA_INDEXES);
  545.                 break;
  546.  
  547.             case IDM_KEY_COLUMN_USAGE: // Execute DBSCHEMA_KEY_COLUMN_USAGE request
  548.                 
  549.                 GetSchemaRowset(DBSCHEMA_KEY_COLUMN_USAGE);
  550.                 break;
  551.  
  552.             case IDM_PRIMARY_KEYS: // Execute DBSCHEMA_PRIMARY_KEYS request
  553.             
  554.                 GetSchemaRowset(DBSCHEMA_PRIMARY_KEYS);
  555.                 break;
  556.  
  557.             case IDM_PROCEDURE_COLUMNS: // Execute DBSCHEMA_PROCEDURE_COLUMNS request
  558.             
  559.                 GetSchemaRowset(DBSCHEMA_PROCEDURE_COLUMNS);
  560.                 break;
  561.  
  562.             case IDM_PROCEDURE_PARAMETERS: // Execute DBSCHEMA_PROCEDURE_PARAMETERS request
  563.             
  564.                 GetSchemaRowset(DBSCHEMA_PROCEDURE_PARAMETERS);
  565.                 break;
  566.  
  567.             case IDM_PROCEDURES: // Execute DBSCHEMA_PROCEDURES request
  568.             
  569.                 GetSchemaRowset(DBSCHEMA_PROCEDURES);
  570.                 break;
  571.  
  572.             case IDM_PROVIDER_TYPES: // Execute DBSCHEMA_TYPES request
  573.             
  574.                 GetSchemaRowset(DBSCHEMA_PROVIDER_TYPES);
  575.                 break;
  576.  
  577.             case IDM_REFERENTIAL_CONSTRAINTS: // Execute DBSCHEMA_REFERENTIAL_CONSTRAINTS request
  578.             
  579.                 GetSchemaRowset(DBSCHEMA_REFERENTIAL_CONSTRAINTS);
  580.                 break;
  581.  
  582.             case IDM_SCHEMATA: // Execute DBSCHEMA_SCHEMATA request
  583.             
  584.                 GetSchemaRowset(DBSCHEMA_SCHEMATA);
  585.                 break;
  586.  
  587.             case IDM_SQL_LANGUAGES: // Execute DBSCHEMA_SQL_LANGUAGES request
  588.             
  589.                 GetSchemaRowset(DBSCHEMA_SQL_LANGUAGES);
  590.                 break;
  591.  
  592.             case IDM_STATISTICS: // Execute DBSCHEMA_STATISTICS request
  593.             
  594.                 GetSchemaRowset(DBSCHEMA_STATISTICS);
  595.                 break;
  596.  
  597.             case IDM_TABLE_CONSTRAINTS: // Execute DBSCHEMA_TABLE_CONSTRAINTS request
  598.             
  599.                 GetSchemaRowset(DBSCHEMA_TABLE_CONSTRAINTS);
  600.                 break;
  601.  
  602.             case IDM_TABLE_PRIVILEGES: // Execute DBSCHEMA_TABLE_PRIVILEGES request
  603.             
  604.                 GetSchemaRowset(DBSCHEMA_TABLE_PRIVILEGES);
  605.                 break;
  606.  
  607.             case IDM_TABLES: // Execute DBSCHEMA_TABLES request
  608.             
  609.                 GetSchemaRowset(DBSCHEMA_TABLES);
  610.                 break;
  611.  
  612.             case IDM_TRANSLATIONS: // Execute DBSCHEMA_TRANSLATIONS request
  613.             
  614.                 GetSchemaRowset(DBSCHEMA_TRANSLATIONS);
  615.                 break;
  616.  
  617.             case IDM_USAGE_PRIVILEGES: // Execute DBSCHEMA_USAGE_PRIVILEGES request
  618.             
  619.                 GetSchemaRowset(DBSCHEMA_USAGE_PRIVILEGES);
  620.                 break;
  621.  
  622.             case IDM_VIEW_COLUMN_USAGE: // Execute DBSCHEMA_VIEW_COLUMN_USAGE request
  623.             
  624.                 GetSchemaRowset(DBSCHEMA_VIEW_COLUMN_USAGE);
  625.                 break;
  626.  
  627.             case IDM_VIEW_TABLE_USAGE: // Execute DBSCHEMA_VIEW_TABLE_USAGE request
  628.             
  629.                 GetSchemaRowset(DBSCHEMA_VIEW_TABLE_USAGE);
  630.                 break;
  631.  
  632.             case IDM_VIEWS: // Execute DBSCHEMA_VIEWS request
  633.             
  634.                 GetSchemaRowset(DBSCHEMA_VIEWS);
  635.                 break;
  636.  
  637.             case IDM_EXIT: // process exit request
  638.  
  639.                 SendMessage(hWndFrame, WM_CLOSE, 0, 0);
  640.                 break;
  641.  
  642.             case IDM_NEW: // create a new query window on current connect
  643.  
  644.                 NewICommandWindow();
  645.                 break;
  646.  
  647.             case IDM_TILE: // let MDI Client tile the MDI children
  648.  
  649.                 SendMessage(hWndMDIClient, WM_MDITILE, 0, 0);
  650.                 break;
  651.  
  652.             case IDM_CASCADE: // let MDI Client cascade MDI children
  653.  
  654.                 SendMessage(hWndMDIClient, WM_MDICASCADE, 0, 0);
  655.                 break;
  656.  
  657.             case IDM_ICONS: // let MDI Client arrange iconic MDI children
  658.  
  659.                 SendMessage(hWndMDIClient, WM_MDIICONARRANGE, 0, 0);
  660.                 break;
  661.  
  662.             case IDM_CLOSEALL: // Close all open windows and free hstmts
  663.             {
  664.                 HWND    hWndTemp;    //temp window handle
  665.  
  666.                 // hide MDI Client Windows to avoid repaints
  667.                 ShowWindow(hWndMDIClient,SW_HIDE);
  668.                 while (hWndTemp = GetWindow(hWndMDIClient, GW_CHILD))
  669.                     SendMessage(hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndTemp, 0);
  670.                 ShowWindow(hWndMDIClient, SW_SHOW);
  671.                 break;
  672.             }
  673.                 
  674.             case IDM_ABOUT: // bringup About dialog
  675.                 DialogBox(hAppInstance, ABOUTDIALOG, hWnd, AboutDlgProc);
  676.                 break;
  677.  
  678.             case IDW_CRSRLIST: // change current cursor ?
  679.  
  680.                 if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
  681.                     ChangeCurrentCursor(GET_WM_COMMAND_HWND(wParam, lParam));
  682.                 else if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_KILLFOCUS)
  683.                     PostMessage(GET_WM_COMMAND_HWND(wParam, lParam), CB_SHOWDROPDOWN,
  684.                         (WPARAM)FALSE, 0);
  685.                 else
  686.                     DefFrameProc(hWnd, hWndMDIClient, WM_COMMAND, wParam, lParam);
  687.                 break;
  688.  
  689.             case IDW_COMMANDLIST: // change current Command ?
  690.  
  691.                 if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE)
  692.                     ChangeCurrentICommand(GET_WM_COMMAND_HWND(wParam, lParam));
  693.                 else if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_KILLFOCUS)
  694.                     PostMessage(GET_WM_COMMAND_HWND(wParam, lParam), CB_SHOWDROPDOWN,
  695.                         (WPARAM)FALSE, 0);
  696.                 else
  697.                     DefFrameProc(hWnd, hWndMDIClient, WM_COMMAND, wParam, lParam);
  698.                 break;
  699.  
  700.             default:
  701.  
  702.                 DefFrameProc(hWnd, hWndMDIClient, WM_COMMAND, wParam, lParam);
  703.                 break;
  704.         }
  705.         break;
  706.  
  707.         case WM_CLOSE: //close all MDI windows, hdbcs & hstmts, else fail
  708.  
  709.             return (CloseIDBCreateCommand() ? DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam) : FALSE);
  710.  
  711.         case WM_DESTROY:
  712.  
  713.             PostQuitMessage(0);
  714.             break;
  715.  
  716.         default:
  717.             return (DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam));
  718.     }
  719.     return (0);
  720. }
  721.  
  722.  
  723. /*
  724.     FUNCTION: MDIChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  725.     COMMENTS: Window Procedure for MDI Child windows
  726. */
  727. long CALLBACK MDIChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  728. {
  729.     switch (message)
  730.     {
  731.         HWND    hWndTemp;    //temporary window handle
  732.     
  733.         case WM_CREATE:
  734.  
  735.         // create child windows
  736.         // 1. Modeless Dialog box in the background to process tabs
  737.         // 2. Static Text to display prompt
  738.         // 3. Edit Control to type SQL text
  739.         // 4. List Box to display results
  740.         // store dialog handle for future reference
  741.         // set focus to edit control
  742.         
  743.         // if create failed due to low system resources
  744.         if (!hWnd)
  745.             break;
  746.             
  747.         hWndActiveChild = hWnd;
  748.         hWndTemp = CreateDialog(hAppInstance, MDICHILDDIALOG, hWndActiveChild, MDIChildDlgProc);
  749.         
  750.         // check to see if the dialog was created?, if not destroy this window
  751.         if (!hWndTemp)
  752.         {
  753.             return (-1);
  754.         }
  755.  
  756.         SetWindowLong(hWnd, GWLAPP_HDLG, (LONG)hWndTemp);
  757.         SetFocus(GetDlgItem(hWndTemp, IDTEXT_SQL));
  758.         break;
  759.  
  760.         case WM_SIZE:
  761.                 {
  762.         WORD    wWidth;                    //New Width of MDI Child
  763.         WORD    wHeight;                //New Height of MDI Child
  764.         HDC        hDC;                    //Device Context
  765.         char    szBuffer[MAXBUFLEN+1];    //Static Control Text
  766.         int        nStrLen;                //Buffer Length
  767.         SIZE    size;                    //Screen size for text display
  768.                 
  769.         // call default procedure first, to let MDI position the child & then move its children
  770.         DefMDIChildProc(hWnd, message, wParam, lParam);
  771.             
  772.         // move child windows with proper screen size for text display
  773.         wWidth = LOWORD(lParam);
  774.         wHeight = HIWORD(lParam);
  775.         hWndTemp = (HWND)GetWindowLong(hWnd, GWLAPP_HDLG);
  776.  
  777.         nStrLen = GetWindowText(GetDlgItem(hWndTemp, IDTEXT_PRMPT), szBuffer, MAXBUFLEN);
  778.         hDC = GetDC(hWnd);
  779.         GetTextExtentPoint(hDC, szBuffer, nStrLen, &size);
  780.         ReleaseDC(hWnd, hDC);
  781.                 
  782.         MoveWindow(hWndTemp, 0, 0, wWidth, wHeight, TRUE);
  783.         MoveWindow(GetDlgItem(hWndTemp, IDTEXT_PRMPT), 0, 0, size.cx+2, size.cy+2, TRUE);
  784.         MoveWindow(GetDlgItem(hWndTemp, IDTEXT_SQL), size.cx+3, 0, wWidth - (size.cx+2), size.cy+2, TRUE);
  785.         MoveWindow(GetDlgItem(hWndTemp, IDLIST_RSLT), 0, size.cy+3, wWidth, wHeight - (size.cy+2), TRUE);
  786.         break;
  787.                 }
  788.                 
  789.         case WM_MENUSELECT: // update status bar to reflect menu selection
  790.                 {
  791.                 int    iMenuFlag;        //Check menu type
  792.                 
  793.         // store the Menu Item Id as a state value for text display
  794.         wStatusText = GET_WM_MENUSELECT_CMD(wParam, lParam);
  795.  
  796.         // if none of the menuitems was selected, check if
  797.         // the control popup menu is selected.
  798.         iMenuFlag = GET_WM_MENUSELECT_FLAGS(wParam, lParam);
  799.  
  800.         // if the selected menu is a system popup menu
  801.         if (wStatusText && (iMenuFlag & MF_SYSMENU) && (iMenuFlag & MF_POPUP))
  802.             wStatusText = IDM_POPUPMDISYS;
  803.  
  804.         // invalidate status bar for repaint
  805.         InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
  806.         break;
  807.         }
  808.  
  809.         case WM_MDIACTIVATE:
  810.  
  811.         // check if the display of comboboxes require a change
  812.         if (GET_WM_MDIACTIVATE_FACTIVATE(hWnd, wParam, lParam) &&
  813.             (hWndActiveChild) && (hWndActiveChild != hWnd))
  814.         {
  815.             hWndActiveChild = hWnd;
  816.             DisplayNewCrsrAndICommand();
  817.         }
  818.         break;
  819.         
  820.         case WM_MOUSEACTIVATE:
  821.         
  822.         // current window has changed, update comboboxes.
  823.         hWndActiveChild = hWnd;
  824.         DisplayNewCrsrAndICommand();
  825.         break;
  826.         
  827.         case WM_SETFOCUS:
  828.         
  829.         // pass on the focus to the edit box for user to type in SQL
  830.         SetFocus(GetDlgItem((HWND)GetWindowLong(hWnd, GWLAPP_HDLG), IDTEXT_SQL));
  831.         break;
  832.         
  833.         case WM_DESTROY:
  834.  
  835.         // check if the window was being destroyed while creation failed
  836.         if (!hWnd)
  837.             break;
  838.                             
  839.         // close the window and free instance thunk for modeless dialog
  840.         CloseICommandWindow(hWnd);
  841.         DestroyWindow((HWND)GetWindowLong(hWnd, GWLAPP_HDLG));
  842.  
  843.         if (hWnd == hWndActiveChild)
  844.             hWndActiveChild = (HWND)NULL;
  845.         break;
  846.  
  847.         default:
  848.             return (DefMDIChildProc(hWnd, message, wParam, lParam));
  849.     }
  850.     return (0);
  851. }
  852.  
  853. /*
  854.     FUNCTION: ToolbarProc(HWND hWnd, UINT   message, WPARAM wParam, LPARAM lParam)
  855.     COMMENTS: callback window procedure for toolbar window.
  856.           Handle pain and mouse messages to paint the toolbar and
  857.           provide default button behaviour for toolbar buttons.
  858. */
  859. long CALLBACK ToolbarProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  860. {
  861.     switch (message)
  862.     {
  863.     static HBITMAP    hbmpNewQuery;                //btn1 bitmap handle
  864.     static HBITMAP    hbmpRunQuery;                //btn2 bitmap handle
  865.     static RECT        stNewQuery;                    //btn1 rectangle
  866.     static RECT        stRunQuery;                 //btn2 rectangle
  867.     POINT            stMousePosition;            //current mouse pos
  868.     BOOL            bButtonPosition;            //mouse pos flag
  869.     static BOOL        bNewQueryBtnDown;            //was btn1 down before?
  870.     static BOOL        bRunQueryBtnDown;            //was btn2 down before?
  871.     static int        nLastButtonDown;            //Which btn was down before?
  872.  
  873.         bNewQueryBtnDown = FALSE;
  874.         bRunQueryBtnDown = FALSE;
  875.         nLastButtonDown  = 0;
  876.  
  877.         case WM_CREATE:
  878.  
  879.         // load bitmaps for buttons
  880.         // initialize static rectangles for button positions on toolbar
  881.         // initialize state variable for status text display
  882.         hbmpNewQuery = LoadBitmap(hAppInstance, BMP_NEWQUERY);
  883.         hbmpRunQuery = LoadBitmap(hAppInstance, BMP_RUNQUERY);
  884.         
  885.         stNewQuery.left   = BTTNX;
  886.         stNewQuery.right  = BTTNX+BTTNWIDTH+1;
  887.         stNewQuery.top    = BTTNY;
  888.         stNewQuery.bottom = BTTNY+BTTNHEIGHT+1;
  889.         
  890.         stRunQuery.left   = BTTNX+BTTNWIDTH+BTTNMARGIN;
  891.         stRunQuery.right  = BTTNX+BTTNWIDTH+BTTNMARGIN+BTTNWIDTH+1;
  892.         stRunQuery.top    = BTTNY;
  893.         stRunQuery.bottom = BTTNY+BTTNHEIGHT+1;
  894.                 
  895.         wStatusText = 0;
  896.         break;
  897.  
  898.         case WM_DESTROY:
  899.  
  900.         // delete bitmap handles
  901.         if (hbmpNewQuery)
  902.             DeleteObject(hbmpNewQuery);
  903.         if (hbmpRunQuery)
  904.             DeleteObject(hbmpRunQuery);
  905.         break;
  906.  
  907.         case WM_LBUTTONDOWN:
  908.  
  909.         // Check if the mouse key lies on any one of the buttons
  910.         // if so, set state variable to reflect that button and
  911.         // invalidate proper regions on tool & status bars for update.
  912.         // set capture on mouse movements till the mouse key is
  913.         // released.
  914.         stMousePosition.x = LOWORD(lParam);
  915.         stMousePosition.y = HIWORD(lParam);
  916.         
  917.         if (PtInRect(&stNewQuery, stMousePosition))
  918.         {
  919.             bNewQueryBtnDown = TRUE;
  920.             wStatusText = nLastButtonDown = IDM_NEW;
  921.             SetCapture(hWnd);
  922.             InvalidateRect(hWnd, &stNewQuery, TRUE);
  923.             InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
  924.         }
  925.         else if (PtInRect(&stRunQuery, stMousePosition))
  926.         {
  927.             bRunQueryBtnDown = TRUE;
  928.             wStatusText = nLastButtonDown = IDM_QUERY;
  929.             SetCapture(hWnd);
  930.             InvalidateRect(hWnd, &stRunQuery, TRUE);
  931.             InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
  932.         }
  933.         break;
  934.  
  935.         case WM_LBUTTONUP:
  936.  
  937.         // check if the mouse movements from key down movements
  938.         // were captured, if so process the key release state.
  939.         // if the key was released in the same button where it
  940.         // was pressed, it is equivalent to a button click.
  941.         if (hWnd != GetCapture())
  942.             break;
  943.  
  944.         stMousePosition.x = LOWORD(lParam);
  945.         stMousePosition.y = HIWORD(lParam);
  946.  
  947.         if (bNewQueryBtnDown && PtInRect(&stNewQuery, stMousePosition))
  948.         {
  949.             bNewQueryBtnDown = FALSE;
  950.             nLastButtonDown = 0;
  951.             InvalidateRect(hWnd, &stNewQuery, TRUE);
  952.             PostMessage(hWndFrame, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_NEW, 0, 0));
  953.             SendMessage(hWndCrsrList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
  954.             SendMessage(hWndStmtList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
  955.         }
  956.         else if (bRunQueryBtnDown && PtInRect(&stRunQuery, stMousePosition))
  957.         {
  958.             bRunQueryBtnDown = FALSE;
  959.             nLastButtonDown = 0;
  960.             InvalidateRect(hWnd, &stRunQuery, TRUE);
  961.             PostMessage(hWndFrame, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_QUERY, 0, 0));
  962.             SendMessage(hWndCrsrList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
  963.             SendMessage(hWndStmtList, CB_SHOWDROPDOWN, (WPARAM)FALSE, 0);
  964.                 }
  965.  
  966.         ReleaseCapture();
  967.         wStatusText = 0;
  968.         InvalidateRect(hWndStatusbar, &rectStatusText, TRUE);
  969.         break;
  970.  
  971.         case WM_MOUSEMOVE:
  972.                 
  973.         // process mouse movement only if the mouse key was pressed
  974.         // down and its movements were being captured. If the mouse
  975.         // moves outside of the currently depressed button, it needs
  976.         // to be drawn again with normal state.
  977.         if (hWnd != GetCapture())
  978.             break;
  979.  
  980.         stMousePosition.x = LOWORD(lParam);
  981.         stMousePosition.y = HIWORD(lParam);
  982.  
  983.         if (nLastButtonDown == IDM_NEW)
  984.         {
  985.             bButtonPosition = PtInRect(&stNewQuery, stMousePosition);
  986.             if (bNewQueryBtnDown != bButtonPosition)
  987.             {
  988.                 bNewQueryBtnDown = bButtonPosition;
  989.                 InvalidateRect(hWnd, &stNewQuery, TRUE);
  990.             }
  991.         }
  992.         else if (nLastButtonDown == IDM_QUERY)
  993.         {
  994.             bButtonPosition = PtInRect(&stRunQuery, stMousePosition);
  995.             if (bRunQueryBtnDown != bButtonPosition)
  996.             {
  997.                 bRunQueryBtnDown = bButtonPosition;
  998.                 InvalidateRect(hWnd, &stRunQuery, TRUE);
  999.             }
  1000.         }
  1001.         break;
  1002.  
  1003.         case WM_PAINT:
  1004.                 {
  1005.         PAINTSTRUCT    ps;            //paint structure
  1006.         RECT        rect;        //rectangle for tool bar
  1007.         HDC            hDC;        //device context handle
  1008.         int            iWidth;        //tool bar width
  1009.         int            iHeight;    //tool bar height
  1010.         HPEN        hLtGrayPen;    //buttonface color pen
  1011.         HPEN        hGrayPen;    //buttonshadow color pen
  1012.         int            btnx;        //button x coordinate position
  1013.                                 
  1014.         if (!(hDC = BeginPaint(hWnd, &ps)))
  1015.             break;
  1016.  
  1017.         GetClientRect(hWnd, &rect);
  1018.         iWidth = rect.right;
  1019.         iHeight = rect.bottom;
  1020.  
  1021.         hLtGrayPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNFACE));
  1022.         hGrayPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));
  1023.                 
  1024.         // draw background and border
  1025.         SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  1026.         SelectObject(hDC, hLtGrayPen);
  1027.         Rectangle(hDC, 0, 0, iWidth, iHeight);
  1028.  
  1029.         SelectObject(hDC, GetStockObject(BLACK_PEN));
  1030.         MoveToEx(hDC, 0, iHeight-1, NULL);
  1031.         LineTo(hDC, iWidth, iHeight-1);
  1032.  
  1033.         SelectObject(hDC, GetStockObject(WHITE_PEN));
  1034.         MoveToEx(hDC, 0, 0, NULL);
  1035.         LineTo(hDC, iWidth, 0);
  1036.  
  1037.         // draw tool bar buttons (new query, run query)
  1038.         // check state variables to draw proper button state
  1039.         btnx = BTTNX;
  1040.         SelectObject(hDC, GetStockObject(BLACK_PEN));
  1041.         DRAWBTTNRECT(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
  1042.         DrawBitmap(hDC, (bNewQueryBtnDown?btnx+3:btnx+2), (bNewQueryBtnDown?BTTNY+3:BTTNY+2), hbmpNewQuery);
  1043.         SelectObject(hDC, (bNewQueryBtnDown ? hGrayPen : GetStockObject(WHITE_PEN)));
  1044.         DRAWBTTNLIFT1(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
  1045.         SelectObject(hDC, (bNewQueryBtnDown ? hLtGrayPen : hGrayPen));
  1046.         DRAWBTTNLIFT2(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
  1047.  
  1048.         btnx += BTTNWIDTH+BTTNMARGIN;
  1049.         SelectObject(hDC, GetStockObject(BLACK_PEN));
  1050.         DRAWBTTNRECT(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
  1051.         DrawBitmap(hDC, (bRunQueryBtnDown?btnx+3:btnx+2), (bRunQueryBtnDown?BTTNY+3:BTTNY+2), hbmpRunQuery);
  1052.         SelectObject(hDC, (bRunQueryBtnDown ? hGrayPen : GetStockObject(WHITE_PEN)));
  1053.         DRAWBTTNLIFT1(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
  1054.         SelectObject(hDC, (bRunQueryBtnDown ? hLtGrayPen : hGrayPen));
  1055.         DRAWBTTNLIFT2(hDC, btnx, BTTNY, BTTNWIDTH, BTTNHEIGHT);
  1056.  
  1057.         SelectObject(hDC, GetStockObject(WHITE_PEN));
  1058.         EndPaint(hWnd, &ps);
  1059.         
  1060.         // delete create objects
  1061.         if (hLtGrayPen)
  1062.             DeleteObject(hLtGrayPen);
  1063.         if (hGrayPen)
  1064.             DeleteObject(hGrayPen);
  1065.         break;
  1066.                 }
  1067.                 
  1068.         default:
  1069.  
  1070.         return (DefWindowProc(hWnd, message, wParam, lParam));
  1071.     }
  1072.     return (0);
  1073. }
  1074.  
  1075. /*
  1076.     FUNCTION: StatusbarProc(HWND hWnd, UINT   message, WPARAM wParam, LPARAM lParam)
  1077.     COMMENTS: callback window procedure for status bar.
  1078.           process paint messages and timer messages to update current
  1079.           state, date and time
  1080. */
  1081. long CALLBACK StatusbarProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1082. {
  1083.     switch (message)
  1084.     {
  1085.     static RECT DateTimeRect; // remember for frequent updates
  1086.     
  1087.         case WM_CREATE:
  1088.                 {
  1089.         HDC        hDC;            // device context
  1090.         SIZE    sizeText;       // size of status text box
  1091.         SIZE    sizeTime;       // size of time display box
  1092.         SIZE    sizeDate;       // size of date display box
  1093.                 
  1094.         // start a timer for periodic updates to date and time display
  1095.         // find out width of status text, date and time display boxes
  1096.         SetTimer(hWnd,  (UINT)IDT_STATUSTIMER, (UINT)TIMERDELAY, NULL);
  1097.  
  1098.         iTimex = iDatex = 0;
  1099.         rectStatusText.left = 2;
  1100.         rectStatusText.top = 3;
  1101.  
  1102.         if (hDC = GetDC(hWnd))
  1103.         {
  1104.             GetTextExtentPoint(hDC, STATUSCONSTRAINT_COLUMN_USAGE, strlen(STATUSCONSTRAINT_COLUMN_USAGE), &sizeText);
  1105.             GetTextExtentPoint(hDC, TIMETEXT, strlen(TIMETEXT), &sizeTime);
  1106.             GetTextExtentPoint(hDC, DATETEXT, strlen(DATETEXT), &sizeDate);
  1107.             ReleaseDC(hWnd, hDC);
  1108.             rectStatusText.right = sizeText.cx + rectStatusText.left;
  1109.             iTimex = sizeTime.cx;
  1110.             iDatex = sizeDate.cx;
  1111.         }
  1112.         break;
  1113.                 }
  1114.                 
  1115.         case WM_TIMER:
  1116.         
  1117.         // invalidate only the date&time area for update
  1118.          InvalidateRect(hWnd, &DateTimeRect, TRUE);
  1119.         break;
  1120.  
  1121.         case WM_PAINT:
  1122.                 {
  1123.         HDC            hDC;                //device context
  1124.         PAINTSTRUCT    ps;                    //paint structure
  1125.         RECT        rect;               //status bar rect
  1126.         int            iWidth;             //status bar width
  1127.         int            iHeight;            //status bar height
  1128.         HPEN        hLtGrayPen;         //btnface color pen
  1129.         HPEN        hGrayPen;           //btnshadow color pen
  1130.         char        szText[MAXBUFLEN];  //text buffer for display
  1131.         time_t        tCurrentTime;       //current date&time
  1132.         struct tm    stTime;             //date&time structure
  1133.  
  1134.         if (!(hDC = BeginPaint(hWnd, &ps)))
  1135.             break;
  1136.  
  1137.         GetClientRect(hWnd, &rect);
  1138.         iWidth = rect.right;
  1139.         iHeight = rect.bottom;
  1140.         rectStatusText.bottom = iHeight-2;
  1141.         
  1142.         hLtGrayPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNFACE));
  1143.         hGrayPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));
  1144.  
  1145.         // paint background and border
  1146.         SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  1147.         SelectObject(hDC, hLtGrayPen);
  1148.         Rectangle(hDC, 0, 0, iWidth, iHeight);
  1149.  
  1150.         SelectObject(hDC, GetStockObject(BLACK_PEN));
  1151.         MoveToEx(hDC, 0, 0, NULL);
  1152.         LineTo(hDC, iWidth, 0);
  1153.         SelectObject(hDC, GetStockObject(WHITE_PEN));
  1154.         MoveToEx(hDC, 0, 1, NULL);
  1155.         LineTo(hDC, iWidth, 1);
  1156.                 
  1157.         // draw text boxes for status, time and date display
  1158.         SelectObject(hDC, hGrayPen);
  1159.         MoveToEx(hDC, rectStatusText.left, rectStatusText.bottom, NULL);
  1160.         LineTo(hDC, rectStatusText.left, rectStatusText.top);
  1161.         LineTo(hDC, rectStatusText.right, rectStatusText.top);
  1162.         SelectObject(hDC, GetStockObject(WHITE_PEN));
  1163.         LineTo(hDC, rectStatusText.right, rectStatusText.bottom);
  1164.         LineTo(hDC, rectStatusText.left, rectStatusText.bottom);
  1165.         
  1166.         SelectObject(hDC, hGrayPen);
  1167.         MoveToEx(hDC, iWidth-2, 3, NULL);
  1168.         LineTo(hDC, iWidth-iDatex-2, 3);
  1169.         LineTo(hDC, iWidth-iDatex-2, iHeight-2);
  1170.         SelectObject(hDC, GetStockObject(WHITE_PEN));
  1171.         LineTo(hDC, iWidth-2, iHeight-2);
  1172.         LineTo(hDC, iWidth-2, 3);
  1173.         
  1174.         SelectObject(hDC, hGrayPen);
  1175.         MoveToEx(hDC, iWidth-iDatex-6, 3, NULL);
  1176.         LineTo(hDC, iWidth-iTimex-iDatex-6, 3);
  1177.         LineTo(hDC, iWidth-iTimex-iDatex-6, iHeight-2);
  1178.         SelectObject(hDC, GetStockObject(WHITE_PEN));
  1179.         LineTo(hDC, iWidth-iDatex-6, iHeight-2);
  1180.         LineTo(hDC, iWidth-iDatex-6, 3);
  1181.  
  1182.         // draw status text in the display box based on current
  1183.         // value of wStatusText global flag
  1184.         SetBkMode(hDC, TRANSPARENT);
  1185.         SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));
  1186.  
  1187.         switch (wStatusText)
  1188.         {
  1189.             case IDM_POPUPAPPSYS:
  1190.             
  1191.             strcpy(szText, STATUSPOPUPAPPSYS);
  1192.             break;
  1193.             
  1194.             case IDM_POPUPMDISYS:
  1195.             
  1196.             strcpy(szText, STATUSPOPUPMDISYS);
  1197.             break;
  1198.             
  1199.             case SC_RESTORE:
  1200.             
  1201.             strcpy(szText, STATUSRESTORE);
  1202.             break;
  1203.             
  1204.             case SC_MOVE:
  1205.             
  1206.             strcpy(szText, STATUSMOVE);
  1207.             break;
  1208.             
  1209.             case SC_SIZE:
  1210.             
  1211.             strcpy(szText, STATUSSIZE);
  1212.             break;
  1213.             
  1214.             case SC_MINIMIZE:
  1215.             
  1216.             strcpy(szText, STATUSMINIMIZE);
  1217.             break;
  1218.             
  1219.             case SC_MAXIMIZE:
  1220.             
  1221.             strcpy(szText, STATUSMAXIMIZE);
  1222.             break;
  1223.             
  1224.             case SC_CLOSE:
  1225.             
  1226.             strcpy(szText, STATUSCLOSE);
  1227.             break;
  1228.             
  1229.             case SC_NEXTWINDOW:
  1230.             
  1231.             strcpy(szText, STATUSNEXTWINDOW);
  1232.             break;
  1233.             
  1234.             case SC_PREVWINDOW:
  1235.             
  1236.             strcpy(szText, STATUSPREVWINDOW);
  1237.             break;
  1238.             
  1239.             case SC_TASKLIST:
  1240.             
  1241.             strcpy(szText, STATUSTASKLIST);
  1242.             break;
  1243.             
  1244.             case IDM_POPUPLOGIN:
  1245.             
  1246.             strcpy(szText, STATUSPOPUPLOGIN);
  1247.             break;
  1248.             
  1249.             case IDM_INITIALIZE:
  1250.             
  1251.             strcpy(szText, STATUSCONNECT);
  1252.             break;
  1253.             
  1254.             case IDM_DISCONNECT:
  1255.             
  1256.             strcpy(szText, STATUSDISCONNECT);
  1257.             break;
  1258.             
  1259.             case IDM_EXIT:
  1260.             
  1261.             strcpy(szText, STATUSEXIT);
  1262.             break;
  1263.             
  1264.             case IDM_POPUPQUERY:
  1265.             
  1266.             strcpy(szText, STATUSPOPUPQUERY);
  1267.             break;
  1268.             
  1269.             case IDM_QUERY:
  1270.                 
  1271.             strcpy(szText, STATUSQUERY);
  1272.             break;
  1273.  
  1274.             case IDM_NEW:
  1275.                 
  1276.                 strcpy(szText, STATUSNEW);
  1277.             break;
  1278.  
  1279.             case IDM_POPUPSCHEMA:
  1280.             
  1281.             strcpy(szText, STATUSPOPUPSCHEMA);
  1282.             break;
  1283.             
  1284.             case IDM_POPUPWINDOW:
  1285.             
  1286.             strcpy(szText, STATUSPOPUPWINDOW);
  1287.             break;
  1288.             
  1289.             case IDM_TILE:
  1290.             
  1291.             strcpy(szText, STATUSTILE);
  1292.             break;
  1293.             
  1294.             case IDM_CASCADE:
  1295.             
  1296.             strcpy(szText, STATUSCASCADE);
  1297.             break;
  1298.             
  1299.             case IDM_ICONS:
  1300.             
  1301.             strcpy(szText, STATUSICONS);
  1302.             break;
  1303.             
  1304.             case IDM_CLOSEALL:
  1305.             
  1306.             strcpy(szText, STATUSCLOSEALL);
  1307.             break;
  1308.             
  1309.             case IDM_POPUPHELP:
  1310.             
  1311.             strcpy(szText, STATUSPOPUPHELP);
  1312.             break;
  1313.             
  1314.             case IDM_APPHELP:
  1315.             
  1316.             strcpy(szText, STATUSAPPHELP);
  1317.             break;
  1318.             
  1319.             case IDM_ABOUT:
  1320.             
  1321.             strcpy(szText, STATUSABOUT);
  1322.             break;
  1323.             
  1324.             case IDM_ASSERTIONS: 
  1325.             
  1326.             strcpy(szText, STATUSASSERTIONS);
  1327.             break;
  1328.  
  1329.             case IDM_CATALOGS: 
  1330.             
  1331.             strcpy(szText, STATUSCATALOGS);
  1332.             break;
  1333.  
  1334.             case IDM_CHARACTER_SETS: 
  1335.             
  1336.             strcpy(szText, STATUSCHARACTER_SETS);    
  1337.             break;
  1338.  
  1339.             case IDM_CHECK_CONSTRAINTS:
  1340.             
  1341.             strcpy(szText, STATUSCHECK_CONSTRAINTS);    
  1342.             break;
  1343.  
  1344.             case IDM_COLLATIONS: 
  1345.             
  1346.             strcpy(szText, STATUSCOLLATIONS);    
  1347.             break;
  1348.  
  1349.             case IDM_COLUMN_DOMAIN_USAGE: 
  1350.             
  1351.             strcpy(szText, STATUSCOLUMN_DOMAIN_USAGE);    
  1352.             break;
  1353.  
  1354.             case IDM_COLUMN_PRIVILEGES: 
  1355.             
  1356.             strcpy(szText, STATUSCOLUMN_PRIVILEGES);    
  1357.             break;
  1358.  
  1359.             case IDM_COLUMNS: 
  1360.             
  1361.             strcpy(szText, STATUSCOLUMNS);    
  1362.             break;
  1363.  
  1364.             case IDM_CONSTRAINT_COLUMN_USAGE: 
  1365.             
  1366.             strcpy(szText, STATUSCONSTRAINT_COLUMN_USAGE);    
  1367.             break;
  1368.  
  1369.             case IDM_CONSTRAINT_TABLE_USAGE: 
  1370.             
  1371.             strcpy(szText, STATUSCONSTRAINT_TABLE_USAGE);    
  1372.             break;
  1373.  
  1374.             case IDM_FOREIGN_KEYS: 
  1375.             
  1376.             strcpy(szText, STATUSFOREIGN_KEYS);    
  1377.             break;
  1378.  
  1379.             case IDM_INDEXES: 
  1380.                 
  1381.             strcpy(szText, STATUSINDEXES);    
  1382.             break;
  1383.  
  1384.             case IDM_KEY_COLUMN_USAGE: 
  1385.                 
  1386.             strcpy(szText, STATUSKEY_COLUMN_USAGE);    
  1387.             break;
  1388.  
  1389.             case IDM_PRIMARY_KEYS: 
  1390.             
  1391.             strcpy(szText, STATUSPRIMARY_KEYS);    
  1392.             break;
  1393.  
  1394.             case IDM_PROCEDURE_COLUMNS: 
  1395.             
  1396.             strcpy(szText, STATUSPROCEDURE_COLUMNS);    
  1397.             break;
  1398.  
  1399.             case IDM_PROCEDURE_PARAMETERS: 
  1400.             
  1401.             strcpy(szText, STATUSPROCEDURE_PARAMETERS);    
  1402.             break;
  1403.  
  1404.             case IDM_PROCEDURES: 
  1405.             
  1406.             strcpy(szText, STATUSPROCEDURES);    
  1407.             break;
  1408.  
  1409.             case IDM_PROVIDER_TYPES: 
  1410.             
  1411.             strcpy(szText, STATUSPROVIDER_TYPES);    
  1412.             break;
  1413.  
  1414.             case IDM_REFERENTIAL_CONSTRAINTS: 
  1415.             
  1416.             strcpy(szText, STATUSREFERENTIAL_CONSTRAINTS);    
  1417.             break;
  1418.  
  1419.             case IDM_SCHEMATA: 
  1420.             
  1421.             strcpy(szText, STATUSSCHEMATA);    
  1422.             break;
  1423.  
  1424.             case IDM_SQL_LANGUAGES: 
  1425.             
  1426.             strcpy(szText, STATUSSQL_LANGUAGES);    
  1427.             break;
  1428.  
  1429.             case IDM_STATISTICS: 
  1430.             
  1431.             strcpy(szText, STATUSSTATISTICS);    
  1432.             break;
  1433.  
  1434.             case IDM_TABLE_CONSTRAINTS: 
  1435.             
  1436.             strcpy(szText, STATUSTABLE_CONSTRAINTS);    
  1437.             break;
  1438.  
  1439.             case IDM_TABLE_PRIVILEGES: 
  1440.             
  1441.             strcpy(szText, STATUSTABLE_PRIVILEGES);
  1442.             break;
  1443.  
  1444.             case IDM_TABLES: 
  1445.             
  1446.             strcpy(szText, STATUSTABLES);    
  1447.             break;
  1448.  
  1449.             case IDM_TRANSLATIONS: 
  1450.             
  1451.             strcpy(szText, STATUSTRANSLATIONS);    
  1452.             break;
  1453.  
  1454.             case IDM_USAGE_PRIVILEGES: 
  1455.             
  1456.             strcpy(szText, STATUSUSAGE_PRIVILEGES);    
  1457.             break;
  1458.  
  1459.             case IDM_VIEW_COLUMN_USAGE: 
  1460.             
  1461.             strcpy(szText, STATUSVIEW_COLUMN_USAGE);    
  1462.             break;
  1463.  
  1464.             case IDM_VIEW_TABLE_USAGE: 
  1465.             
  1466.             strcpy(szText, STATUSVIEW_TABLE_USAGE);    
  1467.             break;
  1468.  
  1469.             case IDM_VIEWS: 
  1470.             
  1471.             strcpy(szText, STATUSVIEWS);    
  1472.             break;
  1473.  
  1474.             default:
  1475.                         
  1476.             if (wStatusText >= IDM_MDICHILD)
  1477.                 sprintf(szText, STATUSMDICHILD, wStatusText-IDM_MDICHILD+1);
  1478.             else    
  1479.             strcpy(szText, STATUSDEFAULT);
  1480.             break;
  1481.         }
  1482.         
  1483.         DrawText(hDC, szText, strlen(szText), &rectStatusText, DT_LEFT);
  1484.                 
  1485.         // get current date and time and display time in time box
  1486.         time(&tCurrentTime);
  1487.         stTime = *localtime(&tCurrentTime);
  1488.         strftime(szText, MAXBUFLEN, TIMEFORMAT, &stTime);
  1489.         rect.top = rectStatusText.top;
  1490.         rect.bottom = rectStatusText.bottom;
  1491.         rect.left  = iWidth-iTimex-iDatex-6;
  1492.         rect.right = iWidth-iDatex-6;
  1493.         DrawText(hDC, szText, strlen(szText), &rect, DT_LEFT);
  1494.         
  1495.         // display date in date box
  1496.         strftime(szText, MAXBUFLEN, DATEFORMAT, &stTime);
  1497.         rect.left  = iWidth-iDatex-2;
  1498.         rect.right = iWidth-2;
  1499.         DrawText(hDC, szText, strlen(szText), &rect, DT_LEFT);
  1500.  
  1501.         // remember the date&time rectangle to minimize painting
  1502.         DateTimeRect.left   = iWidth-iTimex-iDatex-6;
  1503.         DateTimeRect.right  = iWidth-2;
  1504.         DateTimeRect.top    = rect.top;
  1505.         DateTimeRect.bottom = rect.bottom;
  1506.         
  1507.         EndPaint(hWnd, &ps);
  1508.  
  1509.         // delete created objects
  1510.         if (hLtGrayPen)
  1511.             DeleteObject(hLtGrayPen);
  1512.         if (hGrayPen)
  1513.             DeleteObject(hGrayPen);
  1514.         break;
  1515.                 }
  1516.                 
  1517.         default:
  1518.  
  1519.         return (DefWindowProc(hWnd, message, wParam, lParam));
  1520.         break;
  1521.     }
  1522.     return (0);
  1523. }
  1524.  
  1525. /*
  1526.     FUNCTION: ConnectDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1527.     COMMENTS: Callback dialog box procedure for connect menu command
  1528.           displays a list of available data sources, asks for user
  1529.           name and password to pass default connection parameters
  1530.           for a data source connection
  1531. */
  1532. BOOL CALLBACK ConnectDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1533. {
  1534.     switch (message)
  1535.     {
  1536.     HCURSOR    hOldCursor;    // Default Cursor Shape
  1537.  
  1538.         case WM_INITDIALOG:
  1539.                 
  1540.         // display list of available providers
  1541.         hOldCursor = SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
  1542.         DisplayProviders(GetDlgItem(hWnd, IDCOMBO_PROVIDER));
  1543. //        DisplayDataSource(hWnd);    
  1544.         FillPrompt(GetDlgItem(hWnd, IDCOMBO_PROMPT));
  1545.         SetCursor(hOldCursor);
  1546.         break;
  1547.         
  1548.         case WM_COMMAND:
  1549.  
  1550.         switch (GET_WM_COMMAND_ID(wParam, lParam))
  1551.         {
  1552.             // Make a connection using the supplied values
  1553.             case IDOK:
  1554.                 hOldCursor = SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
  1555.                 // Check if a DSO was provided for connection
  1556.                 if( ConnectDatabase(hWnd) )
  1557.                     EndDialog(hWnd, TRUE);
  1558.                 SetCursor(hOldCursor);
  1559.             break;
  1560.  
  1561.             case IDCANCEL:
  1562.                 EndDialog(hWnd, FALSE);
  1563.             break;
  1564.  
  1565.             default:
  1566.  
  1567.             return (FALSE);
  1568.             break;
  1569.         }
  1570.         break;
  1571.         
  1572.         default:
  1573.         
  1574.         return (FALSE);
  1575.         break;
  1576.     }
  1577.     return (TRUE);
  1578. }
  1579.  
  1580. /*
  1581.     FUNCTION: DisconnectDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1582.     COMMENTS: Callback dialog box procedure for disconnect dialog.
  1583.           provides a list of available SESSIONs and a list of HSTMTs
  1584.           for currently selected SESSION. Allows closure of all SESSIONs
  1585.           and HSTMTs one by one or in groups.
  1586. */
  1587. BOOL CALLBACK DisconnectDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1588. {
  1589.     switch (message)
  1590.     {
  1591.     static HWND    hListhdbc;        //listbox that displays hdbc(s)
  1592.     static HWND    hListstmt;      //listbox that displays hstmt(s)
  1593.     static HWND    hPushOk;        //pushbutton to free hdbc
  1594.     static HWND    hPushClose;     //pushbutton to free hstmt
  1595.     static HWND    hPushCancel;    //pushbutton to close dialog
  1596.  
  1597.         case WM_INITDIALOG:
  1598.  
  1599.         // store handles for future reference
  1600.         hListhdbc = GetDlgItem(hWnd, IDLIST_SESSION);
  1601.         hListstmt = GetDlgItem(hWnd, IDLIST_COMMAND);
  1602.         hPushOk = GetDlgItem(hWnd, IDDISCONNECT);
  1603.         hPushCancel = GetDlgItem(hWnd, IDCANCEL);
  1604.         hPushClose = GetDlgItem(hWnd, IDCLOSE_ACTVTY);
  1605.  
  1606.         // display connected database handles and statements
  1607.         DisplayConnections(hListhdbc);
  1608.         DisplayICommands(hListstmt, hListhdbc, 0);
  1609.  
  1610.         // enable or disable pushbuttons & listboxes to match available hdbc & hstmt
  1611.         if (SendMessage(hListhdbc, LB_GETCOUNT, 0, 0)>0)
  1612.         {
  1613.             EnableWindow(hPushOk, TRUE);
  1614.             if (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0)
  1615.             {
  1616.                 EnableWindow(hPushClose, TRUE);
  1617.                 SetFocus(hPushClose);
  1618.                 SendMessage(hPushClose, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
  1619.             }
  1620.             else
  1621.             {
  1622.                 EnableWindow(hListstmt, FALSE);
  1623.                 EnableWindow(hPushClose, FALSE);
  1624.                 SetFocus(hPushOk);
  1625.                 SendMessage(hPushOk, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
  1626.             }
  1627.         }
  1628.         else
  1629.         {
  1630.             EnableWindow(hListhdbc, FALSE);
  1631.             EnableWindow(hListstmt, FALSE);
  1632.             EnableWindow(hPushOk, FALSE);
  1633.             SetFocus(hPushCancel);
  1634.             SendMessage(hPushCancel, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
  1635.         }
  1636.         
  1637.         // return FALSE to prevent default focus.
  1638.         return (FALSE);
  1639.  
  1640.         case WM_COMMAND:
  1641.  
  1642.         switch (GET_WM_COMMAND_ID(wParam, lParam))
  1643.         {
  1644.             case IDDISCONNECT:
  1645.                         
  1646.             // Free current hdbc, display available hdbc(s)
  1647.             FreeConnect(hListhdbc);
  1648.             SendMessage(hListstmt, LB_RESETCONTENT, 0, 0);
  1649.             DisplayConnections(hListhdbc);
  1650.                         
  1651.             // update displayed hstmt(s) for current hdbc
  1652.             // enable or disable pushbuttons to match available
  1653.             // hdbc(s) and hstmt(s) for closure
  1654.             if (SendMessage(hListhdbc, LB_GETCOUNT, 0, 0) > 0)
  1655.             {
  1656.                 SendMessage(hListhdbc, LB_SETCURSEL, 0, 0);
  1657.                 EnableWindow(hListstmt, TRUE);
  1658.                 DisplayICommands(hListstmt, hListhdbc, 0);
  1659.                 if (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0)
  1660.                 {
  1661.                     EnableWindow(hPushClose, TRUE);
  1662.                     SetFocus(hPushClose);
  1663.                     SendMessage(hPushClose, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
  1664.                 }
  1665.                 else
  1666.                 {
  1667.                     EnableWindow(hListstmt, FALSE);
  1668.                     EnableWindow(hPushClose, FALSE);
  1669.                     SetFocus(hPushOk);
  1670.                     SendMessage(hPushOk, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
  1671.                 }
  1672.             }
  1673.             else
  1674.             {
  1675.                 EnableWindow(hListhdbc, FALSE);
  1676.                 EnableWindow(hPushOk, FALSE);
  1677.                 EnableWindow(hPushClose, FALSE);
  1678.                 SetFocus(hPushCancel);
  1679.                 SendMessage(hPushCancel, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
  1680.             }
  1681.             break;
  1682.  
  1683.             case IDCANCEL:
  1684.  
  1685.             // close dialog
  1686.             EndDialog(hWnd, FALSE);
  1687.             break;
  1688.  
  1689.             case IDCLOSE_ACTVTY:
  1690.                         {
  1691.             int    nIndex;    // counter to search for selected hstmt(s)
  1692.             
  1693.             // go through all displayed hstmt(s) and free all highlighted ones
  1694.             for (nIndex = (int)SendMessage(hListstmt, LB_GETCOUNT, 0, 0)-1;
  1695.                 nIndex >= 0; nIndex--)
  1696.                 if (SendMessage(hListstmt, LB_GETSEL, nIndex, 0))
  1697.                     FreeICommand(hListstmt, hListhdbc, nIndex);
  1698.  
  1699.             // reset both hdbc(s) and hstmt(s) display
  1700.             nIndex = (int)SendMessage(hListhdbc, LB_GETCURSEL, 0, 0);
  1701.             DisplayConnections(hListhdbc);
  1702.             SendMessage(hListhdbc, LB_SETCURSEL, nIndex, 0);
  1703.             DisplayICommands(hListstmt, hListhdbc, nIndex);
  1704.             
  1705.             // enable or disable pushbuttons to match available
  1706.             // hdbc(s) and hstmt(s) for closure
  1707.             if (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0)
  1708.             {
  1709.                 EnableWindow(hPushClose, TRUE);
  1710.                 SetFocus(hPushClose);
  1711.                 SendMessage(hPushClose, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
  1712.             }
  1713.             else
  1714.             {
  1715.                 EnableWindow(hListstmt, FALSE);
  1716.                 EnableWindow(hPushClose, FALSE);
  1717.                 SetFocus(hPushOk);
  1718.                 SendMessage(hPushOk, BM_SETSTYLE, (WPARAM)BS_DEFPUSHBUTTON, TRUE);
  1719.             }
  1720.             break;
  1721.                         }
  1722.                         
  1723.             case IDLIST_SESSION:
  1724.             // If the current selection in hdbc(s) has changed
  1725.             // update the list of hstmt(s) to match the new hdbc
  1726.             if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_SELCHANGE)
  1727.                 DisplayICommands(hListstmt, hListhdbc,
  1728.                 (UINT)SendMessage(GET_WM_COMMAND_HWND(wParam, lParam), LB_GETCURSEL, 0, 0));
  1729.  
  1730.             // Enable or disable hstmt listbox and close pushbutton accordingly
  1731.             EnableWindow(hListstmt, (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0));
  1732.             EnableWindow(hPushClose, (SendMessage(hListstmt, LB_GETCOUNT, 0, 0)>0));
  1733.             break;
  1734.  
  1735.             default:
  1736.  
  1737.             return (FALSE);
  1738.         }
  1739.         break;
  1740.  
  1741.         default:
  1742.  
  1743.         return (FALSE);
  1744.     }
  1745.     
  1746.     return (TRUE);
  1747. }
  1748.  
  1749. /*
  1750.     FUNCTION: AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1751.     COMMENTS: Callback dialog box procedure for About dialog box
  1752.           displays the about information and closes upon selection of
  1753.           ok button
  1754. */
  1755. BOOL CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1756. {
  1757.     if (message == WM_COMMAND)
  1758.     {
  1759.         EndDialog(hWnd, TRUE);
  1760.         return (TRUE);
  1761.     }
  1762.     else
  1763.         return (FALSE);
  1764. }
  1765.  
  1766. /*
  1767.     FUNCTION: MDIChildDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1768.     COMMENTS: Callback dialog box procedure for modeless child dialog box
  1769.           in each MDI Child Window. This dialog box simply processes
  1770.           the tab messages (by default) to allow switching from edit
  1771.           control (SQL Text) to list box control (Query results).
  1772. */
  1773. BOOL CALLBACK MDIChildDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1774. {
  1775.     return (FALSE);
  1776. }
  1777.  
  1778. /*
  1779.     FUNCTION: DrawBitmap(HDC hDC, int iLeft, int iTop, HBITMAP hBitmap
  1780.     COMMENTS: Draws a bitmap on given Device context with given bitmap
  1781.           handle at given location
  1782. */
  1783.  
  1784. VOID FAR PASCAL DrawBitmap(HDC hDC, int iLeft, int iTop, HBITMAP hBitmap)
  1785. {
  1786.     HDC        hMemDC;        // Device Context in Memory
  1787.     POINT    stPoint;    // point structure for conversion from device to logical units
  1788.     BITMAP    stBitmap;
  1789.     HGDIOBJ hObject;
  1790.         
  1791.     // create a compatible device context in memory and select the bitmap
  1792.     // in to it.
  1793.     if (!(hMemDC = CreateCompatibleDC(hDC))) return;
  1794.  
  1795.     hObject = SelectObject(hMemDC, hBitmap);
  1796.     SetMapMode(hMemDC, GetMapMode(hDC));
  1797.  
  1798.     // Get bitmap size and convert it to logical units from device units.
  1799.     GetObject(hBitmap, sizeof(BITMAP), &stBitmap);
  1800.     stPoint.x = stBitmap.bmWidth;
  1801.     stPoint.y = stBitmap.bmHeight;
  1802.     DPtoLP(hDC, &stPoint, 1);
  1803.  
  1804.     // bit block transfer the bitmap from memory device context to given
  1805.     // device context at specified location
  1806.     BitBlt(hDC, iLeft, iTop, stPoint.x, stPoint.y, hMemDC, 0, 0, SRCCOPY);
  1807.         
  1808.     // select original object in the memory device context and destroy it
  1809.     SelectObject(hMemDC, hObject);
  1810.     DeleteDC(hMemDC);
  1811. }
  1812.  
  1813.  
  1814. void FillPrompt(HWND hWnd)
  1815. {
  1816.     const static LPCTSTR rgPrompts[] =
  1817.     {    
  1818.         //The order is the same as the Actual DBPROMPT Values
  1819.         "Not Set",            // 0
  1820.         "PROMPT",            // 1 == DBPROMPT_PROMPT
  1821.         "COMPLETE",            // 2 == DBPROMPT_COMPLETE
  1822.         "COMPLETEREQUIRED",    // 3 == DBPROMPT_COMPLETEREQUIRED
  1823.         "NOPROMPT"            // 4 == DBPROMPT_NOPROMPT
  1824.     };
  1825.  
  1826.     for (int i=0;  i<sizeof(rgPrompts) / sizeof(rgPrompts[0]); i++)
  1827.         SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) rgPrompts[i]);
  1828.     SendMessage(hWnd, CB_SETCURSEL, (WPARAM) DBPROMPT_COMPLETE, 0L);
  1829. }
  1830.  
  1831. /********************************************* END OF FILE **************************************************/
  1832.