⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 string.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
 *  pidl     [I] ITEMIDLIST for lpStrRet->uType = STRRET_OFFSET
 *  pBstrOut [O] Destination for converted BSTR
 *
 * RETURNS
 *  Success: S_OK. pBstrOut contains the new string.
 *  Failure: E_FAIL, if any parameters are invalid.
 */
HRESULT WINAPI StrRetToBSTR(STRRET *lpStrRet, LPCITEMIDLIST pidl, BSTR* pBstrOut)
{
  HRESULT hRet = E_FAIL;

  switch (lpStrRet->uType)
  {
  case STRRET_WSTR:
    *pBstrOut = SysAllocString(lpStrRet->u.pOleStr);
    if (*pBstrOut)
      hRet = S_OK;
    CoTaskMemFree(lpStrRet->u.pOleStr);
    break;

  case STRRET_CSTR:
    hRet = _SHStrDupAToBSTR(lpStrRet->u.cStr, pBstrOut);
    break;

  case STRRET_OFFSET:
    hRet = _SHStrDupAToBSTR(((LPCSTR)&pidl->mkid) + lpStrRet->u.uOffset, pBstrOut);
    break;

  default:
    *pBstrOut = NULL;
  }

  return hRet;
}

/*************************************************************************
 * StrFormatKBSizeA	[SHLWAPI.@]
 *
 * Create a formatted string containing a byte count in Kilobytes.
 *
 * PARAMS
 *  llBytes  [I] Byte size to format
 *  lpszDest [I] Destination for formatted string
 *  cchMax   [I] Size of lpszDest
 *
 * RETURNS
 *  lpszDest.
 */
LPSTR WINAPI StrFormatKBSizeA(LONGLONG llBytes, LPSTR lpszDest, UINT cchMax)
{
  WCHAR wszBuf[256];
  
  if (!StrFormatKBSizeW(llBytes, wszBuf, 256))
    return NULL;
  if (!WideCharToMultiByte(CP_ACP, 0, wszBuf, -1, lpszDest, cchMax, NULL, NULL))
    return NULL;
  return lpszDest;
}

/*************************************************************************
 * StrFormatKBSizeW	[SHLWAPI.@]
 *
 * See StrFormatKBSizeA.
 */
LPWSTR WINAPI StrFormatKBSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax)
{
  static const WCHAR kb[] = {' ','K','B',0};
  LONGLONG llKB = (llBytes + 1023) >> 10;
  int len;

  TRACE("(0x%s,%p,%d)\n", wine_dbgstr_longlong(llBytes), lpszDest, cchMax);

  if (!FormatInt(llKB, lpszDest, cchMax))
    return NULL;

  len = lstrlenW(lpszDest);
  if (cchMax - len < 4)
      return NULL;
  lstrcatW(lpszDest, kb);
  return lpszDest;
}

/*************************************************************************
 * StrNCatA	[SHLWAPI.@]
 *
 * Concatenate two strings together.
 *
 * PARAMS
 *  lpszStr [O] String to concatenate to
 *  lpszCat [I] String to add to lpszCat
 *  cchMax  [I] Maximum number of characters to concatenate
 *
 * RETURNS
 *  lpszStr.
 *
 * NOTES
 *  cchMax determines the number of characters that are appended to lpszStr,
 *  not the total length of the string.
 */
LPSTR WINAPI StrNCatA(LPSTR lpszStr, LPCSTR lpszCat, INT cchMax)
{
  LPSTR lpszRet = lpszStr;

  TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszCat), cchMax);

  if (!lpszStr)
  {
    WARN("Invalid lpszStr would crash under Win32!\n");
    return NULL;
  }

  StrCpyNA(lpszStr + strlen(lpszStr), lpszCat, cchMax);
  return lpszRet;
}

/*************************************************************************
 * StrNCatW	[SHLWAPI.@]
 *
 * See StrNCatA.
 */
LPWSTR WINAPI StrNCatW(LPWSTR lpszStr, LPCWSTR lpszCat, INT cchMax)
{
  LPWSTR lpszRet = lpszStr;

  TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszCat), cchMax);

  if (!lpszStr)
  {
    WARN("Invalid lpszStr would crash under Win32\n");
    return NULL;
  }

  StrCpyNW(lpszStr + strlenW(lpszStr), lpszCat, cchMax);
  return lpszRet;
}

/*************************************************************************
 * StrTrimA	[SHLWAPI.@]
 *
 * Remove characters from the start and end of a string.
 *
 * PARAMS
 *  lpszStr  [O] String to remove characters from
 *  lpszTrim [I] Characters to remove from lpszStr
 *
 * RETURNS
 *  TRUE  If lpszStr was valid and modified
 *  FALSE Otherwise
 */
BOOL WINAPI StrTrimA(LPSTR lpszStr, LPCSTR lpszTrim)
{
  DWORD dwLen;
  LPSTR lpszRead = lpszStr;
  BOOL bRet = FALSE;

  TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszTrim));

  if (lpszRead && *lpszRead)
  {
    while (*lpszRead && StrChrA(lpszTrim, *lpszRead))
      lpszRead = CharNextA(lpszRead); /* Skip leading matches */

    dwLen = strlen(lpszRead);

    if (lpszRead != lpszStr)
    {
      memmove(lpszStr, lpszRead, dwLen + 1);
      bRet = TRUE;
    }
    if (dwLen > 0)
    {
      lpszRead = lpszStr + dwLen;
      while (StrChrA(lpszTrim, lpszRead[-1]))
        lpszRead = CharPrevA(lpszStr, lpszRead); /* Skip trailing matches */

      if (lpszRead != lpszStr + dwLen)
      {
        *lpszRead = '\0';
        bRet = TRUE;
      }
    }
  }
  return bRet;
}

/*************************************************************************
 * StrTrimW	[SHLWAPI.@]
 *
 * See StrTrimA.
 */
BOOL WINAPI StrTrimW(LPWSTR lpszStr, LPCWSTR lpszTrim)
{
  DWORD dwLen;
  LPWSTR lpszRead = lpszStr;
  BOOL bRet = FALSE;

  TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszTrim));

  if (lpszRead && *lpszRead)
  {
    while (*lpszRead && StrChrW(lpszTrim, *lpszRead)) lpszRead++;

    dwLen = strlenW(lpszRead);

    if (lpszRead != lpszStr)
    {
      memmove(lpszStr, lpszRead, (dwLen + 1) * sizeof(WCHAR));
      bRet = TRUE;
    }
    if (dwLen > 0)
    {
      lpszRead = lpszStr + dwLen;
      while (StrChrW(lpszTrim, lpszRead[-1]))
        lpszRead--; /* Skip trailing matches */

      if (lpszRead != lpszStr + dwLen)
      {
        *lpszRead = '\0';
        bRet = TRUE;
      }
    }
  }
  return bRet;
}

/*************************************************************************
 *      _SHStrDupAA	[INTERNAL]
 *
 * Duplicates a ASCII string to ASCII. The destination buffer is allocated.
 */
static HRESULT _SHStrDupAA(LPCSTR src, LPSTR * dest)
{
	HRESULT hr;
	int len = 0;

	if (src) {
	    len = lstrlenA(src) + 1;
	    *dest = CoTaskMemAlloc(len);
	} else {
	    *dest = NULL;
	}

	if (*dest) {
	    lstrcpynA(*dest,src, len);
	    hr = S_OK;
	} else {
	    hr = E_OUTOFMEMORY;
	}

	TRACE("%s->(%p)\n", debugstr_a(src), *dest);
	return hr;
}

/*************************************************************************
 * SHStrDupA	[SHLWAPI.@]
 *
 * Return a Unicode copy of a string, in memory allocated by CoTaskMemAlloc().
 *
 * PARAMS
 *  lpszStr   [I] String to copy
 *  lppszDest [O] Destination for the new string copy
 *
 * RETURNS
 *  Success: S_OK. lppszDest contains the new string in Unicode format.
 *  Failure: E_OUTOFMEMORY, If any arguments are invalid or memory allocation
 *           fails.
 */
HRESULT WINAPI SHStrDupA(LPCSTR lpszStr, LPWSTR * lppszDest)
{
  HRESULT hRet;
  int len = 0;

  if (lpszStr)
  {
    len = MultiByteToWideChar(0, 0, lpszStr, -1, 0, 0) * sizeof(WCHAR);
    *lppszDest = CoTaskMemAlloc(len);
  }
  else
    *lppszDest = NULL;

  if (*lppszDest)
  {
    MultiByteToWideChar(0, 0, lpszStr, -1, *lppszDest, len/sizeof(WCHAR));
    hRet = S_OK;
  }
  else
    hRet = E_OUTOFMEMORY;

  TRACE("%s->(%p)\n", debugstr_a(lpszStr), *lppszDest);
  return hRet;
}

/*************************************************************************
 *      _SHStrDupAW	[INTERNAL]
 *
 * Duplicates a UNICODE to a ASCII string. The destination buffer is allocated.
 */
static HRESULT _SHStrDupAW(LPCWSTR src, LPSTR * dest)
{
	HRESULT hr;
	int len = 0;

	if (src) {
	    len = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
	    *dest = CoTaskMemAlloc(len);
	} else {
	    *dest = NULL;
	}

	if (*dest) {
	    WideCharToMultiByte(CP_ACP, 0, src, -1, *dest, len, NULL, NULL);
	    hr = S_OK;
	} else {
	    hr = E_OUTOFMEMORY;
	}

	TRACE("%s->(%p)\n", debugstr_w(src), *dest);
	return hr;
}

/*************************************************************************
 * SHStrDupW	[SHLWAPI.@]
 *
 * See SHStrDupA.
 */
HRESULT WINAPI SHStrDupW(LPCWSTR src, LPWSTR * dest)
{
	HRESULT hr;
	int len = 0;

	if (src) {
	    len = (lstrlenW(src) + 1) * sizeof(WCHAR);
	    *dest = CoTaskMemAlloc(len);
	} else {
	    *dest = NULL;
	}

	if (*dest) {
	    memcpy(*dest, src, len);
	    hr = S_OK;
	} else {
	    hr = E_OUTOFMEMORY;
	}

	TRACE("%s->(%p)\n", debugstr_w(src), *dest);
	return hr;
}

/*************************************************************************
 * SHLWAPI_WriteReverseNum
 *
 * Internal helper for SHLWAPI_WriteTimeClass.
 */
static inline LPWSTR SHLWAPI_WriteReverseNum(LPWSTR lpszOut, DWORD dwNum)
{
  *lpszOut-- = '\0';

  /* Write a decimal number to a string, backwards */
  do
  {
    DWORD dwNextDigit = dwNum % 10;
    *lpszOut-- = '0' + dwNextDigit;
    dwNum = (dwNum - dwNextDigit) / 10;
  } while (dwNum > 0);

  return lpszOut;
}

/*************************************************************************
 * SHLWAPI_FormatSignificant
 *
 * Internal helper for SHLWAPI_WriteTimeClass.
 */
static inline int SHLWAPI_FormatSignificant(LPWSTR lpszNum, int dwDigits)
{
  /* Zero non significant digits, return remaining significant digits */
  while (*lpszNum)
  {
    lpszNum++;
    if (--dwDigits == 0)
    {
      while (*lpszNum)
        *lpszNum++ = '0';
      return 0;
    }
  }
  return dwDigits;
}

/*************************************************************************
 * SHLWAPI_WriteTimeClass
 *
 * Internal helper for StrFromTimeIntervalW.
 */
static int SHLWAPI_WriteTimeClass(LPWSTR lpszOut, DWORD dwValue,
                                  UINT uClassStringId, int iDigits)
{
  WCHAR szBuff[64], *szOut = szBuff + 32;

  szOut = SHLWAPI_WriteReverseNum(szOut, dwValue);
  iDigits = SHLWAPI_FormatSignificant(szOut + 1, iDigits);
  *szOut = ' ';
  LoadStringW(shlwapi_hInstance, uClassStringId, szBuff + 32, 32);
  strcatW(lpszOut, szOut);
  return iDigits;
}

/*************************************************************************
 * StrFromTimeIntervalA	[SHLWAPI.@]
 *
 * Format a millisecond time interval into a string
 *
 * PARAMS
 *  lpszStr  [O] Output buffer for formatted time interval
 *  cchMax   [I] Size of lpszStr
 *  dwMS     [I] Number of milliseconds
 *  iDigits  [I] Number of digits to print
 *
 * RETURNS
 *  The length of the formatted string, or 0 if any parameter is invalid.
 *
 * NOTES
 *  This implementation mimics the Win32 behaviour of always writing a leading
 *  space before the time interval begins.
 *
 *  iDigits is used to provide approximate times if accuracy is not important.
 *  This number of digits will be written of the first non-zero time class
 *  (hours/minutes/seconds). If this does not complete the time classification,
 *  the remaining digits are changed to zeros (i.e. The time is _not_ rounded).
 *  If there are digits remaining following the writing of a time class, the
 *  next time class will be written.
 *
 *  For example, given dwMS represents 138 hours,43 minutes and 15 seconds, the
 *  following will result from the given values of iDigits:
 *
 *|  iDigits    1        2        3        4               5               ...
 *|  lpszStr   "100 hr" "130 hr" "138 hr" "138 hr 40 min" "138 hr 43 min"  ...
 */
INT WINAPI StrFromTimeIntervalA(LPSTR lpszStr, UINT cchMax, DWORD dwMS,
                                int iDigits)
{
  INT iRet = 0;

  TRACE("(%p,%d,%d,%d)\n", lpszStr, cchMax, dwMS, iDigits);

  if (lpszStr && cchMax)
  {
    WCHAR szBuff[128];
    StrFromTimeIntervalW(szBuff, sizeof(szBuff)/sizeof(WCHAR), dwMS, iDigits);
    WideCharToMultiByte(CP_ACP,0,szBuff,-1,lpszStr,cchMax,0,0);
  }
  return iRet;
}


/*************************************************************************
 * StrFromTimeIntervalW	[SHLWAPI.@]
 *
 * See StrFromTimeIntervalA.
 */
INT WINAPI StrFromTimeIntervalW(LPWSTR lpszStr, UINT cchMax, DWORD dwMS,
                                int iDigits)
{
  INT iRet = 0;

  TRACE("(%p,%d,%d,%d)\n", lpszStr, cchMax, dwMS, iDigits);

  if (lpszStr && cchMax)
  {
    WCHAR szCopy[128];
    DWORD dwHours, dwMinutes;

    if (!iDigits || cchMax == 1)
    {
      *lpszStr = '\0';
      return 0;
    }

    /* Calculate the time classes */
    dwMS = (dwMS + 500) / 1000;
    dwHours = dwMS / 3600;
    dwMS -= dwHours * 3600;
    dwMinutes = dwMS / 60;
    dwMS -= dwMinutes * 60;

    szCopy[0] = '\0';

    if (dwHours)
      iDigits = SHLWAPI_WriteTimeClass(szCopy, dwHours, IDS_TIME_INTERVAL_HOURS, iDigits);

    if (dwMinutes && iDigits)
      iDigits = SHLWAPI_WriteTimeClass(szCopy, dwMinutes, IDS_TIME_INTERVAL_MINUTES, iDigits);

    if (iDigits) /* Always write seconds if we have significant digits */
      SHLWAPI_WriteTimeClass(szCopy, dwMS, IDS_TIME_INTERVAL_SECONDS, iDigits);

    lstrcpynW(lpszStr, szCopy, cchMax);
    iRet = strlenW(lpszStr);
  }
  return iRet;
}

/*************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -