15 #error atlmisc.h requires atlapp.h to be included first 19 #ifdef _ATL_TMP_NO_CSTRING 20 #define _WTL_NO_CSTRING 23 #if defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING) 24 #error Conflicting options - both _WTL_USE_CSTRING and _WTL_NO_CSTRING are defined 25 #endif // defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING) 27 #if !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING) 28 #define _WTL_USE_CSTRING 29 #endif // !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING) 31 #ifndef _WTL_NO_CSTRING 32 #if defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT) 33 #error Cannot use CString floating point formatting with _ATL_MIN_CRT defined 34 #endif // defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT) 35 #endif // !_WTL_NO_CSTRING 62 #ifndef _WTL_NO_WTYPES 82 CSize(
int initCX,
int initCY)
90 *(SIZE*)
this = initSize;
95 *(POINT*)
this = initPt;
100 cx = (short)LOWORD(dwSize);
101 cy = (short)HIWORD(dwSize);
105 BOOL operator ==(SIZE size)
const 107 return (cx == size.cx && cy == size.cy);
110 BOOL operator !=(SIZE size)
const 112 return (cx != size.cx || cy != size.cy);
115 void operator +=(SIZE size)
121 void operator -=(SIZE size)
127 void SetSize(
int CX,
int CY)
134 CSize operator +(SIZE size)
const 136 return CSize(cx + size.cx, cy + size.cy);
139 CSize operator -(SIZE size)
const 141 return CSize(cx - size.cx, cy - size.cy);
144 CSize operator -()
const 146 return CSize(-cx, -cy);
150 CPoint operator +(POINT point)
const;
151 CPoint operator -(POINT point)
const;
154 CRect operator +(
const RECT* lpRect)
const;
155 CRect operator -(
const RECT* lpRect)
const;
172 CPoint(
int initX,
int initY)
180 *(POINT*)
this = initPt;
185 *(SIZE*)
this = initSize;
190 x = (short)LOWORD(dwPoint);
191 y = (short)HIWORD(dwPoint);
195 void Offset(
int xOffset,
int yOffset)
201 void Offset(POINT point)
207 void Offset(SIZE size)
213 BOOL operator ==(POINT point)
const 215 return (x == point.x && y == point.y);
218 BOOL operator !=(POINT point)
const 220 return (x != point.x || y != point.y);
223 void operator +=(SIZE size)
229 void operator -=(SIZE size)
235 void operator +=(POINT point)
241 void operator -=(POINT point)
247 void SetPoint(
int X,
int Y)
254 CPoint operator +(SIZE size)
const 256 return CPoint(x + size.cx, y + size.cy);
259 CPoint operator -(SIZE size)
const 261 return CPoint(x - size.cx, y - size.cy);
269 CPoint operator +(POINT point)
const 271 return CPoint(x + point.x, y + point.y);
275 CSize operator -(POINT point)
const 277 return CSize(x - point.x, y - point.y);
281 CRect operator +(
const RECT* lpRect)
const;
282 CRect operator -(
const RECT* lpRect)
const;
301 CRect(
int l,
int t,
int r,
int b)
309 CRect(
const RECT& srcRect)
311 ::CopyRect(
this, &srcRect);
314 CRect(LPCRECT lpSrcRect)
316 ::CopyRect(
this, lpSrcRect);
319 CRect(POINT point, SIZE size)
321 right = (left = point.x) + size.cx;
322 bottom = (top = point.y) + size.cy;
325 CRect(POINT topLeft, POINT bottomRight)
329 right = bottomRight.x;
330 bottom = bottomRight.y;
346 return CSize(right - left, bottom - top);
356 return *((
CPoint*)
this + 1);
359 const CPoint& TopLeft()
const 364 const CPoint& BottomRight()
const 366 return *((
CPoint*)
this + 1);
369 CPoint CenterPoint()
const 371 return CPoint((left + right) / 2, (top + bottom) / 2);
380 operator LPCRECT()
const 385 BOOL IsRectEmpty()
const 387 return ::IsRectEmpty(
this);
390 BOOL IsRectNull()
const 392 return (left == 0 && right == 0 && top == 0 && bottom == 0);
395 BOOL PtInRect(POINT point)
const 397 return ::PtInRect(
this, point);
401 void SetRect(
int x1,
int y1,
int x2,
int y2)
403 ::SetRect(
this, x1, y1, x2, y2);
406 void SetRect(POINT topLeft, POINT bottomRight)
408 ::SetRect(
this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
413 ::SetRectEmpty(
this);
416 void CopyRect(LPCRECT lpSrcRect)
418 ::CopyRect(
this, lpSrcRect);
421 BOOL EqualRect(LPCRECT lpRect)
const 423 return ::EqualRect(
this, lpRect);
426 void InflateRect(
int x,
int y)
428 ::InflateRect(
this, x, y);
431 void InflateRect(SIZE size)
433 ::InflateRect(
this, size.cx, size.cy);
436 void InflateRect(LPCRECT lpRect)
438 left -= lpRect->left;
440 right += lpRect->right;
441 bottom += lpRect->bottom;
444 void InflateRect(
int l,
int t,
int r,
int b)
452 void DeflateRect(
int x,
int y)
454 ::InflateRect(
this, -x, -y);
457 void DeflateRect(SIZE size)
459 ::InflateRect(
this, -size.cx, -size.cy);
462 void DeflateRect(LPCRECT lpRect)
464 left += lpRect->left;
466 right -= lpRect->right;
467 bottom -= lpRect->bottom;
470 void DeflateRect(
int l,
int t,
int r,
int b)
478 void OffsetRect(
int x,
int y)
480 ::OffsetRect(
this, x, y);
482 void OffsetRect(SIZE size)
484 ::OffsetRect(
this, size.cx, size.cy);
487 void OffsetRect(POINT point)
489 ::OffsetRect(
this, point.x, point.y);
512 bottom = Height() + y;
522 void MoveToXY(
int x,
int y)
528 void MoveToXY(POINT pt)
535 BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2)
537 return ::IntersectRect(
this, lpRect1, lpRect2);
540 BOOL UnionRect(LPCRECT lpRect1, LPCRECT lpRect2)
542 return ::UnionRect(
this, lpRect1, lpRect2);
545 BOOL SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2)
547 return ::SubtractRect(
this, lpRectSrc1, lpRectSrc2);
551 void operator =(
const RECT& srcRect)
553 ::CopyRect(
this, &srcRect);
556 BOOL operator ==(
const RECT& rect)
const 558 return ::EqualRect(
this, &rect);
561 BOOL operator !=(
const RECT& rect)
const 563 return !::EqualRect(
this, &rect);
566 void operator +=(POINT point)
568 ::OffsetRect(
this, point.x, point.y);
571 void operator +=(SIZE size)
573 ::OffsetRect(
this, size.cx, size.cy);
576 void operator +=(LPCRECT lpRect)
581 void operator -=(POINT point)
583 ::OffsetRect(
this, -point.x, -point.y);
586 void operator -=(SIZE size)
588 ::OffsetRect(
this, -size.cx, -size.cy);
591 void operator -=(LPCRECT lpRect)
596 void operator &=(
const RECT& rect)
598 ::IntersectRect(
this,
this, &rect);
601 void operator |=(
const RECT& rect)
603 ::UnionRect(
this,
this, &rect);
607 CRect operator +(POINT pt)
const 610 ::OffsetRect(&rect, pt.x, pt.y);
614 CRect operator -(POINT pt)
const 617 ::OffsetRect(&rect, -pt.x, -pt.y);
621 CRect operator +(LPCRECT lpRect)
const 624 rect.InflateRect(lpRect);
628 CRect operator +(SIZE size)
const 631 ::OffsetRect(&rect, size.cx, size.cy);
635 CRect operator -(SIZE size)
const 638 ::OffsetRect(&rect, -size.cx, -size.cy);
642 CRect operator -(LPCRECT lpRect)
const 645 rect.DeflateRect(lpRect);
649 CRect operator &(
const RECT& rect2)
const 652 ::IntersectRect(&rect,
this, &rect2);
656 CRect operator |(
const RECT& rect2)
const 659 ::UnionRect(&rect,
this, &rect2);
663 CRect MulDiv(
int nMultiplier,
int nDivisor)
const 666 ::MulDiv(left, nMultiplier, nDivisor),
667 ::MulDiv(top, nMultiplier, nDivisor),
668 ::MulDiv(right, nMultiplier, nDivisor),
669 ::MulDiv(bottom, nMultiplier, nDivisor));
676 inline CPoint CSize::operator +(POINT point)
const 677 {
return CPoint(cx + point.x, cy + point.y); }
679 inline CPoint CSize::operator -(POINT point)
const 680 {
return CPoint(cx - point.x, cy - point.y); }
682 inline CRect CSize::operator +(
const RECT* lpRect)
const 683 {
return CRect(lpRect) + *
this; }
685 inline CRect CSize::operator -(
const RECT* lpRect)
const 686 {
return CRect(lpRect) - *
this; }
691 inline CRect CPoint::operator +(
const RECT* lpRect)
const 692 {
return CRect(lpRect) + *
this; }
694 inline CRect CPoint::operator -(
const RECT* lpRect)
const 695 {
return CRect(lpRect) - *
this; }
697 #endif // !_WTL_NO_WTYPES 702 #if !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) 705 inline CSize operator *(SIZE s, Num n)
707 return CSize((
int)(s.cx * n), (
int)(s.cy * n));
711 inline void operator *=(SIZE & s, Num n)
717 inline CSize operator /(SIZE s, Num n)
719 return CSize((
int)(s.cx / n), (
int)(s.cy / n));
723 inline void operator /=(SIZE & s, Num n)
728 #endif // !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) 734 #ifndef _WTL_NO_CSTRING 744 {
return (TCHAR*)(
this + 1); }
752 _declspec(selectany)
int rgInitData[] = { -1, 0, 0, 0 };
754 _declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) +
sizeof(
CStringData));
768 ATLASSERT(stringSrc.GetData()->nRefs != 0);
769 if (stringSrc.GetData()->nRefs >= 0)
771 ATLASSERT(stringSrc.GetData() != _atltmpDataNil);
772 m_pchData = stringSrc.m_pchData;
773 InterlockedIncrement(&GetData()->nRefs);
778 *
this = stringSrc.m_pchData;
782 CString(TCHAR ch,
int nRepeat = 1)
784 ATLASSERT(!_istlead(ch));
788 if(AllocBuffer(nRepeat))
791 for (
int i = 0; i < nRepeat; i++)
794 memset(m_pchData, ch, nRepeat);
803 if (lpsz != NULL && HIWORD(lpsz) == NULL)
805 UINT nID = LOWORD((DWORD_PTR)lpsz);
806 if (!LoadString(nID))
807 ATLTRACE2(atlTraceUI, 0, _T(
"Warning: implicit LoadString(%u) in CString failed\n"), nID);
811 int nLen = SafeStrlen(lpsz);
814 if(AllocBuffer(nLen))
815 SecureHelper::memcpy_x(m_pchData, (nLen + 1) *
sizeof(TCHAR), lpsz, nLen *
sizeof(TCHAR));
824 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) 825 int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0;
827 int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0;
831 if(AllocBuffer(nSrcLen))
833 _mbstowcsz(m_pchData, lpsz, nSrcLen + 1);
842 int nSrcLen = (lpsz != NULL) ? (
int)wcslen(lpsz) : 0;
845 if(AllocBuffer(nSrcLen * 2))
847 _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1);
854 CString(LPCTSTR lpch,
int nLength)
859 if(AllocBuffer(nLength))
860 SecureHelper::memcpy_x(m_pchData, (nLength + 1) *
sizeof(TCHAR), lpch, nLength *
sizeof(TCHAR));
865 CString(LPCSTR lpsz,
int nLength)
870 if(AllocBuffer(nLength))
872 int n = ::MultiByteToWideChar(CP_ACP, 0, lpsz, nLength, m_pchData, nLength + 1);
873 ReleaseBuffer((n >= 0) ? n : -1);
878 CString(LPCWSTR lpsz,
int nLength)
883 if(((nLength * 2) > nLength) && AllocBuffer(nLength * 2))
885 int n = ::WideCharToMultiByte(CP_ACP, 0, lpsz, nLength, m_pchData, (nLength * 2) + 1, NULL, NULL);
886 ReleaseBuffer((n >= 0) ? n : -1);
892 CString(
const unsigned char* lpsz)
895 *
this = (LPCSTR)lpsz;
899 int GetLength()
const 901 return GetData()->nDataLength;
906 return GetData()->nDataLength == 0;
911 if (GetData()->nDataLength == 0)
914 if (GetData()->nRefs >= 0)
919 ATLASSERT(GetData()->nDataLength == 0);
920 ATLASSERT(GetData()->nRefs < 0 || GetData()->nAllocLength == 0);
923 TCHAR GetAt(
int nIndex)
const 925 ATLASSERT(nIndex >= 0);
926 ATLASSERT(nIndex < GetData()->nDataLength);
927 return m_pchData[nIndex];
930 TCHAR operator [](
int nIndex)
const 933 ATLASSERT(nIndex >= 0);
934 ATLASSERT(nIndex < GetData()->nDataLength);
935 return m_pchData[nIndex];
938 void SetAt(
int nIndex, TCHAR ch)
940 ATLASSERT(nIndex >= 0);
941 ATLASSERT(nIndex < GetData()->nDataLength);
944 m_pchData[nIndex] = ch;
947 operator LPCTSTR()
const 955 if (m_pchData != stringSrc.m_pchData)
957 if ((GetData()->nRefs < 0 && GetData() != _atltmpDataNil) || stringSrc.GetData()->nRefs < 0)
960 AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
966 ATLASSERT(stringSrc.GetData() != _atltmpDataNil);
967 m_pchData = stringSrc.m_pchData;
968 InterlockedIncrement(&GetData()->nRefs);
976 ATLASSERT(!_istlead(ch));
989 CString& operator =(LPCTSTR lpsz)
991 ATLASSERT(lpsz == NULL || _IsValidString(lpsz));
992 AssignCopy(SafeStrlen(lpsz), lpsz);
997 CString& operator =(LPCSTR lpsz)
999 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) 1000 int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0;
1002 int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0;
1004 if(AllocBeforeWrite(nSrcLen))
1006 _mbstowcsz(m_pchData, lpsz, nSrcLen + 1);
1012 CString& operator =(LPCWSTR lpsz)
1014 int nSrcLen = (lpsz != NULL) ? (
int)wcslen(lpsz) : 0;
1015 if(AllocBeforeWrite(nSrcLen * 2))
1017 _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1);
1024 CString& operator =(
const unsigned char* lpsz)
1026 *
this = (LPCSTR)lpsz;
1033 ConcatInPlace(
string.GetData()->nDataLength,
string.m_pchData);
1037 CString& operator +=(TCHAR ch)
1039 ConcatInPlace(1, &ch);
1051 CString& operator +=(LPCTSTR lpsz)
1053 ATLASSERT(lpsz == NULL || _IsValidString(lpsz));
1054 ConcatInPlace(SafeStrlen(lpsz), lpsz);
1059 friend CString __stdcall operator +(
const CString&
string, TCHAR ch);
1060 friend CString __stdcall operator +(TCHAR ch,
const CString&
string);
1062 friend CString __stdcall operator +(
const CString&
string,
char ch);
1063 friend CString __stdcall operator +(
char ch,
const CString&
string);
1065 friend CString __stdcall operator +(
const CString&
string, LPCTSTR lpsz);
1066 friend CString __stdcall operator +(LPCTSTR lpsz,
const CString&
string);
1069 int Compare(LPCTSTR lpsz)
const 1071 return _cstrcmp(m_pchData, lpsz);
1074 int CompareNoCase(LPCTSTR lpsz)
const 1076 return _cstrcmpi(m_pchData, lpsz);
1082 int Collate(LPCTSTR lpsz)
const 1084 return _cstrcoll(m_pchData, lpsz);
1087 int CollateNoCase(LPCTSTR lpsz)
const 1089 return _cstrcolli(m_pchData, lpsz);
1091 #endif // !_WIN32_WCE 1094 CString Mid(
int nFirst,
int nCount)
const 1102 if (nFirst + nCount > GetData()->nDataLength)
1103 nCount = GetData()->nDataLength - nFirst;
1104 if (nFirst > GetData()->nDataLength)
1108 AllocCopy(dest, nCount, nFirst, 0);
1114 return Mid(nFirst, GetData()->nDataLength - nFirst);
1117 CString Left(
int nCount)
const 1121 else if (nCount > GetData()->nDataLength)
1122 nCount = GetData()->nDataLength;
1125 AllocCopy(dest, nCount, 0, 0);
1129 CString Right(
int nCount)
const 1133 else if (nCount > GetData()->nDataLength)
1134 nCount = GetData()->nDataLength;
1137 AllocCopy(dest, nCount, GetData()->nDataLength-nCount, 0);
1141 CString SpanIncluding(LPCTSTR lpszCharSet)
const 1143 ATLASSERT(_IsValidString(lpszCharSet));
1144 return Left(_cstrspn(m_pchData, lpszCharSet));
1147 CString SpanExcluding(LPCTSTR lpszCharSet)
const 1149 ATLASSERT(_IsValidString(lpszCharSet));
1150 return Left(_cstrcspn(m_pchData, lpszCharSet));
1157 CharUpper(m_pchData);
1163 CharLower(m_pchData);
1169 _cstrrev(m_pchData);
1178 LPTSTR lpsz = m_pchData;
1179 LPTSTR lpszLast = NULL;
1180 while (*lpsz != _T(
'\0'))
1182 if (_cstrisspace(*lpsz))
1184 if (lpszLast == NULL)
1191 lpsz = ::CharNext(lpsz);
1194 if (lpszLast != NULL)
1197 *lpszLast = _T(
'\0');
1198 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1207 LPCTSTR lpsz = m_pchData;
1208 while (_cstrisspace(*lpsz))
1209 lpsz = ::CharNext(lpsz);
1212 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1213 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), lpsz, (nDataLength + 1) *
sizeof(TCHAR));
1214 GetData()->nDataLength = nDataLength;
1218 void TrimRight(TCHAR chTarget)
1224 LPTSTR lpsz = m_pchData;
1225 LPTSTR lpszLast = NULL;
1227 while (*lpsz != _T(
'\0'))
1229 if (*lpsz == chTarget)
1231 if (lpszLast == NULL)
1236 lpsz = ::CharNext(lpsz);
1239 if (lpszLast != NULL)
1242 *lpszLast = _T(
'\0');
1243 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1248 void TrimRight(LPCTSTR lpszTargetList)
1253 LPTSTR lpsz = m_pchData;
1254 LPTSTR lpszLast = NULL;
1256 while (*lpsz != _T(
'\0'))
1258 TCHAR* pNext = ::CharNext(lpsz);
1259 if(pNext > lpsz + 1)
1261 if (_cstrchr_db(lpszTargetList, *lpsz, *(lpsz + 1)) != NULL)
1263 if (lpszLast == NULL)
1273 if (_cstrchr(lpszTargetList, *lpsz) != NULL)
1275 if (lpszLast == NULL)
1287 if (lpszLast != NULL)
1290 *lpszLast = _T(
'\0');
1291 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1296 void TrimLeft(TCHAR chTarget)
1301 LPCTSTR lpsz = m_pchData;
1303 while (chTarget == *lpsz)
1304 lpsz = ::CharNext(lpsz);
1306 if (lpsz != m_pchData)
1309 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1310 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), lpsz, (nDataLength + 1) *
sizeof(TCHAR));
1311 GetData()->nDataLength = nDataLength;
1316 void TrimLeft(LPCTSTR lpszTargets)
1319 if (SafeStrlen(lpszTargets) == 0)
1323 LPCTSTR lpsz = m_pchData;
1325 while (*lpsz != _T(
'\0'))
1327 TCHAR* pNext = ::CharNext(lpsz);
1328 if(pNext > lpsz + 1)
1330 if (_cstrchr_db(lpszTargets, *lpsz, *(lpsz + 1)) == NULL)
1335 if (_cstrchr(lpszTargets, *lpsz) == NULL)
1341 if (lpsz != m_pchData)
1344 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1345 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), lpsz, (nDataLength + 1) *
sizeof(TCHAR));
1346 GetData()->nDataLength = nDataLength;
1352 int Replace(TCHAR chOld, TCHAR chNew)
1361 LPTSTR psz = m_pchData;
1362 LPTSTR pszEnd = psz + GetData()->nDataLength;
1363 while (psz < pszEnd)
1371 psz = ::CharNext(psz);
1379 int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew)
1383 int nSourceLen = SafeStrlen(lpszOld);
1384 if (nSourceLen == 0)
1386 int nReplacementLen = SafeStrlen(lpszNew);
1390 LPTSTR lpszStart = m_pchData;
1391 LPTSTR lpszEnd = m_pchData + GetData()->nDataLength;
1392 LPTSTR lpszTarget = NULL;
1393 while (lpszStart < lpszEnd)
1395 while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL)
1398 lpszStart = lpszTarget + nSourceLen;
1400 lpszStart += lstrlen(lpszStart) + 1;
1409 int nOldLength = GetData()->nDataLength;
1410 int nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount;
1411 if (GetData()->nAllocLength < nNewLength || GetData()->nRefs > 1)
1414 LPTSTR pstr = m_pchData;
1415 if(!AllocBuffer(nNewLength))
1417 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) *
sizeof(TCHAR), pstr, pOldData->nDataLength *
sizeof(TCHAR));
1418 CString::Release(pOldData);
1421 lpszStart = m_pchData;
1422 lpszEnd = m_pchData + GetData()->nDataLength;
1425 while (lpszStart < lpszEnd)
1427 while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL)
1429 int nBalance = nOldLength - ((int)(DWORD_PTR)(lpszTarget - m_pchData) + nSourceLen);
1430 int cchBuffLen = GetData()->nAllocLength - (int)(DWORD_PTR)(lpszTarget - m_pchData);
1431 SecureHelper::memmove_x(lpszTarget + nReplacementLen, (cchBuffLen - nReplacementLen + 1) *
sizeof(TCHAR), lpszTarget + nSourceLen, nBalance *
sizeof(TCHAR));
1432 SecureHelper::memcpy_x(lpszTarget, (cchBuffLen + 1) *
sizeof(TCHAR), lpszNew, nReplacementLen *
sizeof(TCHAR));
1433 lpszStart = lpszTarget + nReplacementLen;
1434 lpszStart[nBalance] = _T(
'\0');
1435 nOldLength += (nReplacementLen - nSourceLen);
1437 lpszStart += lstrlen(lpszStart) + 1;
1439 ATLASSERT(m_pchData[nNewLength] == _T(
'\0'));
1440 GetData()->nDataLength = nNewLength;
1447 int Remove(TCHAR chRemove)
1451 LPTSTR pstrSource = m_pchData;
1452 LPTSTR pstrDest = m_pchData;
1453 LPTSTR pstrEnd = m_pchData + GetData()->nDataLength;
1455 while (pstrSource < pstrEnd)
1457 if (*pstrSource != chRemove)
1459 *pstrDest = *pstrSource;
1460 pstrDest = ::CharNext(pstrDest);
1462 pstrSource = ::CharNext(pstrSource);
1464 *pstrDest = _T(
'\0');
1465 int nCount = (int)(DWORD_PTR)(pstrSource - pstrDest);
1466 GetData()->nDataLength -= nCount;
1472 int Insert(
int nIndex, TCHAR ch)
1479 int nNewLength = GetData()->nDataLength;
1480 if (nIndex > nNewLength)
1481 nIndex = nNewLength;
1484 if (GetData()->nAllocLength < nNewLength)
1487 LPTSTR pstr = m_pchData;
1488 if(!AllocBuffer(nNewLength))
1490 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) *
sizeof(TCHAR), pstr, (pOldData->nDataLength + 1) *
sizeof(TCHAR));
1491 CString::Release(pOldData);
1495 SecureHelper::memmove_x(m_pchData + nIndex + 1, (GetData()->nAllocLength - nIndex) *
sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex) *
sizeof(TCHAR));
1496 m_pchData[nIndex] = ch;
1497 GetData()->nDataLength = nNewLength;
1503 int Insert(
int nIndex, LPCTSTR pstr)
1508 int nInsertLength = SafeStrlen(pstr);
1509 int nNewLength = GetData()->nDataLength;
1510 if (nInsertLength > 0)
1513 if (nIndex > nNewLength)
1514 nIndex = nNewLength;
1515 nNewLength += nInsertLength;
1517 if (GetData()->nAllocLength < nNewLength)
1520 LPTSTR pstrTmp = m_pchData;
1521 if(!AllocBuffer(nNewLength))
1523 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) *
sizeof(TCHAR), pstrTmp, (pOldData->nDataLength + 1) *
sizeof(TCHAR));
1524 CString::Release(pOldData);
1528 SecureHelper::memmove_x(m_pchData + nIndex + nInsertLength, (GetData()->nAllocLength + 1 - nIndex - nInsertLength) *
sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex - nInsertLength + 1) *
sizeof(TCHAR));
1529 SecureHelper::memcpy_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) *
sizeof(TCHAR), pstr, nInsertLength *
sizeof(TCHAR));
1530 GetData()->nDataLength = nNewLength;
1537 int Delete(
int nIndex,
int nCount = 1)
1541 int nLength = GetData()->nDataLength;
1542 if (nCount > 0 && nIndex < nLength)
1544 if((nIndex + nCount) > nLength)
1545 nCount = nLength - nIndex;
1547 int nBytesToCopy = nLength - (nIndex + nCount) + 1;
1549 SecureHelper::memmove_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) *
sizeof(TCHAR), m_pchData + nIndex + nCount, nBytesToCopy *
sizeof(TCHAR));
1551 GetData()->nDataLength = nLength;
1559 int Find(TCHAR ch)
const 1564 int ReverseFind(TCHAR ch)
const 1567 LPCTSTR lpsz = _cstrrchr(m_pchData, (_TUCHAR)ch);
1570 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1573 int Find(TCHAR ch,
int nStart)
const 1575 int nLength = GetData()->nDataLength;
1576 if (nStart < 0 || nStart >= nLength)
1580 LPCTSTR lpsz = _cstrchr(m_pchData + nStart, (_TUCHAR)ch);
1583 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1586 int FindOneOf(LPCTSTR lpszCharSet)
const 1588 ATLASSERT(_IsValidString(lpszCharSet));
1589 LPCTSTR lpsz = _cstrpbrk(m_pchData, lpszCharSet);
1590 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1595 int Find(LPCTSTR lpszSub)
const 1597 return Find(lpszSub, 0);
1600 int Find(LPCTSTR lpszSub,
int nStart)
const 1602 ATLASSERT(_IsValidString(lpszSub));
1604 int nLength = GetData()->nDataLength;
1605 if (nStart < 0 || nStart > nLength)
1609 LPCTSTR lpsz = _cstrstr(m_pchData + nStart, lpszSub);
1612 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1618 const int cchBuff = 12;
1619 TCHAR szBuffer[cchBuff] = { 0 };
1620 SecureHelper::wsprintf_x(szBuffer, cchBuff, _T(
"%d"), n);
1621 ConcatInPlace(SafeStrlen(szBuffer), szBuffer);
1627 BOOL __cdecl Format(LPCTSTR lpszFormat, ...)
1629 ATLASSERT(_IsValidString(lpszFormat));
1632 va_start(argList, lpszFormat);
1633 BOOL bRet = FormatV(lpszFormat, argList);
1638 BOOL __cdecl Format(UINT nFormatID, ...)
1641 BOOL bRet = strFormat.LoadString(nFormatID);
1642 ATLASSERT(bRet != 0);
1645 va_start(argList, nFormatID);
1646 bRet = FormatV(strFormat, argList);
1651 BOOL FormatV(LPCTSTR lpszFormat, va_list argList)
1653 ATLASSERT(_IsValidString(lpszFormat));
1655 enum _FormatModifiers
1657 FORCE_ANSI = 0x10000,
1658 FORCE_UNICODE = 0x20000,
1659 FORCE_INT64 = 0x40000
1662 va_list argListSave = argList;
1666 for (LPCTSTR lpsz = lpszFormat; *lpsz != _T(
'\0'); lpsz = ::CharNext(lpsz))
1669 if (*lpsz != _T(
'%') || *(lpsz = ::CharNext(lpsz)) == _T(
'%'))
1671 nMaxLen += (int)(::CharNext(lpsz) - lpsz);
1679 for (; *lpsz != _T(
'\0'); lpsz = ::CharNext(lpsz))
1682 if (*lpsz == _T(
'#'))
1684 else if (*lpsz == _T(
'*'))
1685 nWidth = va_arg(argList,
int);
1686 else if (*lpsz == _T(
'-') || *lpsz == _T(
'+') || *lpsz == _T(
'0') || *lpsz == _T(
' '))
1695 nWidth = _cstrtoi(lpsz);
1696 for (; *lpsz != _T(
'\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
1699 ATLASSERT(nWidth >= 0);
1702 if (*lpsz == _T(
'.'))
1705 lpsz = ::CharNext(lpsz);
1708 if (*lpsz == _T(
'*'))
1710 nPrecision = va_arg(argList,
int);
1711 lpsz = ::CharNext(lpsz);
1715 nPrecision = _cstrtoi(lpsz);
1716 for (; *lpsz != _T(
'\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
1719 ATLASSERT(nPrecision >= 0);
1724 if(lpsz[0] == _T(
'I'))
1726 if((lpsz[1] == _T(
'6')) && (lpsz[2] == _T(
'4')))
1729 nModifier = FORCE_INT64;
1731 else if((lpsz[1] == _T(
'3')) && (lpsz[2] == _T(
'2')))
1738 if(
sizeof(
size_t) == 8)
1739 nModifier = FORCE_INT64;
1748 nModifier = FORCE_ANSI;
1749 lpsz = ::CharNext(lpsz);
1752 nModifier = FORCE_UNICODE;
1753 lpsz = ::CharNext(lpsz);
1760 lpsz = ::CharNext(lpsz);
1766 switch (*lpsz | nModifier)
1772 va_arg(argList, TCHAR);
1774 case _T(
'c') | FORCE_ANSI:
1775 case _T(
'C') | FORCE_ANSI:
1777 va_arg(argList,
char);
1779 case _T(
'c') | FORCE_UNICODE:
1780 case _T(
'C') | FORCE_UNICODE:
1782 va_arg(argList, WCHAR);
1788 LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR);
1789 if (pstrNextArg == NULL)
1795 nItemLen = lstrlen(pstrNextArg);
1796 nItemLen = __max(1, nItemLen);
1804 LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
1805 if (pstrNextArg == NULL)
1811 nItemLen = (int)wcslen(pstrNextArg);
1812 nItemLen = __max(1, nItemLen);
1815 LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
1816 if (pstrNextArg == NULL)
1822 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) 1823 nItemLen = ATL::lstrlenA(pstrNextArg);
1825 nItemLen = lstrlenA(pstrNextArg);
1827 nItemLen = __max(1, nItemLen);
1833 case _T(
's') | FORCE_ANSI:
1834 case _T(
'S') | FORCE_ANSI:
1836 LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
1837 if (pstrNextArg == NULL)
1843 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) 1844 nItemLen = ATL::lstrlenA(pstrNextArg);
1846 nItemLen = lstrlenA(pstrNextArg);
1848 nItemLen = __max(1, nItemLen);
1853 case _T(
's') | FORCE_UNICODE:
1854 case _T(
'S') | FORCE_UNICODE:
1856 LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
1857 if (pstrNextArg == NULL)
1863 nItemLen = (int)wcslen(pstrNextArg);
1864 nItemLen = __max(1, nItemLen);
1873 nItemLen = __max(nItemLen, nWidth);
1874 if (nPrecision != 0)
1875 nItemLen = __min(nItemLen, nPrecision);
1888 if (nModifier & FORCE_INT64)
1889 va_arg(argList, __int64);
1891 va_arg(argList,
int);
1893 nItemLen = __max(nItemLen, nWidth + nPrecision);
1896 #ifndef _ATL_USE_CSTRING_FLOAT 1902 ATLASSERT(!
"Floating point (%%e, %%E, %%f, %%g, and %%G) is not supported by the WTL::CString class.");
1904 ::OutputDebugString(_T(
"Floating point (%%e, %%f, %%g, and %%G) is not supported by the WTL::CString class."));
1907 #else // CE specific 1909 #endif // _WIN32_WCE 1912 #else // _ATL_USE_CSTRING_FLOAT 1917 va_arg(argList,
double);
1919 nItemLen = __max(nItemLen, nWidth + nPrecision);
1923 double f = va_arg(argList,
double);
1928 int cchLen = __max(nWidth, 312 + nPrecision + 6);
1930 LPTSTR pszTemp = buff.Allocate(cchLen);
1933 SecureHelper::sprintf_x(pszTemp, cchLen, _T(
"%*.*f"), nWidth, nPrecision + 6, f);
1934 nItemLen = (int)_tcslen(pszTemp);
1942 #endif // _ATL_USE_CSTRING_FLOAT 1945 va_arg(argList,
void*);
1947 nItemLen = __max(nItemLen, nWidth + nPrecision);
1952 va_arg(argList,
int*);
1961 nMaxLen += nItemLen;
1964 if(GetBuffer(nMaxLen) == NULL)
1966 #ifndef _ATL_USE_CSTRING_FLOAT 1967 int nRet = SecureHelper::wvsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave);
1968 #else // _ATL_USE_CSTRING_FLOAT 1969 int nRet = SecureHelper::vsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave);
1970 #endif // _ATL_USE_CSTRING_FLOAT 1972 ATLASSERT(nRet <= GetAllocLength());
1975 va_end(argListSave);
1981 BOOL __cdecl FormatMessage(LPCTSTR lpszFormat, ...)
1985 va_start(argList, lpszFormat);
1986 LPTSTR lpszTemp = NULL;
1989 if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1990 lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) || (lpszTemp == NULL))
1995 LocalFree(lpszTemp);
2000 BOOL __cdecl FormatMessage(UINT nFormatID, ...)
2004 BOOL bRetTmp = strFormat.LoadString(nFormatID);
2006 ATLASSERT(bRetTmp != 0);
2010 va_start(argList, nFormatID);
2011 LPTSTR lpszTemp = NULL;
2014 if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
2015 strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) || (lpszTemp == NULL))
2020 LocalFree(lpszTemp);
2026 BOOL LoadString(UINT nID)
2029 const int CHAR_FUDGE = 1;
2031 const int CHAR_FUDGE = 2;
2035 TCHAR szTemp[256] = { 0 };
2036 int nCount =
sizeof(szTemp) /
sizeof(szTemp[0]);
2037 int nLen = _LoadString(nID, szTemp, nCount);
2038 if (nCount - nLen > CHAR_FUDGE)
2049 LPTSTR lpstr = GetBuffer(nSize - 1);
2055 nLen = _LoadString(nID, lpstr, nSize);
2056 }
while (nSize - nLen <= CHAR_FUDGE);
2067 ::AnsiToOem(m_pchData, m_pchData);
2073 ::OemToAnsi(m_pchData, m_pchData);
2079 BSTR AllocSysString()
const 2081 #if defined(_UNICODE) || defined(OLE2ANSI) 2082 BSTR bstr = ::SysAllocStringLen(m_pchData, GetData()->nDataLength);
2084 int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData,
2085 GetData()->nDataLength, NULL, NULL);
2086 BSTR bstr = ::SysAllocStringLen(NULL, nLen);
2088 MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, bstr, nLen);
2093 BSTR SetSysString(BSTR* pbstr)
const 2095 #if defined(_UNICODE) || defined(OLE2ANSI) 2096 ::SysReAllocStringLen(pbstr, m_pchData, GetData()->nDataLength);
2098 int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData,
2099 GetData()->nDataLength, NULL, NULL);
2100 if(::SysReAllocStringLen(pbstr, NULL, nLen))
2101 MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, *pbstr, nLen);
2103 ATLASSERT(*pbstr != NULL);
2106 #endif // !_ATL_NO_COM 2109 LPTSTR GetBuffer(
int nMinBufLength)
2111 ATLASSERT(nMinBufLength >= 0);
2113 if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength)
2117 int nOldLen = GetData()->nDataLength;
2118 if (nMinBufLength < nOldLen)
2119 nMinBufLength = nOldLen;
2121 if(!AllocBuffer(nMinBufLength))
2124 SecureHelper::memcpy_x(m_pchData, (nMinBufLength + 1) *
sizeof(TCHAR), pOldData->data(), (nOldLen + 1) *
sizeof(TCHAR));
2125 GetData()->nDataLength = nOldLen;
2126 CString::Release(pOldData);
2128 ATLASSERT(GetData()->nRefs <= 1);
2131 ATLASSERT(m_pchData != NULL);
2135 void ReleaseBuffer(
int nNewLength = -1)
2139 if (nNewLength == -1)
2140 nNewLength = lstrlen(m_pchData);
2142 ATLASSERT(nNewLength <= GetData()->nAllocLength);
2143 GetData()->nDataLength = nNewLength;
2144 m_pchData[nNewLength] = _T(
'\0');
2147 LPTSTR GetBufferSetLength(
int nNewLength)
2149 ATLASSERT(nNewLength >= 0);
2151 if(GetBuffer(nNewLength) == NULL)
2154 GetData()->nDataLength = nNewLength;
2155 m_pchData[nNewLength] = _T(
'\0');
2161 ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
2162 if (GetData()->nDataLength != GetData()->nAllocLength)
2165 if(AllocBuffer(GetData()->nDataLength))
2167 SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), pOldData->data(), pOldData->nDataLength *
sizeof(TCHAR));
2168 ATLASSERT(m_pchData[GetData()->nDataLength] == _T(
'\0'));
2169 CString::Release(pOldData);
2172 ATLASSERT(GetData() != NULL);
2178 LPTSTR lpsz = GetBuffer(0);
2180 GetData()->nRefs = -1;
2186 ATLASSERT(GetData()->nRefs == -1);
2187 if (GetData() != _atltmpDataNil)
2188 GetData()->nRefs = 1;
2195 if (GetData() != _atltmpDataNil)
2197 if (InterlockedDecrement(&GetData()->nRefs) <= 0)
2198 delete[] (BYTE*)GetData();
2202 int GetAllocLength()
const 2204 return GetData()->nAllocLength;
2207 static BOOL __stdcall _IsValidString(LPCTSTR lpsz,
int = -1)
2209 return (lpsz != NULL) ? TRUE : FALSE;
2218 ATLASSERT(m_pchData != NULL);
2224 m_pchData = _GetEmptyString().m_pchData;
2227 BOOL AllocCopy(
CString& dest,
int nCopyLen,
int nCopyIndex,
int nExtraLen)
const 2235 int nNewLen = nCopyLen + nExtraLen;
2241 else if(nNewLen >= nCopyLen)
2243 if(dest.AllocBuffer(nNewLen))
2245 SecureHelper::memcpy_x(dest.m_pchData, (nNewLen + 1) *
sizeof(TCHAR), m_pchData + nCopyIndex, nCopyLen *
sizeof(TCHAR));
2255 BOOL AllocBuffer(
int nLen)
2257 ATLASSERT(nLen >= 0);
2258 ATLASSERT(nLen <= INT_MAX - 1);
2272 pData->data()[nLen] = _T(
'\0');
2273 pData->nDataLength = nLen;
2274 pData->nAllocLength = nLen;
2275 m_pchData = pData->data();
2290 void AssignCopy(
int nSrcLen, LPCTSTR lpszSrcData)
2292 if(AllocBeforeWrite(nSrcLen))
2294 SecureHelper::memcpy_x(m_pchData, (nSrcLen + 1) *
sizeof(TCHAR), lpszSrcData, nSrcLen *
sizeof(TCHAR));
2295 GetData()->nDataLength = nSrcLen;
2296 m_pchData[nSrcLen] = _T(
'\0');
2307 BOOL ConcatCopy(
int nSrc1Len, LPCTSTR lpszSrc1Data,
int nSrc2Len, LPCTSTR lpszSrc2Data)
2314 int nNewLen = nSrc1Len + nSrc2Len;
2315 if(nNewLen < nSrc1Len || nNewLen < nSrc2Len)
2319 else if(nNewLen != 0)
2321 bRet = AllocBuffer(nNewLen);
2324 SecureHelper::memcpy_x(m_pchData, (nNewLen + 1) *
sizeof(TCHAR), lpszSrc1Data, nSrc1Len *
sizeof(TCHAR));
2325 SecureHelper::memcpy_x(m_pchData + nSrc1Len, (nNewLen + 1 - nSrc1Len) *
sizeof(TCHAR), lpszSrc2Data, nSrc2Len *
sizeof(TCHAR));
2331 void ConcatInPlace(
int nSrcLen, LPCTSTR lpszSrcData)
2341 if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
2345 if (ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData))
2347 ATLASSERT(pOldData != NULL);
2348 CString::Release(pOldData);
2354 SecureHelper::memcpy_x(m_pchData + GetData()->nDataLength, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), lpszSrcData, nSrcLen *
sizeof(TCHAR));
2355 GetData()->nDataLength += nSrcLen;
2356 ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
2357 m_pchData[GetData()->nDataLength] = _T(
'\0');
2361 void CopyBeforeWrite()
2363 if (GetData()->nRefs > 1)
2367 if(AllocBuffer(pData->nDataLength))
2368 SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), pData->data(), (pData->nDataLength + 1) *
sizeof(TCHAR));
2370 ATLASSERT(GetData()->nRefs <= 1);
2373 BOOL AllocBeforeWrite(
int nLen)
2376 if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
2379 bRet = AllocBuffer(nLen);
2381 ATLASSERT(GetData()->nRefs <= 1);
2387 if (GetData() != _atltmpDataNil)
2389 ATLASSERT(GetData()->nRefs != 0);
2390 if (InterlockedDecrement(&GetData()->nRefs) <= 0)
2391 delete[] (BYTE*)GetData();
2398 if (pData != _atltmpDataNil)
2400 ATLASSERT(pData->nRefs != 0);
2401 if (InterlockedDecrement(&pData->nRefs) <= 0)
2402 delete[] (BYTE*)pData;
2406 static int PASCAL SafeStrlen(LPCTSTR lpsz)
2408 return (lpsz == NULL) ? 0 : lstrlen(lpsz);
2411 static int __stdcall _LoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf)
2416 if (::FindResource(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE((nID >> 4) + 1), RT_STRING) == NULL)
2418 lpszBuf[0] = _T(
'\0');
2423 int nLen = ::LoadString(ModuleHelper::GetResourceInstance(), nID, lpszBuf, nMaxBuf);
2425 lpszBuf[0] = _T(
'\0');
2430 static const CString& __stdcall _GetEmptyString()
2432 return *(
CString*)&_atltmpPchNil;
2436 static int __cdecl _wcstombsz(
char* mbstr,
const wchar_t* wcstr,
size_t count)
2438 if (count == 0 && mbstr != NULL)
2441 int result = ::WideCharToMultiByte(CP_ACP, 0, wcstr, -1, mbstr, (
int)count, NULL, NULL);
2442 ATLASSERT(mbstr == NULL || result <= (
int)count);
2443 if ((mbstr != NULL) && (result > 0))
2444 mbstr[result - 1] = 0;
2448 static int __cdecl _mbstowcsz(
wchar_t* wcstr,
const char* mbstr,
size_t count)
2450 if (count == 0 && wcstr != NULL)
2453 int result = ::MultiByteToWideChar(CP_ACP, 0, mbstr, -1, wcstr, (
int)count);
2454 ATLASSERT(wcstr == NULL || result <= (
int)count);
2455 if ((wcstr != NULL) && (result > 0))
2456 wcstr[result - 1] = 0;
2462 static const TCHAR* _cstrchr(
const TCHAR* p, TCHAR ch)
2471 return (*p == ch) ? p : NULL;
2474 static TCHAR* _cstrrev(TCHAR* pStr)
2477 if ((pStr == NULL) || (pStr[0] == _T(
'\0')) || (pStr[1] == _T(
'\0')))
2484 TCHAR* pNext = ::CharNext(p);
2487 char p1 = *(
char*)p;
2488 *(
char*)p = *(
char*)(p + 1);
2489 *(
char*)(p + 1) = p1;
2508 static const TCHAR* _cstrstr(
const TCHAR* pStr,
const TCHAR* pCharSet)
2510 int nLen = lstrlen(pCharSet);
2512 return (TCHAR*)pStr;
2514 const TCHAR* pRet = NULL;
2515 const TCHAR* pCur = pStr;
2516 while((pCur = _cstrchr(pCur, *pCharSet)) != NULL)
2518 if(memcmp(pCur, pCharSet, nLen *
sizeof(TCHAR)) == 0)
2523 pCur = ::CharNext(pCur);
2528 static int _cstrspn(
const TCHAR* pStr,
const TCHAR* pCharSet)
2531 const TCHAR* p = pStr;
2534 const TCHAR* pNext = ::CharNext(p);
2537 if(_cstrchr_db(pCharSet, *p, *(p + 1)) == NULL)
2543 if(_cstrchr(pCharSet, *p) == NULL)
2552 static int _cstrcspn(
const TCHAR* pStr,
const TCHAR* pCharSet)
2555 TCHAR* p = (TCHAR*)pStr;
2558 TCHAR* pNext = ::CharNext(p);
2561 if(_cstrchr_db(pCharSet, *p, *(p + 1)) != NULL)
2567 if(_cstrchr(pCharSet, *p) != NULL)
2576 static const TCHAR* _cstrpbrk(
const TCHAR* p,
const TCHAR* lpszCharSet)
2578 int n = _cstrcspn(p, lpszCharSet);
2579 return (p[n] != 0) ? &p[n] : NULL;
2582 static int _cstrcmp(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2584 return lstrcmp(pstrOne, pstrOther);
2587 static int _cstrcmpi(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2589 return lstrcmpi(pstrOne, pstrOther);
2592 static int _cstrcoll(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2594 int nRet = CompareString(GetThreadLocale(), 0, pstrOne, -1, pstrOther, -1);
2595 ATLASSERT(nRet != 0);
2599 static int _cstrcolli(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2601 int nRet = CompareString(GetThreadLocale(), NORM_IGNORECASE, pstrOne, -1, pstrOther, -1);
2602 ATLASSERT(nRet != 0);
2605 #else // !_ATL_MIN_CRT 2606 static const TCHAR* _cstrchr(
const TCHAR* p, TCHAR ch)
2608 return _tcschr(p, ch);
2611 static TCHAR* _cstrrev(TCHAR* pStr)
2613 return _tcsrev(pStr);
2616 static const TCHAR* _cstrstr(
const TCHAR* pStr,
const TCHAR* pCharSet)
2618 return _tcsstr(pStr, pCharSet);
2621 static int _cstrspn(
const TCHAR* pStr,
const TCHAR* pCharSet)
2623 return (
int)_tcsspn(pStr, pCharSet);
2626 static int _cstrcspn(
const TCHAR* pStr,
const TCHAR* pCharSet)
2628 return (
int)_tcscspn(pStr, pCharSet);
2631 static const TCHAR* _cstrpbrk(
const TCHAR* p,
const TCHAR* lpszCharSet)
2633 return _tcspbrk(p, lpszCharSet);
2636 static int _cstrcmp(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2638 return _tcscmp(pstrOne, pstrOther);
2641 static int _cstrcmpi(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2643 return _tcsicmp(pstrOne, pstrOther);
2647 static int _cstrcoll(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2649 return _tcscoll(pstrOne, pstrOther);
2652 static int _cstrcolli(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2654 return _tcsicoll(pstrOne, pstrOther);
2656 #endif // !_WIN32_WCE 2657 #endif // !_ATL_MIN_CRT 2659 static const TCHAR* _cstrrchr(
const TCHAR* p, TCHAR ch)
2661 return MinCrtHelper::_strrchr(p, ch);
2664 static int _cstrisdigit(TCHAR ch)
2666 return MinCrtHelper::_isdigit(ch);
2669 static int _cstrisspace(TCHAR ch)
2671 return MinCrtHelper::_isspace(ch);
2674 static int _cstrtoi(
const TCHAR* nptr)
2676 return MinCrtHelper::_atoi(nptr);
2679 static const TCHAR* _cstrchr_db(
const TCHAR* p, TCHAR ch1, TCHAR ch2)
2681 const TCHAR* lpsz = NULL;
2684 if (*p == ch1 && *(p + 1) == ch2)
2698 inline bool __stdcall operator ==(
const CString& s1,
const CString& s2)
2699 {
return s1.Compare(s2) == 0; }
2701 inline bool __stdcall operator ==(
const CString& s1, LPCTSTR s2)
2702 {
return s1.Compare(s2) == 0; }
2704 inline bool __stdcall operator ==(LPCTSTR s1,
const CString& s2)
2705 {
return s2.Compare(s1) == 0; }
2707 inline bool __stdcall operator !=(
const CString& s1,
const CString& s2)
2708 {
return s1.Compare(s2) != 0; }
2710 inline bool __stdcall operator !=(
const CString& s1, LPCTSTR s2)
2711 {
return s1.Compare(s2) != 0; }
2713 inline bool __stdcall operator !=(LPCTSTR s1,
const CString& s2)
2714 {
return s2.Compare(s1) != 0; }
2716 inline bool __stdcall operator <(
const CString& s1,
const CString& s2)
2717 {
return s1.Compare(s2) < 0; }
2719 inline bool __stdcall operator <(
const CString& s1, LPCTSTR s2)
2720 {
return s1.Compare(s2) < 0; }
2722 inline bool __stdcall operator <(LPCTSTR s1,
const CString& s2)
2723 {
return s2.Compare(s1) > 0; }
2725 inline bool __stdcall operator >(
const CString& s1,
const CString& s2)
2726 {
return s1.Compare(s2) > 0; }
2728 inline bool __stdcall operator >(
const CString& s1, LPCTSTR s2)
2729 {
return s1.Compare(s2) > 0; }
2731 inline bool __stdcall operator >(LPCTSTR s1,
const CString& s2)
2732 {
return s2.Compare(s1) < 0; }
2734 inline bool __stdcall operator <=(
const CString& s1,
const CString& s2)
2735 {
return s1.Compare(s2) <= 0; }
2737 inline bool __stdcall operator <=(
const CString& s1, LPCTSTR s2)
2738 {
return s1.Compare(s2) <= 0; }
2740 inline bool __stdcall operator <=(LPCTSTR s1,
const CString& s2)
2741 {
return s2.Compare(s1) >= 0; }
2743 inline bool __stdcall operator >=(
const CString& s1,
const CString& s2)
2744 {
return s1.Compare(s2) >= 0; }
2746 inline bool __stdcall operator >=(
const CString& s1, LPCTSTR s2)
2747 {
return s1.Compare(s2) >= 0; }
2749 inline bool __stdcall operator >=(LPCTSTR s1,
const CString& s2)
2750 {
return s2.Compare(s1) <= 0; }
2758 s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, string2.GetData()->nDataLength, string2.m_pchData);
2762 inline CString __stdcall operator +(
const CString&
string, TCHAR ch)
2765 s.ConcatCopy(
string.GetData()->nDataLength,
string.m_pchData, 1, &ch);
2769 inline CString __stdcall operator +(TCHAR ch,
const CString&
string)
2772 s.ConcatCopy(1, &ch,
string.GetData()->nDataLength,
string.m_pchData);
2777 inline CString __stdcall operator +(
const CString&
string,
char ch)
2779 return string + (TCHAR)ch;
2782 inline CString __stdcall operator +(
char ch,
const CString&
string)
2784 return (TCHAR)ch + string;
2788 inline CString __stdcall operator +(
const CString&
string, LPCTSTR lpsz)
2790 ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz));
2792 s.ConcatCopy(
string.GetData()->nDataLength,
string.m_pchData, CString::SafeStrlen(lpsz), lpsz);
2796 inline CString __stdcall operator +(LPCTSTR lpsz,
const CString&
string)
2798 ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz));
2800 s.ConcatCopy(CString::SafeStrlen(lpsz), lpsz,
string.GetData()->nDataLength,
string.m_pchData);
2804 #endif // !_WTL_NO_CSTRING 2812 #ifndef _WTL_MRUEMPTY_TEXT 2813 #define _WTL_MRUEMPTY_TEXT _T("(empty)") 2817 inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn,
int cchLen);
2819 template <
class T,
int t_cchItemLen = MAX_PATH,
int t_nFirstID = ID_FILE_MRU_FIRST,
int t_nLastID = ID_FILE_MRU_LAST>
2826 TCHAR szDocName[t_cchItemLen];
2827 bool operator ==(
const _DocEntry& de)
const 2828 {
return (lstrcmpi(szDocName, de.szDocName) == 0); }
2833 m_nMaxEntries_Min = 2,
2834 m_nMaxEntries_Max = t_nLastID - t_nFirstID + 1,
2835 m_cchMaxItemLen_Min = 6,
2836 m_cchMaxItemLen_Max = t_cchItemLen,
2837 m_cchItemNameLen = 11
2841 ATL::CSimpleArray<_DocEntry> m_arrDocs;
2845 TCHAR m_szNoEntries[t_cchItemLen];
2847 int m_cchMaxItemLen;
2853 ATLASSERT(t_cchItemLen > m_cchMaxItemLen_Min);
2854 ATLASSERT(m_nMaxEntries_Max > m_nMaxEntries_Min);
2858 HMENU GetMenuHandle()
const 2863 void SetMenuHandle(HMENU hMenu)
2865 ATLASSERT(hMenu == NULL || ::IsMenu(hMenu));
2867 if(m_hMenu == NULL || (::GetMenuString(m_hMenu, t_nFirstID, m_szNoEntries, t_cchItemLen, MF_BYCOMMAND) == 0))
2869 T* pT =
static_cast<T*
>(
this);
2871 SecureHelper::strncpy_x(m_szNoEntries, _countof(m_szNoEntries), pT->GetMRUEmptyText(), _TRUNCATE);
2875 int GetMaxEntries()
const 2877 return m_nMaxEntries;
2880 void SetMaxEntries(
int nMaxEntries)
2882 ATLASSERT(nMaxEntries >= m_nMaxEntries_Min && nMaxEntries <= m_nMaxEntries_Max);
2883 if(nMaxEntries < m_nMaxEntries_Min)
2884 nMaxEntries = m_nMaxEntries_Min;
2885 else if(nMaxEntries > m_nMaxEntries_Max)
2886 nMaxEntries = m_nMaxEntries_Max;
2887 m_nMaxEntries = nMaxEntries;
2890 int GetMaxItemLength()
const 2892 return m_cchMaxItemLen;
2895 void SetMaxItemLength(
int cchMaxLen)
2897 ATLASSERT((cchMaxLen >= m_cchMaxItemLen_Min && cchMaxLen <= m_cchMaxItemLen_Max) || cchMaxLen == -1);
2900 if(cchMaxLen < m_cchMaxItemLen_Min)
2901 cchMaxLen = m_cchMaxItemLen_Min;
2902 else if(cchMaxLen > m_cchMaxItemLen_Max)
2903 cchMaxLen = m_cchMaxItemLen_Max;
2905 m_cchMaxItemLen = cchMaxLen;
2906 T* pT =
static_cast<T*
>(
this);
2911 BOOL AddToList(LPCTSTR lpstrDocName)
2914 errno_t nRet = SecureHelper::strncpy_x(de.szDocName, _countof(de.szDocName), lpstrDocName, _TRUNCATE);
2915 if(nRet != 0 && nRet != STRUNCATE)
2918 for(
int i = 0; i < m_arrDocs.GetSize(); i++)
2920 if(lstrcmpi(m_arrDocs[i].szDocName, lpstrDocName) == 0)
2922 m_arrDocs.RemoveAt(i);
2927 if(m_arrDocs.GetSize() == m_nMaxEntries)
2928 m_arrDocs.RemoveAt(0);
2930 BOOL bRet = m_arrDocs.Add(de);
2933 T* pT =
static_cast<T*
>(
this);
2934 bRet = pT->UpdateMenu();
2941 #if (_MSC_VER >= 1300) 2942 __declspec(deprecated)
2944 BOOL GetFromList(
int , LPTSTR )
2950 BOOL GetFromList(
int nItemID, LPTSTR lpstrDocName,
int cchLength)
2952 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2953 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2955 if(lstrlen(m_arrDocs[nIndex].szDocName) >= cchLength)
2957 SecureHelper::strcpy_x(lpstrDocName, cchLength, m_arrDocs[nIndex].szDocName);
2962 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 2963 BOOL GetFromList(
int nItemID, _CSTRING_NS::CString& strDocName)
2965 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2966 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2968 strDocName = m_arrDocs[nIndex].szDocName;
2971 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 2973 BOOL RemoveFromList(
int nItemID)
2975 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2976 BOOL bRet = m_arrDocs.RemoveAt(nIndex);
2979 T* pT =
static_cast<T*
>(
this);
2980 bRet = pT->UpdateMenu();
2985 BOOL MoveToTop(
int nItemID)
2987 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2988 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2991 de = m_arrDocs[nIndex];
2992 m_arrDocs.RemoveAt(nIndex);
2993 BOOL bRet = m_arrDocs.Add(de);
2996 T* pT =
static_cast<T*
>(
this);
2997 bRet = pT->UpdateMenu();
3002 BOOL ReadFromRegistry(LPCTSTR lpstrRegKey)
3004 T* pT =
static_cast<T*
>(
this);
3008 LONG lRet = rkParent.Open(HKEY_CURRENT_USER, lpstrRegKey);
3009 if(lRet != ERROR_SUCCESS)
3011 lRet = rk.Open(rkParent, pT->GetRegKeyName());
3012 if(lRet != ERROR_SUCCESS)
3016 lRet = rk.QueryDWORDValue(pT->GetRegCountName(), dwRet);
3017 if(lRet != ERROR_SUCCESS)
3019 SetMaxEntries(dwRet);
3021 m_arrDocs.RemoveAll();
3023 TCHAR szRetString[t_cchItemLen] = { 0 };
3026 for(
int nItem = m_nMaxEntries; nItem > 0; nItem--)
3028 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3029 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3030 ULONG ulCount = t_cchItemLen;
3031 lRet = rk.QueryStringValue(szBuff, szRetString, &ulCount);
3032 if(lRet == ERROR_SUCCESS)
3034 SecureHelper::strcpy_x(de.szDocName, _countof(de.szDocName), szRetString);
3042 return pT->UpdateMenu();
3045 BOOL WriteToRegistry(LPCTSTR lpstrRegKey)
3047 T* pT =
static_cast<T*
>(
this);
3052 LONG lRet = rkParent.Create(HKEY_CURRENT_USER, lpstrRegKey);
3053 if(lRet != ERROR_SUCCESS)
3055 lRet = rk.Create(rkParent, pT->GetRegKeyName());
3056 if(lRet != ERROR_SUCCESS)
3059 lRet = rk.SetDWORDValue(pT->GetRegCountName(), m_nMaxEntries);
3060 ATLASSERT(lRet == ERROR_SUCCESS);
3064 for(nItem = m_arrDocs.GetSize(); nItem > 0; nItem--)
3066 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3067 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3068 TCHAR szDocName[t_cchItemLen] = { 0 };
3069 GetFromList(t_nFirstID + nItem - 1, szDocName, t_cchItemLen);
3070 lRet = rk.SetStringValue(szBuff, szDocName);
3071 ATLASSERT(lRet == ERROR_SUCCESS);
3075 for(nItem = m_arrDocs.GetSize() + 1; nItem <= m_nMaxEntries_Max; nItem++)
3077 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3078 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3079 rk.DeleteValue(szBuff);
3093 ATLASSERT(::IsMenu(m_hMenu));
3095 int nItems = ::GetMenuItemCount(m_hMenu);
3096 int nInsertPoint = 0;
3097 for(
int i = 0; i < nItems; i++)
3101 ::GetMenuItemInfo(m_hMenu, i, TRUE, &mi);
3102 if (mi.wID == t_nFirstID)
3109 ATLASSERT(nInsertPoint < nItems &&
"You need a menu item with an ID = t_nFirstID");
3111 for(
int j = t_nFirstID; j < (t_nFirstID + m_nMaxEntries); j++)
3114 if (j != t_nFirstID)
3115 ::DeleteMenu(m_hMenu, j, MF_BYCOMMAND);
3118 TCHAR szItemText[t_cchItemLen + 6] = { 0 };
3119 int nSize = m_arrDocs.GetSize();
3123 for(nItem = 0; nItem < nSize; nItem++)
3125 if(m_cchMaxItemLen == -1)
3127 SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T(
"&%i %s"), nItem + 1, m_arrDocs[nSize - 1 - nItem].szDocName);
3131 TCHAR szBuff[t_cchItemLen] = { 0 };
3132 T* pT =
static_cast<T*
>(
this);
3134 bool bRet = pT->CompactDocumentName(szBuff, m_arrDocs[nSize - 1 - nItem].szDocName, m_cchMaxItemLen);
3137 SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T(
"&%i %s"), nItem + 1, szBuff);
3140 ::InsertMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION | MF_STRING, t_nFirstID + nItem, szItemText);
3145 ::InsertMenu(m_hMenu, nInsertPoint, MF_BYPOSITION | MF_STRING, t_nFirstID, m_szNoEntries);
3146 ::EnableMenuItem(m_hMenu, t_nFirstID, MF_GRAYED);
3149 ::DeleteMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION);
3156 static bool CompactDocumentName(LPTSTR lpstrOut, LPCTSTR lpstrIn,
int cchLen)
3158 return AtlCompactPath(lpstrOut, lpstrIn, cchLen);
3161 static LPCTSTR GetRegKeyName()
3163 return _T(
"Recent Document List");
3166 static LPCTSTR GetRegCountName()
3168 return _T(
"DocumentCount");
3171 static LPCTSTR GetRegItemName()
3176 return _T(
"Document%i");
3179 static LPCTSTR GetMRUEmptyText()
3181 return _WTL_MRUEMPTY_TEXT;
3191 #endif // _WIN32_WCE 3201 WIN32_FIND_DATA m_fd;
3202 TCHAR m_lpszRoot[MAX_PATH];
3203 TCHAR m_chDirSeparator;
3208 CFindFile() : m_hFind(NULL), m_chDirSeparator(_T(
'\\')), m_bFound(FALSE)
3217 ULONGLONG GetFileSize()
const 3219 ATLASSERT(m_hFind != NULL);
3221 ULARGE_INTEGER nFileSize = { 0 };
3225 nFileSize.LowPart = m_fd.nFileSizeLow;
3226 nFileSize.HighPart = m_fd.nFileSizeHigh;
3230 nFileSize.QuadPart = 0;
3233 return nFileSize.QuadPart;
3236 BOOL GetFileName(LPTSTR lpstrFileName,
int cchLength)
const 3238 ATLASSERT(m_hFind != NULL);
3239 if(lstrlen(m_fd.cFileName) >= cchLength)
3243 SecureHelper::strcpy_x(lpstrFileName, cchLength, m_fd.cFileName);
3248 BOOL GetFilePath(LPTSTR lpstrFilePath,
int cchLength)
const 3250 ATLASSERT(m_hFind != NULL);
3252 int nLen = lstrlen(m_lpszRoot);
3254 ATLASSERT(nLen > 0);
3258 bool bAddSep = (m_lpszRoot[nLen - 1] != _T(
'\\') && m_lpszRoot[nLen - 1] !=_T(
'/'));
3259 #else // CE specific 3261 bool bAddSep = ((nLen == 0) || (m_lpszRoot[nLen - 1] != _T(
'\\') && m_lpszRoot[nLen - 1] !=_T(
'/')));
3262 #endif // _WIN32_WCE 3264 if((lstrlen(m_lpszRoot) + (bAddSep ? 1 : 0)) >= cchLength)
3267 SecureHelper::strcpy_x(lpstrFilePath, cchLength, m_lpszRoot);
3271 TCHAR szSeparator[2] = { m_chDirSeparator, 0 };
3272 SecureHelper::strcat_x(lpstrFilePath, cchLength, szSeparator);
3275 SecureHelper::strcat_x(lpstrFilePath, cchLength, m_fd.cFileName);
3281 BOOL GetFileTitle(LPTSTR lpstrFileTitle,
int cchLength)
const 3283 ATLASSERT(m_hFind != NULL);
3285 TCHAR szBuff[MAX_PATH] = { 0 };
3286 if(!GetFileName(szBuff, MAX_PATH))
3289 if(lstrlen(szBuff) >= cchLength || cchLength < 1)
3293 LPTSTR pstrDot = MinCrtHelper::_strrchr(szBuff, _T(
'.'));
3297 SecureHelper::strcpy_x(lpstrFileTitle, cchLength, szBuff);
3301 #endif // !_WIN32_WCE 3303 BOOL GetFileURL(LPTSTR lpstrFileURL,
int cchLength)
const 3305 ATLASSERT(m_hFind != NULL);
3307 TCHAR szBuff[MAX_PATH] = { 0 };
3308 if(!GetFilePath(szBuff, MAX_PATH))
3310 LPCTSTR lpstrFileURLPrefix = _T(
"file://");
3311 if(lstrlen(szBuff) + lstrlen(lpstrFileURLPrefix) >= cchLength)
3313 SecureHelper::strcpy_x(lpstrFileURL, cchLength, lpstrFileURLPrefix);
3314 SecureHelper::strcat_x(lpstrFileURL, cchLength, szBuff);
3319 BOOL GetRoot(LPTSTR lpstrRoot,
int cchLength)
const 3321 ATLASSERT(m_hFind != NULL);
3322 if(lstrlen(m_lpszRoot) >= cchLength)
3325 SecureHelper::strcpy_x(lpstrRoot, cchLength, m_lpszRoot);
3330 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 3331 _CSTRING_NS::CString GetFileName()
const 3333 ATLASSERT(m_hFind != NULL);
3335 _CSTRING_NS::CString ret;
3338 ret = m_fd.cFileName;
3342 _CSTRING_NS::CString GetFilePath()
const 3344 ATLASSERT(m_hFind != NULL);
3346 _CSTRING_NS::CString strResult = m_lpszRoot;
3347 int nLen = strResult.GetLength();
3349 ATLASSERT(nLen > 0);
3353 if((strResult[nLen - 1] != _T(
'\\')) && (strResult[nLen - 1] != _T(
'/')))
3354 #else // CE specific 3356 if((nLen == 0) || ((strResult[nLen - 1] != _T(
'\\')) && (strResult[nLen - 1] != _T(
'/'))))
3357 #endif // _WIN32_WCE 3358 strResult += m_chDirSeparator;
3359 strResult += GetFileName();
3364 _CSTRING_NS::CString GetFileTitle()
const 3366 ATLASSERT(m_hFind != NULL);
3368 _CSTRING_NS::CString strResult;
3369 GetFileTitle(strResult.GetBuffer(MAX_PATH), MAX_PATH);
3370 strResult.ReleaseBuffer();
3374 #endif // !_WIN32_WCE 3376 _CSTRING_NS::CString GetFileURL()
const 3378 ATLASSERT(m_hFind != NULL);
3380 _CSTRING_NS::CString strResult(
"file://");
3381 strResult += GetFilePath();
3385 _CSTRING_NS::CString GetRoot()
const 3387 ATLASSERT(m_hFind != NULL);
3389 _CSTRING_NS::CString str = m_lpszRoot;
3392 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 3394 BOOL GetLastWriteTime(FILETIME* pTimeStamp)
const 3396 ATLASSERT(m_hFind != NULL);
3397 ATLASSERT(pTimeStamp != NULL);
3399 if(m_bFound && pTimeStamp != NULL)
3401 *pTimeStamp = m_fd.ftLastWriteTime;
3408 BOOL GetLastAccessTime(FILETIME* pTimeStamp)
const 3410 ATLASSERT(m_hFind != NULL);
3411 ATLASSERT(pTimeStamp != NULL);
3413 if(m_bFound && pTimeStamp != NULL)
3415 *pTimeStamp = m_fd.ftLastAccessTime;
3422 BOOL GetCreationTime(FILETIME* pTimeStamp)
const 3424 ATLASSERT(m_hFind != NULL);
3426 if(m_bFound && pTimeStamp != NULL)
3428 *pTimeStamp = m_fd.ftCreationTime;
3435 BOOL MatchesMask(DWORD dwMask)
const 3437 ATLASSERT(m_hFind != NULL);
3440 return ((m_fd.dwFileAttributes & dwMask) != 0);
3447 ATLASSERT(m_hFind != NULL);
3452 BOOL bResult = FALSE;
3453 if(m_bFound && IsDirectory())
3455 if(m_fd.cFileName[0] == _T(
'.') && (m_fd.cFileName[1] == _T(
'\0') || (m_fd.cFileName[1] == _T(
'.') && m_fd.cFileName[2] == _T(
'\0'))))
3462 BOOL IsReadOnly()
const 3464 return MatchesMask(FILE_ATTRIBUTE_READONLY);
3467 BOOL IsDirectory()
const 3469 return MatchesMask(FILE_ATTRIBUTE_DIRECTORY);
3472 BOOL IsCompressed()
const 3474 return MatchesMask(FILE_ATTRIBUTE_COMPRESSED);
3477 BOOL IsSystem()
const 3479 return MatchesMask(FILE_ATTRIBUTE_SYSTEM);
3482 BOOL IsHidden()
const 3484 return MatchesMask(FILE_ATTRIBUTE_HIDDEN);
3487 BOOL IsTemporary()
const 3489 return MatchesMask(FILE_ATTRIBUTE_TEMPORARY);
3492 BOOL IsNormal()
const 3494 return MatchesMask(FILE_ATTRIBUTE_NORMAL);
3497 BOOL IsArchived()
const 3499 return MatchesMask(FILE_ATTRIBUTE_ARCHIVE);
3503 BOOL FindFile(LPCTSTR pstrName = NULL)
3507 if(pstrName == NULL)
3509 pstrName = _T(
"*.*");
3511 else if(lstrlen(pstrName) >= MAX_PATH)
3517 SecureHelper::strcpy_x(m_fd.cFileName, _countof(m_fd.cFileName), pstrName);
3519 m_hFind = ::FindFirstFile(pstrName, &m_fd);
3521 if(m_hFind == INVALID_HANDLE_VALUE)
3525 bool bFullPath = (::GetFullPathName(pstrName, MAX_PATH, m_lpszRoot, NULL) != 0);
3526 #else // CE specific 3527 errno_t nRet = SecureHelper::strncpy_x(m_lpszRoot, _countof(m_lpszRoot), pstrName, _TRUNCATE);
3528 bool bFullPath = (nRet == 0 || nRet == STRUNCATE);
3529 #endif // _WIN32_WCE 3532 ATLASSERT(bFullPath);
3536 ::SetLastError(ERROR_INVALID_NAME);
3542 LPTSTR pstrBack = MinCrtHelper::_strrchr(m_lpszRoot, _T(
'\\'));
3543 LPTSTR pstrFront = MinCrtHelper::_strrchr(m_lpszRoot, _T(
'/'));
3545 if(pstrFront != NULL || pstrBack != NULL)
3547 if(pstrFront == NULL)
3548 pstrFront = m_lpszRoot;
3549 if(pstrBack == NULL)
3550 pstrBack = m_lpszRoot;
3554 if(pstrFront >= pstrBack)
3555 *pstrFront = _T(
'\0');
3557 *pstrBack = _T(
'\0');
3568 ATLASSERT(m_hFind != NULL);
3576 m_bFound = ::FindNextFile(m_hFind, &m_fd);
3585 if(m_hFind != NULL && m_hFind != INVALID_HANDLE_VALUE)
3587 ::FindClose(m_hFind);
3597 inline HPEN AtlGetStockPen(
int nPen)
3599 #if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE) 3600 ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN);
3602 ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN);
3604 return (HPEN)::GetStockObject(nPen);
3607 inline HBRUSH AtlGetStockBrush(
int nBrush)
3609 #if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE) 3610 ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH);
3612 ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH);
3614 return (HBRUSH)::GetStockObject(nBrush);
3617 inline HFONT AtlGetStockFont(
int nFont)
3620 ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT);
3621 #else // CE specific 3622 ATLASSERT(nFont == SYSTEM_FONT);
3623 #endif // _WIN32_WCE 3624 return (HFONT)::GetStockObject(nFont);
3627 inline HPALETTE AtlGetStockPalette(
int nPalette)
3629 ATLASSERT(nPalette == DEFAULT_PALETTE);
3630 return (HPALETTE)::GetStockObject(nPalette);
3638 inline bool _IsDBCSTrailByte(LPCTSTR lpstr,
int nChar)
3644 if(!::IsDBCSLeadByte(lpstr[i - 1]))
3647 return ((nChar > 0) && (((nChar - i) & 1) != 0));
3654 inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn,
int cchLen)
3656 ATLASSERT(lpstrOut != NULL);
3657 ATLASSERT(lpstrIn != NULL);
3658 ATLASSERT(cchLen > 0);
3660 LPCTSTR szEllipsis = _T(
"...");
3661 const int cchEndEllipsis = 3;
3662 const int cchMidEllipsis = 4;
3664 if(lstrlen(lpstrIn) < cchLen)
3666 SecureHelper::strcpy_x(lpstrOut, cchLen, lpstrIn);
3673 TCHAR chSlash = _T(
'\\');
3674 for(LPTSTR lpstr = (LPTSTR)lpstrIn; *lpstr != 0; lpstr = ::CharNext(lpstr))
3676 if((*lpstr == _T(
'/')) || (*lpstr == _T(
'\\')))
3681 LPCTSTR lpstrFileName = lpstrIn;
3682 for(LPCTSTR pPath = lpstrIn; *pPath; pPath = ::CharNext(pPath))
3684 if((pPath[0] == _T(
'\\') || pPath[0] == _T(
':') || pPath[0] == _T(
'/'))
3685 && pPath[1] && pPath[1] != _T(
'\\') && pPath[1] != _T(
'/'))
3686 lpstrFileName = pPath + 1;
3688 int cchFileName = lstrlen(lpstrFileName);
3691 if(lpstrFileName == lpstrIn && cchLen > cchEndEllipsis)
3693 bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchLen - cchEndEllipsis - 1) == 0);
3697 if(_IsDBCSTrailByte(lpstrIn, cchLen - cchEndEllipsis))
3698 lpstrOut[cchLen - cchEndEllipsis - 1] = 0;
3700 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3706 if((cchLen < (cchMidEllipsis + cchEndEllipsis)))
3708 for(
int i = 0; i < cchLen - 1; i++)
3709 lpstrOut[i] = ((i + 1) == cchMidEllipsis) ? chSlash : _T(
'.');
3710 lpstrOut[cchLen - 1] = 0;
3715 int cchToCopy = cchLen - (cchMidEllipsis + cchFileName) - 1;
3721 if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrIn, cchToCopy))
3725 bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchToCopy) == 0);
3730 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3731 TCHAR szSlash[2] = { chSlash, 0 };
3732 SecureHelper::strcat_x(lpstrOut, cchLen, szSlash);
3735 if(cchLen > (cchMidEllipsis + cchFileName))
3737 SecureHelper::strcat_x(lpstrOut, cchLen, lpstrFileName);
3741 cchToCopy = cchLen - cchMidEllipsis - cchEndEllipsis - 1;
3743 if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrFileName, cchToCopy))
3746 bRet = (SecureHelper::strncpy_x(&lpstrOut[cchMidEllipsis], cchLen - cchMidEllipsis, lpstrFileName, cchToCopy) == 0);
3748 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3756 #endif // __ATLMISC_H__ Definition: atlmisc.h:2820
Definition: atlmisc.h:736
Definition: atlmisc.h:2824
Definition: atlapp.h:1872
Definition: atlmisc.h:289
Definition: atlmisc.h:3185
Definition: atlmisc.h:162
Definition: atlmisc.h:757
Definition: atlapp.h:1455
Definition: atlmisc.h:3197