// CtrlHolder.cpp : implementation file
//

#include "stdafx.h"
#include "CtrlHolder.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCtrlHolder

CCtrlHolder::CCtrlHolder(CString ClsidString)
{
	USES_CONVERSION

	m_ClsidString = ClsidString ;
	CLSIDFromString (A2W((LPCTSTR) ClsidString), &m_Clsid) ;
}

CCtrlHolder::CCtrlHolder(CLSID clsid)
{
	m_Clsid = clsid ;

	USES_CONVERSION ;
	WCHAR wName [256] ;

	StringFromGUID2 (clsid, wName, sizeof(wName)/sizeof(WCHAR)) ;
	m_ClsidString = W2A (wName) ;
}

CCtrlHolder::~CCtrlHolder()
{
}


BEGIN_MESSAGE_MAP(CCtrlHolder, CWnd)
	//{{AFX_MSG_MAP(CCtrlHolder)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CCtrlHolder message handlers


/*
My own stuff added for acess to private members
*/

#include <occimpl.h>

HRESULT	CCtrlHolder::GetDispatch (LPDISPATCH * ppOut) 
{
	*ppOut = m_pCtrlSite->m_dispDriver.m_lpDispatch ;
	m_pCtrlSite->m_dispDriver.m_lpDispatch->AddRef( ) ;
	return S_OK ;
}

HRESULT CCtrlHolder::GetTypeInfo (LPTYPEINFO * ppOut)
{
	HKEY hKey, hSubKey ;
	char TypeLibString [256] ;
	long length = sizeof (TypeLibString) ;
	CLSID TypeLibClsid ;
	USES_CONVERSION

	RegOpenKey (HKEY_CLASSES_ROOT, "Clsid", &hKey) ;
	RegOpenKey (hKey, (LPCTSTR) m_ClsidString, &hSubKey) ;
	RegQueryValue (hSubKey, "TypeLib", TypeLibString, &length) ;

	CLSIDFromString (A2W(TypeLibString), &TypeLibClsid) ;
	ITypeLib *pTypeLib;
	LoadRegTypeLib (TypeLibClsid, 1, 0, LOCALE_SYSTEM_DEFAULT, &pTypeLib) ;
	HRESULT hr = pTypeLib->GetTypeInfoOfGuid (m_Clsid, ppOut) ;
	
	return hr ;
}


HRESULT CCtrlHolder::SetPropByName (CString PropName, CString PropVal)
{

/*
Get dispatch ID of named property
*/
	DISPID id ;
	HRESULT hr = GetIDOfName (PropName, &id) ;

	if (hr != S_OK)
	{
		return hr ;
	}

/*
Get type of named property
*/
	VARTYPE vt ;
	hr = GetTypeOfProperty (id, &vt) ;

/*
Convert string value of property into requested type.
*/
	COleVariant var (PropVal) ;
	var.ChangeType (vt) ;

	/*VARIANT varIn, varOut ;

	VariantInit (&varIn) ;
	VariantInit (&varOut) ;

	varIn.vt = VT_BSTR ;
	varIn.bstrVal = 

	hr = VariantChangeType (&varOut, &varIn, 0, vt) ;
*/	
/*
Set the actual property
*/

	VARIANT *pv = (LPVARIANT)(&var)	;
	m_pCtrlSite->SetPropertyV (id, vt, ((char *)pv) + 8) ;

	return S_OK ;
}


HRESULT CCtrlHolder::GetIDOfName (CString &Name, DISPID *pDispIdOut) 
{
	DISPID id ;

	WCHAR wName [256], *pNames ;

	MultiByteToWideChar (CP_ACP, 0, (LPCTSTR)Name, -1,
		wName, sizeof(wName)/sizeof(WCHAR)) ;

	pNames = wName ;

	HRESULT hr = m_pCtrlSite->m_dispDriver.m_lpDispatch->GetIDsOfNames(
		IID_NULL, &pNames, 1, LOCALE_SYSTEM_DEFAULT, &id) ;
	
	*pDispIdOut = id ;
	return hr ;
}

HRESULT CCtrlHolder::GetTypeOfProperty (DISPID id, VARTYPE *pvt)
{
	ITypeInfo *pti ;

/*
Get type info describing this IDispatch.
*/
	HRESULT hr = m_pCtrlSite->m_dispDriver.m_lpDispatch->GetTypeInfo (0, LOCALE_SYSTEM_DEFAULT, &pti) ;

	if (hr != S_OK)
	{
		return hr ;
	}

/*
Check for stock property dispids
*/

	switch (id)
	{
		case DISPID_BACKCOLOR:
		case DISPID_FORECOLOR:
		{
			*pvt = VT_I4 ;
			return S_OK ;
		}
	}

/*
Iterate through all the properties until we find ours.
*/

	int i = 0 ;
	VARDESC *pVarDesc ;
	
	while (pti->GetVarDesc  (i, &pVarDesc) == S_OK)
	{
		if (pVarDesc->memid == id)
		{
			*pvt = (pVarDesc->elemdescVar).tdesc.vt ;
			pti->ReleaseVarDesc (pVarDesc) ;
			return S_OK ;
		}

		i++ ;
		pti->ReleaseVarDesc (pVarDesc) ;
	}

	return E_FAIL ;
}
