2009-11-20 2 views
16

Чтобы получить настройки локали, например. короткий формат даты, мы всегда использовали GetLocaleFormatSettings с GetThreadLocale. До сих пор это всегда работало без проблем.GetThreadLocale возвращает другое значение, чем GetUserDefaultLCID?

Несколько наших пользователей получают разные значения для GetThreadLocale, которые не соответствуют тем, что они настроили в региональных настройках в Windows 7. Мы не смогли воспроизвести это независимо от того, что мы пытаемся, но я отправил один пользователь - тестовая программа, чтобы получить информацию о локали, и, конечно же, GetThreadLocale возвращает другой идентификатор LCID (1033), чем GetUserDefaultLCID (2057). Поэтому вместо того, чтобы получать настройки в Великобритании, они в конечном итоге устанавливают настройки локали в США.

Неправильно ли вы получаете информацию о локали? Должны ли мы использовать GetUserDefaultLCID вместо GetThreadLocale?

Благодаря

+0

Вы фактически используете несколько потоков, или вы просто вызываете GetThreadLocale из основного потока? –

ответ

15

Вы не единственный. Я тоже видел это в Windows 7 здесь, в Новой Зеландии, и по некоторым причинам, по некоторым причинам, по некоторым причинам они только отключают приложения Delphi.

Странная вещь, которую мы обнаружили, это переход на другие региональные настройки с помощью панели управления, а затем переход в NZ устраняет проблему. Мне было бы любопытно узнать, разрешает ли это обходное решение для вас просто проверить, что мы видим одно и то же явление.

Мне интересно, не выбрали ли какие-либо региональные настройки региона через процесс установки Windows 7 не совсем «правильно», а лишь по каким-то причинам только запускают приложения Delphi.

Я пришел к аналогичному тестовому коду в JP's, пытаясь отследить его и найти решение для программного обеспечения, но наш парень с QA с тех пор нашел обходное решение для региональных настроек switcheroo, и он не хотел полностью переустанавливать Windows 7 снова, чтобы вернуться к оригинальному состоянию фанки по какой-то причине :-)

+3

Переключение на другие региональные настройки с помощью панели управления и последующее переключение, похоже, работают. Благодаря! – Mick

6

я заметил та же проблема, когда я начал использовать новый Windows 7 компьютер. Я потратил некоторое время, пытаясь найти причину этого, но ничего не нашел. Итак, я просто добавил эти две строки в раздел инициализации некоторых единиц.

initialization 
    SetThreadLocale(LOCALE_USER_DEFAULT); 
    GetFormatSettings; 

Странно, что такое поведение наблюдается только на моем компьютере, так как у нас еще мало компьютеров Win7 в офисе.

+0

Переключение на другие региональные настройки, а затем назад, похоже, также исправить это, как предложил Павел Хайнц. Так что это может быть что-то вроде процесса установки Windows 7. Все программы, которые я нашел, имели проблемы с Delphi. Странно, хотя у DatetimePicker был правильный формат даты и времени. –

+0

Это исправляет проблему только для текущего потока? Поэтому для многопоточных приложений я должен тщательно добавить его к каждой инициализации потока, если в потоке используются некоторые зависящие от языка функции. ... – mjn

1

Я только что протестировал новую установку Windows 7 Starter Edition и имел ту же проблему, но я обнаружил, что язык, который возвращает GetThreadLocale, был точно языковой стандарт, запущенный программой установки Windows, но я изменил его во время установки на другой, который возвращает GetUserDefaultLCID, а также тот, который я хотел использовать, (для этого я сделал небольшую программу). Таким образом, локаль изменилась для пользователя, но где-то все еще была указана первая локаль, и она была возвращена GetThreadLocale. Как отметил JP, на самом деле проблема с установкой, она не меняет локаль во всех местах, где она может быть найдена. Кажется, что изменение языка с помощью панели управления делает работу прекрасной, и это может объяснить ее изменение как предлагаемые работы, кстати, это объясняет, почему другие компьютеры не могут иметь такую ​​же проблему (если вы не изменили язык во время монтаж). Надеюсь, что эта помощь.

18

Для некоторых справочной информации посмотрите здесь:

http://www.siao2.com/2010/03/19/9980203.aspx

Так что, кажется, эта проблема проявляется на Vista, а также Windows 7.Это происходит из-за того, что Microsoft, похоже, находится в процессе устаревания Locale ID в пользу Название локали.

Подводя итог: соответствующие вызовы API работают со значениями реестра, которые можно найти по адресу HKCU\Control Panel\International. Значение «Locale» поддерживается по соображениям обратной совместимости и при нормальных обстоятельствах сохраняется в синхронизации с его новым коллегой под названием «LocaleName». Однако этот синхронный процесс не работает при некоторых обстоятельствах.

Во всяком случае, вызов GetThreadLocale API получает возвращаемое значение из «Locale» реестр, упомянутых выше, в то время как другие (GetUserDefaultLCID, GetSystemDefaultLCID и т.д.) использовать запись реестра «LocaleName».

Отсюда путаница.

КСТАТИ, решение упоминается JP in a previous post, вероятно, должен быть продлен до

initialization 
    SetThreadLocale(GetUserDefaultLCID); 
    GetFormatSettings; 

, потому что (если я правильно читать это!) В соответствии с docco вызов GetUserDefaultLCID будет приходиться на пользовательские параметры.

После немного большего исследования Vista не затронута вообще. У меня есть еще несколько деталей ...

Соответствующие вызовы API работают со значениями реестра, которые можно найти по адресу HKCU\Control Panel\International. Значение «Locale» поддерживается по соображениям обратной совместимости и при нормальных обстоятельствах синхронизируется с его новым коллегой под названием «LocaleName». В Windows 7, по крайней мере, этот процесс синхронизации, однако, не работает, когда процессы запускаются как другой пользователь (т. Е. RunAs или олицетворение). Похоже, что это происходит во время установки, когда установщик запускается из существующего сеанса Windows. Однако он работает правильно, если вы загрузились с установочного компакт-диска.

  • GetThreadLocale получает свое значение от Thread Information Block или Thread Environment Block (TIB или TEB) См: http://en.wikipedia.org/wiki/Thread_Environment_Block Для обоих Vista, и Windows 7, то ИРТ инициализирован с вводом в HKCU\Control Panel\International\Locale реестра при входе в систему. Это становится стандартным языком для всех потоков, созданных во время сеанса. Изменение этого значения реестра во время сеанса не влияет на значение, возвращаемое вызовом API GetThreadLocale. Чтобы просмотреть изменения, пользователь должен выйти из системы и снова войти в систему. Это вызов API, который Delphi использует в качестве основы для инициализации всех его строк формата локали (см. Метод SysUtils.GetFormatSettings), из которого форматируются все поля даты.

  • GetUserDefaultLCID: в Vista, основывает свое возвращаемое значение на записи реестра . В Windows 7 основывается его возвращаемое значение в записи реестра HKCU\Control Panel\International\LocaleName. Соответствующая запись в реестре может быть изменена во время сеанса, и результат немедленно отражается в этом возвращаемом значении вызова API.

  • SetThreadLocale обновляет TIB, чтобы отразить языковой стандарт, указанный в параметре этого вызова. Обратите внимание, что это только когда-либо влияет на поток, из которого выполняется вызов API. API-вызовы SetThreadLocale(LOCALE_USER_DEFAULT) и SetThreadLocale(GetUserDefaultLCID) функционально эквивалентны. Они оба получают исходный язык, как описано выше в API-интерфейсе GetUserDefaultLCID.

1

new post in the RTL forum предлагает исправления в SysUtils-> InitSysLocale:

SetThreadLocale(LOCALE_USER_DEFAULT); 
SysLocale.DefaultLCID := LOCALE_USER_DEFAULT; 
GetFormatSettings; 

И далее поясняет:

Он должен быть установлен по умолчанию LOCALE_USER_DEFAULT и не 0x409! Эта ошибка в 2010 году, XE и XE2

Смежные вопросы