Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Разрешить ввод в Edit только числовые значения с плавающей точкой   Найти похожие ветки 

 
upc   (2012-01-28 15:06) [0]

Такое решение будет правильным?
Добавить в OnKeyPress:

if not(Key in ["0".."9", #13, #8, DecimalSeparator]) then
 Key := #0;

Просто везде пишут вместо DecimalSeparator
",", "."
но ведь десятичный разделитель в системе только один и зависит от страны, как я понял. Так почему не использовать DecimalSeparator из SysUtils? Есть ли тут какой-то подводный камень, или я сделал всё правильно?


 
Германн ©   (2012-01-28 15:11) [1]


> или я сделал всё правильно?

Забыл "-" и "E"


 
upc   (2012-01-28 15:14) [2]

Точно! Правда в моем случае отрицательных быть не может, и слишком больших и слишком маленьких тоже.

Значит писать DecimalSeparator можно вместо точки и запятой?


 
sniknik ©   (2012-01-28 15:19) [3]

> Просто везде пишут вместо DecimalSeparator
тоже так пишу, точку, запятую, + DecimalSeparator ... (один раз "нарвался". была настройка # как разделителя... и х.з, почему "не работает" по телефону...)
а перед преобразованием считанного  к числу делаю замену их обоих на DecimalSeparator.

> Есть ли тут какой-то подводный камень
только не удобство ввода. пойди пойми почему нажатие клавиши игнорируется... не все же работают с мыслью "сегодня у нас запятая разделителем..."

> в OnKeyPress:
а копи паст?


 
upc   (2012-01-28 15:23) [4]

Вот те на! Действительно копипаст то сломался. Как же быть? В принципе, в моем частном случае можно и без него обойтись, но в других вот...

> а перед преобразованием считанного  к числу делаю замену
> их обоих на DecimalSeparator.

То есть свой StrToFloat писать?


 
Dimka Maslov ©   (2012-01-28 15:27) [5]

А еслт усер введёт две точки?

Проверка может быть такой - в OnChange проверяется правильность числового ввода. Если это число (или пустая строка), ничего не происходит, но текущее состояние сохраняется в к.н. переменной. Если это не число, программа бибикает и восстанавливает сохранённое состояние.

Или: когда ввод данных завершён и поступает команда на продолжение работы, проверяется состояние всех полей ввода. Если обнаружится ошибка - программа бибикает, приостанавливает дальнейшую работу и передаёт фокус в то поле ввода, где обнаружилась ошибка.


 
Inovet ©   (2012-01-28 15:55) [6]

> [1] Германн ©   (28.01.12 15:11)
> Забыл "-" и "E"

Ещё "+" и ещё несколько навроде "NaN".


 
sniknik ©   (2012-01-28 16:10) [7]

> копипаст то сломался. Как же быть?
а не парится по этому поводу... нужно понимать введенное однозначно потом, после ввода, а не пытаться "вести юзера за ручку, бить по пальцам если не так", такие попытки только раздражают, и отследить/закрыть все, все одно не сможешь.
ну вот к примеру, копирую число из браузера, легальное на вид... а там форматирование/символы другой кодовой страницы "цепляет". не проблема, скопирую, уберу. а твоя "умная" прога, вдруг начинает запрещать, или хуже того корректировать в процессе.... не заметил, будет глюк уже в твоей работе, при запрете нужно будет сначала скопировать куда то, привести к правильному виду, и только после в твою прогу. удобно? меня такие программы бесят. стараюсь избавится (что иногда, когда от меня зависит(вернее зависело, сейчас не занимаюсь), приводило к отказу от покупки(и дальнейшего распространения) программы конторой...)


 
Anatoly Podgoretsky ©   (2012-01-28 17:32) [8]

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

Руки прочь от Патриса Лумумбы Эдитовича


 
Германн ©   (2012-01-29 01:33) [9]


> Inovet ©   (28.01.12 15:55) [6]
>
> > [1] Германн ©   (28.01.12 15:11)
> > Забыл "-" и "E"
>
> Ещё "+" и ещё несколько навроде "NaN".

Это уже перебор. "+" - нафиг не нужен. Отсутствие минуса == есть признак плюса. "Not a Number" в Эдит ни один пользователь в здравом уме вводить не станет.
:)


 
upc   (2012-01-30 03:17) [10]

В общем, я сделал так: разрешил пользователю вводить всё что угодно, а введенное значение проверяю специальной функцией и если было введено не число, то вывожу сообщение с ошибкой и подсказкой, каким является десятичный разделитель в системе.


 
Медвежонок Пятачок ©   (2012-01-30 09:51) [11]

Такое решение будет правильным?

Конечно нет:

допустим разделитель точка. вводим:
1.1......2.3.3.3.4.5.6.7.8.9.9.0..

допустим запятая. вводим:
06,6,7,8,8,,5,4,3,2,2,2,12,1,,1,,1,111111,,,,,,,,11,1,1,1


 
Геррман   (2012-01-30 10:07) [12]

Установи компонент и не парься :)

unit NumEdit;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;

type
 TNumEdit = class(TCustomEdit)
 constructor Create(AOwner:TComponent); override;
 destructor Destroy; override;
 private
   FAllowDec: boolean;
   FAllowNeg: boolean;
   FMaxValue: extended;
   FMinValue: extended;
   procedure WhenKeyPress(Sender: TObject; var Key: Char);
   procedure SeteValue(const Value: extended);
   procedure SetiValue(const Value: integer);
   procedure SetAllowDec(const Value: boolean);
   procedure SetAllowNeg(const Value: boolean);
   procedure SetMaxValue(const Value: extended);
   procedure SetMinValue(const Value: extended);
   function GetiValue: integer;
   function GeteValue: extended;
 public
 published
   property eValue : extended read GeteValue write SeteValue;
   property iValue : integer read GetiValue write SetiValue;
   property AllowDec : boolean read FAllowDec write SetAllowDec;
   property AllowNeg : boolean read FAllowNeg write SetAllowNeg;
   property MinValue : extended read FMinValue write SetMinValue;
   property MaxValue : extended read FMaxValue write SetMaxValue;

   property Anchors;
   property AutoSelect;
   property AutoSize;
   property BorderStyle;
   property Color;
   property Constraints;
   property Ctl3D;
   property DragCursor;
   property DragKind;
   property DragMode;
   property Enabled;
   property Font;
   property HideSelection;
   property ParentBiDiMode;
   property ParentColor;
   property ParentCtl3D;
   property ParentFont;
   property ParentShowHint;
   property PopupMenu;
   property ReadOnly;
   property ShowHint;
   property TabOrder;
   property TabStop;
   property Text;
   property Visible;
   property OnChange;
   property OnClick;
   property OnDblClick;
   property OnDragDrop;
   property OnDragOver;
   property OnEndDock;
   property OnEndDrag;
   property OnEnter;
   property OnExit;
   property OnKeyDown;
   property OnKeyPress;
   property OnKeyUp;
   property OnMouseDown;
   property OnMouseMove;
   property OnMouseUp;
   property OnStartDock;
   property OnStartDrag;
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents("delphi.about.com", [TNumEdit]);
end;

{ TNumEdit }

constructor TNumEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
OnKeyPress:=WhenKeyPress;
Text:="0";
AllowDec:=true;
AllowNeg:=true;
end;

destructor TNumEdit.Destroy;
begin
inherited Destroy;
end;

function TNumEdit.GeteValue: extended;
begin
result:=StrToFloat(Text);
end;

function TNumEdit.GetiValue: integer;
var
 i : integer;
begin
val(Text,result,i);
end;

procedure TNumEdit.SetAllowDec(const Value: boolean);
begin
FAllowDec := Value;
end;

procedure TNumEdit.SetAllowNeg(const Value: boolean);
begin
FAllowNeg := Value;
end;

procedure TNumEdit.SeteValue(const Value: extended);
begin
if FAllowDec
 then  Text:=FloatToStr(Value)
 else  Text:=IntToStr(round(Value));
end;

procedure TNumEdit.SetiValue(const Value: integer);
begin
if NOT FAllowDec then
 Text:=IntToStr(Value);
end;

procedure TNumEdit.SetMaxValue(const Value: extended);
begin
FMaxValue := Value;
if (FMaxValue<eValue) and (FMaxValue>FMinValue) then
 eValue:=FMaxValue;
end;

procedure TNumEdit.SetMinValue(const Value: extended);
begin
FMinValue := Value;
if (FMinValue>eValue) and (FMinValue<FMaxValue) then
 eValue:=FMinValue;
end;

procedure TNumEdit.WhenKeyPress(Sender: TObject; var Key: Char);
var
 p : integer;
begin
case Key of
 "0".."9"  : ;
 ".",","   : if AllowDec AND
                (pos(DecimalSeparator,Text)=0)
               then  Key:=DecimalSeparator
               else  Key:=#0;
 #8        : ;
 #45       : if FAllowNeg then
               begin
               p:=SelStart;
               eValue:=-eValue;
               if eValue>0
                 then  SelStart:=p-1
                 else  SelStart:=p+1;
               Key:=#0;
               end;
 else        Key:=#0;
end;
end;

end.


 
Юрий Зотов ©   (2012-01-30 11:15) [13]

> Геррман   (30.01.12 10:07) [12]

Я бы не доверял таким компонентам. Подробно не смотрел, но вот что бросилось в глаза сразу же.

1. Свойства AllowDec и AllowNeg.

Нет описателя default true. Хотя он и не строго обязателен, но его отсутствие говорит о квалификации разработчика. В частности, о том, что он мог допустить куда более серьезные ошибки.

2. Конструктор.

OnKeyPress := WhenKeyPress;
Грубейшая ошибка. Стоит юзеру сделать свой обработчик события (на что он имеет полное право) - и компонент перестанет работать.

3. Деструктор.

В такой редакции на фиг не нужен. Это, конечно, не ошибка, но тоже говорит о квалификации разработчика.

4. Методы SetAllowDec и SetAllowNeg.

То же самое - в такой редакции на фиг не нужны.


 
Юрий Зотов ©   (2012-01-30 11:18) [14]


> > Геррман   (30.01.12 10:07) [12]

И уж если делать компонент, то для целых чисел есть TSpinEdit, а для дробных - сделать по его образцу.


 
Германн ©   (2012-01-30 16:25) [15]


> Юрий Зотов ©   (30.01.12 11:18) [14]

А для дробных давно уже существует TRxSpinEdit. Только анонимы про RxLib ничего не знают. :)


 
upc   (2012-01-31 15:51) [16]

Да мне просто не хотелось использовать сторонние компоненты, думал можно сделать простое решение самому. Оказалось, нельзя :(


 
Юрий Зотов ©   (2012-01-31 19:44) [17]

> upc   (31.01.12 15:51) [16]

Можно, и в [7] Вам уже подсказали решение - проверять текст в Edit (число или не число) надо не при вводе, а после окончания ввода. То есть, в обработчике события OnExit. Например:
procedure
TForm1.Edit1Exit(Sender: TObject);
var
 Value: Extended;
begin
 with TEdit(Sender) do
  if not TryStrToFloat(Text, Value) then
  begin
   MessageBox(Handle, PChar(Text + " - это не число"), "Ошибка", MB_OK or MB_ICONERROR);  
   SetFocus
  end
end;


 
MsGuns ©   (2012-02-01 11:51) [18]

>Германн ©   (30.01.12 16:25) [15]
>Только анонимы про RxLib ничего не знают. :)

"Неанонимы" - это те, которые хватаются за любой глянцевый компонент и тащат его в свое "гнездо", превращая его в свалище ?


 
Германн ©   (2012-02-01 13:08) [19]


> MsGuns ©   (01.02.12 11:51) [18]

Некоторые неанонимы похоже тоже ничего не знают про RxLib.


 
upc   (2012-02-01 13:26) [20]


> Юрий Зотов ©   (31.01.12 19:44) [17]

Точно! Спасибо!! Я в точности так и сделал, но только не на OnExit, а просто при начале обработки. Поставлю в OnExit.


 
Юрий Зотов ©   (2012-02-01 13:46) [21]


> upc   (01.02.12 13:26) [20]
> Поставлю в OnExit.

Не спешите, подумайте. Куда ставить проверку - это зависит от того, как у Вас организован интерфейс с юзером. Возможно, есть смысл делать все проверки при нажатии кнопки OK, возможно еще где-то.


 
upc   (2012-02-01 14:25) [22]

В принципе, на OnExit подходит. Но сейчас заметил следующее: на форме есть TButton с Default := true, и если нажать энтер находясь в TEdit, то OnExit у него не сработает. Выходит действительно надо делать дополнительные проверки в OnClick у кнопки.


 
Anatoly Podgoretsky ©   (2012-02-01 14:37) [23]

> upc  (01.02.2012 14:25:22)  [22]

Конечно не стоит делать проверку в OnExit, поскольку выхода при нажатии
кнопки по умолчанию нет. И в OnClick тоже не подайдет. Надо делать перед
закрытием формы.



Страницы: 1 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.252 c
8-1227539352
sh1k4r1
2008-11-24 18:09
2013.03.22
Подкинули задачку


15-1339959786
Artem
2012-06-17 23:03
2013.03.22
Pocket Fritz


6-1256849792
Демо
2009-10-29 23:56
2013.03.22
WSARecv или ReadFile?


2-1332225008
ixen
2012-03-20 10:30
2013.03.22
Обращение из потока


4-1258417192
мурзик
2009-11-17 03:19
2013.03.22
Как определить что за изменения произошли в директории?