home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / tutsamp / locserve / server.cpp < prev    next >
C/C++ Source or Header  |  1997-08-05  |  11KB  |  382 lines

  1. /*+==========================================================================
  2.   File:      SERVER.CPP
  3.  
  4.   Summary:   Implementation file for the CServer server-related utility
  5.              C++ object.  This object encapsulates the server's internal
  6.              control of global server object and lock counts.
  7.  
  8.              For a comprehensive tutorial code tour of this module's
  9.              contents and offerings see the tutorial LOCSERVE.HTM file.
  10.              For more specific technical details on the internal workings
  11.              see the comments dispersed throughout the module's source code.
  12.  
  13.   Classes:   CServer.
  14.  
  15.   Functions:
  16.  
  17.   Origin:    11-14-95: atrent - Editor-inheritance from DLLSERVE.CPP in
  18.                the DLLSERVE Tutorial Code Sample.
  19.  
  20. ----------------------------------------------------------------------------
  21.   This file is part of the Microsoft COM Tutorial Code Samples.
  22.  
  23.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  24.  
  25.   This source code is intended only as a supplement to Microsoft
  26.   Development Tools and/or on-line documentation.  See these other
  27.   materials for detailed information regarding Microsoft code samples.
  28.  
  29.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  30.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  31.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  32.   PARTICULAR PURPOSE.
  33. ==========================================================================+*/
  34.  
  35. /*---------------------------------------------------------------------------
  36.   We include WINDOWS.H for all Win32 applications.
  37.   We include OLE2.H because we will be calling the COM/OLE Libraries.
  38.   We include APPUTIL.H because we will be building this EXE using
  39.     the convenient Virtual Window and Dialog classes and other
  40.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  41.   We include MICARS.H and CARGUIDS.H for the common car-related Interface
  42.     class, GUID, and CLSID specifications.
  43.   We include SERVER.H for the object class declarations for the
  44.     C++ CServer server control object.
  45.   We include FACTORY.H because it has the necessary internal class factory
  46.     declarations for this component server.
  47. ---------------------------------------------------------------------------*/
  48. #include <windows.h>
  49. #include <ole2.h>
  50. #include <apputil.h>
  51. #include <micars.h>
  52. #include <carguids.h>
  53. #include "server.h"
  54. #include "factory.h"
  55.  
  56.  
  57. /*---------------------------------------------------------------------------
  58.   Implementation the internal CServer C++ object.  Used to encapsulate
  59.   some server data and the methods for Lock and Object count incrementing
  60.   and decrementing.
  61. ---------------------------------------------------------------------------*/
  62.  
  63. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  64.   Method:   CServer::CServer
  65.  
  66.   Summary:  CServer Constructor.
  67.  
  68.   Args:     void
  69.  
  70.   Modifies: .
  71.  
  72.   Returns:  void
  73. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  74. CServer::CServer(void)
  75. {
  76.   // Zero the Object and Lock counts.
  77.   m_cObjects = 0;
  78.   m_cLocks = 0;
  79.  
  80.   // Zero the cached handles.
  81.   m_hInstServer = NULL;
  82.   m_hWndServer = NULL;
  83.  
  84.   // Zero the Factory references.
  85.   m_pCFCar = NULL;
  86.   m_pCFUtilityCar = NULL;
  87.   m_pCFCruiseCar = NULL;
  88.   m_dwCFCar = 0;
  89.   m_dwCFUtilityCar = 0;
  90.   m_dwCFCruiseCar = 0;
  91.  
  92.   return;
  93. }
  94.  
  95.  
  96. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  97.   Method:   CServer::~CServer
  98.  
  99.   Summary:  CServer Destructor.
  100.  
  101.   Args:     void
  102.  
  103.   Modifies: .
  104.  
  105.   Returns:  void
  106. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  107. CServer::~CServer(void)
  108. {
  109.   return;
  110. }
  111.  
  112.  
  113. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  114.   Method:   CServer::ObjectsUp
  115.  
  116.   Summary:  Increment the Server's living Object count.
  117.  
  118.   Args:     void
  119.  
  120.   Modifies: m_cObjects.
  121.  
  122.   Returns:  void
  123. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  124. void CServer::ObjectsUp(void)
  125. {
  126.   InterlockedIncrement((PLONG) &m_cObjects);
  127.  
  128.   LOGF1("L: CServer::ObjectsUp. New cObjects=%i.", m_cObjects);
  129.  
  130.   return;
  131. }
  132.  
  133.  
  134. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  135.   Method:   CServer::ObjectsDown
  136.  
  137.   Summary:  Decrement the Server's living object count.
  138.  
  139.   Args:     void
  140.  
  141.   Modifies: m_cObjects.
  142.  
  143.   Returns:  void
  144. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  145. void CServer::ObjectsDown(void)
  146. {
  147.   InterlockedDecrement((PLONG) &m_cObjects);
  148.  
  149.   LOGF1("L: CServer::ObjectsDown. New cObjects=%i.", m_cObjects);
  150.  
  151.   // If no more living objects and no locks then shut the server down.
  152.   if (0L == m_cObjects && 0L == m_cLocks && IsWindow(m_hWndServer))
  153.   {
  154.     LOG("L: CServer::ObjectsDown. Closing down LOCSERVE server.");
  155.     // Post a message to this local server's message queue requesting
  156.     // a close of the application.
  157.     PostMessage(m_hWndServer, WM_CLOSE, 0, 0L);
  158.   }
  159.  
  160.   return;
  161. }
  162.  
  163.  
  164. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  165.   Method:   CServer::Lock
  166.  
  167.   Summary:  Increment the Server's Lock count.
  168.  
  169.   Args:     void
  170.  
  171.   Modifies: m_cLocks.
  172.  
  173.   Returns:  void
  174. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  175. void CServer::Lock(void)
  176. {
  177.   InterlockedIncrement((PLONG) &m_cLocks);
  178.  
  179.   LOGF1("L: CServer::Lock. New cLocks=%i.", m_cLocks);
  180.  
  181.   return;
  182. }
  183.  
  184.  
  185. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  186.   Method:   CServer::Unlock
  187.  
  188.   Summary:  Decrement the Server's Lock count.
  189.  
  190.   Args:     void
  191.  
  192.   Modifies: m_cLocks.
  193.  
  194.   Returns:  void
  195. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  196. void CServer::Unlock(void)
  197. {
  198.   InterlockedDecrement((PLONG) &m_cLocks);
  199.  
  200.   LOGF1("L: CServer::Unlock. New cLocks=%i.", m_cLocks);
  201.  
  202.   // Use ObjectsDown to force a server shutdown if this unlock warrants it.
  203.   InterlockedIncrement((PLONG) &m_cObjects);
  204.   ObjectsDown();
  205.  
  206.   return;
  207. }
  208.  
  209.  
  210. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  211.   Method:   CServer::OpenFactories
  212.  
  213.   Summary:  Create and register all of this server's class factories.
  214.  
  215.   Args:     void
  216.  
  217.   Modifies: m_pCFCar, m_pCFUtilityCar, m_pCFCruiseCar,
  218.             m_dwCFCar, m_dwCFUtilityCar, m_dwCFCruiseCar.
  219.  
  220.   Returns:  BOOL
  221.               TRUE if success; FALSE if not
  222. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  223. BOOL CServer::OpenFactories(void)
  224. {
  225.   BOOL bOk = FALSE;
  226.   HRESULT hr;
  227.  
  228.   LOG("L: CServer::OpenFactories. Begin.");
  229.  
  230.   // Build and register the LocCar factory.
  231.   m_pCFCar = new CFCar(NULL, this);
  232.   if (NULL != m_pCFCar)
  233.   {
  234.     // AddRef this cached pointer to the Class Factory.
  235.     m_pCFCar->AddRef();
  236.  
  237.     // Now register this class factory with COM.
  238.     hr = CoRegisterClassObject(
  239.            CLSID_LocCar,
  240.            m_pCFCar,
  241.            CLSCTX_LOCAL_SERVER,
  242.            REGCLS_MULTIPLEUSE,
  243.            &m_dwCFCar);
  244.  
  245.     bOk = SUCCEEDED(hr);
  246.     if (!bOk)
  247.     {
  248.       LOGF1("L: CServer::OpenFactories. CFCar failed. hr=0x%X.", hr);
  249.       // If can't register factory then clean up for server exit.
  250.       m_pCFCar->Release();
  251.       DELETE_POINTER(m_pCFCar);
  252.     }
  253.   }
  254.   else
  255.     bOk = FALSE;
  256.  
  257.   // Build and register the LocUtilityCar factory.
  258.   if (bOk)
  259.   {
  260.     m_pCFUtilityCar = new CFUtilityCar(NULL, this);
  261.     if (NULL != m_pCFUtilityCar)
  262.     {
  263.       // AddRef this cached pointer to the Class Factory.
  264.       m_pCFUtilityCar->AddRef();
  265.  
  266.       // Now register this class factory with COM.
  267.       hr = CoRegisterClassObject(
  268.              CLSID_LocUtilityCar,
  269.              m_pCFUtilityCar,
  270.              CLSCTX_LOCAL_SERVER,
  271.              REGCLS_MULTIPLEUSE,
  272.              &m_dwCFUtilityCar);
  273.  
  274.       bOk = SUCCEEDED(hr);
  275.       if (!bOk)
  276.       {
  277.         LOGF1("L: CServer::OpenFactories. CFUtilityCar failed. hr=0x%X.", hr);
  278.         // If can't register factory then clean up for server exit.
  279.         m_pCFUtilityCar->Release();
  280.         DELETE_POINTER(m_pCFUtilityCar);
  281.       }
  282.     }
  283.     else
  284.       bOk = FALSE;
  285.   }
  286.  
  287.   // Build and register the LocCruiseCar factory.
  288.   if (bOk)
  289.   {
  290.     m_pCFCruiseCar = new CFCruiseCar(NULL, this);
  291.     if (NULL != m_pCFCruiseCar)
  292.     {
  293.       // AddRef this cached pointer to the Class Factory.
  294.       m_pCFCruiseCar->AddRef();
  295.  
  296.       // Now register this class factory with COM.
  297.       hr = CoRegisterClassObject(
  298.              CLSID_LocCruiseCar,
  299.              m_pCFCruiseCar,
  300.              CLSCTX_LOCAL_SERVER,
  301.              REGCLS_MULTIPLEUSE,
  302.              &m_dwCFCruiseCar);
  303.  
  304.       bOk = SUCCEEDED(hr);
  305.       if (!bOk)
  306.       {
  307.         LOGF1("L: CServer::OpenFactories. CFCruiseCar failed. hr=0x%X.", hr);
  308.         // If can't register factory then clean up for server exit.
  309.         m_pCFCruiseCar->Release();
  310.         DELETE_POINTER(m_pCFCruiseCar);
  311.       }
  312.     }
  313.     else
  314.       bOk = FALSE;
  315.   }
  316.  
  317.   LOG("L: CServer::OpenFactories. End.");
  318.  
  319.   return bOk;
  320. }
  321.  
  322.  
  323. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  324.   Method:   CServer::CloseFactories
  325.  
  326.   Summary:  Revoke (ie, unregister) and delete all the server's class
  327.             factories.
  328.  
  329.   Args:     void
  330.  
  331.   Modifies: m_pCFCar, m_pCFUtilityCar, m_pCFCruiseCar.
  332.  
  333.   Returns:  BOOL
  334.               TRUE if success; FALSE if not
  335. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  336. BOOL CServer::CloseFactories(void)
  337. {
  338.   BOOL bOk = TRUE;
  339.   HRESULT hr;
  340.  
  341.   LOG("L: CServer::CloseFactories. Begin.");
  342.  
  343.   // Unregister the LocCar class factory with COM.
  344.   if (0 != m_dwCFCar)
  345.   {
  346.     LOG("L: CServer::CloseFactories. Revoke CFCar.");
  347.     hr = CoRevokeClassObject(m_dwCFCar);
  348.     if (FAILED(hr))
  349.       bOk = FALSE;
  350.   }
  351.  
  352.   // Unregister the LocUtilityCar class factory with COM.
  353.   if (0 != m_dwCFCar)
  354.   {
  355.     LOG("L: CServer::CloseFactories. Revoke CFUtilityCar.");
  356.     hr = CoRevokeClassObject(m_dwCFUtilityCar);
  357.     if (FAILED(hr))
  358.       bOk = FALSE;
  359.   }
  360.  
  361.   // Unregister the LocCruiseCar class factory with COM.
  362.   if (0 != m_dwCFCar)
  363.   {
  364.     LOG("L: CServer::CloseFactories. Revoke CFCruiseCar.");
  365.     hr = CoRevokeClassObject(m_dwCFCruiseCar);
  366.     if (FAILED(hr))
  367.       bOk = FALSE;
  368.   }
  369.  
  370.   // Release any and all of the Class Factory interface pointers.
  371.   LOG("L: CServer::CloseFactories. Release all factory interfaces.");
  372.   RELEASE_INTERFACE(m_pCFCar);
  373.   RELEASE_INTERFACE(m_pCFUtilityCar);
  374.   RELEASE_INTERFACE(m_pCFCruiseCar);
  375.  
  376.   LOG("L: CServer::CloseFactories. End.");
  377.  
  378.   return bOk;
  379. }
  380.  
  381. // =============================== END ======================================
  382.