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 / crsrdemo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-20  |  11.7 KB  |  368 lines

  1. /*--------------------------------------------------------------------------
  2.   Crsrdemo.C --- Cursors main file
  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.     CRSRDEMO.C contains the standard functions used in a Windows program
  10.     (such as, WinMain) plus two functions shared between all the files.
  11.     These functions are:
  12.  
  13.       DoMessage       - Issue a message
  14.       EndInstance     - Clean up an instance of this program
  15.       InitApplication - Prepare the first instance of this program
  16.       InitInstance    - Prepare an instance of this program
  17.       ODBCError       - Retrieve and display an ODBC error
  18.       WinMain         - Main Windows entry point
  19.  
  20.     This code is furnished on an as-is basis as part of the ODBC SDK and is
  21.     intended for example purposes only.
  22.  
  23. --------------------------------------------------------------------------*/
  24.  
  25. /* Includes --------------------------------------------------------------*/
  26. #include "headers.h"
  27.  
  28. #pragma warning(disable:4001)
  29. #define  INCL_GLOBAL
  30. #include    "resource.h"
  31. #include "crsrdemo.h"
  32.  
  33.  
  34. // Prototypes --------------------------------------------------------------
  35. void INTFUNC EndInstance(void);
  36. BOOL INTFUNC InitApplication(void);
  37. BOOL INTFUNC InitInstance(int);
  38. int  INTFUNC WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
  39.  
  40.  
  41. /* DoMessage ---------------------------------------------------------------
  42.    Description: Issue a message
  43.    --------------------------------------------------------------------------*/
  44. void INTFUNC DoMessage(HWND hwnd, UINT id)
  45. {
  46.    char  sz[cbSTRLEN];
  47.  
  48.    LoadString(g_hinst, id, sz, sizeof(sz));
  49.    MessageBox(hwnd, sz, g_szTITLE, MB_ICONINFORMATION | MB_OK);
  50.    return;
  51. }
  52.  
  53.  
  54. /* EndInstance -------------------------------------------------------------
  55.    Description: Free instance related data
  56.    --------------------------------------------------------------------------*/
  57. void INTFUNC EndInstance(void)
  58. {
  59.    if (g_hfontName)  DeleteObject(g_hfontName);
  60.    if (g_hfontData)  DeleteObject(g_hfontData);
  61.  
  62.    if (g_hbrWin)     DeleteObject(g_hbrWin);
  63.    if (g_hbrBtn)     DeleteObject(g_hbrBtn);
  64.    if (g_hbrScroll)  DeleteObject(g_hbrScroll);
  65.  
  66.    return;
  67. }
  68.  
  69.  
  70. /* InitApplication ---------------------------------------------------------
  71.    Description: Prepare application by registering window classes
  72.    --------------------------------------------------------------------------*/
  73. BOOL INTFUNC InitApplication(void)
  74. {
  75.    WNDCLASS  wc;
  76.  
  77.    wc.style         = CS_HREDRAW | CS_VREDRAW;
  78.    wc.lpfnWndProc   = FrameProc;
  79.    wc.cbClsExtra    = 0;
  80.    wc.cbWndExtra    = 0;
  81.    wc.hInstance     = g_hinst;
  82.    wc.hIcon         = LoadIcon(g_hinst, MAKEINTRESOURCE(IDR_MAIN));
  83.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  84.    wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
  85.    wc.lpszMenuName  = NULL;
  86.    wc.lpszClassName = szFRAMECLASS;
  87.  
  88.    if (!RegisterClass(&wc))
  89.       return FALSE;
  90.  
  91.    wc.style         = CS_HREDRAW | CS_VREDRAW;
  92.    wc.lpfnWndProc   = ChildProc;
  93.    wc.cbClsExtra    = 0;
  94.    wc.cbWndExtra    = sizeof(LPCHILD);
  95.    wc.hInstance     = g_hinst;
  96.    wc.hIcon         = LoadIcon(g_hinst, MAKEINTRESOURCE(IDR_CHILD));
  97.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  98.    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  99.    wc.lpszMenuName  = NULL;
  100.    wc.lpszClassName = szCHILDCLASS;
  101.  
  102.    if (!RegisterClass(&wc))
  103.       return FALSE;
  104.  
  105.    return TRUE;
  106. }
  107.  
  108.  
  109. /* InitInstance ------------------------------------------------------------
  110.    Description: Prepare instance by initializing global variables and
  111.                 creating main frame window
  112.                 --------------------------------------------------------------------------*/
  113. BOOL INTFUNC InitInstance(int nCmdShow)
  114. {
  115.    RECT     rc;
  116.    HDC         hdc;
  117.    HFONT    hfont;
  118.    TEXTMETRIC  tm;
  119.    char     sz[cbSTRLEN];
  120.    SIZE        size;
  121.  
  122.    // Initialize global variables
  123.    g_hwnd       =
  124.       g_hwndClient = NULL;
  125.  
  126.    g_haccel     = NULL;
  127.  
  128.    g_hmenuInit        =
  129.       g_hmenuInitWindow  =
  130.          g_hmenuFrame       =
  131.             g_hmenuFrameWindow =
  132.                g_hmenuChild       =
  133.                   g_hmenuChildWindow = NULL;
  134.  
  135.    g_hfontName =
  136.       g_hfontData = NULL;
  137.  
  138.    g_hbrWin    =
  139.       g_hbrBtn    =
  140.          g_hbrScroll = NULL;
  141.  
  142.    g_henv = SQL_NULL_HENV;
  143.    g_hdbc = SQL_NULL_HDBC;
  144.  
  145.    g_haccel = LoadAccelerators(g_hinst, MAKEINTRESOURCE(IDR_MAIN));
  146.  
  147.    g_hmenuInit  = LoadMenu(g_hinst, MAKEINTRESOURCE(IDR_INIT));
  148.    g_hmenuFrame = LoadMenu(g_hinst, MAKEINTRESOURCE(IDR_MAIN));
  149.    g_hmenuChild = LoadMenu(g_hinst, MAKEINTRESOURCE(IDR_CHILD));
  150.  
  151.    g_hmenuInitWindow  = GetSubMenu(g_hmenuInit,  IDM_WINDOWINIT);
  152.    g_hmenuFrameWindow = GetSubMenu(g_hmenuFrame, IDM_WINDOWFRAME);
  153.    g_hmenuChildWindow = GetSubMenu(g_hmenuChild, IDM_WINDOWCHILD);
  154.  
  155.    g_cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
  156.    g_cyHScroll = GetSystemMetrics(SM_CYHSCROLL);
  157.  
  158.    LoadString(g_hinst, IDS_TABLE,      g_szTable,      sizeof(g_szTable));
  159.    LoadString(g_hinst, IDR_MAIN,       g_szTITLE,      sizeof(g_szTITLE));
  160.    LoadString(g_hinst, IDS_NOROW,      g_szNoRow,      sizeof(g_szNoRow));
  161.    LoadString(g_hinst, IDS_ROWERROR,   g_szRowError,  sizeof(g_szRowError));
  162.    LoadString(g_hinst, IDS_NULL,       g_szNull,       sizeof(g_szNull));
  163.    LoadString(g_hinst, IDS_ROWDELETED, g_szRowDeleted, sizeof(g_szRowDeleted));
  164.    LoadString(g_hinst, IDS_UNKNOWN,    g_szUnknown,    sizeof(g_szUnknown));
  165.  
  166.    // Create main window in upper 3/4 of desktop
  167.    GetWindowRect(GetDesktopWindow(), &rc);
  168.  
  169.    g_hwnd = CreateWindow(szFRAMECLASS,
  170.                          g_szTITLE,
  171.                          WS_OVERLAPPEDWINDOW,
  172.                          rc.left,
  173.                          rc.top,
  174.                          rc.right - rc.left,
  175.                          ((rc.bottom - rc.top) / 4) * 3,
  176.                          HWND_DESKTOP,
  177.                          g_hmenuInit,
  178.                          g_hinst,
  179.                          NULL);
  180.    if (!g_hwnd)
  181.       return FALSE;
  182.  
  183.    // Create fonts used in painting child windows
  184.    hdc = GetDC(g_hwnd);
  185.  
  186.    g_hfontName = CreateFont((GetDeviceCaps(hdc, LOGPIXELSY) * cPOINTS) / 72,
  187.                             0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0,
  188.                             szFONT);
  189.  
  190.    hfont = SelectObject(hdc, g_hfontName);
  191.  
  192.    GetTextMetrics(hdc, &tm);
  193.    g_cx = tm.tmMaxCharWidth;
  194.    g_cy = tm.tmHeight + tm.tmInternalLeading;
  195.  
  196.    g_hfontData = CreateFont((GetDeviceCaps(hdc, LOGPIXELSY) * cPOINTS) / 72,
  197.                             0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 0, 0, 0, 0,
  198.                             szFONT);
  199.  
  200.    SelectObject(hdc, g_hfontData);
  201.  
  202.    // Determine font size characteristics
  203.    GetTextMetrics(hdc, &tm);
  204.    g_cx = max(g_cx, tm.tmMaxCharWidth);
  205.    g_cy = max(g_cy, tm.tmHeight + tm.tmInternalLeading);
  206.  
  207.    GetTextExtentPoint(hdc, szRECORD, lstrlen(szRECORD), &size);
  208.    g_cxRecord = size.cx;
  209.  
  210.    wsprintf(sz, szRECNUM, 999999);
  211.  
  212.    GetTextExtentPoint(hdc, sz, lstrlen(sz), &size);
  213.    g_cxRecnum = size.cx;
  214.  
  215.    SelectObject(hdc, hfont);
  216.  
  217.    ReleaseDC(g_hwnd, hdc);
  218.  
  219.    // Allocate brushes
  220.    g_hbrWin    = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  221.    g_hbrBtn    = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  222.    g_hbrScroll = CreateSolidBrush(GetSysColor(COLOR_SCROLLBAR));
  223.  
  224.    // Allocate ODBC environment and connection handles; register as a 3.0 app
  225.    if (ENVError(g_hwnd, SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HENV,&g_henv)))
  226.       return FALSE;
  227.    if (ENVError(g_hwnd, SQLSetEnvAttr(g_henv, SQL_ATTR_ODBC_VERSION,
  228.                                       (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER)))
  229.       return FALSE;
  230.    if (ENVError(g_hwnd, SQLAllocHandle(SQL_HANDLE_DBC,g_henv, &g_hdbc)))
  231.       return FALSE;
  232.  
  233.    // Always use the cursor library
  234.    if (DBCError(g_hwnd, SQLSetConnectAttr(   g_hdbc,
  235.                                           SQL_ATTR_ODBC_CURSORS,
  236.                                           (void *)SQL_CUR_USE_ODBC,0))) {
  237.       return FALSE;
  238.    }
  239.  
  240.  
  241.  
  242.  
  243.    // Complete variable initialization
  244.    g_cbName          = 0;
  245.    g_fConnected      = FALSE;
  246.    g_fAsyncSupported = FALSE;
  247.    g_szDSN[0]        = '\0';
  248.    g_cChild          = 0;
  249.    g_cCursor         = 0;
  250.  
  251.    g_mrows      = 1000;
  252.  
  253.    g_hwndClient = GetWindow(g_hwnd, GW_CHILD);
  254.  
  255.    // Set initial menu state
  256.    AdjustMenus();
  257.  
  258.    // Show frame window
  259.    ShowWindow(g_hwnd, nCmdShow);
  260.    UpdateWindow(g_hwnd);
  261.    return TRUE;
  262. }
  263.  
  264.  
  265. /* ODBCError ---------------------------------------------------------------
  266.    Description: Fetch and display an ODBC error message
  267.                 NOTE: SQL_NO_DATA and SQL_STILL_EXECUTING are
  268.                       not considered errors
  269.                       --------------------------------------------------------------------------*/
  270. BOOL INTFUNC ODBCError(HWND hwnd, SWORD fHandleType, SQLHANDLE handle, SQLRETURN rc)
  271. {
  272.    if (rc == SQL_SUCCESS)
  273.       return FALSE;
  274.  
  275.    if (rc == SQL_NO_DATA) {
  276.       DoMessage(hwnd, IDS_NODATAFOUND);
  277.       return FALSE;
  278.    }
  279.  
  280.    if (rc == SQL_STILL_EXECUTING) {
  281.       DoMessage(hwnd, IDS_STILLEXEC);
  282.       return FALSE;
  283.    }
  284.  
  285.    {
  286.       SDWORD   fNative;
  287.       SWORD cbError;
  288.       LPSTR lpszFmt;
  289.       LPSTR lpszSQLState;
  290.       LPSTR lpszError;
  291.       LPSTR lpsz;
  292.       SWORD sMsgNum = 1;
  293.  
  294.       // Allocate storage
  295.       lpsz = AllocPtr(1024 + cbSTRLEN + 6 + SQL_MAX_MESSAGE_LENGTH);
  296.  
  297.       lpszFmt      = lpsz + 1024;
  298.       lpszSQLState = lpszFmt + cbSTRLEN;
  299.       lpszError    = lpszSQLState + 6;
  300.       LoadString(g_hinst, IDS_MSGFMT, lpszFmt, cbSTRLEN);
  301.  
  302.       // sometimes handle comes in as NULL
  303.       if (handle) {
  304.          // Retrieve and display errors until there are no more
  305.          while (SQLGetDiagRec(fHandleType, handle, sMsgNum++,
  306.                               (UCHAR FAR *)lpszSQLState,
  307.                               &fNative,
  308.                               (UCHAR FAR *)lpszError,
  309.                               SQL_MAX_MESSAGE_LENGTH-1,
  310.                               &cbError) != SQL_NO_DATA) {
  311.             if (lstrcmpi(lpszSQLState, szDATATRUNC)) {
  312.                wsprintf(lpsz, lpszFmt, lpszSQLState, fNative, lpszError);
  313.  
  314.                MessageBox(hwnd, lpsz, g_szTITLE,
  315.                           strncmp(lpszSQLState, "01", 2)
  316.                           ? MB_ICONSTOP | MB_OK
  317.                           : MB_ICONINFORMATION | MB_OK);
  318.             }
  319.          }
  320.       }
  321.       else {
  322.          MessageBox(hwnd, "Invalid handle", g_szTITLE,
  323.                     MB_ICONSTOP | MB_OK);
  324.       }
  325.  
  326.       // Free storage
  327.       FreePtr(lpsz);
  328.    }
  329.  
  330.    return (!SUCCESS(rc));
  331. }
  332.  
  333.  
  334. /* WinMain -----------------------------------------------------------------
  335.    Description: Standard WinMain function
  336.    --------------------------------------------------------------------------*/
  337. int INTFUNC WinMain(HINSTANCE   hinstCur,
  338.                     HINSTANCE   hinstPrev,
  339.                     LPSTR       lpszCmdLine,
  340.                     int         nCmdShow)
  341. {
  342.    MSG msg;
  343.  
  344.    UNREF_PARAM(lpszCmdLine);
  345.    g_hinst = hinstCur;
  346.  
  347.    if (!hinstPrev)
  348.       if (!InitApplication())
  349.          return (FALSE);
  350.  
  351.    if (!InitInstance(nCmdShow)) {
  352.       EndInstance();
  353.       return (FALSE);
  354.    }
  355.  
  356.    while (GetMessage(&msg, (HWND)NULL, (UINT)NULL, (UINT)NULL))
  357.       if (!TranslateMDISysAccel(g_hwndClient, &msg) &&
  358.           !TranslateAccelerator(g_hwnd, g_haccel, &msg) &&
  359.           (!(g_hwndChildDialog) || (!IsDialogMessage(g_hwndChildDialog, &msg)))) {
  360.          TranslateMessage(&msg);
  361.          DispatchMessage(&msg);
  362.       }
  363.  
  364.    EndInstance();
  365.  
  366.    return msg.wParam;
  367. }
  368.