From d3519a4284ef90d076a6d84dfcb0ec4d83e63682 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Wed, 23 Sep 2015 20:05:31 +0000 Subject: [PATCH] [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 --- reactos/lib/atl/atlcore.h | 91 ++++++++ reactos/lib/atl/atlsimpstr.h | 435 ++++++++++++++++++++++++++++------- reactos/lib/atl/atlstr.h | 138 ++++++++--- reactos/lib/atl/cstringt.h | 151 +++++++----- 4 files changed, 651 insertions(+), 164 deletions(-) diff --git a/reactos/lib/atl/atlcore.h b/reactos/lib/atl/atlcore.h index 5b7dbbe44d1..f679568e80d 100644 --- a/reactos/lib/atl/atlcore.h +++ b/reactos/lib/atl/atlcore.h @@ -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(~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(~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 diff --git a/reactos/lib/atl/atlsimpstr.h b/reactos/lib/atl/atlsimpstr.h index f33b9f58eff..30de737e87c 100644 --- a/reactos/lib/atl/atlsimpstr.h +++ b/reactos/lib/atl/atlsimpstr.h @@ -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::XCHAR XCHAR; + typedef typename ChTraitsBase::PXSTR PXSTR; + typedef typename ChTraitsBase::PCXSTR PCXSTR; + typedef typename ChTraitsBase::YCHAR YCHAR; + typedef typename ChTraitsBase::PYSTR PYSTR; + typedef typename ChTraitsBase::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& 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::XCHAR XCHAR; - typedef typename ChTraitsBase::PXSTR PXSTR; - typedef typename ChTraitsBase::PCXSTR PCXSTR; - typedef typename ChTraitsBase::YCHAR YCHAR; - typedef typename ChTraitsBase::PYSTR PYSTR; - typedef typename ChTraitsBase::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(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(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& 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 \ No newline at end of file diff --git a/reactos/lib/atl/atlstr.h b/reactos/lib/atl/atlstr.h index 7764e38ca41..b16d44275da 100644 --- a/reactos/lib/atl/atlstr.h +++ b/reactos/lib/atl/atlstr.h @@ -2,42 +2,128 @@ #define __ATLSTR_H__ #pragma once - -#ifndef __cplusplus - #error ATL requires C++ compilation (use a .cpp suffix) -#endif - #include #include 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(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> +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>> CAtlStringW; diff --git a/reactos/lib/atl/cstringt.h b/reactos/lib/atl/cstringt.h index f72dfb54738..8f83e48dfa4 100644 --- a/reactos/lib/atl/cstringt.h +++ b/reactos/lib/atl/cstringt.h @@ -2,75 +2,122 @@ #define __CSTRINGT_H__ #pragma once - #include #include - #include #include - +#include 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 +class ChTraitsCRT : public ChTraitsBase<_CharType> +{ +public: + + static int __cdecl GetBaseTypeLength(_In_z_ LPCWSTR pszSource) throw() { - public: - - }; - - - - namespace _CSTRING_IMPL_ - { - template - 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 ::c_bIsMFCDLLTraits> + static int __cdecl GetBaseTypeLength( + _In_reads_(nLength) LPCWSTR pszSource, + _In_ int nLength) throw() { - public: - typedef CSimpleStringT::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 + struct _MFCDLLTraitsCheck + { + const static bool c_bIsMFCDLLTraits = false; }; +} + + +template +class CStringT : + public CSimpleStringT ::c_bIsMFCDLLTraits> +{ +public: + typedef CSimpleStringT::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