18 #error atlmisc.h requires atlapp.h to be included first 22 #ifdef _ATL_TMP_NO_CSTRING 23 #define _WTL_NO_CSTRING 26 #if defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING) 27 #error Conflicting options - both _WTL_USE_CSTRING and _WTL_NO_CSTRING are defined 28 #endif // defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING) 30 #if !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING) 31 #define _WTL_USE_CSTRING 32 #endif // !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING) 34 #ifndef _WTL_NO_CSTRING 35 #if defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT) 36 #error Cannot use CString floating point formatting with _ATL_MIN_CRT defined 37 #endif // defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT) 38 #endif // !_WTL_NO_CSTRING 65 #ifndef _WTL_NO_WTYPES 85 CSize(
int initCX,
int initCY)
93 *(SIZE*)
this = initSize;
98 *(POINT*)
this = initPt;
103 cx = (short)LOWORD(dwSize);
104 cy = (short)HIWORD(dwSize);
108 BOOL operator ==(SIZE size)
const 110 return (cx == size.cx && cy == size.cy);
113 BOOL operator !=(SIZE size)
const 115 return (cx != size.cx || cy != size.cy);
118 void operator +=(SIZE size)
124 void operator -=(SIZE size)
130 void SetSize(
int CX,
int CY)
137 CSize operator +(SIZE size)
const 139 return CSize(cx + size.cx, cy + size.cy);
142 CSize operator -(SIZE size)
const 144 return CSize(cx - size.cx, cy - size.cy);
147 CSize operator -()
const 149 return CSize(-cx, -cy);
153 CPoint operator +(POINT point)
const;
154 CPoint operator -(POINT point)
const;
157 CRect operator +(
const RECT* lpRect)
const;
158 CRect operator -(
const RECT* lpRect)
const;
175 CPoint(
int initX,
int initY)
183 *(POINT*)
this = initPt;
188 *(SIZE*)
this = initSize;
193 x = (short)LOWORD(dwPoint);
194 y = (short)HIWORD(dwPoint);
198 void Offset(
int xOffset,
int yOffset)
204 void Offset(POINT point)
210 void Offset(SIZE size)
216 BOOL operator ==(POINT point)
const 218 return (x == point.x && y == point.y);
221 BOOL operator !=(POINT point)
const 223 return (x != point.x || y != point.y);
226 void operator +=(SIZE size)
232 void operator -=(SIZE size)
238 void operator +=(POINT point)
244 void operator -=(POINT point)
250 void SetPoint(
int X,
int Y)
257 CPoint operator +(SIZE size)
const 259 return CPoint(x + size.cx, y + size.cy);
262 CPoint operator -(SIZE size)
const 264 return CPoint(x - size.cx, y - size.cy);
272 CPoint operator +(POINT point)
const 274 return CPoint(x + point.x, y + point.y);
278 CSize operator -(POINT point)
const 280 return CSize(x - point.x, y - point.y);
284 CRect operator +(
const RECT* lpRect)
const;
285 CRect operator -(
const RECT* lpRect)
const;
304 CRect(
int l,
int t,
int r,
int b)
312 CRect(
const RECT& srcRect)
314 ::CopyRect(
this, &srcRect);
317 CRect(LPCRECT lpSrcRect)
319 ::CopyRect(
this, lpSrcRect);
322 CRect(POINT point, SIZE size)
324 right = (left = point.x) + size.cx;
325 bottom = (top = point.y) + size.cy;
328 CRect(POINT topLeft, POINT bottomRight)
332 right = bottomRight.x;
333 bottom = bottomRight.y;
349 return CSize(right - left, bottom - top);
359 return *((
CPoint*)
this + 1);
362 const CPoint& TopLeft()
const 367 const CPoint& BottomRight()
const 369 return *((
CPoint*)
this + 1);
372 CPoint CenterPoint()
const 374 return CPoint((left + right) / 2, (top + bottom) / 2);
383 operator LPCRECT()
const 388 BOOL IsRectEmpty()
const 390 return ::IsRectEmpty(
this);
393 BOOL IsRectNull()
const 395 return (left == 0 && right == 0 && top == 0 && bottom == 0);
398 BOOL PtInRect(POINT point)
const 400 return ::PtInRect(
this, point);
404 void SetRect(
int x1,
int y1,
int x2,
int y2)
406 ::SetRect(
this, x1, y1, x2, y2);
409 void SetRect(POINT topLeft, POINT bottomRight)
411 ::SetRect(
this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
416 ::SetRectEmpty(
this);
419 void CopyRect(LPCRECT lpSrcRect)
421 ::CopyRect(
this, lpSrcRect);
424 BOOL EqualRect(LPCRECT lpRect)
const 426 return ::EqualRect(
this, lpRect);
429 void InflateRect(
int x,
int y)
431 ::InflateRect(
this, x, y);
434 void InflateRect(SIZE size)
436 ::InflateRect(
this, size.cx, size.cy);
439 void InflateRect(LPCRECT lpRect)
441 left -= lpRect->left;
443 right += lpRect->right;
444 bottom += lpRect->bottom;
447 void InflateRect(
int l,
int t,
int r,
int b)
455 void DeflateRect(
int x,
int y)
457 ::InflateRect(
this, -x, -y);
460 void DeflateRect(SIZE size)
462 ::InflateRect(
this, -size.cx, -size.cy);
465 void DeflateRect(LPCRECT lpRect)
467 left += lpRect->left;
469 right -= lpRect->right;
470 bottom -= lpRect->bottom;
473 void DeflateRect(
int l,
int t,
int r,
int b)
481 void OffsetRect(
int x,
int y)
483 ::OffsetRect(
this, x, y);
485 void OffsetRect(SIZE size)
487 ::OffsetRect(
this, size.cx, size.cy);
490 void OffsetRect(POINT point)
492 ::OffsetRect(
this, point.x, point.y);
515 bottom = Height() + y;
525 void MoveToXY(
int x,
int y)
531 void MoveToXY(POINT pt)
538 BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2)
540 return ::IntersectRect(
this, lpRect1, lpRect2);
543 BOOL UnionRect(LPCRECT lpRect1, LPCRECT lpRect2)
545 return ::UnionRect(
this, lpRect1, lpRect2);
548 BOOL SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2)
550 return ::SubtractRect(
this, lpRectSrc1, lpRectSrc2);
554 void operator =(
const RECT& srcRect)
556 ::CopyRect(
this, &srcRect);
559 BOOL operator ==(
const RECT& rect)
const 561 return ::EqualRect(
this, &rect);
564 BOOL operator !=(
const RECT& rect)
const 566 return !::EqualRect(
this, &rect);
569 void operator +=(POINT point)
571 ::OffsetRect(
this, point.x, point.y);
574 void operator +=(SIZE size)
576 ::OffsetRect(
this, size.cx, size.cy);
579 void operator +=(LPCRECT lpRect)
584 void operator -=(POINT point)
586 ::OffsetRect(
this, -point.x, -point.y);
589 void operator -=(SIZE size)
591 ::OffsetRect(
this, -size.cx, -size.cy);
594 void operator -=(LPCRECT lpRect)
599 void operator &=(
const RECT& rect)
601 ::IntersectRect(
this,
this, &rect);
604 void operator |=(
const RECT& rect)
606 ::UnionRect(
this,
this, &rect);
610 CRect operator +(POINT pt)
const 613 ::OffsetRect(&rect, pt.x, pt.y);
617 CRect operator -(POINT pt)
const 620 ::OffsetRect(&rect, -pt.x, -pt.y);
624 CRect operator +(LPCRECT lpRect)
const 627 rect.InflateRect(lpRect);
631 CRect operator +(SIZE size)
const 634 ::OffsetRect(&rect, size.cx, size.cy);
638 CRect operator -(SIZE size)
const 641 ::OffsetRect(&rect, -size.cx, -size.cy);
645 CRect operator -(LPCRECT lpRect)
const 648 rect.DeflateRect(lpRect);
652 CRect operator &(
const RECT& rect2)
const 655 ::IntersectRect(&rect,
this, &rect2);
659 CRect operator |(
const RECT& rect2)
const 662 ::UnionRect(&rect,
this, &rect2);
666 CRect MulDiv(
int nMultiplier,
int nDivisor)
const 669 ::MulDiv(left, nMultiplier, nDivisor),
670 ::MulDiv(top, nMultiplier, nDivisor),
671 ::MulDiv(right, nMultiplier, nDivisor),
672 ::MulDiv(bottom, nMultiplier, nDivisor));
679 inline CPoint CSize::operator +(POINT point)
const 680 {
return CPoint(cx + point.x, cy + point.y); }
682 inline CPoint CSize::operator -(POINT point)
const 683 {
return CPoint(cx - point.x, cy - point.y); }
685 inline CRect CSize::operator +(
const RECT* lpRect)
const 686 {
return CRect(lpRect) + *
this; }
688 inline CRect CSize::operator -(
const RECT* lpRect)
const 689 {
return CRect(lpRect) - *
this; }
694 inline CRect CPoint::operator +(
const RECT* lpRect)
const 695 {
return CRect(lpRect) + *
this; }
697 inline CRect CPoint::operator -(
const RECT* lpRect)
const 698 {
return CRect(lpRect) - *
this; }
700 #endif // !_WTL_NO_WTYPES 705 #if !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) 708 inline CSize operator *(SIZE s, Num n)
710 return CSize((
int)(s.cx * n), (
int)(s.cy * n));
714 inline void operator *=(SIZE & s, Num n)
720 inline CSize operator /(SIZE s, Num n)
722 return CSize((
int)(s.cx / n), (
int)(s.cy / n));
726 inline void operator /=(SIZE & s, Num n)
731 #endif // !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) 737 #ifndef _WTL_NO_CSTRING 747 {
return (TCHAR*)(
this + 1); }
755 _declspec(selectany)
int rgInitData[] = { -1, 0, 0, 0 };
757 _declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) +
sizeof(
CStringData));
771 ATLASSERT(stringSrc.GetData()->nRefs != 0);
772 if (stringSrc.GetData()->nRefs >= 0)
774 ATLASSERT(stringSrc.GetData() != _atltmpDataNil);
775 m_pchData = stringSrc.m_pchData;
776 InterlockedIncrement(&GetData()->nRefs);
781 *
this = stringSrc.m_pchData;
785 CString(TCHAR ch,
int nRepeat = 1)
787 ATLASSERT(!_istlead(ch));
791 if(AllocBuffer(nRepeat))
794 for (
int i = 0; i < nRepeat; i++)
797 memset(m_pchData, ch, nRepeat);
806 if (lpsz != NULL && HIWORD(lpsz) == NULL)
808 UINT nID = LOWORD((DWORD_PTR)lpsz);
809 if (!LoadString(nID))
810 ATLTRACE2(atlTraceUI, 0, _T(
"Warning: implicit LoadString(%u) in CString failed\n"), nID);
814 int nLen = SafeStrlen(lpsz);
817 if(AllocBuffer(nLen))
818 SecureHelper::memcpy_x(m_pchData, (nLen + 1) *
sizeof(TCHAR), lpsz, nLen *
sizeof(TCHAR));
827 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) 828 int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0;
830 int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0;
834 if(AllocBuffer(nSrcLen))
836 _mbstowcsz(m_pchData, lpsz, nSrcLen + 1);
845 int nSrcLen = (lpsz != NULL) ? (
int)wcslen(lpsz) : 0;
848 if(AllocBuffer(nSrcLen * 2))
850 _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1);
857 CString(LPCTSTR lpch,
int nLength)
862 if(AllocBuffer(nLength))
863 SecureHelper::memcpy_x(m_pchData, (nLength + 1) *
sizeof(TCHAR), lpch, nLength *
sizeof(TCHAR));
868 CString(LPCSTR lpsz,
int nLength)
873 if(AllocBuffer(nLength))
875 int n = ::MultiByteToWideChar(CP_ACP, 0, lpsz, nLength, m_pchData, nLength + 1);
876 ReleaseBuffer((n >= 0) ? n : -1);
881 CString(LPCWSTR lpsz,
int nLength)
886 if(((nLength * 2) > nLength) && AllocBuffer(nLength * 2))
888 int n = ::WideCharToMultiByte(CP_ACP, 0, lpsz, nLength, m_pchData, (nLength * 2) + 1, NULL, NULL);
889 ReleaseBuffer((n >= 0) ? n : -1);
895 CString(
const unsigned char* lpsz)
898 *
this = (LPCSTR)lpsz;
902 int GetLength()
const 904 return GetData()->nDataLength;
909 return GetData()->nDataLength == 0;
914 if (GetData()->nDataLength == 0)
917 if (GetData()->nRefs >= 0)
922 ATLASSERT(GetData()->nDataLength == 0);
923 ATLASSERT(GetData()->nRefs < 0 || GetData()->nAllocLength == 0);
926 TCHAR GetAt(
int nIndex)
const 928 ATLASSERT(nIndex >= 0);
929 ATLASSERT(nIndex < GetData()->nDataLength);
930 return m_pchData[nIndex];
933 TCHAR operator [](
int nIndex)
const 936 ATLASSERT(nIndex >= 0);
937 ATLASSERT(nIndex < GetData()->nDataLength);
938 return m_pchData[nIndex];
941 void SetAt(
int nIndex, TCHAR ch)
943 ATLASSERT(nIndex >= 0);
944 ATLASSERT(nIndex < GetData()->nDataLength);
947 m_pchData[nIndex] = ch;
950 operator LPCTSTR()
const 958 if (m_pchData != stringSrc.m_pchData)
960 if ((GetData()->nRefs < 0 && GetData() != _atltmpDataNil) || stringSrc.GetData()->nRefs < 0)
963 AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
969 ATLASSERT(stringSrc.GetData() != _atltmpDataNil);
970 m_pchData = stringSrc.m_pchData;
971 InterlockedIncrement(&GetData()->nRefs);
979 ATLASSERT(!_istlead(ch));
992 CString& operator =(LPCTSTR lpsz)
994 ATLASSERT(lpsz == NULL || _IsValidString(lpsz));
995 AssignCopy(SafeStrlen(lpsz), lpsz);
1000 CString& operator =(LPCSTR lpsz)
1002 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) 1003 int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0;
1005 int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0;
1007 if(AllocBeforeWrite(nSrcLen))
1009 _mbstowcsz(m_pchData, lpsz, nSrcLen + 1);
1015 CString& operator =(LPCWSTR lpsz)
1017 int nSrcLen = (lpsz != NULL) ? (
int)wcslen(lpsz) : 0;
1018 if(AllocBeforeWrite(nSrcLen * 2))
1020 _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1);
1027 CString& operator =(
const unsigned char* lpsz)
1029 *
this = (LPCSTR)lpsz;
1036 ConcatInPlace(
string.GetData()->nDataLength,
string.m_pchData);
1040 CString& operator +=(TCHAR ch)
1042 ConcatInPlace(1, &ch);
1054 CString& operator +=(LPCTSTR lpsz)
1056 ATLASSERT(lpsz == NULL || _IsValidString(lpsz));
1057 ConcatInPlace(SafeStrlen(lpsz), lpsz);
1062 friend CString __stdcall operator +(
const CString&
string, TCHAR ch);
1063 friend CString __stdcall operator +(TCHAR ch,
const CString&
string);
1065 friend CString __stdcall operator +(
const CString&
string,
char ch);
1066 friend CString __stdcall operator +(
char ch,
const CString&
string);
1068 friend CString __stdcall operator +(
const CString&
string, LPCTSTR lpsz);
1069 friend CString __stdcall operator +(LPCTSTR lpsz,
const CString&
string);
1072 int Compare(LPCTSTR lpsz)
const 1074 return _cstrcmp(m_pchData, lpsz);
1077 int CompareNoCase(LPCTSTR lpsz)
const 1079 return _cstrcmpi(m_pchData, lpsz);
1085 int Collate(LPCTSTR lpsz)
const 1087 return _cstrcoll(m_pchData, lpsz);
1090 int CollateNoCase(LPCTSTR lpsz)
const 1092 return _cstrcolli(m_pchData, lpsz);
1094 #endif // !_WIN32_WCE 1097 CString Mid(
int nFirst,
int nCount)
const 1105 if (nFirst + nCount > GetData()->nDataLength)
1106 nCount = GetData()->nDataLength - nFirst;
1107 if (nFirst > GetData()->nDataLength)
1111 AllocCopy(dest, nCount, nFirst, 0);
1117 return Mid(nFirst, GetData()->nDataLength - nFirst);
1120 CString Left(
int nCount)
const 1124 else if (nCount > GetData()->nDataLength)
1125 nCount = GetData()->nDataLength;
1128 AllocCopy(dest, nCount, 0, 0);
1132 CString Right(
int nCount)
const 1136 else if (nCount > GetData()->nDataLength)
1137 nCount = GetData()->nDataLength;
1140 AllocCopy(dest, nCount, GetData()->nDataLength-nCount, 0);
1144 CString SpanIncluding(LPCTSTR lpszCharSet)
const 1146 ATLASSERT(_IsValidString(lpszCharSet));
1147 return Left(_cstrspn(m_pchData, lpszCharSet));
1150 CString SpanExcluding(LPCTSTR lpszCharSet)
const 1152 ATLASSERT(_IsValidString(lpszCharSet));
1153 return Left(_cstrcspn(m_pchData, lpszCharSet));
1160 CharUpper(m_pchData);
1166 CharLower(m_pchData);
1172 _cstrrev(m_pchData);
1181 LPTSTR lpsz = m_pchData;
1182 LPTSTR lpszLast = NULL;
1183 while (*lpsz != _T(
'\0'))
1185 if (_cstrisspace(*lpsz))
1187 if (lpszLast == NULL)
1194 lpsz = ::CharNext(lpsz);
1197 if (lpszLast != NULL)
1200 *lpszLast = _T(
'\0');
1201 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1210 LPCTSTR lpsz = m_pchData;
1211 while (_cstrisspace(*lpsz))
1212 lpsz = ::CharNext(lpsz);
1215 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1216 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), lpsz, (nDataLength + 1) *
sizeof(TCHAR));
1217 GetData()->nDataLength = nDataLength;
1221 void TrimRight(TCHAR chTarget)
1227 LPTSTR lpsz = m_pchData;
1228 LPTSTR lpszLast = NULL;
1230 while (*lpsz != _T(
'\0'))
1232 if (*lpsz == chTarget)
1234 if (lpszLast == NULL)
1239 lpsz = ::CharNext(lpsz);
1242 if (lpszLast != NULL)
1245 *lpszLast = _T(
'\0');
1246 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1251 void TrimRight(LPCTSTR lpszTargetList)
1256 LPTSTR lpsz = m_pchData;
1257 LPTSTR lpszLast = NULL;
1259 while (*lpsz != _T(
'\0'))
1261 TCHAR* pNext = ::CharNext(lpsz);
1262 if(pNext > lpsz + 1)
1264 if (_cstrchr_db(lpszTargetList, *lpsz, *(lpsz + 1)) != NULL)
1266 if (lpszLast == NULL)
1276 if (_cstrchr(lpszTargetList, *lpsz) != NULL)
1278 if (lpszLast == NULL)
1290 if (lpszLast != NULL)
1293 *lpszLast = _T(
'\0');
1294 GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
1299 void TrimLeft(TCHAR chTarget)
1304 LPCTSTR lpsz = m_pchData;
1306 while (chTarget == *lpsz)
1307 lpsz = ::CharNext(lpsz);
1309 if (lpsz != m_pchData)
1312 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1313 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), lpsz, (nDataLength + 1) *
sizeof(TCHAR));
1314 GetData()->nDataLength = nDataLength;
1319 void TrimLeft(LPCTSTR lpszTargets)
1322 if (SafeStrlen(lpszTargets) == 0)
1326 LPCTSTR lpsz = m_pchData;
1328 while (*lpsz != _T(
'\0'))
1330 TCHAR* pNext = ::CharNext(lpsz);
1331 if(pNext > lpsz + 1)
1333 if (_cstrchr_db(lpszTargets, *lpsz, *(lpsz + 1)) == NULL)
1338 if (_cstrchr(lpszTargets, *lpsz) == NULL)
1344 if (lpsz != m_pchData)
1347 int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
1348 SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), lpsz, (nDataLength + 1) *
sizeof(TCHAR));
1349 GetData()->nDataLength = nDataLength;
1355 int Replace(TCHAR chOld, TCHAR chNew)
1364 LPTSTR psz = m_pchData;
1365 LPTSTR pszEnd = psz + GetData()->nDataLength;
1366 while (psz < pszEnd)
1374 psz = ::CharNext(psz);
1382 int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew)
1386 int nSourceLen = SafeStrlen(lpszOld);
1387 if (nSourceLen == 0)
1389 int nReplacementLen = SafeStrlen(lpszNew);
1393 LPTSTR lpszStart = m_pchData;
1394 LPTSTR lpszEnd = m_pchData + GetData()->nDataLength;
1395 LPTSTR lpszTarget = NULL;
1396 while (lpszStart < lpszEnd)
1398 while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL)
1401 lpszStart = lpszTarget + nSourceLen;
1403 lpszStart += lstrlen(lpszStart) + 1;
1412 int nOldLength = GetData()->nDataLength;
1413 int nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount;
1414 if (GetData()->nAllocLength < nNewLength || GetData()->nRefs > 1)
1417 LPTSTR pstr = m_pchData;
1418 if(!AllocBuffer(nNewLength))
1420 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) *
sizeof(TCHAR), pstr, pOldData->nDataLength *
sizeof(TCHAR));
1421 CString::Release(pOldData);
1424 lpszStart = m_pchData;
1425 lpszEnd = m_pchData + GetData()->nDataLength;
1428 while (lpszStart < lpszEnd)
1430 while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL)
1432 int nBalance = nOldLength - ((int)(DWORD_PTR)(lpszTarget - m_pchData) + nSourceLen);
1433 int cchBuffLen = GetData()->nAllocLength - (int)(DWORD_PTR)(lpszTarget - m_pchData);
1434 SecureHelper::memmove_x(lpszTarget + nReplacementLen, (cchBuffLen - nReplacementLen + 1) *
sizeof(TCHAR), lpszTarget + nSourceLen, nBalance *
sizeof(TCHAR));
1435 SecureHelper::memcpy_x(lpszTarget, (cchBuffLen + 1) *
sizeof(TCHAR), lpszNew, nReplacementLen *
sizeof(TCHAR));
1436 lpszStart = lpszTarget + nReplacementLen;
1437 lpszStart[nBalance] = _T(
'\0');
1438 nOldLength += (nReplacementLen - nSourceLen);
1440 lpszStart += lstrlen(lpszStart) + 1;
1442 ATLASSERT(m_pchData[nNewLength] == _T(
'\0'));
1443 GetData()->nDataLength = nNewLength;
1450 int Remove(TCHAR chRemove)
1454 LPTSTR pstrSource = m_pchData;
1455 LPTSTR pstrDest = m_pchData;
1456 LPTSTR pstrEnd = m_pchData + GetData()->nDataLength;
1458 while (pstrSource < pstrEnd)
1460 if (*pstrSource != chRemove)
1462 *pstrDest = *pstrSource;
1463 pstrDest = ::CharNext(pstrDest);
1465 pstrSource = ::CharNext(pstrSource);
1467 *pstrDest = _T(
'\0');
1468 int nCount = (int)(DWORD_PTR)(pstrSource - pstrDest);
1469 GetData()->nDataLength -= nCount;
1475 int Insert(
int nIndex, TCHAR ch)
1482 int nNewLength = GetData()->nDataLength;
1483 if (nIndex > nNewLength)
1484 nIndex = nNewLength;
1487 if (GetData()->nAllocLength < nNewLength)
1490 LPTSTR pstr = m_pchData;
1491 if(!AllocBuffer(nNewLength))
1493 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) *
sizeof(TCHAR), pstr, (pOldData->nDataLength + 1) *
sizeof(TCHAR));
1494 CString::Release(pOldData);
1498 SecureHelper::memmove_x(m_pchData + nIndex + 1, (GetData()->nAllocLength - nIndex) *
sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex) *
sizeof(TCHAR));
1499 m_pchData[nIndex] = ch;
1500 GetData()->nDataLength = nNewLength;
1506 int Insert(
int nIndex, LPCTSTR pstr)
1511 int nInsertLength = SafeStrlen(pstr);
1512 int nNewLength = GetData()->nDataLength;
1513 if (nInsertLength > 0)
1516 if (nIndex > nNewLength)
1517 nIndex = nNewLength;
1518 nNewLength += nInsertLength;
1520 if (GetData()->nAllocLength < nNewLength)
1523 LPTSTR pstr = m_pchData;
1524 if(!AllocBuffer(nNewLength))
1526 SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) *
sizeof(TCHAR), pstr, (pOldData->nDataLength + 1) *
sizeof(TCHAR));
1527 CString::Release(pOldData);
1531 SecureHelper::memmove_x(m_pchData + nIndex + nInsertLength, (GetData()->nAllocLength + 1 - nIndex - nInsertLength) *
sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex - nInsertLength + 1) *
sizeof(TCHAR));
1532 SecureHelper::memcpy_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) *
sizeof(TCHAR), pstr, nInsertLength *
sizeof(TCHAR));
1533 GetData()->nDataLength = nNewLength;
1540 int Delete(
int nIndex,
int nCount = 1)
1544 int nLength = GetData()->nDataLength;
1545 if (nCount > 0 && nIndex < nLength)
1547 if((nIndex + nCount) > nLength)
1548 nCount = nLength - nIndex;
1550 int nBytesToCopy = nLength - (nIndex + nCount) + 1;
1552 SecureHelper::memmove_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) *
sizeof(TCHAR), m_pchData + nIndex + nCount, nBytesToCopy *
sizeof(TCHAR));
1554 GetData()->nDataLength = nLength;
1562 int Find(TCHAR ch)
const 1567 int ReverseFind(TCHAR ch)
const 1570 LPCTSTR lpsz = _cstrrchr(m_pchData, (_TUCHAR)ch);
1573 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1576 int Find(TCHAR ch,
int nStart)
const 1578 int nLength = GetData()->nDataLength;
1579 if (nStart < 0 || nStart >= nLength)
1583 LPCTSTR lpsz = _cstrchr(m_pchData + nStart, (_TUCHAR)ch);
1586 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1589 int FindOneOf(LPCTSTR lpszCharSet)
const 1591 ATLASSERT(_IsValidString(lpszCharSet));
1592 LPCTSTR lpsz = _cstrpbrk(m_pchData, lpszCharSet);
1593 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1598 int Find(LPCTSTR lpszSub)
const 1600 return Find(lpszSub, 0);
1603 int Find(LPCTSTR lpszSub,
int nStart)
const 1605 ATLASSERT(_IsValidString(lpszSub));
1607 int nLength = GetData()->nDataLength;
1608 if (nStart < 0 || nStart > nLength)
1612 LPCTSTR lpsz = _cstrstr(m_pchData + nStart, lpszSub);
1615 return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
1621 const int cchBuff = 12;
1622 TCHAR szBuffer[cchBuff] = { 0 };
1623 SecureHelper::wsprintf_x(szBuffer, cchBuff, _T(
"%d"), n);
1624 ConcatInPlace(SafeStrlen(szBuffer), szBuffer);
1630 BOOL __cdecl Format(LPCTSTR lpszFormat, ...)
1632 ATLASSERT(_IsValidString(lpszFormat));
1635 va_start(argList, lpszFormat);
1636 BOOL bRet = FormatV(lpszFormat, argList);
1641 BOOL __cdecl Format(UINT nFormatID, ...)
1644 BOOL bRet = strFormat.LoadString(nFormatID);
1645 ATLASSERT(bRet != 0);
1648 va_start(argList, nFormatID);
1649 bRet = FormatV(strFormat, argList);
1654 BOOL FormatV(LPCTSTR lpszFormat, va_list argList)
1656 ATLASSERT(_IsValidString(lpszFormat));
1658 enum _FormatModifiers
1660 FORCE_ANSI = 0x10000,
1661 FORCE_UNICODE = 0x20000,
1662 FORCE_INT64 = 0x40000
1665 va_list argListSave = argList;
1669 for (LPCTSTR lpsz = lpszFormat; *lpsz != _T(
'\0'); lpsz = ::CharNext(lpsz))
1672 if (*lpsz != _T(
'%') || *(lpsz = ::CharNext(lpsz)) == _T(
'%'))
1674 nMaxLen += (int)(::CharNext(lpsz) - lpsz);
1682 for (; *lpsz != _T(
'\0'); lpsz = ::CharNext(lpsz))
1685 if (*lpsz == _T(
'#'))
1687 else if (*lpsz == _T(
'*'))
1688 nWidth = va_arg(argList,
int);
1689 else if (*lpsz == _T(
'-') || *lpsz == _T(
'+') || *lpsz == _T(
'0') || *lpsz == _T(
' '))
1698 nWidth = _cstrtoi(lpsz);
1699 for (; *lpsz != _T(
'\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
1702 ATLASSERT(nWidth >= 0);
1705 if (*lpsz == _T(
'.'))
1708 lpsz = ::CharNext(lpsz);
1711 if (*lpsz == _T(
'*'))
1713 nPrecision = va_arg(argList,
int);
1714 lpsz = ::CharNext(lpsz);
1718 nPrecision = _cstrtoi(lpsz);
1719 for (; *lpsz != _T(
'\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
1722 ATLASSERT(nPrecision >= 0);
1727 if(lpsz[0] == _T(
'I') && lpsz[1] == _T(
'6') && lpsz[2] == _T(
'4'))
1730 nModifier = FORCE_INT64;
1738 nModifier = FORCE_ANSI;
1739 lpsz = ::CharNext(lpsz);
1742 nModifier = FORCE_UNICODE;
1743 lpsz = ::CharNext(lpsz);
1750 lpsz = ::CharNext(lpsz);
1756 switch (*lpsz | nModifier)
1762 va_arg(argList, TCHAR);
1764 case _T(
'c') | FORCE_ANSI:
1765 case _T(
'C') | FORCE_ANSI:
1767 va_arg(argList,
char);
1769 case _T(
'c') | FORCE_UNICODE:
1770 case _T(
'C') | FORCE_UNICODE:
1772 va_arg(argList, WCHAR);
1778 LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR);
1779 if (pstrNextArg == NULL)
1785 nItemLen = lstrlen(pstrNextArg);
1786 nItemLen = max(1, nItemLen);
1794 LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
1795 if (pstrNextArg == NULL)
1801 nItemLen = (int)wcslen(pstrNextArg);
1802 nItemLen = max(1, nItemLen);
1805 LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
1806 if (pstrNextArg == NULL)
1812 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) 1813 nItemLen = ATL::lstrlenA(pstrNextArg);
1815 nItemLen = lstrlenA(pstrNextArg);
1817 nItemLen = max(1, nItemLen);
1823 case _T(
's') | FORCE_ANSI:
1824 case _T(
'S') | FORCE_ANSI:
1826 LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
1827 if (pstrNextArg == NULL)
1833 #if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) 1834 nItemLen = ATL::lstrlenA(pstrNextArg);
1836 nItemLen = lstrlenA(pstrNextArg);
1838 nItemLen = max(1, nItemLen);
1843 case _T(
's') | FORCE_UNICODE:
1844 case _T(
'S') | FORCE_UNICODE:
1846 LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
1847 if (pstrNextArg == NULL)
1853 nItemLen = (int)wcslen(pstrNextArg);
1854 nItemLen = max(1, nItemLen);
1863 nItemLen = max(nItemLen, nWidth);
1864 if (nPrecision != 0)
1865 nItemLen = min(nItemLen, nPrecision);
1878 if (nModifier & FORCE_INT64)
1879 va_arg(argList, __int64);
1881 va_arg(argList,
int);
1883 nItemLen = max(nItemLen, nWidth + nPrecision);
1886 #ifndef _ATL_USE_CSTRING_FLOAT 1892 ATLASSERT(!
"Floating point (%%e, %%E, %%f, %%g, and %%G) is not supported by the WTL::CString class.");
1894 ::OutputDebugString(_T(
"Floating point (%%e, %%f, %%g, and %%G) is not supported by the WTL::CString class."));
1897 #else // CE specific 1899 #endif // _WIN32_WCE 1902 #else // _ATL_USE_CSTRING_FLOAT 1907 va_arg(argList,
double);
1909 nItemLen = max(nItemLen, nWidth + nPrecision);
1913 double f = va_arg(argList,
double);
1918 int cchLen = max(nWidth, 312 + nPrecision + 6);
1920 LPTSTR pszTemp = buff.Allocate(cchLen);
1923 SecureHelper::sprintf_x(pszTemp, cchLen, _T(
"%*.*f"), nWidth, nPrecision + 6, f);
1924 nItemLen = (int)_tcslen(pszTemp);
1932 #endif // _ATL_USE_CSTRING_FLOAT 1935 va_arg(argList,
void*);
1937 nItemLen = max(nItemLen, nWidth + nPrecision);
1942 va_arg(argList,
int*);
1951 nMaxLen += nItemLen;
1954 if(GetBuffer(nMaxLen) == NULL)
1956 #ifndef _ATL_USE_CSTRING_FLOAT 1957 int nRet = SecureHelper::wvsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave);
1958 #else // _ATL_USE_CSTRING_FLOAT 1959 int nRet = SecureHelper::vsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave);
1960 #endif // _ATL_USE_CSTRING_FLOAT 1962 ATLASSERT(nRet <= GetAllocLength());
1965 va_end(argListSave);
1971 BOOL __cdecl FormatMessage(LPCTSTR lpszFormat, ...)
1975 va_start(argList, lpszFormat);
1979 if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1980 lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 || lpszTemp == NULL)
1985 LocalFree(lpszTemp);
1990 BOOL __cdecl FormatMessage(UINT nFormatID, ...)
1994 BOOL bRetTmp = strFormat.LoadString(nFormatID);
1996 ATLASSERT(bRetTmp != 0);
2000 va_start(argList, nFormatID);
2004 if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
2005 strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 || lpszTemp == NULL)
2010 LocalFree(lpszTemp);
2016 BOOL LoadString(UINT nID)
2019 const int CHAR_FUDGE = 1;
2021 const int CHAR_FUDGE = 2;
2025 TCHAR szTemp[256] = { 0 };
2026 int nCount =
sizeof(szTemp) /
sizeof(szTemp[0]);
2027 int nLen = _LoadString(nID, szTemp, nCount);
2028 if (nCount - nLen > CHAR_FUDGE)
2039 LPTSTR lpstr = GetBuffer(nSize - 1);
2045 nLen = _LoadString(nID, lpstr, nSize);
2046 }
while (nSize - nLen <= CHAR_FUDGE);
2057 ::AnsiToOem(m_pchData, m_pchData);
2063 ::OemToAnsi(m_pchData, m_pchData);
2069 BSTR AllocSysString()
const 2071 #if defined(_UNICODE) || defined(OLE2ANSI) 2072 BSTR bstr = ::SysAllocStringLen(m_pchData, GetData()->nDataLength);
2074 int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData,
2075 GetData()->nDataLength, NULL, NULL);
2076 BSTR bstr = ::SysAllocStringLen(NULL, nLen);
2078 MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, bstr, nLen);
2083 BSTR SetSysString(BSTR* pbstr)
const 2085 #if defined(_UNICODE) || defined(OLE2ANSI) 2086 ::SysReAllocStringLen(pbstr, m_pchData, GetData()->nDataLength);
2088 int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData,
2089 GetData()->nDataLength, NULL, NULL);
2090 if(::SysReAllocStringLen(pbstr, NULL, nLen))
2091 MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, *pbstr, nLen);
2093 ATLASSERT(*pbstr != NULL);
2096 #endif // !_ATL_NO_COM 2099 LPTSTR GetBuffer(
int nMinBufLength)
2101 ATLASSERT(nMinBufLength >= 0);
2103 if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength)
2107 int nOldLen = GetData()->nDataLength;
2108 if (nMinBufLength < nOldLen)
2109 nMinBufLength = nOldLen;
2111 if(!AllocBuffer(nMinBufLength))
2114 SecureHelper::memcpy_x(m_pchData, (nMinBufLength + 1) *
sizeof(TCHAR), pOldData->data(), (nOldLen + 1) *
sizeof(TCHAR));
2115 GetData()->nDataLength = nOldLen;
2116 CString::Release(pOldData);
2118 ATLASSERT(GetData()->nRefs <= 1);
2121 ATLASSERT(m_pchData != NULL);
2125 void ReleaseBuffer(
int nNewLength = -1)
2129 if (nNewLength == -1)
2130 nNewLength = lstrlen(m_pchData);
2132 ATLASSERT(nNewLength <= GetData()->nAllocLength);
2133 GetData()->nDataLength = nNewLength;
2134 m_pchData[nNewLength] = _T(
'\0');
2137 LPTSTR GetBufferSetLength(
int nNewLength)
2139 ATLASSERT(nNewLength >= 0);
2141 if(GetBuffer(nNewLength) == NULL)
2144 GetData()->nDataLength = nNewLength;
2145 m_pchData[nNewLength] = _T(
'\0');
2151 ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
2152 if (GetData()->nDataLength != GetData()->nAllocLength)
2155 if(AllocBuffer(GetData()->nDataLength))
2157 SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), pOldData->data(), pOldData->nDataLength *
sizeof(TCHAR));
2158 ATLASSERT(m_pchData[GetData()->nDataLength] == _T(
'\0'));
2159 CString::Release(pOldData);
2162 ATLASSERT(GetData() != NULL);
2168 LPTSTR lpsz = GetBuffer(0);
2170 GetData()->nRefs = -1;
2176 ATLASSERT(GetData()->nRefs == -1);
2177 if (GetData() != _atltmpDataNil)
2178 GetData()->nRefs = 1;
2185 if (GetData() != _atltmpDataNil)
2187 if (InterlockedDecrement(&GetData()->nRefs) <= 0)
2188 delete[] (BYTE*)GetData();
2192 int GetAllocLength()
const 2194 return GetData()->nAllocLength;
2197 static BOOL __stdcall _IsValidString(LPCTSTR lpsz,
int = -1)
2199 return (lpsz != NULL) ? TRUE : FALSE;
2208 ATLASSERT(m_pchData != NULL);
2214 m_pchData = _GetEmptyString().m_pchData;
2217 BOOL AllocCopy(
CString& dest,
int nCopyLen,
int nCopyIndex,
int nExtraLen)
const 2225 int nNewLen = nCopyLen + nExtraLen;
2231 else if(nNewLen >= nCopyLen)
2233 if(dest.AllocBuffer(nNewLen))
2235 SecureHelper::memcpy_x(dest.m_pchData, (nNewLen + 1) *
sizeof(TCHAR), m_pchData + nCopyIndex, nCopyLen *
sizeof(TCHAR));
2245 BOOL AllocBuffer(
int nLen)
2247 ATLASSERT(nLen >= 0);
2248 ATLASSERT(nLen <= INT_MAX - 1);
2262 pData->data()[nLen] = _T(
'\0');
2263 pData->nDataLength = nLen;
2264 pData->nAllocLength = nLen;
2265 m_pchData = pData->data();
2280 void AssignCopy(
int nSrcLen, LPCTSTR lpszSrcData)
2282 if(AllocBeforeWrite(nSrcLen))
2284 SecureHelper::memcpy_x(m_pchData, (nSrcLen + 1) *
sizeof(TCHAR), lpszSrcData, nSrcLen *
sizeof(TCHAR));
2285 GetData()->nDataLength = nSrcLen;
2286 m_pchData[nSrcLen] = _T(
'\0');
2297 BOOL ConcatCopy(
int nSrc1Len, LPCTSTR lpszSrc1Data,
int nSrc2Len, LPCTSTR lpszSrc2Data)
2304 int nNewLen = nSrc1Len + nSrc2Len;
2305 if(nNewLen < nSrc1Len || nNewLen < nSrc2Len)
2309 else if(nNewLen != 0)
2311 bRet = AllocBuffer(nNewLen);
2314 SecureHelper::memcpy_x(m_pchData, (nNewLen + 1) *
sizeof(TCHAR), lpszSrc1Data, nSrc1Len *
sizeof(TCHAR));
2315 SecureHelper::memcpy_x(m_pchData + nSrc1Len, (nNewLen + 1 - nSrc1Len) *
sizeof(TCHAR), lpszSrc2Data, nSrc2Len *
sizeof(TCHAR));
2321 void ConcatInPlace(
int nSrcLen, LPCTSTR lpszSrcData)
2331 if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
2335 if (ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData))
2337 ATLASSERT(pOldData != NULL);
2338 CString::Release(pOldData);
2344 SecureHelper::memcpy_x(m_pchData + GetData()->nDataLength, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), lpszSrcData, nSrcLen *
sizeof(TCHAR));
2345 GetData()->nDataLength += nSrcLen;
2346 ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
2347 m_pchData[GetData()->nDataLength] = _T(
'\0');
2351 void CopyBeforeWrite()
2353 if (GetData()->nRefs > 1)
2357 if(AllocBuffer(pData->nDataLength))
2358 SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) *
sizeof(TCHAR), pData->data(), (pData->nDataLength + 1) *
sizeof(TCHAR));
2360 ATLASSERT(GetData()->nRefs <= 1);
2363 BOOL AllocBeforeWrite(
int nLen)
2366 if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
2369 bRet = AllocBuffer(nLen);
2371 ATLASSERT(GetData()->nRefs <= 1);
2377 if (GetData() != _atltmpDataNil)
2379 ATLASSERT(GetData()->nRefs != 0);
2380 if (InterlockedDecrement(&GetData()->nRefs) <= 0)
2381 delete[] (BYTE*)GetData();
2388 if (pData != _atltmpDataNil)
2390 ATLASSERT(pData->nRefs != 0);
2391 if (InterlockedDecrement(&pData->nRefs) <= 0)
2392 delete[] (BYTE*)pData;
2396 static int PASCAL SafeStrlen(LPCTSTR lpsz)
2398 return (lpsz == NULL) ? 0 : lstrlen(lpsz);
2401 static int __stdcall _LoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf)
2406 if (::FindResource(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE((nID >> 4) + 1), RT_STRING) == NULL)
2408 lpszBuf[0] = _T(
'\0');
2413 int nLen = ::LoadString(ModuleHelper::GetResourceInstance(), nID, lpszBuf, nMaxBuf);
2415 lpszBuf[0] = _T(
'\0');
2420 static const CString& __stdcall _GetEmptyString()
2422 return *(
CString*)&_atltmpPchNil;
2426 static int __cdecl _wcstombsz(
char* mbstr,
const wchar_t* wcstr,
size_t count)
2428 if (count == 0 && mbstr != NULL)
2431 int result = ::WideCharToMultiByte(CP_ACP, 0, wcstr, -1, mbstr, (
int)count, NULL, NULL);
2432 ATLASSERT(mbstr == NULL || result <= (
int)count);
2434 mbstr[result - 1] = 0;
2438 static int __cdecl _mbstowcsz(
wchar_t* wcstr,
const char* mbstr,
size_t count)
2440 if (count == 0 && wcstr != NULL)
2443 int result = ::MultiByteToWideChar(CP_ACP, 0, mbstr, -1, wcstr, (
int)count);
2444 ATLASSERT(wcstr == NULL || result <= (
int)count);
2446 wcstr[result - 1] = 0;
2452 static const TCHAR* _cstrchr(
const TCHAR* p, TCHAR ch)
2461 return (*p == ch) ? p : NULL;
2464 static TCHAR* _cstrrev(TCHAR* pStr)
2467 if ((pStr == NULL) || (pStr[0] == _T(
'\0')) || (pStr[1] == _T(
'\0')))
2474 TCHAR* pNext = ::CharNext(p);
2477 char p1 = *(
char*)p;
2478 *(
char*)p = *(
char*)(p + 1);
2479 *(
char*)(p + 1) = p1;
2498 static const TCHAR* _cstrstr(
const TCHAR* pStr,
const TCHAR* pCharSet)
2500 int nLen = lstrlen(pCharSet);
2502 return (TCHAR*)pStr;
2504 const TCHAR* pRet = NULL;
2505 const TCHAR* pCur = pStr;
2506 while((pCur = _cstrchr(pCur, *pCharSet)) != NULL)
2508 if(memcmp(pCur, pCharSet, nLen *
sizeof(TCHAR)) == 0)
2513 pCur = ::CharNext(pCur);
2518 static int _cstrspn(
const TCHAR* pStr,
const TCHAR* pCharSet)
2521 const TCHAR* p = pStr;
2524 const TCHAR* pNext = ::CharNext(p);
2527 if(_cstrchr_db(pCharSet, *p, *(p + 1)) == NULL)
2533 if(_cstrchr(pCharSet, *p) == NULL)
2542 static int _cstrcspn(
const TCHAR* pStr,
const TCHAR* pCharSet)
2545 TCHAR* p = (TCHAR*)pStr;
2548 TCHAR* pNext = ::CharNext(p);
2551 if(_cstrchr_db(pCharSet, *p, *(p + 1)) != NULL)
2557 if(_cstrchr(pCharSet, *p) != NULL)
2566 static const TCHAR* _cstrpbrk(
const TCHAR* p,
const TCHAR* lpszCharSet)
2568 int n = _cstrcspn(p, lpszCharSet);
2569 return (p[n] != 0) ? &p[n] : NULL;
2572 static int _cstrcmp(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2574 return lstrcmp(pstrOne, pstrOther);
2577 static int _cstrcmpi(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2579 return lstrcmpi(pstrOne, pstrOther);
2582 static int _cstrcoll(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2584 int nRet = CompareString(GetThreadLocale(), 0, pstrOne, -1, pstrOther, -1);
2585 ATLASSERT(nRet != 0);
2589 static int _cstrcolli(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2591 int nRet = CompareString(GetThreadLocale(), NORM_IGNORECASE, pstrOne, -1, pstrOther, -1);
2592 ATLASSERT(nRet != 0);
2595 #else // !_ATL_MIN_CRT 2596 static const TCHAR* _cstrchr(
const TCHAR* p, TCHAR ch)
2598 return _tcschr(p, ch);
2601 static TCHAR* _cstrrev(TCHAR* pStr)
2603 return _tcsrev(pStr);
2606 static const TCHAR* _cstrstr(
const TCHAR* pStr,
const TCHAR* pCharSet)
2608 return _tcsstr(pStr, pCharSet);
2611 static int _cstrspn(
const TCHAR* pStr,
const TCHAR* pCharSet)
2613 return (
int)_tcsspn(pStr, pCharSet);
2616 static int _cstrcspn(
const TCHAR* pStr,
const TCHAR* pCharSet)
2618 return (
int)_tcscspn(pStr, pCharSet);
2621 static const TCHAR* _cstrpbrk(
const TCHAR* p,
const TCHAR* lpszCharSet)
2623 return _tcspbrk(p, lpszCharSet);
2626 static int _cstrcmp(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2628 return _tcscmp(pstrOne, pstrOther);
2631 static int _cstrcmpi(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2633 return _tcsicmp(pstrOne, pstrOther);
2637 static int _cstrcoll(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2639 return _tcscoll(pstrOne, pstrOther);
2642 static int _cstrcolli(
const TCHAR* pstrOne,
const TCHAR* pstrOther)
2644 return _tcsicoll(pstrOne, pstrOther);
2646 #endif // !_WIN32_WCE 2647 #endif // !_ATL_MIN_CRT 2649 static const TCHAR* _cstrrchr(
const TCHAR* p, TCHAR ch)
2651 return MinCrtHelper::_strrchr(p, ch);
2654 static int _cstrisdigit(TCHAR ch)
2656 return MinCrtHelper::_isdigit(ch);
2659 static int _cstrisspace(TCHAR ch)
2661 return MinCrtHelper::_isspace(ch);
2664 static int _cstrtoi(
const TCHAR* nptr)
2666 return MinCrtHelper::_atoi(nptr);
2669 static const TCHAR* _cstrchr_db(
const TCHAR* p, TCHAR ch1, TCHAR ch2)
2671 const TCHAR* lpsz = NULL;
2674 if (*p == ch1 && *(p + 1) == ch2)
2688 inline bool __stdcall operator ==(
const CString& s1,
const CString& s2)
2689 {
return s1.Compare(s2) == 0; }
2691 inline bool __stdcall operator ==(
const CString& s1, LPCTSTR s2)
2692 {
return s1.Compare(s2) == 0; }
2694 inline bool __stdcall operator ==(LPCTSTR s1,
const CString& s2)
2695 {
return s2.Compare(s1) == 0; }
2697 inline bool __stdcall operator !=(
const CString& s1,
const CString& s2)
2698 {
return s1.Compare(s2) != 0; }
2700 inline bool __stdcall operator !=(
const CString& s1, LPCTSTR s2)
2701 {
return s1.Compare(s2) != 0; }
2703 inline bool __stdcall operator !=(LPCTSTR s1,
const CString& s2)
2704 {
return s2.Compare(s1) != 0; }
2706 inline bool __stdcall operator <(
const CString& s1,
const CString& s2)
2707 {
return s1.Compare(s2) < 0; }
2709 inline bool __stdcall operator <(
const CString& s1, LPCTSTR s2)
2710 {
return s1.Compare(s2) < 0; }
2712 inline bool __stdcall operator <(LPCTSTR s1,
const CString& s2)
2713 {
return s2.Compare(s1) > 0; }
2715 inline bool __stdcall operator >(
const CString& s1,
const CString& s2)
2716 {
return s1.Compare(s2) > 0; }
2718 inline bool __stdcall operator >(
const CString& s1, LPCTSTR s2)
2719 {
return s1.Compare(s2) > 0; }
2721 inline bool __stdcall operator >(LPCTSTR s1,
const CString& s2)
2722 {
return s2.Compare(s1) < 0; }
2724 inline bool __stdcall operator <=(
const CString& s1,
const CString& s2)
2725 {
return s1.Compare(s2) <= 0; }
2727 inline bool __stdcall operator <=(
const CString& s1, LPCTSTR s2)
2728 {
return s1.Compare(s2) <= 0; }
2730 inline bool __stdcall operator <=(LPCTSTR s1,
const CString& s2)
2731 {
return s2.Compare(s1) >= 0; }
2733 inline bool __stdcall operator >=(
const CString& s1,
const CString& s2)
2734 {
return s1.Compare(s2) >= 0; }
2736 inline bool __stdcall operator >=(
const CString& s1, LPCTSTR s2)
2737 {
return s1.Compare(s2) >= 0; }
2739 inline bool __stdcall operator >=(LPCTSTR s1,
const CString& s2)
2740 {
return s2.Compare(s1) <= 0; }
2748 s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, string2.GetData()->nDataLength, string2.m_pchData);
2752 inline CString __stdcall operator +(
const CString&
string, TCHAR ch)
2755 s.ConcatCopy(
string.GetData()->nDataLength,
string.m_pchData, 1, &ch);
2759 inline CString __stdcall operator +(TCHAR ch,
const CString&
string)
2762 s.ConcatCopy(1, &ch,
string.GetData()->nDataLength,
string.m_pchData);
2767 inline CString __stdcall operator +(
const CString&
string,
char ch)
2769 return string + (TCHAR)ch;
2772 inline CString __stdcall operator +(
char ch,
const CString&
string)
2774 return (TCHAR)ch + string;
2778 inline CString __stdcall operator +(
const CString&
string, LPCTSTR lpsz)
2780 ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz));
2782 s.ConcatCopy(
string.GetData()->nDataLength,
string.m_pchData, CString::SafeStrlen(lpsz), lpsz);
2786 inline CString __stdcall operator +(LPCTSTR lpsz,
const CString&
string)
2788 ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz));
2790 s.ConcatCopy(CString::SafeStrlen(lpsz), lpsz,
string.GetData()->nDataLength,
string.m_pchData);
2794 #endif // !_WTL_NO_CSTRING 2802 #ifndef _WTL_MRUEMPTY_TEXT 2803 #define _WTL_MRUEMPTY_TEXT _T("(empty)") 2807 inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn,
int cchLen);
2809 template <
class T,
int t_cchItemLen = MAX_PATH,
int t_nFirstID = ID_FILE_MRU_FIRST,
int t_nLastID = ID_FILE_MRU_LAST>
2816 TCHAR szDocName[t_cchItemLen];
2817 bool operator ==(
const _DocEntry& de)
const 2818 {
return (lstrcmpi(szDocName, de.szDocName) == 0); }
2823 m_nMaxEntries_Min = 2,
2824 m_nMaxEntries_Max = t_nLastID - t_nFirstID + 1,
2825 m_cchMaxItemLen_Min = 6,
2826 m_cchMaxItemLen_Max = t_cchItemLen,
2827 m_cchItemNameLen = 11
2831 ATL::CSimpleArray<_DocEntry> m_arrDocs;
2835 TCHAR m_szNoEntries[t_cchItemLen];
2837 int m_cchMaxItemLen;
2843 ATLASSERT(t_cchItemLen > m_cchMaxItemLen_Min);
2844 ATLASSERT(m_nMaxEntries_Max > m_nMaxEntries_Min);
2848 HMENU GetMenuHandle()
const 2853 void SetMenuHandle(HMENU hMenu)
2855 ATLASSERT(hMenu == NULL || ::IsMenu(hMenu));
2857 if(m_hMenu == NULL || (::GetMenuString(m_hMenu, t_nFirstID, m_szNoEntries, t_cchItemLen, MF_BYCOMMAND) == 0))
2859 T* pT =
static_cast<T*
>(
this);
2861 SecureHelper::strncpy_x(m_szNoEntries, _countof(m_szNoEntries), pT->GetMRUEmptyText(), _TRUNCATE);
2865 int GetMaxEntries()
const 2867 return m_nMaxEntries;
2870 void SetMaxEntries(
int nMaxEntries)
2872 ATLASSERT(nMaxEntries >= m_nMaxEntries_Min && nMaxEntries <= m_nMaxEntries_Max);
2873 if(nMaxEntries < m_nMaxEntries_Min)
2874 nMaxEntries = m_nMaxEntries_Min;
2875 else if(nMaxEntries > m_nMaxEntries_Max)
2876 nMaxEntries = m_nMaxEntries_Max;
2877 m_nMaxEntries = nMaxEntries;
2880 int GetMaxItemLength()
const 2882 return m_cchMaxItemLen;
2885 void SetMaxItemLength(
int cchMaxLen)
2887 ATLASSERT((cchMaxLen >= m_cchMaxItemLen_Min && cchMaxLen <= m_cchMaxItemLen_Max) || cchMaxLen == -1);
2890 if(cchMaxLen < m_cchMaxItemLen_Min)
2891 cchMaxLen = m_cchMaxItemLen_Min;
2892 else if(cchMaxLen > m_cchMaxItemLen_Max)
2893 cchMaxLen = m_cchMaxItemLen_Max;
2895 m_cchMaxItemLen = cchMaxLen;
2896 T* pT =
static_cast<T*
>(
this);
2901 BOOL AddToList(LPCTSTR lpstrDocName)
2904 errno_t nRet = SecureHelper::strncpy_x(de.szDocName, _countof(de.szDocName), lpstrDocName, _TRUNCATE);
2905 if(nRet != 0 && nRet != STRUNCATE)
2908 for(
int i = 0; i < m_arrDocs.GetSize(); i++)
2910 if(lstrcmpi(m_arrDocs[i].szDocName, lpstrDocName) == 0)
2912 m_arrDocs.RemoveAt(i);
2917 if(m_arrDocs.GetSize() == m_nMaxEntries)
2918 m_arrDocs.RemoveAt(0);
2920 BOOL bRet = m_arrDocs.Add(de);
2923 T* pT =
static_cast<T*
>(
this);
2924 bRet = pT->UpdateMenu();
2931 #if (_MSC_VER >= 1300) 2932 __declspec(deprecated)
2934 BOOL GetFromList(
int , LPTSTR )
2940 BOOL GetFromList(
int nItemID, LPTSTR lpstrDocName,
int cchLength)
2942 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2943 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2945 if(lstrlen(m_arrDocs[nIndex].szDocName) >= cchLength)
2947 SecureHelper::strcpy_x(lpstrDocName, cchLength, m_arrDocs[nIndex].szDocName);
2952 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 2953 BOOL GetFromList(
int nItemID, _CSTRING_NS::CString& strDocName)
2955 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2956 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2958 strDocName = m_arrDocs[nIndex].szDocName;
2961 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 2963 BOOL RemoveFromList(
int nItemID)
2965 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2966 BOOL bRet = m_arrDocs.RemoveAt(nIndex);
2969 T* pT =
static_cast<T*
>(
this);
2970 bRet = pT->UpdateMenu();
2975 BOOL MoveToTop(
int nItemID)
2977 int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1;
2978 if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
2981 de = m_arrDocs[nIndex];
2982 m_arrDocs.RemoveAt(nIndex);
2983 BOOL bRet = m_arrDocs.Add(de);
2986 T* pT =
static_cast<T*
>(
this);
2987 bRet = pT->UpdateMenu();
2992 BOOL ReadFromRegistry(LPCTSTR lpstrRegKey)
2994 T* pT =
static_cast<T*
>(
this);
2998 LONG lRet = rkParent.Open(HKEY_CURRENT_USER, lpstrRegKey);
2999 if(lRet != ERROR_SUCCESS)
3001 lRet = rk.Open(rkParent, pT->GetRegKeyName());
3002 if(lRet != ERROR_SUCCESS)
3006 lRet = rk.QueryDWORDValue(pT->GetRegCountName(), dwRet);
3007 if(lRet != ERROR_SUCCESS)
3009 SetMaxEntries(dwRet);
3011 m_arrDocs.RemoveAll();
3013 TCHAR szRetString[t_cchItemLen] = { 0 };
3016 for(
int nItem = m_nMaxEntries; nItem > 0; nItem--)
3018 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3019 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3020 ULONG ulCount = t_cchItemLen;
3021 lRet = rk.QueryStringValue(szBuff, szRetString, &ulCount);
3022 if(lRet == ERROR_SUCCESS)
3024 SecureHelper::strcpy_x(de.szDocName, _countof(de.szDocName), szRetString);
3032 return pT->UpdateMenu();
3035 BOOL WriteToRegistry(LPCTSTR lpstrRegKey)
3037 T* pT =
static_cast<T*
>(
this);
3042 LONG lRet = rkParent.Create(HKEY_CURRENT_USER, lpstrRegKey);
3043 if(lRet != ERROR_SUCCESS)
3045 lRet = rk.Create(rkParent, pT->GetRegKeyName());
3046 if(lRet != ERROR_SUCCESS)
3049 lRet = rk.SetDWORDValue(pT->GetRegCountName(), m_nMaxEntries);
3050 ATLASSERT(lRet == ERROR_SUCCESS);
3054 for(nItem = m_arrDocs.GetSize(); nItem > 0; nItem--)
3056 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3057 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3058 TCHAR szDocName[t_cchItemLen] = { 0 };
3059 GetFromList(t_nFirstID + nItem - 1, szDocName, t_cchItemLen);
3060 lRet = rk.SetStringValue(szBuff, szDocName);
3061 ATLASSERT(lRet == ERROR_SUCCESS);
3065 for(nItem = m_arrDocs.GetSize() + 1; nItem < m_nMaxEntries_Max; nItem++)
3067 TCHAR szBuff[m_cchItemNameLen] = { 0 };
3068 SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem);
3069 rk.DeleteValue(szBuff);
3083 ATLASSERT(::IsMenu(m_hMenu));
3085 int nItems = ::GetMenuItemCount(m_hMenu);
3087 for(nInsertPoint = 0; nInsertPoint < nItems; nInsertPoint++)
3091 ::GetMenuItemInfo(m_hMenu, nInsertPoint, TRUE, &mi);
3092 if (mi.wID == t_nFirstID)
3095 ATLASSERT(nInsertPoint < nItems &&
"You need a menu item with an ID = t_nFirstID");
3098 for(nItem = t_nFirstID; nItem < t_nFirstID + m_nMaxEntries; nItem++)
3101 if (nItem != t_nFirstID)
3102 ::DeleteMenu(m_hMenu, nItem, MF_BYCOMMAND);
3105 TCHAR szItemText[t_cchItemLen + 6] = { 0 };
3106 int nSize = m_arrDocs.GetSize();
3110 for(nItem = 0; nItem < nSize; nItem++)
3112 if(m_cchMaxItemLen == -1)
3114 SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T(
"&%i %s"), nItem + 1, m_arrDocs[nSize - 1 - nItem].szDocName);
3118 TCHAR szBuff[t_cchItemLen] = { 0 };
3119 T* pT =
static_cast<T*
>(
this);
3121 bool bRet = pT->CompactDocumentName(szBuff, m_arrDocs[nSize - 1 - nItem].szDocName, m_cchMaxItemLen);
3124 SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T(
"&%i %s"), nItem + 1, szBuff);
3126 ::InsertMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION | MF_STRING, t_nFirstID + nItem, szItemText);
3131 ::InsertMenu(m_hMenu, nInsertPoint, MF_BYPOSITION | MF_STRING, t_nFirstID, m_szNoEntries);
3132 ::EnableMenuItem(m_hMenu, t_nFirstID, MF_GRAYED);
3135 ::DeleteMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION);
3142 static bool CompactDocumentName(LPTSTR lpstrOut, LPCTSTR lpstrIn,
int cchLen)
3144 return AtlCompactPath(lpstrOut, lpstrIn, cchLen);
3147 static LPCTSTR GetRegKeyName()
3149 return _T(
"Recent Document List");
3152 static LPCTSTR GetRegCountName()
3154 return _T(
"DocumentCount");
3157 static LPCTSTR GetRegItemName()
3162 return _T(
"Document%i");
3165 static LPCTSTR GetMRUEmptyText()
3167 return _WTL_MRUEMPTY_TEXT;
3177 #endif // _WIN32_WCE 3187 WIN32_FIND_DATA m_fd;
3188 TCHAR m_lpszRoot[MAX_PATH];
3189 TCHAR m_chDirSeparator;
3194 CFindFile() : m_hFind(NULL), m_chDirSeparator(_T(
'\\')), m_bFound(FALSE)
3203 ULONGLONG GetFileSize()
const 3205 ATLASSERT(m_hFind != NULL);
3207 ULARGE_INTEGER nFileSize = { 0 };
3211 nFileSize.LowPart = m_fd.nFileSizeLow;
3212 nFileSize.HighPart = m_fd.nFileSizeHigh;
3216 nFileSize.QuadPart = 0;
3219 return nFileSize.QuadPart;
3222 BOOL GetFileName(LPTSTR lpstrFileName,
int cchLength)
const 3224 ATLASSERT(m_hFind != NULL);
3225 if(lstrlen(m_fd.cFileName) >= cchLength)
3229 SecureHelper::strcpy_x(lpstrFileName, cchLength, m_fd.cFileName);
3234 BOOL GetFilePath(LPTSTR lpstrFilePath,
int cchLength)
const 3236 ATLASSERT(m_hFind != NULL);
3238 int nLen = lstrlen(m_lpszRoot);
3240 ATLASSERT(nLen > 0);
3244 bool bAddSep = (m_lpszRoot[nLen - 1] != _T(
'\\') && m_lpszRoot[nLen - 1] !=_T(
'/'));
3245 #else // CE specific 3247 bool bAddSep = ((nLen == 0) || (m_lpszRoot[nLen - 1] != _T(
'\\') && m_lpszRoot[nLen - 1] !=_T(
'/')));
3248 #endif // _WIN32_WCE 3250 if((lstrlen(m_lpszRoot) + (bAddSep ? 1 : 0)) >= cchLength)
3253 SecureHelper::strcpy_x(lpstrFilePath, cchLength, m_lpszRoot);
3257 TCHAR szSeparator[2] = { m_chDirSeparator, 0 };
3258 SecureHelper::strcat_x(lpstrFilePath, cchLength, szSeparator);
3261 SecureHelper::strcat_x(lpstrFilePath, cchLength, m_fd.cFileName);
3267 BOOL GetFileTitle(LPTSTR lpstrFileTitle,
int cchLength)
const 3269 ATLASSERT(m_hFind != NULL);
3271 TCHAR szBuff[MAX_PATH] = { 0 };
3272 if(!GetFileName(szBuff, MAX_PATH))
3275 if(lstrlen(szBuff) >= cchLength || cchLength < 1)
3279 LPTSTR pstrDot = MinCrtHelper::_strrchr(szBuff, _T(
'.'));
3283 SecureHelper::strcpy_x(lpstrFileTitle, cchLength, szBuff);
3287 #endif // !_WIN32_WCE 3289 BOOL GetFileURL(LPTSTR lpstrFileURL,
int cchLength)
const 3291 ATLASSERT(m_hFind != NULL);
3293 TCHAR szBuff[MAX_PATH] = { 0 };
3294 if(!GetFilePath(szBuff, MAX_PATH))
3296 LPCTSTR lpstrFileURLPrefix = _T(
"file://");
3297 if(lstrlen(szBuff) + lstrlen(lpstrFileURLPrefix) >= cchLength)
3299 SecureHelper::strcpy_x(lpstrFileURL, cchLength, lpstrFileURLPrefix);
3300 SecureHelper::strcat_x(lpstrFileURL, cchLength, szBuff);
3305 BOOL GetRoot(LPTSTR lpstrRoot,
int cchLength)
const 3307 ATLASSERT(m_hFind != NULL);
3308 if(lstrlen(m_lpszRoot) >= cchLength)
3311 SecureHelper::strcpy_x(lpstrRoot, cchLength, m_lpszRoot);
3316 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 3317 _CSTRING_NS::CString GetFileName()
const 3319 ATLASSERT(m_hFind != NULL);
3321 _CSTRING_NS::CString ret;
3324 ret = m_fd.cFileName;
3328 _CSTRING_NS::CString GetFilePath()
const 3330 ATLASSERT(m_hFind != NULL);
3332 _CSTRING_NS::CString strResult = m_lpszRoot;
3333 int nLen = strResult.GetLength();
3335 ATLASSERT(nLen > 0);
3339 if((strResult[nLen - 1] != _T(
'\\')) && (strResult[nLen - 1] != _T(
'/')))
3340 #else // CE specific 3342 if((nLen == 0) || ((strResult[nLen - 1] != _T(
'\\')) && (strResult[nLen - 1] != _T(
'/'))))
3343 #endif // _WIN32_WCE 3344 strResult += m_chDirSeparator;
3345 strResult += GetFileName();
3350 _CSTRING_NS::CString GetFileTitle()
const 3352 ATLASSERT(m_hFind != NULL);
3354 _CSTRING_NS::CString strResult;
3355 GetFileTitle(strResult.GetBuffer(MAX_PATH), MAX_PATH);
3356 strResult.ReleaseBuffer();
3360 #endif // !_WIN32_WCE 3362 _CSTRING_NS::CString GetFileURL()
const 3364 ATLASSERT(m_hFind != NULL);
3366 _CSTRING_NS::CString strResult(
"file://");
3367 strResult += GetFilePath();
3371 _CSTRING_NS::CString GetRoot()
const 3373 ATLASSERT(m_hFind != NULL);
3375 _CSTRING_NS::CString str = m_lpszRoot;
3378 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) 3380 BOOL GetLastWriteTime(FILETIME* pTimeStamp)
const 3382 ATLASSERT(m_hFind != NULL);
3383 ATLASSERT(pTimeStamp != NULL);
3385 if(m_bFound && pTimeStamp != NULL)
3387 *pTimeStamp = m_fd.ftLastWriteTime;
3394 BOOL GetLastAccessTime(FILETIME* pTimeStamp)
const 3396 ATLASSERT(m_hFind != NULL);
3397 ATLASSERT(pTimeStamp != NULL);
3399 if(m_bFound && pTimeStamp != NULL)
3401 *pTimeStamp = m_fd.ftLastAccessTime;
3408 BOOL GetCreationTime(FILETIME* pTimeStamp)
const 3410 ATLASSERT(m_hFind != NULL);
3412 if(m_bFound && pTimeStamp != NULL)
3414 *pTimeStamp = m_fd.ftCreationTime;
3421 BOOL MatchesMask(DWORD dwMask)
const 3423 ATLASSERT(m_hFind != NULL);
3426 return ((m_fd.dwFileAttributes & dwMask) != 0);
3433 ATLASSERT(m_hFind != NULL);
3438 BOOL bResult = FALSE;
3439 if(m_bFound && IsDirectory())
3441 if(m_fd.cFileName[0] == _T(
'.') && (m_fd.cFileName[1] == _T(
'\0') || (m_fd.cFileName[1] == _T(
'.') && m_fd.cFileName[2] == _T(
'\0'))))
3448 BOOL IsReadOnly()
const 3450 return MatchesMask(FILE_ATTRIBUTE_READONLY);
3453 BOOL IsDirectory()
const 3455 return MatchesMask(FILE_ATTRIBUTE_DIRECTORY);
3458 BOOL IsCompressed()
const 3460 return MatchesMask(FILE_ATTRIBUTE_COMPRESSED);
3463 BOOL IsSystem()
const 3465 return MatchesMask(FILE_ATTRIBUTE_SYSTEM);
3468 BOOL IsHidden()
const 3470 return MatchesMask(FILE_ATTRIBUTE_HIDDEN);
3473 BOOL IsTemporary()
const 3475 return MatchesMask(FILE_ATTRIBUTE_TEMPORARY);
3478 BOOL IsNormal()
const 3480 return MatchesMask(FILE_ATTRIBUTE_NORMAL);
3483 BOOL IsArchived()
const 3485 return MatchesMask(FILE_ATTRIBUTE_ARCHIVE);
3489 BOOL FindFile(LPCTSTR pstrName = NULL)
3493 if(pstrName == NULL)
3495 pstrName = _T(
"*.*");
3497 else if(lstrlen(pstrName) >= MAX_PATH)
3503 SecureHelper::strcpy_x(m_fd.cFileName, _countof(m_fd.cFileName), pstrName);
3505 m_hFind = ::FindFirstFile(pstrName, &m_fd);
3507 if(m_hFind == INVALID_HANDLE_VALUE)
3511 bool bFullPath = (::GetFullPathName(pstrName, MAX_PATH, m_lpszRoot, NULL) != 0);
3512 #else // CE specific 3513 errno_t nRet = SecureHelper::strncpy_x(m_lpszRoot, _countof(m_lpszRoot), pstrName, _TRUNCATE);
3514 bool bFullPath = (nRet == 0 || nRet == STRUNCATE);
3515 #endif // _WIN32_WCE 3518 ATLASSERT(bFullPath);
3522 ::SetLastError(ERROR_INVALID_NAME);
3528 LPTSTR pstrBack = MinCrtHelper::_strrchr(m_lpszRoot, _T(
'\\'));
3529 LPTSTR pstrFront = MinCrtHelper::_strrchr(m_lpszRoot, _T(
'/'));
3531 if(pstrFront != NULL || pstrBack != NULL)
3533 if(pstrFront == NULL)
3534 pstrFront = m_lpszRoot;
3535 if(pstrBack == NULL)
3536 pstrBack = m_lpszRoot;
3540 if(pstrFront >= pstrBack)
3541 *pstrFront = _T(
'\0');
3543 *pstrBack = _T(
'\0');
3554 ATLASSERT(m_hFind != NULL);
3562 m_bFound = ::FindNextFile(m_hFind, &m_fd);
3571 if(m_hFind != NULL && m_hFind != INVALID_HANDLE_VALUE)
3573 ::FindClose(m_hFind);
3583 inline HPEN AtlGetStockPen(
int nPen)
3585 #if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE) 3586 ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN);
3588 ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN);
3590 return (HPEN)::GetStockObject(nPen);
3593 inline HBRUSH AtlGetStockBrush(
int nBrush)
3595 #if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE) 3596 ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH);
3598 ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH);
3600 return (HBRUSH)::GetStockObject(nBrush);
3603 inline HFONT AtlGetStockFont(
int nFont)
3606 ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT);
3607 #else // CE specific 3608 ATLASSERT(nFont == SYSTEM_FONT);
3609 #endif // _WIN32_WCE 3610 return (HFONT)::GetStockObject(nFont);
3613 inline HPALETTE AtlGetStockPalette(
int nPalette)
3615 ATLASSERT(nPalette == DEFAULT_PALETTE);
3616 return (HPALETTE)::GetStockObject(nPalette);
3624 inline bool _IsDBCSTrailByte(LPCTSTR lpstr,
int nChar)
3630 if(!::IsDBCSLeadByte(lpstr[i - 1]))
3633 return ((nChar > 0) && (((nChar - i) & 1) != 0));
3640 inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn,
int cchLen)
3642 ATLASSERT(lpstrOut != NULL);
3643 ATLASSERT(lpstrIn != NULL);
3644 ATLASSERT(cchLen > 0);
3646 LPCTSTR szEllipsis = _T(
"...");
3647 const int cchEndEllipsis = 3;
3648 const int cchMidEllipsis = 4;
3650 if(lstrlen(lpstrIn) < cchLen)
3652 SecureHelper::strcpy_x(lpstrOut, cchLen, lpstrIn);
3659 TCHAR chSlash = _T(
'\\');
3660 for(LPTSTR lpstr = (LPTSTR)lpstrIn; *lpstr != 0; lpstr = ::CharNext(lpstr))
3662 if((*lpstr == _T(
'/')) || (*lpstr == _T(
'\\')))
3667 LPCTSTR lpstrFileName = lpstrIn;
3668 for(LPCTSTR pPath = lpstrIn; *pPath; pPath = ::CharNext(pPath))
3670 if((pPath[0] == _T(
'\\') || pPath[0] == _T(
':') || pPath[0] == _T(
'/'))
3671 && pPath[1] && pPath[1] != _T(
'\\') && pPath[1] != _T(
'/'))
3672 lpstrFileName = pPath + 1;
3674 int cchFileName = lstrlen(lpstrFileName);
3677 if(lpstrFileName == lpstrIn && cchLen > cchEndEllipsis)
3679 bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchLen - cchEndEllipsis - 1) == 0);
3683 if(_IsDBCSTrailByte(lpstrIn, cchLen - cchEndEllipsis))
3684 lpstrOut[cchLen - cchEndEllipsis - 1] = 0;
3686 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3692 if((cchLen < (cchMidEllipsis + cchEndEllipsis)))
3694 for(
int i = 0; i < cchLen - 1; i++)
3695 lpstrOut[i] = ((i + 1) == cchMidEllipsis) ? chSlash : _T(
'.');
3696 lpstrOut[cchLen - 1] = 0;
3701 int cchToCopy = cchLen - (cchMidEllipsis + cchFileName) - 1;
3707 if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrIn, cchToCopy))
3711 bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchToCopy) == 0);
3716 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3719 TCHAR szSlash[2] = { chSlash, 0 };
3720 SecureHelper::strcat_x(lpstrOut, cchLen, szSlash);
3725 if(cchLen > (cchMidEllipsis + cchFileName))
3727 SecureHelper::strcat_x(lpstrOut, cchLen, lpstrFileName);
3731 cchToCopy = cchLen - cchMidEllipsis - cchEndEllipsis - 1;
3733 if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrFileName, cchToCopy))
3736 bRet = (SecureHelper::strncpy_x(&lpstrOut[cchMidEllipsis], cchLen - cchMidEllipsis, lpstrFileName, cchToCopy) == 0);
3738 SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis);
3746 #endif // __ATLMISC_H__ Definition: atlmisc.h:2810
Definition: atlmisc.h:739
Definition: atlmisc.h:2814
Definition: atlapp.h:1730
Definition: atlmisc.h:292
Definition: atlmisc.h:3171
Definition: atlmisc.h:165
Definition: atlmisc.h:760
Definition: atlapp.h:1317
Definition: atlmisc.h:3183