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

Windows编程

开发平台:

Visual C++

  1. /*
  2.  * DLLPOLY.CPP
  3.  * Polyline Component Chapter 24
  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. #define INITGUIDS
  17. #include "polyline.h"
  18. //Count number of objects and number of locks.
  19. ULONG       g_cObj=0;
  20. ULONG       g_cLock=0;
  21. //DLL Instance handle
  22. HINSTANCE   g_hInst=0;
  23. /*
  24.  * LibMain32 (Win32)
  25.  *
  26.  * Purpose:
  27.  *  Entry point for Win32 DLLs that calls the Win16 LibMain.
  28.  */
  29. #ifdef WIN32
  30. BOOL WINAPI LibMain32(HINSTANCE hInstance, ULONG ulReason
  31.     , LPVOID pvReserved)
  32.     {
  33.     if (DLL_PROCESS_DETACH==ulReason)
  34.         {
  35.         return TRUE;
  36.         }
  37.     else
  38.         {
  39.         if (DLL_PROCESS_ATTACH!=ulReason)
  40.             return TRUE;
  41.         }
  42.     return (0!=LibMain(hInstance, 0,  0, NULL));
  43.     }
  44. #endif
  45. /*
  46.  * LibMain (also called from Win32 LibMain32)
  47.  *
  48.  * Purpose:
  49.  *  DLL-specific entry point called from LibEntry.
  50.  */
  51. int PASCAL LibMain(HINSTANCE hInst, WORD wDataSeg
  52.     , WORD cbHeapSize, LPSTR lpCmdLine)
  53.     {
  54.     WNDCLASS    wc;
  55.     if (GetClassInfo(hInst, SZCLASSPOLYLINE, &wc))
  56.         return (int)hInst;
  57.    #ifndef WIN32
  58.     if (0!=cbHeapSize)
  59.         UnlockData(0);
  60.    #endif
  61.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  62.     wc.hInstance     = hInst;
  63.     wc.cbClsExtra    = 0;
  64.     wc.lpfnWndProc   = PolylineWndProc;
  65.     wc.cbWndExtra    = CBPOLYLINEWNDEXTRA;
  66.     wc.hIcon         = NULL;
  67.     wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
  68.     wc.hbrBackground = NULL;
  69.     wc.lpszMenuName  = NULL;
  70.     wc.lpszClassName = SZCLASSPOLYLINE;
  71.     if (!RegisterClass(&wc))
  72.         return 0;
  73.     if (!HatchWindowRegister(hInst))
  74.         return 0;
  75.     g_hInst=hInst;
  76.     return (int)hInst;
  77.     }
  78. /*
  79.  * DllGetClassObject
  80.  *
  81.  * Purpose:
  82.  *  Provides an IClassFactory for a given CLSID that this DLL is
  83.  *  registered to support.  This DLL is placed under the CLSID
  84.  *  in the registration database as the InProcServer.
  85.  *
  86.  * Parameters:
  87.  *  clsID           REFCLSID that identifies the class factory
  88.  *                  desired.  Since this parameter is passed this
  89.  *                  DLL can handle any number of objects simply
  90.  *                  by returning different class factories here
  91.  *                  for different CLSIDs.
  92.  *
  93.  *  riid            REFIID specifying the interface the caller wants
  94.  *                  on the class object, usually IID_ClassFactory.
  95.  *
  96.  *  ppv             PPVOID in which to return the interface
  97.  *                  pointer.
  98.  *
  99.  * Return Value:
  100.  *  HRESULT         NOERROR on success, otherwise an error code.
  101.  */
  102. HRESULT APIENTRY DllGetClassObject(REFCLSID rclsid
  103.     , REFIID riid, PPVOID ppv)
  104.     {
  105.     if (CLSID_Polyline19!=rclsid)
  106.         return ResultFromScode(E_FAIL);
  107.     //Check that we can provide the interface
  108.     if (IID_IUnknown!=riid && IID_IClassFactory!=riid)
  109.         return ResultFromScode(E_NOINTERFACE);
  110.     //Return our IClassFactory for Polyline objects
  111.     *ppv=new CPolylineClassFactory;
  112.     if (NULL==*ppv)
  113.         return ResultFromScode(E_OUTOFMEMORY);
  114.     //AddRef the object through any interface we return
  115.     ((LPUNKNOWN)*ppv)->AddRef();
  116.     g_cObj++;
  117.     return NOERROR;
  118.     }
  119. /*
  120.  * DllCanUnloadNow
  121.  *
  122.  * Purpose:
  123.  *  Answers if the DLL can be freed, that is, if there are no
  124.  *  references to anything this DLL provides.
  125.  *
  126.  * Parameters:
  127.  *  None
  128.  *
  129.  * Return Value:
  130.  *  BOOL            TRUE if nothing is using us, FALSE otherwise.
  131.  */
  132. STDAPI DllCanUnloadNow(void)
  133.     {
  134.     SCODE   sc;
  135.     //Our answer is whether there are any object or locks
  136.     sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE;
  137.     return ResultFromScode(sc);
  138.     }
  139. /*
  140.  * ObjectDestroyed
  141.  *
  142.  * Purpose:
  143.  *  Function for the Polyline object to call when it gets destroyed.
  144.  *  Since we're in a DLL we only track the number of objects here
  145.  *  letting DllCanUnloadNow take care of the rest.
  146.  */
  147. void ObjectDestroyed(void)
  148.     {
  149.     g_cObj--;
  150.     return;
  151.     }
  152. /*
  153.  * CPolylineClassFactory::CPolylineClassFactory
  154.  *
  155.  * Purpose:
  156.  *  Constructor for an object supporting an IClassFactory that
  157.  *  instantiates Polyline objects.
  158.  *
  159.  * Parameters:
  160.  *  None
  161.  */
  162. CPolylineClassFactory::CPolylineClassFactory(void)
  163.     {
  164.     m_cRef=0L;
  165.     return;
  166.     }
  167. /*
  168.  * CPolylineClassFactory::~CPolylineClassFactory
  169.  *
  170.  * Purpose:
  171.  *  Destructor for a CPolylineClassFactory object.  This will be
  172.  *  called when we Release the object to a zero reference count.
  173.  */
  174. CPolylineClassFactory::~CPolylineClassFactory(void)
  175.     {
  176.     return;
  177.     }
  178. /*
  179.  * CPolylineClassFactory::QueryInterface
  180.  * CPolylineClassFactory::AddRef
  181.  * CPolylineClassFactory::Release
  182.  */
  183. STDMETHODIMP CPolylineClassFactory::QueryInterface(REFIID riid
  184.     , PPVOID ppv)
  185.     {
  186.     *ppv=NULL;
  187.     if (IID_IUnknown==riid || IID_IClassFactory==riid)
  188.         *ppv=this;
  189.     if (NULL!=*ppv)
  190.         {
  191.         ((LPUNKNOWN)*ppv)->AddRef();
  192.         return NOERROR;
  193.         }
  194.     return ResultFromScode(E_NOINTERFACE);
  195.     }
  196. STDMETHODIMP_(ULONG) CPolylineClassFactory::AddRef(void)
  197.     {
  198.     return ++m_cRef;
  199.     }
  200. STDMETHODIMP_(ULONG) CPolylineClassFactory::Release(void)
  201.     {
  202.     if (0L!=--m_cRef)
  203.         return m_cRef;
  204.     delete this;
  205.     ObjectDestroyed();
  206.     return 0L;
  207.     }
  208. /*
  209.  * CPolylineClassFactory::CreateInstance
  210.  *
  211.  * Purpose:
  212.  *  Instantiates a Polyline object.
  213.  *
  214.  * Parameters:
  215.  *  pUnkOuter       LPUNKNOWN to the controlling IUnknown if we
  216.  *                  are being used in an aggregation.
  217.  *  riid            REFIID identifying the interface the caller
  218.  *                  desires to have for the new object.
  219.  *  ppvObj          PPVOID in which to store the desired
  220.  *                  interface pointer for the new object.
  221.  *
  222.  * Return Value:
  223.  *  HRESULT         NOERROR if successful, otherwise E_NOINTERFACE
  224.  *                  if we cannot support the requested interface.
  225.  */
  226. STDMETHODIMP CPolylineClassFactory::CreateInstance
  227.     (LPUNKNOWN pUnkOuter, REFIID riid, PPVOID ppvObj)
  228.     {
  229.     PCPolyline          pObj;
  230.     HRESULT             hr;
  231.     *ppvObj=NULL;
  232.     hr=ResultFromScode(E_OUTOFMEMORY);
  233.     //Verify that a controlling unknown asks for IUnknown
  234.     if (NULL!=pUnkOuter && IID_IUnknown!=riid)
  235.         return ResultFromScode(E_NOINTERFACE);
  236.     //Create the object.  This also creates a window.
  237.     pObj=new CPolyline(pUnkOuter, ObjectDestroyed, g_hInst);
  238.     if (NULL==pObj)
  239.         return hr;
  240.     if (pObj->Init())
  241.         hr=pObj->QueryInterface(riid, ppvObj);
  242.     //Kill the object if initial creation or Init failed.
  243.     if (FAILED(hr))
  244.         delete pObj;
  245.     else
  246.         g_cObj++;
  247.     return hr;
  248.     }
  249. /*
  250.  * CPolylineClassFactory::LockServer
  251.  *
  252.  * Purpose:
  253.  *  Increments or decrements the lock count of the DLL.  If the lock
  254.  *  count goes to zero and there are no objects, the DLL is allowed
  255.  *  to unload.  See DllCanUnloadNow.
  256.  *
  257.  * Parameters:
  258.  *  fLock           BOOL specifying whether to increment or
  259.  *                  decrement the lock count.
  260.  *
  261.  * Return Value:
  262.  *  HRESULT         NOERROR always.
  263.  */
  264. STDMETHODIMP CPolylineClassFactory::LockServer(BOOL fLock)
  265.     {
  266.     if (fLock)
  267.         g_cLock++;
  268.     else
  269.         g_cLock--;
  270.     return NOERROR;
  271.     }