home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / odbc / crsrdemo / frame.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-20  |  15.7 KB  |  529 lines

  1. /*--------------------------------------------------------------------------
  2.   Frame.C --- Cursors main window procedure
  3.  
  4.   Description:
  5.         This sample is spread across four files, each named for the role
  6.         the contained functions play.  Each file header contains a brief
  7.         description of its purpose and the routines it contains.
  8.  
  9.         FRAME.C contains those functions used to manage the main frame
  10.         window.  The frame window, created by code in MAIN.C, owns the
  11.         MDI client window, the menu bar, and other major parts of the
  12.         interface.  The functions is contains are:
  13.  
  14.             AdjustMenus    - Enable/disable menu items given current state
  15.             CloseAll       - Close all child windows
  16.             CloseAllEnum   - Window enumeration callback used by CloseAll
  17.             CloseChild     - Close the currently active child window
  18.             CreateChild    - Create a new child window
  19.             DoConnect      - Connect to a host
  20.             DoDisconnect   - Disconnect from a host
  21.             DoFrameMenu    - Process a menu request
  22.             FrameProc      - Process frame window messages
  23.  
  24.   This code is furnished on an as-is basis as part of the ODBC SDK and is
  25.   intended for example purposes only.
  26.  
  27. --------------------------------------------------------------------------*/
  28.  
  29. /* Includes --------------------------------------------------------------*/
  30. #include    "headers.h"
  31.  
  32. #include   "resource.h"
  33. #include    "crsrdemo.h"
  34.  
  35.  
  36. // Constants ---------------------------------------------------------------
  37. #define fDISABLED   (MF_BYCOMMAND | MF_DISABLED | MF_GRAYED)
  38. #define fENABLED    (MF_BYCOMMAND | MF_ENABLED)
  39.  
  40.  
  41. // Prototypes --------------------------------------------------------------
  42. void INTFUNC CloseAll(HWND);
  43. void INTFUNC CloseChild(HWND);
  44. HWND INTFUNC CreateChild(HWND);
  45. BOOL INTFUNC DoConnect(HWND);
  46. void INTFUNC DoDisconnect(void);
  47. BOOL INTFUNC DoFrameMenu(HWND, WPARAM, LPARAM);
  48.  
  49. BOOL CALLBACK CloseAllEnum(HWND, LPARAM);
  50.  
  51.  
  52. /* AdjustMenus -------------------------------------------------------------
  53.     Description: Enable/disable appropriate menu items
  54.     --------------------------------------------------------------------------*/
  55. void INTFUNC AdjustMenus(void)
  56. {
  57.    LRESULT lresult;
  58.    BOOL    fMaximized;
  59.    HWND    hwnd;
  60.    HMENU   hmenu;
  61.    UINT    idMenu;
  62.    UINT    fOption;
  63.  
  64.    lresult = SendMessage(g_hwndClient, WM_MDIGETACTIVE, 0, 0L);
  65.  
  66. #ifdef WIN32
  67.    hwnd       = (HWND)lresult;
  68.    fMaximized = GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZE;
  69. #else
  70.    hwnd       = (HWND)(LOWORD(lresult));
  71.    fMaximized = HIWORD(lresult);
  72. #endif
  73.  
  74.    if( hwnd ) {
  75.       LPCHILD lpchild;
  76.  
  77.       lpchild = (LPCHILD)GetWindowLong(hwnd, 0);
  78.  
  79.       idMenu = IDM_FETCH + (fMaximized ? 1 : 0);
  80.  
  81.       if( lpchild->fResultSetExists ) {
  82.          EnableMenuItem(GetMenu(g_hwnd), idMenu, MF_BYPOSITION |
  83.                         MF_ENABLED);
  84.          fOption = fENABLED;
  85.       }
  86.       else {
  87.          EnableMenuItem(GetMenu(g_hwnd), idMenu, MF_BYPOSITION |
  88.                         MF_DISABLED   |
  89.                         MF_GRAYED);
  90.          fOption = fDISABLED;
  91.       }
  92.  
  93.       hmenu = GetSubMenu(GetMenu(g_hwnd), idMenu);
  94.       EnableMenuItem(hmenu, IDM_FETCH_FIRST, fOption);
  95.       EnableMenuItem(hmenu, IDM_FETCH_PRIOR,  fOption);
  96.       EnableMenuItem(hmenu, IDM_FETCH_NEXT,   fOption);
  97.       EnableMenuItem(hmenu, IDM_FETCH_LAST,   fOption);
  98.       EnableMenuItem(hmenu, IDM_FETCH_ABSOLUTE, fOption);
  99.       EnableMenuItem(hmenu, IDM_FETCH_RELATIVE, fOption);
  100. #if 0
  101.       EnableMenuItem(hmenu, IDM_FETCH_RESUME, fOption);
  102. #endif  //  0
  103.       if( lpchild->dwOperation != OPER_SELECT ) {
  104.          EnableMenuItem(hmenu, (UINT)IDM_FETCH_DELETEROW, fDISABLED);
  105.          EnableMenuItem(hmenu, (UINT)IDM_FETCH_UPDATEROW, fDISABLED);
  106.       }
  107.       else {
  108.          EnableMenuItem(hmenu, (UINT)IDM_FETCH_DELETEROW, fOption);
  109.          EnableMenuItem(hmenu, (UINT)IDM_FETCH_UPDATEROW, fOption);
  110.       }
  111.  
  112.       idMenu = IDM_FETCHCHILD + (fMaximized ? 1 : 0);
  113.       if( g_fConnected ) {
  114.          EnableMenuItem(GetMenu(g_hwnd), idMenu, MF_BYPOSITION |
  115.                         MF_ENABLED);
  116.          fOption = fENABLED;
  117.       }
  118.       else {
  119.          EnableMenuItem(GetMenu(g_hwnd), idMenu, MF_BYPOSITION  |
  120.                         MF_DISABLED    |
  121.                         MF_GRAYED);
  122.          fOption = fDISABLED;
  123.       }
  124.    }
  125.    else {
  126.       UINT    wCount;
  127.       
  128.       hmenu = GetMenu(g_hwnd);
  129.       wCount = GetMenuItemCount(hmenu);
  130.       for( idMenu = 0; idMenu < wCount; idMenu++ )
  131.          EnableMenuItem(hmenu, idMenu, MF_BYPOSITION | MF_ENABLED);
  132.    }
  133.  
  134.    DrawMenuBar(g_hwnd);
  135.    return;
  136. }
  137.  
  138.  
  139. /* CloseAll ----------------------------------------------------------------
  140.     Description: Close all child windows
  141.     --------------------------------------------------------------------------*/
  142. void INTFUNC CloseAll(HWND hwnd)
  143. {
  144.    UNREF_PARAM(hwnd);
  145.    if (!g_fConnected)
  146.       return;
  147.  
  148.    EnumChildWindows(g_hwndClient, CloseAllEnum, 0L);
  149.    return;
  150. }
  151.  
  152.  
  153. /* CloseAllEnum ------------------------------------------------------------
  154.     Description: EnumChildWindows procedure, it calls CloseChild for each
  155.                  child window passed
  156.                  --------------------------------------------------------------------------*/
  157. BOOL CALLBACK CloseAllEnum(HWND hwnd, LPARAM lparam)
  158. {
  159.    UNREF_PARAM(lparam);
  160.    if (!GetWindow(hwnd, GW_OWNER))
  161.       CloseChild(hwnd);
  162.    return TRUE;
  163. }
  164.  
  165.  
  166. /* CloseChild --------------------------------------------------------------
  167.     Description: Close a child window
  168.     --------------------------------------------------------------------------*/
  169. void INTFUNC CloseChild(HWND hwnd)
  170. {
  171.    // Destroy child window
  172.    FORWARD_WM_MDIDESTROY(g_hwndClient, hwnd, SendMessage);
  173.  
  174.    // Decrement child count
  175.    g_cChild--;
  176.  
  177.    // Set appropriate menu bar
  178.    if (!g_cChild)
  179. #ifdef WIN32
  180.       SendMessage(g_hwndClient,WM_MDISETMENU,(WPARAM)g_hmenuFrame,(LPARAM)g_hmenuFrameWindow);
  181. #else
  182.    FORWARD_WM_MDISETMENU(g_hwndClient,
  183.                          0, g_hmenuFrame, g_hmenuFrameWindow, SendMessage);
  184. #endif
  185.    return;
  186. }
  187.  
  188.  
  189. /* CreateChild -------------------------------------------------------------
  190.     Description: Create a child window
  191.     --------------------------------------------------------------------------*/
  192. HWND INTFUNC CreateChild(HWND hwnd)
  193. {
  194.    HWND            hwndChild;
  195.    MDICREATESTRUCT mdi;
  196.    int             x, y, cx, cy;
  197.  
  198.    // Have child fill client area if it is the only child window
  199.    if (!g_cChild) {
  200.       RECT    rc;
  201.  
  202.       GetClientRect(hwnd, &rc);
  203.  
  204.       x  = rc.left;
  205.       y  = rc.top;
  206.       cx = rc.right - rc.left;
  207.       cy = rc.bottom - rc.top;
  208.    }
  209.  
  210.    // Otherwise, accept default placement
  211.    else {
  212.       x  =
  213.          y  =
  214.             cx =
  215.                cy = CW_USEDEFAULT;
  216.    }
  217.  
  218.    // Increment child count and cursor number
  219.    g_cChild++;
  220.    g_cCursor++;
  221.  
  222.    // Create child via MDI interface
  223.    mdi.szClass = szCHILDCLASS;
  224.    mdi.szTitle = g_szDSN;
  225.    mdi.hOwner  = g_hinst;
  226.    mdi.x       = x;
  227.    mdi.y       = y;
  228.    mdi.cx      = cx;
  229.    mdi.cy      = cy;
  230.    mdi.style   = 0;
  231.    mdi.lParam  = (LPARAM)NULL;
  232.  
  233.    hwndChild = FORWARD_WM_MDICREATE(g_hwndClient, ((LPSTR)&mdi), SendMessage);
  234.  
  235.    if (hwndChild) {
  236.       if (g_cChild == 1)
  237. #ifdef WIN32
  238.          SendMessage(g_hwndClient,WM_MDISETMENU,(WPARAM)g_hmenuChild,(LPARAM)g_hmenuChildWindow);
  239. #else
  240.       FORWARD_WM_MDISETMENU(g_hwndClient,
  241.                             0, g_hmenuChild, g_hmenuChildWindow, SendMessage);
  242. #endif
  243.    }
  244.    else
  245.       g_cChild--;
  246.  
  247.    return hwndChild;
  248. }
  249.  
  250.  
  251. /* DoConnect ---------------------------------------------------------------
  252.     Description: Connect to a data source
  253.     --------------------------------------------------------------------------*/
  254. BOOL INTFUNC DoConnect(HWND hwnd)
  255. {
  256.    HCURSOR   hcur;
  257.    char      sz[cbMAXSQL];
  258.    SWORD     cb;
  259.    SQLRETURN rc;
  260.  
  261.    // If already connected, close all children and disconnect
  262.    if (g_fConnected) {
  263.       LoadString(g_hinst, IDS_CONWARN, sz, sizeof(sz));
  264.       rc = MessageBox(hwnd,
  265.                       sz, g_szTITLE,
  266.                       MB_ICONQUESTION | MB_OKCANCEL | MB_DEFBUTTON2);
  267.       if (rc == IDCANCEL)
  268.          return FALSE;
  269.       CloseAll(hwnd);
  270.       DoDisconnect();
  271.    }
  272.  
  273.    hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  274.  
  275.    // Call SQLDriverConnect
  276.    rc = SQLDriverConnect(g_hdbc, g_hwnd, NULL, 0,
  277.                          (UCHAR FAR *)sz, sizeof(sz), &cb, SQL_DRIVER_COMPLETE);
  278.  
  279.    // If successfully connected, get data source attributes
  280.    if (SUCCESS(rc)) {
  281.       LPSTR    lpszS, lpszD;
  282.       SQLHSTMT hstmt;
  283.  
  284.       // Mark as connected
  285.       g_fConnected = TRUE;
  286.  
  287.       // Extract and save data source name
  288.       lpszS = _fstrstr(sz, szDSNKEY);
  289.  
  290.       if (lpszS) {
  291.          lpszS = _fstrstr(sz, szDSNKEY) + lstrlen(szDSNKEY);
  292.          lpszD = g_szDSN;
  293.          while (*lpszS && *lpszS != ';') *lpszD++ = *lpszS++;
  294.          *lpszD = '\0';
  295.       }
  296.       else
  297.          LoadString(g_hinst, IDS_NODSN, g_szDSN, sizeof(g_szDSN));
  298.  
  299.       // Change to the appropriate menu bar
  300. #ifdef WIN32
  301.       SendMessage(g_hwndClient,WM_MDISETMENU,(WPARAM)g_hmenuFrame,(LPARAM)g_hmenuFrameWindow);
  302. #else
  303.       FORWARD_WM_MDISETMENU(g_hwndClient,
  304.                             0, g_hmenuFrame, g_hmenuFrameWindow, SendMessage);
  305. #endif
  306.  
  307.       // Get maximum column name length
  308.       if (DBCError(hwnd, SQLGetInfo(g_hdbc, SQL_MAX_COLUMN_NAME_LEN,
  309.                                     &g_cbName, sizeof(g_cbName), NULL)))
  310.          g_cbName = 32;
  311.  
  312.       // Get identifier quote character
  313.       if (DBCError(hwnd, SQLGetInfo(g_hdbc, SQL_IDENTIFIER_QUOTE_CHAR,
  314.                                     g_szQuoteChar, sizeof(g_szQuoteChar), NULL)))
  315.          *g_szQuoteChar = ' ';
  316.  
  317.       // Determine if async support is available
  318.       rc = SQLAllocHandle(SQL_HANDLE_STMT,g_hdbc, &hstmt);
  319.       if (!SUCCESS(rc))
  320.          g_fAsyncSupported = FALSE;
  321.  
  322.       else {
  323.          g_fAsyncSupported = SUCCESS(SQLSetStmtAttr(hstmt,
  324.                                                     SQL_ATTR_ASYNC_ENABLE,
  325.                                                     (SQLPOINTER) 1,
  326.                                                     SQL_IS_INTEGER));
  327.          SQLFreeHandle(SQL_HANDLE_STMT,hstmt);
  328.       }
  329.    }
  330.    else if (rc != SQL_NO_DATA)
  331.       DBCError(hwnd, rc);
  332.  
  333.    SetCursor(hcur);
  334.    return SUCCESS(rc);
  335. }
  336.  
  337.  
  338. /* DoDisconnect ------------------------------------------------------------
  339.     Description: Drop ODBC connection
  340.     --------------------------------------------------------------------------*/
  341. void INTFUNC DoDisconnect(void)
  342. {
  343.    // Change to the appropriate menu bar
  344. #ifdef WIN32
  345.    SendMessage(g_hwndClient,WM_MDISETMENU,(WPARAM)g_hmenuInit,(LPARAM)g_hmenuInitWindow);
  346. #else
  347.    FORWARD_WM_MDISETMENU(g_hwndClient,
  348.                          0, g_hmenuInit, g_hmenuInitWindow, SendMessage);
  349. #endif
  350.  
  351.    // If not fully connected, return immediately
  352.    if (!g_fConnected)
  353.       return;
  354.  
  355.    // Disconnect with ODBC
  356.    SQLDisconnect(g_hdbc);
  357.  
  358.    // Reset connection related variables
  359.    g_cbName     = 0;
  360.    g_fConnected = FALSE;
  361.    g_szDSN[0]   = '\0';
  362.    g_cChild     = 0;
  363.    g_cCursor    = 0;
  364.    return;
  365. }
  366.  
  367.  
  368. /* DoFrameMenu -------------------------------------------------------------
  369.     Description: Respond to a request from the frame window menu
  370.     --------------------------------------------------------------------------*/
  371. BOOL INTFUNC DoFrameMenu(HWND  hwnd, WPARAM  wparam, LPARAM  lparam)
  372. {
  373.    HWND    hwndChild;
  374.  
  375.    hwndChild = FORWARD_WM_MDIGETACTIVE(g_hwndClient, SendMessage);
  376.  
  377.    switch (GET_WM_COMMAND_ID(wparam, lparam)) {
  378.  
  379.      case IDM_STMT_ADDDSN:
  380.       SQLCreateDataSource(hwnd, NULL);
  381.       break;
  382.  
  383.      case IDM_STMT_DISCONNECT:
  384.       if (g_cChild)
  385.          CloseAll(hwnd);
  386.       DoDisconnect();
  387.       break;
  388.  
  389.      case IDM_STMT_CONNECT:
  390.       if (!DoConnect(hwnd))
  391.          break;
  392.  
  393.      case IDM_STMT_NEW:
  394.       hwndChild = CreateChild(hwnd);
  395.       break;
  396.  
  397.      case IDM_STMT_CLOSE:
  398.       CloseChild(hwndChild);
  399.       break;
  400.  
  401.      case IDM_STMT_CLOSEALL:
  402.       CloseAll(hwnd);
  403.       break;
  404.  
  405.      case IDM_STMT_EXIT:
  406.       PostMessage(hwnd, WM_CLOSE, 0, 0L);
  407.       break;
  408.  
  409.      case IDM_WINDOW_ARRANGE:
  410.       FORWARD_WM_MDIICONARRANGE(g_hwndClient, SendMessage);
  411.       break;
  412.  
  413.      case IDM_WINDOW_CASCADE:
  414.       FORWARD_WM_MDICASCADE(g_hwndClient, 0, SendMessage);
  415.       break;
  416.  
  417.      case IDM_WINDOW_TILEH:
  418.      case IDM_WINDOW_TILEV: {
  419.         WPARAM  fTile;
  420.  
  421.         fTile = (GET_WM_COMMAND_ID(wparam, lparam) == IDM_WINDOW_TILEH
  422.                  ? MDITILE_HORIZONTAL
  423.                  : MDITILE_VERTICAL);
  424.         FORWARD_WM_MDITILE(g_hwndClient, fTile, SendMessage);
  425.         break;
  426.      }
  427.  
  428.      case IDM_HELP_ABOUT:
  429.       DoDialog(g_hwnd, IDD_ABOUTBOX, AboutDlgProc);
  430.       break;
  431.       
  432.      case IDM_HELP_HELP:
  433.       WinHelp(g_hwnd, szHELPFILE, HELP_KEY ,(DWORD)(LPTSTR)szKeyword );
  434.         break;
  435.     
  436.  
  437.  
  438.      default:
  439.       // Pass unrecognized request to the current child
  440.       SendMessage(hwndChild, WM_COMMAND, wparam, lparam);
  441.       return FALSE;
  442.    }
  443.  
  444.    // Adjust menu state
  445.    AdjustMenus();
  446.    return TRUE;
  447. }
  448.  
  449.  
  450. /* FrameProc ---------------------------------------------------------------
  451.     Description: Frame window procedure
  452.     --------------------------------------------------------------------------*/
  453. LRESULT EXPFUNC FrameProc(HWND    hwnd,
  454.                           UINT   msg,
  455.                           WPARAM wparam,
  456.                           LPARAM lparam)
  457. {
  458.    switch (msg) {
  459.  
  460.       // Create MDI client window
  461.      case WM_CREATE: {
  462.         CLIENTCREATESTRUCT  client;
  463.  
  464.         client.hWindowMenu  = g_hmenuInitWindow;
  465.         client.idFirstChild = IDM_FIRSTCHILD;
  466.  
  467.         g_hwndClient = CreateWindow(szMDICLIENT, NULL,
  468.                                     WS_CHILD        |
  469.                                     WS_CLIPCHILDREN |
  470.                                     WS_VISIBLE,
  471.                                     0, 0, 0, 0, hwnd, (HMENU)1, g_hinst,
  472.                                     &client);
  473.         break;
  474.      }
  475.  
  476.       // Refresh brushes when colors change
  477.      case WM_SYSCOLORCHANGE:
  478.       if (g_hbrWin)    DeleteObject(g_hbrWin);
  479.       if (g_hbrBtn)    DeleteObject(g_hbrBtn);
  480.       if (g_hbrScroll) DeleteObject(g_hbrScroll);
  481.  
  482.       g_hbrWin    = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  483.       g_hbrBtn    = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  484.       g_hbrScroll = CreateSolidBrush(GetSysColor(COLOR_SCROLLBAR));
  485.       break;
  486.  
  487.       // Close all children, drop connection, and close frame window
  488.      case WM_CLOSE:
  489.       CloseAll(hwnd);
  490.       DoDisconnect();
  491.       DestroyWindow(hwnd);
  492.       break;
  493.  
  494.       // Destroy menus not attached to the window and drop ODBC handles
  495.      case WM_DESTROY: {
  496.         HMENU   hmenu;
  497.  
  498.         hmenu = GetMenu(hwnd);
  499.  
  500.         if (g_hmenuInit  != hmenu) DestroyMenu(g_hmenuInit);
  501.         if (g_hmenuFrame != hmenu) DestroyMenu(g_hmenuFrame);
  502.         if (g_hmenuChild != hmenu) DestroyMenu(g_hmenuChild);
  503.  
  504.         if (g_hdbc)
  505.            SQLFreeHandle(SQL_HANDLE_DBC,g_hdbc);
  506.  
  507.         if (g_henv)
  508.            SQLFreeHandle(SQL_HANDLE_ENV,g_henv);
  509.  
  510.         g_hwnd = NULL;
  511.  
  512.         WinHelp(hwnd, szHELPFILE, HELP_QUIT, 0L);
  513.         PostQuitMessage(0);
  514.         break;
  515.      }
  516.  
  517.       // Pass menu commands to handler routine
  518.      case WM_COMMAND:
  519.       if (DoFrameMenu(hwnd, wparam, lparam))
  520.          break;
  521.  
  522.       // All other requests go to default MDI frame procedure
  523.      default:
  524.       return DefFrameProc(hwnd, g_hwndClient, msg, wparam, lparam);
  525.    }
  526.  
  527.    return (LRESULT)NULL;
  528. }
  529.