Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

Разрешить ввод в 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.079 c
15-1333917002
Юрий
2012-04-09 00:30
2013.03.22
С днем рождения ! 9 апреля 2012 понедельник


15-1339705802
Юрий
2012-06-15 00:30
2013.03.22
С днем рождения ! 15 июня 2012 пятница


2-1328539227
jacksotnik
2012-02-06 18:40
2013.03.22
Координаты объекта


15-1343766602
Юрий
2012-08-01 00:30
2013.03.22
С днем рождения ! 1 августа 2012 среда


3-1278051371
ford
2010-07-02 10:16
2013.03.22
плохой индекс в FireBird





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский