Make Single|Double->BSTR conversion use the specified locale for the

decimal point even without the LOCALE_USE_NLS flag. Test supplied.
This commit is contained in:
Alex Villacís Lasso 2005-09-09 15:01:17 +00:00 committed by Alexandre Julliard
parent 840eca52f6
commit 10f0ace4a2
2 changed files with 68 additions and 1 deletions

View File

@ -4596,7 +4596,10 @@ static void test_VarBstrFromR4(void)
{
static const WCHAR szNative[] = { '6','5','4','3','2','2','.','3','\0' };
static const WCHAR szZero[] = {'0', '\0'};
static const WCHAR szOneHalf_English[] = { '0','.','5','\0' }; /* uses period */
static const WCHAR szOneHalf_Spanish[] = { '0',',','5','\0' }; /* uses comma */
LCID lcid;
LCID lcid_spanish;
HRESULT hres;
BSTR bstr = NULL;
@ -4605,6 +4608,7 @@ static void test_VarBstrFromR4(void)
CHECKPTR(VarBstrFromR4);
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
lcid_spanish = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT);
f = 654322.23456f;
hres = pVarBstrFromR4(f, lcid, 0, &bstr);
ok(hres == S_OK, "got hres 0x%08lx\n", hres);
@ -4626,6 +4630,22 @@ static void test_VarBstrFromR4(void)
{
ok(memcmp(bstr, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr));
}
/* The following tests that lcid is used for decimal separator even without LOCALE_USE_NLS */
f = 0.5;
hres = pVarBstrFromR4(f, lcid, 0, &bstr);
ok(hres == S_OK, "got hres 0x%08lx\n", hres);
if (bstr)
{
ok(memcmp(bstr, szOneHalf_English, sizeof(szOneHalf_English)) == 0, "English locale failed (got %s)\n", wtoascii(bstr));
}
f = 0.5;
hres = pVarBstrFromR4(f, lcid_spanish, 0, &bstr);
ok(hres == S_OK, "got hres 0x%08lx\n", hres);
if (bstr)
{
ok(memcmp(bstr, szOneHalf_Spanish, sizeof(szOneHalf_Spanish)) == 0, "Spanish locale failed (got %s)\n", wtoascii(bstr));
}
}
#define BSTR_DATE(dt,str) SysFreeString(bstr); bstr = NULL; \

View File

@ -5442,7 +5442,54 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags,
*pbstrOut = SysAllocString(numbuff);
}
else
*pbstrOut = SysAllocString(buff);
{
WCHAR lpDecimalSep[16];
/* Native oleaut32 uses the locale-specific decimal separator even in the
absence of the LOCALE_USE_NLS flag. For example, the Spanish/Latin
American locales will see "one thousand and one tenth" as "1000,1"
instead of "1000.1" (notice the comma). The following code checks for
the need to replace the decimal separator, and if so, will prepare an
appropriate NUMBERFMTW structure to do the job via GetNumberFormatW().
*/
GetLocaleInfoW(lcid, LOCALE_SDECIMAL, lpDecimalSep, sizeof(lpDecimalSep) / sizeof(WCHAR));
if (lpDecimalSep[0] == '.' && lpDecimalSep[1] == '\0')
{
/* locale is compatible with English - return original string */
*pbstrOut = SysAllocString(buff);
}
else
{
WCHAR *p;
WCHAR numbuff[256];
WCHAR empty[1] = {'\0'};
NUMBERFMTW minFormat;
minFormat.NumDigits = 0;
minFormat.LeadingZero = 0;
minFormat.Grouping = 0;
minFormat.lpDecimalSep = lpDecimalSep;
minFormat.lpThousandSep = empty;
minFormat.NegativeOrder = 1; /* NLS_NEG_LEFT */
/* count number of decimal digits in string */
p = strchrW( buff, '.' );
if (p) minFormat.NumDigits = strlenW(p + 1);
numbuff[0] = '\0';
if (!GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
buff, &minFormat, numbuff, sizeof(numbuff) / sizeof(WCHAR)))
{
WARN("GetNumberFormatW() failed, returning raw number string instead\n");
*pbstrOut = SysAllocString(buff);
}
else
{
TRACE("created minimal NLS string %s\n", debugstr_w(numbuff));
*pbstrOut = SysAllocString(numbuff);
}
}
}
return *pbstrOut ? S_OK : E_OUTOFMEMORY;
}