Easy way to get NUMBERFMT with default settings?

I use the GetNumberFormatEx Windows API to format certain numbers for display with the appropriate localization options for the current user (for example, to make sure they have the correct delimiters in the right places). This is trivial if you want to specify the default user exactly.

But in some cases, I sometimes have to redefine the number of digits after the base delimiter. This requires the creation of a NUMBERFMT structure . I would like to name an API that returns NUMBERFMT, populated with the appropriate default values ​​for the user, and then overrides only those fields that I need to change. But the API does not seem to be suitable for getting default values.

I am currently calling GetLocaleInfoEx again and again, and then translating this data into the NUMBERFMT form.

NUMBERFMT fmt = {0};
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
                  LOCALE_IDIGITS | LOCALE_RETURN_NUMBER,
                  reinterpret_cast<LPWSTR>(&fmt.NumDigits),
                  sizeof(fmt.NumDigits)/sizeof(WCHAR));
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
                  LOCALE_ILZERO | LOCALE_RETURN_NUMBER,
                  reinterpret_cast<LPWSTR>(&fmt.LeadingZero),
                  sizeof(fmt.LeadingZero)/sizeof(WCHAR));
WCHAR szGrouping[32] = L"";
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SGROUPING, szGrouping,
                  ARRAYSIZE(szGrouping));
if (::lstrcmp(szGrouping, L"3;0") == 0 ||
    ::lstrcmp(szGrouping, L"3") == 0
) {
    fmt.Grouping = 3;
} else if (::lstrcmp(szGrouping, L"3;2;0") == 0) {
    fmt.Grouping = 32;
} else {
    assert(false);  // unexpected grouping string
}
WCHAR szDecimal[16] = L"";
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SDECIMAL, szDecimal,
                  ARRAYSIZE(szDecimal));
fmt.lpDecimalSep = szDecimal;
WCHAR szThousand[16] = L"";
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_STHOUSAND, szThousand,
                  ARRAYSIZE(szThousand));
fmt.lpThousandSep = szThousand;
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
                  LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER,
                  reinterpret_cast<LPWSTR>(&fmt.NegativeOrder),
                  sizeof(fmt.NegativeOrder)/sizeof(WCHAR));

Isn't there an API that already does this?

+3
source share
2 answers

, . , , GetDefaultNumberFormat (LCID lcid, NUMBERFMT * fmt); , . , , ; "3" ( 30) , , ( , , , ).

+2

, , , (, LOCALE_NAME_USER_DEFAULT), ( , ) , , :

#define cut_off_decimals(sz, cch) \
    if (cch >= 5 && (sz[cch-4] == _T('.') || sz[cch-4] == _T(','))) \
        sz[cch-4] = _T('\0');

( : sz - C, cch - , . _T - Windows char wchar_t , UNICODE Windows 9x/ME.)

, , "-" , , . , , .

, , , - , .

0

Source: https://habr.com/ru/post/1531179/


All Articles