Форум: "Начинающим";
Текущий архив: 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.094 c