home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_DAO.SDK / DISK4 / DAOSDK.1 / getrdlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-15  |  8.3 KB  |  341 lines

  1. // GetRDlg.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "GetRows.h"
  6. #include "GetRDlg.h"
  7.  
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13.  
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CAboutDlg dialog used for App About
  16.  
  17. class CAboutDlg : public CDialog
  18. {
  19. public:
  20.     CAboutDlg();
  21.  
  22. // Dialog Data
  23.     //{{AFX_DATA(CAboutDlg)
  24.     enum { IDD = IDD_ABOUTBOX };
  25.     //}}AFX_DATA
  26.  
  27.     // ClassWizard generated virtual function overrides
  28.     //{{AFX_VIRTUAL(CAboutDlg)
  29.     protected:
  30.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  31.     //}}AFX_VIRTUAL
  32.  
  33. // Implementation
  34. protected:
  35.     //{{AFX_MSG(CAboutDlg)
  36.     //}}AFX_MSG
  37.     DECLARE_MESSAGE_MAP()
  38. };
  39.  
  40. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  41. {
  42.     //{{AFX_DATA_INIT(CAboutDlg)
  43.     //}}AFX_DATA_INIT
  44. }
  45.  
  46. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  47. {
  48.     CDialog::DoDataExchange(pDX);
  49.     //{{AFX_DATA_MAP(CAboutDlg)
  50.     //}}AFX_DATA_MAP
  51. }
  52.  
  53. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  54.      //{{AFX_MSG_MAP(CAboutDlg)
  55.     //}}AFX_MSG_MAP
  56. END_MESSAGE_MAP()
  57.  
  58. /////////////////////////////////////////////////////////////////////////////
  59. // CGetRowsDlg dialog
  60.  
  61. CGetRowsDlg::CGetRowsDlg(CWnd* pParent /*=NULL*/)
  62.     : CDialog(CGetRowsDlg::IDD, pParent)
  63. {
  64.     //{{AFX_DATA_INIT(CGetRowsDlg)
  65.         // NOTE: the ClassWizard will add member initialization here
  66.     //}}AFX_DATA_INIT
  67.     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  68.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  69. }
  70.  
  71. void CGetRowsDlg::DoDataExchange(CDataExchange* pDX)
  72. {
  73.     CDialog::DoDataExchange(pDX);
  74.     //{{AFX_DATA_MAP(CGetRowsDlg)
  75.         // NOTE: the ClassWizard will add DDX and DDV calls here
  76.     //}}AFX_DATA_MAP
  77. }
  78.  
  79. BEGIN_MESSAGE_MAP(CGetRowsDlg, CDialog)
  80.     //{{AFX_MSG_MAP(CGetRowsDlg)
  81.     ON_WM_SYSCOMMAND()
  82.     ON_WM_PAINT()
  83.     ON_WM_QUERYDRAGICON()
  84.     ON_BN_CLICKED(IDD_EXECUTE, OnExecute)
  85.     //}}AFX_MSG_MAP
  86. END_MESSAGE_MAP()
  87.  
  88. /////////////////////////////////////////////////////////////////////////////
  89. // CGetRowsDlg message handlers
  90.  
  91. BOOL CGetRowsDlg::OnInitDialog()
  92. {
  93.     CDialog::OnInitDialog();
  94.  
  95.     // Add "About..." menu item to system menu.
  96.  
  97.     // IDM_ABOUTBOX must be in the system command range.
  98.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  99.     ASSERT(IDM_ABOUTBOX < 0xF000);
  100.  
  101.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  102.     CString strAboutMenu;
  103.     strAboutMenu.LoadString(IDS_ABOUTBOX);
  104.     if (!strAboutMenu.IsEmpty())
  105.     {
  106.         pSysMenu->AppendMenu(MF_SEPARATOR);
  107.         pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  108.     }
  109.  
  110.     // Set the icon for this dialog.  The framework does this automatically
  111.     //  when the application's main window is not a dialog
  112.     SetIcon(m_hIcon, TRUE);            // Set big icon
  113.     SetIcon(m_hIcon, FALSE);        // Set small icon
  114.     
  115.     return TRUE;  // return TRUE  unless you set the focus to a control
  116. }
  117.  
  118. void CGetRowsDlg::OnSysCommand(UINT nID, LPARAM lParam)
  119. {
  120.     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  121.     {
  122.         CAboutDlg dlgAbout;
  123.         dlgAbout.DoModal();
  124.     }
  125.     else
  126.     {
  127.         CDialog::OnSysCommand(nID, lParam);
  128.     }
  129. }
  130.  
  131. // If you add a minimize button to your dialog, you will need the code below
  132. //  to draw the icon.  For MFC applications using the document/view model,
  133. //  this is automatically done for you by the framework.
  134.  
  135. void CGetRowsDlg::OnPaint() 
  136. {
  137.     if (IsIconic())
  138.     {
  139.         CPaintDC dc(this); // device context for painting
  140.  
  141.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  142.  
  143.         // Center icon in client rectangle
  144.         int cxIcon = GetSystemMetrics(SM_CXICON);
  145.         int cyIcon = GetSystemMetrics(SM_CYICON);
  146.         CRect rect;
  147.         GetClientRect(&rect);
  148.         int x = (rect.Width() - cxIcon + 1) / 2;
  149.         int y = (rect.Height() - cyIcon + 1) / 2;
  150.  
  151.         // Draw the icon
  152.         dc.DrawIcon(x, y, m_hIcon);
  153.     }
  154.     else
  155.     {
  156.         CDialog::OnPaint();
  157.     }
  158. }
  159.  
  160. // The system calls this to obtain the cursor to display while the user drags
  161. //  the minimized window.
  162. HCURSOR CGetRowsDlg::OnQueryDragIcon()
  163. {
  164.     return (HCURSOR) m_hIcon;
  165. }
  166.  
  167.  
  168. void CGetRowsDlg::OnExecute() 
  169. {
  170.  
  171.     CFileDialog        cOpenFile(    TRUE, 
  172.                                 _T("MDB"), 
  173.                                 _T("employee.mdb"), 
  174.                                 OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
  175.                                 (_T("Access Files (*.mdb) | *.mdb ||")));
  176.  
  177.  
  178.     //Get the location of database (assume it's the Employee example)
  179.     cOpenFile.DoModal();
  180.  
  181.     try
  182.         {
  183.         // Connect to the Employee database example
  184.         m_cEmpDatabase = m_cDBEngine.OpenDatabase(cOpenFile.m_ofn.lpstrFile);
  185.  
  186.         // Connect the recordset straight to the table.
  187.         m_cEmpRecordSet = m_cEmpDatabase.OpenRecordset(_T("Employees"), dbOpenSnapshot);
  188.  
  189.         // Perform the two GetRows functions
  190.         DoGetRows();
  191.  
  192.         // Reset the recordset
  193.         m_cEmpRecordSet.MoveFirst();
  194.  
  195.         DoGetRowsEx();
  196.  
  197.         }
  198.     catch (CdbException e)
  199.         {
  200.         TCHAR szBuf[256];
  201.  
  202.         wsprintf(szBuf, _T("Error %d : %s\n"), DBERR(e.m_hr), (LPCTSTR) "Couldn't find Employee table.");
  203.         AfxMessageBox(szBuf);
  204.         }
  205. }
  206.  
  207.  
  208. // Perform standard GetRows against the Employee table
  209. void CGetRowsDlg::DoGetRows() 
  210. {
  211.     COleVariant        cRows;
  212.     COleVariant        varField;
  213.     CString            strLBRow;
  214.     TCHAR            szId[16];
  215.     LONG            lNumRecords;
  216.     LONG            lIndex[2];
  217.     HRESULT            hResult;
  218.     CListBox        *pListBox = (CListBox *)GetDlgItem(IDD_GETROWSLIST);
  219.  
  220.     //Perform GetRows on Employee table
  221.     //This GetRows uses VARIANTS
  222.     cRows = m_cEmpRecordSet.GetRows(MAX_EMP_REC); //arbitrarily get MAX_EMP_REC rows
  223.  
  224.     //Find out how many records were actually retrieved
  225.     //(SafeArrays are 1-based)
  226.     SafeArrayGetUBound(cRows.parray, 2, &lNumRecords);
  227.  
  228.     //Clear the listbox
  229.     pListBox->ResetContent();
  230.     
  231.     for (lIndex[1] = 0; lIndex[1] <= lNumRecords; lIndex[1]++)
  232.         {
  233.         strLBRow.Empty();//Clear the string
  234.  
  235.         lIndex[0] = EMP_ID;
  236.             
  237.         //Use OLE safe array function to access fields
  238.         hResult = SafeArrayGetElement(cRows.parray, &lIndex[0], &varField);
  239.  
  240.         //Watch out for bum variants
  241.         if(FAILED(hResult))
  242.             break;
  243.  
  244.         if(varField.vt == VT_I4) //Gotta be a long
  245.             {
  246.             wsprintf(szId, _T("%d,  "), varField.iVal);
  247.             }
  248.         else
  249.             {
  250.             lstrcpy(szId, _T("Unexpected Data Type"));
  251.             }
  252.  
  253.         strLBRow += (LPCTSTR)szId;
  254.  
  255.         //Get last name
  256.         lIndex[0] = EMP_LNAME;
  257.         SafeArrayGetElement(cRows.parray, &lIndex[0], &varField);
  258.         strLBRow += (LPCTSTR)varField.bstrVal;
  259.  
  260.         //Get first name
  261.         strLBRow += _T(", ");
  262.         lIndex[0] = EMP_FNAME;
  263.         SafeArrayGetElement(cRows.parray, &lIndex[0], &varField);
  264.         strLBRow += (LPCTSTR)varField.bstrVal;
  265.  
  266.         pListBox->AddString(strLBRow);
  267.         }
  268. }
  269.  
  270.  
  271. // Structure for GetRowsEx
  272. typedef struct
  273.     {
  274.     LONG    lEmpId;
  275.     TCHAR    *strLastName;
  276.     TCHAR    strFirstName[20];
  277.     } EMP, *LPEMP ;
  278.  
  279. // Employee table binding 
  280. DAORSETBINDING    Bindings[] = 
  281. {
  282. //Index Type        Column        Type            Offset                        Size
  283. {dbBindIndexINT,    EMP_ID,        dbBindI4,        offsetof(EMP,lEmpId),        sizeof(LONG)},
  284. {dbBindIndexINT,    EMP_LNAME,    dbBindLPSTRING,    offsetof(EMP,strLastName),    sizeof(TCHAR *)},
  285. {dbBindIndexINT,    EMP_FNAME,    dbBindSTRING,    offsetof(EMP,strFirstName),    sizeof(TCHAR) * 20}
  286. };
  287.  
  288. // Perform C++ GetRowsEx against the Employee table
  289. void CGetRowsDlg::DoGetRowsEx() 
  290. {
  291.     LPEMP            pEmpRows = new EMP[MAX_EMP_REC];
  292.     CListBox        *pListBox = (CListBox *)GetDlgItem(IDD_GETROWSLISTEX);
  293.     CString            strLBRow;
  294.     TCHAR            szId[16];
  295.     LONG            lNumRecords;
  296.     LONG            lCount;
  297.     TCHAR            pBuf[MAX_EMP_REC * 15];        // allow average of 15 chars/name
  298.  
  299.     //Perform GetRows on Employee table
  300.     //This GetRows uses a specific C++ structure
  301.     try
  302.         {
  303.         lNumRecords = m_cEmpRecordSet.GetRowsEx(pEmpRows, sizeof(EMP),
  304.                                     &Bindings[0], sizeof(Bindings) / sizeof(DAORSETBINDING),
  305.                                     pBuf, sizeof(pBuf),
  306.                                     MAX_EMP_REC); //arbitrarily get MAX_EMP_REC rows
  307.         }
  308.     catch (CdbException e)
  309.         {
  310.         //Differentiate between GetRowsEx Errors and other CdbExceptions
  311.         // see defines in DAOGETRW.H
  312.         if(    e.m_hr == E_ROWTOOSHORT ||
  313.             e.m_hr == E_BADBINDINFO ||            
  314.             e.m_hr == E_COLUMNUNAVAILABLE )
  315.             {
  316.             AfxMessageBox(_T("Error in GetRowsEx call."));
  317.             }    
  318.         else
  319.             {
  320.             AfxMessageBox(_T("General CdbException"));
  321.             }
  322.         delete [] pEmpRows;
  323.         return;
  324.         }
  325.  
  326.  
  327.     //Step through the returned rows 
  328.     for (lCount = 0; lCount < lNumRecords; lCount++)
  329.         {
  330.         strLBRow.Empty();
  331.         wsprintf(szId, _T("%d,  "), pEmpRows[lCount].lEmpId);
  332.         strLBRow += szId;
  333.         strLBRow += pEmpRows[lCount].strLastName;
  334.         strLBRow += _T(", ");
  335.         strLBRow += (LPCTSTR) pEmpRows[lCount].strFirstName;
  336.         pListBox->AddString(strLBRow);
  337.         }
  338.  
  339.     delete [] pEmpRows;
  340. }
  341.