📄 atlbase.h
字号:
template <class _Ty>
void *operator new(size_t, _Ty* p)
{
return p;
}
T t;
};
void SetAtIndex(int nIndex, T& t)
{
ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
new(m_aT + nIndex) Wrapper(t);
}
int Find(T& t) const
{
for(int i = 0; i < m_nSize; i++)
{
if(m_aT[i] == t)
return i;
}
return -1; // not found
}
};
// for arrays of simple types
template <class T>
class CSimpleValArray : public CSimpleArray< T >
{
public:
BOOL Add(T t)
{
return CSimpleArray< T >::Add(t);
}
BOOL Remove(T t)
{
return CSimpleArray< T >::Remove(t);
}
T operator[] (int nIndex) const
{
return CSimpleArray< T >::operator[](nIndex);
}
};
// intended for small number of simple types or pointers
template <class TKey, class TVal>
class CSimpleMap
{
public:
TKey* m_aKey;
TVal* m_aVal;
int m_nSize;
// Construction/destruction
CSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
{ }
~CSimpleMap()
{
RemoveAll();
}
// Operations
int GetSize() const
{
return m_nSize;
}
BOOL Add(TKey key, TVal val)
{
TKey* pKey;
pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));
if(pKey == NULL)
return FALSE;
m_aKey = pKey;
TVal* pVal;
pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));
if(pVal == NULL)
return FALSE;
m_aVal = pVal;
m_nSize++;
SetAtIndex(m_nSize - 1, key, val);
return TRUE;
}
BOOL Remove(TKey key)
{
int nIndex = FindKey(key);
if(nIndex == -1)
return FALSE;
if(nIndex != (m_nSize - 1))
{
m_aKey[nIndex].~TKey();
#if _MSC_VER >= 1200
m_aVal[nIndex].~TVal();
#else
TVal * t1;
t1 = &m_aVal[nIndex];
t1->~TVal();
#endif
memmove((void*)&m_aKey[nIndex], (void*)&m_aKey[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TKey));
memmove((void*)&m_aVal[nIndex], (void*)&m_aVal[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TVal));
}
TKey* pKey;
pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
if(pKey != NULL || m_nSize == 1)
m_aKey = pKey;
TVal* pVal;
pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
if(pVal != NULL || m_nSize == 1)
m_aVal = pVal;
m_nSize--;
return TRUE;
}
void RemoveAll()
{
if(m_aKey != NULL)
{
for(int i = 0; i < m_nSize; i++)
{
m_aKey[i].~TKey();
#if _MSC_VER >= 1200
m_aVal[i].~TVal();
#else
TVal * t1;
t1 = &m_aVal[i];
t1->~TVal();
#endif
}
free(m_aKey);
m_aKey = NULL;
}
if(m_aVal != NULL)
{
free(m_aVal);
m_aVal = NULL;
}
m_nSize = 0;
}
BOOL SetAt(TKey key, TVal val)
{
int nIndex = FindKey(key);
if(nIndex == -1)
return FALSE;
SetAtIndex(nIndex, key, val);
return TRUE;
}
TVal Lookup(TKey key) const
{
int nIndex = FindKey(key);
if(nIndex == -1)
return NULL; // must be able to convert
return GetValueAt(nIndex);
}
TKey ReverseLookup(TVal val) const
{
int nIndex = FindVal(val);
if(nIndex == -1)
return NULL; // must be able to convert
return GetKeyAt(nIndex);
}
TKey& GetKeyAt(int nIndex) const
{
ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_aKey[nIndex];
}
TVal& GetValueAt(int nIndex) const
{
ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_aVal[nIndex];
}
// Implementation
template <typename T>
class Wrapper
{
public:
Wrapper(T& _t) : t(_t)
{
}
template <typename _Ty>
void *operator new(size_t, _Ty* p)
{
return p;
}
T t;
};
void SetAtIndex(int nIndex, TKey& key, TVal& val)
{
ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
new(m_aKey + nIndex) Wrapper<TKey>(key);
new(m_aVal + nIndex) Wrapper<TVal>(val);
}
int FindKey(TKey& key) const
{
for(int i = 0; i < m_nSize; i++)
{
if(m_aKey[i] == key)
return i;
}
return -1; // not found
}
int FindVal(TVal& val) const
{
for(int i = 0; i < m_nSize; i++)
{
if(m_aVal[i] == val)
return i;
}
return -1; // not found
}
};
class CComModule;
__declspec(selectany) CComModule* _pModule=NULL;
// {B62F5910-6528-11d1-9611-0000F81E0D0D}
_declspec(selectany) GUID GUID_ATLVer30 = { 0xb62f5910, 0x6528, 0x11d1, { 0x96, 0x11, 0x0, 0x0, 0xf8, 0x1e, 0xd, 0xd } };
class CComModule : public _ATL_MODULE
{
// Operations
public:
static GUID m_libid;
#ifdef _ATL_DEBUG_INTERFACES
UINT m_nIndexQI;
UINT m_nIndexBreakAt;
CSimpleArray<_QIThunk*>* m_paThunks;
#endif // _ATL_DEBUG_INTERFACES
void AddCreateWndData(_AtlCreateWndData* pData, void* pObject)
{
AtlModuleAddCreateWndData(this, pData, pObject);
}
void* ExtractCreateWndData()
{
return AtlModuleExtractCreateWndData(this);
}
#if _ATL_VER > 0x0300
LONG GetNextWindowID()
{
LONG nID;
nID = InterlockedIncrement(&m_nNextWindowID);
return nID;
}
#endif
HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL)
{
pguidVer = &GUID_ATLVer30;
_pModule = this;
cbSize = sizeof(_ATL_MODULE);
dwAtlBuildVer = _ATL_VER;
AtlModuleInit(this, p, h);
if (plibid != NULL)
memcpy((void*)&m_libid, plibid, sizeof(GUID));
#if _ATL_VER > 0x0300
m_nNextWindowID = 1;
#endif
#ifdef _ATL_MIN_CRT
// Create a base heap
m_hHeap = HeapCreate(0, 0, 0);
#ifndef _ATL_NO_MP_HEAP
SYSTEM_INFO si;
GetSystemInfo(&si);
if (si.dwNumberOfProcessors > 1)
{
DWORD dwHeaps = si.dwNumberOfProcessors * 2;
m_dwHeaps = 0xFFFFFFFF;
for (int bits = 0; bits < 32; bits++)
{
if (dwHeaps & 0x80000000)
break;
dwHeaps <<= 1;
m_dwHeaps >>= 1;
}
m_dwHeaps >>= 1;
// Allocate more heaps for each processor
m_phHeaps = (HANDLE*) HeapAlloc(m_hHeap, _ATL_HEAPFLAGS, sizeof(HANDLE) * (m_dwHeaps + 1));
for (DWORD i = 0; i <= m_dwHeaps; i++)
m_phHeaps[i] = HeapCreate(0, 0, 0);
}
else
#endif
{
m_phHeaps = NULL;
m_dwHeaps = 0;
}
#endif
#ifdef _ATL_DEBUG_INTERFACES
m_nIndexQI = 0;
m_nIndexBreakAt = 0;
m_paThunks = NULL;
ATLTRY(m_paThunks = new CSimpleArray<_QIThunk*>);
if (m_paThunks == NULL)
return E_OUTOFMEMORY;
#endif // _ATL_DEBUG_INTERFACES
return S_OK;
}
#ifdef _ATL_DEBUG_INTERFACES
HRESULT AddThunk(IUnknown** pp, LPCTSTR lpsz, REFIID iid)
{
if ((pp == NULL) || (*pp == NULL))
return E_POINTER;
IUnknown* p = *pp;
_QIThunk* pThunk = NULL;
EnterCriticalSection(&m_csObjMap);
// Check if exists already for identity
if (InlineIsEqualUnknown(iid))
{
for (int i = 0; i < m_paThunks->GetSize(); i++)
{
if (m_paThunks->operator[](i)->pUnk == p)
{
m_paThunks->operator[](i)->InternalAddRef();
pThunk = m_paThunks->operator[](i);
break;
}
}
}
if (pThunk == NULL)
{
++m_nIndexQI;
if (m_nIndexBreakAt == m_nIndexQI)
DebugBreak();
ATLTRY(pThunk = new _QIThunk(p, lpsz, iid, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));
if (pThunk == NULL)
return E_OUTOFMEMORY;
pThunk->InternalAddRef();
m_paThunks->Add(pThunk);
}
LeaveCriticalSection(&m_csObjMap);
*pp = (IUnknown*)pThunk;
return S_OK;
}
HRESULT AddNonAddRefThunk(IUnknown* p, LPCTSTR lpsz, IUnknown** ppThunkRet)
{
_QIThunk* pThunk = NULL;
EnterCriticalSection(&m_csObjMap);
// Check if exists already for identity
for (int i = 0; i < m_paThunks->GetSize(); i++)
{
if (m_paThunks->operator[](i)->pUnk == p)
{
m_paThunks->operator[](i)->bNonAddRefThunk = true;
pThunk = m_paThunks->operator[](i);
break;
}
}
if (pThunk == NULL)
{
++m_nIndexQI;
if (m_nIndexBreakAt == m_nIndexQI)
DebugBreak();
ATLTRY(pThunk = new _QIThunk(p, lpsz, IID_IUnknown, m_nIndexQI, (m_nIndexBreakAt == m_nIndexQI)));
if (pThunk == NULL)
{
*ppThunkRet = NULL;
return E_OUTOFMEMORY;
}
pThunk->bNonAddRefThunk = true;
m_paThunks->Add(pThunk);
}
LeaveCriticalSection(&m_csObjMap);
*ppThunkRet = (IUnknown*)pThunk;
return S_OK;;
}
void DeleteNonAddRefThunk(IUnknown* pUnk)
{
EnterCriticalSection(&m_csObjMap);
for (int i = 0; i < m_paThunks->GetSize(); i++)
{
if (m_paThunks->operator[](i)->pUnk == pUnk)
{
delete m_paThunks->operator[](i);
m_paThunks->RemoveAt(i);
break;
}
}
LeaveCriticalSection(&m_csObjMap);
}
void DeleteThunk(_QIThunk* p)
{
EnterCriticalSection(&m_csObjMap);
int nIndex = m_paThunks->Find(p);
if (nIndex != -1)
{
delete m_paThunks->operator[](nIndex);
m_paThunks->RemoveAt(nIndex);
}
LeaveCriticalSection(&m_csObjMap);
}
bool DumpLeakedThunks()
{
bool b = false;
for (int i = 0; i < m_paThunks->GetSize(); i++)
{
b = true;
m_paThunks->operator[](i)->Dump();
delete m_paThunks->operator[](i);
}
m_paThunks->RemoveAll();
return b;
}
#endif // _ATL_DEBUG_INTERFACES
void Term()
{
#ifdef _ATL_DEBUG_INTERFACES
m_bDestroyHeap = false; // prevent heap from going away
AtlModuleTerm(this);
DumpLeakedThunks();
delete m_paThunks;
#ifndef _ATL_NO_MP_HEAP
if (m_phHeaps != NULL)
{
for (DWORD i = 0; i <= m_dwHeaps; i++)
HeapDestroy(m_phHeaps[i]);
}
#endif
if (m_hHeap != NULL)
HeapDestroy(m_hHeap);
#else
AtlModuleTerm(this);
#endif // _ATL_DEBUG_INTERFACES
}
HRESULT AddTermFunc(_ATL_TERMFUNC* pFunc, DWORD_PTR dw)
{
return AtlModuleAddTermFunc(this, pFunc, dw);
}
LONG Lock()
{
return CComGlobalsThreadModel::Increment(&m_nLockCnt);
}
LONG Unlock()
{
return CComGlobalsThreadModel::Decrement(&m_nLockCnt);
}
LONG GetLockCount()
{
return m_nLockCnt;
}
HINSTANCE GetModuleInstance() {return m_hInst;}
HINSTANCE GetResourceInstance() {return m_hInstResource;}
HINSTANCE GetTypeLibInstance() {return m_hInstTypeLib;}
// Registry support (helpers)
HRESULT RegisterTypeLib()
{
return AtlModuleRegisterTypeLib(this, NULL);
}
HRESULT RegisterTypeLib(LPCTSTR lpszIndex)
{
USES_CONVERSION;
return AtlModuleRegisterTypeLib(this, T2COLE(lpszIndex));
}
HRESULT UnRegisterTypeLib()
{
return AtlModuleUnRegisterTypeLib(this, NULL);
}
HRESULT UnRegisterTypeLib(LPCTSTR lpszIndex)
{
USES_CONVERSION;
return AtlModuleUnRegisterTypeLib(this, T2COLE(lpszIndex));
}
HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
{
return AtlModuleRegisterServer(this, bRegTypeLib, pCLSID);
}
HRESULT UnregisterServer(const CLSID* pCLSID = NULL)
{
return AtlModuleUnregisterServer(this, pCLSID);
}
HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL)
{
return AtlModuleUnregisterServerEx(this, bUnRegTypeLib, pCLSID);
}
// Resource-based Registration
HRESULT WINAPI UpdateRegistryFromResourceD(LPCTSTR lpszRes, BOOL bRegister,
struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
{
USES_CONVERSION;
return AtlModuleUpdateRegistryFromResourceD(this, T2COLE(lpszRes), bRegister,
pMapEntries);
}
HRESULT WINAPI UpdateRegistryFromResourceD(UINT nResID, BOOL bRegister,
struct _ATL_REGMAP_ENTRY* pMapEntries = NULL)
{
return AtlModuleUpdateRegistryFromResourceD(this,
(LPCOLESTR)MAKEINTRESOURCE(nResID), bRegister, pMapEntries);
}
#ifdef _ATL_STATIC_REGISTRY
// Statically linking to Registry Ponent
HRESULT WINAPI UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
HRESULT WINAPI UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
struct _ATL_REGMAP_ENTRY* pMapEntries = NULL);
#endif
// Standard Registration
HRESULT WINAPI UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister);
HRESULT WINAPI RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags);
HRESULT WINAPI UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
LPCTSTR lpszVerIndProgID);
// Register/Revoke All Class Factories with the OS (EXE only)
HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags)
{
return AtlModuleRegisterClassObjects(this, dwClsContext, dwFlags);
}
HRESULT RevokeClassObjects()
{
return AtlModuleRevokeClassObjects(this);
}
// Obtain a Class Factory (DLL only)
HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return AtlModuleGetClassObject(this, rclsid, riid, ppv);
}
// Only used in CComAutoThreadModule
HRESULT CreateInstance(void* /*pfnCreateInstance*/, REFIID /*riid*/, void** /*ppvObj*/)
{
ATLASSERT(FALSE);
return E_NOTIMPL;
}
static HRESULT RegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc);
static void ReplaceSingleQuote(LPOLESTR lpDest, LPCOLESTR lp)
{
while (*lp)
{
*lpDest++ = *lp;
if (*lp == OLESTR('\''))
*lpDest++ = *lp;
lp++;
}
*lpDest = NULL;
}
};
#ifdef _ATL_DEBUG_INTERFACES
inline ULONG _QIThunk::Release()
{
if (bBreak)
DebugBreak();
ATLASSERT(m_dwRef > 0);
ULONG l = InterlockedDecrement(&m_dwRef);
ATLTRACE(_T("%d< "), m_dwRef);
AtlDumpIID(iid, lpszClassName, S_OK);
pUnk->Release();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -