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 / chap23 / polyline / dllpoly.cpp next >
Encoding:
C/C++ Source or Header  |  1996-05-21  |  7.7 KB  |  369 lines

  1. /*
  2.  * DLLPOLY.CPP
  3.  * Polyline Component Chapter 23
  4.  *
  5.  * Polyline component object used in CoCosmo that supports a custom
  6.  * interface IPolyline.  Contains DLL entry code and the component
  7.  * object exports DllGetClassObject and DllCanUnloadNow and the
  8.  * class factory object.
  9.  *
  10.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  11.  *
  12.  * Kraig Brockschmidt, Microsoft
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #define INITGUIDS
  19. #include "polyline.h"
  20.  
  21.  
  22. //Count number of objects and number of locks.
  23. ULONG       g_cObj=0;
  24. ULONG       g_cLock=0;
  25.  
  26. //DLL Instance handle
  27. HINSTANCE   g_hInst=0;
  28.  
  29.  
  30.  
  31. /*
  32.  * LibMain32 (Win32)
  33.  *
  34.  * Purpose:
  35.  *  Entry point for Win32 DLLs that calls the Win16 LibMain.
  36.  */
  37.  
  38. #ifdef WIN32
  39. BOOL WINAPI LibMain32(HINSTANCE hInstance, ULONG ulReason
  40.     , LPVOID pvReserved)
  41.     {
  42.     if (DLL_PROCESS_DETACH==ulReason)
  43.         {
  44.         return TRUE;
  45.         }
  46.     else
  47.         {
  48.         if (DLL_PROCESS_ATTACH!=ulReason)
  49.             return TRUE;
  50.         }
  51.  
  52.     return (0!=LibMain(hInstance, 0,  0, NULL));
  53.     }
  54. #endif
  55.  
  56.  
  57.  
  58. /*
  59.  * LibMain (also called from Win32 LibMain32)
  60.  *
  61.  * Purpose:
  62.  *  DLL-specific entry point called from LibEntry.
  63.  */
  64.  
  65. int PASCAL LibMain(HINSTANCE hInst, WORD wDataSeg
  66.     , WORD cbHeapSize, LPSTR lpCmdLine)
  67.     {
  68.     WNDCLASS    wc;
  69.  
  70.     if (GetClassInfo(hInst, SZCLASSPOLYLINE, &wc))
  71.         return (int)hInst;
  72.  
  73.    #ifndef WIN32
  74.     if (0!=cbHeapSize)
  75.         UnlockData(0);
  76.    #endif
  77.  
  78.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  79.     wc.hInstance     = hInst;
  80.     wc.cbClsExtra    = 0;
  81.     wc.lpfnWndProc   = PolylineWndProc;
  82.     wc.cbWndExtra    = CBPOLYLINEWNDEXTRA;
  83.     wc.hIcon         = NULL;
  84.     wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
  85.     wc.hbrBackground = NULL;
  86.     wc.lpszMenuName  = NULL;
  87.     wc.lpszClassName = SZCLASSPOLYLINE;
  88.  
  89.     if (!RegisterClass(&wc))
  90.         return 0;
  91.  
  92.     //CHAPTER23MOD
  93.     if (!HatchWindowRegister(hInst))
  94.         return 0;
  95.     //End CHAPTER23MOD
  96.  
  97.     g_hInst=hInst;
  98.     return (int)hInst;
  99.     }
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107. /*
  108.  * DllGetClassObject
  109.  *
  110.  * Purpose:
  111.  *  Provides an IClassFactory for a given CLSID that this DLL is
  112.  *  registered to support.  This DLL is placed under the CLSID
  113.  *  in the registration database as the InProcServer.
  114.  *
  115.  * Parameters:
  116.  *  clsID           REFCLSID that identifies the class factory
  117.  *                  desired.  Since this parameter is passed this
  118.  *                  DLL can handle any number of objects simply
  119.  *                  by returning different class factories here
  120.  *                  for different CLSIDs.
  121.  *
  122.  *  riid            REFIID specifying the interface the caller wants
  123.  *                  on the class object, usually IID_ClassFactory.
  124.  *
  125.  *  ppv             PPVOID in which to return the interface
  126.  *                  pointer.
  127.  *
  128.  * Return Value:
  129.  *  HRESULT         NOERROR on success, otherwise an error code.
  130.  */
  131.  
  132. HRESULT APIENTRY DllGetClassObject(REFCLSID rclsid
  133.     , REFIID riid, PPVOID ppv)
  134.     {
  135.     if (CLSID_Polyline19!=rclsid)
  136.         return ResultFromScode(E_FAIL);
  137.  
  138.     //Check that we can provide the interface
  139.     if (IID_IUnknown!=riid && IID_IClassFactory!=riid)
  140.         return ResultFromScode(E_NOINTERFACE);
  141.  
  142.     //Return our IClassFactory for Polyline objects
  143.     *ppv=new CPolylineClassFactory;
  144.  
  145.     if (NULL==*ppv)
  146.         return ResultFromScode(E_OUTOFMEMORY);
  147.  
  148.     //AddRef the object through any interface we return
  149.     ((LPUNKNOWN)*ppv)->AddRef();
  150.     g_cObj++;
  151.     return NOERROR;
  152.     }
  153.  
  154.  
  155.  
  156.  
  157.  
  158. /*
  159.  * DllCanUnloadNow
  160.  *
  161.  * Purpose:
  162.  *  Answers if the DLL can be freed, that is, if there are no
  163.  *  references to anything this DLL provides.
  164.  *
  165.  * Parameters:
  166.  *  None
  167.  *
  168.  * Return Value:
  169.  *  BOOL            TRUE if nothing is using us, FALSE otherwise.
  170.  */
  171.  
  172. STDAPI DllCanUnloadNow(void)
  173.     {
  174.     SCODE   sc;
  175.  
  176.     //Our answer is whether there are any object or locks
  177.     sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE;
  178.     return ResultFromScode(sc);
  179.     }
  180.  
  181.  
  182.  
  183.  
  184. /*
  185.  * ObjectDestroyed
  186.  *
  187.  * Purpose:
  188.  *  Function for the Polyline object to call when it gets destroyed.
  189.  *  Since we're in a DLL we only track the number of objects here
  190.  *  letting DllCanUnloadNow take care of the rest.
  191.  */
  192.  
  193. void ObjectDestroyed(void)
  194.     {
  195.     g_cObj--;
  196.     return;
  197.     }
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204. /*
  205.  * CPolylineClassFactory::CPolylineClassFactory
  206.  *
  207.  * Purpose:
  208.  *  Constructor for an object supporting an IClassFactory that
  209.  *  instantiates Polyline objects.
  210.  *
  211.  * Parameters:
  212.  *  None
  213.  */
  214.  
  215. CPolylineClassFactory::CPolylineClassFactory(void)
  216.     {
  217.     m_cRef=0L;
  218.     return;
  219.     }
  220.  
  221.  
  222.  
  223.  
  224.  
  225. /*
  226.  * CPolylineClassFactory::~CPolylineClassFactory
  227.  *
  228.  * Purpose:
  229.  *  Destructor for a CPolylineClassFactory object.  This will be
  230.  *  called when we Release the object to a zero reference count.
  231.  */
  232.  
  233. CPolylineClassFactory::~CPolylineClassFactory(void)
  234.     {
  235.     return;
  236.     }
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243. /*
  244.  * CPolylineClassFactory::QueryInterface
  245.  * CPolylineClassFactory::AddRef
  246.  * CPolylineClassFactory::Release
  247.  */
  248.  
  249. STDMETHODIMP CPolylineClassFactory::QueryInterface(REFIID riid
  250.     , PPVOID ppv)
  251.     {
  252.     *ppv=NULL;
  253.  
  254.     if (IID_IUnknown==riid || IID_IClassFactory==riid)
  255.         *ppv=this;
  256.  
  257.     if (NULL!=*ppv)
  258.         {
  259.         ((LPUNKNOWN)*ppv)->AddRef();
  260.         return NOERROR;
  261.         }
  262.  
  263.     return ResultFromScode(E_NOINTERFACE);
  264.     }
  265.  
  266.  
  267. STDMETHODIMP_(ULONG) CPolylineClassFactory::AddRef(void)
  268.     {
  269.     return ++m_cRef;
  270.     }
  271.  
  272.  
  273. STDMETHODIMP_(ULONG) CPolylineClassFactory::Release(void)
  274.     {
  275.     if (0L!=--m_cRef)
  276.         return m_cRef;
  277.  
  278.     delete this;
  279.     ObjectDestroyed();
  280.     return 0L;
  281.     }
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289. /*
  290.  * CPolylineClassFactory::CreateInstance
  291.  *
  292.  * Purpose:
  293.  *  Instantiates a Polyline object.
  294.  *
  295.  * Parameters:
  296.  *  pUnkOuter       LPUNKNOWN to the controlling IUnknown if we
  297.  *                  are being used in an aggregation.
  298.  *  riid            REFIID identifying the interface the caller
  299.  *                  desires to have for the new object.
  300.  *  ppvObj          PPVOID in which to store the desired
  301.  *                  interface pointer for the new object.
  302.  *
  303.  * Return Value:
  304.  *  HRESULT         NOERROR if successful, otherwise E_NOINTERFACE
  305.  *                  if we cannot support the requested interface.
  306.  */
  307.  
  308. STDMETHODIMP CPolylineClassFactory::CreateInstance
  309.     (LPUNKNOWN pUnkOuter, REFIID riid, PPVOID ppvObj)
  310.     {
  311.     PCPolyline          pObj;
  312.     HRESULT             hr;
  313.  
  314.     *ppvObj=NULL;
  315.     hr=ResultFromScode(E_OUTOFMEMORY);
  316.  
  317.     //Verify that a controlling unknown asks for IUnknown
  318.     if (NULL!=pUnkOuter && IID_IUnknown!=riid)
  319.         return ResultFromScode(E_NOINTERFACE);
  320.  
  321.     //Create the object.  This also creates a window.
  322.     pObj=new CPolyline(pUnkOuter, ObjectDestroyed, g_hInst);
  323.  
  324.     if (NULL==pObj)
  325.         return hr;
  326.  
  327.     if (pObj->Init())
  328.         hr=pObj->QueryInterface(riid, ppvObj);
  329.  
  330.     //Kill the object if initial creation or Init failed.
  331.     if (FAILED(hr))
  332.         delete pObj;
  333.     else
  334.         g_cObj++;
  335.  
  336.     return hr;
  337.     }
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344. /*
  345.  * CPolylineClassFactory::LockServer
  346.  *
  347.  * Purpose:
  348.  *  Increments or decrements the lock count of the DLL.  If the lock
  349.  *  count goes to zero and there are no objects, the DLL is allowed
  350.  *  to unload.  See DllCanUnloadNow.
  351.  *
  352.  * Parameters:
  353.  *  fLock           BOOL specifying whether to increment or
  354.  *                  decrement the lock count.
  355.  *
  356.  * Return Value:
  357.  *  HRESULT         NOERROR always.
  358.  */
  359.  
  360. STDMETHODIMP CPolylineClassFactory::LockServer(BOOL fLock)
  361.     {
  362.     if (fLock)
  363.         g_cLock++;
  364.     else
  365.         g_cLock--;
  366.  
  367.     return NOERROR;
  368.     }
  369.