[ Home | Syllabus |Course Notes]
Common Object Request Broker Architecture (specification)
HRESULT QueryInterface(REFIID iid, void** ppvObject); ULONG AddRef(void); ULONG Release(void);

// LabObj.h : Declaration of the CLabrador
//
// This is a part of the ActiveX Template Library.
// Copyright (C) 1996 Microsoft Corporation
// All rights reserved.
#include "labres.h" // main symbols
class CLabrador :
public IMammal,
public IDog,
public CComObjectRoot,
public CComCoClass<CLabrador, &CLSID_Labrador> // Template
{
public:
CLabrador();
BEGIN_COM_MAP(CLabrador)
COM_INTERFACE_ENTRY(IMammal)
COM_INTERFACE_ENTRY(IDog)
END_COM_MAP()
DECLARE_NOT_AGGREGATABLE(CLabrador)
DECLARE_REGISTRY(CLabrador, _T("LABRADOR.Labrador.1"), _T("LABRADOR.Labrador.1"), IDS_LABRADOR_DESC, THREADFLAGS_BOTH)
// IDog
STDMETHOD(GetPetName)(MY_BSTR pStr);
STDMETHOD(SetPetName)(MY_BSTR pStr);
STDMETHOD(IsBarking)(BOOL* pBool);
// IMammal
STDMETHOD(GetSpeciesName)(MY_BSTR pStr);
STDMETHOD(IsAlive)(BOOL* pBool);
private:
WCHAR m_szPetName[32];
WCHAR m_szSpeciesName[32];
BOOL m_bIsBarking;
BOOL m_bIsAlive;
};
// LabObj.cpp : Implementation of CLabradorApp and DLL registration.
#include "prelab.h"
#include "Labrador.h"
#include "LabObj.h"
#include <wchar.h>
/////////////////////////////////////////////////////////////////////////////
// CLabrador Interface Implementation
CLabrador::CLabrador()
{
wcscpy(m_szPetName, L"Fido");
wcscpy(m_szSpeciesName, L"Warthog");
m_bIsAlive = TRUE;
m_bIsBarking = FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// IDog Implementation
STDMETHODIMP CLabrador::GetPetName(MY_BSTR pStr)
{
if (pStr)
wcscpy(pStr, m_szPetName);
return (HRESULT)NOERROR;
}
STDMETHODIMP CLabrador::SetPetName(MY_BSTR pStr)
{
if (pStr)
{
wcscpy(m_szPetName, pStr);
return S_OK;
}
return E_POINTER;
}
STDMETHODIMP CLabrador::IsBarking(BOOL* pBool)
{
if (pBool)
{
*pBool = m_bIsBarking;
return S_OK;
}
return E_POINTER;
}
/////////////////////////////////////////////////////////////////////////////
// IMammal Implementation
STDMETHODIMP CLabrador::GetSpeciesName(MY_BSTR pStr)
{
if (pStr != NULL)
wcscpy(pStr, m_szSpeciesName);
return (HRESULT)NOERROR;
}
STDMETHODIMP CLabrador::IsAlive(BOOL* pBool)
{
if (pBool)
{
*pBool = m_bIsAlive;
return S_OK;
}
return E_POINTER;
}
// Labrador.idl : IDL source for Labrador.dll
// This file will be processed by the MIDL tool to
// produce the type library (Labrador.tlb) and marshalling code.
import "unknwn.idl";
#define MAX_MY_BSTR_LEN 32
typedef [string] WCHAR MY_BSTR[MAX_MY_BSTR_LEN];
[
object,
uuid(62A33E75-932A-11CF-B056-00A0C90348FA),
helpstring("IMammal Interface"),
pointer_default(unique)
]
interface IMammal : IUnknown
{
import "oaidl.idl";
HRESULT GetSpeciesName([out, string] MY_BSTR p);
HRESULT IsAlive([out] BOOL* pBool);
};
[
object,
uuid(62A33E76-932A-11CF-B056-00A0C90348FA),
helpstring("IDog Interface"),
pointer_default(unique)
]
interface IDog : IUnknown
{
import "oaidl.idl";
HRESULT GetPetName([out, string] MY_BSTR p);
HRESULT SetPetName([in, string] MY_BSTR p);
HRESULT IsBarking([out] BOOL* pBool);
};
[
uuid(62A33E74-932A-11CF-B056-00A0C90348FA),
version(1.0),
helpstring("Labrador 1.0 Type Library")
]
library LABRADORLib
{
importlib("stdole32.tlb");
[
uuid(62A33E79-932A-11CF-B056-00A0C90348FA),
helpstring("Labrador Class")
]
coclass Labrador
{
[default] interface IMammal;
interface IDog;
};
};
// labdriv.cpp : driver for the Labrador sample
#include "prelabdr.h"
///////////////////////////////////////////////////////////////
// helper to do print traces
void _cdecl Trace(LPCTSTR lpszFormat, ...)
{
va_list args;
va_start(args, lpszFormat);
int nBuf;
TCHAR szBuffer[512];
nBuf = _vstprintf(szBuffer, lpszFormat, args);
_ASSERTE(nBuf < sizeof(szBuffer));
_tprintf(szBuffer);
OutputDebugString(szBuffer);
va_end(args);
}
// helper function to do the work
void _cdecl CallLabrador()
{
WCHAR szTmp[32];
Trace(_T("\nSTARTING\n=============================\n"));
Trace(_T("Calling CoCreateInstance()...\n"));
IUnknown* pUnk = NULL;
HRESULT hRes = CoCreateInstance(CLSID_Labrador, NULL, CLSCTX_LOCAL_SERVER,
IID_IUnknown, (void**)&pUnk);
if (FAILED(hRes))
{
Trace(_T("Failed to create Labrador\n"));
return;
}
Trace(_T("Object created\n"));
IMammal* pMammal = NULL;
hRes = pUnk->QueryInterface(IID_IMammal, (LPVOID*)&pMammal);
pUnk->Release();
if (FAILED(hRes))
{
Trace(_T("QueryInterface() for IMammal failed\n"));
return;
}
Trace(_T("Calling through IMammal methods...\n"));
pMammal->GetSpeciesName(szTmp);
Trace(_T("Species name is <%ls>\n"), szTmp);
BOOL bIsAlive;
pMammal->IsAlive(&bIsAlive);
if (bIsAlive)
Trace(_T("And it's alive!\n"));
else
Trace(_T("And it's dead!\n"));
IDog* pDog = NULL;
hRes = pMammal->QueryInterface(IID_IDog, (void**)&pDog);
pMammal->Release();
if (FAILED(hRes))
{
Trace(_T("QueryInterface() for IDog failed\n"));
return;
}
Trace(_T("Calling through IDog methods...\n"));
BOOL bIsBarking;
pDog->GetPetName(szTmp);
Trace(_T("Dog's name is <%ls>\n"), szTmp);
pDog->IsBarking(&bIsBarking);
if (bIsBarking)
printf("BARK! BARK! BARK! BARK!\n");
pDog->SetPetName(L"KIVA");
pDog->GetPetName(szTmp);
printf("Dog's New name is <%ls>\n", szTmp);
Trace(_T("Releasing Object\n"));
pDog->Release();
Trace(_T("\nDONE!!!\n=============================\n"));
}
int main( int argc, char *argv[ ])
{
if (FAILED(CoInitialize(NULL)))
return -1;
CallLabrador();
#ifdef _DEBUG
_CrtDumpMemoryLeaks();
#endif
CoUninitialize();
return 0;
}