home *** CD-ROM | disk | FTP | other *** search
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
-
- #ifdef AFXCTL_CORE2_SEG
- #pragma code_seg(AFXCTL_CORE2_SEG)
- #endif
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- #define new DEBUG_NEW
-
- /////////////////////////////////////////////////////////////////////////////
- // CCmdTarget::EnableTypeLib - locks the typelib cache for this class
-
- void CCmdTarget::EnableTypeLib()
- {
- AfxLockGlobals(CRIT_TYPELIBCACHE);
-
- CTypeLibCache* pTypeLibCache = GetTypeLibCache();
- ASSERT(pTypeLibCache != NULL); // must override GetTypeLibCache
-
- if (pTypeLibCache != NULL)
- pTypeLibCache->Lock(); // will be unlocked in OnFinalRelease
-
- AfxUnlockGlobals(CRIT_TYPELIBCACHE);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CCmdTarget::GetTypeInfoOfGuid - Returns typeinfo
-
- HRESULT CCmdTarget::GetTypeInfoOfGuid(LCID lcid, REFGUID guid,
- LPTYPEINFO* ppTypeInfo)
- {
- USES_CONVERSION;
-
- AfxLockGlobals(CRIT_TYPELIBCACHE);
-
- HRESULT hr = TYPE_E_CANTLOADLIBRARY;
- CTypeLibCache* pTypeLibCache = GetTypeLibCache();
- LPTYPELIB pTypeLib = NULL;
-
- // If type info is already cached, just return it.
- if (pTypeLibCache->LookupTypeInfo(lcid, guid, ppTypeInfo))
- {
- hr = S_OK;
- }
- else
- {
- // If type library isn't already cached, try to locate it.
- if (!pTypeLibCache->Lookup(lcid, &pTypeLib))
- {
- // First, try getting the subclass to load the type library
- // (normally this goes through LoadRegTypeLib).
-
- if (FAILED(GetTypeLib(lcid, &pTypeLib)))
- {
- AFX_MANAGE_STATE(m_pModuleState);
-
- // If that failed, try loading the type library from our own
- // resources.
-
- TCHAR szPath[_MAX_PATH];
- GetModuleFileName(AfxGetInstanceHandle(), szPath, _MAX_PATH);
-
- if (FAILED(LoadTypeLib(T2COLE(szPath), &pTypeLib)))
- pTypeLib = NULL;
- }
-
- pTypeLibCache->Cache(lcid, pTypeLib);
- }
-
- // If we got a type library, extract the requested type info.
- if (pTypeLib != NULL)
- {
- hr = pTypeLib->GetTypeInfoOfGuid(guid, ppTypeInfo);
- pTypeLib->Release();
- pTypeLibCache->CacheTypeInfo(lcid, guid, *ppTypeInfo);
- }
- }
-
- AfxUnlockGlobals(CRIT_TYPELIBCACHE);
-
- return hr;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // AfxGetTypeLibCache
-
- CTypeLibCache* AFXAPI AfxGetTypeLibCache(const GUID* pTypeLibID)
- {
- AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
- ASSERT(pModuleState != NULL);
-
- if (pModuleState->m_pTypeLibCacheMap == NULL)
- {
- const GUID* pCachedTypeLibID = pModuleState->m_typeLibCache.m_pTypeLibID;
-
- if (pCachedTypeLibID == NULL)
- {
- // Cache not initialized yet; initialize it now
- pModuleState->m_typeLibCache.m_pTypeLibID = pTypeLibID;
- return &pModuleState->m_typeLibCache;
- }
- else if (pCachedTypeLibID == pTypeLibID)
- {
- // This is the cache we need; return it
- return &pModuleState->m_typeLibCache;
- }
- else
- {
- // Another cache is needed; initialize the map
- pModuleState->m_pTypeLibCacheMap = new CTypeLibCacheMap;
- pModuleState->m_pTypeLibCacheMap->SetAt(
- (void*)(const void*)pModuleState->m_typeLibCache.m_pTypeLibID,
- &pModuleState->m_typeLibCache);
-
- // FALL THRU
- }
- }
-
- ASSERT(pModuleState->m_pTypeLibCacheMap != NULL);
-
- // Try to locate cache in the map
- CTypeLibCache* pCache;
- if (!pModuleState->m_pTypeLibCacheMap->Lookup((void*)(const void*)pTypeLibID,
- (void*&)pCache))
- {
- // Create new cache and add it to the map
- pCache = new CTypeLibCache;
- pCache->m_pTypeLibID = pTypeLibID;
- pModuleState->m_pTypeLibCacheMap->SetAt((void*)(const void*)pTypeLibID, pCache);
- }
-
- ASSERT(pCache != NULL);
- ASSERT(pCache->m_pTypeLibID == pTypeLibID);
- return pCache;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CTypeLibCache
- // (Note: CTypeLibCache::Unlock is implemented in afxstate.cpp)
-
- void CTypeLibCache::Lock()
- {
- ASSERT(m_cRef >= 0);
-
- if (m_cRef == 0)
- m_lcid = (LCID)-1;
-
- InterlockedIncrement(&m_cRef);
- }
-
- BOOL CTypeLibCache::Lookup(LCID lcid, LPTYPELIB* pptlib)
- {
- if ((m_lcid != -1) && (m_lcid == lcid))
- {
- ASSERT(m_ptlib != NULL);
- *pptlib = m_ptlib;
- m_ptlib->AddRef();
- return TRUE;
- }
- else
- {
- *pptlib = NULL;
- return FALSE;
- }
- }
-
- void CTypeLibCache::Cache(LCID lcid, LPTYPELIB ptlib)
- {
- if (ptlib != NULL)
- {
- m_lcid = lcid;
- m_guidInfo = GUID_NULL;
- RELEASE(m_ptinfo);
- RELEASE(m_ptlib);
- m_ptlib = ptlib;
- m_ptlib->AddRef();
- }
- }
-
- BOOL CTypeLibCache::LookupTypeInfo(LCID lcid, REFGUID guid,
- LPTYPEINFO* pptinfo)
- {
- if ((m_lcid != -1) && (m_lcid == lcid) && (m_ptinfo != NULL) &&
- IsEqualGUID(m_guidInfo, guid))
- {
- ASSERT(m_ptlib != NULL);
- ASSERT(m_ptinfo != NULL);
- *pptinfo = m_ptinfo;
- m_ptinfo->AddRef();
- return TRUE;
- }
- else
- {
- *pptinfo = NULL;
- return FALSE;
- }
- }
-
- void CTypeLibCache::CacheTypeInfo(LCID lcid, REFGUID guid, LPTYPEINFO ptinfo)
- {
- if ((ptinfo != NULL) && (m_lcid == lcid))
- {
- m_guidInfo = guid;
- RELEASE(m_ptinfo);
- m_ptinfo = ptinfo;
- m_ptinfo->AddRef();
- }
- }
-