Ograniczenie wpisywanych znaków do TEdit

Juhas

Cześć, ostatnio często na forum padają pytania, jak ograniczyć znaki wpisywane do TEdit. Jakiś czas temu napisałem klasę, która to w bardzo prosty sposób realizuje, więc postanowiłem się nią podzielić:

type
  TEditManager = class(TObject)

  public
    constructor Create;
    destructor Destroy; override;

    procedure KeyPressNumeric(Sender: TObject; var Key: Char);
    procedure KeyPressInteger(Sender: TObject; var Key: Char);
    procedure KeyPressMoney(Sender: TObject; var Key: Char);
    procedure KeyPressNotSpecial(Sender: TObject; var Key: Char);
    procedure KeyPressPostalCode(Sender: TObject; var Key: Char);
end;


implementation

constructor TEditManager.Create;
begin
  inherited;
end;


procedure TEditManager.KeyPressInteger(Sender: TObject; var Key: Char);
begin
//dopuszczenie cyfr
  if not ((ord(key) in [48..57]) or (ord(key) = 8)) then key:=#0;
end;

procedure TEditManager.KeyPressNumeric(Sender: TObject; var Key: Char);
begin
//dopuszczenie cyfr, przecinka i backspace
  if (ord(key) = 44) and (pos(',', (TEdit(sender)).Text)>0) then
  begin
    key:=#0;
    exit;
  end;

  if not ((ord(key) in [48..57]) or (ord(key) = 44) or (ord(key) = 8)) then key:=#0;
end;




//tak jak KeyPressnumeric, tylko dozwolone dwa znaki po przecinku
procedure TEditManager.KeyPressMoney(Sender: TObject; var Key: Char);
var
  cPos: word; //index przecinka
begin
  if key = #8 then exit; //backspace

  KeyPressNumeric(Sender, Key);

  if key<>#0 then
  begin
    //sprawdzam, czy jest przecinek
    cPos:=pos(',', (TEdit(sender)).Text);

    //jeśli wpisujemy przed przecinkiem, to jest dopuszczalne
    if (TEdit(Sender).SelLength = 0) and (TEdit(Sender).SelStart<cPos) then exit;

    if (cPos>0) and (length(TEdit(sender).Text) = cPos + 2) then key:=#0;
  end;
end;


procedure TEditManager.KeyPressNotSpecial(Sender: TObject; var Key: Char);
begin
//cyfry, litery, znaki - bez specjalnych, np. polskich
  if not ((ord(key) in [32..125]) or (ord(key) = 8)) then
  begin
    key:=#0;
    exit;
  end;
end;


procedure TEditManager.KeyPressPostalCode(Sender: TObject; var Key: Char);
begin
  //format kodu: 00-000
  if key = #8 then exit; //backspace

  //na pozycji 1, 2, 4, 5, 6 można wpisywać jedynie cyfry
  if (TEdit(Sender).SelLength = 0) and (TEdit(Sender).SelStart<>2) then
     if not (ord(key) in [48..57]) then
     begin
       key:=#0;
       exit;
     end;

  //na pozycji 3 można wpisać jedynie myślnik
  if (TEdit(Sender).SelLength = 0) and (TEdit(Sender).SelStart = 2) then
     if not (ord(key) = 45) then
     begin
       key:=#0;
       exit;
     end;
end;




destructor TEditManager.Destroy;
begin
  inherited;
end;

<font size="4">Małe wyjaśnienie.</span>
Każda z tych procedur odpowiada za inne ograniczenia:
KeyPressNumeric - dopuszcza wpisywanie jedynie cyfr i przecinka(tylko jednego). Czyli liczb rzeczywistych. Oczywiście przecinek można zamienić na decimalSeparator. To nie jest dużo roboty.

KeyPressInteger - dopuszcza wpisywanie jedynie liczb całkowitych
KeyPressMoney - dopuszcza wpisywanie jedynie liczb rzeczywistych z maks dwiema cyframi po przecinku. Czyli np: "123,54"
KeyPressNotSpecial - dopuszcza wpisywanie jedynie znaków alfanumerycznych. Tzn. cyfr i liter, a także znaków będących na standardowej klawiaturze. Nie dopuszcza wpisywania polskich znaków i innych. Jedynie znaki o kodach Ascii>=32 i <=125 + oczywiście backspace.

No i perełka:
KeyPressPostalCode - dopuszcza wpisanie jedynie polskiego kodu pocztowego, czyli np: "123-45".

<font size="4">Jak używać?</span>
Bardzo prosto:

var
  editMgr: TEditManager;
begin
  editMgr:=TEditManager.Create;
  editZOgraniczeniem.OnKeyPress:=editMgr.KeyPressInteger;
end;

Takie coś spowoduje możliwość wpisania jedynie cyfr(liczba całkowita) w edicie: EditZOgraniczeniem.

Oczywiście pamiętajcie o zwolnieniu klasy, gdy już nie będzie potrzebna(dla mało kumatych: editMgr.Free)

3 komentarzy

1 linijka kodu załatwia sprawę i dodatkowo blokuje gdy wrzucasz z schowka śmieci Ctrl+v :-)

SetWindowLong(Edit.Handle, GWL_STYLE, GetWindowLong(Edit.Handle, GWL_STYLE) or ES_NUMBER);

a jakbym chciał wpisać liczbę 1.23e-3 albo -12.34 to jak tego cudu dokonać?
Dodatkowo np. w KeyPressMoney jeśli mamy w edicie 1234,56 i 56 są zaznaczone to wciśnięcie np. 7 nic nie da a powinno wyjść 1234,7

A nie lepiej w OnKeyPress Edita takie coś:
if not(Key in['a'..'b', #8)] then Key := #0;