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 / chap16 / beeper6 / dbeeper.cpp < prev    next >
C/C++ Source or Header  |  1996-05-21  |  5KB  |  239 lines

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