// DecalRes.cpp : Implementation of cDecalRes #include "stdafx.h" #include "Decal.h" #include "DecalRes.h" ///////////////////////////////////////////////////////////////////////////// // cDecalRes HRESULT cDecalRes::getLibID( MSXML::IXMLDOMDocumentPtr &pdoc, GUID *pGUID ) { _variant_t vlib = pdoc->selectSingleNode( _T( "/*/@lib" ) )->text; if( vlib.vt == VT_NULL ) { // lib is a required field _ASSERT( FALSE ); return E_FAIL; } return ::CLSIDFromString( vlib.bstrVal, pGUID ); } bool cDecalRes::getTypelibFilename( MSXML::IXMLDOMDocumentPtr &pdoc, BSTR *pbstrFilename ) { USES_CONVERSION; GUID libid; HRESULT hRes = getLibID( pdoc, &libid ); if( FAILED( hRes ) ) return SUCCEEDED ( hRes ); // Look up the path of the typelib in the registry hRes = ::QueryPathOfRegTypeLib( libid, 1, 0, 0, pbstrFilename ); if( SUCCEEDED( hRes ) ) return true; // Otherwise, manufacture a type library filename RegKey key; key.Open( HKEY_LOCAL_MACHINE, _T( "Software\\Decal\\Agent" ) ); TCHAR szPath[ MAX_PATH ]; DWORD dwPath = MAX_PATH; key.QueryStringValue (_T("PluginPath"), szPath, &dwPath); if( szPath[ ::_tcslen( szPath ) - 1 ] != _T( '\\' ) ) ::_tcscat( szPath, _T( "\\" ) ); _variant_t vName = pdoc->selectSingleNode( _T( "/*/@name" ) )->text; if( vName.vt == VT_NULL ) ::_tcscat( szPath, _T( "ErrorUnnamedTypelib.tlb" ) ); else { ::_tcscat( szPath, OLE2T( vName.bstrVal ) ); ::_tcscat( szPath, _T( ".tlb" ) ); } *pbstrFilename = T2BSTR( szPath ); return false; } HRESULT cDecalRes::initTypelib( MSXML::IXMLDOMDocumentPtr &pdoc, BSTR strFilename ) { HRESULT hRes = ::CreateTypeLib2( SYS_WIN32, strFilename, &m_pLib ); if( FAILED( hRes ) ) return hRes; GUID libid; hRes = getLibID( pdoc, &libid ); if( FAILED( hRes ) ) return hRes; m_pLib->SetGuid( libid ); _variant_t vName = pdoc->selectSingleNode( _T( "/*/@name" ) )->text; if( vName.vt == VT_NULL ) { // Name is a required field _ASSERT( FALSE ); return E_FAIL; } m_pLib->SetName( vName.bstrVal ); m_pLib->SetVersion( 1, 0 ); // One initialized typelib return S_OK; } HRESULT cDecalRes::scanTemplate( MSXML::IXMLDOMElementPtr &ptemp, ITypeInfo **ppCoClass, ITypeInfo **ppSource ) { // Get the IDs for the coclass, default interface and default source interface _variant_t vIDCoClass = ptemp->getAttribute( _T( "class" ) ), vIDEvent = ptemp->getAttribute( _T( "event" ) ), vName = ptemp->getAttribute( _T( "name" ) ); if( vIDCoClass.vt == VT_NULL || vIDEvent.vt == VT_NULL || vName.vt == VT_NULL ) { // Both of these are required _ASSERT( FALSE ); return E_FAIL; } // Next convert them to GUIDs CLSID idClass; IID idEvent; if( FAILED( ::CLSIDFromString( vIDCoClass.bstrVal, &idClass ) ) || FAILED( ::CLSIDFromString( vIDEvent.bstrVal, &idEvent ) ) ) { // They must be converted to guids _ASSERT( FALSE ); return E_FAIL; } // Now we make the coclass typeinfo, default source typeinfo, get the default interface typeinfo // and slap them all together CComPtr< ICreateTypeInfo > pCoClass; m_pLib->CreateTypeInfo( vName.bstrVal, TKIND_COCLASS, &pCoClass ); pCoClass->SetGuid( idClass ); pCoClass->QueryInterface( ppCoClass ); CComPtr< ITypeInfo > pDefaultItf; GetTypeInfo( 0, 0, &pDefaultItf ); HREFTYPE hrefDefaultItf; pCoClass->AddRefTypeInfo( pDefaultItf, &hrefDefaultItf ); pCoClass->AddImplType( 0, hrefDefaultItf ); pCoClass->SetImplTypeFlags( 0, IMPLTYPEFLAG_FDEFAULT ); CComPtr< ICreateTypeInfo > pSourceItf; _bstr_t strEvent( _T( "_" ) ); strEvent += vName.bstrVal; strEvent += _T( "Events" ); m_pLib->CreateTypeInfo( strEvent, TKIND_DISPATCH, &pSourceItf ); pSourceItf->SetGuid( idEvent ); HREFTYPE hrefSourceItf; pSourceItf->QueryInterface( ppSource ); pCoClass->AddRefTypeInfo( *ppSource, &hrefSourceItf ); pCoClass->AddImplType( 1, hrefSourceItf ); pCoClass->SetImplTypeFlags( 1, IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE ); // Still incomplete return S_OK; }