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.h < prev    next >
C/C++ Source or Header  |  1998-04-03  |  9KB  |  302 lines

  1. // ComplexCtl.h : Declaration of the 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. #ifndef __COMPLEXCTL_H_
  14. #define __COMPLEXCTL_H_
  15.  
  16. #include "resource.h"       // main symbols
  17.  
  18. // Used to get the data when using CManualAccessor
  19. struct mydata
  20. {
  21.     BYTE    bookmark[4];
  22.     BSTR    bstrData;
  23. };
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CComplexCtl
  27. class ATL_NO_VTABLE CComplexCtl :
  28.     public CComObjectRootEx<CComSingleThreadModel>,
  29.     public CComCoClass<CComplexCtl, &CLSID_ComplexCtl>,
  30.     public CComControl<CComplexCtl>,
  31.     public IDispatchImpl<IComplexCtl, &IID_IComplexCtl, &LIBID_COMPLEXDBLib>,
  32.     public IProvideClassInfo2Impl<&CLSID_ComplexCtl, NULL, &LIBID_COMPLEXDBLib>,
  33.     public IPersistStreamInitImpl<CComplexCtl>,
  34.     public IPersistStorageImpl<CComplexCtl>,
  35.     public IPersistPropertyBagImpl<CComplexCtl>,
  36.     public IQuickActivateImpl<CComplexCtl>,
  37.     public IOleControlImpl<CComplexCtl>,
  38.     public IOleObjectImpl<CComplexCtl>,
  39.     public IOleInPlaceActiveObjectImpl<CComplexCtl>,
  40.     public IViewObjectExImpl<CComplexCtl>,
  41.     public IOleInPlaceObjectWindowlessImpl<CComplexCtl>,
  42.     public IDataObjectImpl<CComplexCtl>,
  43.     public ISpecifyPropertyPagesImpl<CComplexCtl>,
  44.     public IPerPropertyBrowsingImpl<CComplexCtl>,
  45.     public IRowPositionChange,
  46.     public CAccessorRowset<CManualAccessor>
  47. {
  48. public:
  49.     CContainedWindow m_ctlListBox;
  50.  
  51.  
  52.     CComplexCtl() :
  53.         m_ctlListBox(_T("ListBox"), this, 1)
  54.     {
  55.  
  56.         m_bWindowOnly    = TRUE;
  57.         m_dwCookie       = 0;
  58.         m_bHaveBookmarks = false;
  59.         m_pColumnInfo    = NULL;
  60.         m_pStrings       = NULL;
  61.         m_nColumns       = 0;
  62.     }
  63.     ~CComplexCtl()
  64.     {
  65.         CoTaskMemFree(m_pColumnInfo);
  66.         CoTaskMemFree(m_pStrings);
  67.         FreeBookmarkMemory();
  68.     }
  69.  
  70. DECLARE_REGISTRY_RESOURCEID(IDR_COMPLEXCTL)
  71.  
  72. BEGIN_COM_MAP(CComplexCtl)
  73.     COM_INTERFACE_ENTRY(IComplexCtl)
  74.     COM_INTERFACE_ENTRY(IDispatch)
  75.     COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
  76.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
  77.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
  78.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)
  79.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)
  80.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
  81.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
  82.     COM_INTERFACE_ENTRY_IMPL(IOleControl)
  83.     COM_INTERFACE_ENTRY_IMPL(IOleObject)
  84.     COM_INTERFACE_ENTRY_IMPL(IQuickActivate)
  85.     COM_INTERFACE_ENTRY_IMPL(IPersistStorage)
  86.     COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)
  87.     COM_INTERFACE_ENTRY_IMPL(ISpecifyPropertyPages)
  88.     COM_INTERFACE_ENTRY_IMPL(IDataObject)
  89.     COM_INTERFACE_ENTRY(IProvideClassInfo)
  90.     COM_INTERFACE_ENTRY(IProvideClassInfo2)
  91.     COM_INTERFACE_ENTRY(IPerPropertyBrowsing)
  92.     COM_INTERFACE_ENTRY(IPersistPropertyBag)
  93.     COM_INTERFACE_ENTRY(IRowPositionChange)
  94. END_COM_MAP()
  95.  
  96. BEGIN_PROPERTY_MAP(CComplexCtl)
  97.     // Example entries
  98.     PROP_ENTRY("DataMember", 2, CLSID_NULL)
  99.     PROP_ENTRY("FieldName", 3, CLSID_NULL)
  100.     PROP_PAGE(CLSID_StockColorPage)
  101. END_PROPERTY_MAP()
  102.  
  103.  
  104. BEGIN_MSG_MAP(CComplexCtl)
  105.     MESSAGE_HANDLER(WM_PAINT, OnPaint)
  106.     MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
  107.     MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
  108.     MESSAGE_HANDLER(WM_CREATE, OnCreate)
  109. ALT_MSG_MAP(1)
  110.     // Replace this with message map entries for subclassed ListBox
  111. END_MSG_MAP()
  112.  
  113.     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  114.     {
  115.         RECT rc;
  116.         GetWindowRect(&rc);
  117.         rc.right -= rc.left;
  118.         rc.bottom -= rc.top;
  119.         rc.top = rc.left = 0;
  120.         m_ctlListBox.Create(m_hWnd, rc, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VSCROLL);
  121.         return 0;
  122.     }
  123.     STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
  124.     {
  125.         IOleInPlaceObjectWindowlessImpl<CComplexCtl>::SetObjectRects(prcPos, prcClip);
  126.         int cx, cy;
  127.         cx = prcPos->right - prcPos->left;
  128.         cy = prcPos->bottom - prcPos->top;
  129.         ::SetWindowPos(m_ctlListBox.m_hWnd, NULL, 0,
  130.             0, cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
  131.         return S_OK;
  132.     }
  133.  
  134. // IViewObjectEx
  135.     STDMETHOD(GetViewStatus)(DWORD* pdwStatus)
  136.     {
  137.         ATLTRACE(_T("IViewObjectExImpl::GetViewStatus\n"));
  138.         *pdwStatus = VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE;
  139.         return S_OK;
  140.     }
  141.  
  142. // IRowPositionChange
  143.     STDMETHOD(OnRowPositionChange)(DBREASON eReason, DBEVENTPHASE ePhase, BOOL bCantDeny)
  144.     {
  145.         if (ePhase == DBEVENTPHASE_DIDEVENT)
  146.         {
  147.             DBPOSITIONFLAGS dwPositionFlags;
  148.             HRESULT hr;
  149.             HCHAPTER hChapter = DB_NULL_HCHAPTER;
  150.  
  151.             hr = m_spRowPosition->GetRowPosition(&hChapter, &m_hRow, &dwPositionFlags);
  152.             if (FAILED(hr) || m_hRow == DB_NULL_HROW)
  153.                 return S_OK;
  154.  
  155.             hr = CRowset::GetData();
  156.             if (FAILED(hr))
  157.                 return S_OK;
  158.  
  159.             // Now we need to find a match based upon the bookmark;
  160.             int i, nRows = m_apBookmark.GetSize();
  161.             for (i = 0; i < nRows; i++)
  162.             {
  163.                 if (memcmp(m_apBookmark[i], &m_data.bookmark, m_pColumnInfo->ulColumnSize) == 0)
  164.                 {
  165.                     m_ctlListBox.SendMessage(LB_SETCURSEL, i, 0);
  166.                     break;
  167.                 }
  168.             }
  169.             FreeRecordMemory();
  170.             ReleaseRows();
  171.         }
  172.         return S_OK;
  173.     }
  174.  
  175. // IPerPropertyBrowsing
  176.     STDMETHOD(GetPredefinedStrings)(DISPID dispID, CALPOLESTR *pCaStringsOut, CADWORD *pCaCookiesOut)
  177.     {
  178.         ATLTRACE("CComplexCtl::GetPredefinedStrings\n");
  179.         if (pCaStringsOut == NULL || pCaCookiesOut == NULL)
  180.             return E_POINTER;
  181.  
  182.         // Only have our custom processing if it is the FieldName property and we
  183.         // have retrieved some columns
  184.         if (dispID != 3 || m_nColumns == 0)
  185.             return IPerPropertyBrowsingImpl<CComplexCtl>::GetPredefinedStrings(dispID, pCaStringsOut, pCaCookiesOut);
  186.  
  187.         LPOLESTR*   ppStr;
  188.         LPOLESTR    pName;
  189.         ULONG       nLength;
  190.         DWORD*      pCookie;
  191.         ULONG       nColumns = m_nColumns;
  192.         ULONG       nStart;
  193.  
  194.         // We don't bind to the bookmark column
  195.         if (m_bHaveBookmarks)
  196.         {
  197.             nStart = 1;
  198.             nColumns--;
  199.         }
  200.         else
  201.             nStart = 0;
  202.  
  203.         pCaStringsOut->cElems = nColumns;
  204.         pCaCookiesOut->cElems = nColumns;
  205.  
  206.         pCaStringsOut->pElems = (LPOLESTR*)CoTaskMemAlloc(sizeof(LPOLESTR) * nColumns);
  207.         if (pCaStringsOut->pElems == NULL)
  208.             return E_OUTOFMEMORY;
  209.  
  210.         pCaCookiesOut->pElems = (DWORD*)CoTaskMemAlloc(sizeof(DWORD) * nColumns);
  211.         if (pCaCookiesOut->pElems == NULL)
  212.         {
  213.             CoTaskMemFree(pCaStringsOut->pElems);
  214.             return E_OUTOFMEMORY;
  215.         }
  216.  
  217.         ppStr = pCaStringsOut->pElems;
  218.         pCookie = pCaCookiesOut->pElems;
  219.         for (ULONG i = nStart; i < m_nColumns; i++)
  220.         {
  221.             pName = m_pColumnInfo[i].pwszName;
  222.             nLength = ocslen(pName) + 1;    // Remember the NULL
  223.  
  224.             *ppStr = (LPOLESTR)CoTaskMemAlloc(sizeof(OLECHAR) * nLength);
  225.             if (*ppStr != NULL)
  226.                 memcpy(*ppStr, pName, sizeof(OLECHAR) * nLength);
  227.  
  228.             *pCookie = i;
  229.  
  230.             ppStr++;
  231.             pCookie++;
  232.         }
  233.         return S_OK;
  234.     }
  235.     STDMETHOD(GetPredefinedValue)(DISPID dispID, DWORD dwCookie, VARIANT* pVarOut)
  236.     {
  237.         if (pVarOut == NULL)
  238.             return E_POINTER;
  239.  
  240.         LPOLESTR pName = m_pColumnInfo[dwCookie].pwszName;
  241.  
  242.         if (dispID == 3 && pName != NULL)
  243.         {
  244.             pVarOut->vt = VT_BSTR;
  245.             pVarOut->bstrVal = ::SysAllocString(pName);
  246.         }
  247.         else
  248.             pVarOut->vt = VT_EMPTY;
  249.  
  250.         return S_OK;
  251.     }
  252.  
  253. // IOleObject::Close
  254.     STDMETHOD(Close)(DWORD dwSaveOption)
  255.     {
  256.         // Unhook everything before we go away
  257.         if (m_dwCookie != 0)
  258.             AtlUnadvise(m_spRowPosition, IID_IRowPositionChange, m_dwCookie);
  259.  
  260.         m_spDataSource.Release();
  261.         m_spRowPosition.Release();
  262.  
  263.         return IOleObjectImpl<CComplexCtl>::Close(dwSaveOption);
  264.     }
  265.  
  266.     void FreeBookmarkMemory()
  267.     {
  268.         int i, nSize = m_apBookmark.GetSize();
  269.         for (i=0; i<nSize; i++)
  270.         {
  271.             delete [] m_apBookmark[i];
  272.         }
  273.         m_apBookmark.RemoveAll();
  274.     }
  275.  
  276. // IComplexCtl
  277. public:
  278.     HRESULT UpdateControl();
  279.     STDMETHOD(get_FieldName)(/*[out, retval]*/ BSTR *pVal);
  280.     STDMETHOD(put_FieldName)(/*[in]*/ BSTR newVal);
  281.     HRESULT GetRowset();
  282.     STDMETHOD(get_DataMember)(/*[out, retval]*/ DataMember *pVal);
  283.     STDMETHOD(put_DataMember)(/*[in]*/ DataMember newVal);
  284.     STDMETHOD(get_DataSource)(/*[out, retval]*/ DataSource **pDataSource);
  285.     STDMETHOD(putref_DataSource)(/*[in]*/ DataSource* pDataSource);
  286.     HRESULT OnDraw(ATL_DRAWINFO& di);
  287.  
  288.     CSimpleArray<BYTE*>     m_apBookmark;
  289.     CComPtr<IDataSource>    m_spDataSource;
  290.     CComPtr<IRowPosition>   m_spRowPosition;
  291.     CComBSTR                m_strDataMember;
  292.     CComBSTR                m_strFieldName;
  293.     DWORD                   m_dwCookie;
  294.     bool                    m_bHaveBookmarks;
  295.     ULONG                   m_nColumns;
  296.     DBCOLUMNINFO*           m_pColumnInfo;
  297.     LPOLESTR                m_pStrings;
  298.     mydata                  m_data;
  299. };
  300.  
  301. #endif //__COMPLEXCTL_H_
  302.