home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / vcoledb / consumer / complexdb / complexctl.cpp next >
C/C++ Source or Header  |  1998-04-03  |  5KB  |  187 lines

  1. // ComplexCtl.cpp : Implementation of CComplexCtl
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12.  
  13. #include "stdafx.h"
  14. #include "ComplexDB.h"
  15. #include "ComplexCtl.h"
  16.  
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CComplexCtl
  19.  
  20. HRESULT CComplexCtl::OnDraw(ATL_DRAWINFO& di)
  21. {
  22.     return S_OK;
  23. }
  24.  
  25. STDMETHODIMP CComplexCtl::get_DataSource(DataSource** ppDataSource)
  26. {
  27.     *ppDataSource = m_spDataSource;
  28.  
  29.     return S_OK;
  30. }
  31.  
  32. STDMETHODIMP CComplexCtl::putref_DataSource(DataSource* pDataSource)
  33. {
  34.     m_spDataSource = pDataSource;
  35.     UpdateControl();
  36.  
  37.     return S_OK;
  38. }
  39.  
  40. STDMETHODIMP CComplexCtl::get_DataMember(DataMember * pVal)
  41. {
  42.     *pVal = m_strDataMember.Copy();
  43.  
  44.     return S_OK;
  45. }
  46.  
  47. STDMETHODIMP CComplexCtl::put_DataMember(DataMember newVal)
  48. {
  49.     m_strDataMember = newVal;
  50.     UpdateControl();
  51.  
  52.     return S_OK;
  53. }
  54.  
  55. STDMETHODIMP CComplexCtl::get_FieldName(BSTR * pVal)
  56. {
  57.     *pVal = m_strFieldName.Copy();
  58.  
  59.     return S_OK;
  60. }
  61.  
  62. STDMETHODIMP CComplexCtl::put_FieldName(BSTR newVal)
  63. {
  64.     m_strFieldName = newVal;
  65.  
  66.     if (newVal != NULL)
  67.         UpdateControl();
  68.  
  69.     return S_OK;
  70. }
  71.  
  72. HRESULT CComplexCtl::GetRowset()
  73. {
  74.     ATLASSERT(m_spDataSource != NULL);
  75.     HRESULT hr;
  76.  
  77.     // Close anything we had open and unadvise if necessary
  78.     if (m_dwCookie != 0)
  79.         AtlUnadvise(m_spRowPosition, IID_IRowPositionChange, m_dwCookie);
  80.     CAccessorRowset<CManualAccessor>::Close();
  81.     m_spRowPosition.Release();
  82.  
  83.     hr = m_spDataSource->getDataMember(m_strDataMember, IID_IRowPosition,
  84.         (IUnknown**)&m_spRowPosition);
  85.     if (FAILED(hr))
  86.         return hr;
  87.  
  88.     return m_spRowPosition->GetRowset(IID_IRowset, (IUnknown**)&m_spRowset);
  89. }
  90.  
  91. HRESULT CComplexCtl::UpdateControl()
  92. {
  93.     USES_CONVERSION;
  94.     CBookmark<> bookmark;
  95.     HRESULT     hr;
  96.     BOOL        bUserMode;
  97.     BYTE*       pBookmarkCopy;
  98.     ULONG       nBookmarkSize;
  99.     ULONG       nColumn, nEntries, nLength;
  100.  
  101.     // We can't do anything if the datasource hasn't been set
  102.     if (m_spDataSource == NULL)
  103.         return S_OK;
  104.  
  105.     m_nColumns = 0; // Reset the column count
  106.     // Get the rowset from the data control
  107.     hr = GetRowset();
  108.     if (FAILED(hr))
  109.         return hr;
  110.  
  111.     // Get the column information so we know the column names etc.
  112.     hr = CAccessorRowset<CManualAccessor>::GetColumnInfo(&m_nColumns, &m_pColumnInfo, &m_pStrings);
  113.  
  114.     // If the field name hasn't been set then there is no data to retrieve
  115.     if (m_strFieldName.m_str == NULL)
  116.         return S_OK;
  117.  
  118.     // Check if we have bookmarks we can store
  119.     if (m_pColumnInfo->iOrdinal == 0)
  120.     {
  121.         m_bHaveBookmarks = true;
  122.         FreeBookmarkMemory();
  123.         nBookmarkSize = m_pColumnInfo->ulColumnSize;
  124.     }
  125.     else
  126.         m_bHaveBookmarks = false;
  127.  
  128.     GetAmbientUserMode(bUserMode);
  129.     if (bUserMode == FALSE)
  130.         return S_OK;    // Don't do anything else at design mode
  131.  
  132.     // Now we can create the accessor and bind the data
  133.     // First of all we need to find the column ordinal from the name
  134.     for (nColumn = 0; nColumn < m_nColumns; nColumn++)
  135.     {
  136.         if (m_pColumnInfo[nColumn].pwszName != NULL)
  137.         {
  138.             nLength = ocslen(m_pColumnInfo[nColumn].pwszName) + 1;
  139.             if (memcmp(m_pColumnInfo[nColumn].pwszName, m_strFieldName.m_str, nLength * sizeof(OLECHAR)) == 0)
  140.                 break;
  141.         }
  142.     }
  143.  
  144.     // If we didn't find a match then return
  145.     if (nColumn == m_nColumns)
  146.         return S_OK;
  147.  
  148.     if (m_bHaveBookmarks)
  149.         nEntries = 2;
  150.     else
  151.         nEntries = 1;
  152.     CreateAccessor(nEntries, &m_data, sizeof(m_data));
  153.     if (m_bHaveBookmarks)
  154.         AddBindEntry(0, DBTYPE_BYTES, sizeof(m_data.bookmark), &m_data.bookmark);
  155.  
  156.     AddBindEntry(nColumn, DBTYPE_BSTR, sizeof(BSTR), &m_data.bstrData);
  157.     hr = Bind();
  158.     if (FAILED(hr))
  159.         return hr;
  160.  
  161.     // Loop around and store each record in our list control
  162.     m_ctlListBox.SendMessage(LB_RESETCONTENT, 0, 0);
  163.     hr = MoveFirst();
  164.     while (hr == S_OK)
  165.     {
  166.         if (m_bHaveBookmarks)
  167.         {
  168.             pBookmarkCopy = new BYTE[nBookmarkSize];
  169.             if (pBookmarkCopy != NULL)
  170.                 memcpy(pBookmarkCopy, &m_data.bookmark, nBookmarkSize);
  171.  
  172.             m_apBookmark.Add(pBookmarkCopy);
  173.         }
  174.         m_ctlListBox.SendMessage(LB_ADDSTRING, 0, (LPARAM)OLE2T(m_data.bstrData));
  175.  
  176.         FreeRecordMemory();
  177.         hr = MoveNext();
  178.     }
  179.     // Set the cursor to the beginning
  180.     m_ctlListBox.SendMessage(LB_SETCURSEL, 0, 0);
  181.  
  182.     // Set up the sink so we know when the rowset is repositioned
  183.     AtlAdvise(m_spRowPosition, GetUnknown(), IID_IRowPositionChange, &m_dwCookie);
  184.  
  185.     return S_OK;
  186. }
  187.