home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / inproc / strcoll.cpp < prev    next >
C/C++ Source or Header  |  1998-03-26  |  5KB  |  195 lines

  1. // strcoll.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "inproc.h"
  15. #include "strcoll.h"
  16. #include "enumvar.h"
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char BASED_CODE THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CStringCollect
  25.  
  26. IMPLEMENT_DYNCREATE(CStringCollect, CCmdTarget)
  27.  
  28. CStringCollect::CStringCollect()
  29. {
  30.     EnableAutomation();
  31.  
  32.     // To keep the application running as long as an OLE automation
  33.     //  object is active, the constructor calls AfxOleLockApp.
  34.  
  35.     AfxOleLockApp();
  36. }
  37.  
  38. CStringCollect::~CStringCollect()
  39. {
  40.     // To terminate the application when all objects created with
  41.     //  with OLE automation, the destructor calls AfxOleUnlockApp.
  42.  
  43.     AfxOleUnlockApp();
  44. }
  45.  
  46. void CStringCollect::OnFinalRelease()
  47. {
  48.     // When the last reference for an automation object is released
  49.     //  OnFinalRelease is called.  This implementation deletes the
  50.     //  object.  Add additional cleanup required for your object before
  51.     //  deleting it from memory.
  52.  
  53.     delete this;
  54. }
  55.  
  56. BEGIN_MESSAGE_MAP(CStringCollect, CCmdTarget)
  57.     //{{AFX_MSG_MAP(CStringCollect)
  58.         // NOTE - the ClassWizard will add and remove mapping macros here.
  59.     //}}AFX_MSG_MAP
  60. END_MESSAGE_MAP()
  61.  
  62. // {BA0357C0-C377-11cd-9A90-00DD01113F12}
  63. IMPLEMENT_OLECREATE(CStringCollect, "mfc.inproc.strcoll",
  64.     0xba0357c0, 0xc377, 0x11cd, 0x9a, 0x90, 0x0, 0xdd, 0x1, 0x11, 0x3f, 0x12);
  65.  
  66. BEGIN_DISPATCH_MAP(CStringCollect, CCmdTarget)
  67.     //{{AFX_DISPATCH_MAP(CStringCollect)
  68.     DISP_PROPERTY_EX(CStringCollect, "Count", GetCount, SetNotSupported, VT_I4)
  69.     DISP_FUNCTION(CStringCollect, "Add", Add, VT_I4, VTS_BSTR)
  70.     DISP_FUNCTION(CStringCollect, "Find", Find, VT_I4, VTS_BSTR)
  71.     DISP_FUNCTION(CStringCollect, "Remove", Remove, VT_I4, VTS_VARIANT)
  72.     DISP_FUNCTION(CStringCollect, "RemoveAll", RemoveAll, VT_EMPTY, VTS_NONE)
  73.     DISP_PROPERTY_PARAM(CStringCollect, "Item", GetItem, SetItem, VT_BSTR, VTS_I4)
  74.     //}}AFX_DISPATCH_MAP
  75.     DISP_PROPERTY_EX_ID(CStringCollect, "_NewEnum", DISPID_NEWENUM, GetNewEnum, SetNotSupported, VT_UNKNOWN)
  76.     DISP_DEFVALUE(CStringCollect, "Item")
  77. END_DISPATCH_MAP()
  78.  
  79. // {0F098950-F9F0-11cd-8C3D-00AA004BB3B7}
  80. static const IID IID_IStringCollect = { 0xf098950, 0xf9f0, 0x11cd,
  81.     { 0x8c, 0x3d, 0x0, 0xaa, 0x0, 0x4b, 0xb3, 0xb7 } };
  82.  
  83. // Note: we add support for IID_IStringCollect to support typesafe binding
  84. // from VBA.  This IID must match the GUID that is attached to the
  85. // dispinterface in the .ODL file.
  86.  
  87. BEGIN_INTERFACE_MAP(CStringCollect, CCmdTarget)
  88.     INTERFACE_PART(CStringCollect, IID_IStringCollect, Dispatch)
  89. END_INTERFACE_MAP()
  90.  
  91. /////////////////////////////////////////////////////////////////////////////
  92. // CStringCollect message handlers
  93.  
  94. void CStringCollect::CheckIndex(long nIndex)
  95. {
  96.     if (nIndex <= 0 || nIndex > m_strArray.GetSize())
  97.         AfxThrowOleException(E_INVALIDARG);
  98. }
  99.  
  100. LPUNKNOWN CStringCollect::GetNewEnum()
  101. {
  102.     CEnumVariant* pEnum = new CEnumVariant;
  103.     int nCount = m_strArray.GetSize();
  104.     VARIANT* pContents = new VARIANT[nCount];
  105.     int i;
  106.  
  107.     TRY
  108.     {
  109.         for (i = 0; i < nCount; ++i)
  110.         {
  111.             VariantInit(&pContents[i]);
  112.             pContents[i].bstrVal = m_strArray.ElementAt(i).AllocSysString();
  113.             pContents[i].vt = VT_BSTR;
  114.         }
  115.     }
  116.     CATCH_ALL(e)
  117.     {
  118.         while (--i >= 0)
  119.             VariantClear(&pContents[i]);
  120.  
  121.         THROW_LAST();
  122.     }
  123.     END_CATCH_ALL
  124.     pEnum->SetContents(pContents, nCount);
  125.  
  126.     return pEnum->GetInterface(&IID_IUnknown);
  127. }
  128.  
  129. long CStringCollect::GetCount()
  130. {
  131.     return m_strArray.GetSize();
  132. }
  133.  
  134. BSTR CStringCollect::GetItem(long nIndex)
  135. {
  136.     CheckIndex(nIndex);
  137.     return m_strArray.ElementAt((int)nIndex-1).AllocSysString();
  138. }
  139.  
  140. void CStringCollect::SetItem(long nIndex, LPCTSTR lpszNewValue)
  141. {
  142.     CheckIndex(nIndex);
  143.     m_strArray.ElementAt((int)nIndex-1) = lpszNewValue;
  144. }
  145.  
  146. long CStringCollect::Add(LPCTSTR newValue)
  147. {
  148.     m_strArray.Add(newValue);
  149.     return m_strArray.GetSize();
  150. }
  151.  
  152. long CStringCollect::Find(LPCTSTR findValue)
  153. {
  154.     int nCount = m_strArray.GetSize();
  155.     for (int i = 0; i < nCount; ++i)
  156.     {
  157.         if (m_strArray.ElementAt(i) == findValue)
  158.             return i+1;
  159.     }
  160.     return -1;
  161. }
  162.  
  163. long CStringCollect::Remove(const VARIANT FAR& removeValue)
  164. {
  165.     int nIndex = -1;
  166.  
  167.     VARIANT varTemp;
  168.     VariantInit(&varTemp);
  169.     const VARIANT* pvar = &removeValue;
  170.     if (removeValue.vt != VT_BSTR)
  171.     {
  172.         if (VariantChangeType(&varTemp, (VARIANT*)&removeValue, 0, VT_I4) == NOERROR)
  173.             pvar = &varTemp;
  174.         else if (VariantChangeType(&varTemp, (VARIANT*)&removeValue, 0, VT_BSTR) == NOERROR)
  175.             pvar = &varTemp;
  176.         else
  177.             AfxThrowOleException(DISP_E_TYPEMISMATCH);
  178.     }
  179.     if (pvar->vt == VT_BSTR)
  180.         nIndex = (int)Find(CString(pvar->bstrVal));
  181.     else if (pvar->vt == VT_I4)
  182.         nIndex = (int)pvar->lVal;
  183.     VariantClear(&varTemp);
  184.  
  185.     CheckIndex(nIndex);
  186.  
  187.     m_strArray.RemoveAt(nIndex);
  188.     return m_strArray.GetSize();
  189. }
  190.  
  191. void CStringCollect::RemoveAll()
  192. {
  193.     m_strArray.RemoveAll();
  194. }
  195.