2013-04-17 2 views
2

Все номера, которые я пишу в файлы для обмена цели можно использовать следующий код:GetLocaleFormatSettings для LOCALE_INVARIANT возвращает настройки пользователей под Windows XP немецкий

GetLocaleFormatSettings(LOCALE_INVARIANT, fsInvariant); 
FloatToStrF(Value, fsInvariant); 

Когда я прочитал в номере я использую этот

GetLocaleFormatSettings(LOCALE_INVARIANT, fsInvariant); 
if TryStrToFloat(value, floatval, fsInvariant) then 
    result := floatVal 

Это работает под Windows 7, вкл. немецкая версия, но не удалась в немецкой версии Windows XP.

Проблема, похоже, в процедуре GetLocaleFormatSettings, поскольку она дает мне те же значения для LOCALE_INVARIANT и LOCALE_DEFAULT_USER.

Вот код, который показывает мой вопрос:

unit uMain; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, Grids, ValEdit; 

type 
    TForm1 = class(TForm) 
    VLEditor: TValueListEditor; 
    procedure FormShow(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.FormShow(Sender: TObject); 
var 
    fsInvariant : TFormatSettings; 
    fsLocaleUser : TFormatSettings; 
begin 
    GetLocaleFormatSettings(LOCALE_INVARIANT, fsInvariant); 
    VLEditor.InsertRow('Invariant Decimal Seperator', fsInvariant.DecimalSeparator, true); 
    VLEditor.InsertRow('Invariant Thousand Seperator', fsInvariant.ThousandSeparator , true); 
    VLEditor.InsertRow('Invariant List Seperator', fsInvariant.ListSeparator , true); 

    GetLocaleFormatSettings(LOCALE_USER_DEFAULT, fsLocaleUser); 
    VLEditor.InsertRow('Locale Decimal Seperator', fsLocaleUser.DecimalSeparator, true); 
    VLEditor.InsertRow('Locale Thousand Seperator', fsLocaleUser.ThousandSeparator, true); 
    VLEditor.InsertRow('Locale List Seperator', fsLocaleUser.ListSeparator, true); 
end; 

end. 

Когда я запускаю ех в Windows XP Pro SP3 - - НЕМЕЦКИЙ, он отображает те же символы для одних и тех же сепараторов. В немецкой Windows 7 он отображается, как ожидалось.

Что мне здесь не хватает? Почему это дает разные результаты?

Спасибо, Томас

Update: GetLocaleFormatSettings проверяет первый, если LCID действует с помощью функции kernel32 IsValidLCID(LCID, LCID_INSTALLED). Вопрос заключается в использовании LCID_INSTALLED, а не LCID_SUPPORTED. LOCALE_INVARIANT поддерживается, но не установлен в системах Windows XP. Поэтому процедура GetLocaleFormatSettings всегда возвращается к пользовательскому LCID.

Каков наилучший способ его крепления? Создать собственную процедуру GetLocaleFormatSettings? Измените код в файле SysUtils.pas Delphi?

+1

Если вы не называете 'GetLocaleFormatSettings()' часто, имеет смысл написать свою собственный для изолированных использований , Если вы часто используете его, имеет смысл исправлять и перекомпилировать 'SysUtils' вместо этого. Кстати, проблема с «LCID_INSTALLED» все еще существует в XE3, поэтому я бы предложил сообщить об этом как ошибку в QC. –

+0

Я решил создать глобальную переменную для параметров инварианта, которые я заполняю вручную. Настройки никогда не должны меняться. Я оставил код «SysUtils» нетронутым, просто чтобы избежать непредвиденных побочных эффектов при изменении «LCID_INSTALLED» на «LCID_SUPPORTED». – Thomas

ответ

4

У более ранних версий Delphi были проблемы с инициализацией TFormatSettings правильно. Например, D2010 имеет ошибку инициализации в отношении массивов ShortMonthNames, LongMonthNames, ShortDayNames и LongDayNames, когда указанный LCID не установлен (но это не влияет на ваш пример). В новых версиях исправлены ошибки, связанные с форматированием.

В некоторых случаях вызов SetThreadLocale() и GetFormatSettings() в разделе initialization устройства помогает решить проблемы с форматированием.

FYI, GetLocaleFormatSettings() теперь осуждаются в последних версии, в пользу нового TFormatSettings.Create() метода:

procedure TForm1.FormShow(Sender: TObject); 
var 
    fsInvariant : TFormatSettings; 
    fsLocaleUser : TFormatSettings; 
begin 
    fsInvariant := TFormatSettings.Create(LOCALE_INVARIANT); 
    ... 
    fsLocaleUser := TFormatSettings.Create(LOCALE_USER_DEFAULT); 
    ... 
end; 
+0

К сожалению, в Delphi 2010 метод 'TFormatSettings.Create()' недоступен. Я попытаюсь получить что-то работающее 'SetThreaddLocale()'. – Thomas

+0

'TFormatSettings.Create()' был добавлен в XE. –

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