Autor Beitrag
Nano-Ware
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 394
Erhaltene Danke: 7



BeitragVerfasst: So 08.05.11 11:17 
Hey,

ich habe versucht, ein TEdit zu basteln, dass nur Kommazahlen akzeptiert. Er bombt mich mit Meldungen voll, dass die Typen inkompatibel sind und ich weiß leider nicht warum.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure Tfrm_monitor.ed_onlyfloat(Sender: TObject; var Key: Char);
begin

  if (Key in [',']) then
    Key := '.';

  if not ((Key in ['0'..'9''.']) or (Key = vk_delete) or (Key = VK_LEFT) or (Key = VK_RIGHT) or (Key = VK_RETURN)) then
    Key := #0;

end;


Danke schonmal
colaka
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 200
Erhaltene Danke: 4

Win XP, W7
Delphi 2005 Prof.
BeitragVerfasst: So 08.05.11 11:27 
Hallo,

schreibe in das OnKeyPress-Ereignis den folgenden Code:

ausblenden Delphi-Quelltext
1:
2:
if not (Key in [#8#13'0'..'9'',']) then   // #8 = BACKSPACE
  Key := #0;  // erlaubt nur die Eingabe von Zahlen, Komma, BACKSPACE und RETURN


Gruß Ebi
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: So 08.05.11 12:34 
Hallo,

Zu den inkompatiblen Typen: Wenn du Strg drückst und dein vk_xyz anklickst, wirst du sehen dass es einfach die Zahl ist. Zahlen kannst du aber mit Chars nicht so einfach vergleichen, weil Delphi typenstreng ist(und das hilft auch manchmal, weil es sonst vielleicht einfach "nicht funktioniert", wenn es sich um wirklich inkompatible Typen handelt, die nicht durch reine Umbenennung ineinander übergehen).

Deine erste Abfrage ist schon ganz nützlich, die würde ich drin behalten. Würde aber auf Key = ',' prüfen, statt auf Key in [','] :zwinker:

Einen zusätzlichen Fall habt ihr noch nicht bedacht: Es kann nur ein '.' pro Zahl geben.
Einfach und bedienerfreundlich wäre es, den alten Punkt rauszulöschen und den neuen an der passenden Stelle zu belassen: So kann man ihn einfach mal verschieben, statt dass einfach nichts passiert(das ist nämlich unintuitiv ;)).

À propos Intuition: Wenn du es ganz nett machen willst, machst du bei Fehleingabe ein Beep; und färbst das Editfeld kurz rot ein oder so :)

lg,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: So 08.05.11 12:43 
Hallo,

problematisch ist auch, wenn Du zweimal '-', '+', ',' in deinem Text hast. Z.B.: '0,,4546' oder '+0+.00342'. Außerdem kommen '+' und '-' ja nur an der 1. Position vor.

Du solltest dann zusätzlich für ',' '-' '+' Abfragen einbauen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
  e: TEdit;
  p : integer;
begin
  e := Sender as TEdit;   // dann kannst Du beliebige Editfelder mit einer OnKeyPress-Prozedur bearbeiten, ohne die Prozedur an das Editfeld anzupassen.
                          // Beschränkung: Nut TEditkomponenten oder Nachfahren möglich!
  if not (Key in [#8#13#27'0'..'9'',''+''-']) then
    Key := #0;
  if Key in [',''+''-'then
  begin
    if (Pos(Key, e.Text) > 0then
      Key := #0;
  end;
  if Key in ['+''-'then
  begin
    p := e.SelStart+1;    // Position des Cursors speichern
    e.Text := Key + e.Text;
    Key := #0;
    e.SelStart := p;     // und wieder an Position zurückgehen
  end;
  if Key = #27 then
    e.Text := '';
  if Key = #13 then
    Label1.Caption := FormatFloat('0.#######', StrToFloat(e.Text));   // Hier übergibst Du das Ergebnis an eine Variable (nur ein Beispiel)
                                                                      // Alternativ kannst Du auch in der OnKeyDown-Prozedur das erledigen lassen. Dann aber 
                                                                      // #13 aus der ersten Abfrage herausnehmen oder in der OnKeyDown-Prozedur anschließend an die Übergabe
                                                                      // mit Key := 0; die Variable Key zurücksetzen. Dann wird OnKeyPress nicht mehr aufgerufen.
end;

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: So 08.05.11 13:00 
Vorschlag für Default-Verhalten: '-' bzw '+' überschreiben das Vorzeichen, egal wo sie gedrückt werden.

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: So 08.05.11 13:21 
Kein Problem:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
  e: TEdit;
  c : char;
  s : string;
  p, p1 : integer;
begin
  e := Sender as TEdit;
  s := e.Text+#0;                 // wegen Umwandlung des ersten Zeichens in Char notwendig.
  if not (Key in [#8#13#27'0'..'9'',''+''-']) then
    Key := #0;
  if Key = ',' then    // Kommaposition wird auf aktuelle Pos. verschoben
  begin
    p := e.SelStart+1;
    p1 := Pos(Key, e.Text);
    if p1>0 then begin
      e.Text := Copy(e.Text,1,p1-1)+Copy(e.Text,p1+1,255);
      e.Text := Copy(e.Text,1,p-1) +','+Copy(e.Text,p+1,255);
      Key := #0;
      e.SelStart := p-1;
    end;
  end;
  if Key in ['+''-'then    // +, - werden gewechselt
  begin
    p := e.SelStart+1;
    c := s[1];    // Abfrage des ersten Zeichens   (Bei Leerstring im Editfeld ist s = #0, s.o.);
    if c in ['+','-'then
      e.Text := Copy(e.Text,2,255);
    e.Text := Key + e.Text;
    Key := #0;
    e.SelStart := p;
  end;
  if Key = #27 then
    e.Text := '';
  if Key = #13 then
    Label1.Caption := FormatFloat('0.#######', StrToFloat(e.Text));
end;



EDIT:

Das Ganze könnte auch als überladene (override) KeyPress-Prozedur in einem Nachfahre von TEdit nützlich sein. (Sozusagen ein TFloatEdit oder so). Das Ergebnis wäre dann eine Value-Eigenschaft, und statt Edit1.Text könnten man dann Edit1.Value abrufen. Aber sicher existiert schon irgendwo ein solcher Nachfahre von TEdit, oder?

Dann müsste allerdings jeder Bezug auf andere Objekte wie oben bei Key= #13 auf Label1, unterbleiben, weil diese ja zum Zeitpunkt der Erstellung der Komponente nicht bekannt sind. Das wird aber mehr als ersetzt durch die property (Eigenschaft) Value der neuen Komponente.

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.