📄 atlmisc.h
字号:
}
inline int CString::Find(LPCTSTR lpszSub, int nStart) const
{
ATLASSERT(_IsValidString(lpszSub));
int nLength = GetData()->nDataLength;
if (nStart < 0 || nStart > nLength)
return -1;
// find first matching substring
LPCTSTR lpsz = _cstrstr(m_pchData + nStart, lpszSub);
// return -1 for not found, distance from beginning otherwise
return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
}
inline BOOL CString::FormatV(LPCTSTR lpszFormat, va_list argList)
{
ATLASSERT(_IsValidString(lpszFormat));
enum _FormatModifiers
{
FORCE_ANSI = 0x10000,
FORCE_UNICODE = 0x20000,
FORCE_INT64 = 0x40000
};
va_list argListSave = argList;
// make a guess at the maximum length of the resulting string
int nMaxLen = 0;
for (LPCTSTR lpsz = lpszFormat; *lpsz != _T('\0'); lpsz = ::CharNext(lpsz))
{
// handle '%' character, but watch out for '%%'
if (*lpsz != _T('%') || *(lpsz = ::CharNext(lpsz)) == _T('%'))
{
// this is instead of _tclen()
#if !defined(_UNICODE) && defined(_MBCS)
nMaxLen += (int)(::CharNext(lpsz) - lpsz);
#else
nMaxLen++;
#endif
continue;
}
int nItemLen = 0;
// handle '%' character with format
int nWidth = 0;
for (; *lpsz != _T('\0'); lpsz = ::CharNext(lpsz))
{
// check for valid flags
if (*lpsz == _T('#'))
nMaxLen += 2; // for '0x'
else if (*lpsz == _T('*'))
nWidth = va_arg(argList, int);
else if (*lpsz == _T('-') || *lpsz == _T('+') || *lpsz == _T('0') || *lpsz == _T(' '))
;
else // hit non-flag character
break;
}
// get width and skip it
if (nWidth == 0)
{
// width indicated by
nWidth = _cstrtoi(lpsz);
for (; *lpsz != _T('\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
;
}
ATLASSERT(nWidth >= 0);
int nPrecision = 0;
if (*lpsz == _T('.'))
{
// skip past '.' separator (width.precision)
lpsz = ::CharNext(lpsz);
// get precision and skip it
if (*lpsz == _T('*'))
{
nPrecision = va_arg(argList, int);
lpsz = ::CharNext(lpsz);
}
else
{
nPrecision = _cstrtoi(lpsz);
for (; *lpsz != _T('\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz))
;
}
ATLASSERT(nPrecision >= 0);
}
// should be on type modifier or specifier
int nModifier = 0;
if(lpsz[0] == _T('I') && lpsz[1] == _T('6') && lpsz[2] == _T('4'))
{
lpsz += 3;
nModifier = FORCE_INT64;
}
else
{
switch (*lpsz)
{
// modifiers that affect size
case _T('h'):
nModifier = FORCE_ANSI;
lpsz = ::CharNext(lpsz);
break;
case _T('l'):
nModifier = FORCE_UNICODE;
lpsz = ::CharNext(lpsz);
break;
// modifiers that do not affect size
case _T('F'):
case _T('N'):
case _T('L'):
lpsz = ::CharNext(lpsz);
break;
}
}
// now should be on specifier
switch (*lpsz | nModifier)
{
// single characters
case _T('c'):
case _T('C'):
nItemLen = 2;
va_arg(argList, TCHAR);
break;
case _T('c') | FORCE_ANSI:
case _T('C') | FORCE_ANSI:
nItemLen = 2;
va_arg(argList, char);
break;
case _T('c') | FORCE_UNICODE:
case _T('C') | FORCE_UNICODE:
nItemLen = 2;
va_arg(argList, WCHAR);
break;
// strings
case _T('s'):
{
LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR);
if (pstrNextArg == NULL)
{
nItemLen = 6; // "(null)"
}
else
{
nItemLen = lstrlen(pstrNextArg);
nItemLen = max(1, nItemLen);
}
break;
}
case _T('S'):
{
#ifndef _UNICODE
LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
if (pstrNextArg == NULL)
{
nItemLen = 6; // "(null)"
}
else
{
nItemLen = (int)wcslen(pstrNextArg);
nItemLen = max(1, nItemLen);
}
#else // _UNICODE
LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
if (pstrNextArg == NULL)
{
nItemLen = 6; // "(null)"
}
else
{
#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800)
nItemLen = ATL::lstrlenA(pstrNextArg);
#else
nItemLen = lstrlenA(pstrNextArg);
#endif
nItemLen = max(1, nItemLen);
}
#endif // _UNICODE
break;
}
case _T('s') | FORCE_ANSI:
case _T('S') | FORCE_ANSI:
{
LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
if (pstrNextArg == NULL)
{
nItemLen = 6; // "(null)"
}
else
{
#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800)
nItemLen = ATL::lstrlenA(pstrNextArg);
#else
nItemLen = lstrlenA(pstrNextArg);
#endif
nItemLen = max(1, nItemLen);
}
break;
}
case _T('s') | FORCE_UNICODE:
case _T('S') | FORCE_UNICODE:
{
LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
if (pstrNextArg == NULL)
{
nItemLen = 6; // "(null)"
}
else
{
nItemLen = (int)wcslen(pstrNextArg);
nItemLen = max(1, nItemLen);
}
break;
}
}
// adjust nItemLen for strings
if (nItemLen != 0)
{
nItemLen = max(nItemLen, nWidth);
if (nPrecision != 0)
nItemLen = min(nItemLen, nPrecision);
}
else
{
switch (*lpsz)
{
// integers
case _T('d'):
case _T('i'):
case _T('u'):
case _T('x'):
case _T('X'):
case _T('o'):
if (nModifier & FORCE_INT64)
va_arg(argList, __int64);
else
va_arg(argList, int);
nItemLen = 32;
nItemLen = max(nItemLen, nWidth + nPrecision);
break;
#ifndef _ATL_USE_CSTRING_FLOAT
case _T('e'):
case _T('E'):
case _T('f'):
case _T('g'):
case _T('G'):
ATLASSERT(!"Floating point (%%e, %%E, %%f, %%g, and %%G) is not supported by the WTL::CString class.");
#ifndef _DEBUG
::OutputDebugString(_T("Floating point (%%e, %%f, %%g, and %%G) is not supported by the WTL::CString class."));
#ifndef _WIN32_WCE
::DebugBreak();
#else // CE specific
DebugBreak();
#endif // _WIN32_WCE
#endif // !_DEBUG
break;
#else // _ATL_USE_CSTRING_FLOAT
case _T('e'):
case _T('E'):
case _T('g'):
case _T('G'):
va_arg(argList, double);
nItemLen = 128;
nItemLen = max(nItemLen, nWidth + nPrecision);
break;
case _T('f'):
{
double f;
LPTSTR pszTemp;
// 312 == strlen("-1+(309 zeroes).")
// 309 zeroes == max precision of a double
// 6 == adjustment in case precision is not specified,
// which means that the precision defaults to 6
pszTemp = (LPTSTR)_alloca(max(nWidth, 312 + nPrecision + 6) * sizeof(TCHAR));
f = va_arg(argList, double);
_stprintf(pszTemp, _T("%*.*f"), nWidth, nPrecision + 6, f);
nItemLen = _tcslen(pszTemp);
}
break;
#endif // _ATL_USE_CSTRING_FLOAT
case _T('p'):
va_arg(argList, void*);
nItemLen = 32;
nItemLen = max(nItemLen, nWidth + nPrecision);
break;
// no output
case _T('n'):
va_arg(argList, int*);
break;
default:
ATLASSERT(FALSE); // unknown formatting option
}
}
// adjust nMaxLen for output nItemLen
nMaxLen += nItemLen;
}
if(GetBuffer(nMaxLen) == NULL)
return FALSE;
#ifndef _ATL_USE_CSTRING_FLOAT
int nRet = ::wvsprintf(m_pchData, lpszFormat, argListSave);
#else // _ATL_USE_CSTRING_FLOAT
int nRet = _vstprintf(m_pchData, lpszFormat, argListSave);
#endif // _ATL_USE_CSTRING_FLOAT
nRet; // ref
ATLASSERT(nRet <= GetAllocLength());
ReleaseBuffer();
va_end(argListSave);
return TRUE;
}
// formatting (using wsprintf style formatting)
inline BOOL __cdecl CString::Format(LPCTSTR lpszFormat, ...)
{
ATLASSERT(_IsValidString(lpszFormat));
va_list argList;
va_start(argList, lpszFormat);
BOOL bRet = FormatV(lpszFormat, argList);
va_end(argList);
return bRet;
}
inline BOOL __cdecl CString::Format(UINT nFormatID, ...)
{
CString strFormat;
BOOL bRet = strFormat.LoadString(nFormatID);
ATLASSERT(bRet != 0);
va_list argList;
va_start(argList, nFormatID);
bRet = FormatV(strFormat, argList);
va_end(argList);
return bRet;
}
// formatting (using FormatMessage style formatting)
inline BOOL __cdecl CString::FormatMessage(LPCTSTR lpszFormat, ...)
{
// format message into temporary buffer lpszTemp
va_list argList;
va_start(argList, lpszFormat);
LPTSTR lpszTemp;
BOOL bRet = TRUE;
if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 || lpszTemp == NULL)
bRet = FALSE;
// assign lpszTemp into the resulting string and free the temporary
*this = lpszTemp;
LocalFree(lpszTemp);
va_end(argList);
return bRet;
}
inline BOOL __cdecl CString::FormatMessage(UINT nFormatID, ...)
{
// get format string from string table
CString strFormat;
BOOL bRetTmp = strFormat.LoadString(nFormatID);
bRetTmp; // ref
ATLASSERT(bRetTmp != 0);
// format message into temporary buffer lpszTemp
va_list argList;
va_start(argList, nFormatID);
LPTSTR lpszTemp;
BOOL bRet = TRUE;
if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 || lpszTemp == NULL)
bRet = FALSE;
// assign lpszTemp into the resulting string and free lpszTemp
*this = lpszTemp;
LocalFree(lpszTemp);
va_end(argList);
return bRet;
}
inline void CString::TrimRight()
{
CopyBeforeWrite();
// find beginning of trailing spaces by starting at beginning (DBCS aware)
LPTSTR lpsz = m_pchData;
LPTSTR lpszLast = NULL;
while (*lpsz != _T('\0'))
{
if (_cstrisspace(*lpsz))
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
{
lpszLast = NULL;
}
lpsz = ::CharNext(lpsz);
}
if (lpszLast != NULL)
{
// truncate at trailing space start
*lpszLast = _T('\0');
GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
}
}
inline void CString::TrimLeft()
{
CopyBeforeWrite();
// find first non-space character
LPCTSTR lpsz = m_pchData;
while (_cstrisspace(*lpsz))
lpsz = ::CharNext(lpsz);
// fix up data and length
int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData);
memmove(m_pchData, lpsz, (nDataLength + 1) * sizeof(TCHAR));
GetData()->nDataLength = nDataLength;
}
inline void CString::TrimRight(LPCTSTR lpszTargetList)
{
// find beginning of trailing matches
// by starting at beginning (DBCS aware)
CopyBeforeWrite();
LPTSTR lpsz = m_pchData;
LPTSTR lpszLast = NULL;
while (*lpsz != _T('\0'))
{
TCHAR* pNext = ::CharNext(lpsz);
if(pNext > lpsz + 1)
{
if (_cstrchr_db(lpszTargetList, *lpsz, *(lpsz + 1)) != NULL)
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
{
lpszLast = NULL;
}
}
else
{
if (_cstrchr(lpszTargetList, *lpsz) != NULL)
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
{
lpszLast = NULL;
}
}
lpsz = pNext;
}
if (lpszLast != NULL)
{
// truncate at left-most matching character
*lpszLast = _T('\0');
GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
}
}
inline void CString::TrimRight(TCHAR chTarget)
{
// find beginning of trailing matches
// by starting at beginning (DBCS aware)
CopyBeforeWrite();
LPTSTR lpsz = m_pchData;
LPTSTR lpszLast = NULL;
while (*lpsz != _T('\0'))
{
if (*lpsz == chTarget)
{
if (lpszLast == NULL)
lpszLast = lpsz;
}
else
lpszLast = NULL;
lpsz = ::CharNext(lpsz);
}
if (lpszLast != NULL)
{
// truncate at left-most matching character
*lpszLast = _T('\0');
GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData);
}
}
inl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -