Click here to Skip to main content
15,895,557 members
Articles / Desktop Programming / WTL

Form Designer

26 Jul 2021CPOL24 min read 352.1K   82.5K   230  
Component for adding scriptable forms capabilities to an application.
// TypeInfoHelpers.cpp
//
// Author : David Shepherd
//			Copyright (c) 2002, DaeDoe-Software
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TypeInfoHelpers.h"

BOOL DoesCoClassImplementInterface(
	const CComPtr<ITypeInfo> &spTypeInfo,const IID &InterfaceId)
{
	// check parameters
	if(spTypeInfo==NULL)
	{
		throw std::exception();
	}
	// get type attributes
	CAutoTypeAttrPtr pTypeAttr(spTypeInfo);
	if(pTypeAttr->typekind!=TKIND_COCLASS)
	{
		throw std::exception();
	}
	// determine if the coclass implements the interface
	BOOL Found=FALSE;
	for(long l=0; l<pTypeAttr->cImplTypes and Found==FALSE; l++)
	{
		// get type info for the next interface entry
		HREFTYPE hRefType=0;
		if(!SUCCEEDED(spTypeInfo->GetRefTypeOfImplType(l,&hRefType)))
		{
			throw std::exception();
		}
		CComPtr<ITypeInfo> spTypeInfoInterface;
		if(!SUCCEEDED(spTypeInfo->GetRefTypeInfo(hRefType,&spTypeInfoInterface)))
		{
			throw std::exception();
		}
		// compare the interface guids
		if(CAutoTypeAttrPtr(spTypeInfoInterface)->guid==InterfaceId)
		{
			Found=TRUE;	// found it
		}
	}
	return Found;
}

CComPtr<ITypeInfo> GetImplementingCoClassTypeInfo(
	const CComPtr<IDispatch> &spDispatch)
{
	// check parameters
	if(spDispatch==NULL)
	{
		throw std::exception();
	}
	// get type info for the interface
	CComPtr<ITypeInfo> spTypeInfoInterface;
	if(!SUCCEEDED(
		spDispatch->GetTypeInfo(0,LOCALE_USER_DEFAULT,&spTypeInfoInterface)))
	{
		throw std::exception();
	}
	// get the interface id
	IID InterfaceId=CAutoTypeAttrPtr(spTypeInfoInterface)->guid;
	// get the containing type lib
	UINT Ix=0;
	CComPtr<ITypeLib> spTypeLib;
	if(!SUCCEEDED(
		spTypeInfoInterface->GetContainingTypeLib(&spTypeLib,&Ix)))
	{
		throw std::exception();
	}
	// find the coclass implementing the interface
	BOOL Found=FALSE;
	CComPtr<ITypeInfo> spTypeInfoCoClass;
	for(long l=0; l<(long)spTypeLib->GetTypeInfoCount() and Found==FALSE; l++)
	{
		// get type info for the next type lib entry
		CComPtr<ITypeInfo> spTypeInfo;
		if(!SUCCEEDED(spTypeLib->GetTypeInfo(l,&spTypeInfo)))
		{
			throw std::exception();
		}
		// if the entry is a coclass
		if(CAutoTypeAttrPtr(spTypeInfo)->typekind==TKIND_COCLASS and
			// and it implements the interface
			DoesCoClassImplementInterface(spTypeInfo,InterfaceId))
		{
			spTypeInfoCoClass=spTypeInfo;
			Found=TRUE;	// found it
		}
	}
	if(Found==FALSE)	// not found
	{
		throw std::exception();
	}
	return spTypeInfoCoClass;
}

CComPtr<ITypeInfo> GetDefaultSourceInterfaceTypeInfo(
	const CComPtr<ITypeInfo> &spTypeInfo)
{
	// check parameters
	if(spTypeInfo==NULL)
	{
		throw std::exception();
	}
	// get type attributes
	CAutoTypeAttrPtr pTypeAttr(spTypeInfo);
	if(pTypeAttr->typekind!=TKIND_COCLASS)
	{
		throw std::exception();
	}
	// find the default source interface
	BOOL Found=FALSE;
	for(long l=0; l<pTypeAttr->cImplTypes and Found==FALSE; l++)
	{
		// get the interface flags
		int ImplTypeFlags=0;
		if(!SUCCEEDED(spTypeInfo->GetImplTypeFlags(l,&ImplTypeFlags)))
		{
			throw std::exception();
		}
		// check for the default source interface
		if(	ImplTypeFlags & IMPLTYPEFLAG_FDEFAULT and
			ImplTypeFlags & IMPLTYPEFLAG_FSOURCE)
		{
			Found=TRUE;	// found it
		}
	}
	if(Found==FALSE)	// not found
	{
		throw std::exception();
	}
	// get type info for the default source interface
	HREFTYPE hRefType=0;
	if(!SUCCEEDED(spTypeInfo->GetRefTypeOfImplType(l-1,&hRefType)))
	{
		throw std::exception();
	}
	CComPtr<ITypeInfo> spTypeInfoInterface;
	if(!SUCCEEDED(spTypeInfo->GetRefTypeInfo(hRefType,&spTypeInfoInterface)))
	{
		throw std::exception();
	}
	return spTypeInfoInterface;
}

std::wstring GetFunctionName(
	long Ix,const CComPtr<ITypeInfo> &spTypeInfo)
{
	// check parameters
	if(spTypeInfo==NULL)
	{
		throw std::exception();
	}
	// get the function description
	CAutoFuncDescPtr pFuncDesc(Ix,spTypeInfo);
	// get the function name
	CComBSTR FunctionName;
	UINT Count=0;
	if(!SUCCEEDED(spTypeInfo->GetNames(
		pFuncDesc->memid,&FunctionName,1,&Count)))
	{
		throw std::exception();
	}
	ATLASSERT(Count==1);
	return BSTR2W(FunctionName);
}

std::wstring GetCommaSeperatedFunctionParameterNames(
	long Ix,const CComPtr<ITypeInfo> &spTypeInfo)
{
	// check parameters
	if(spTypeInfo==NULL)
	{
		throw std::exception();
	}
	// get the function description
	CAutoFuncDescPtr pFuncDesc(Ix,spTypeInfo);
	// create a BSTR array to hold the function and parameter names
	UINT ParamCount=pFuncDesc->cParams;
	auto_array_ptr<BSTR> pBSTR(new BSTR[ParamCount+1]);
	// get the function and parameter names
	UINT Count=0;
	if(!SUCCEEDED(spTypeInfo->GetNames(
		pFuncDesc->memid,pBSTR.get(),ParamCount+1,&Count)))
	{
		throw std::exception();
	}
	ATLASSERT(Count==ParamCount+1);
	// create a CComBSTR array to manage the BSTR array
	// todo : if possible prevent a BSTR leak here if new throws
	auto_array_ptr<CComBSTR> pCComBSTR(new CComBSTR[Count]);
	for(long l=0; l<(long)Count; l++)
	{
		pCComBSTR.get()[l].Attach(pBSTR.get()[l]);
	}
	// create the comma seperated list of function parameter names
	std::wstring ParameterNames;
	for(l=0; l<(long)ParamCount; l++)
	{
		// comma
		if(ParameterNames.length())
		{
			ParameterNames+=L",";
		}
		// parameter name
		ParameterNames+=BSTR2W(pBSTR.get()[l+1]);
	}
	return ParameterNames;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions