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

📄 varformat.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
      TRACE("short day\n");
      localeValue = LOCALE_SABBREVDAYNAME1 + udate.st.wMonth - 1;
      defaultChar = '?';
      break;

    case FMT_DATE_DAY_LONG:
      /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
      TRACE("long day\n");
      localeValue = LOCALE_SDAYNAME1 + udate.st.wMonth - 1;
      defaultChar = '?';
      break;

    case FMT_DATE_SHORT:
      /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
      dwFmt = LOCALE_SSHORTDATE;
      break;

    case FMT_DATE_LONG:
      /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
      dwFmt = LOCALE_SLONGDATE;
      break;

    case FMT_DATE_MEDIUM:
      FIXME("Medium date treated as long date\n");
      dwFmt = LOCALE_SLONGDATE;
      break;

    case FMT_DATE_DAY_WEEK:
      szPrintFmt = szPercent_d;
      if (pToken[1])
        dwVal = udate.st.wDayOfWeek + 2 - pToken[1];
      else
      {
        GetLocaleInfoW(lcid,LOCALE_RETURN_NUMBER|LOCALE_IFIRSTDAYOFWEEK,
                       (LPWSTR)&dwVal, sizeof(dwVal)/sizeof(WCHAR));
        dwVal = udate.st.wDayOfWeek + 1 - dwVal;
      }
      pToken++;
      break;

    case FMT_DATE_WEEK_YEAR:
      szPrintFmt = szPercent_d;
      dwVal = udate.wDayOfYear / 7 + 1;
      pToken += 2;
      FIXME("Ignoring nFirstDay of %d, nFirstWeek of %d\n", pToken[0], pToken[1]);
      break;

    case FMT_DATE_MON:
      szPrintFmt = szPercent_d;
      dwVal = udate.st.wMonth;
      break;

    case FMT_DATE_MON_0:
      szPrintFmt = szPercentZeroTwo_d;
      dwVal = udate.st.wMonth;
      break;

    case FMT_DATE_MON_SHORT:
      /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
      TRACE("short month\n");
      localeValue = LOCALE_SABBREVMONTHNAME1 + udate.st.wMonth - 1;
      defaultChar = '?';
      break;

    case FMT_DATE_MON_LONG:
      /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
      TRACE("long month\n");
      localeValue = LOCALE_SMONTHNAME1 + udate.st.wMonth - 1;
      defaultChar = '?';
      break;

    case FMT_DATE_YEAR_DOY:
      szPrintFmt = szPercent_d;
      dwVal = udate.wDayOfYear;
      break;

    case FMT_DATE_YEAR_0:
      szPrintFmt = szPercentZeroTwo_d;
      dwVal = udate.st.wYear % 100;
      break;

    case FMT_DATE_YEAR_LONG:
      szPrintFmt = szPercent_d;
      dwVal = udate.st.wYear;
      break;

    case FMT_DATE_MIN:
      szPrintFmt = szPercent_d;
      dwVal = udate.st.wMinute;
      break;

    case FMT_DATE_MIN_0:
      szPrintFmt = szPercentZeroTwo_d;
      dwVal = udate.st.wMinute;
      break;

    case FMT_DATE_SEC:
      szPrintFmt = szPercent_d;
      dwVal = udate.st.wSecond;
      break;

    case FMT_DATE_SEC_0:
      szPrintFmt = szPercentZeroTwo_d;
      dwVal = udate.st.wSecond;
      break;

    case FMT_DATE_HOUR:
      szPrintFmt = szPercent_d;
      dwVal = udate.st.wHour;
      break;

    case FMT_DATE_HOUR_0:
      szPrintFmt = szPercentZeroTwo_d;
      dwVal = udate.st.wHour;
      break;

    case FMT_DATE_HOUR_12:
      szPrintFmt = szPercent_d;
      dwVal = udate.st.wHour ? udate.st.wHour > 12 ? udate.st.wHour - 12 : udate.st.wHour : 12;
      break;

    case FMT_DATE_HOUR_12_0:
      szPrintFmt = szPercentZeroTwo_d;
      dwVal = udate.st.wHour ? udate.st.wHour > 12 ? udate.st.wHour - 12 : udate.st.wHour : 12;
      break;

    case FMT_DATE_AMPM_SYS1:
    case FMT_DATE_AMPM_SYS2:
      localeValue = udate.st.wHour < 12 ? LOCALE_S1159 : LOCALE_S2359;
      defaultChar = '?';
      break;

    case FMT_DATE_AMPM_UPPER:
      *pBuff++ = udate.st.wHour < 12 ? 'A' : 'P';
      *pBuff++ = 'M';
      break;

    case FMT_DATE_A_UPPER:
      *pBuff++ = udate.st.wHour < 12 ? 'A' : 'P';
      break;

    case FMT_DATE_AMPM_LOWER:
      *pBuff++ = udate.st.wHour < 12 ? 'a' : 'p';
      *pBuff++ = 'm';
      break;

    case FMT_DATE_A_LOWER:
      *pBuff++ = udate.st.wHour < 12 ? 'a' : 'p';
      break;

    default:
      ERR("Unknown token 0x%02x!\n", *pToken);
      hRes = E_INVALIDARG;
      goto VARIANT_FormatDate_Exit;
    }
    if (localeValue)
    {
      *pBuff = '\0';
      if (GetLocaleInfoW(lcid, localeValue, pBuff,
          sizeof(buff)/sizeof(WCHAR)-(pBuff-buff)))
      {
        TRACE("added %s\n", debugstr_w(pBuff));
        while (*pBuff)
          pBuff++;
      }
      else
      {
        TRACE("added %d %c\n", defaultChar, defaultChar);
        *pBuff++ = defaultChar;
      }
    }
    else if (dwFmt)
    {
      WCHAR fmt_buff[80];

      if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, sizeof(fmt_buff)/sizeof(WCHAR)) ||
          !GetDateFormatW(lcid, 0, &udate.st, fmt_buff, pBuff,
                          sizeof(buff)/sizeof(WCHAR)-(pBuff-buff)))
      {
        hRes = E_INVALIDARG;
        goto VARIANT_FormatDate_Exit;
      }
      while (*pBuff)
        pBuff++;
    }
    else if (szPrintFmt)
    {
      sprintfW(pBuff, szPrintFmt, dwVal);
      while (*pBuff)
        pBuff++;
    }
    pToken++;
  }

VARIANT_FormatDate_Exit:
  *pBuff = '\0';
  TRACE("buff is %s\n", debugstr_w(buff));
  if (SUCCEEDED(hRes))
  {
    *pbstrOut = SysAllocString(buff);
    if (!*pbstrOut)
      hRes = E_OUTOFMEMORY;
  }
  return hRes;
}

/* Format a variant using a string format */
static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat,
                                    LPBYTE rgbTok, ULONG dwFlags,
                                    BSTR *pbstrOut, LCID lcid)
{
  static WCHAR szEmpty[] = { '\0' };
  WCHAR buff[256], *pBuff = buff;
  WCHAR *pSrc;
  FMT_HEADER *header = (FMT_HEADER*)rgbTok;
  FMT_STRING_HEADER *strHeader;
  const BYTE* pToken = NULL;
  VARIANT vStr;
  int blanks_first;
  BOOL bUpper = FALSE;
  HRESULT hRes = S_OK;

  TRACE("(%p->(%s%s),%s,%p,0x%08x,%p,0x%08x)\n", pVarIn, debugstr_VT(pVarIn),
        debugstr_VF(pVarIn), debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut,
        lcid);

  V_VT(&vStr) = VT_EMPTY;

  if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL)
  {
    strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header));
    V_BSTR(&vStr) = szEmpty;
  }
  else
  {
    hRes = VariantChangeTypeEx(&vStr, pVarIn, LCID_US, VARIANT_NOUSEROVERRIDE, VT_BSTR);
    if (FAILED(hRes))
      return hRes;

    if (V_BSTR(pVarIn)[0] == '\0')
      strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header));
    else
      strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetPositive(header));
  }
  pSrc = V_BSTR(&vStr);
  if ((strHeader->flags & (FMT_FLAG_LT|FMT_FLAG_GT)) == FMT_FLAG_GT)
    bUpper = TRUE;
  blanks_first = strHeader->copy_chars - strlenW(pSrc);
  pToken = (const BYTE*)strHeader + sizeof(FMT_DATE_HEADER);

  while (*pToken != FMT_GEN_END)
  {
    int dwCount = 0;

    if (pToken - rgbTok > header->size)
    {
      ERR("Ran off the end of the format!\n");
      hRes = E_INVALIDARG;
      goto VARIANT_FormatString_Exit;
    }

    switch (*pToken)
    {
    case FMT_GEN_COPY:
      TRACE("copy %s\n", debugstr_wn(lpszFormat + pToken[1], pToken[2]));
      memcpy(pBuff, lpszFormat + pToken[1], pToken[2] * sizeof(WCHAR));
      pBuff += pToken[2];
      pToken += 2;
      break;

    case FMT_STR_COPY_SPACE:
    case FMT_STR_COPY_SKIP:
      dwCount = pToken[1];
      if (*pToken == FMT_STR_COPY_SPACE && blanks_first > 0)
      {
        TRACE("insert %d initial spaces\n", blanks_first);
        while (dwCount > 0 && blanks_first > 0)
        {
          *pBuff++ = ' ';
          dwCount--;
          blanks_first--;
        }
      }
      TRACE("copy %d chars%s\n", dwCount,
            *pToken == FMT_STR_COPY_SPACE ? " with space" :"");
      while (dwCount > 0 && *pSrc)
      {
        if (bUpper)
          *pBuff++ = toupperW(*pSrc);
        else
          *pBuff++ = tolowerW(*pSrc);
        dwCount--;
        pSrc++;
      }
      if (*pToken == FMT_STR_COPY_SPACE && dwCount > 0)
      {
        TRACE("insert %d spaces\n", dwCount);
        while (dwCount-- > 0)
          *pBuff++ = ' ';
      }
      pToken++;
      break;

    default:
      ERR("Unknown token 0x%02x!\n", *pToken);
      hRes = E_INVALIDARG;
      goto VARIANT_FormatString_Exit;
    }
    pToken++;
  }

VARIANT_FormatString_Exit:
  /* Copy out any remaining chars */
  while (*pSrc)
  {
    if (bUpper)
      *pBuff++ = toupperW(*pSrc);
    else
      *pBuff++ = tolowerW(*pSrc);
    pSrc++;
  }
  VariantClear(&vStr);
  *pBuff = '\0';
  TRACE("buff is %s\n", debugstr_w(buff));
  if (SUCCEEDED(hRes))
  {
    *pbstrOut = SysAllocString(buff);
    if (!*pbstrOut)
      hRes = E_OUTOFMEMORY;
  }
  return hRes;
}

#define NUMBER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2| \
                       VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8| \
                       VTBIT_R4|VTBIT_R8|VTBIT_CY|VTBIT_DECIMAL| \
                       VTBIT_BOOL|VTBIT_INT|VTBIT_UINT)

/**********************************************************************
 *              VarFormatFromTokens [OLEAUT32.139]
 */
HRESULT WINAPI VarFormatFromTokens(LPVARIANT pVarIn, LPOLESTR lpszFormat,
                                   LPBYTE rgbTok, ULONG dwFlags,
                                   BSTR *pbstrOut, LCID lcid)
{
  FMT_SHORT_HEADER *header = (FMT_SHORT_HEADER *)rgbTok;
  VARIANT vTmp;
  HRESULT hres;

  TRACE("(%p,%s,%p,%x,%p,0x%08x)\n", pVarIn, debugstr_w(lpszFormat),
          rgbTok, dwFlags, pbstrOut, lcid);

  if (!pbstrOut)
    return E_INVALIDARG;

  *pbstrOut = NULL;

  if (!pVarIn || !rgbTok)
    return E_INVALIDARG;

  if (V_VT(pVarIn) == VT_NULL)
    return S_OK;

  if (*rgbTok == FMT_TO_STRING || header->type == FMT_TYPE_GENERAL)
  {
    /* According to MSDN, general format acts somewhat like the 'Str'
     * function in Visual Basic.
     */
VarFormatFromTokens_AsStr:
    V_VT(&vTmp) = VT_EMPTY;
    hres = VariantChangeTypeEx(&vTmp, pVarIn, lcid, dwFlags, VT_BSTR);
    *pbstrOut = V_BSTR(&vTmp);
  }
  else
  {
    if (header->type == FMT_TYPE_NUMBER ||
        (header->type == FMT_TYPE_UNKNOWN && ((1 << V_TYPE(pVarIn)) & NUMBER_VTBITS)))
    {
      hres = VARIANT_FormatNumber(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid);
    }
    else if (header->type == FMT_TYPE_DATE ||
             (header->type == FMT_TYPE_UNKNOWN && V_TYPE(pVarIn) == VT_DATE))
    {
      hres = VARIANT_FormatDate(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid);
    }
    else if (header->type == FMT_TYPE_STRING || V_TYPE(pVarIn) == VT_BSTR)
    {
      hres = VARIANT_FormatString(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid);
    }
    else
    {
      ERR("unrecognised format type 0x%02x\n", header->type);
      return E_INVALIDARG;
    }
    /* If the coercion failed, still try to create output, unless the
     * VAR_FORMAT_NOSUBSTITUTE flag is set.
     */
    if ((hres == DISP_E_OVERFLOW || hres == DISP_E_TYPEMISMATCH) &&
        !(dwFlags & VAR_FORMAT_NOSUBSTITUTE))
      goto VarFormatFromTokens_AsStr;
  }

  return hres;
}

/**********************************************************************
 *              VarFormat [OLEAUT32.87]
 *
 * Format a variant fro

⌨️ 快捷键说明

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