📄 varformat.c
字号:
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 + -