mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
[ATL]
- Add support for CAtlString and all its supporting base classes. - It doesn't do much more than assign wchat_t arrarys and call LoadString, but it's a full base to start adding more methods as people decide to. svn path=/trunk/; revision=69332
This commit is contained in:
parent
c43914c6a7
commit
d3519a4284
4 changed files with 651 additions and 164 deletions
|
@ -204,8 +204,99 @@ public:
|
|||
{
|
||||
return m_hInstResource;
|
||||
}
|
||||
|
||||
HINSTANCE SetResourceInstance(HINSTANCE hInst)
|
||||
{
|
||||
return static_cast< HINSTANCE >(InterlockedExchangePointer((void**)&m_hInstResource, hInst));
|
||||
}
|
||||
|
||||
HINSTANCE GetHInstanceAt(int i);
|
||||
};
|
||||
|
||||
extern CAtlBaseModule _AtlBaseModule;
|
||||
|
||||
|
||||
///
|
||||
// String Resource helper functions
|
||||
//
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
struct ATLSTRINGRESOURCEIMAGE
|
||||
{
|
||||
WORD nLength;
|
||||
WCHAR achString[];
|
||||
};
|
||||
#pragma warning(pop)
|
||||
|
||||
inline const ATLSTRINGRESOURCEIMAGE* _AtlGetStringResourceImage(
|
||||
_In_ HINSTANCE hInstance,
|
||||
_In_ HRSRC hResource,
|
||||
_In_ UINT id)
|
||||
{
|
||||
const ATLSTRINGRESOURCEIMAGE* pImage;
|
||||
const ATLSTRINGRESOURCEIMAGE* pImageEnd;
|
||||
ULONG nResourceSize;
|
||||
HGLOBAL hGlobal;
|
||||
UINT iIndex;
|
||||
|
||||
hGlobal = ::LoadResource(hInstance, hResource);
|
||||
if (hGlobal == NULL) return NULL;
|
||||
|
||||
pImage = (const ATLSTRINGRESOURCEIMAGE*)::LockResource(hGlobal);
|
||||
if (pImage == NULL) return NULL;
|
||||
|
||||
nResourceSize = ::SizeofResource(hInstance, hResource);
|
||||
pImageEnd = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + nResourceSize);
|
||||
iIndex = id & 0x000f;
|
||||
|
||||
while ((iIndex > 0) && (pImage < pImageEnd))
|
||||
{
|
||||
pImage = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + (sizeof(ATLSTRINGRESOURCEIMAGE) + (pImage->nLength * sizeof(WCHAR))));
|
||||
iIndex--;
|
||||
}
|
||||
|
||||
if (pImage >= pImageEnd) return NULL;
|
||||
if (pImage->nLength == 0) return NULL;
|
||||
|
||||
return pImage;
|
||||
}
|
||||
|
||||
inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
|
||||
_In_ HINSTANCE hInstance,
|
||||
_In_ UINT id) throw()
|
||||
{
|
||||
HRSRC hResource;
|
||||
hResource = ::FindResourceW(hInstance, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast<WORD>(~0))), (LPWSTR)RT_STRING);
|
||||
if (hResource == NULL) return NULL;
|
||||
return _AtlGetStringResourceImage(hInstance, hResource, id);
|
||||
}
|
||||
|
||||
inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
|
||||
_In_ HINSTANCE hInstance,
|
||||
_In_ UINT id,
|
||||
_In_ WORD wLanguage)
|
||||
{
|
||||
HRSRC hResource;
|
||||
hResource = ::FindResourceExW(hInstance, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast<WORD>(~0))), wLanguage);
|
||||
if (hResource == NULL) return NULL;
|
||||
return _AtlGetStringResourceImage(hInstance, hResource, id);
|
||||
}
|
||||
|
||||
inline HINSTANCE AtlFindStringResourceInstance(
|
||||
UINT nID,
|
||||
WORD wLanguage = 0)
|
||||
{
|
||||
const ATLSTRINGRESOURCEIMAGE* strRes = NULL;
|
||||
HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0);
|
||||
|
||||
for (int i = 1; hInst != NULL && strRes == NULL; hInst = _AtlBaseModule.GetHInstanceAt(i++))
|
||||
{
|
||||
strRes = AtlGetStringResourceImage(hInst, nID, wLanguage);
|
||||
if (strRes != NULL) return hInst;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}; // namespace ATL
|
||||
|
|
|
@ -8,125 +8,388 @@
|
|||
|
||||
namespace ATL
|
||||
{
|
||||
struct CStringData;
|
||||
struct CStringData;
|
||||
|
||||
__interface IAtlStringMgr
|
||||
__interface IAtlStringMgr
|
||||
{
|
||||
public:
|
||||
|
||||
_Ret_maybenull_ _Post_writable_byte_size_(sizeof(CStringData) + nAllocLength*nCharSize)
|
||||
CStringData* Allocate(
|
||||
_In_ int nAllocLength,
|
||||
_In_ int nCharSize
|
||||
);
|
||||
|
||||
void Free(
|
||||
_Inout_ CStringData* pData
|
||||
);
|
||||
|
||||
virtual _Ret_maybenull_ _Post_writable_byte_size_(sizeof(CStringData) + nAllocLength*nCharSize)
|
||||
CStringData* Reallocate(
|
||||
_Inout_ CStringData* pData,
|
||||
_In_ int nAllocLength,
|
||||
_In_ int nCharSize
|
||||
);
|
||||
|
||||
CStringData* GetNilString(void);
|
||||
IAtlStringMgr* Clone(void);
|
||||
};
|
||||
|
||||
|
||||
struct CStringData
|
||||
{
|
||||
IAtlStringMgr* pStringMgr;
|
||||
int nAllocLength;
|
||||
int nDataLength;
|
||||
long nRefs;
|
||||
|
||||
void* data() throw()
|
||||
{
|
||||
public:
|
||||
return (this + 1);
|
||||
}
|
||||
|
||||
_Ret_maybenull_ _Post_writable_byte_size_(sizeof(CStringData) + nAllocLength*nCharSize)
|
||||
CStringData* Allocate(
|
||||
_In_ int nAllocLength,
|
||||
_In_ int nCharSize) throw();
|
||||
|
||||
void Free(_Inout_ CStringData* pData) throw();
|
||||
|
||||
virtual _Ret_maybenull_ _Post_writable_byte_size_(sizeof(CStringData) + nAllocLength*nCharSize)
|
||||
CStringData* Reallocate(
|
||||
_Inout_ CStringData* pData,
|
||||
_In_ int nAllocLength,
|
||||
_In_ int nCharSize) throw();
|
||||
|
||||
CStringData* GetNilString() throw();
|
||||
|
||||
IAtlStringMgr* Clone() throw();
|
||||
};
|
||||
|
||||
struct CStringData
|
||||
void AddRef() throw()
|
||||
{
|
||||
IAtlStringMgr* pStringMgr;
|
||||
int nDataLength;
|
||||
int nAllocLength;
|
||||
long nRefs;
|
||||
ATLASSERT(nRefs > 0);
|
||||
_InterlockedIncrement(&nRefs);
|
||||
}
|
||||
|
||||
void* data() throw()
|
||||
void Release() throw()
|
||||
{
|
||||
ATLASSERT(nRefs != 0);
|
||||
|
||||
if (_InterlockedDecrement(&nRefs) <= 0)
|
||||
{
|
||||
return (this + 1);
|
||||
pStringMgr->Free(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AddRef() throw()
|
||||
bool IsLocked() const throw()
|
||||
{
|
||||
return (nRefs < 0);
|
||||
}
|
||||
|
||||
bool IsShared() const throw()
|
||||
{
|
||||
return (nRefs > 1);
|
||||
}
|
||||
};
|
||||
|
||||
class CNilStringData :
|
||||
public CStringData
|
||||
{
|
||||
public:
|
||||
CNilStringData() throw()
|
||||
{
|
||||
pStringMgr = NULL;
|
||||
nRefs = 2;
|
||||
nDataLength = 0;
|
||||
nAllocLength = 0;
|
||||
achNil[0] = 0;
|
||||
achNil[1] = 0;
|
||||
}
|
||||
|
||||
void SetManager(_In_ IAtlStringMgr* pMgr) throw()
|
||||
{
|
||||
ATLASSERT(pStringMgr == NULL);
|
||||
pStringMgr = pMgr;
|
||||
}
|
||||
|
||||
public:
|
||||
wchar_t achNil[2];
|
||||
};
|
||||
|
||||
template< typename BaseType = char >
|
||||
class ChTraitsBase
|
||||
{
|
||||
public:
|
||||
typedef char XCHAR;
|
||||
typedef LPSTR PXSTR;
|
||||
typedef LPCSTR PCXSTR;
|
||||
typedef wchar_t YCHAR;
|
||||
typedef LPWSTR PYSTR;
|
||||
typedef LPCWSTR PCYSTR;
|
||||
};
|
||||
|
||||
template<>
|
||||
class ChTraitsBase< wchar_t >
|
||||
{
|
||||
public:
|
||||
typedef wchar_t XCHAR;
|
||||
typedef LPWSTR PXSTR;
|
||||
typedef LPCWSTR PCXSTR;
|
||||
typedef char YCHAR;
|
||||
typedef LPSTR PYSTR;
|
||||
typedef LPCSTR PCYSTR;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template< typename BaseType, bool t_bMFCDLL = false>
|
||||
class CSimpleStringT
|
||||
{
|
||||
private:
|
||||
LPWSTR m_pszData;
|
||||
|
||||
public:
|
||||
typedef typename ChTraitsBase<BaseType>::XCHAR XCHAR;
|
||||
typedef typename ChTraitsBase<BaseType>::PXSTR PXSTR;
|
||||
typedef typename ChTraitsBase<BaseType>::PCXSTR PCXSTR;
|
||||
typedef typename ChTraitsBase<BaseType>::YCHAR YCHAR;
|
||||
typedef typename ChTraitsBase<BaseType>::PYSTR PYSTR;
|
||||
typedef typename ChTraitsBase<BaseType>::PCYSTR PCYSTR;
|
||||
|
||||
public:
|
||||
explicit CSimpleStringT(_Inout_ IAtlStringMgr* pStringMgr)
|
||||
{
|
||||
CStringData* pData = pStringMgr->GetNilString();
|
||||
Attach(pData);
|
||||
}
|
||||
|
||||
CSimpleStringT(_In_ const CSimpleStringT& strSrc)
|
||||
{
|
||||
CStringData* pSrcData = strSrc.GetData();
|
||||
CStringData* pNewData = CloneData(pSrcData);
|
||||
Attach(pNewData);
|
||||
}
|
||||
|
||||
CSimpleStringT(_In_ const CSimpleStringT<BaseType, !t_bMFCDLL>& strSrc)
|
||||
{
|
||||
CStringData* pSrcData = strSrc.GetData();
|
||||
CStringData* pNewData = CloneData(pSrcData);
|
||||
Attach(pNewData);
|
||||
}
|
||||
|
||||
CSimpleStringT& operator=(_In_opt_z_ PCXSTR pszSrc)
|
||||
{
|
||||
SetString(pszSrc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
operator PCXSTR() const throw()
|
||||
{
|
||||
return m_pszData;
|
||||
}
|
||||
|
||||
|
||||
void Empty() throw()
|
||||
{
|
||||
CStringData* pOldData = GetData();
|
||||
IAtlStringMgr* pStringMgr = pOldData->pStringMgr;
|
||||
if (pOldData->nDataLength == 0) return;
|
||||
|
||||
if (pOldData->IsLocked())
|
||||
{
|
||||
ATLASSERT(nRefs > 0);
|
||||
_InterlockedIncrement(&nRefs);
|
||||
SetLength(0);
|
||||
}
|
||||
|
||||
void Release() throw()
|
||||
else
|
||||
{
|
||||
ATLASSERT(nRefs != 0);
|
||||
pOldData->Release();
|
||||
CStringData* pNewData = pStringMgr->GetNilString();
|
||||
Attach(pNewData);
|
||||
}
|
||||
}
|
||||
|
||||
if (_InterlockedDecrement(&nRefs) <= 0)
|
||||
void SetString(_In_opt_z_ PCXSTR pszSrc)
|
||||
{
|
||||
SetString(pszSrc, StringLength(pszSrc));
|
||||
}
|
||||
|
||||
void SetString(_In_reads_opt_(nLength) PCXSTR pszSrc,
|
||||
_In_ int nLength)
|
||||
{
|
||||
if (nLength == 0)
|
||||
{
|
||||
Empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT nOldLength = GetLength();
|
||||
UINT_PTR nOffset = pszSrc - GetString();
|
||||
|
||||
PXSTR pszBuffer = GetBuffer(nLength);
|
||||
if (nOffset <= nOldLength)
|
||||
{
|
||||
pStringMgr->Free(this);
|
||||
CopyCharsOverlapped(pszBuffer, GetAllocLength(),
|
||||
pszBuffer + nOffset, nLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyChars(pszBuffer, GetAllocLength(), pszSrc, nLength);
|
||||
}
|
||||
ReleaseBufferSetLength(nLength);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template< typename BaseType = char >
|
||||
class ChTraitsBase
|
||||
static int __cdecl StringLength(_In_opt_z_ const wchar_t* psz) throw()
|
||||
{
|
||||
public:
|
||||
typedef char XCHAR;
|
||||
typedef LPSTR PXSTR;
|
||||
typedef LPCSTR PCXSTR;
|
||||
typedef wchar_t YCHAR;
|
||||
typedef LPWSTR PYSTR;
|
||||
typedef LPCWSTR PCYSTR;
|
||||
};
|
||||
if (psz == NULL) return 0;
|
||||
return (int)wcslen(psz);
|
||||
}
|
||||
|
||||
template<>
|
||||
class ChTraitsBase< wchar_t >
|
||||
PXSTR GetBuffer()
|
||||
{
|
||||
public:
|
||||
typedef wchar_t XCHAR;
|
||||
typedef LPWSTR PXSTR;
|
||||
typedef LPCWSTR PCXSTR;
|
||||
typedef char YCHAR;
|
||||
typedef LPSTR PYSTR;
|
||||
typedef LPCSTR PCYSTR;
|
||||
};
|
||||
CStringData* pData = GetData();
|
||||
if (pData->IsShared())
|
||||
{
|
||||
// We should fork here
|
||||
Fork(pData->nDataLength);
|
||||
}
|
||||
|
||||
return m_pszData;
|
||||
}
|
||||
|
||||
|
||||
template< typename BaseType, bool t_bMFCDLL = false>
|
||||
class CSimpleStringT
|
||||
int GetAllocLength() const throw()
|
||||
{
|
||||
public:
|
||||
typedef typename ChTraitsBase<BaseType>::XCHAR XCHAR;
|
||||
typedef typename ChTraitsBase<BaseType>::PXSTR PXSTR;
|
||||
typedef typename ChTraitsBase<BaseType>::PCXSTR PCXSTR;
|
||||
typedef typename ChTraitsBase<BaseType>::YCHAR YCHAR;
|
||||
typedef typename ChTraitsBase<BaseType>::PYSTR PYSTR;
|
||||
typedef typename ChTraitsBase<BaseType>::PCYSTR PCYSTR;
|
||||
return GetData()->nAllocLength;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit CSimpleStringT(_Inout_ IAtlStringMgr* pStringMgr)
|
||||
int GetLength() const throw()
|
||||
{
|
||||
return GetData()->nDataLength;
|
||||
}
|
||||
|
||||
PCXSTR GetString() const throw()
|
||||
{
|
||||
return m_pszData;
|
||||
}
|
||||
|
||||
void ReleaseBufferSetLength(_In_ int nNewLength)
|
||||
{
|
||||
ATLASSERT(nNewLength >= 0);
|
||||
SetLength(nNewLength);
|
||||
}
|
||||
|
||||
bool IsEmpty() const throw()
|
||||
{
|
||||
return (GetLength() == 0);
|
||||
}
|
||||
|
||||
_Ret_notnull_ _Post_writable_size_(nMinBufferLength + 1) PXSTR GetBuffer(_In_ int nMinBufferLength)
|
||||
{
|
||||
return PrepareWrite(nMinBufferLength);
|
||||
}
|
||||
|
||||
CStringData* GetData() const throw()
|
||||
{
|
||||
return reinterpret_cast<CStringData*>(m_pszData) - 1;
|
||||
}
|
||||
|
||||
static void __cdecl CopyChars(
|
||||
_Out_writes_to_(nDestLen, nChars) XCHAR* pchDest,
|
||||
_In_ size_t nDestLen,
|
||||
_In_reads_opt_(nChars) const XCHAR* pchSrc,
|
||||
_In_ int nChars) throw()
|
||||
{
|
||||
memcpy(pchDest, pchSrc, nChars * sizeof(XCHAR));
|
||||
}
|
||||
|
||||
static void __cdecl CopyCharsOverlapped(
|
||||
_Out_writes_to_(nDestLen, nDestLen) XCHAR* pchDest,
|
||||
_In_ size_t nDestLen,
|
||||
_In_reads_(nChars) const XCHAR* pchSrc,
|
||||
_In_ int nChars) throw()
|
||||
{
|
||||
memmove(pchDest, pchSrc, nChars * sizeof(XCHAR));
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void Attach(_Inout_ CStringData* pData) throw()
|
||||
{
|
||||
m_pszData = static_cast<PXSTR>(pData->data());
|
||||
}
|
||||
__declspec(noinline) void Fork(_In_ int nLength)
|
||||
{
|
||||
CStringData* pOldData = GetData();
|
||||
int nOldLength = pOldData->nDataLength;
|
||||
CStringData* pNewData = pOldData->pStringMgr->Clone()->Allocate(nLength, sizeof(XCHAR));
|
||||
if (pNewData == NULL)
|
||||
{
|
||||
ATLENSURE(pStringMgr != NULL);
|
||||
CStringData* pData = pStringMgr->GetNilString();
|
||||
Attach(pData);
|
||||
throw; // ThrowMemoryException();
|
||||
}
|
||||
int nCharsToCopy = ((nOldLength < nLength) ? nOldLength : nLength) + 1;
|
||||
CopyChars(PXSTR(pNewData->data()), nCharsToCopy,
|
||||
PCXSTR(pOldData->data()), nCharsToCopy);
|
||||
pNewData->nDataLength = nOldLength;
|
||||
pOldData->Release();
|
||||
Attach(pNewData);
|
||||
}
|
||||
|
||||
|
||||
PXSTR PrepareWrite(_In_ int nLength)
|
||||
{
|
||||
CStringData* pOldData = GetData();
|
||||
int nShared = 1 - pOldData->nRefs;
|
||||
int nTooShort = pOldData->nAllocLength - nLength;
|
||||
if ((nShared | nTooShort) < 0)
|
||||
{
|
||||
PrepareWrite2(nLength);
|
||||
}
|
||||
|
||||
CSimpleStringT(_In_ const CSimpleStringT& strSrc)
|
||||
return m_pszData;
|
||||
}
|
||||
void PrepareWrite2(_In_ int nLength)
|
||||
{
|
||||
CStringData* pOldData = GetData();
|
||||
if (pOldData->nDataLength > nLength)
|
||||
{
|
||||
CStringData* pSrcData = strSrc.GetData();
|
||||
CStringData* pNewData = CloneData(pSrcData);
|
||||
Attach(pNewData);
|
||||
nLength = pOldData->nDataLength;
|
||||
}
|
||||
|
||||
CSimpleStringT(_In_ const CSimpleStringT<BaseType, !t_bMFCDLL>& strSrc)
|
||||
if (pOldData->IsShared())
|
||||
{
|
||||
CStringData* pSrcData = strSrc.GetData();
|
||||
CStringData* pNewData = CloneData(pSrcData);
|
||||
Attach(pNewData);
|
||||
Fork(nLength);
|
||||
ATLASSERT(FALSE);
|
||||
}
|
||||
|
||||
|
||||
operator PCXSTR() const throw()
|
||||
else if (pOldData->nAllocLength < nLength)
|
||||
{
|
||||
return m_pszData;
|
||||
int nNewLength = pOldData->nAllocLength;
|
||||
if (nNewLength > 1024 * 1024 * 1024)
|
||||
{
|
||||
nNewLength += 1024 * 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
nNewLength = nNewLength + nNewLength / 2;
|
||||
}
|
||||
if (nNewLength < nLength)
|
||||
{
|
||||
nNewLength = nLength;
|
||||
}
|
||||
Reallocate(nNewLength);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
void Reallocate(_In_ int nLength)
|
||||
{
|
||||
CStringData* pOldData = GetData();
|
||||
ATLASSERT(pOldData->nAllocLength < nLength);
|
||||
IAtlStringMgr* pStringMgr = pOldData->pStringMgr;
|
||||
if (pOldData->nAllocLength >= nLength || nLength <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CStringData* pNewData = pStringMgr->Reallocate(pOldData, nLength, sizeof(XCHAR));
|
||||
if (pNewData == NULL) throw;
|
||||
|
||||
Attach(pNewData);
|
||||
}
|
||||
|
||||
void SetLength(_In_ int nLength)
|
||||
{
|
||||
ATLASSERT(nLength >= 0);
|
||||
ATLASSERT(nLength <= GetData()->nAllocLength);
|
||||
|
||||
if (nLength < 0 || nLength > GetData()->nAllocLength)
|
||||
throw;
|
||||
|
||||
GetData()->nDataLength = nLength;
|
||||
m_pszData[nLength] = 0;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2,42 +2,128 @@
|
|||
#define __ATLSTR_H__
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error ATL requires C++ compilation (use a .cpp suffix)
|
||||
#endif
|
||||
|
||||
#include <atlbase.h>
|
||||
#include <cstringt.h>
|
||||
|
||||
namespace ATL
|
||||
{
|
||||
template< typename _BaseType = char, class StringIterator = ChTraitsOS<_BaseType>>
|
||||
class StrTraitATL :
|
||||
public StringIterator
|
||||
|
||||
class CAtlStringMgr : public IAtlStringMgr
|
||||
{
|
||||
protected:
|
||||
IAtlMemMgr* m_MemMgr;
|
||||
CNilStringData m_NilStrData;
|
||||
|
||||
public:
|
||||
CAtlStringMgr(_In_opt_ IAtlMemMgr* MemMgr = NULL):
|
||||
m_MemMgr(MemMgr)
|
||||
{
|
||||
public:
|
||||
static HINSTANCE FindStringResourceInstance(_In_ UINT nID) throw()
|
||||
{
|
||||
return(AtlFindStringResourceInstance(nID));
|
||||
}
|
||||
m_NilStrData.SetManager(this);
|
||||
}
|
||||
|
||||
static IAtlStringMgr* GetDefaultManager() throw()
|
||||
{
|
||||
return CAtlStringMgr::GetInstance();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template< typename _CharType = wchar_t>
|
||||
class ChTraitsOS :
|
||||
public ChTraitsBase<_CharType>
|
||||
virtual ~CAtlStringMgr(void)
|
||||
{
|
||||
protected:
|
||||
}
|
||||
|
||||
public:
|
||||
static IAtlStringMgr* GetInstance(void)
|
||||
{
|
||||
static CWin32Heap Win32Heap(::GetProcessHeap());
|
||||
static CAtlStringMgr StringMgr(&Win32Heap);
|
||||
return &StringMgr;
|
||||
}
|
||||
|
||||
};
|
||||
virtual _Ret_maybenull_ _Post_writable_byte_size_(sizeof(CStringData) + NumChars * CharSize) CStringData* Allocate(
|
||||
_In_ int NumChars,
|
||||
_In_ int CharSize)
|
||||
{
|
||||
size_t SizeBytes;
|
||||
CStringData* StrData;
|
||||
|
||||
SizeBytes = sizeof(CStringData) + ((NumChars + 1) * CharSize);
|
||||
|
||||
StrData = static_cast<CStringData*>(m_MemMgr->Allocate(SizeBytes));
|
||||
if (StrData == NULL) return NULL;
|
||||
|
||||
StrData->pStringMgr = this;
|
||||
StrData->nRefs = 1;
|
||||
StrData->nAllocLength = NumChars;
|
||||
StrData->nDataLength = 0;
|
||||
|
||||
return StrData;
|
||||
}
|
||||
|
||||
virtual void Free(_In_ CStringData* StrData)
|
||||
{
|
||||
ATLASSERT(StrData->pStringMgr == this);
|
||||
m_MemMgr->Free(StrData);
|
||||
}
|
||||
|
||||
virtual _Ret_maybenull_ _Post_writable_byte_size_(sizeof(CStringData) + nChars*nCharSize) CStringData* Reallocate(
|
||||
_Inout_ _Post_readable_byte_size_(sizeof(CStringData)) CStringData* StrData,
|
||||
_In_ int nChars,
|
||||
_In_ int nCharSize) throw()
|
||||
{
|
||||
ATLASSERT(StrData->pStringMgr == this);
|
||||
|
||||
CStringData* pNewData;
|
||||
ULONG SizeBytes;
|
||||
ULONG nDataBytes;
|
||||
|
||||
nChars++;
|
||||
nDataBytes = nChars * nCharSize;
|
||||
SizeBytes = sizeof(CStringData) + nDataBytes;
|
||||
|
||||
pNewData = static_cast< CStringData* >(m_MemMgr->Reallocate(StrData, SizeBytes));
|
||||
if (pNewData == NULL) return NULL;
|
||||
|
||||
pNewData->nAllocLength = nChars - 1;
|
||||
return pNewData;
|
||||
}
|
||||
virtual CStringData* GetNilString() throw()
|
||||
{
|
||||
m_NilStrData.AddRef();
|
||||
return &m_NilStrData;
|
||||
}
|
||||
virtual IAtlStringMgr* Clone() throw()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool StaticInitialize()
|
||||
{
|
||||
GetInstance();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename _BaseType = char, class StringIterator = ChTraitsOS<_BaseType>>
|
||||
class StrTraitATL :
|
||||
public StringIterator
|
||||
{
|
||||
public:
|
||||
static HINSTANCE FindStringResourceInstance(_In_ UINT nID) throw()
|
||||
{
|
||||
return AtlFindStringResourceInstance(nID);
|
||||
}
|
||||
|
||||
static IAtlStringMgr* GetDefaultManager() throw()
|
||||
{
|
||||
return CAtlStringMgr::GetInstance();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template< typename _CharType = wchar_t>
|
||||
class ChTraitsOS :
|
||||
public ChTraitsBase<_CharType>
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
#ifndef _ATL_CSTRING_NO_CRT
|
||||
typedef CStringT<wchar_t, StrTraitATL<wchar_t, ChTraitsCRT<wchar_t>>> CAtlStringW;
|
||||
|
|
|
@ -2,75 +2,122 @@
|
|||
#define __CSTRINGT_H__
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atlsimpstr.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <atlmem.h>
|
||||
|
||||
namespace ATL
|
||||
{
|
||||
|
||||
template< typename _CharType = wchar_t>
|
||||
class ChTraitsCRT :
|
||||
public ChTraitsBase<_CharType>
|
||||
inline UINT WINAPI _AtlGetConversionACP() throw()
|
||||
{
|
||||
#ifdef _CONVERSION_DONT_USE_THREAD_LOCALE
|
||||
return CP_ACP;
|
||||
#else
|
||||
return CP_THREAD_ACP;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template<typename _CharType = wchar_t>
|
||||
class ChTraitsCRT : public ChTraitsBase<_CharType>
|
||||
{
|
||||
public:
|
||||
|
||||
static int __cdecl GetBaseTypeLength(_In_z_ LPCWSTR pszSource) throw()
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace _CSTRING_IMPL_
|
||||
{
|
||||
template <typename _CharType, class StringTraits>
|
||||
struct _MFCDLLTraitsCheck
|
||||
{
|
||||
const static bool c_bIsMFCDLLTraits = false;
|
||||
};
|
||||
return ::WideCharToMultiByte(_AtlGetConversionACP(), 0, pszSource, -1, NULL, 0, NULL, NULL) - 1;
|
||||
}
|
||||
|
||||
template< typename BaseType, class StringTraits>
|
||||
class CStringT :
|
||||
public CSimpleStringT <BaseType, _CSTRING_IMPL_::_MFCDLLTraitsCheck<BaseType, StringTraits>::c_bIsMFCDLLTraits>
|
||||
static int __cdecl GetBaseTypeLength(
|
||||
_In_reads_(nLength) LPCWSTR pszSource,
|
||||
_In_ int nLength) throw()
|
||||
{
|
||||
public:
|
||||
typedef CSimpleStringT<BaseType, _CSTRING_IMPL_::_MFCDLLTraitsCheck<BaseType, StringTraits>::c_bIsMFCDLLTraits> CThisSimpleString;
|
||||
typedef StringTraits StrTraits;
|
||||
typedef typename CThisSimpleString::XCHAR XCHAR;
|
||||
typedef typename CThisSimpleString::PXSTR PXSTR;
|
||||
typedef typename CThisSimpleString::PCXSTR PCXSTR;
|
||||
typedef typename CThisSimpleString::YCHAR YCHAR;
|
||||
typedef typename CThisSimpleString::PYSTR PYSTR;
|
||||
typedef typename CThisSimpleString::PCYSTR PCYSTR;
|
||||
return ::WideCharToMultiByte(CP_THREAD_ACP, 0, pszSource, nLength, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
public:
|
||||
CStringT() throw() :
|
||||
CThisSimpleString(StringTraits::GetDefaultManager())
|
||||
{
|
||||
}
|
||||
explicit CStringT( _In_ IAtlStringMgr* pStringMgr) throw() :
|
||||
CThisSimpleString(pStringMgr)
|
||||
{
|
||||
}
|
||||
static void __cdecl ConvertToBaseType(
|
||||
_Out_writes_(nDestLength) LPWSTR pszDest,
|
||||
_In_ int nDestLength,
|
||||
_In_ LPCWSTR pszSrc,
|
||||
_In_ int nSrcLength = -1)
|
||||
{
|
||||
if (nSrcLength == -1)
|
||||
nSrcLength = 1 + GetBaseTypeLength(pszSrc);
|
||||
|
||||
CStringT(_In_ const VARIANT& varSrc);
|
||||
CStringT(
|
||||
_In_ const VARIANT& varSrc,
|
||||
_In_ IAtlStringMgr* pStringMgr);
|
||||
wmemcpy(pszDest, pszSrc, nSrcLength);
|
||||
}
|
||||
};
|
||||
|
||||
static void __cdecl Construct(_In_ CStringT* pString)
|
||||
{
|
||||
new(pString)CStringT;
|
||||
}
|
||||
|
||||
CStringT(_In_ const CStringT& strSrc) :
|
||||
CThisSimpleString(strSrc)
|
||||
{
|
||||
}
|
||||
|
||||
namespace _CSTRING_IMPL_
|
||||
{
|
||||
template <typename _CharType, class StringTraits>
|
||||
struct _MFCDLLTraitsCheck
|
||||
{
|
||||
const static bool c_bIsMFCDLLTraits = false;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
template <typename BaseType, class StringTraits>
|
||||
class CStringT :
|
||||
public CSimpleStringT <BaseType, _CSTRING_IMPL_::_MFCDLLTraitsCheck<BaseType, StringTraits>::c_bIsMFCDLLTraits>
|
||||
{
|
||||
public:
|
||||
typedef CSimpleStringT<BaseType, _CSTRING_IMPL_::_MFCDLLTraitsCheck<BaseType, StringTraits>::c_bIsMFCDLLTraits> CThisSimpleString;
|
||||
typedef StringTraits StrTraits;
|
||||
typedef typename CThisSimpleString::XCHAR XCHAR;
|
||||
typedef typename CThisSimpleString::PXSTR PXSTR;
|
||||
typedef typename CThisSimpleString::PCXSTR PCXSTR;
|
||||
typedef typename CThisSimpleString::YCHAR YCHAR;
|
||||
typedef typename CThisSimpleString::PYSTR PYSTR;
|
||||
typedef typename CThisSimpleString::PCYSTR PCYSTR;
|
||||
|
||||
public:
|
||||
CStringT() throw() :
|
||||
CThisSimpleString(StringTraits::GetDefaultManager())
|
||||
{
|
||||
}
|
||||
|
||||
explicit CStringT( _In_ IAtlStringMgr* pStringMgr) throw() :
|
||||
CThisSimpleString(pStringMgr)
|
||||
{
|
||||
}
|
||||
|
||||
static void __cdecl Construct(_In_ CStringT* pString)
|
||||
{
|
||||
new pString (CStringT);
|
||||
}
|
||||
|
||||
CStringT(_In_ const CStringT& strSrc) :
|
||||
CThisSimpleString(strSrc)
|
||||
{
|
||||
}
|
||||
|
||||
CStringT& operator=(_In_opt_z_ PCXSTR pszSrc)
|
||||
{
|
||||
CThisSimpleString::operator=(pszSrc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_Check_return_ BOOL LoadString(_In_ HINSTANCE hInstance,
|
||||
_In_ UINT nID)
|
||||
{
|
||||
const ATLSTRINGRESOURCEIMAGE* pImage = AtlGetStringResourceImage(hInstance, nID);
|
||||
if (pImage == NULL) return FALSE;
|
||||
|
||||
int nLength = StringTraits::GetBaseTypeLength(pImage->achString, pImage->nLength);
|
||||
PXSTR pszBuffer = GetBuffer(nLength);
|
||||
StringTraits::ConvertToBaseType(pszBuffer, nLength, pImage->achString, pImage->nLength);
|
||||
ReleaseBufferSetLength(nLength);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace ATL
|
||||
|
||||
|
|
Loading…
Reference in a new issue