Sometimes, GDI respects users (even if no one else does!)

by Michael S. Kaplan, published on 2008/06/16 10:01 -04:00, original URI:

Regular readers know how I am always encouraging, cajoling, and sometimes even threatening developers to respect the user's locale settings choices.

Not everyone is of a mind to do this, however....

Like just the other day when someone was sending me mail about a problem they were having:

We found that the GDI uses the user locale regardless of  the current thread locale for rendering. Data gets formatted using Current thread locale but at last moment the digit replacement happen using the user locale. Is there a strong reason behind this inconsistent behavior or is this a bug in GDI.

Of course formatting behavior, via functions like

is based on the locale you give it, and there is no constant that tells these NLS API functions to "use the thread locale" (though there are ones that will look up the user locale for the caller if requested. :-)

So that text in red above is not really accurate, unless there is some rogue library or program clling GetThreadLocale and pasing the results to one of the non-Ex functions in the list above....

Becsause the truth is that GDI doesn't give a crap about formatting or really anything related to locales, with one signle exception:

Digit Substitution

Any time you go to render text it will grab those digit substitution settings in the user locale (including the user override information) and use the info to decide how to display numbers.

And since there is no way to override those settings at the level where GDI uses them like there is (kind of) for Uniscribe (ref: And the digits just keep on coming).

Well, there is one way....

If you are doing your GDI rendering vie ExtTextOutW, then there are two flags that have been around since Windows 95:

ETO_NUMERICSLATIN Windows 95 and Windows NT 4.0 and later: To display numbers, use European digits.
ETO_NUMERICSLOCAL Windows 95 and Windows NT 4.0 and later: To display numbers, use digits appropriate to the locale.

Basically these are the (very differently named!) equivalents of GetLocaleInfo's LOCALE_IDIGITSUBSTITUTION settings:

1 No substitution is used. This gives full Unicode compatibility.
2 Native digit substitution. National shapes are displayed according to LOCALE_SNATIVEDIGITS.

So you can override the assumption of the GDI code that the user locale preferences are to be respected if yo uwant to, by calling low level functions and pasing one of those two ETO_* flags.

But there is no way to make it easier than that, sorry. And not because the OS respects me and my advice,  but because sometimes the only way the user will get any respect is if we force developers to give it to them.... :-)

This behavior is completely by design.


This blog brought to you by R (U+0052, aka LATIN CAPITAL LETTER R)

# Mike Dimmick on 16 Jun 2008 12:26 PM:

I have to be honest, I find that behaviour a little surprising. I expect GDI to output whatever glyphs map to the codepoints I provided, not map them a further time. But what's done is done, and changing this no doubt would break at least some applications.

I assume that ETO_NUMERICSLATIN doesn't modify the local digits, where they have been used?

# Michael S. Kaplan on 16 Jun 2008 1:00 PM:

Correct -- these flags only modify U+0030 -- U+0039, as needed....

referenced by

2010/11/12 Suddenly, in a bit more time than a blink of an eye, "standards support" becomes "less i18n support"

2008/10/02 When swimming in a sea of CONTEXT, applications can drown (and there is no lifeguard)

go to newer or older post, or back to index or month or day