home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Internet Business Development Kit / PRODUCT_CD.iso / sqlsvr / odbcsdk / samples / crsrdemo / frame.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-07  |  13.8 KB  |  534 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.     {
  76.         LPCHILD    lpchild;
  77.  
  78.         lpchild = (LPCHILD)GetWindowLong(hwnd, 0);
  79.  
  80.         idMenu = IDM_FETCH + (fMaximized ? 1 : 0);
  81.  
  82.         if( lpchild->fResultSetExists )
  83.         {
  84.             EnableMenuItem(GetMenu(g_hwnd), idMenu, MF_BYPOSITION |
  85.                                                     MF_ENABLED);
  86.             fOption = fENABLED;
  87.         }
  88.         else
  89.         {
  90.         EnableMenuItem(GetMenu(g_hwnd), idMenu, MF_BYPOSITION |
  91.                                                 MF_DISABLED   |
  92.                                                 MF_GRAYED);
  93.         fOption = fDISABLED;
  94.         }
  95.  
  96.         hmenu = GetSubMenu(GetMenu(g_hwnd), idMenu);
  97.         EnableMenuItem(hmenu, IDM_FETCH_FIRST, fOption);
  98.         EnableMenuItem(hmenu, IDM_FETCH_PRIOR,    fOption);
  99.         EnableMenuItem(hmenu, IDM_FETCH_NEXT,    fOption);
  100.         EnableMenuItem(hmenu, IDM_FETCH_LAST,    fOption);
  101.         EnableMenuItem(hmenu, IDM_FETCH_ABSOLUTE, fOption);
  102.         EnableMenuItem(hmenu, IDM_FETCH_RELATIVE, fOption);
  103. #if    0
  104.         EnableMenuItem(hmenu, IDM_FETCH_RESUME,    fOption);
  105. #endif    //    0
  106.         if( lpchild->dwOperation != OPER_SELECT )
  107.         {
  108.             EnableMenuItem(hmenu, (UINT)IDM_FETCH_DELETEROW, fDISABLED);
  109.             EnableMenuItem(hmenu, (UINT)IDM_FETCH_UPDATEROW, fDISABLED);
  110.         }
  111.         else
  112.         {
  113.             EnableMenuItem(hmenu, (UINT)IDM_FETCH_DELETEROW, fOption);
  114.             EnableMenuItem(hmenu, (UINT)IDM_FETCH_UPDATEROW, fOption);
  115.         }
  116.  
  117.         idMenu = IDM_FETCHCHILD + (fMaximized ? 1 : 0);
  118.         if( g_fConnected )
  119.         {
  120.             EnableMenuItem(GetMenu(g_hwnd), idMenu, MF_BYPOSITION |
  121.                                                     MF_ENABLED);
  122.             fOption = fENABLED;
  123.         }
  124.         else
  125.         {
  126.         EnableMenuItem(GetMenu(g_hwnd), idMenu, MF_BYPOSITION  |
  127.                                                 MF_DISABLED    |
  128.                                                 MF_GRAYED);
  129.         fOption = fDISABLED;
  130.         }
  131.     }
  132.     else
  133.     {
  134.         UINT    wCount;
  135.  
  136.         hmenu = GetMenu(g_hwnd);
  137.         wCount = GetMenuItemCount(hmenu);
  138.         for( idMenu = 0; idMenu < wCount; idMenu++ )
  139.             EnableMenuItem(hmenu, idMenu, MF_BYPOSITION | MF_ENABLED);
  140.     }
  141.  
  142.     DrawMenuBar(g_hwnd);
  143.     return;
  144. }
  145.  
  146.  
  147. /* CloseAll ----------------------------------------------------------------
  148.     Description: Close all child windows
  149. --------------------------------------------------------------------------*/
  150. void INTFUNC CloseAll(HWND hwnd)
  151. {
  152.     UNREF_PARAM(hwnd);
  153.     if (!g_fConnected)
  154.         return;
  155.  
  156.     EnumChildWindows(g_hwndClient, CloseAllEnum, 0L);
  157.     return;
  158. }
  159.  
  160.  
  161. /* CloseAllEnum ------------------------------------------------------------
  162.     Description: EnumChildWindows procedure, it calls CloseChild for each
  163.                  child window passed
  164. --------------------------------------------------------------------------*/
  165. BOOL CALLBACK CloseAllEnum(HWND hwnd, LPARAM lparam)
  166. {
  167.     UNREF_PARAM(lparam);
  168.     if (!GetWindow(hwnd, GW_OWNER))
  169.         CloseChild(hwnd);
  170.     return TRUE;
  171. }
  172.  
  173.  
  174. /* CloseChild --------------------------------------------------------------
  175.     Description: Close a child window
  176. --------------------------------------------------------------------------*/
  177. void INTFUNC CloseChild(HWND hwnd)
  178. {
  179.     // Destroy child window
  180.     FORWARD_WM_MDIDESTROY(g_hwndClient, hwnd, SendMessage);
  181.  
  182.     // Decrement child count
  183.     g_cChild--;
  184.  
  185.     // Set appropriate menu bar
  186.     if (!g_cChild)
  187. #ifdef WIN32
  188.         SendMessage(g_hwndClient,WM_MDISETMENU,(WPARAM)g_hmenuFrame,(LPARAM)g_hmenuFrameWindow);
  189. #else
  190.         FORWARD_WM_MDISETMENU(g_hwndClient,
  191.                     0, g_hmenuFrame, g_hmenuFrameWindow, SendMessage);
  192. #endif
  193.     return;
  194. }
  195.  
  196.  
  197. /* CreateChild -------------------------------------------------------------
  198.     Description: Create a child window
  199. --------------------------------------------------------------------------*/
  200. HWND INTFUNC CreateChild(HWND hwnd)
  201. {
  202.     HWND            hwndChild;
  203.     MDICREATESTRUCT    mdi;
  204.     int                x, y, cx, cy;
  205.  
  206.     // Have child fill client area if it is the only child window
  207.     if (!g_cChild) {
  208.         RECT    rc;
  209.  
  210.         GetClientRect(hwnd, &rc);
  211.  
  212.         x  = rc.left;
  213.         y  = rc.top;
  214.         cx = rc.right - rc.left;
  215.         cy = rc.bottom - rc.top;
  216.     }
  217.  
  218.     // Otherwise, accept default placement
  219.     else {
  220.         x  =
  221.         y  =
  222.         cx =
  223.         cy = CW_USEDEFAULT;
  224.     }
  225.  
  226.     // Increment child count and cursor number
  227.     g_cChild++;
  228.     g_cCursor++;
  229.  
  230.     // Create child via MDI interface
  231.     mdi.szClass = szCHILDCLASS;
  232.     mdi.szTitle = g_szDSN;
  233.     mdi.hOwner  = g_hinst;
  234.     mdi.x       = x;
  235.     mdi.y       = y;
  236.     mdi.cx      = cx;
  237.     mdi.cy      = cy;
  238.     mdi.style   = 0;
  239.     mdi.lParam  = (LPARAM)NULL;
  240.  
  241.     hwndChild = FORWARD_WM_MDICREATE(g_hwndClient, ((LPSTR)&mdi), SendMessage);
  242.  
  243.     if (hwndChild) {
  244.         if (g_cChild == 1)
  245. #ifdef WIN32
  246.             SendMessage(g_hwndClient,WM_MDISETMENU,(WPARAM)g_hmenuChild,(LPARAM)g_hmenuChildWindow);
  247. #else
  248.             FORWARD_WM_MDISETMENU(g_hwndClient,
  249.                         0, g_hmenuChild, g_hmenuChildWindow, SendMessage);
  250. #endif
  251.     }
  252.     else
  253.         g_cChild--;
  254.  
  255.     return hwndChild;
  256. }
  257.  
  258.  
  259. /* DoConnect ---------------------------------------------------------------
  260.     Description: Connect to a data source
  261. --------------------------------------------------------------------------*/
  262. BOOL INTFUNC DoConnect(HWND hwnd)
  263. {
  264.     HCURSOR    hcur;
  265.     char    sz[cbMAXSQL];
  266.     SWORD    cb;
  267.     RETCODE    rc;
  268.  
  269.     // If already connected, close all children and disconnect
  270.     if (g_fConnected) {
  271.         LoadString(g_hinst, IDS_CONWARN, sz, sizeof(sz));
  272.         rc = MessageBox(hwnd,
  273.                         sz, g_szTITLE,
  274.                         MB_ICONQUESTION | MB_OKCANCEL | MB_DEFBUTTON2);
  275.         if (rc == IDCANCEL)
  276.             return FALSE;
  277.         CloseAll(hwnd);
  278.         DoDisconnect();
  279.     }
  280.  
  281.     hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  282.  
  283.     // Call SQLDriverConnect
  284.     rc = SQLDriverConnect(g_hdbc, g_hwnd, NULL, 0,
  285.         (UCHAR FAR *)sz, sizeof(sz), &cb, SQL_DRIVER_COMPLETE);
  286.  
  287.     // If successfully connected, get data source attributes
  288.     if (SUCCESS(rc)) {
  289.         LPSTR    lpszS, lpszD;
  290.         HSTMT    hstmt;
  291.  
  292.         // Mark as connected
  293.         g_fConnected = TRUE;
  294.  
  295.         // Extract and save data source name
  296.         lpszS = _fstrstr(sz, szDSNKEY);
  297.  
  298.         if (lpszS)
  299.         {
  300.             lpszS = _fstrstr(sz, szDSNKEY) + lstrlen(szDSNKEY);
  301.             lpszD = g_szDSN;
  302.             while (*lpszS && *lpszS != ';') *lpszD++ = *lpszS++;
  303.             *lpszD = '\0';
  304.         } else
  305.             LoadString(g_hinst, IDS_NODSN, g_szDSN, sizeof(g_szDSN));
  306.  
  307.         // Change to the appropriate menu bar
  308. #ifdef WIN32
  309.         SendMessage(g_hwndClient,WM_MDISETMENU,(WPARAM)g_hmenuFrame,(LPARAM)g_hmenuFrameWindow);
  310. #else
  311.         FORWARD_WM_MDISETMENU(g_hwndClient,
  312.                     0, g_hmenuFrame, g_hmenuFrameWindow, SendMessage);
  313. #endif
  314.  
  315.         // Get maximum column name length
  316.         if (DBCError(hwnd, SQLGetInfo(g_hdbc, SQL_MAX_COLUMN_NAME_LEN,
  317.                                 &g_cbName, sizeof(g_cbName), NULL)))
  318.             g_cbName = 32;
  319.  
  320.         // Get identifier quote character
  321.         if (DBCError(hwnd, SQLGetInfo(g_hdbc, SQL_IDENTIFIER_QUOTE_CHAR,
  322.                                 g_szQuoteChar, sizeof(g_szQuoteChar), NULL)))
  323.             *g_szQuoteChar = ' ';
  324.  
  325.         // Determine if async support is available
  326.         rc = SQLAllocStmt(g_hdbc, &hstmt);
  327.         if (!SUCCESS(rc))
  328.             g_fAsyncSupported = FALSE;
  329.  
  330.         else {
  331.             g_fAsyncSupported = SUCCESS(SQLSetStmtOption(hstmt,
  332.                                                         SQL_ASYNC_ENABLE, 1));
  333.             SQLFreeStmt(hstmt, SQL_DROP);
  334.         }
  335.     }
  336.     else if (rc != SQL_NO_DATA_FOUND)
  337.         DBCError(hwnd, rc);
  338.  
  339.     SetCursor(hcur);
  340.     return SUCCESS(rc);
  341. }
  342.  
  343.  
  344. /* DoDisconnect ------------------------------------------------------------
  345.     Description: Drop ODBC connection
  346. --------------------------------------------------------------------------*/
  347. void INTFUNC DoDisconnect(void)
  348. {
  349.     // Change to the appropriate menu bar
  350. #ifdef WIN32
  351.     SendMessage(g_hwndClient,WM_MDISETMENU,(WPARAM)g_hmenuInit,(LPARAM)g_hmenuInitWindow);
  352. #else
  353.     FORWARD_WM_MDISETMENU(g_hwndClient,
  354.                 0, g_hmenuInit, g_hmenuInitWindow, SendMessage);
  355. #endif
  356.  
  357.     // If not fully connected, return immediately
  358.     if (!g_fConnected)
  359.         return;
  360.  
  361.     // Disconnect with ODBC
  362.     SQLDisconnect(g_hdbc);
  363.  
  364.     // Reset connection related variables
  365.     g_cbName     = 0;
  366.     g_fConnected = FALSE;
  367.     g_szDSN[0]   = '\0';
  368.     g_cChild     = 0;
  369.     g_cCursor    = 0;
  370.     return;
  371. }
  372.  
  373.  
  374. /* DoFrameMenu -------------------------------------------------------------
  375.     Description: Respond to a request from the frame window menu
  376. --------------------------------------------------------------------------*/
  377. BOOL INTFUNC DoFrameMenu(HWND  hwnd, WPARAM  wparam, LPARAM  lparam)
  378. {
  379.     HWND    hwndChild;
  380.  
  381.     hwndChild = FORWARD_WM_MDIGETACTIVE(g_hwndClient, SendMessage);
  382.  
  383.     switch (GET_WM_COMMAND_ID(wparam, lparam)) {
  384.  
  385.         case IDM_STMT_ADDDSN:
  386.             SQLCreateDataSource(hwnd, NULL);
  387.             break;
  388.  
  389.         case IDM_STMT_DISCONNECT:
  390.             if (g_cChild)
  391.                 CloseAll(hwnd);
  392.             DoDisconnect();
  393.             break;
  394.  
  395.         case IDM_STMT_CONNECT:
  396.             if (!DoConnect(hwnd))
  397.                 break;
  398.  
  399.         case IDM_STMT_NEW:
  400.             hwndChild = CreateChild(hwnd);
  401.             break;
  402.  
  403.         case IDM_STMT_CLOSE:
  404.             CloseChild(hwndChild);
  405.             break;
  406.  
  407.         case IDM_STMT_CLOSEALL:
  408.             CloseAll(hwnd);
  409.             break;
  410.  
  411.         case IDM_STMT_EXIT:
  412.             PostMessage(hwnd, WM_CLOSE, 0, 0L);
  413.             break;
  414.  
  415.         case IDM_WINDOW_ARRANGE:
  416.             FORWARD_WM_MDIICONARRANGE(g_hwndClient, SendMessage);
  417.             break;
  418.  
  419.         case IDM_WINDOW_CASCADE:
  420.             FORWARD_WM_MDICASCADE(g_hwndClient, 0, SendMessage);
  421.             break;
  422.  
  423.         case IDM_WINDOW_TILEH:
  424.         case IDM_WINDOW_TILEV: {
  425.             WPARAM    fTile;
  426.  
  427.             fTile = (GET_WM_COMMAND_ID(wparam, lparam) == IDM_WINDOW_TILEH
  428.                         ? MDITILE_HORIZONTAL
  429.                         : MDITILE_VERTICAL);
  430.             FORWARD_WM_MDITILE(g_hwndClient, fTile, SendMessage);
  431.             break;
  432.         }
  433.  
  434.         case IDM_HELP_ABOUT:
  435.             DoDialog(g_hwnd, IDD_ABOUTBOX, AboutDlgProc);
  436.             break;
  437.  
  438.         case IDM_HELP_HELP:
  439.             WinHelp(g_hwnd, szHELPFILE, HELP_CONTEXT, HLP_CRSRDEMO);
  440.  
  441.         default:
  442.             // Pass unrecognized request to the current child
  443.             SendMessage(hwndChild, WM_COMMAND, wparam, lparam);
  444.             return FALSE;
  445.     }
  446.  
  447.     // Adjust menu state
  448.     AdjustMenus();
  449.     return TRUE;
  450. }
  451.  
  452.  
  453. /* FrameProc ---------------------------------------------------------------
  454.     Description: Frame window procedure
  455. --------------------------------------------------------------------------*/
  456. LRESULT EXPFUNC FrameProc(HWND    hwnd,
  457.                             UINT   msg,
  458.                             WPARAM wparam,
  459.                             LPARAM lparam)
  460. {
  461.     switch (msg) {
  462.  
  463.         // Create MDI client window
  464.         case WM_CREATE: {
  465.             CLIENTCREATESTRUCT    client;
  466.  
  467.             client.hWindowMenu  = g_hmenuInitWindow;
  468.             client.idFirstChild = IDM_FIRSTCHILD;
  469.  
  470.             g_hwndClient = CreateWindow(szMDICLIENT, NULL,
  471.                                         WS_CHILD        |
  472.                                         WS_CLIPCHILDREN |
  473.                                         WS_VISIBLE,
  474.                                         0, 0, 0, 0, hwnd, (HMENU)1, g_hinst,
  475.                                         &client);
  476.             break;
  477.         }
  478.  
  479.         // Refresh brushes when colors change
  480.         case WM_SYSCOLORCHANGE:
  481.             Ctl3dColorChange();
  482.  
  483.             if (g_hbrWin)    DeleteObject(g_hbrWin);
  484.             if (g_hbrBtn)    DeleteObject(g_hbrBtn);
  485.             if (g_hbrScroll) DeleteObject(g_hbrScroll);
  486.  
  487.             g_hbrWin    = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  488.             g_hbrBtn    = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  489.             g_hbrScroll = CreateSolidBrush(GetSysColor(COLOR_SCROLLBAR));
  490.             break;
  491.  
  492.         // Close all children, drop connection, and close frame window
  493.         case WM_CLOSE:
  494.             CloseAll(hwnd);
  495.             DoDisconnect();
  496.             DestroyWindow(hwnd);
  497.             break;
  498.  
  499.         // Destroy menus not attached to the window and drop ODBC handles
  500.         case WM_DESTROY: {
  501.             HMENU    hmenu;
  502.  
  503.             hmenu = GetMenu(hwnd);
  504.  
  505.             if (g_hmenuInit  != hmenu) DestroyMenu(g_hmenuInit);
  506.             if (g_hmenuFrame != hmenu) DestroyMenu(g_hmenuFrame);
  507.             if (g_hmenuChild != hmenu) DestroyMenu(g_hmenuChild);
  508.  
  509.             if (g_hdbc)
  510.                 SQLFreeConnect(g_hdbc);
  511.  
  512.             if (g_henv)
  513.                 SQLFreeEnv(g_henv);
  514.  
  515.             g_hwnd = NULL;
  516.  
  517.             WinHelp(hwnd, szHELPFILE, HELP_QUIT, 0L);
  518.             PostQuitMessage(0);
  519.             break;
  520.         }
  521.  
  522.         // Pass menu commands to handler routine
  523.         case WM_COMMAND:
  524.             if (DoFrameMenu(hwnd, wparam, lparam))
  525.                 break;
  526.  
  527.         // All other requests go to default MDI frame procedure
  528.         default:
  529.             return DefFrameProc(hwnd, g_hwndClient, msg, wparam, lparam);
  530.    }
  531.  
  532.    return (LRESULT)NULL;
  533. }
  534.