Listing 4: The COMCalc object

//
// COMCalc.cpp
//

#include <iostream.h>
#include <objbase.h>

#include "Iserver.h"      // Interface declarations
#include "Registry.h"   // Registry helper functions

///////////////////////////////////////////////////////////
//
// Global variables
//
static HMODULE g_hModule = NULL ;   // DLL module handle
static long g_cComponents = 0 ;     // Count of active components
static long g_cServerLocks = 0 ;    // Count of locks

// Friendly name of component
const char g_szFriendlyName[] = "COMCalc Server" ;
// Version-independent ProgID
const char g_szVerIndProgID[] = "Example.COMCalc" ;
// ProgID
const char g_szProgID[] = "Example.COMCalc.1" ;

//
// Interface GUID definitions -- same as in client.cpp
// Not shown here
// ...
//
// Component 
//
class CA : public IAddSub,
     public IMulDiv 
{
public:
  // IUnknown
  virtual HRESULT 
    __stdcall QueryInterface(const IID& iid, void** ppv);
  virtual ULONG __stdcall AddRef() ;
  virtual ULONG __stdcall Release() ;

  // Interface IaddSub
  virtual int __stdcall Add(int x,int y)
    { IAddSub_last_result=x+y; return IAddSub_last_result; }
  virtual int __stdcall Subtract(int x,int y)
    { IAddSub_last_result=x-y; return IAddSub_last_result; }
  
  // Interface ImulDiv
  virtual int __stdcall Multiply(int x,int y)
    { IMulDiv_last_result=x*y; return IMulDiv_last_result; }
  virtual int __stdcall Divide(int x,int y)
    { IMulDiv_last_result=x/y; return IMulDiv_last_result; }

  // Constructor
  CA() ;

  // Destructor
  ~CA() ;

private:
  // Reference count
  long m_cRef ;
} ;

//
// Not shown: CA constructor and destructor
// ...
//

//
// IUnknown implementation
//
HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv)
{    
  if (iid == IID_IUnknown)
  {
    *ppv = static_cast<IAddSub*>(this) ; 
  }
  else if (iid == IID_IAddSub)
  {
    *ppv = static_cast<IAddSub*>(this) ;
    cout<<"COMCalc:\t\tReturn pointer to IAddSub.\n" ; 
  }
  else if (iid == IID_IMulDiv)
  {
    *ppv = static_cast<IMulDiv*>(this) ; 
    cout<<"COMCalc:\t\tReturn pointer to IMulDiv.\n" ; 
  }
  else
  {
    *ppv = NULL ;
    return E_NOINTERFACE ;
  }
  reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  return S_OK ;
}

//
// Not shown: CA::AddRef() and CA::Release(), 
// ...
//
//End of File