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