home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / oleaut / browseh / coclass.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-31  |  5.8 KB  |  203 lines

  1. /*************************************************************************
  2. **
  3. **  This is a part of the Microsoft Source Code Samples.
  4. **
  5. **  Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
  6. **
  7. **  This source code is only intended as a supplement to Microsoft Development
  8. **  Tools and/or WinHelp documentation.  See these sources for detailed
  9. **  information regarding the Microsoft samples programs.
  10. **
  11. **  OLE Automation TypeLibrary Browse Helper Sample
  12. **
  13. **  coclass.cpp
  14. **
  15. **  CCoClass implementation
  16. **
  17. **  Written by Microsoft Product Support Services, Windows Developer Support
  18. **
  19. *************************************************************************/
  20.  
  21. #include <windows.h>
  22. #include <windowsx.h>
  23. #ifdef WIN16   
  24.   #include <ole2.h>
  25.   #include <compobj.h>    
  26.   #include <dispatch.h> 
  27.   #include <variant.h>
  28.   #include <olenls.h>  
  29. #endif 
  30. #include "browseh.h"  
  31.  
  32. /*
  33.  * CCoClass::Create
  34.  *
  35.  * Purpose:
  36.  *  Creates an instance of the CoClass automation object and initializes it.
  37.  *
  38.  * Parameters:       
  39.  *  ptinfo       TypeInfo of coclass.
  40.  *  ppCoClass    Returns CoClass automation object.
  41.  *
  42.  * Return Value:
  43.  *  HRESULT
  44.  *
  45.  */
  46. HRESULT 
  47. CCoClass::Create(LPTYPEINFO ptinfo, CCoClass FAR* FAR* ppCoClass) 
  48. {   
  49.     HRESULT hr;
  50.     CCoClass FAR* pCoClass = NULL;
  51.      
  52.     *ppCoClass = NULL;
  53.     
  54.     // Create object.
  55.     pCoClass = new CCoClass();
  56.     if (pCoClass == NULL)
  57.     {
  58.         hr = E_OUTOFMEMORY; 
  59.         goto error;
  60.     }   
  61.     // Load type information for the object from type library.
  62.     hr = pCoClass->LoadTypeInfo(IID_ICoClass);
  63.     if (FAILED(hr))
  64.         goto error;
  65.     
  66.     // Ask base class (CTypeInfo) to initialize.
  67.     hr = pCoClass->_InitTypeInfo(ptinfo);
  68.     if (FAILED(hr))
  69.         goto error;
  70.     
  71.     ptinfo->AddRef();
  72.     pCoClass->m_ptinfo = ptinfo; 
  73.  
  74. #ifdef _DEBUG  
  75.     lstrcpyn(pCoClass->m_szClassName, TEXT("CoClass"), 100);
  76. #endif 
  77.         
  78.     *ppCoClass = pCoClass;
  79.     return NOERROR;
  80.     
  81. error:                        
  82.     if (pCoClass == NULL) return E_OUTOFMEMORY;
  83.     if (pCoClass->m_ptinfo) pCoClass->m_ptinfo->Release();
  84.          
  85.     // Set to NULL to prevent destructor from attempting to free again  
  86.     pCoClass->m_ptinfo = NULL;
  87.     
  88.     delete pCoClass;
  89.     return hr;
  90. }
  91.  
  92. /*
  93.  * CCoClass::CCoClass
  94.  *
  95.  * Purpose:
  96.  *  Constructor for CCoClass object. Initializes members to NULL.
  97.  *
  98.  */
  99. CCoClass::CCoClass()
  100. {
  101.     m_pdispInterfaces = NULL;  
  102.     m_ptinfo = NULL;
  103. }
  104.  
  105. /*
  106.  * CCoClass::~CCoClass
  107.  *
  108.  * Purpose:
  109.  *  Destructor for CCoClass object. 
  110.  *
  111.  */
  112. CCoClass::~CCoClass()
  113. {
  114.     if (m_pdispInterfaces) m_pdispInterfaces->Release(); 
  115.     if (m_ptinfo) m_ptinfo->Release();
  116. }
  117.  
  118. STDMETHODIMP_(REFCLSID)
  119. CCoClass::GetInterfaceID()
  120. {
  121.     return IID_ICoClass;
  122. }
  123.  
  124. STDMETHODIMP_(ICollection FAR*)
  125. CCoClass::get_Interfaces()     
  126. {   
  127.     HRESULT hr;
  128.     CCollection FAR* pCollection = NULL;     
  129.     CInterface FAR* pInterface;
  130.     CCoClass FAR* pCoClass;
  131.     LPDISPATCH pdisp;    
  132.     HREFTYPE hreftype;  
  133.     LPTYPEATTR ptypeattr = NULL;
  134.     LPTYPEINFO ptinfoInterface = NULL;  
  135.     LPTYPELIB ptlib = NULL;
  136.     unsigned int nIndex;    
  137.     unsigned short n;   
  138.     TYPEKIND typekind;    
  139.     
  140.     if (m_pdispInterfaces == NULL)
  141.     {
  142.         hr = m_ptinfo->GetTypeAttr(&ptypeattr);  
  143.         if (FAILED(hr))
  144.             {RaiseException(IDS_Unexpected); return NULL;}   
  145.         hr = CCollection::Create(ptypeattr->cImplTypes, 0, &pCollection); 
  146.         if (FAILED(hr))
  147.             {RaiseException(IDS_Unexpected); goto error;} 
  148.         
  149.         // Enumerate interfaces/dispinterfaces in coclass and return a collection of these.
  150.         for (n=0; n<ptypeattr->cImplTypes; n++)
  151.         {       
  152.             hr = m_ptinfo->GetRefTypeOfImplType(n, &hreftype);  
  153.             if (FAILED(hr))
  154.                 {RaiseException(IDS_Unexpected); goto error;}   
  155.             hr = m_ptinfo->GetRefTypeInfo(hreftype, &ptinfoInterface);   
  156.             if (FAILED(hr))
  157.                 {RaiseException(IDS_Unexpected); goto error;} 
  158.             hr = ptinfoInterface->GetContainingTypeLib(&ptlib, &nIndex); 
  159.             if (FAILED(hr))
  160.                 {RaiseException(IDS_Unexpected); goto error;}        
  161.             hr = ptlib->GetTypeInfoType(nIndex, &typekind);    
  162.             if (FAILED(hr))
  163.                 {RaiseException(IDS_Unexpected); goto error;} 
  164.             ptlib->Release(); 
  165.             ptlib = NULL;
  166.         
  167.             switch (typekind)
  168.             {
  169.                 case TKIND_INTERFACE:
  170.                     hr = CInterface::Create(ptinfoInterface, &pInterface);     
  171.                     if (FAILED(hr))
  172.                         {RaiseException(IDS_Unexpected); goto error;}     
  173.                     pInterface->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
  174.                     break;
  175.              
  176.                 case TKIND_DISPATCH:
  177.                     hr = CCoClass::Create(ptinfoInterface, &pCoClass);
  178.                     if (FAILED(hr))
  179.                         {RaiseException(IDS_Unexpected); goto error;}        
  180.                     pCoClass->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
  181.                     break;
  182.             }
  183.         
  184.             ptinfoInterface->Release();   
  185.             ptinfoInterface = NULL;
  186.             pCollection->Add(pdisp); 
  187.             pdisp->Release(); 
  188.         }
  189.         pCollection->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
  190.         m_pdispInterfaces = pdisp; 
  191.         m_ptinfo->ReleaseTypeAttr(ptypeattr);   
  192.     }
  193.     m_pdispInterfaces->AddRef();
  194.     return (ICollection FAR*)m_pdispInterfaces; 
  195.  
  196. error:    
  197.     if (ptypeattr) m_ptinfo->ReleaseTypeAttr(ptypeattr);   
  198.     if (pCollection) delete pCollection;
  199.     if (ptlib) ptlib->Release();   
  200.     if (ptinfoInterface) ptinfoInterface->Release(); 
  201.     return NULL;
  202. }
  203.