TYPE.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  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. **  type.cpp
  14. **
  15. **  CTypeDesc implementation
  16. **
  17. **  Written by Microsoft Product Support Services, Windows Developer Support
  18. **
  19. *************************************************************************/
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #ifdef WIN16   
  23.   #include <ole2.h>
  24.   #include <compobj.h>    
  25.   #include <dispatch.h> 
  26.   #include <variant.h>
  27.   #include <olenls.h>  
  28. #endif 
  29. #include "browseh.h"  
  30. /*
  31.  * CTypeDesc::Create
  32.  *
  33.  * Purpose:
  34.  *  Creates an instance of the TypeDesc automation object and initializes it.
  35.  *
  36.  * ArrayBounds:       
  37.  *  ptinfo        TypeInfo in which the element which this type describes is contained.    
  38.  *  ptypedesc     TYPDESC that describes this type.
  39.  *  ppTypeDesc    Returns TypeDesc automation object.
  40.  *
  41.  * Return Value:
  42.  *  HRESULT
  43.  *
  44.  */
  45. HRESULT 
  46. CTypeDesc::Create(LPTYPEINFO ptinfo, TYPEDESC FAR* ptypedesc, CTypeDesc FAR* FAR* ppTypeDesc) 
  47. {   
  48.     HRESULT hr;
  49.     CTypeDesc FAR* pTypeDesc = NULL; 
  50.     CTypeDesc FAR* pTypeDescPointedAt = NULL;
  51.     CArrayDesc FAR* pArrayDesc = NULL;    
  52.     CTypeInfo FAR* pTypeInfo = NULL;
  53.     LPTYPEINFO ptinfoUserDefined;  
  54.      
  55.     *ppTypeDesc = NULL;
  56.     pTypeDesc = new CTypeDesc();
  57.     if (pTypeDesc == NULL)
  58.     {
  59.         hr = E_OUTOFMEMORY; 
  60.         goto error;
  61.     }   
  62.     // Load type information for the object from type library. 
  63.     hr = pTypeDesc->LoadTypeInfo(IID_ITypeDesc);
  64.     if (FAILED(hr))
  65.         goto error;  
  66.         
  67.     pTypeDesc->m_vartype = ptypedesc->vt;
  68.     if (ptypedesc->vt == VT_USERDEFINED)
  69.     {
  70.         hr = ptinfo->GetRefTypeInfo(ptypedesc->hreftype, &ptinfoUserDefined); 
  71.         if (FAILED(hr))
  72.             goto error;
  73.         hr = CTypeInfo::Create(ptinfoUserDefined, &pTypeInfo);    
  74.         if (FAILED(hr))
  75.             goto error; 
  76.         pTypeInfo->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pTypeDesc->m_pdispUserDefinedDesc);
  77.     }
  78.     else if (ptypedesc->vt == VT_CARRAY)
  79.     { 
  80.         hr = CArrayDesc::Create(ptinfo, ptypedesc->lpadesc, &pArrayDesc);    
  81.         if (FAILED(hr))
  82.             goto error;  
  83.         pArrayDesc->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pTypeDesc->m_pdispArrayDesc);
  84.     }
  85.     else if (ptypedesc->vt == VT_PTR)
  86.     {
  87.         hr = CTypeDesc::Create(ptinfo, ptypedesc->lptdesc, &pTypeDescPointedAt);    
  88.         if (FAILED(hr))
  89.             goto error;  
  90.         pTypeDescPointedAt->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pTypeDesc->m_pdispPointerDesc);                                                                                      
  91.     }
  92. #ifdef _DEBUG  
  93.     lstrcpyn(pTypeDesc->m_szClassName, TEXT("TypeDesc"), 100);
  94. #endif
  95.         
  96.     *ppTypeDesc = pTypeDesc;
  97.     return NOERROR;
  98.     
  99. error:
  100.     if (pTypeDesc == NULL) return E_OUTOFMEMORY;
  101.          
  102.     // Set to NULL to prevent destructor from attempting to free again
  103.     
  104.     delete pTypeDesc;
  105.     return hr;
  106. }
  107. /*
  108.  * CTypeDesc::CTypeDesc
  109.  *
  110.  * Purpose:
  111.  *  Constructor for CTypeDesc object. Initializes members to NULL.
  112.  *
  113.  */
  114. CTypeDesc::CTypeDesc()
  115. {
  116.     m_pdispUserDefinedDesc = NULL;
  117.     m_pdispArrayDesc = NULL;
  118.     m_pdispPointerDesc = NULL;
  119. }
  120. /*
  121.  * CTypeDesc::~CTypeDesc
  122.  *
  123.  * Purpose:
  124.  *  Destructor for CTypeDesc object. 
  125.  *
  126.  */
  127. CTypeDesc::~CTypeDesc()
  128. {
  129.     if (m_pdispUserDefinedDesc) m_pdispUserDefinedDesc->Release();
  130.     if (m_pdispArrayDesc) m_pdispArrayDesc->Release(); 
  131.     if (m_pdispPointerDesc) m_pdispPointerDesc->Release();
  132. }  
  133. STDMETHODIMP_(REFCLSID)
  134. CTypeDesc::GetInterfaceID()
  135. {
  136.     return IID_ITypeDesc;
  137. }
  138. STDMETHODIMP_(short)
  139. CTypeDesc::get_Type()
  140.     return (short)m_vartype;
  141. }
  142. STDMETHODIMP_(ITypeInformation FAR*)
  143. CTypeDesc::get_UserDefinedDesc()
  144. {
  145.     if (NULL == m_pdispUserDefinedDesc)
  146.     {
  147.         RaiseException(IDS_WrongType);    
  148.         return NULL;
  149.     }
  150.     m_pdispUserDefinedDesc->AddRef();
  151.     return (ITypeInformation FAR*)m_pdispUserDefinedDesc;
  152. }
  153. STDMETHODIMP_(IArrayDesc FAR*)
  154. CTypeDesc::get_ArrayDesc()
  155. {
  156.     if (NULL == m_pdispArrayDesc)
  157.     {
  158.         RaiseException(IDS_WrongType);    
  159.         return NULL;
  160.     }
  161.     m_pdispArrayDesc->AddRef();
  162.     return (IArrayDesc FAR*)m_pdispArrayDesc;
  163. }
  164. STDMETHODIMP_(ITypeDesc FAR*)
  165. CTypeDesc::get_PointerDesc()
  166. {  
  167.     if (NULL == m_pdispPointerDesc)
  168.     {
  169.         RaiseException(IDS_WrongType);    
  170.         return NULL;
  171.     }
  172.     m_pdispPointerDesc->AddRef();
  173.     return (ITypeDesc FAR*)m_pdispPointerDesc;
  174. }   
  175. /*
  176.  * CArrayDesc::Create
  177.  *
  178.  * Purpose:
  179.  *  Creates an instance of the ArrayDesc automation object and initializes it. 
  180.  *  An ArrayDesc describes a C-style array.
  181.  *
  182.  * ArrayBounds:       
  183.  *  ptinfo        TypeInfo in which the element which this type describes is contained.    
  184.  *  parraydesc    ARRAYDESC that describes this ArrayDesc object.
  185.  *  ppArrayDesc   Returns ArrayDesc automation object.
  186.  *
  187.  * Return Value:
  188.  *  HRESULT
  189.  *
  190.  */
  191. HRESULT 
  192. CArrayDesc::Create(LPTYPEINFO ptinfo, ARRAYDESC FAR* parraydesc, CArrayDesc FAR* FAR* ppArrayDesc) 
  193. {   
  194.     HRESULT hr;
  195.     CArrayDesc FAR* pArrayDesc = NULL;      
  196.     CTypeDesc FAR* pTypeDesc = NULL;  
  197.     CCollection FAR* pCollection = NULL;  
  198.     CArrayBound FAR* pArrayBound;
  199.     USHORT n;
  200.     LPDISPATCH pdisp;
  201.      
  202.     *ppArrayDesc = NULL;
  203.     
  204.     // Create object.
  205.     pArrayDesc = new CArrayDesc();
  206.     if (pArrayDesc == NULL)
  207.     {
  208.         hr = E_OUTOFMEMORY; 
  209.         goto error;
  210.     }    
  211.     
  212.     // Load type information for the object from type library. 
  213.     hr = pArrayDesc->LoadTypeInfo(IID_IArrayDesc);
  214.     if (FAILED(hr))
  215.         goto error;
  216.         
  217.     hr = CTypeDesc::Create(ptinfo, &parraydesc->tdescElem, &pTypeDesc);
  218.     if (FAILED(hr))
  219.         goto error;
  220.     pTypeDesc->QueryInterface(IID_IDispatch, (LPVOID FAR*)&pArrayDesc->m_pdispTypeDescElement);  
  221.     
  222.     // Create collection of array bounds. One array bound per dimension.
  223.     hr = CCollection::Create(parraydesc->cDims, 0, &pCollection);  
  224.     if (FAILED(hr))
  225.         goto error;  
  226.     for (n=0; n<parraydesc->cDims; n++)
  227.     {
  228.         hr = CArrayBound::Create(parraydesc->rgbounds[n].cElements, parraydesc->rgbounds[n].lLbound, &pArrayBound);
  229.         if (FAILED(hr))
  230.             goto error;
  231.         pArrayBound->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
  232.         pCollection->Add(pdisp);
  233.         pdisp->Release();  
  234.     }
  235.     pCollection->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
  236.     pArrayDesc->m_pdispArrayBounds = pdisp;
  237. #ifdef _DEBUG  
  238.     lstrcpyn(pArrayDesc->m_szClassName, TEXT("ArrayDesc"), 100);
  239. #endif 
  240.         
  241.     *ppArrayDesc = pArrayDesc;
  242.     return NOERROR;
  243.     
  244. error:                        
  245.     if (pArrayDesc == NULL) return E_OUTOFMEMORY;
  246.     // Set to NULL to prevent destructor from attempting to free again
  247.     pArrayDesc->m_pdispTypeDescElement = NULL;
  248.     pArrayDesc->m_pdispArrayBounds = NULL;
  249.     delete pArrayDesc;
  250.     return hr;
  251. }
  252. /*
  253.  * CArrayDesc::CArrayDesc
  254.  *
  255.  * Purpose:
  256.  *  Constructor for CArrayDesc object. Initializes members to NULL.
  257.  *
  258.  */
  259. CArrayDesc::CArrayDesc()
  260. {
  261.     m_pdispTypeDescElement = NULL;
  262.     m_pdispArrayBounds = NULL;
  263. }
  264. /*
  265.  * CArrayDesc::~CArrayDesc
  266.  *
  267.  * Purpose:
  268.  *  Destructor for CArrayDesc object. 
  269.  *
  270.  */
  271. CArrayDesc::~CArrayDesc()
  272. {
  273.      if (m_pdispTypeDescElement) m_pdispTypeDescElement->Release();      
  274.      if (m_pdispArrayBounds) m_pdispArrayBounds->Release();
  275. }
  276. STDMETHODIMP_(REFCLSID)
  277. CArrayDesc::GetInterfaceID()
  278. {
  279.     return IID_IArrayDesc;
  280. }
  281. STDMETHODIMP_(ITypeDesc FAR*)
  282. CArrayDesc::get_ElementType()
  283. {   
  284.     m_pdispTypeDescElement->AddRef();
  285.     return (ITypeDesc FAR*)m_pdispTypeDescElement;
  286. }
  287. STDMETHODIMP_(ICollection FAR*)
  288. CArrayDesc::get_ArrayBounds()
  289. {   
  290.     m_pdispArrayBounds->AddRef();
  291.     return (ICollection FAR*)m_pdispArrayBounds;
  292. }  
  293. /*
  294.  * CArrayBound::Create
  295.  *
  296.  * Purpose:
  297.  *  Creates an instance of the ArrayBound automation object and initializes it.
  298.  *
  299.  * ArrayBounds:       
  300.  *  cElements       Number of elements in Array.
  301.  *  lLBound         Lower bound of array.
  302.  *  ppArrayBound    Returns ArrayBound automation object.
  303.  *
  304.  * Return Value:
  305.  *  HRESULT
  306.  *
  307.  */
  308. HRESULT 
  309. CArrayBound::Create(unsigned long cElements, long lLBound, CArrayBound FAR* FAR* ppArrayBound) 
  310. {   
  311.     HRESULT hr;
  312.     CArrayBound FAR* pArrayBound = NULL;
  313.      
  314.     *ppArrayBound = NULL;
  315.     
  316.     // Create object.
  317.     pArrayBound = new CArrayBound();
  318.     if (pArrayBound == NULL)
  319.     {
  320.         hr = E_OUTOFMEMORY; 
  321.         goto error;
  322.     }    
  323.    // Load type information for the application object from type library. 
  324.     hr = pArrayBound->LoadTypeInfo(IID_IArrayBound);
  325.     if (FAILED(hr))
  326.         goto error; 
  327.     pArrayBound->m_cElements = cElements;   
  328.     pArrayBound->m_lLBound = lLBound;
  329. #ifdef _DEBUG  
  330.     lstrcpyn(pArrayBound->m_szClassName, TEXT("ArrayBound"), 100);
  331. #endif
  332.         
  333.     *ppArrayBound = pArrayBound;
  334.     return NOERROR;
  335.     
  336. error:                        
  337.     if (pArrayBound == NULL) return E_OUTOFMEMORY;
  338.     
  339.     delete pArrayBound;
  340.     return hr;
  341. }
  342. STDMETHODIMP_(REFCLSID)
  343. CArrayBound::GetInterfaceID()
  344. {
  345.     return IID_IArrayBound;
  346. }
  347. STDMETHODIMP_(long)
  348. CArrayBound::get_ElementsCount()
  349. {
  350.     return (long)m_cElements;
  351. }
  352. STDMETHODIMP_(long)
  353. CArrayBound::get_LowerBound()
  354. {
  355.     return m_lLBound;
  356. }