home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap14 / beeper5 / dbeeper.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-21  |  4.3 KB  |  233 lines

  1. /*
  2.  * DBEEPER.CPP
  3.  * Beeper Automation Object Chapter 14
  4.  *
  5.  * Server module code for the Beeper object.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #define INITGUIDS
  16. #include "dbeeper.h"
  17.  
  18.  
  19. //Count number of objects and number of locks.
  20. ULONG       g_cObj=0;
  21. ULONG       g_cLock=0;
  22.  
  23.  
  24. /*
  25.  * LibMain(32)
  26.  *
  27.  * Purpose:
  28.  *  Entry point conditionally compiled for Win32 and Windows
  29.  *  3.1.  Provides the proper structure for each environment.
  30.  */
  31.  
  32. #ifdef WIN32
  33. BOOL WINAPI LibMain32(HINSTANCE hInstance, ULONG ulReason
  34.     , LPVOID pvReserved)
  35.     {
  36.     if (DLL_PROCESS_DETACH==ulReason)
  37.         {
  38.         return TRUE;
  39.         }
  40.     else
  41.         {
  42.         if (DLL_PROCESS_ATTACH!=ulReason)
  43.             return TRUE;
  44.         }
  45.  
  46.     return TRUE;
  47.     }
  48. #else
  49. int PASCAL LibMain(HINSTANCE hInstance, WORD wDataSeg
  50.     , WORD cbHeapSize, LPSTR lpCmdLine)
  51.     {
  52.     if (0!=cbHeapSize)
  53.         UnlockData(0);
  54.  
  55.     return (int)hInstance;
  56.     }
  57. #endif
  58.  
  59.  
  60.  
  61. /*
  62.  * DllGetClassObject
  63.  * DllCanUnloadNow
  64.  * Standard COM exports for DLL servers.
  65.  */
  66.  
  67. HRESULT APIENTRY DllGetClassObject(REFCLSID rclsid, REFIID riid
  68.     , PPVOID ppv)
  69.     {
  70.     CBeeperFactory *pBF;
  71.     HRESULT         hr;
  72.  
  73.     if (CLSID_Beeper!=rclsid)
  74.         return ResultFromScode(E_FAIL);
  75.  
  76.     //Check that we can provide the interface
  77.     if (IID_IUnknown!=riid && IID_IClassFactory!=riid)
  78.         return ResultFromScode(E_NOINTERFACE);
  79.  
  80.     //Return our beeper factory's IClassFactory
  81.     pBF=new CBeeperFactory();
  82.  
  83.     if (NULL==pBF)
  84.         return ResultFromScode(E_OUTOFMEMORY);
  85.  
  86.     //If the factory hasn't the interface, delete it
  87.     hr=pBF->QueryInterface(riid, ppv);
  88.  
  89.     if (FAILED(hr))
  90.         delete pBF;
  91.  
  92.     return hr;
  93.     }
  94.  
  95.  
  96. STDAPI DllCanUnloadNow(void)
  97.     {
  98.     SCODE   sc;
  99.  
  100.     //Our answer is whether there are any object or locks
  101.     sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE;
  102.     return ResultFromScode(sc);
  103.     }
  104.  
  105.  
  106.  
  107. /*
  108.  * ObjectDestroyed
  109.  *
  110.  * Purpose:
  111.  *  Function for the object to call when it gets destroyed.  Since
  112.  *  we're in a DLL we only track the number of objects here, letting
  113.  *  DllCanUnloadNow take care of the rest.
  114.  */
  115.  
  116. void ObjectDestroyed(void)
  117.     {
  118.     g_cObj--;
  119.     return;
  120.     }
  121.  
  122.  
  123.  
  124. /*
  125.  * CBeeperFactory::CBeeperFactory
  126.  * CBeeperFactory::~CBeeperFactory
  127.  */
  128.  
  129. CBeeperFactory::CBeeperFactory(void)
  130.     {
  131.     m_cRef=0L;
  132.     return;
  133.     }
  134.  
  135.  
  136. CBeeperFactory::~CBeeperFactory(void)
  137.     {
  138.     return;
  139.     }
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146. /*
  147.  * CBeeperFactory::QueryInterface
  148.  * CBeeperFactory::AddRef
  149.  * CBeeperFactory::Release
  150.  */
  151.  
  152. STDMETHODIMP CBeeperFactory::QueryInterface(REFIID riid, PPVOID ppv)
  153.     {
  154.     *ppv=NULL;
  155.  
  156.     if (IID_IUnknown==riid || IID_IClassFactory==riid)
  157.         *ppv=this;
  158.  
  159.     if (NULL!=*ppv)
  160.         {
  161.         ((LPUNKNOWN)*ppv)->AddRef();
  162.         return NOERROR;
  163.         }
  164.  
  165.     return ResultFromScode(E_NOINTERFACE);
  166.     }
  167.  
  168.  
  169. STDMETHODIMP_(ULONG) CBeeperFactory::AddRef(void)
  170.     {
  171.     return ++m_cRef;
  172.     }
  173.  
  174.  
  175. STDMETHODIMP_(ULONG) CBeeperFactory::Release(void)
  176.     {
  177.     if (0!=--m_cRef)
  178.         return m_cRef;
  179.  
  180.     delete this;
  181.     ObjectDestroyed();
  182.     return 0;
  183.     }
  184.  
  185.  
  186.  
  187. /*
  188.  * CBeeperFactory::CreateInstance
  189.  * CBeeperFactory::LockServer
  190.  */
  191.  
  192. STDMETHODIMP CBeeperFactory::CreateInstance(LPUNKNOWN pUnkOuter
  193.     , REFIID riid, PPVOID ppvObj)
  194.     {
  195.     PCBeeper            pObj;
  196.     HRESULT             hr;
  197.  
  198.     *ppvObj=NULL;
  199.     hr=ResultFromScode(E_OUTOFMEMORY);
  200.  
  201.     //Verify that a controlling unknown asks for IUnknown
  202.     if (NULL!=pUnkOuter && IID_IUnknown!=riid)
  203.         return ResultFromScode(CLASS_E_NOAGGREGATION);
  204.  
  205.     //Create the object passing function to notify on destruction.
  206.     pObj=new CBeeper(pUnkOuter, ObjectDestroyed);
  207.  
  208.     if (NULL==pObj)
  209.         return hr;
  210.  
  211.     if (pObj->Init())
  212.         hr=pObj->QueryInterface(riid, ppvObj);
  213.  
  214.     //Kill the object if initial creation or Init failed.
  215.     if (FAILED(hr))
  216.         delete pObj;
  217.     else
  218.         g_cObj++;
  219.  
  220.     return hr;
  221.     }
  222.  
  223.  
  224. STDMETHODIMP CBeeperFactory::LockServer(BOOL fLock)
  225.     {
  226.     if (fLock)
  227.         g_cLock++;
  228.     else
  229.         g_cLock--;
  230.  
  231.     return NOERROR;
  232.     }
  233.