Страница 1 из 1

Разделитель дробной части по-умолчанию

СообщениеДобавлено: 16.10.2020 10:19:07
gluhow
Мне для моей программы удобно выставить в качестве разделителя точку вместо запятой, которая используется для русской локали по-умолчанию. Для этого я просто при инициализации программы прописывал
Код: Выделить всё
DefaultFormatSettings.DecimalSeparator:='.';

Но как оказалось, если при работающей программе Windows уйдет в режим ожидания(смены пользователя) и вернется, то разделитель опять становится запятой и программа начинает работать некорректно.
Кто нибудь может подсказать либо как выставить разделитель так чтоб он не менялся во время работы всей программы, либо какое событие отлавливать чтобы вручную возвращать на точку?

Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 16.10.2020 10:55:55
zub
Делать
Код: Выделить всё
DefaultFormatSettings.DecimalSeparator:='.';

Каждый раз перед преобразованием строк

Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 16.10.2020 12:18:56
Снег Север
gluhow, а вы где инициализируете? У меня вставлено в секции инициализации всех модулей, где это требуется, и всё работает.

Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 16.10.2020 13:40:47
gluhow
zub писал(а):Каждый раз перед преобразованием строк

Да, вот сейчас изыскиваю по старому проекту все преобразования. Но без DefaultFormatSettings элементы на форме типа TFloatSpinEdit тоже начинают показывать через запятую.

Снег Север писал(а):gluhow, а вы где инициализируете? У меня вставлено в секции инициализации всех модулей, где это требуется, и всё работает.

У меня прописано один раз в инициализации главного модуля. Всё работает, но до момента ждущего режима.

Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 16.10.2020 13:50:15
zub
Чудес не бывает. Либо Вы сами, либо включенный сторонний код меняет сепаратор в какомто событии происходящем при входевыходе в спячку.
Поэтому просто это вот так:
Код: Выделить всё
   myseparator: char;
begin
  myseparator := DecimalSeparator;
  DecimalSeparator := '.';
  Result := FloatToStr( d );
  DecimalSeparator := myseparator;
end;

А правильно это не юзать DefaultFormatSettings.DecimalSeparator используя функции в которые передается ваш FormatSettings

Добавлено спустя 1 минуту 45 секунд:
>>Но без DefaultFormatSettings элементы на форме типа TFloatSpinEdit
Я нуб, у TFloatSpinEdit разве нет своего управления разделителями?

Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 16.10.2020 14:05:29
Alex2013
По моему цифры "распознаются" с точкой по умолчанию, а DecimalSeparator как-бы "доброе пожелание" .
(Но возможно я что-то путаю так как обычно использую легаси процедуру Val удобную тем, что при ошибке не порождает исключения, а дает номер позиции в строке где обнаружена ошибка . )
.
( VAL (ST, X, CODE), где ST – строка, которую необходимо преобразовать в число, X – вещественная или символьная переменная, в которую записывается это число, CODE – необязательный параметр, который, в случае ошибки будет содержать номер позиции, в которой обнаружен ошибочный символ или ноль если все в порядке )

Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 16.10.2020 15:26:48
gluhow
zub писал(а):у TFloatSpinEdit разве нет своего управления разделителями?
нет, нету. Он чудесно реагирует на смену стандартного.

Похоже, что меняется где-то в недрах lcl, т.к. в консоли все норм. Минимальный код для графического приложения:
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Memo1: TMemo;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  DefaultFormatSettings.DecimalSeparator:='.';
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
    Memo1.Lines.Insert(0, FloatToStr(3.14));
end;

end.


Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 17.10.2020 03:31:20
zub
>>Минимальный код для графического приложения:
У меня в транковом лазаре все работает нормально. Вполне возможно у вас установлен какойнить кривой компонент который все портит
я бы копал:
1.поиск DefaultFormatSettings в исходниках всех установленных компонентов
2.проверка примера на лазаре из коробки, с последующей доустановкой в лазарь стороннего добра
3.установка на DefaultFormatSettings.DecimalSeparator точки останова на изменение данных

1 и 2 - по сути одно и тоже, 3 - когда мне подобное было надо не работал, работает ли сейчас хз

Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 19.10.2020 10:26:18
alexs
Для того, чтобы не изменялись переменные с разделителями надо в коде старта программы после Initialize добавить Application.UpdateFormatSettings:=false;

т.е.:
Код: Выделить всё
  Application.Initialize;
  Application.UpdateFormatSettings:=false;

Re: Разделитель дробной части по-умолчанию

СообщениеДобавлено: 19.10.2020 11:01:59
gluhow
alexs писал(а):Application.UpdateFormatSettings:=false;

А вот это помогло. Спасибо!