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 / mydisp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-31  |  5.9 KB  |  271 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. **  mydisp.cpp
  14. **
  15. **  CMyDispatch implementation
  16. **
  17. **  Written by Microsoft Product Support Services, Windows Developer Support
  18. **
  19. **  The CMyDispatch object implement IUnknown & IDispatch for all the automation
  20. **  objects in this sample. All objects derive from CMyDispatch.
  21. **
  22. *************************************************************************/
  23.  
  24. #include <windows.h>
  25. #include <windowsx.h>
  26. #ifdef WIN16   
  27.   #include <ole2.h>
  28.   #include <compobj.h>    
  29.   #include <dispatch.h> 
  30.   #include <variant.h>
  31.   #include <olenls.h>  
  32. #endif 
  33. #include "browseh.h" 
  34.  
  35. /*
  36.  * CMyDispatch::CMyDispatch
  37.  *
  38.  * Purpose:
  39.  *  Constructor for CMyDispatch object. Initializes members to NULL.
  40.  *
  41.  */
  42. CMyDispatch::CMyDispatch()
  43. {    
  44.     m_ptinfo = NULL;
  45.     m_cRef = 0;
  46. }
  47.  
  48. /*
  49.  * CMyDispatch::~CMyDispatch
  50.  *
  51.  * Purpose:
  52.  *  Destructor for CMyDispatch object. 
  53.  *
  54.  */
  55. CMyDispatch::~CMyDispatch()
  56. {    
  57.      if (m_ptinfo) m_ptinfo->Release();                   
  58. }
  59.  
  60. /*
  61.  * CMyDispatch::QueryInterface, AddRef, Release
  62.  *
  63.  * Purpose:
  64.  *  Implements IUnknown::QueryInterface, AddRef, Release
  65.  *
  66.  */
  67.  
  68. STDMETHODIMP
  69. CMyDispatch::QueryInterface(REFIID iid, void FAR* FAR* ppv) 
  70. {   
  71.     *ppv = NULL;
  72.         
  73.     if (iid == IID_IUnknown) 
  74.         *ppv = this;   
  75.     else if (iid == IID_IDispatch)
  76.         *ppv = this;     
  77.     else if (iid == GetInterfaceID())
  78.         *ppv = this;
  79.     else return E_NOINTERFACE; 
  80.  
  81.     AddRef();
  82.     return NOERROR;    
  83. }
  84.  
  85.  
  86. STDMETHODIMP_(ULONG)
  87. CMyDispatch::AddRef(void)
  88. {
  89. #ifdef _DEBUG  
  90.     TCHAR ach[150];
  91.     wsprintf(ach, TEXT("Ref = %ld, Object = %s\r\n"), m_cRef+1, m_szClassName); 
  92.     OutputDebugString(ach); 
  93. #endif    
  94.     return ++m_cRef;
  95. }
  96.  
  97.  
  98. STDMETHODIMP_(ULONG)
  99. CMyDispatch::Release(void)
  100. {
  101. #ifdef _DEBUG  
  102.     TCHAR ach[150];
  103.     wsprintf(ach, TEXT("Ref = %ld, Object = %s\r\n"), m_cRef-1, m_szClassName); 
  104.     OutputDebugString(ach);
  105. #endif  
  106.     if(--m_cRef == 0)
  107.     {
  108.         delete this;
  109.         return 0;
  110.     }
  111.     return m_cRef;
  112.  
  113. /*
  114.  * CMyDispatch::GetTypeInfoCount
  115.  *
  116.  * Purpose:
  117.  *  Implements IDispatch::GetTypeInfoCount.
  118.  *
  119.  */
  120. STDMETHODIMP
  121. CMyDispatch::GetTypeInfoCount(UINT FAR* pctinfo)
  122. {
  123.     *pctinfo = 1;
  124.     return NOERROR;
  125. }
  126.  
  127. /*
  128.  * CMyDispatch::GetTypeInfo
  129.  *
  130.  * Purpose:
  131.  *  Implements IDispatch::GetTypeInfo. 
  132.  *
  133.  */
  134. STDMETHODIMP
  135. CMyDispatch::GetTypeInfo(
  136.       UINT itinfo,
  137.       LCID lcid,
  138.       ITypeInfo FAR* FAR* pptinfo)
  139. {    
  140.     *pptinfo = NULL;
  141.      
  142.     if(itinfo != 0)
  143.         return DISP_E_BADINDEX;
  144.     
  145.     m_ptinfo->AddRef(); 
  146.     *pptinfo = m_ptinfo;
  147.     
  148.     return NOERROR;
  149. }
  150.  
  151. /*
  152.  * CMyDispatch::GetIDsOfNames
  153.  *
  154.  * Purpose:
  155.  *  Implements IDispatch::GetIDsOfNames.  The standard implementation, DispGetIDsOfNames,
  156.  *  is used.
  157.  *
  158.  */
  159. STDMETHODIMP 
  160. CMyDispatch::GetIDsOfNames(
  161.       REFIID riid,
  162.       OLECHAR FAR* FAR* rgszNames,
  163.       UINT cNames,
  164.       LCID lcid,
  165.       DISPID FAR* rgdispid)
  166. {
  167.     return DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
  168. }
  169.  
  170. /*
  171.  * CMyDispatch::Invoke
  172.  *
  173.  * Purpose:
  174.  *  Implements IDispatch::Invoke.  The standard implementation, DispInvoke,
  175.  *  is used. Properties and methods  will
  176.  *  set m_bRaiseException to raise an exception. 
  177.  *
  178.  */
  179. STDMETHODIMP
  180. CMyDispatch::Invoke(
  181.       DISPID dispidMember,
  182.       REFIID riid,
  183.       LCID lcid,
  184.       WORD wFlags,
  185.       DISPPARAMS FAR* pdispparams,
  186.       VARIANT FAR* pvarResult,
  187.       EXCEPINFO FAR* pexcepinfo,
  188.       UINT FAR* puArgErr)
  189. {  
  190.     HRESULT hr;
  191.    
  192.     m_bRaiseException = FALSE;         
  193.     hr =  DispInvoke(
  194.         this, m_ptinfo,
  195.         dispidMember, wFlags, pdispparams,
  196.         pvarResult, pexcepinfo, puArgErr); 
  197.     if (m_bRaiseException) 
  198.     {
  199.        if (NULL != pexcepinfo)
  200.            _fmemcpy(pexcepinfo, &m_excepinfo, sizeof(EXCEPINFO));  
  201.        return DISP_E_EXCEPTION; 
  202.     }
  203.     else return hr;   
  204.  
  205. /*
  206.  * CMyDispatch::LoadTypeInfo
  207.  *
  208.  *  Purpose:
  209.  *   Gets type information of an object's interface from type library.
  210.  *
  211.  * Parameters:
  212.  *  clsid               Interface id of object in type library. 
  213.  *
  214.  * Return Value:
  215.  *  HRESULT
  216.  *
  217.  */
  218. STDMETHODIMP
  219. CMyDispatch::LoadTypeInfo(REFCLSID clsid)
  220. {                          
  221.     HRESULT hr;
  222.     LPTYPELIB ptlib = NULL;
  223.     LPTYPEINFO ptinfo = NULL;
  224.     
  225.     // Load Type Library. If required, notify user on failure.
  226.     hr = LoadRegTypeLib(LIBID_BrowseHelper, 1, 0, 0x09, &ptlib);
  227.     if (FAILED(hr))
  228.         return hr; 
  229.     
  230.     // Get type information for interface of the object.      
  231.     hr = ptlib->GetTypeInfoOfGuid(clsid, &ptinfo);
  232.     if (FAILED(hr))  
  233.     { 
  234.         ptlib->Release();
  235.         return hr;
  236.     }   
  237.  
  238.     ptlib->Release();
  239.     m_ptinfo = ptinfo;
  240.     return NOERROR;
  241. }
  242.  
  243. /*
  244.  * CMyDispatch::RaiseException
  245.  *
  246.  *  Purpose:
  247.  *   Raises exception so CMyDispatch::Invoke will return DISP_E_EXCEPTION
  248.  *
  249.  * Parameters:
  250.  *  nID               ID of exception to be raised.
  251.  *
  252.  */
  253. STDMETHODIMP_(void)
  254. CMyDispatch::RaiseException(int nID)
  255. {   
  256.     extern HINSTANCE g_hinst;
  257.     extern TCHAR g_szServerName[];     
  258.     TCHAR szError[STR_LEN];
  259.     
  260.     _fmemset(&m_excepinfo, 0, sizeof(EXCEPINFO));
  261.     
  262.     m_excepinfo.wCode = nID;
  263.     if (LoadString(g_hinst, nID, szError, sizeof(szError)))
  264.         m_excepinfo.bstrDescription = SysAllocString(TO_OLE_STRING(szError));    
  265.     m_excepinfo.bstrSource = SysAllocString(TO_OLE_STRING(g_szServerName));
  266.     
  267.     m_bRaiseException = TRUE; 
  268. }
  269.