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

Материал из DRKB

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

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

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;


Author: Krid
Source: Взято из http://forum.sources.ru
ID: 00543



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

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.


Author: Vit (www.delphist.com, www.drkb.ru, www.unihighlighter.com, www.nevzorov.org)
ID: 00967



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

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.


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



Расширенный вариант числовой маски компонента TЕdit[править | править код]

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


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;


ID: 00970



Вариант с учетом буфера обмена и научной нотации чисел[править | править код]

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

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


unit Unit1;

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);

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


Author: Vit (www.delphist.com, www.drkb.ru, www.unihighlighter.com, www.nevzorov.org)
ID: 00971