home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / ado / read / adorddlg.cpp next >
Encoding:
C/C++ Source or Header  |  1997-11-13  |  14.4 KB  |  572 lines

  1. //--------------------------------------------------------------------
  2. // Microsoft ADO Samples
  3. //
  4. // (c) 1996 Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // @doc ADORead Sample
  7. //
  8. // @module    ADOrddlg.cpp
  9. //
  10. // @devnote None
  11. //--------------------------------------------------------------------
  12.  
  13. // ADOReadDlg.cpp : implementation file
  14. //
  15. #define INITGUID
  16. #include "stdafx.h"
  17. #include "ADORead.h"
  18. #include "ADORdDlg.h"
  19.  
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24.  
  25. const LPCTSTR x_lpcszSource = _T("OLE_DB_NWind_Jet;");
  26. const LPCTSTR x_lpcszUser = _T("Admin");
  27.  
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CAboutDlg dialog used for App About
  30.  
  31. class CAboutDlg : public CDialog
  32. {
  33. public:
  34.     CAboutDlg();
  35.  
  36. // Dialog Data
  37.     //{{AFX_DATA(CAboutDlg)
  38.     enum { IDD = IDD_ABOUTBOX };
  39.     //}}AFX_DATA
  40.  
  41. // Implementation
  42. protected:
  43.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  44.     //{{AFX_MSG(CAboutDlg)
  45.     //}}AFX_MSG
  46.     DECLARE_MESSAGE_MAP()
  47. };
  48.  
  49. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  50. {
  51.     //{{AFX_DATA_INIT(CAboutDlg)
  52.     //}}AFX_DATA_INIT
  53. }
  54.  
  55. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  56. {
  57.     CDialog::DoDataExchange(pDX);
  58.     //{{AFX_DATA_MAP(CAboutDlg)
  59.     //}}AFX_DATA_MAP
  60. }
  61.  
  62. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  63.     //{{AFX_MSG_MAP(CAboutDlg)
  64.         // No message handlers
  65.     //}}AFX_MSG_MAP
  66. END_MESSAGE_MAP()
  67.  
  68. /////////////////////////////////////////////////////////////////////////////
  69. // CADOReadDlg dialog
  70.  
  71. CADOReadDlg::CADOReadDlg(CWnd* pParent /*=NULL*/)
  72.     : CDialog(CADOReadDlg::IDD, pParent)
  73. {
  74.     //{{AFX_DATA_INIT(CADOReadDlg)
  75.     m_lCacheSize = 100;
  76.     m_strTableQuery = _T("SELECT EmployeeId, LastName, FirstName FROM Employees");
  77.     m_lNumRows = 10;
  78.     m_bDynamic = TRUE;
  79.     m_bKeyset = TRUE;
  80.     m_bStatic = TRUE;
  81.     m_bForwardOnly = TRUE;
  82.     m_strSource = x_lpcszSource; //.. D:\\samples\\Employee.mdb
  83.     m_strProvider = _T("msdasql");
  84.     m_strUser = x_lpcszUser;
  85.     m_lConnectMode  = adModeRead;        
  86.     m_lConnectOption  = adPromptAlways;
  87. //    m_bReadOnly = FALSE;
  88.     //}}AFX_DATA_INIT
  89.     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  90.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  91.     m_comboBoxOption.Create(CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP| WS_CHILD | WS_VISIBLE, 
  92.                             CRect(261,7,94,12), this, IDC_ConnectOption);
  93.     m_piConnection = NULL;
  94. }
  95.   
  96. CADOReadDlg::~CADOReadDlg()
  97. {
  98.     if ( m_piConnection != NULL )
  99.         m_piConnection->Release();                     
  100.     m_piConnection = NULL;
  101. }
  102.                  
  103. void CADOReadDlg::DoDataExchange(CDataExchange* pDX)
  104. {
  105.     CDialog::DoDataExchange(pDX);
  106.     //{{AFX_DATA_MAP(CADOReadDlg)
  107.     DDX_Control(pDX, IDC_ConnectMode, m_comboBoxMode);        
  108.     DDX_Control(pDX, IDC_ConnectOption, m_comboBoxOption);
  109.     DDX_Text(pDX, IDC_CACHESIZE, m_lCacheSize);
  110.     DDV_MinMaxLong(pDX, m_lCacheSize, 0, 1200);
  111.     DDX_Text(pDX, IDC_TABLEQUERYEDIT, m_strTableQuery);
  112.     DDX_Text(pDX, IDC_NUMROWS, m_lNumRows);
  113.     DDV_MinMaxLong(pDX, m_lNumRows, 1, 32000);
  114.     DDX_Check(pDX, IDC_Dynamic, m_bDynamic);
  115.     DDX_Check(pDX, IDC_Keyset, m_bKeyset);
  116.     DDX_Check(pDX, IDC_StaticCursor, m_bStatic);
  117.     DDX_Check(pDX, IDC_FORWARDONLY, m_bForwardOnly);
  118.     DDX_Text(pDX, IDC_Source, m_strSource);
  119.     DDV_MaxChars(pDX, m_strSource, 256);
  120.     DDX_Text(pDX, IDC_PROVIDER, m_strProvider);
  121.     DDV_MaxChars(pDX, m_strProvider, 256);
  122.     DDX_Text(pDX, IDC_User, m_strUser);
  123.     DDV_MaxChars(pDX, m_strUser, 256);
  124.     //}}AFX_DATA_MAP
  125.  
  126.     //Do the manual checks
  127.  
  128.     //Check the database name parameter
  129.     if(pDX->m_bSaveAndValidate)
  130.     {
  131.         pDX->PrepareEditCtrl(IDC_Source);
  132.         if (m_strSource.IsEmpty()) 
  133.         {
  134.             MessageBox(_T("Missing Jet database name."), _T("ADO Test App Error"), MB_ICONEXCLAMATION );
  135.             pDX->Fail();
  136.         }
  137.     }
  138.  
  139.  
  140.     //Check the Table/Query parameter
  141.     if(pDX->m_bSaveAndValidate)
  142.     {
  143.         pDX->PrepareEditCtrl(IDC_TABLEQUERYEDIT);
  144.         if (m_strTableQuery.IsEmpty()) 
  145.         {
  146.             MessageBox(_T("Missing table,query or SQL."), _T("ADO Test App Error"), MB_ICONEXCLAMATION );
  147.             pDX->Fail();
  148.         }
  149.     }
  150. }
  151.  
  152. BEGIN_MESSAGE_MAP(CADOReadDlg, CDialog)
  153.     //{{AFX_MSG_MAP(CADOReadDlg)
  154.     ON_WM_SYSCOMMAND()
  155.     ON_WM_PAINT()
  156.     ON_WM_QUERYDRAGICON()
  157.     ON_BN_CLICKED(IDC_DATABASEBUTTON, OnDatabase)
  158.     ON_BN_CLICKED(ID_EXECUTE, OnExecute)
  159.     ON_CBN_SELCHANGE(IDC_ConnectMode, OnSelchangeConnectMode)
  160.     ON_CBN_SELCHANGE(IDC_ConnectOption, OnSelchangeConnectOption)
  161.     //}}AFX_MSG_MAP
  162. END_MESSAGE_MAP()
  163.  
  164. /////////////////////////////////////////////////////////////////////////////
  165. // CADOReadDlg message handlers
  166.  
  167. BOOL CADOReadDlg::OnInitDialog()
  168. {
  169.     CDialog::OnInitDialog();
  170.  
  171.     // Add "About..." menu item to system menu.
  172.  
  173.     // IDM_ABOUTBOX must be in the system command range.
  174.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  175.     ASSERT(IDM_ABOUTBOX < 0xF000);
  176.  
  177.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  178.     CString strAboutMenu;
  179.     strAboutMenu.LoadString(IDS_ABOUTBOX);
  180.     if (!strAboutMenu.IsEmpty())
  181.     {
  182.         pSysMenu->AppendMenu(MF_SEPARATOR);
  183.         pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  184.     }
  185.     
  186.  
  187.     //Set default selections
  188.     SetDlgItemText(IDC_CACHESIZE, _T("100"));
  189.     SetDlgItemText(IDC_NUMROWS, _T("10"));
  190.     
  191.     return TRUE;  // return TRUE  unless you set the focus to a control
  192. }
  193.  
  194. void CADOReadDlg::OnSysCommand(UINT nID, LPARAM lParam)
  195. {
  196.     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  197.     {
  198.         CAboutDlg dlgAbout;
  199.         dlgAbout.DoModal();
  200.     }
  201.     else
  202.     {
  203.         CDialog::OnSysCommand(nID, lParam);
  204.     }
  205. }
  206.  
  207. // If you add a minimize button to your dialog, you will need the code below
  208. //  to draw the icon.  For MFC applications using the document/view model,
  209. //  this is automatically done for you by the framework.
  210.  
  211. void CADOReadDlg::OnPaint() 
  212. {
  213.     if (IsIconic())
  214.     {
  215.         CPaintDC dc(this); // device context for painting
  216.  
  217.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  218.  
  219.         // Center icon in client rectangle
  220.         int cxIcon = GetSystemMetrics(SM_CXICON);
  221.         int cyIcon = GetSystemMetrics(SM_CYICON);
  222.         CRect rect;
  223.         GetClientRect(&rect);
  224.         int x = (rect.Width() - cxIcon + 1) / 2;
  225.         int y = (rect.Height() - cyIcon + 1) / 2;
  226.  
  227.         // Draw the icon
  228.         dc.DrawIcon(x, y, m_hIcon);
  229.     }
  230.     else
  231.     {
  232.         CDialog::OnPaint();
  233.     }
  234. }
  235.  
  236. // The system calls this to obtain the cursor to display while the user drags
  237. //  the minimized window.
  238. HCURSOR CADOReadDlg::OnQueryDragIcon()
  239. {
  240.     return (HCURSOR) m_hIcon;
  241. }
  242.  
  243. void CADOReadDlg::OnDatabase() 
  244. {
  245.     CFileDialog*    pcBrowse;    //Need a file open dialog
  246.  
  247.     pcBrowse = (CFileDialog*)new CFileDialog(TRUE,_T("mdb"),NULL,NULL,_T("Jet Database Files | *.mdb ||"), NULL)    ;
  248.  
  249.     pcBrowse->DoModal();
  250.  
  251.     (GetDlgItem(IDC_Source))->SetWindowText(pcBrowse->GetPathName());
  252.  
  253.     delete pcBrowse;
  254. }
  255.  
  256.  
  257.  
  258. void CADOReadDlg::Execute(    
  259.             CursorTypeEnum    cursorType,
  260.             int                iControlID,
  261.             int                iUnitsID
  262.             ) 
  263. {
  264.     ADORecordset    *piRecordSet;    
  265.     DWORD            dwStart, dwEnd;
  266.     DWORD            dwDuration;
  267.     LONG            lIndex;
  268.     COleVariant        dbVar;
  269.     COleVariant        vNull;
  270.     HRESULT            hr;
  271.     BSTR            bstrTableQuery;
  272.     VARIANT_BOOL    vbEOF;
  273.  
  274.     dwStart = timeGetTime();
  275.  
  276.     //Open recordset 
  277.     hr = CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_INPROC_SERVER, IID_IADORecordset, (LPVOID *)&piRecordSet);
  278.     if (FAILED(hr))        goto ErrorExit;
  279.  
  280.     //Check that recordset was created
  281.     if (piRecordSet != NULL)
  282.     {
  283.         bstrTableQuery = m_strTableQuery.AllocSysString();
  284.         hr = piRecordSet->put_Source(bstrTableQuery);        // convert to bstr 
  285.         if (FAILED(hr))        goto ErrorExit;
  286.  
  287.         hr = piRecordSet->putref_ActiveConnection(m_piConnection);        
  288.         if (FAILED(hr))        goto ErrorExit;
  289.  
  290.         //Set the cache size to value supplied by user.
  291.         hr = piRecordSet->put_CacheSize(m_lCacheSize);
  292.         if (FAILED(hr))        goto ErrorExit;
  293.                         
  294.         vNull.vt = VT_ERROR;
  295.         vNull.scode = DISP_E_PARAMNOTFOUND;
  296.         hr = piRecordSet->Open(vNull, vNull, cursorType, adLockOptimistic, adCmdUnknown);
  297.         if (FAILED(hr))        goto ErrorExit;
  298.  
  299.         //Watch for end of record set
  300.         piRecordSet->get_EOF(&vbEOF);
  301.         if (FAILED(hr))        goto ErrorExit;
  302.  
  303.         for (lIndex = 0L; !vbEOF && lIndex < m_lNumRows; lIndex++)
  304.         {
  305.             //Get the first returned column
  306.             hr = piRecordSet->get_Collect(COleVariant(0L, VT_I4), &dbVar);
  307.             if (FAILED(hr))        goto ErrorExit;
  308.  
  309.             AddFieldToList(lIndex, &dbVar);
  310.             hr = piRecordSet->MoveNext();
  311.             if (FAILED(hr))        goto ErrorExit;
  312.             piRecordSet->get_EOF(&vbEOF);
  313.             if (FAILED(hr))        goto ErrorExit;
  314.             //            dbVar.Clear();    // release memory
  315.         }
  316.  
  317.         //Report the estimated execute time (in milliseconds)
  318.         dwEnd = timeGetTime();
  319.         dwDuration = dwEnd - dwStart;
  320.         DisplayQueryTime(iControlID, iUnitsID, dwDuration);
  321.     }
  322.     else
  323.     {
  324.         (GetDlgItem(IDC_DynamicTIME))->SetWindowText(_T("ERROR"));
  325.     }
  326.     
  327.     piRecordSet->Release();
  328.     SysFreeString(bstrTableQuery);
  329.     return ;
  330.  
  331.  ErrorExit:
  332.     TCHAR szBuf[256];
  333.     wsprintf(szBuf, _T("Error: %d \n"), hr);
  334.     AfxMessageBox(szBuf);
  335.  
  336.     piRecordSet->Release();
  337.     SysFreeString(bstrTableQuery);
  338.     return ;
  339. }        
  340.  
  341.  
  342. //When the Execute button is pressed, run through the selected methods and perform each
  343. //reporting an approximate execution time and listing the first field returned (only if
  344. //it's a string or numeric)
  345.  
  346. void CADOReadDlg::OnExecute() 
  347. {
  348.     CListBox    *pList = ((CListBox *)(GetDlgItem(IDC_ROWSLIST)));
  349.     HRESULT        hr;
  350.     BSTR        bstrSource;
  351.     BSTR        bstrUser;
  352.     BSTR        bstrProvider;
  353.     CString        strSource, strUser,    strPassword, strProvider;
  354.     static BOOLEAN        fIsFirstTime = TRUE;
  355.  
  356.     //Update the parameters
  357.     if (!UpdateData(TRUE))
  358.     {
  359.         return;
  360.     }
  361.  
  362.     // This could take a while, 
  363.     CWaitCursor wait;
  364.  
  365.     //Clear the list
  366.     pList->ResetContent();
  367.  
  368.     // Following is a series of database table retrieves using variations
  369.     // on the Recordset object. This isn't a great programming structure,
  370.     // but it shows each method clearly.
  371.     
  372.     //Execute each the requested read methods, recording a time for each
  373.     //Open the database
  374.     if ( m_piConnection == NULL )
  375.     {
  376.         hr = CoInitialize(NULL);
  377.         if (FAILED(hr))        goto ErrorExit;
  378.         hr = CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_INPROC_SERVER, IID_IADOConnection, (LPVOID *)&m_piConnection);
  379.         if (FAILED(hr))        goto ErrorExit;
  380.     }        
  381.  
  382.     (GetDlgItem(IDC_Source))->GetWindowText(strSource);      
  383.     (GetDlgItem(IDC_User))->GetWindowText(strUser);           
  384.     (GetDlgItem(IDC_Password))->GetWindowText(strPassword);
  385.     (GetDlgItem(IDC_PROVIDER))->GetWindowText(strProvider);
  386.  
  387.     if ( fIsFirstTime || m_strSource != strSource  || m_strUser != strUser    || 
  388.                 m_strPassword != strPassword || m_strProvider != strProvider )
  389.     {
  390.         fIsFirstTime = FALSE;
  391.         m_strSource = strSource ;
  392.         m_strUser = strUser; 
  393.         m_strPassword = strPassword ;
  394.         m_strProvider = strProvider;
  395.  
  396.         bstrSource = m_strSource.AllocSysString();
  397.         bstrUser = m_strUser.AllocSysString();
  398.         bstrProvider = m_strProvider.AllocSysString();
  399.         if ( bstrProvider == NULL || bstrSource == NULL || bstrUser == NULL)    goto ErrorExit;             
  400.  
  401.         if (FAILED(hr = m_piConnection->put_Provider(bstrProvider)))
  402.             goto ErrorExit;
  403.  
  404.         hr = m_piConnection->Open( bstrSource, bstrUser, NULL, -1 );  //toaddpassword
  405.          if (FAILED(hr))        goto ErrorExit;
  406.  
  407.         SysFreeString(bstrProvider);
  408.         SysFreeString(bstrSource);
  409.         SysFreeString(bstrUser);
  410.     }
  411.  
  412.     //Open recordset on as a Dynamic
  413.     if(m_bDynamic)
  414.     {
  415.         pList->AddString(_T("Dynamic Cursor"));
  416.         pList->AddString(_T("=========================="));
  417.         Execute( adOpenDynamic, IDC_DynamicTIME, IDC_UNITDynamic );
  418.     }
  419.     //Open recordset on as a Keyset
  420.     if(m_bKeyset)
  421.     {
  422.         pList->AddString(_T("Keyset Cursor"));
  423.         pList->AddString(_T("=========================="));
  424.         Execute( adOpenKeyset, IDC_KeysetTIME, IDC_UNITDYNA );
  425.     }
  426.     //Open recordset on as a Static
  427.     if(m_bStatic)
  428.     {
  429.         pList->AddString(_T("Static Cursor"));
  430.         pList->AddString(_T("=========================="));
  431.         Execute( adOpenStatic, IDC_StaticTIME, IDC_UNITSNAP );
  432.     }
  433.     //Open recordset on as ForwardOnly
  434.     if(m_bForwardOnly)
  435.     {
  436.         pList->AddString(_T("ForwardOnly Cursor"));
  437.         pList->AddString(_T("=========================="));
  438.         Execute( adOpenForwardOnly, IDC_FORWARDONLYTIME, IDC_UNITFORWARDONLY );
  439.     } 
  440.     
  441.     return ;
  442.  
  443.  ErrorExit:
  444.     TCHAR szBuf[256];
  445.     wsprintf(szBuf, _T("Error: %d \n"), hr);
  446.     AfxMessageBox(szBuf);
  447.  
  448.     SysFreeString(bstrProvider);
  449.     SysFreeString(bstrSource);
  450.     SysFreeString(bstrUser);
  451.     return ;
  452.  
  453. }
  454.  
  455.  
  456. /////////////////////////////////////////////////////////////////////////////
  457. // Other functions
  458.  
  459. void CADOReadDlg::DisplayQueryTime(int iControlID, int iUnitsID, DWORD dwDuration)
  460. {
  461.     CString strDisp;
  462.     CString strUnits(_T("ms"));
  463.     double    fDuration = dwDuration;
  464.     
  465.     //Did it go into minutes?
  466.     if(fDuration >= 60000.0)
  467.     {
  468.         fDuration = fDuration/60000.0;
  469.         strUnits = _T("M");
  470.     }
  471.     //Did it go to seconds?
  472.     else if(fDuration >= 1000.0)
  473.     {
  474.         fDuration = fDuration/1000.0;
  475.         strUnits = _T("S");
  476.     }
  477.  
  478.     strDisp.Format(_T("%.2f"), fDuration);
  479.  
  480.     (GetDlgItem(iUnitsID))->SetWindowText(strUnits);
  481.     (GetDlgItem(iControlID))->SetWindowText(strDisp);
  482.  
  483. }
  484.  
  485. void CADOReadDlg::AddFieldToList(LONG lRecordNum, COleVariant *pdbVar)
  486. {
  487.     CString        strDisp;
  488.     CString        strScratch;
  489.     CListBox    *pList = ((CListBox *)(GetDlgItem(IDC_ROWSLIST)));
  490.  
  491.     //Add record number
  492.     strDisp.Format(_T("%d - "), lRecordNum);
  493.     
  494.     //NOTE: This only works for strings/numerics
  495.     
  496.     switch(pdbVar->vt)
  497.     {
  498.         case VT_BSTR:
  499.         {
  500.             strDisp += (LPCTSTR)pdbVar->bstrVal;
  501.             break;
  502.         }
  503.  
  504.         case VT_I4:
  505.         {
  506.             strScratch.Format(_T("%d"), pdbVar->lVal);
  507.             strDisp += strScratch;
  508.             break;
  509.         }
  510.  
  511.         case VT_UI1:
  512.         {
  513.             strScratch.Format(_T("%u"), pdbVar->bVal);
  514.             strDisp += strScratch;
  515.             break;
  516.         }
  517.  
  518.         case VT_I2:
  519.         {
  520.             strScratch.Format(_T("%d"), pdbVar->iVal);
  521.             strDisp += strScratch;
  522.             break;
  523.         }
  524.  
  525.         case VT_R4:
  526.         {
  527.             strScratch.Format(_T("%f"), pdbVar->fltVal);
  528.             strDisp += strScratch;
  529.             break;
  530.         }
  531.  
  532.         case VT_R8 :
  533.         {
  534.             strScratch.Format(_T("%f"), pdbVar->dblVal);
  535.             strDisp += strScratch;
  536.             break;
  537.         }
  538.  
  539.         default: //
  540.         {
  541.             strDisp += _T("Field type not supported by sample code");
  542.         }
  543.  
  544.     }
  545.     pList->AddString(strDisp);
  546.  
  547. }
  548.  
  549. ConnectPromptEnum rgConnectPrompts[] = {adPromptAlways,
  550.                                         adPromptComplete,
  551.                                         adPromptCompleteRequired,
  552.                                         adPromptNever};
  553.  
  554. void CADOReadDlg::OnSelchangeConnectOption() 
  555. {
  556.     m_lConnectOption = rgConnectPrompts[m_comboBoxOption.GetCurSel()];
  557. }
  558.  
  559. ConnectModeEnum rgConnectModes[] = {adModeRead, 
  560.                                     adModeWrite, 
  561.                                     adModeReadWrite, 
  562.                                     adModeShareDenyRead,
  563.                                     adModeShareDenyWrite,
  564.                                     adModeShareExclusive,
  565.                                     adModeShareDenyNone};
  566.  
  567. void CADOReadDlg::OnSelchangeConnectMode() 
  568. {
  569.  
  570.     m_lConnectMode = rgConnectModes[m_comboBoxMode.GetCurSel()];
  571. }
  572.