// inproc.cpp : Defines the class behaviors for the application.
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1993 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and Microsoft
// QuickHelp and/or WinHelp documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"
#include "inproc.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CInProcApp

BEGIN_MESSAGE_MAP(CInProcApp, CWinApp)
	//{{AFX_MSG_MAP(CInProcApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CInProcApp construction

CInProcApp::CInProcApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CInProcApp object

CInProcApp NEAR theApp;

/////////////////////////////////////////////////////////////////////////////
// CInProcApp initialization

BOOL CInProcApp::InitInstance()
{
#ifndef _USRDLL
	if (!RunEmbedded() && !RunAutomated())
	{
		Enable3dControls();

		COleObjectFactory::UpdateRegistryAll();

		AfxMessageBox(IDP_CANT_RUN_STANDALONE);
		return FALSE;
	}

	// Initialize OLE libraries
	if (!AfxOleInit())
	{
		Enable3dControls();

		AfxMessageBox(IDP_OLE_INIT_FAILED);
		return FALSE;
	}
#endif

	// Register all OLE server (factories) as running.  This enables the
	//  OLE libraries to create objects from other applications.
	COleObjectFactory::RegisterAll();

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// Special entry points required for inproc servers

#ifdef _USRDLL
#if (_MFC_VER >= 0x300)
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
	return AfxDllGetClassObject(rclsid, riid, ppv);
}

STDAPI DllCanUnloadNow(void)
{
	return AfxDllCanUnloadNow();
}
#endif

// by exporting DllRegisterServer, you can use regsvr.exe
STDAPI DllRegisterServer(void)
{
	COleObjectFactory::UpdateRegistryAll();
	return S_OK;
}
#endif //_USRDLL

/////////////////////////////////////////////////////////////////////////////
// CVariant helper class

CVariant::CVariant(const VARIANT& that)
{
	VariantInit(this);
	VariantCopy(this, (LPVARIANT)&that);
}

#ifndef WIN32
// SysStringByteLen is a new API in 32-bit OLE.  It is (for the most part)
// equivalent to SysStringLen in 16-bit OLE.
#define SysStringByteLen SysStringLen
#endif

BOOL CVariant::operator==(const VARIANT& that) const
{
	if (&that == this)
		return TRUE;

	if (that.vt != vt)
		return FALSE;

	switch (vt)
	{
	case VT_EMPTY: 		
	case VT_NULL: 		
		return TRUE;
	case VT_I2: 		
		return that.iVal == iVal;
	case VT_I4: 		
		return that.lVal == lVal;
	case VT_R4: 		
		return that.fltVal == fltVal;
	case VT_R8: 		
		return that.dblVal == dblVal;
	case VT_BOOL:		
		return that.bool == bool;
	case VT_ERROR: 		
		return that.scode == scode;
	case VT_DATE:		
		return that.date == date;
	case VT_BSTR:		
		return SysStringByteLen(that.bstrVal) == SysStringByteLen(bstrVal) &&
			memcmp(that.bstrVal, bstrVal, SysStringByteLen(bstrVal)) == 0;
	case VT_DISPATCH:
	case VT_UNKNOWN: 	
		return that.punkVal == punkVal;

	default:
		ASSERT(FALSE);	// reference and array types are not implemented
	}

	return FALSE;
}

VARIANT CVariant::Detach()
{
	VARIANT varResult = *this;
	vt = VT_EMPTY;
	return varResult;
}

// special map class helpers
void SerializeElements(CArchive& ar, CVariant* pElements, int nCount)
{
	ASSERT(FALSE);	//TODO: not yet implemented
}

void ConstructElements(CVariant* pElements, int nCount)
{
	for (; nCount--; ++pElements)
		new(pElements) CVariant;	
}

void DestructElements(CVariant* pElements, int nCount)
{
	for (; nCount--; ++pElements)
		pElements->CVariant::~CVariant();
}

void DumpElements(CDumpContext& dc, CVariant* pElements, int nCount)
{
	//TODO: not yet implemented
}

#if (_MFC_VER < 0x300)
// MFC 3.0 has templated versions of these functions, with specialized
// versions for strings.  MFC 2.x does not so we must provide them.
// These implementations were simply copied from MFC 2.5 collection 
// classes.

UINT AFXAPI HashKey(LPCTSTR key)
{
	UINT nHash = 0;
	while (*key)
		nHash = (nHash<<5) + nHash + *key++;
	return nHash;
}

static inline AFXAPI HashKey(DWORD key)
{
	// default identity hash - works for most primitive values
	return ((UINT)key) >> 4;
}
#endif //(_MFC_VER < 0x300)

UINT HashKey(LPCVARIANT pVar)
{
	switch (pVar->vt)
	{
	case VT_EMPTY: 		
	case VT_NULL: 		
		return 0;
	case VT_I2: 		
		return HashKey((DWORD)pVar->iVal);
	case VT_I4: 		
		return HashKey((DWORD)pVar->lVal);
	case VT_R4: 		
		return (UINT)(pVar->fltVal / 16);
	case VT_R8: 		
		return (UINT)(pVar->dblVal / 16);
	case VT_BOOL:		
		return HashKey((DWORD)pVar->bool);
	case VT_ERROR: 		
		return HashKey((DWORD)pVar->scode);
	case VT_DATE:		
		return (UINT)(pVar->date / 16);
	case VT_BSTR:		
		return HashKey(pVar->bstrVal);
	case VT_DISPATCH:
	case VT_UNKNOWN: 	
		return HashKey((DWORD)pVar->punkVal);

	default:
		ASSERT(FALSE);	// reference and array types are not implemented
	}

	return 0;
}

/////////////////////////////////////////////////////////////////////////////
// CInProcApp commands
