  | 
   COM Tutorial Code 
   Submitted by  |   
  
  
I recently wrote this very simple/fast COM tutorial, since many wondered how
you do multiple implementations of the same interface like for having
different renders etc.
 | 
 
 
 
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/COMTest/COMTest.cpp] - (1,269 bytes)
 
 // COMTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
  // Include com api
#include <objbase.h>
  // Include interface (That's all we need. COM needs no libs :)
#include "..\include\icoolrender.h"
  // Create usefull release macro
#define COM_SAFE_RELEASE(x) if (x != NULL) x->Release(); x = NULL
  // Create cool render pointer
ICoolRender * pAnyRender = NULL;
  int main(int argc, char* argv[])
{
	
	// Initialize COM
	CoInitialize(NULL);
	
	// First try the DirectX8 render
	if (FAILED(GetDirectX8Render(pAnyRender)))
	{
		MessageBox(NULL, "Make sure DirectX8 render component is installed", "ERROR!", MB_ICONERROR|MB_OK);
		return 1;
	}
  	// Run function
	pAnyRender->DoCool3DGame();
  	// Relase again. This is important or COM component won't get unloaded!
	COM_SAFE_RELEASE(pAnyRender);
  	// Try OpenGL render
	if (FAILED(GetOpenGLRender(pAnyRender)))
	{
		MessageBox(NULL, "Make sure OpenGL render component is installed", "ERROR!", MB_ICONERROR|MB_OK);
		return 1;
	}
  	// Run function
	pAnyRender->DoCool3DGame();
  	// Relase again. This is important or COM component won't get unloaded!
	COM_SAFE_RELEASE(pAnyRender);
	
	// Release COM
	CoUninitialize();
	
	return 0;
}
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/COMTest/StdAfx.cpp] - (294 bytes)
 
 // stdafx.cpp : source file that includes just the standard includes
//	COMTest.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
  // TODO: reference any additional headers you need in STDAFX.H
// and not in this file
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/COMTest/StdAfx.h] - (667 bytes)
 
 // stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//
#if !defined(AFX_STDAFX_H__40807C4B_690F_4E33_B669_63E6591DEE83__INCLUDED_)
#define AFX_STDAFX_H__40807C4B_690F_4E33_B669_63E6591DEE83__INCLUDED_
  #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
  // TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__40807C4B_690F_4E33_B669_63E6591DEE83__INCLUDED_)
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/DirectX8Render/DirectX8Render.cpp] - (5,920 bytes)
 
 // DirectX8Render1.cpp: implementation of the CDirectX8Render class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DirectX8Render.h"
  // Include shared registry handling
#include "..\shared\Registry.h"   
  ///////////////////////////////////////////////////////////
//
// 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[] = "CoolRender DirectX8 component";
  // Version-independent ProgID
const char g_szVerIndProgID[] = "CoolRender.DirectX8";
  // ProgID
const char g_szProgID[] = "CoolRender.DirectX8.1";
  //////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDirectX8Render::CDirectX8Render() : m_cRef(1)
{
	// Exclusive increment (COM stuff)
	InterlockedIncrement(&g_cComponents); 
}
  CDirectX8Render::~CDirectX8Render()
{
	// Exclusive decrement (COM stuff)
	InterlockedDecrement(&g_cComponents); 
}
  // Our only function
void CDirectX8Render::DoCool3DGame()
{
	MessageBox(NULL, "Hello from the DirectX8 render!", "Render", MB_ICONINFORMATION|MB_OK);
}
  // *** COM Stuff here ***
//
// IUnknown implementation
//
HRESULT __stdcall CDirectX8Render::QueryInterface(const IID& iid, void** ppv)
{    
	if (iid == IID_IUnknown)
	{
		*ppv = static_cast<ICoolRender*>(this) ; 
	}
	else if (iid == IID_DIRECTX8RENDER)
	{
		*ppv = static_cast<ICoolRender*>(this) ;
	}
	else
	{
		*ppv = NULL ;
		return E_NOINTERFACE ;
	}
	reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
	return S_OK ;
}
  ULONG __stdcall CDirectX8Render::AddRef()
{
	return InterlockedIncrement(&m_cRef) ;
}
  ULONG __stdcall CDirectX8Render::Release() 
{
	if (InterlockedDecrement(&m_cRef) == 0)
	{
		delete this ;
		return 0 ;
	}
	return m_cRef ;
}
  
///////////////////////////////////////////////////////////
//
// Class factory
//
class CFactory : public IClassFactory
{
public:
	// IUnknown
	virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;         
	virtual ULONG   __stdcall AddRef() ;
	virtual ULONG   __stdcall Release() ;
  	// Interface IClassFactory
	virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,
	                                         const IID& iid,
	                                         void** ppv) ;
	virtual HRESULT __stdcall LockServer(BOOL bLock) ; 
  	// Constructor
	CFactory() : m_cRef(1) {}
  	// Destructor
	~CFactory() {}
  private:
	long m_cRef ;
} ;
  //
// Class factory IUnknown implementation
//
HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv)
{    
	if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
	{
		*ppv = static_cast<IClassFactory*>(this) ; 
	}
	else
	{
		*ppv = NULL ;
		return E_NOINTERFACE ;
	}
	reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
	return S_OK ;
}
  ULONG __stdcall CFactory::AddRef()
{
	return InterlockedIncrement(&m_cRef) ;
}
  ULONG __stdcall CFactory::Release() 
{
	if (InterlockedDecrement(&m_cRef) == 0)
	{
		delete this ;
		return 0 ;
	}
	return m_cRef ;
}
  //
// IClassFactory implementation
//
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
                                           const IID& iid,
                                           void** ppv) 
{
  	// Cannot aggregate.
	if (pUnknownOuter != NULL)
	{
		return CLASS_E_NOAGGREGATION ;
	}
  	// Create component.
	CDirectX8Render* pA = new CDirectX8Render ;
	if (pA == NULL)
	{
		return E_OUTOFMEMORY ;
	}
  	// Get the requested interface.
	HRESULT hr = pA->QueryInterface(iid, ppv) ;
  	// Release the IUnknown pointer.
	// (If QueryInterface failed, component will delete itself.)
	pA->Release() ;
	return hr ;
}
  // LockServer
HRESULT __stdcall CFactory::LockServer(BOOL bLock) 
{
	if (bLock)
	{
		InterlockedIncrement(&g_cServerLocks) ; 
	}
	else
	{
		InterlockedDecrement(&g_cServerLocks) ;
	}
	return S_OK ;
}
  // * * * Exported functions * * *
//
// Server registration
//
STDAPI DllRegisterServer()
{
	return RegisterServer(g_hModule, 
	                      CLSID_DIRECTX8RENDER,
	                      g_szFriendlyName,
	                      g_szVerIndProgID,
	                      g_szProgID) ;
}
  
//
// Server unregistration
//
STDAPI DllUnregisterServer()
{
	return UnregisterServer(CLSID_DIRECTX8RENDER,
	                        g_szVerIndProgID,
	                        g_szProgID) ;
}
  ///////////////////////////////////////////////////////////
//
// DLL module information
//
BOOL APIENTRY DllMain(HANDLE hModule,
                      DWORD dwReason,
                      void* lpReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		g_hModule = (struct HINSTANCE__ *)hModule ;
	}
	return TRUE;
}
  //
// Can DLL unload now?
//
STDAPI DllCanUnloadNow()
{
	if ((g_cComponents == 0) && (g_cServerLocks == 0))
	{
		return S_OK ;
	}
	else
	{
		return S_FALSE ;
	}
}
  //
// Get class factory
//
STDAPI DllGetClassObject(const CLSID& clsid,
                         const IID& iid,
                         void** ppv)
{
	
	// Can we create this component?
	if (clsid != CLSID_DIRECTX8RENDER)
	{
		return CLASS_E_CLASSNOTAVAILABLE ;
	}
  	// Create class factory.
	CFactory* pFactory = new CFactory ;  // Reference count set to 1
	                                     // in constructor
	if (pFactory == NULL)
	{
		return E_OUTOFMEMORY ;
	}
  	// Get requested interface.
	HRESULT hr = pFactory->QueryInterface(iid, ppv) ;
	pFactory->Release() ;
  	return hr ;
}
 
 
 
 
     |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/DirectX8Render/DirectX8Render.h] - (1,107 bytes)
 
 // DirectX8Render.h: interface for the CDirectX8Render class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DIRECTX8RENDER1_H__CA9AE665_9168_47A1_BCD9_BF258FF535B0__INCLUDED_)
#define AFX_DIRECTX8RENDER1_H__CA9AE665_9168_47A1_BCD9_BF258FF535B0__INCLUDED_
  #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Include interface
#include "..\include\ICoolRender.h"
  // Make class that inherits from the cool render interface.
// This is the actual implementation
class CDirectX8Render : public ICoolRender
{
public:
	
	// Needed to implement IUnknown used by COM to acces your component
	virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv);
	virtual ULONG __stdcall AddRef();
	virtual ULONG __stdcall Release();
	
	// Constructor
	CDirectX8Render();
	
	// Destructor
	virtual ~CDirectX8Render();
  	// Our only function
	void DoCool3DGame();
  private:
  	long m_cRef; // Reference count for component
};
  #endif // !defined(AFX_DIRECTX8RENDER1_H__CA9AE665_9168_47A1_BCD9_BF258FF535B0__INCLUDED_)
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/DirectX8Render/StdAfx.cpp] - (301 bytes)
 
 // stdafx.cpp : source file that includes just the standard includes
//	DirectX8Render.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
  // TODO: reference any additional headers you need in STDAFX.H
// and not in this file
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/DirectX8Render/StdAfx.h] - (802 bytes)
 
 // stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//
#if !defined(AFX_STDAFX_H__1009A526_1E5F_47A9_A98F_9F99904E3B6A__INCLUDED_)
#define AFX_STDAFX_H__1009A526_1E5F_47A9_A98F_9F99904E3B6A__INCLUDED_
  #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
  // Insert your headers here
#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#include <windows.h>
  // TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__1009A526_1E5F_47A9_A98F_9F99904E3B6A__INCLUDED_)
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/Include/ICoolRender.h] - (470 bytes)
 
 // Shared interface for the CoolRender (tm) interface
// COM tutorial by odin@nukesoftware.com
// Use as you please :)
// Include com API (IUnknown etc)
#include <objbase.h>
  // Include possible render GUIDS + their construction macros
#include "RenderGUIDS.h"
  // Render interface. Derives from IUnknown. (Don't be scared by interface. It's just a struct :)
interface ICoolRender : IUnknown
{
	// Our only function
	virtual void DoCool3DGame() = 0;
};
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/Include/RenderGUIDS.h] - (1,387 bytes)
 
 // Render GUIDS the CoolRender (tm) interface
// COM tutorial by odin@nukesoftware.com
// Use as you please :)
// NOTE : GUIDS are generated with "Microsoft Visual Studio\Common\Tools\GUIDGEN.EXE"
// DirectX8 render
// Interface identifier
// {FDB516F0-2086-402d-9276-79F867925BA4}
static const IID IID_DIRECTX8RENDER = 
{ 0xfdb516f0, 0x2086, 0x402d, { 0x92, 0x76, 0x79, 0xf8, 0x67, 0x92, 0x5b, 0xa4 } };
  // Class identifier
// {B037CE71-3A01-4cda-8334-FA6096CA1C3D}
static const CLSID CLSID_DIRECTX8RENDER = 
{ 0xb037ce71, 0x3a01, 0x4cda, { 0x83, 0x34, 0xfa, 0x60, 0x96, 0xca, 0x1c, 0x3d } };
  // OpenGL render
// Interface identifier
// {FE01952B-8278-48c9-B3EA-7B9187219F9A}
static const IID IID_OPENGLRENDER = 
{ 0xfe01952b, 0x8278, 0x48c9, { 0xb3, 0xea, 0x7b, 0x91, 0x87, 0x21, 0x9f, 0x9a } };
  // Class identifier
// {BD38F132-DEB2-4677-9CD2-570EED2CE5FE}
static const CLSID CLSID_OPENGLRENDER = 
{ 0xbd38f132, 0xdeb2, 0x4677, { 0x9c, 0xd2, 0x57, 0xe, 0xed, 0x2c, 0xe5, 0xfe } };
  // Macro for easy creation of DirectX Render
#define GetDirectX8Render(pRender) ::CoCreateInstance(CLSID_DIRECTX8RENDER, NULL, CLSCTX_INPROC_SERVER, IID_DIRECTX8RENDER, (void**)&pRender)
  // Macro for easy creation of OpenGL Render
#define GetOpenGLRender(pRender) ::CoCreateInstance(CLSID_OPENGLRENDER, NULL, CLSCTX_INPROC_SERVER, IID_OPENGLRENDER, (void**)&pRender)  |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/OpenGLRender/OpenGLRender.cpp] - (5,880 bytes)
 
 // OpenGLRender1.cpp: implementation of the COpenGLRender class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "OpenGLRender.h"
  // Include shared registry handling
#include "..\shared\Registry.h"   
  ///////////////////////////////////////////////////////////
//
// 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[] = "CoolRender OpenGL component";
  // Version-independent ProgID
const char g_szVerIndProgID[] = "CoolRender.OpenGL";
  // ProgID
const char g_szProgID[] = "CoolRender.OpenGL.1";
  // Our only function
void COpenGLRender::DoCool3DGame()
{
	MessageBox(NULL, "Hello from the OpenGL render!", "Render", MB_ICONINFORMATION|MB_OK);
}
  //////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
COpenGLRender::COpenGLRender() : m_cRef(1)
{
	// Exclusive increment (COM stuff)
	InterlockedIncrement(&g_cComponents); 
}
  COpenGLRender::~COpenGLRender()
{
	// Exclusive decrement (COM stuff)
	InterlockedDecrement(&g_cComponents); 
}
  // *** COM Stuff here ***
//
// IUnknown implementation
//
HRESULT __stdcall COpenGLRender::QueryInterface(const IID& iid, void** ppv)
{    
	if (iid == IID_IUnknown)
	{
		*ppv = static_cast<ICoolRender*>(this) ; 
	}
	else if (iid == IID_OPENGLRENDER)
	{
		*ppv = static_cast<ICoolRender*>(this) ;
	}
	else
	{
		*ppv = NULL ;
		return E_NOINTERFACE ;
	}
	reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
	return S_OK ;
}
  ULONG __stdcall COpenGLRender::AddRef()
{
	return InterlockedIncrement(&m_cRef) ;
}
  ULONG __stdcall COpenGLRender::Release() 
{
	if (InterlockedDecrement(&m_cRef) == 0)
	{
		delete this ;
		return 0 ;
	}
	return m_cRef ;
}
  
///////////////////////////////////////////////////////////
//
// Class factory
//
class CFactory : public IClassFactory
{
public:
	// IUnknown
	virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;         
	virtual ULONG   __stdcall AddRef() ;
	virtual ULONG   __stdcall Release() ;
  	// Interface IClassFactory
	virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,
	                                         const IID& iid,
	                                         void** ppv) ;
	virtual HRESULT __stdcall LockServer(BOOL bLock) ; 
  	// Constructor
	CFactory() : m_cRef(1) {}
  	// Destructor
	~CFactory() {}
  private:
	long m_cRef ;
} ;
  //
// Class factory IUnknown implementation
//
HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv)
{    
	if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
	{
		*ppv = static_cast<IClassFactory*>(this) ; 
	}
	else
	{
		*ppv = NULL ;
		return E_NOINTERFACE ;
	}
	reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
	return S_OK ;
}
  ULONG __stdcall CFactory::AddRef()
{
	return InterlockedIncrement(&m_cRef) ;
}
  ULONG __stdcall CFactory::Release() 
{
	if (InterlockedDecrement(&m_cRef) == 0)
	{
		delete this ;
		return 0 ;
	}
	return m_cRef ;
}
  //
// IClassFactory implementation
//
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
                                           const IID& iid,
                                           void** ppv) 
{
  	// Cannot aggregate.
	if (pUnknownOuter != NULL)
	{
		return CLASS_E_NOAGGREGATION ;
	}
  	// Create component.
	COpenGLRender* pA = new COpenGLRender ;
	if (pA == NULL)
	{
		return E_OUTOFMEMORY ;
	}
  	// Get the requested interface.
	HRESULT hr = pA->QueryInterface(iid, ppv) ;
  	// Release the IUnknown pointer.
	// (If QueryInterface failed, component will delete itself.)
	pA->Release() ;
	return hr ;
}
  // LockServer
HRESULT __stdcall CFactory::LockServer(BOOL bLock) 
{
	if (bLock)
	{
		InterlockedIncrement(&g_cServerLocks) ; 
	}
	else
	{
		InterlockedDecrement(&g_cServerLocks) ;
	}
	return S_OK ;
}
  // * * * Exported functions * * *
//
// Server registration
//
STDAPI DllRegisterServer()
{
	return RegisterServer(g_hModule, 
	                      CLSID_OPENGLRENDER,
	                      g_szFriendlyName,
	                      g_szVerIndProgID,
	                      g_szProgID) ;
}
  
//
// Server unregistration
//
STDAPI DllUnregisterServer()
{
	return UnregisterServer(CLSID_OPENGLRENDER,
	                        g_szVerIndProgID,
	                        g_szProgID) ;
}
  ///////////////////////////////////////////////////////////
//
// DLL module information
//
BOOL APIENTRY DllMain(HANDLE hModule,
                      DWORD dwReason,
                      void* lpReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		g_hModule = (struct HINSTANCE__ *)hModule ;
	}
	return TRUE;
}
  //
// Can DLL unload now?
//
STDAPI DllCanUnloadNow()
{
	if ((g_cComponents == 0) && (g_cServerLocks == 0))
	{
		return S_OK ;
	}
	else
	{
		return S_FALSE ;
	}
}
  //
// Get class factory
//
STDAPI DllGetClassObject(const CLSID& clsid,
                         const IID& iid,
                         void** ppv)
{
	
	// Can we create this component?
	if (clsid != CLSID_OPENGLRENDER)
	{
		return CLASS_E_CLASSNOTAVAILABLE ;
	}
  	// Create class factory.
	CFactory* pFactory = new CFactory ;  // Reference count set to 1
	                                     // in constructor
	if (pFactory == NULL)
	{
		return E_OUTOFMEMORY ;
	}
  	// Get requested interface.
	HRESULT hr = pFactory->QueryInterface(iid, ppv) ;
	pFactory->Release() ;
  	return hr ;
}
 
 
 
 
  
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/OpenGLRender/OpenGLRender.h] - (1,079 bytes)
 
 // OpenGLRender.h: interface for the COpenGLRender class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_OPENGLRENDER1_H__EE377BF3_CF74_4A3C_851F_04523308980B__INCLUDED_)
#define AFX_OPENGLRENDER1_H__EE377BF3_CF74_4A3C_851F_04523308980B__INCLUDED_
  #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Include interface
#include "..\include\ICoolRender.h"
  // Make class that inherits from the cool render interface.
// This is the actual implementation
class COpenGLRender : public ICoolRender
{
public:
	
	// Needed to implement IUnknown used by COM to acces your component
	virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv);
	virtual ULONG __stdcall AddRef();
	virtual ULONG __stdcall Release();
	
	// Constructor
	COpenGLRender();
	
	// Destructor
	virtual ~COpenGLRender();
  	// Our only function
	void DoCool3DGame();
  private:
  	// Reference counter
	long m_cRef;
};
  #endif // !defined(AFX_OPENGLRENDER1_H__EE377BF3_CF74_4A3C_851F_04523308980B__INCLUDED_)
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/OpenGLRender/StdAfx.cpp] - (299 bytes)
 
 // stdafx.cpp : source file that includes just the standard includes
//	OpenGLRender.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
  // TODO: reference any additional headers you need in STDAFX.H
// and not in this file
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/OpenGLRender/StdAfx.h] - (802 bytes)
 
 // stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//
#if !defined(AFX_STDAFX_H__647553AE_49DA_44B1_A8E3_49257E2B5875__INCLUDED_)
#define AFX_STDAFX_H__647553AE_49DA_44B1_A8E3_49257E2B5875__INCLUDED_
  #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
  // Insert your headers here
#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#include <windows.h>
  // TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__647553AE_49DA_44B1_A8E3_49257E2B5875__INCLUDED_)
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/Shared/REGISTRY.CPP] - (6,381 bytes)
 
 //
// Registry.cpp
//
#include <objbase.h>
#include <assert.h>
  #include "Registry.h"
  ////////////////////////////////////////////////////////
//
// Internal helper functions prototypes
//
// Set the given key and its value.
BOOL setKeyAndValue(const char* pszPath,
                    const char* szSubkey,
                    const char* szValue) ;
  // Convert a CLSID into a char string.
void CLSIDtochar(const CLSID& clsid, 
                 char* szCLSID,
                 int length) ;
  // Delete szKeyChild and all of its descendents.
LONG recursiveDeleteKey(HKEY hKeyParent, const char* szKeyChild) ;
  ////////////////////////////////////////////////////////
//
// Constants
//
// Size of a CLSID as a string
const int CLSID_STRING_SIZE = 39 ;
  /////////////////////////////////////////////////////////
//
// Public function implementation
//
//
// Register the component in the registry.
//
HRESULT RegisterServer(HMODULE hModule,            // DLL module handle
                       const CLSID& clsid,         // Class ID
                       const char* szFriendlyName, // Friendly Name
                       const char* szVerIndProgID, // Programmatic
                       const char* szProgID)       //   IDs
{
	// Get server location.
	char szModule[512] ;
	DWORD dwResult =
		::GetModuleFileName(hModule, 
		                    szModule,
		                    sizeof(szModule)/sizeof(char)) ;
	assert(dwResult != 0) ;
  	// Convert the CLSID into a char.
	char szCLSID[CLSID_STRING_SIZE] ;
	CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;
  	// Build the key CLSID\\{...}
	char szKey[64] ;
	strcpy(szKey, "CLSID\\") ;
	strcat(szKey, szCLSID) ;
  
	// Add the CLSID to the registry.
	setKeyAndValue(szKey, NULL, szFriendlyName) ;
  	// Add the server filename subkey under the CLSID key.
	setKeyAndValue(szKey, "InprocServer32", szModule) ;
  	// Add the ProgID subkey under the CLSID key.
	setKeyAndValue(szKey, "ProgID", szProgID) ;
  	// Add the version-independent ProgID subkey under CLSID key.
	setKeyAndValue(szKey, "VersionIndependentProgID",
	               szVerIndProgID) ;
  	// Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
	setKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ; 
	setKeyAndValue(szVerIndProgID, "CLSID", szCLSID) ;
	setKeyAndValue(szVerIndProgID, "CurVer", szProgID) ;
  	// Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
	setKeyAndValue(szProgID, NULL, szFriendlyName) ; 
	setKeyAndValue(szProgID, "CLSID", szCLSID) ;
  	return S_OK ;
}
  //
// Remove the component from the registry.
//
LONG UnregisterServer(const CLSID& clsid,         // Class ID
                      const char* szVerIndProgID, // Programmatic
                      const char* szProgID)       //   IDs
{
	// Convert the CLSID into a char.
	char szCLSID[CLSID_STRING_SIZE] ;
	CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;
  	// Build the key CLSID\\{...}
	char szKey[64] ;
	strcpy(szKey, "CLSID\\") ;
	strcat(szKey, szCLSID) ;
  	// Delete the CLSID Key - CLSID\{...}
	LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
	assert((lResult == ERROR_SUCCESS) ||
	       (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
	// Delete the version-independent ProgID Key.
	lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ;
	assert((lResult == ERROR_SUCCESS) ||
	       (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
	// Delete the ProgID key.
	lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ;
	assert((lResult == ERROR_SUCCESS) ||
	       (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
	return S_OK ;
}
  ///////////////////////////////////////////////////////////
//
// Internal helper functions
//
// Convert a CLSID to a char string.
void CLSIDtochar(const CLSID& clsid,
                 char* szCLSID,
                 int length)
{
	assert(length >= CLSID_STRING_SIZE) ;
	// Get CLSID
	LPOLESTR wszCLSID = NULL ;
	HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
	assert(SUCCEEDED(hr)) ;
  	// Covert from wide characters to non-wide.
	wcstombs(szCLSID, wszCLSID, length) ;
  	// Free memory.
	CoTaskMemFree(wszCLSID) ;
}
  //
// Delete a key and all of its descendents.
//
LONG recursiveDeleteKey(HKEY hKeyParent,           // Parent of key to delete
                        const char* lpszKeyChild)  // Key to delete
{
	// Open the child.
	HKEY hKeyChild ;
	LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
	                         KEY_ALL_ACCESS, &hKeyChild) ;
	if (lRes != ERROR_SUCCESS)
	{
		return lRes ;
	}
  	// Enumerate all of the decendents of this child.
	FILETIME time ;
	char szBuffer[256] ;
	DWORD dwSize = 256 ;
	while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
	                    NULL, NULL, &time) == S_OK)
	{
		// Delete the decendents of this child.
		lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
		if (lRes != ERROR_SUCCESS)
		{
			// Cleanup before exiting.
			RegCloseKey(hKeyChild) ;
			return lRes;
		}
		dwSize = 256 ;
	}
  	// Close the child.
	RegCloseKey(hKeyChild) ;
  	// Delete this child.
	return RegDeleteKey(hKeyParent, lpszKeyChild) ;
}
  //
// Create a key and set its value.
//   - This helper function was borrowed and modifed from
//     Kraig Brockschmidt's book Inside OLE.
//
BOOL setKeyAndValue(const char* szKey,
                    const char* szSubkey,
                    const char* szValue)
{
	HKEY hKey;
	char szKeyBuf[1024] ;
  	// Copy keyname into buffer.
	strcpy(szKeyBuf, szKey) ;
  	// Add subkey name to buffer.
	if (szSubkey != NULL)
	{
		strcat(szKeyBuf, "\\") ;
		strcat(szKeyBuf, szSubkey ) ;
	}
  	// Create and open key and subkey.
	long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
	                              szKeyBuf, 
	                              0, NULL, REG_OPTION_NON_VOLATILE,
	                              KEY_ALL_ACCESS, NULL, 
	                              &hKey, NULL) ;
	if (lResult != ERROR_SUCCESS)
	{
		return FALSE ;
	}
  	// Set the Value.
	if (szValue != NULL)
	{
		RegSetValueEx(hKey, NULL, 0, REG_SZ, 
		              (BYTE *)szValue, 
		              strlen(szValue)+1) ;
	}
  	RegCloseKey(hKey) ;
	return TRUE ;
}
   |  
  
 | 
 
  
Currently browsing [COMTutorial.zip] (184,818 bytes) - [COMTutorial/Shared/REGISTRY.H] - (799 bytes)
 
 #ifndef __Registry_H__
#define __Registry_H__
//
// Registry.h
//   - Helper functions registering and unregistering a component.
//
// This function will register a component in the Registry.
// The component calls this function from its DllRegisterServer function.
HRESULT RegisterServer(HMODULE hModule, 
                       const CLSID& clsid, 
                       const char* szFriendlyName,
                       const char* szVerIndProgID,
                       const char* szProgID) ;
  // This function will unregister a component.  Components
// call this function from their DllUnregisterServer function.
HRESULT UnregisterServer(const CLSID& clsid,
                         const char* szVerIndProgID,
                         const char* szProgID) ;
  #endif  |  
  
 | 
 
 
 
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
 
 
 |