Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как заблокировать ввод нецифровых данных в Edit

Delphi , Программа и Интерфейс , TEdit

Блокировка вставки нецифровых данных через буфер обмена

Code:

uses Clipbrd;
 
function NewEditProc(wnd:HWND; uMsg:UINT; wParam:WPARAM; lParam:LPARAM):integer; stdcall;
var
s:string;
i:integer;
begin
if (uMsg=WM_PASTE) and Clipboard.HasFormat(CF_TEXT) then
begin
s := Clipboard.AsText;
for i:=1 to Length(s) do if (not (s[i] in ['0'..'9'])) then begin uMsg:=0; break end
end;
result:=CallWindowProc(Pointer(GetWindowLong(wnd,GWL_USERDATA)),wnd,uMsg,wParam,lParam)
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
SetWindowLong(Edit1.Handle,GWL_STYLE,GetWindowLong(Edit1.Handle,GWL_STYLE) or ES_NUMBER);
SetWindowLong(Edit1.Handle,GWL_USERDATA,SetWindowLong(Edit1.Handle, GWL_WNDPROC, LPARAM(@NewEditProc)))
end;

Автор: Krid

Взято из http://forum.sources.ru

Следующий код создаёт TEdit который блокирует ввод любых нецифровых данных при вводе любым способом.

Code:

unit Unit1;
 
interface
 
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
 
{ Пример TEdit с выравниванием по центру © Song
в модификации Vit}


 
type
TForm1 = class(TForm)
 procedure FormCreate(Sender: TObject);
private
 { Private declarations }
public
 { Public declarations }
end;
 
{ Обявляем класс нашего едита как потомок от стандартного}
type TMySuperEdit=class(TCustomEdit)
public
{ Внутри класса переопредялем процедуру CreateParams,
    т.к. нужный нам стиль можно изменить только на создании или пересоздании
    окна  }
Procedure CreateParams(Var Params: TCreateParams); override;
end;
 
var
Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
Procedure TMySuperEdit.CreateParams(Var Params: TCreateParams);
Begin
{ Вызываем родительский обработчик, чтобы он сделал все процедуры по созданию объекта класса }
inherited CreateParams(Params);
{ Изменяем стиль }
With Params Do Style:=Style or ES_NUMBER;
End;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
{ Создаём едит на основе нашего класса и кладём его на форму }
With TMySuperEdit.Create(Self) Do
Parent:=Self;
end;
End.
Автор: Vit (www.delphist.com, www.drkb.ru, www.unihighlighter.com, www.nevzorov.org)

Как сделать, чтобы TEdit воспринимал одни цифры и DecimalSeparator?

Автор: Full  ( http://full.hotmail.ru/ )

Code:

type
TNumEdit = class(TEdit)
procedure CreateParams(var Params: TCreateParams); override;
procedure KeyPress(var Key: Char); override;
end;
 
procedure Register;
 
implementation
 
procedure Register;
begin
RegisterComponents('Standard', [TNumEdit]);
end;
 
procedure TNumEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or ES_MULTILINE or ES_RIGHT;
end;
 
procedure TNumEdit.KeyPress(var Key: Char);
begin
case key of
'0'..'9': ; // цифры
#8: ; // забой
'.', ',': if Pos(DecimalSeparator, Text)=0 then Key:=DecimalSeparator else Key:=#0; // десятичный разделитель
else key:=#0;
end; // case
end;
 
end.

Взято из http://forum.sources.ru

Посылаю Вам несколько расширенный вариант числовой маски компонента TЕdit c помощью OnKeyPress. В отличие от имеющегося в "Советах", приведенный код не "запирает" поле ввода при заполнении десятичной части, преобразует точку в запятую (для удобства пользователя), не позволяет поставить десятичную запятую перед числом и позволяет стирать знаки в поле ввода клавишей 'Back Space'. Код проверен в Delphi 5.

Code:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var //цифровая маска
vrPos, vrLength, vrSelStart: byte;
const
I: byte = 1;
   //I+1 = количество знаков после запятой (в данном случае - 2 знака)
begin
 
with Sender as TEdit do
begin
   vrLength := Length(Text); //определяем длину текста
   vrPos := Pos(',', Text); //проверяем наличие запятой
   vrSelStart := SelStart; //определяем положение курсора
end;
 
case Key of
 
   '0'..'9':
     begin
       //проверяем положение курсора и количество знаков после запятой
       if (vrPos > 0) and (vrLength - vrPos > I) and (vrSelStart >= vrPos) then
         Key := #0; //"погасить" клавишу
     end;
   ',', '.':
     begin
       //если запятая уже есть или запятую пытаются поставить перед
       //числом или никаких цифр в поле ввода еще нет
       if (vrPos > 0) or (vrSelStart = 0) or (vrLength = 0) then
         Key := #0 //"погасить" клавишу
       else
         Key := #44; //всегда заменять точку на запятую
     end;
   #8: ; //позволить удаление знаков клавишей 'Back Space'
else
   Key := #0; //"погасить" все остальные клавиши
end;
end;


Все приведенные выше примеры грешат несколькими проблемами: одни из них не учитывают ВСЕ способы которыми может вводится информация в TEdit - одни не учитывают clipboard, другие ввод из кода программы, и наконец все они не учитывают, что число может иметь например такую запись "2E4" или даже "2E-4".

Попытка разрешить ситуацию привела к следующему простому коду:

Code:

unit Unit1;
{®Vit (Vitaly Nevzorov) - nevzorov@yahoo.com}
 
interface
 
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
 
type
TForm1 = class(TForm)
   Edit1: TEdit;
   procedure Edit1Change(Sender: TObject);
   procedure FormCreate(Sender: TObject);
private
   EditValue:string;
public
   { Public declarations }
end;
 
var
Form1: TForm1;
 
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Edit1Change(Sender: TObject);
var selstart, sellength:integer;
begin
if Edit1.Text='' then
   begin
     Edit1.Text:='0';
     Edit1.SelStart:=1;
     Edit1.SelLength:=0;
     Exit;
   end; 
try
   strtofloat(Edit1.Text);
   EditValue:=Edit1.Text;
except
   selstart:=Edit1.SelStart;
   sellength:=Edit1.SelLength;
   Edit1.Text:=EditValue;
   Edit1.SelStart:=selstart;
   Edit1.SelLength:=sellength;
end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
EditValue:='0';
Edit1.Text:=EditValue;
end;
 
end.

В данном коде в TEdit не получится вставить не цифровые данные. Можно заменить строку

strtofloat(Edit1.Text);

на

strtoint(Edit1.Text);

для того чтобы ограничить возможность ввода только целыми числами.

Автор: Vit (www.delphist.com, www.drkb.ru, www.unihighlighter.com, www.nevzorov.org)

Бессконечная поиска надежного способа предотвратить ввод нечисловых данных в контроле TEdit!

Я должен признать авторов кодовых фрагментов, которые вы предоставили, за их креативность и упорство в решении этой проблемы.

После изучения кода, я сделал некоторые наблюдения и предложения:

  1. Первый фрагмент кода Крид использует сообщение WM_PASTE для перехвата данных из буфера обмена и фильтрации нечисловых символов. Этот подход имеет свои ограничения, поскольку он работает только в том случае, если пользователь вставляет текст из буфера обмена.
  2. Второй фрагмент кода Вита использует custom класс TEdit для переопределения метода CreateParams и установки стиля ES_NUMBER. Хотя этот подход эффективен для предотвращения прямого ввода нечисловых символов, он не учитывает другие способы ввода данных (например, из буфера обмена или программно).
  3. Третий фрагмент кода Фулл использует схожий подход с кодом Вита, но с дополнительной логикой для обработки знаков разделения дробных частей и клавиши "Backspace".

Теперь я хочу поделиться своим предложением:

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

procedure TForm1.Edit1Change(Sender: TObject);
var
  Val: Double;
begin
  try
    Val := StrToFloat(Edit1.Text);
    // Проверка значения (например, проверка знака разделения дробных частей)
    EditValue := FloatToStr(Val);
  except
    Edit1.Text := EditValue; // Восстановление оригинального текста в случае ошибки
  end;
end;

В этом коде мы используем событие OnChange для обнаружения, когда пользователь вводит новый текст. Затем мы пытаемся преобразовать текст в вещественное число с помощью StrToFloat. Если преобразование успешно, мы проверяем значение (например, проверка знака разделения дробных частей). Если проверка не проходит или возникает ошибка при преобразовании, мы восстанавливаем оригинальный текст и предотваряем ввод нечисловых данных.

Этот подход имеет некоторые преимущества перед предыдущими кодовыми фрагментами:

  • Он обрабатывает все типы ввода (прямой, из буфера обмена, программно) одинаково.
  • Он обеспечивает более надежную обработку ошибок и не позволяет хранить недопустимые данные в контроле TEdit.
  • Он позволяет реализовать пользовательскую логику проверки для конкретных требований (например, знаки разделения дробных частей).

Конечно, могут быть краевые случаи или специфические требования, которые этот подход не покрывает. Я рад обсудить любые вопросы или concerns у вас!

Как заблокировать ввод нецифровых данных в Edit контролле Delphi.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: TEdit ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-16 14:52:41/0.0061290264129639/1