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

Windows编程

开发平台:

Visual C++

  1. /*+----------------------------------------------------------------------------
  2. Microsoft Windows Sample Program
  3. Copyright (C) 1994 - 1997 Microsoft Corporation.  All rights reserved.
  4. FILE:       CHello.cxx
  5. PURPOSE:    Implements the CHello object and class factory.
  6. CLASSES:    CHello
  7.             CHelloClassFactory
  8. FUNCTIONS:  RegisterClassFactory
  9.             RevokeClassFactory
  10. -----------------------------------------------------------------------------*/
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include "ohello.h"
  14. void DecrementLockCount();
  15. void IncrementLockCount();
  16. void ObjectCreated();
  17. void ObjectDestroyed();
  18. extern "C" const CLSID CLSID_OHello;
  19. long    g_fClassRegistered  = FALSE;
  20. DWORD   g_dwRegister        = 0;
  21. //The CHello class implements the server object.
  22. class CHello : public IHello
  23. {
  24. private:
  25.     unsigned long    m_cRef;
  26.     //destructor
  27.     ~CHello()
  28.     {
  29.         DecrementLockCount();
  30.         ObjectDestroyed();
  31.     }
  32.     
  33. public:
  34.     //constructor
  35.     CHello()
  36.     {
  37.         m_cRef = 1;
  38.         ObjectCreated();
  39.         IncrementLockCount();
  40.     }
  41.     
  42. HRESULT STDMETHODCALLTYPE QueryInterface(
  43. REFIID iid,
  44.     void **ppv);
  45. ULONG STDMETHODCALLTYPE AddRef();
  46. ULONG STDMETHODCALLTYPE Release();
  47. HRESULT STDMETHODCALLTYPE HelloProc(unsigned char *pszString);
  48. };
  49. //+-------------------------------------------------------------------------
  50. //
  51. //  Method:     CHello::AddRef, public
  52. //
  53. //  Synopsis:   Increment reference count
  54. //
  55. //  See Also:   IUnknown::AddRef
  56. //
  57. //--------------------------------------------------------------------------
  58. ULONG STDMETHODCALLTYPE 
  59. CHello::AddRef()
  60. {
  61.     InterlockedIncrement((long *) &m_cRef);
  62.     return m_cRef;
  63. }
  64. //+---------------------------------------------------------------------------
  65. //
  66. //  Method:     CHello::HelloProc()
  67. //
  68. //  Synopsis:   Displays the specified string.
  69. //
  70. //  See Also:   IHello::HelloProc
  71. //
  72. //----------------------------------------------------------------------------
  73. HRESULT STDMETHODCALLTYPE
  74. CHello::HelloProc(unsigned char *pszString)
  75. {
  76.     printf("HelloProc: %s n", pszString);
  77.     return S_OK;
  78. }
  79. //+-------------------------------------------------------------------------
  80. //
  81. //  Method:     CHello::QueryInterface, public
  82. //
  83. //  Synopsis:   Query for an interface on the class factory.
  84. //
  85. //  See Also:   IUnknown:QueryInterface
  86. //
  87. //--------------------------------------------------------------------------
  88. HRESULT STDMETHODCALLTYPE 
  89. CHello::QueryInterface (
  90.     REFIID iid,
  91.     void **ppv )
  92. {
  93.     HRESULT hr;
  94.     if ( IsEqualGUID( iid, IID_IUnknown ) ||
  95.          IsEqualGUID( iid, IID_IHello ) )
  96.     {
  97.         *ppv = (IHello *) this;
  98.         AddRef();
  99.     hr = S_OK;
  100.     }
  101.     else
  102.     {
  103.         *ppv = 0;
  104.         hr = E_NOINTERFACE;
  105.     }
  106.     return hr;
  107. }
  108. //+-------------------------------------------------------------------------
  109. //
  110. //  Method:     CHello::Release, public
  111. //
  112. //  Synopsis:   Decrement DLL reference count
  113. //
  114. //  Notes:      After the m_cRef is decremented, the object may be 
  115. //              deleted by another thread.  In order to make this code safe
  116. //              for multiple threads, we have to access the object state 
  117. //              before decrementing m_cRef.
  118. //
  119. //  See Also:   IUnknown::Release.
  120. //
  121. //--------------------------------------------------------------------------
  122. ULONG STDMETHODCALLTYPE
  123. CHello::Release()
  124. {
  125.     unsigned long count;
  126.     
  127.     count = m_cRef - 1;
  128.     if(InterlockedDecrement((long *) &m_cRef) == 0)
  129.     {
  130.         count = 0;
  131.         delete this;
  132.     }
  133.     return count;
  134. }
  135. // this is the class factory for the CHello server object.
  136. // it manufactures CHello server objects in response to a CreateInstance
  137. // call
  138. class CHelloClassFactory : public IClassFactory
  139. {
  140. private:
  141.     unsigned long    m_cRef;
  142.     //destructor
  143.     ~CHelloClassFactory()
  144.     {
  145.         ObjectDestroyed();
  146.     }
  147. public:
  148.     //constructor
  149.     CHelloClassFactory()
  150.     {
  151.         m_cRef = 1;
  152.         ObjectCreated();
  153.     }
  154. HRESULT STDMETHODCALLTYPE QueryInterface(
  155. REFIID iid,
  156.     void **ppv);
  157. ULONG STDMETHODCALLTYPE AddRef();
  158. ULONG STDMETHODCALLTYPE Release();
  159. HRESULT STDMETHODCALLTYPE CreateInstance(
  160.     IUnknown *punkOuter,
  161.     REFIID riid,
  162.     void **ppv);
  163.    HRESULT STDMETHODCALLTYPE LockServer(
  164.         BOOL fLock );
  165. };
  166. //+-------------------------------------------------------------------------
  167. //
  168. //  Method:     CHelloClassFactory::AddRef, public
  169. //
  170. //  Synopsis:   Increment DLL reference counts
  171. //
  172. //  See Also:   IUnknown::AddRef
  173. //
  174. //--------------------------------------------------------------------------
  175. ULONG STDMETHODCALLTYPE 
  176. CHelloClassFactory::AddRef()
  177. {
  178.     InterlockedIncrement((long *) &m_cRef);
  179.     return m_cRef;
  180. }
  181. //+-------------------------------------------------------------------------
  182. //
  183. //  Method:     CHelloClassFactory::CreateInstance, public
  184. //
  185. //  Synopsis:   Create an instance of CHello.
  186. //
  187. //  See Also:   IClassFactory::CreateInstance
  188. //
  189. //--------------------------------------------------------------------------
  190. HRESULT STDMETHODCALLTYPE 
  191. CHelloClassFactory::CreateInstance
  192. (
  193.     IUnknown *punkOuter,
  194.     REFIID riid,
  195.     void **ppv
  196. )
  197. {
  198.     HRESULT hr;
  199.     CHello *pHello;
  200.     if(punkOuter != 0)
  201.     {
  202.         //The CHello class doesn't support aggregation.
  203.         return CLASS_E_NOAGGREGATION;
  204.     }
  205.     pHello = new CHello();
  206.     if(pHello != 0)
  207.     {
  208.         hr = pHello->QueryInterface(riid, ppv);
  209.         pHello->Release();
  210.     }
  211.     else
  212.     {
  213.         hr = E_OUTOFMEMORY;
  214.         *ppv = 0;
  215.     }
  216.     return hr;
  217. }
  218. //+-------------------------------------------------------------------------
  219. //
  220. //  Method:     CHelloClassFactory::LockServer, public
  221. //
  222. //  Synopsis:   Lock the server in memory (by adding an extra reference)
  223. //
  224. //  Notes:      The class factory will be revoked when the lock count
  225. //              is decremented to zero.  LockServer(TRUE) will increment the
  226. //              lock count and ensure that the class factory will
  227. //              not be revoked.
  228. //
  229. //  See Also:   IClassFactory::LockServer
  230. //
  231. //--------------------------------------------------------------------------
  232. HRESULT STDMETHODCALLTYPE 
  233. CHelloClassFactory::LockServer(
  234.     BOOL fLock )
  235. {
  236.     if (fLock == TRUE)
  237.         IncrementLockCount();
  238.     else
  239.         DecrementLockCount();
  240.     return S_OK;
  241. }
  242. //+-------------------------------------------------------------------------
  243. //
  244. //  Method:     CHelloClassFactory::QueryInterface, public
  245. //
  246. //  Synopsis:   Query for an interface on the class factory.
  247. //
  248. //  See Also:   IUnknown::QueryInterface
  249. //
  250. //--------------------------------------------------------------------------
  251. HRESULT STDMETHODCALLTYPE 
  252. CHelloClassFactory::QueryInterface (
  253.     REFIID iid,
  254.     void **ppv )
  255. {
  256.     HRESULT hr;
  257.     if ( IsEqualGUID( iid, IID_IUnknown) ||
  258.          IsEqualGUID( iid, IID_IClassFactory ) )
  259.     {
  260.         *ppv = this;
  261.         AddRef();
  262.         hr = S_OK;
  263.     }
  264.     else
  265.     {
  266.         *ppv = 0;
  267.         hr = E_NOINTERFACE;
  268.     }
  269.     return hr;
  270. }
  271. //+-------------------------------------------------------------------------
  272. //
  273. //  Method:     CHelloClassFactory::Release, public
  274. //
  275. //  Synopsis:   Decrement DLL reference count
  276. //
  277. //  See Also:   IUnknown::Release
  278. //
  279. //--------------------------------------------------------------------------
  280. ULONG STDMETHODCALLTYPE
  281. CHelloClassFactory::Release()
  282. {
  283.     unsigned long count;
  284.     
  285.     count = m_cRef - 1;
  286.     if(InterlockedDecrement((long *) &m_cRef) == 0)
  287.     {
  288.         count = 0;
  289.         ObjectDestroyed();
  290.     }
  291.     return count;
  292. }
  293. //+-------------------------------------------------------------------------
  294. //
  295. //  Function:   RegisterClassFactory.
  296. //
  297. //  Synopsis:   Register the class factory if it is not currently registered.
  298. //
  299. //--------------------------------------------------------------------------
  300. HRESULT RegisterClassFactory()
  301. {
  302.     HRESULT hr;
  303.     CHelloClassFactory *pClassFactory;
  304.     if(InterlockedExchange(&g_fClassRegistered, TRUE) == FALSE)
  305.     {
  306.         pClassFactory = new CHelloClassFactory;
  307.         
  308.         if(pClassFactory != 0)
  309.         {
  310.             hr = CoRegisterClassObject(CLSID_OHello,
  311.                             (IUnknown *) pClassFactory,
  312.                              CLSCTX_LOCAL_SERVER,
  313.                             REGCLS_MULTIPLEUSE,
  314.                            &g_dwRegister);
  315.            pClassFactory->Release();
  316.         }
  317.         else
  318.         {
  319.            hr = E_OUTOFMEMORY;
  320.         }
  321.     }
  322.     else
  323.     {
  324.         hr = S_OK;
  325.     }
  326.     return hr;  
  327. }
  328. //+-------------------------------------------------------------------------
  329. //
  330. //  Function:   RevokeClassFactory.
  331. //
  332. //  Synopsis:   Revoke the registered class factories if they have not
  333. //              already been revoked.
  334. //
  335. //--------------------------------------------------------------------------
  336. HRESULT RevokeClassFactory()
  337. {
  338.     HRESULT hr;
  339.     if(InterlockedExchange(&g_fClassRegistered, FALSE) == TRUE)
  340.     {
  341.         hr = CoRevokeClassObject(g_dwRegister);
  342.     }
  343.     else
  344.     {
  345.         hr = S_OK;
  346.     }
  347.     return hr;
  348. }