Программа на Delphi, запрещающая ввод нечисловых символов
Программа состоит из двух процедур. Первая, работающая в обработчике события KeyPress компонента Edit, не допускает появления нежелательных символов, то есть любых, не равных цифре или символу-разделителю целой и дробной частей числа. Последний может быть равен точке или запятой, в зависимости от текущих настроек Windows. Поэтому используется встроенная в Delphi константа DecimalSeparator, содержащая нужный символ. Вторая процедура, базирующаяся на обработчике события KeyUp, приводит вводимое число к привычному, общеупотребительному виду. Например, не допускает появления числа, у которого символ-разделитель - первый из символов.
type
TForm1 = class(TForm)
Edit1: TEdit; procedure Edit1KeyPress(Sender: TObject; var Key: Char); procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); private
{ Private declarations } public
{ Public declarations } end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{Процедура, запрещающая появление нежелательных символов в edit.
Если вводимый символ, код которого содержится в переменной Key, не содержится во множествах Digit или Separator, то переменной Key присваивается код "отсутствие символа", равный #0.
Для того чтобы раскладки клавиатуры не влияли на ввод символа-разделителя, производится анализ на символы, находящиеся на тех кнопках, где располагаются точка либо запятая. Нажатие этих кнопок приводит к вводу символа DecimalSeparator. Однако повторный ввод разделителя не допускается.}
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); //Множество цифр, допустимых для ввода в edit: const Digit: set of Char=['1'..'9', '0']; //Множество символов, воспринимаемых как символ-разделитель:
Separator: set of Char=['/', '.', ',', 'ю', 'Ю', 'б', 'Б']; begin with (Sender as TEdit) do begin if (Key in Separator) then Key:=DecimalSeparator //Delphi-константа типа Char, равная символу-разделителю Windows else if (not(Key in Digit)) then Key:=#0; if ((Key=DecimalSeparator)and(pos(DecimalSeparator, Text)<>0)) then Key:=#0; end; end;
{Процедура, приводящая вводимое число к общеупотребительному виду. Для этого производится анализ на положение символа-разделителя (чтобы он был не первым либо последним), первый ноль перед символом, не равным символу-разделителю, завершающие нули в нецелом числе и т. д. Процедура также обеспечивает стирание введённых символов.}
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); var n: Integer;
S: String; begin with (Sender as TEdit) do begin if pos(DecimalSeparator, Text)=1 then begin
Text:='0'+Text;
SelStart:=Length(Text); end; if (pos(DecimalSeparator, Text)<>Length(Text)) then if Text[Length(Text)]<>'0' then if FloatToStr(StrToFloat(Text))<>'0' then
Text:=FloatToStr(StrToFloat(Text)); if Key=8 then begin
n:=SelStart;
S:=Text;
Delete(S, n, 1);
Text:=S; end;
SelStart:=Length(Text); end; end;
end.
Сначала положите на Форму компонент Edit. Затем, открыв вкладку Events в Инспекторе Объектов и дважды щёлкнув по обработчикам событий OnKeyPress и OnKeyUp компонента Edit, создайте заготовки обработчиков этих событий. Затем замените обработчики предлагаемыми процедурами - и ваш Edit сможет содержать только числа. Если у вас несколько компонентов, то достаточно создать тоько одну пару предлагаемых процедур, для одного, любого из них. К остальным их нужно подключить, выбрав в Инспекторе Объектов в качестве обработчиков соответствующих событий.
Дополнительно можно обеспечить размещение числа у правого края Edit, как в калькуляторе Windows. Для этого сразу после
implementation
{$R *.dfm}
добавьте следующий код:
type
TMEdit = class(TEdit) procedure CreateParams(var Params: TCreateParams); override; end;
{ TMEdit }
procedure TMEdit.CreateParams(var Params: TCreateParams); begin inherited;
Params.Style := Params.Style or ES_RIGHT; end;
а также в обработчике события OnCreate Формы (если его нет - создайте!) добавьте строку
PPointer(Edit1)^ := TMEdit;
Естественно, Edit1 замените на имя вашего компонента.