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 / function.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-31  |  8.1 KB  |  297 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. **  function.cpp
  14. **
  15. **  CFunction 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.  * CFunction::Create
  34.  *
  35.  * Purpose:
  36.  *  Creates an instance of the Function automation object and initializes it.
  37.  *
  38.  * Parameters:       
  39.  *  ptinfo        TypeInfo of which this Function is an element of.
  40.  *  nIndex          Index of function in containing TypeInfo.
  41.  *  ppFunction    Returns Function automation object.
  42.  *
  43.  * Return Value:
  44.  *  HRESULT
  45.  *
  46.  */
  47. HRESULT 
  48. CFunction::Create(LPTYPEINFO ptinfo, unsigned short nIndex, CFunction FAR* FAR* ppFunction) 
  49. {   
  50.     HRESULT hr;
  51.     CFunction FAR* pFunction = NULL;      
  52.     CTypeDesc FAR* pTypeDesc = NULL;
  53.      
  54.     *ppFunction = NULL;
  55.     
  56.     // Create object.
  57.     pFunction = new CFunction();
  58.     if (pFunction == NULL)
  59.     {
  60.         hr = E_OUTOFMEMORY; 
  61.         goto error;
  62.     }    
  63.     
  64.     // Load type information for the application object from type library. 
  65.     hr = pFunction->LoadTypeInfo(IID_IFunction);
  66.     if (FAILED(hr))
  67.         goto error; 
  68.     
  69.     hr = ptinfo->GetFuncDesc(nIndex, &pFunction->m_pfuncdesc);   
  70.     if (FAILED(hr))
  71.         goto error;
  72.     // Function return type.
  73.     hr = CTypeDesc::Create(ptinfo, &pFunction->m_pfuncdesc->elemdescFunc.tdesc, &pTypeDesc);
  74.     if (FAILED(hr))
  75.         goto error;
  76.     pTypeDesc->QueryInterface(IID_IDispatch, (LPVOID FAR*)&pFunction->m_pdispTypeDesc);
  77.     
  78.     hr = ptinfo->GetDocumentation(pFunction->m_pfuncdesc->memid, &pFunction->m_bstrName, &pFunction->m_bstrDocumentation,
  79.              &pFunction->m_ulHelpContext, &pFunction->m_bstrHelpFile); 
  80.     if (FAILED(hr))
  81.         goto error;   
  82.         
  83.     ptinfo->AddRef();
  84.     pFunction->m_ptinfoFunction = ptinfo;
  85.  
  86. #ifdef _DEBUG  
  87.     lstrcpyn(pFunction->m_szClassName, TEXT("Function"), 100);
  88. #endif 
  89.         
  90.     *ppFunction = pFunction;
  91.     return NOERROR;
  92.     
  93. error:                        
  94.     if (pFunction == NULL) return E_OUTOFMEMORY;
  95.     if (pFunction->m_pfuncdesc) ptinfo->ReleaseFuncDesc(pFunction->m_pfuncdesc);    
  96.     if (pFunction->m_ptinfoFunction) pFunction->m_ptinfoFunction->Release();
  97.     if (pFunction->m_bstrName) SysFreeString(pFunction->m_bstrName);
  98.     if (pFunction->m_bstrDocumentation) SysFreeString(pFunction->m_bstrDocumentation);
  99.     if (pFunction->m_bstrHelpFile) SysFreeString(pFunction->m_bstrHelpFile);
  100.          
  101.     // Set to NULL to prevent destructor from attempting to free again  
  102.     pFunction->m_ptinfoFunction = NULL;
  103.     pFunction->m_pfuncdesc = NULL;
  104.     pFunction->m_bstrName = NULL;
  105.     pFunction->m_bstrDocumentation = NULL;
  106.     pFunction->m_bstrHelpFile = NULL;
  107.     
  108.     delete pFunction;
  109.     return hr;
  110. }
  111.  
  112. /*
  113.  * CFunction::CFunction
  114.  *
  115.  * Purpose:
  116.  *  Constructor for CFunction object. Initializes members to NULL.
  117.  *
  118.  */
  119. CFunction::CFunction()
  120. {
  121.     m_bstrName = NULL;
  122.     m_bstrDocumentation = NULL;
  123.     m_bstrHelpFile = NULL;
  124.     m_pdispParameters = NULL;    
  125.     m_ptinfoFunction = NULL;
  126.     m_pfuncdesc = NULL;  
  127.     m_pdispTypeDesc = NULL;
  128. }
  129.  
  130. /*
  131.  * CFunction::~CFunction
  132.  *
  133.  * Purpose:
  134.  *  Destructor for CFunction object. 
  135.  *
  136.  */
  137. CFunction::~CFunction()
  138. {    
  139.      if (m_bstrName) SysFreeString(m_bstrName);
  140.      if (m_bstrDocumentation) SysFreeString(m_bstrDocumentation);
  141.      if (m_bstrHelpFile) SysFreeString(m_bstrHelpFile);
  142.      if (m_pdispParameters) m_pdispParameters->Release();        
  143.      if (m_pfuncdesc && m_ptinfoFunction) m_ptinfoFunction->ReleaseFuncDesc(m_pfuncdesc);
  144.      if (m_ptinfoFunction) m_ptinfoFunction->Release();      
  145.      if (m_pdispTypeDesc) m_pdispTypeDesc->Release();
  146. }
  147.  
  148. STDMETHODIMP_(REFCLSID)
  149. CFunction::GetInterfaceID()
  150. {
  151.     return IID_IFunction;
  152. }
  153.  
  154. STDMETHODIMP_(BSTR)
  155. CFunction::get_Name()
  156. {
  157.     return SysAllocString(m_bstrName);
  158.  
  159. STDMETHODIMP_(BSTR)
  160. CFunction::get_Documentation()     
  161. {
  162.     return SysAllocString(m_bstrDocumentation);
  163. }  
  164.  
  165. STDMETHODIMP_(long)
  166. CFunction::get_HelpContext()     
  167. {
  168.     return (long)m_ulHelpContext;
  169. }
  170.  
  171. STDMETHODIMP_(BSTR)
  172. CFunction::get_HelpFile()     
  173. {
  174.     return SysAllocString(m_bstrHelpFile);
  175. }   
  176.  
  177.  
  178. STDMETHODIMP_(ITypeDesc FAR*)
  179. CFunction::get_ReturnType()
  180. {   
  181.     m_pdispTypeDesc->AddRef();
  182.     return (ITypeDesc FAR*)m_pdispTypeDesc;
  183. }
  184.  
  185.  
  186. STDMETHODIMP_(ICollection FAR*)
  187. CFunction::get_Parameters()
  188. {   
  189.     HRESULT hr;        
  190.     CParameter FAR* pParameter;
  191.     CCollection FAR* pCollection = NULL;
  192.     LPDISPATCH pdisp;
  193.     BSTR FAR* rgbstrNames = NULL;  
  194.     unsigned int cNames;       
  195.     unsigned short n = 0;
  196.     
  197.     // Create a collection of parameters and return it.
  198.     if (m_pdispParameters == NULL)
  199.     {   
  200.         rgbstrNames = new BSTR[m_pfuncdesc->cParams+1];
  201.         if (rgbstrNames == NULL)
  202.             {RaiseException(IDS_OutOfMemory); return NULL;}  
  203.         
  204.         // Get the name of the function and its parameters
  205.         hr = m_ptinfoFunction->GetNames(m_pfuncdesc->memid, rgbstrNames, 
  206.                               m_pfuncdesc->cParams+1, &cNames);
  207.         if (FAILED(hr))
  208.             {RaiseException(IDS_Unexpected); goto error;}     
  209.         SysFreeString(rgbstrNames[0]);
  210.         
  211.         // Create a parameter collection
  212.         hr = CCollection::Create(m_pfuncdesc->cParams, 0, &pCollection);  
  213.         if (FAILED(hr))
  214.             {RaiseException(IDS_Unexpected); goto error;}        
  215.         
  216.         // The value being assigned to a property does not have a name. Call it 'Value'
  217.         if (m_pfuncdesc->invkind & INVOKE_PROPERTYPUT)
  218.             rgbstrNames[n+1] = SysAllocString(OLESTR("Value"));
  219.         // Add parameters to the parameter collection
  220.         for (n=0; n<m_pfuncdesc->cParams; n++)
  221.         {
  222.             hr = CParameter::Create(m_ptinfoFunction, 
  223.                    rgbstrNames[n+1], 
  224.                    &m_pfuncdesc->lprgelemdescParam[n].tdesc, 
  225.                    &m_pfuncdesc->lprgelemdescParam[n].idldesc,
  226.                    &pParameter);
  227.             if (FAILED(hr))
  228.                 {RaiseException(IDS_Unexpected); goto error;}     
  229.             SysFreeString(rgbstrNames[n+1]);
  230.             pParameter->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
  231.             pCollection->Add(pdisp);
  232.             pdisp->Release();  
  233.         }
  234.         pCollection->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
  235.         m_pdispParameters = pdisp;   
  236.         delete rgbstrNames;
  237.     }    
  238.     m_pdispParameters->AddRef();
  239.     return (ICollection FAR*)m_pdispParameters;       
  240.     
  241. error:  
  242.     if (pCollection) delete pCollection;  
  243.     if (rgbstrNames) 
  244.         for (; n<m_pfuncdesc->cParams; n++)
  245.             SysFreeString(rgbstrNames[n+1]);     
  246.     return NULL;
  247.  
  248. STDMETHODIMP_(MEMBERID)
  249. CFunction::get_Memberid()
  250. {
  251.     return m_pfuncdesc->memid;
  252. }
  253.  
  254. STDMETHODIMP_(CALLCONV)
  255. CFunction::get_CallConvention()
  256.     return m_pfuncdesc->callconv;
  257. }
  258.  
  259. STDMETHODIMP_(FUNCKIND)
  260. CFunction::get_FuncKind()
  261.     return m_pfuncdesc->funckind;
  262. }
  263.  
  264. STDMETHODIMP_(INVOKEKIND)
  265. CFunction::get_InvocationKind()
  266.     return m_pfuncdesc->invkind;
  267. }
  268.  
  269. STDMETHODIMP_(short)
  270. CFunction::get_NumberOfOptionalParams()
  271. {
  272.     return m_pfuncdesc->cParamsOpt;
  273. }
  274.  
  275. STDMETHODIMP_(short)
  276. CFunction::get_OffsetInVtbl()
  277. {
  278.     return m_pfuncdesc->oVft;
  279. }
  280.  
  281. STDMETHODIMP_(unsigned short)
  282. CFunction::get_FuncFlags()
  283. {
  284.     return m_pfuncdesc->wFuncFlags;
  285. }
  286.  
  287. STDMETHODIMP_(OBJTYPE)
  288. CFunction::get_Kind()
  289. {   
  290.     return TYPE_FUNCTION;
  291. }
  292.