Search code examples
delphidelphi-7

Extended ASCII characters displayed as ? (question mark)


I have a form with a bunch of flags (static images) and below each flag is a tick box. The user selects the tick box to allow them to use a particular language. At design-time, I've set the checkbox captions for each language in their localised equivalent, in this example "Español" (Spanish).

Design-time Spanish image and checkbox

For nearly every language this is displayed just fine at runtime, but for a couple of languages this changes to "Espa?ol". Specifically, this happens when I select Lithuanian and use:

// Note: 1063 = ((SUBLANG_DEFAULT shl 10) or LANG_LITHUANIAN)
SetThreadLocale(1063);

Spanish text at runtime (without modification)

Curiously, if I simply re-apply the caption with the following line in the form's OnShow handler, then it displays correctly as "Español".

tbLangSpanish.Caption := 'Español';  // Strange, it now corrects itself!

The above code might be improved slightly by checking to see whether the runtime caption has a "?" character in it and only then re-apply the caption. The rest of the application displays Lithuanian perfectly (with labels being set at runtime).

Note that "ñ" is extended ASCII code 241. This issue affects a couple of other extended characters such as "ç" (character 231) in "Français". Of interest is that some extended ASCII characters are displayed correctly eg. "¾" (character 190).

Is this a bug in the IDE (using Delphi 7) or just a fact-of-life with legacy ASCII (ie. non-UNICODE) characters? Is there a prefered way to detect incompatible design-time extended ASCII characters at runtime (perhaps based on locale)?

None of the searches I performed gave any explanation about why a character would display as "?". I'm assuming this is because the requested character must be missing from the current Windows codepage, but no reference I could find explicitly says what is displayed when this happens (nor how to overcome the problem if you cannot use UNICODE).


Solution

  • The ? character is what happens when a conversion from one code page to another fails because the target code page does not contain the required character. This is an inevitable consequence of programming against the ANSI Win32 API. You simply cannot represent all characters in all languages.

    The only realistic way forward is to use Unicode. You have two main options starting from Delphi 7:

    1. Stick to Delphi 7 and use the TNT Unicode components.
    2. Upgrade to a modern version of Delphi which has native support for Unicode.