TYPEINFO.CPP

/************************************************************************* 
**
** This is a part of the Microsoft Source Code Samples.
**
** Copyright 1992 - 1998 Microsoft Corporation. All rights reserved.
**
** This source code is only intended as a supplement to Microsoft Development
** Tools and/or WinHelp documentation. See these sources for detailed
** information regarding the Microsoft samples programs.
**
** OLE Automation TypeLibrary Browse Helper Sample
**
** typeinfo.cpp
**
** CTypeInfo implementation
**
** Written by Microsoft Product Support Services, Windows Developer Support
**
*************************************************************************/

#include <windows.h>
#include <windowsx.h>
#ifdef WIN16
#include <ole2.h>
#include <compobj.h>
#include <dispatch.h>
#include <variant.h>
#include <olenls.h>
#endif
#include "browseh.h"

/*
* CTypeInfo::Create
*
* Purpose:
* Creates an instance of the TypeInfo automation object and initializes it.
*
* Parameters:
* ptinfo TypeInfo in type library..
* ppTypeInfo Returns TypeInfo automation object.
*
* Return Value:
* HRESULT
*
*/
HRESULT
CTypeInfo::Create(LPTYPEINFO ptinfo, CTypeInfo FAR* FAR* ppTypeInfo)
{
HRESULT hr;
CTypeInfo FAR* pTypeInfo = NULL;

*ppTypeInfo = NULL;

// Create application object.
pTypeInfo = new CTypeInfo();
if (pTypeInfo == NULL)
{
hr = E_OUTOFMEMORY;
goto error;
}
// Load type information for the application object from type library.
hr = pTypeInfo->LoadTypeInfo(IID_ITypeInformation);
if (FAILED(hr))
goto error;
hr = pTypeInfo->_InitTypeInfo(ptinfo);
if (FAILED(hr))
goto error;

#ifdef _DEBUG
lstrcpyn(pTypeInfo->m_szClassName, TEXT("TypeInfo"), 100);
#endif

*ppTypeInfo = pTypeInfo;
return NOERROR;

error:
if (pTypeInfo == NULL) return E_OUTOFMEMORY;

delete pTypeInfo;
return hr;
}

/*
* CTypeInfo::CTypeInfo
*
* Purpose:
* Constructor for CTypeInfo object. Initializes members to NULL.
*
*/
CTypeInfo::CTypeInfo()
{
m_bstrName = NULL;
m_bstrDocumentation = NULL;
m_bstrHelpFile = NULL;
m_pszGUID = NULL;
}

/*
* CTypeInfo::~CTypeInfo
*
* Purpose:
* Destructor for CTypeInfo object.
*
*/
CTypeInfo::~CTypeInfo()
{
if (m_bstrName) SysFreeString(m_bstrName);
if (m_bstrDocumentation) SysFreeString(m_bstrDocumentation);
if (m_bstrHelpFile) SysFreeString(m_bstrHelpFile);

#ifdef WIN32
if (m_pszGUID) CoTaskMemFree(m_pszGUID);
#else
HRESULT hr;
LPMALLOC pmalloc;
if (m_pszGUID)
{
hr = CoGetMalloc(MEMCTX_TASK, &pmalloc);
if (SUCCEEDED(hr))
{
pmalloc->Free(m_pszGUID);
pmalloc->Release();
}
}
#endif
}

STDMETHODIMP_(REFCLSID)
CTypeInfo::GetInterfaceID()
{
return IID_ITypeInformation;
}

STDMETHODIMP
CTypeInfo::_InitTypeInfo(LPTYPEINFO ptinfo)
{
HRESULT hr;
LPTYPELIB ptlib = NULL;
unsigned int nIndex;
LPTYPEATTR ptypeattr;

// Get information from TYPEATTR
hr = ptinfo->GetTypeAttr(&ptypeattr);
if (FAILED(hr))
return hr;
m_typekind = ptypeattr->typekind;
m_guid = ptypeattr->guid;
m_wTypeFlags = ptypeattr->wTypeFlags;
ptinfo->ReleaseTypeAttr(ptypeattr);

hr = ptinfo->GetContainingTypeLib(&ptlib, &nIndex);
if (FAILED(hr))
{
if (hr == E_NOTIMPL) //Supportes runtime typeinfo browsing. (Type info
//obtained from IDispatch::GetTypeInfo does not have a containing
//type library).
return NOERROR;
else return hr;
}
hr = ptlib->GetDocumentation(nIndex, &m_bstrName, &m_bstrDocumentation,
&m_ulHelpContext, &m_bstrHelpFile);
if (FAILED(hr))
goto error;
ptlib->Release();
return NOERROR;

error:
if (ptlib) ptlib->Release();
if (m_bstrName) SysFreeString(m_bstrName);
if (m_bstrDocumentation) SysFreeString(m_bstrDocumentation);
if (m_bstrHelpFile) SysFreeString(m_bstrHelpFile);
m_bstrName = NULL;
m_bstrDocumentation = NULL;
m_bstrHelpFile = NULL;
return hr;
}

STDMETHODIMP_(BSTR)
CTypeInfo::get_Name()
{
return SysAllocString(m_bstrName);
}

STDMETHODIMP_(BSTR)
CTypeInfo::get_Documentation()
{
return SysAllocString(m_bstrDocumentation);
}

STDMETHODIMP_(long)
CTypeInfo::get_HelpContext()
{
return (long)m_ulHelpContext;
}

STDMETHODIMP_(BSTR)
CTypeInfo::get_HelpFile()
{
return SysAllocString(m_bstrHelpFile);
}

STDMETHODIMP_(TYPEKIND)
CTypeInfo::get_TypeInfoKind()
{
return m_typekind;
}

STDMETHODIMP_(short)
CTypeInfo::get_TypeFlags()
{
return m_wTypeFlags;
}

STDMETHODIMP_(BSTR)
CTypeInfo::get_GUIDAsString()
{
if (m_pszGUID == NULL)
StringFromCLSID(m_guid, &m_pszGUID);
return SysAllocString(m_pszGUID);
}