📄 atlbase.h
字号:
m_aVal[nIndex].~TVal();
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();
m_aVal[i].~TVal();
}
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);
}
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));
#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 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();
if (l == 0 && !bNonAddRefThunk)
_pModule->DeleteThunk(this);
return l;
}
inline static void atlBadThunkCall()
{
ATLASSERT(FALSE && "Call through deleted thunk");
}
#define IMPL_THUNK(n)\
__declspec(naked) inline HRESULT _QIThunk::f##n()\
{\
__asm mov eax, [esp+4]\
__asm cmp dword ptr [eax+8], 0\
__asm jg goodref\
__asm call atlBadThunkCall\
__asm goodref:\
__asm mov eax, [esp+4]\
__asm mov eax, dword ptr [eax+4]\
__asm mov [esp+4], eax\
__asm mov eax, dword ptr [eax]\
__asm mov eax, dword ptr [eax+4*n]\
__asm jmp eax\
}
IMPL_THUNK(3)
IMPL_THUNK(4)
IMPL_THUNK(5)
IMPL_THUNK(6)
IMPL_THUNK(7)
IMPL_THUNK(8)
IMPL_THUNK(9)
IMPL_THUNK(10)
IMPL_THUNK(11)
IMPL_THUNK(12)
IMPL_THUNK(13)
IMPL_THUNK(14)
IMPL_THUNK(15)
IMPL_THUNK(16)
IMPL_THUNK(17)
IMPL_THUNK(18)
IMPL_THUNK(19)
IMPL_THUNK(20)
IMPL_THUNK(21)
IMPL_THUNK(22)
IMPL_THUNK(23)
IMPL_THUNK(24)
IMPL_THUNK(25)
IMPL_THUNK(26)
IMPL_THUNK(27)
IMPL_THUNK(28)
IMPL_THUNK(29)
IMPL_THUNK(30)
IMPL_THUNK(31)
IMPL_THUNK(32)
IMPL_THUNK(33)
IMPL_THUNK(34)
IMPL_THUNK(35)
IMPL_THUNK(36)
IMPL_THUNK(37)
IMPL_THUNK(38)
IMPL_THUNK(39)
IMPL_THUNK(40)
IMPL_THUNK(41)
IMPL_THUNK(42)
IMPL_THUNK(43)
IMPL_THUNK(44)
IMPL_THUNK(45)
IMPL_THUNK(46)
IMPL_THUNK(47)
IMPL_THUNK(48)
IMPL_THUNK(49)
IMPL_THUNK(50)
IMPL_THUNK(51)
IMPL_THUNK(52)
IMPL_THUNK(53)
IMPL_THUNK(54)
IMPL_THUNK(55)
IMPL_THUNK(56)
IMPL_THUNK(57)
IMPL_THUNK(58)
IMPL_THUNK(59)
IMPL_THUNK(60)
IMPL_THUNK(61)
IMPL_THUNK(62)
IMPL_THUNK(63)
IMPL_THUNK(64)
IMPL_THUNK(65)
IMPL_THUNK(66)
IMPL_THUNK(67)
IMPL_THUNK(68)
IMPL_THUNK(69)
IMPL_THUNK(70)
IMPL_THUNK(71)
IMPL_THUNK(72)
IMPL_THUNK(73)
IMPL_THUNK(74)
IMPL_THUNK(75)
IMPL_THUNK(76)
IMPL_THUNK(77)
IMPL_THUNK(78)
IMPL_THUNK(79)
IMPL_THUNK(80)
IMPL_THUNK(81)
IMPL_THUNK(82)
IMPL_THUNK(83)
IMPL_THUNK(84)
IMPL_THUNK(85)
IMPL_THUNK(86)
IMPL_THUNK(87)
IMPL_THUNK(88)
IMPL_THUNK(89)
IMPL_THUNK(90)
IMPL_THUNK(91)
IMPL_THUNK(92)
IMPL_THUNK(93)
IMPL_THUNK(94)
IMPL_THUNK(95)
IMPL_THUNK(96)
IMPL_THUNK(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -