Подтвердить что ты не робот

GetThreadLocale возвращает другое значение, чем GetUserDefaultLCID?

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

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

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

Спасибо

4b9b3361

Ответ 1

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

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

Мне интересно, если выбор неамериканских региональных настроек через процесс установки Windows 7 не совсем "делает правильные вещи" каким-то тонким способом, который по какой-то причине только запускает приложения Delphi.

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

Ответ 2

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

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

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

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

В любом случае, вызов API GetThreadLocale получает свое возвращаемое значение из записи реестра "Locale" , упомянутой выше, а остальные (GetUserDefaultLCID, GetSystemDefaultLCID и т.д.) используют запись реестра "LocaleName" .

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

BTW, решение, упомянутое JP в предыдущем сообщении, вероятно, должно быть расширено до

initialization
  SetThreadLocale(GetUserDefaultLCID);
  GetFormatSettings;

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

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

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

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

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

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

Ответ 3

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

initialization
  SetThreadLocale(LOCALE_USER_DEFAULT);
  GetFormatSettings;

Странно то, что это происходит только на моем компьютере, так как у нас мало других компьютеров Win7 в офисе.

Ответ 4

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

Ответ 5

A новое сообщение в форуме RTL предлагает это исправление в SysUtils- > InitSysLocale:

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

И далее объясняется:

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