mirror of
https://github.com/reactos/reactos.git
synced 2025-07-29 16:31:44 +00:00
[KERNEL32] make some NLS and Format functions work. Wine-sync with latest version
This commit is contained in:
parent
ca24df9c85
commit
655d24d9eb
8 changed files with 504 additions and 54 deletions
|
@ -56,7 +56,7 @@ static const WCHAR szLangGroupsKeyName[] = {
|
|||
'L','a','n','g','u','a','g','e',' ','G','r','o','u','p','s',0
|
||||
};
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#if (WINVER >= 0x0600)
|
||||
/* Charset to codepage map, sorted by name. */
|
||||
static const struct charset_entry
|
||||
{
|
||||
|
@ -262,6 +262,248 @@ static inline UINT get_lcid_codepage( LCID lcid )
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if (WINVER >= 0x0600)
|
||||
/***********************************************************************
|
||||
* charset_cmp (internal)
|
||||
*/
|
||||
static int charset_cmp( const void *name, const void *entry )
|
||||
{
|
||||
const struct charset_entry *charset = entry;
|
||||
return strcasecmp( name, charset->charset_name );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* find_charset
|
||||
*/
|
||||
static UINT find_charset( const WCHAR *name )
|
||||
{
|
||||
const struct charset_entry *entry;
|
||||
char charset_name[16];
|
||||
size_t i, j;
|
||||
|
||||
/* remove punctuation characters from charset name */
|
||||
for (i = j = 0; name[i] && j < sizeof(charset_name)-1; i++)
|
||||
if (isalnum((unsigned char)name[i])) charset_name[j++] = name[i];
|
||||
charset_name[j] = 0;
|
||||
|
||||
entry = bsearch( charset_name, charset_names, ARRAY_SIZE( charset_names ),
|
||||
sizeof(charset_names[0]), charset_cmp );
|
||||
if (entry) return entry->codepage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LANGID get_default_sublang( LANGID lang )
|
||||
{
|
||||
switch (lang)
|
||||
{
|
||||
case MAKELANGID( LANG_SPANISH, SUBLANG_NEUTRAL ):
|
||||
return MAKELANGID( LANG_SPANISH, SUBLANG_SPANISH_MODERN );
|
||||
case MAKELANGID( LANG_CHINESE, SUBLANG_NEUTRAL ):
|
||||
return MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED );
|
||||
case MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SINGAPORE ):
|
||||
return MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED );
|
||||
case MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL ):
|
||||
case MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_MACAU ):
|
||||
return MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_HONGKONG );
|
||||
}
|
||||
if (SUBLANGID( lang ) == SUBLANG_NEUTRAL) lang = MAKELANGID( PRIMARYLANGID(lang), SUBLANG_DEFAULT );
|
||||
return lang;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* find_locale_id_callback
|
||||
*/
|
||||
static BOOL CALLBACK find_locale_id_callback( HMODULE hModule, LPCWSTR type,
|
||||
LPCWSTR name, LANGID lang, LPARAM lParam )
|
||||
{
|
||||
struct locale_name *data = (struct locale_name *)lParam;
|
||||
WCHAR buffer[128];
|
||||
int matches = 0;
|
||||
LCID lcid = MAKELCID( lang, SORT_DEFAULT ); /* FIXME: handle sort order */
|
||||
|
||||
if (PRIMARYLANGID(lang) == LANG_NEUTRAL) return TRUE; /* continue search */
|
||||
|
||||
/* first check exact name */
|
||||
if (data->win_name[0] &&
|
||||
GetLocaleInfoW( lcid, LOCALE_SNAME | LOCALE_NOUSEROVERRIDE, buffer, ARRAY_SIZE( buffer )))
|
||||
{
|
||||
if (!strcmpiW( data->win_name, buffer ))
|
||||
{
|
||||
matches = 4; /* everything matches */
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetLocaleInfoW( lcid, LOCALE_SISO639LANGNAME | LOCALE_NOUSEROVERRIDE,
|
||||
buffer, ARRAY_SIZE( buffer )))
|
||||
return TRUE;
|
||||
if (strcmpiW( buffer, data->lang )) return TRUE;
|
||||
matches++; /* language name matched */
|
||||
|
||||
if (data->script)
|
||||
{
|
||||
if (GetLocaleInfoW( lcid, LOCALE_SSCRIPTS | LOCALE_NOUSEROVERRIDE,
|
||||
buffer, ARRAY_SIZE( buffer )))
|
||||
{
|
||||
const WCHAR *p = buffer;
|
||||
unsigned int len = strlenW( data->script );
|
||||
while (*p)
|
||||
{
|
||||
if (!strncmpiW( p, data->script, len ) && (!p[len] || p[len] == ';')) break;
|
||||
if (!(p = strchrW( p, ';'))) goto done;
|
||||
p++;
|
||||
}
|
||||
if (!*p) goto done;
|
||||
matches++; /* script matched */
|
||||
}
|
||||
}
|
||||
|
||||
if (data->country)
|
||||
{
|
||||
if (GetLocaleInfoW( lcid, LOCALE_SISO3166CTRYNAME|LOCALE_NOUSEROVERRIDE,
|
||||
buffer, ARRAY_SIZE( buffer )))
|
||||
{
|
||||
if (strcmpiW( buffer, data->country )) goto done;
|
||||
matches++; /* country name matched */
|
||||
}
|
||||
}
|
||||
else /* match default language */
|
||||
{
|
||||
LANGID def_lang = data->script ? lang : MAKELANGID( PRIMARYLANGID(lang), LANG_NEUTRAL );
|
||||
if (lang == get_default_sublang( def_lang )) matches++;
|
||||
}
|
||||
|
||||
if (data->codepage)
|
||||
{
|
||||
UINT unix_cp;
|
||||
if (GetLocaleInfoW( lcid, LOCALE_IDEFAULTUNIXCODEPAGE | LOCALE_RETURN_NUMBER,
|
||||
(LPWSTR)&unix_cp, sizeof(unix_cp)/sizeof(WCHAR) ))
|
||||
{
|
||||
if (unix_cp == data->codepage) matches++;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: check sort order */
|
||||
|
||||
done:
|
||||
if (matches > data->matches)
|
||||
{
|
||||
data->lcid = lcid;
|
||||
data->matches = matches;
|
||||
}
|
||||
return (data->matches < 4); /* no need to continue for perfect match */
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* parse_locale_name
|
||||
*
|
||||
* Parse a locale name into a struct locale_name, handling both Windows and Unix formats.
|
||||
* Unix format is: lang[_country][.charset][@modifier]
|
||||
* Windows format is: lang[-script][-country][_modifier]
|
||||
*/
|
||||
static void parse_locale_name( const WCHAR *str, struct locale_name *name )
|
||||
{
|
||||
static const WCHAR sepW[] = {'-','_','.','@',0};
|
||||
static const WCHAR winsepW[] = {'-','_',0};
|
||||
static const WCHAR posixW[] = {'P','O','S','I','X',0};
|
||||
static const WCHAR cW[] = {'C',0};
|
||||
static const WCHAR latinW[] = {'l','a','t','i','n',0};
|
||||
static const WCHAR latnW[] = {'-','L','a','t','n',0};
|
||||
WCHAR *p;
|
||||
|
||||
TRACE("%s\n", debugstr_w(str));
|
||||
|
||||
name->country = name->charset = name->script = name->modifier = NULL;
|
||||
name->lcid = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT );
|
||||
name->matches = 0;
|
||||
name->codepage = 0;
|
||||
name->win_name[0] = 0;
|
||||
lstrcpynW( name->lang, str, ARRAY_SIZE( name->lang ));
|
||||
|
||||
if (!*name->lang)
|
||||
{
|
||||
name->lcid = LOCALE_INVARIANT;
|
||||
name->matches = 4;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(p = strpbrkW( name->lang, sepW )))
|
||||
{
|
||||
if (!strcmpW( name->lang, posixW ) || !strcmpW( name->lang, cW ))
|
||||
{
|
||||
name->matches = 4; /* perfect match for default English lcid */
|
||||
return;
|
||||
}
|
||||
strcpyW( name->win_name, name->lang );
|
||||
}
|
||||
else if (*p == '-') /* Windows format */
|
||||
{
|
||||
strcpyW( name->win_name, name->lang );
|
||||
*p++ = 0;
|
||||
name->country = p;
|
||||
if ((p = strpbrkW( p, winsepW )) && *p == '-')
|
||||
{
|
||||
*p++ = 0;
|
||||
name->script = name->country;
|
||||
name->country = p;
|
||||
p = strpbrkW( p, winsepW );
|
||||
}
|
||||
if (p)
|
||||
{
|
||||
*p++ = 0;
|
||||
name->modifier = p;
|
||||
}
|
||||
/* second value can be script or country, check length to resolve the ambiguity */
|
||||
if (!name->script && strlenW( name->country ) == 4)
|
||||
{
|
||||
name->script = name->country;
|
||||
name->country = NULL;
|
||||
}
|
||||
}
|
||||
else /* Unix format */
|
||||
{
|
||||
if (*p == '_')
|
||||
{
|
||||
*p++ = 0;
|
||||
name->country = p;
|
||||
p = strpbrkW( p, sepW + 2 );
|
||||
}
|
||||
if (p && *p == '.')
|
||||
{
|
||||
*p++ = 0;
|
||||
name->charset = p;
|
||||
p = strchrW( p, '@' );
|
||||
}
|
||||
if (p)
|
||||
{
|
||||
*p++ = 0;
|
||||
name->modifier = p;
|
||||
}
|
||||
|
||||
if (name->charset)
|
||||
name->codepage = find_charset( name->charset );
|
||||
|
||||
/* rebuild a Windows name if possible */
|
||||
|
||||
if (name->charset) goto done; /* can't specify charset in Windows format */
|
||||
if (name->modifier && strcmpW( name->modifier, latinW ))
|
||||
goto done; /* only Latn script supported for now */
|
||||
strcpyW( name->win_name, name->lang );
|
||||
if (name->modifier) strcatW( name->win_name, latnW );
|
||||
if (name->country)
|
||||
{
|
||||
p = name->win_name + strlenW(name->win_name);
|
||||
*p++ = '-';
|
||||
strcpyW( p, name->country );
|
||||
}
|
||||
}
|
||||
done:
|
||||
EnumResourceLanguagesW( kernel32_handle, (LPCWSTR)RT_STRING, (LPCWSTR)LOCALE_ILANGUAGE,
|
||||
find_locale_id_callback, (LPARAM)name );
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* convert_default_lcid
|
||||
*
|
||||
|
@ -585,6 +827,52 @@ LANGID WINAPI GetSystemDefaultUILanguage(void)
|
|||
return lang;
|
||||
}
|
||||
|
||||
#if (WINVER >= 0x0600)
|
||||
/***********************************************************************
|
||||
* LocaleNameToLCID (KERNEL32.@)
|
||||
*/
|
||||
LCID WINAPI LocaleNameToLCID( LPCWSTR name, DWORD flags )
|
||||
{
|
||||
struct locale_name locale_name;
|
||||
static int once;
|
||||
|
||||
if (flags && !once++)
|
||||
FIXME( "unsupported flags %x\n", flags );
|
||||
|
||||
if (name == LOCALE_NAME_USER_DEFAULT)
|
||||
return GetUserDefaultLCID();
|
||||
|
||||
/* string parsing */
|
||||
parse_locale_name( name, &locale_name );
|
||||
|
||||
TRACE( "found lcid %x for %s, matches %d\n",
|
||||
locale_name.lcid, debugstr_w(name), locale_name.matches );
|
||||
|
||||
if (!locale_name.matches)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (locale_name.matches == 1)
|
||||
WARN( "locale %s not recognized, defaulting to %s\n",
|
||||
debugstr_w(name), debugstr_w(locale_name.lang) );
|
||||
|
||||
return locale_name.lcid;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* LCIDToLocaleName (KERNEL32.@)
|
||||
*/
|
||||
INT WINAPI LCIDToLocaleName( LCID lcid, LPWSTR name, INT count, DWORD flags )
|
||||
{
|
||||
static int once;
|
||||
if (flags && !once++) FIXME( "unsupported flags %x\n", flags );
|
||||
|
||||
return GetLocaleInfoW( lcid, LOCALE_SNAME | LOCALE_NOUSEROVERRIDE, name, count );
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* get_registry_locale_info
|
||||
|
@ -965,6 +1253,41 @@ INT WINAPI GetLocaleInfoW( LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len )
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if (WINVER >= 0x0600)
|
||||
WINBASEAPI
|
||||
int
|
||||
WINAPI
|
||||
GetLocaleInfoEx(
|
||||
_In_opt_ LPCWSTR lpLocaleName,
|
||||
_In_ LCTYPE LCType,
|
||||
_Out_writes_opt_(cchData) LPWSTR lpLCData,
|
||||
_In_ int cchData)
|
||||
{
|
||||
TRACE( "GetLocaleInfoEx not implemented (lcid=%s,lctype=0x%x,%s,%d)\n", debugstr_w(lpLocaleName), LCType, debugstr_w(lpLCData), cchData );
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
IsValidLocaleName(
|
||||
LPCWSTR lpLocaleName
|
||||
)
|
||||
{
|
||||
TRACE( "IsValidLocaleName not implemented (lpLocaleName=%s)\n", debugstr_w(lpLocaleName));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
GetUserDefaultLocaleName(
|
||||
LPWSTR lpLocaleName,
|
||||
INT cchLocaleName
|
||||
)
|
||||
{
|
||||
TRACE( "GetUserDefaultLocaleName not implemented (lpLocaleName=%s, cchLocaleName=%d)\n", debugstr_w(lpLocaleName), cchLocaleName);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* SetLocaleInfoA [KERNEL32.@]
|
||||
|
@ -1284,6 +1607,56 @@ BOOL WINAPI EnumSystemLocalesW( LOCALE_ENUMPROCW lpfnLocaleEnum, DWORD dwFlags )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
struct enum_locale_ex_data
|
||||
{
|
||||
LOCALE_ENUMPROCEX proc;
|
||||
DWORD flags;
|
||||
LPARAM lparam;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK enum_locale_ex_proc( HMODULE module, LPCWSTR type,
|
||||
LPCWSTR name, WORD lang, LONG_PTR lparam )
|
||||
{
|
||||
struct enum_locale_ex_data *data = (struct enum_locale_ex_data *)lparam;
|
||||
WCHAR buffer[256];
|
||||
DWORD neutral;
|
||||
unsigned int flags;
|
||||
|
||||
GetLocaleInfoW( MAKELCID( lang, SORT_DEFAULT ), LOCALE_SNAME | LOCALE_NOUSEROVERRIDE,
|
||||
buffer, ARRAY_SIZE( buffer ));
|
||||
if (!GetLocaleInfoW( MAKELCID( lang, SORT_DEFAULT ),
|
||||
LOCALE_INEUTRAL | LOCALE_NOUSEROVERRIDE | LOCALE_RETURN_NUMBER,
|
||||
(LPWSTR)&neutral, sizeof(neutral) / sizeof(WCHAR) ))
|
||||
neutral = 0;
|
||||
flags = LOCALE_WINDOWS;
|
||||
flags |= neutral ? LOCALE_NEUTRALDATA : LOCALE_SPECIFICDATA;
|
||||
if (data->flags && !(data->flags & flags)) return TRUE;
|
||||
return data->proc( buffer, flags, data->lparam );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* EnumSystemLocalesEx (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI EnumSystemLocalesEx( LOCALE_ENUMPROCEX proc, DWORD flags, LPARAM lparam, LPVOID reserved )
|
||||
{
|
||||
struct enum_locale_ex_data data;
|
||||
|
||||
if (reserved)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
data.proc = proc;
|
||||
data.flags = flags;
|
||||
data.lparam = lparam;
|
||||
EnumResourceLanguagesW( kernel32_handle, (LPCWSTR)RT_STRING,
|
||||
(LPCWSTR)MAKEINTRESOURCE((LOCALE_SNAME >> 4) + 1),
|
||||
enum_locale_ex_proc, (LONG_PTR)&data );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* VerLanguageNameA (KERNEL32.@)
|
||||
*
|
||||
|
|
|
@ -124,7 +124,7 @@ static DWORD NLS_GetLocaleNumber(LCID lcid, DWORD dwFlags)
|
|||
DWORD dwVal = 0;
|
||||
|
||||
szBuff[0] = '\0';
|
||||
GetLocaleInfoW(lcid, dwFlags, szBuff, sizeof(szBuff) / sizeof(WCHAR));
|
||||
GetLocaleInfoW(lcid, dwFlags, szBuff, ARRAY_SIZE(szBuff));
|
||||
|
||||
if (szBuff[0] && szBuff[1] == ';' && szBuff[2] != '0')
|
||||
dwVal = (szBuff[0] - '0') * 10 + (szBuff[2] - '0');
|
||||
|
@ -149,7 +149,7 @@ static WCHAR* NLS_GetLocaleString(LCID lcid, DWORD dwFlags)
|
|||
DWORD dwLen;
|
||||
|
||||
szBuff[0] = '\0';
|
||||
GetLocaleInfoW(lcid, dwFlags, szBuff, sizeof(szBuff) / sizeof(WCHAR));
|
||||
GetLocaleInfoW(lcid, dwFlags, szBuff, ARRAY_SIZE(szBuff));
|
||||
dwLen = strlenW(szBuff) + 1;
|
||||
str = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
|
||||
if (str)
|
||||
|
@ -278,7 +278,7 @@ static const NLS_FORMAT_NODE *NLS_GetFormats(LCID lcid, DWORD dwFlags)
|
|||
GET_LOCALE_STRING(new_node->cyfmt.lpCurrencySymbol, LOCALE_SCURRENCY);
|
||||
|
||||
/* Date/Time Format info, negative character, etc */
|
||||
for (i = 0; i < sizeof(NLS_LocaleIndices)/sizeof(NLS_LocaleIndices[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(NLS_LocaleIndices); i++)
|
||||
{
|
||||
GET_LOCALE_STRING(new_node->lppszStrings[i], NLS_LocaleIndices[i]);
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ static const NLS_FORMAT_NODE *NLS_GetFormats(LCID lcid, DWORD dwFlags)
|
|||
/* We raced and lost: The node was already added by another thread.
|
||||
* node points to the currently cached node, so free new_node.
|
||||
*/
|
||||
for (i = 0; i < sizeof(NLS_LocaleIndices)/sizeof(NLS_LocaleIndices[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(NLS_LocaleIndices); i++)
|
||||
HeapFree(GetProcessHeap(), 0, new_node->lppszStrings[i]);
|
||||
HeapFree(GetProcessHeap(), 0, new_node->fmt.lpDecimalSep);
|
||||
HeapFree(GetProcessHeap(), 0, new_node->fmt.lpThousandSep);
|
||||
|
@ -697,7 +697,7 @@ static INT NLS_GetDateTimeFormatW(LCID lcid, DWORD dwFlags,
|
|||
{
|
||||
static const WCHAR fmtW[] = {'%','.','*','d',0};
|
||||
/* We have a numeric value to add */
|
||||
snprintfW(buff, sizeof(buff)/sizeof(WCHAR), fmtW, count, dwVal);
|
||||
snprintfW(buff, ARRAY_SIZE(buff), fmtW, count, dwVal);
|
||||
}
|
||||
|
||||
dwLen = szAdd ? strlenW(szAdd) : 0;
|
||||
|
@ -793,10 +793,10 @@ static INT NLS_GetDateTimeFormatA(LCID lcid, DWORD dwFlags,
|
|||
}
|
||||
|
||||
if (lpFormat)
|
||||
MultiByteToWideChar(cp, 0, lpFormat, -1, szFormat, sizeof(szFormat)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(cp, 0, lpFormat, -1, szFormat, ARRAY_SIZE(szFormat));
|
||||
|
||||
if (cchOut > (int)(sizeof(szOut)/sizeof(WCHAR)))
|
||||
cchOut = sizeof(szOut)/sizeof(WCHAR);
|
||||
if (cchOut > (int) ARRAY_SIZE(szOut))
|
||||
cchOut = ARRAY_SIZE(szOut);
|
||||
|
||||
szOut[0] = '\0';
|
||||
|
||||
|
@ -866,7 +866,7 @@ INT WINAPI GetDateFormatA( LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
|
|||
lpFormat, lpDateStr, cchOut);
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
/******************************************************************************
|
||||
* GetDateFormatEx [KERNEL32.@]
|
||||
*
|
||||
|
@ -906,7 +906,7 @@ INT WINAPI GetDateFormatEx(LPCWSTR localename, DWORD flags,
|
|||
flags | DATE_DATEVARSONLY, date, format,
|
||||
outbuf, bufsize);
|
||||
}
|
||||
#endif /* !__REACTOS__ */
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
/******************************************************************************
|
||||
* GetDateFormatW [KERNEL32.@]
|
||||
|
@ -974,7 +974,7 @@ INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
|
|||
lpFormat, lpTimeStr, cchOut);
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
/******************************************************************************
|
||||
* GetTimeFormatEx [KERNEL32.@]
|
||||
*
|
||||
|
@ -1006,7 +1006,7 @@ INT WINAPI GetTimeFormatEx(LPCWSTR localename, DWORD flags,
|
|||
flags | TIME_TIMEVARSONLY, time, format,
|
||||
outbuf, bufsize);
|
||||
}
|
||||
#endif /* !__REACTOS__ */
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
/******************************************************************************
|
||||
* GetTimeFormatW [KERNEL32.@]
|
||||
|
@ -1087,21 +1087,21 @@ INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags,
|
|||
pfmt = &fmt;
|
||||
if (lpFormat->lpDecimalSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, sizeof(szDec)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
|
||||
fmt.lpDecimalSep = szDec;
|
||||
}
|
||||
if (lpFormat->lpThousandSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, sizeof(szGrp)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
|
||||
fmt.lpThousandSep = szGrp;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpszValue)
|
||||
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, sizeof(szIn)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
|
||||
|
||||
if (cchOut > (int)(sizeof(szOut)/sizeof(WCHAR)))
|
||||
cchOut = sizeof(szOut)/sizeof(WCHAR);
|
||||
if (cchOut > (int) ARRAY_SIZE(szOut))
|
||||
cchOut = ARRAY_SIZE(szOut);
|
||||
|
||||
szOut[0] = '\0';
|
||||
|
||||
|
@ -1136,7 +1136,7 @@ INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags,
|
|||
LPCWSTR lpszValue, const NUMBERFMTW *lpFormat,
|
||||
LPWSTR lpNumberStr, int cchOut)
|
||||
{
|
||||
WCHAR szBuff[128], *szOut = szBuff + sizeof(szBuff) / sizeof(WCHAR) - 1;
|
||||
WCHAR szBuff[128], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
|
||||
WCHAR szNegBuff[8];
|
||||
const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc;
|
||||
DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0;
|
||||
|
@ -1164,7 +1164,7 @@ INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags,
|
|||
else
|
||||
{
|
||||
GetLocaleInfoW(lcid, LOCALE_SNEGATIVESIGN|(dwFlags & LOCALE_NOUSEROVERRIDE),
|
||||
szNegBuff, sizeof(szNegBuff)/sizeof(WCHAR));
|
||||
szNegBuff, ARRAY_SIZE(szNegBuff));
|
||||
lpszNegStart = lpszNeg = szNegBuff;
|
||||
}
|
||||
lpszNeg = lpszNeg + strlenW(lpszNeg) - 1;
|
||||
|
@ -1368,7 +1368,7 @@ error:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
/**************************************************************************
|
||||
* GetNumberFormatEx (KERNEL32.@)
|
||||
*/
|
||||
|
@ -1387,7 +1387,7 @@ INT WINAPI GetNumberFormatEx(LPCWSTR name, DWORD flags,
|
|||
|
||||
return GetNumberFormatW(lcid, flags, value, format, number, numout);
|
||||
}
|
||||
#endif /* !__REACTOS__ */
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
/**************************************************************************
|
||||
* GetCurrencyFormatA (KERNEL32.@)
|
||||
|
@ -1453,26 +1453,26 @@ INT WINAPI GetCurrencyFormatA(LCID lcid, DWORD dwFlags,
|
|||
pfmt = &fmt;
|
||||
if (lpFormat->lpDecimalSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, sizeof(szDec)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
|
||||
fmt.lpDecimalSep = szDec;
|
||||
}
|
||||
if (lpFormat->lpThousandSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, sizeof(szGrp)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
|
||||
fmt.lpThousandSep = szGrp;
|
||||
}
|
||||
if (lpFormat->lpCurrencySymbol)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpCurrencySymbol, -1, szCy, sizeof(szCy)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpCurrencySymbol, -1, szCy, ARRAY_SIZE(szCy));
|
||||
fmt.lpCurrencySymbol = szCy;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpszValue)
|
||||
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, sizeof(szIn)/sizeof(WCHAR));
|
||||
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
|
||||
|
||||
if (cchOut > (int)(sizeof(szOut)/sizeof(WCHAR)))
|
||||
cchOut = sizeof(szOut)/sizeof(WCHAR);
|
||||
if (cchOut > (int) ARRAY_SIZE(szOut))
|
||||
cchOut = ARRAY_SIZE(szOut);
|
||||
|
||||
szOut[0] = '\0';
|
||||
|
||||
|
@ -1528,7 +1528,7 @@ INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags,
|
|||
CF_CY_LEFT|CF_CY_SPACE, /* $ 1.1 */
|
||||
CF_CY_RIGHT|CF_CY_SPACE, /* 1.1 $ */
|
||||
};
|
||||
WCHAR szBuff[128], *szOut = szBuff + sizeof(szBuff) / sizeof(WCHAR) - 1;
|
||||
WCHAR szBuff[128], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
|
||||
WCHAR szNegBuff[8];
|
||||
const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc, *lpszCy, *lpszCyStart;
|
||||
DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0, dwFmt;
|
||||
|
@ -1559,7 +1559,7 @@ INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags,
|
|||
else
|
||||
{
|
||||
GetLocaleInfoW(lcid, LOCALE_SNEGATIVESIGN|(dwFlags & LOCALE_NOUSEROVERRIDE),
|
||||
szNegBuff, sizeof(szNegBuff)/sizeof(WCHAR));
|
||||
szNegBuff, ARRAY_SIZE(szNegBuff));
|
||||
lpszNegStart = lpszNeg = szNegBuff;
|
||||
}
|
||||
dwFlags &= (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP);
|
||||
|
@ -1782,6 +1782,21 @@ error:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
/***********************************************************************
|
||||
* GetCurrencyFormatEx (KERNEL32.@)
|
||||
*/
|
||||
int WINAPI GetCurrencyFormatEx(LPCWSTR localename, DWORD flags, LPCWSTR value,
|
||||
const CURRENCYFMTW *format, LPWSTR str, int len)
|
||||
{
|
||||
TRACE("(%s,0x%08x,%s,%p,%p,%d)\n", debugstr_w(localename), flags,
|
||||
debugstr_w(value), format, str, len);
|
||||
|
||||
return GetCurrencyFormatW( LocaleNameToLCID(localename, 0), flags, value, format, str, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* FIXME: Everything below here needs to move somewhere else along with the
|
||||
* other EnumXXX functions, when a method for storing resources for
|
||||
* alternate calendars is determined.
|
||||
|
@ -1854,9 +1869,9 @@ static BOOL NLS_EnumDateFormats(const struct enumdateformats_context *ctxt)
|
|||
|
||||
lctype |= ctxt->flags & LOCALE_USE_CP_ACP;
|
||||
if (ctxt->unicode)
|
||||
ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, sizeof(bufW)/sizeof(bufW[0]));
|
||||
ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, ARRAY_SIZE(bufW));
|
||||
else
|
||||
ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, sizeof(bufA)/sizeof(bufA[0]));
|
||||
ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, ARRAY_SIZE(bufA));
|
||||
|
||||
if (ret)
|
||||
{
|
||||
|
@ -1949,7 +1964,7 @@ BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags)
|
|||
return NLS_EnumDateFormats(&ctxt);
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
/**************************************************************************
|
||||
* EnumDateFormatsExEx (KERNEL32.@)
|
||||
*/
|
||||
|
@ -1966,7 +1981,7 @@ BOOL WINAPI EnumDateFormatsExEx(DATEFMT_ENUMPROCEXEX proc, const WCHAR *locale,
|
|||
|
||||
return NLS_EnumDateFormats(&ctxt);
|
||||
}
|
||||
#endif /* !__REACTOS__ */
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
struct enumtimeformats_context {
|
||||
enum enum_callback_type type; /* callback kind */
|
||||
|
@ -2009,9 +2024,9 @@ static BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt)
|
|||
|
||||
lctype |= ctxt->flags & LOCALE_USE_CP_ACP;
|
||||
if (ctxt->unicode)
|
||||
ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, sizeof(bufW)/sizeof(bufW[0]));
|
||||
ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, ARRAY_SIZE(bufW));
|
||||
else
|
||||
ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, sizeof(bufA)/sizeof(bufA[0]));
|
||||
ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, ARRAY_SIZE(bufA));
|
||||
|
||||
if (ret)
|
||||
{
|
||||
|
@ -2073,7 +2088,7 @@ BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags)
|
|||
return NLS_EnumTimeFormats(&ctxt);
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
/**************************************************************************
|
||||
* EnumTimeFormatsEx (KERNEL32.@)
|
||||
*/
|
||||
|
@ -2090,7 +2105,7 @@ BOOL WINAPI EnumTimeFormatsEx(TIMEFMT_ENUMPROCEX proc, const WCHAR *locale, DWOR
|
|||
|
||||
return NLS_EnumTimeFormats(&ctxt);
|
||||
}
|
||||
#endif /* !__REACTOS__ */
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
struct enumcalendar_context {
|
||||
enum enum_callback_type type; /* callback kind */
|
||||
|
@ -2321,7 +2336,7 @@ BOOL WINAPI EnumCalendarInfoExW( CALINFO_ENUMPROCEXW calinfoproc,LCID locale,
|
|||
return NLS_EnumCalendarInfo(&ctxt);
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
/******************************************************************************
|
||||
* EnumCalendarInfoExEx [KERNEL32.@]
|
||||
*/
|
||||
|
@ -2341,7 +2356,7 @@ BOOL WINAPI EnumCalendarInfoExEx( CALINFO_ENUMPROCEXEX calinfoproc, LPCWSTR loca
|
|||
ctxt.unicode = TRUE;
|
||||
return NLS_EnumCalendarInfo(&ctxt);
|
||||
}
|
||||
#endif /* !__REACTOS__ */
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
/*********************************************************************
|
||||
* GetCalendarInfoA (KERNEL32.@)
|
||||
|
@ -2567,6 +2582,23 @@ int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
/*********************************************************************
|
||||
* GetCalendarInfoEx (KERNEL32.@)
|
||||
*/
|
||||
int WINAPI GetCalendarInfoEx(LPCWSTR locale, CALID calendar, LPCWSTR lpReserved, CALTYPE caltype,
|
||||
LPWSTR data, int len, DWORD *value)
|
||||
{
|
||||
static int once;
|
||||
|
||||
LCID lcid = LocaleNameToLCID(locale, 0);
|
||||
if (!once++)
|
||||
FIXME("(%s, %d, %p, 0x%08x, %p, %d, %p): semi-stub\n", debugstr_w(locale), calendar, lpReserved, caltype,
|
||||
data, len, value);
|
||||
return GetCalendarInfoW(lcid, calendar, caltype, data, len, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* SetCalendarInfoA (KERNEL32.@)
|
||||
*
|
||||
|
|
|
@ -2261,4 +2261,17 @@ GetNLSVersion(IN NLS_FUNCTION Function,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetNLSVersionEx(IN NLS_FUNCTION function,
|
||||
IN LPCWSTR lpLocaleName,
|
||||
IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
|
||||
{
|
||||
STUB;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue