Autor |
Beitrag |
midan23
      
Beiträge: 48
Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
|
Verfasst: Mi 25.08.04 14:38
Die tDateTimePicker-Komponente von Delphi eignet sich zwar ganz gut zur Eingabe von Uhrzeiten, hat aber für meine Zwecke gravierende Nachteile :
1) Man kann keine Grenzen angeben. Wenn man also nur Uhrzeiten zwischen 08:00 und 20:00 zulassen möchte, muss man das nach der Eingabe überprüfen und den Benutzer mittels Fehlermeldung darauf aufmerksam machen. Besser wäre es, wenn man dem Benutzer vorher die Grenzen mitteilt und diese während der Eingabe überprüft.
2) Das von tDateTimePicker verwendete Format zur Speicherung von Uhrzeiten ist für Berechnungen und Vergleiche denkbar ungünstig. tDateTime ist als double definiert und die Zeit wird als Wert zwischen 0 und 1 gespeichert (Im Prinzip als Bruchteil eines Tages).
Mein Problem ist jetzt, das ich zwar recht gut mit der Sprache Pascal umgehen kann, aber nicht so gut mit Delphi ...
Ich dachte mir, das ich das ganze aufteile in einen nicht-visuellen Teil, welcher die Uhrzeiten verwaltet und einen visuellen Teil, welcher für Ein- und Ausgabe verantwortlich ist.
Nach ein oder zwei schlaflosen Nächten ist der nicht-visuelle Teil fertig. Ich hab allerdings keine Ahnung, wo ich bei dem Visuellen Teil anfangen soll.
Ich bin für jede Hilfe dankbar.
|
|
midan23 
      
Beiträge: 48
Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
|
Verfasst: Sa 28.08.04 18:47
Und ich noch mal ...
Also, den visuellen Teil werde ich von tCustomMaskEdit ableiten.
Im Constructor setze ich EditMask auf '00:00:00;1;0'
Mein Problem :
Wie kann ich dafür sorgen, das nur gültige Uhrzeiten eingegeben werden können ?
|
|
Böser Borstel
      
Beiträge: 154
|
Verfasst: Di 31.08.04 08:37
prüfe in onkeypress ob das eingegebene zeichen + dem bisherigen text eine gültige uhrzeit ergibt, wenn nicht lösche das zeichen in key
|
|
midan23 
      
Beiträge: 48
Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
|
Verfasst: Di 31.08.04 09:01
Etwa so :
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure TfgTimeEdit.keyPress(var key : char); var s : string; begin s := EditText; case selStart of 0 : if (key in ['3'..'9']) then key := #0; 1 : if (s[1] = '2') and (key in ['4'..'9']) then key := #0; 3 : if (key in ['6'..'9']) then key := #0; 6 : if (key in ['6'..'9']) then key := #0; end; if (selStart = 0) and (key = '2') and (s[2] in ['4'..'9']) then begin s[2] := '3'; EditText := s; end; inherited; end; |
Ich hatte dabei mit zwei Problemen zu kämpfen :
1) Warum steht nirgends, das SelStart die Position des Text-Cursors darstellt ... ich hab zwei Tage suchen dürfen, um das raus zu bekommen ...
2) Das inherited; hatte ich am Anfang der Prozedur stehen und ich hab mich gewundert, warum es nicht so funktionierte wie es sollte ... erst als ich besagte Zeile nach meinem Code gepackt hatte lief es ...
Derzeit bin ich noch am Testen ...
|
|
midan23 
      
Beiträge: 48
Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
|
Verfasst: Do 16.09.04 15:52
Hier erst mal der Code :
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: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105:
| unit TimeEdit;
interface
uses Windows, Messages, SysUtils, Classes, Controls, StdCtrls, Mask;
type TTimeEdit = class(TCustomMaskEdit) private FTime : longint; FUseSeconds : boolean; procedure setUseSeconds(aUseSeconds : boolean); procedure setTime(aTime : longint); protected procedure KeyPress(var Key : Char); override; procedure Change; override; public constructor Create(AOwner : TComponent); override; function GetTimeStr : string; published property Font; property OnChange; property UseSeconds : boolean read FUseSeconds write setUseSeconds default True; property Time : longint read FTime write setTime default 0; end;
procedure Register;
implementation
constructor TTimeEdit.Create(AOwner : TComponent); begin inherited; FTime := 0; FUseSeconds := True; AutoSelect := False; EditMask := '00:00:00;1;0'; EditText := '00:00:00'; end;
procedure TTimeEdit.KeyPress(var Key : Char); var s : string; begin s := EditText; case selStart of 0 : if (key in ['3'..'9']) then key := #0; 1 : if (s[1] = '2') and (key in ['4'..'9']) then key := #0; 3 : if (key in ['6'..'9']) then key := #0; 6 : if (key in ['6'..'9']) then key := #0; end; if (selStart = 0) and (key = '2') and (s[2] in ['4'..'9']) then begin s[2] := '3'; EditText := s; end; inherited; end;
procedure TTimeEdit.Change; var h,m,s : integer; begin h := strToInt(editText[1] + editText[2]); m := strToInt(editText[4] + editText[5]); s := strToInt(editText[7] + editText[8]); FTime := h * 3600 + m * 60 + s; inherited; end;
procedure TTimeEdit.setUseSeconds(aUseSeconds : boolean); begin FUseSeconds := aUseSeconds; if aUseSeconds then EditMask := '00:00:00;1;0' else EditMask := '00:00;1;0'; EditText := getTimeStr; end;
function TTimeEdit.GetTimeStr : string; var h, m, s : byte; begin h := FTime div 3600; m := (FTime div 60) mod 60; s := FTime mod 60; if fUseSeconds then result := format('%.2d:%.2d:%.2d', [h,m,s]) else result := format('%.2d:%.2d', [h,m]); end;
procedure TTimeEdit.setTime(aTime : longint); begin FTime := aTime; EditText := getTimeStr; end;
procedure Register; begin RegisterComponents('fgTime', [TTimeEdit]); end;
end. |
Wäre nett, wenn ein paar Leute das mal testen könnten ...
In der Zwischenzeit mache ich mir mal Gedanken, wie man die Begrenzungen am Besten realisieren könnte ...
|
|
Tom.Schröder
      
Beiträge: 33
|
Verfasst: Fr 17.09.04 10:57
Klappt soweit sogut, hab es auch für mich modifiziert, dass Format 'HH:MM' ist!
Und zur Begrenzung:
Du verwendest in der case abfrage konstanten zu prüfen ob die eingabe gültig ist.
verpass der klasse noch zwei properties TDateTim LeftTimeBoarder und RightTimeBoarder oder ähnliches (welche von beginn an per default als unbeschränkt sind)
sind nun grenzen gewünscht, wie z.B. ladenöffnungszeiten, werden die grenzen mit den entsprechenden zeiten belegt.
die case abfrage dann so modifizieren, dass die gültigkeitsprüfung die gewünschten zeiten beachtet!
|
|
midan23 
      
Beiträge: 48
Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
|
Verfasst: Fr 17.09.04 12:28
Tom.Schröder hat folgendes geschrieben: | Klappt soweit sogut, hab es auch für mich modifiziert, dass Format 'HH:MM' ist! |
Setz doch im OI die Eigenschaft UseSeconds auf false ...
Zitat: |
Und zur Begrenzung:
Du verwendest in der case abfrage konstanten zu prüfen ob die eingabe gültig ist.
verpass der klasse noch zwei properties TDateTim LeftTimeBoarder und RightTimeBoarder oder ähnliches (welche von beginn an per default als unbeschränkt sind)
|
So etwas in der Art hatte ich auch vor, allerdings ohne TDateTime ... eher mit LongInt
EDIT :
Ich glaube, das Strings eher geeignet sind ... ich experimentiere mal mit meiner Idee ...
|
|
Tom.Schröder
      
Beiträge: 33
|
Verfasst: Fr 17.09.04 13:03
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:
| procedure TTimeEdit.KeyPress(var Key : Char); var s : string; begin s := EditText; case selStart of 0 : if (key in ['3'..'9']) then begin key := #0; beep; end; 1 : if (s[1] = '2') and (key in ['4'..'9']) then begin key := #0; beep; end; 3 : if (key in ['6'..'9']) then begin key := #0; beep; end; end; if (selStart = 0) and (key = '2') and (s[2] in ['4'..'9']) then begin s[2] := '3'; EditText := s; end; inherited; end; |
Des weiteren habe ich noch zusätzliche 'beeps' eingeführt aus folgendem Grund:
Das Feld akzeptiert nur Numerische Zeichen! Gibt man ein anderes Zeichen ein peept der Rechner. Gibt man aber eine ungültige Zeit ein, beepts nicht!
Also die Änderung bewirkt nur, dass es bei jeder Fehleingabe beept
Edit: Mir ist auch ein Bug aufgefallen!
In der Maske soll '0' für leerzeichen stehen!
gibt man 10:10 ein, werden die eingetragenen als leerzeichen interpretiert, somit die ausgelesene uhrzeit auf 1:1 gesetzt
Moderiert von Christian S.: Code- durch Delphi-Tags ersetzt.
|
|
midan23 
      
Beiträge: 48
Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
|
Verfasst: Fr 17.09.04 15:25
Kann ich irgendwie nicht nachvollziehen ...
Wenn ich 10:10 eingebe, liefert mir die Funktion "getTimeStr" auch genau das : 10:10
Zeig mal Code, in dem der Fehler auftritt ...
|
|
Tom.Schröder
      
Beiträge: 33
|
Verfasst: Mo 20.09.04 10:03
Habe Code gerade nicht zur Hand, werd ich wenn ich kann nachträglich editieren...
ich habe nicht getTimeString verwendet, sondern (sinngemäß)
Delphi-Quelltext 1: 2:
| timeString := Form1.TimeEdit1.text; time := StrToTime(timeString); |
und da wird die leerzeichen null wohl rausgefiltert
Moderiert von Christian S.: Code- durch Delphi-Tags ersetzt.
|
|
midan23 
      
Beiträge: 48
Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
|
Verfasst: Mo 20.09.04 12:32
Ist eine Eigenart von TCustomMask ... ich glaube, das liegt an der Definition der Eingabemaske ...
Ausserdem hatte ich die Verwendung der Text-Eigenschaft nie wirklich vorgesehen ...
Eigentlich war es so gedacht :
Property Time(rw) : Anzahl Sekunden seit Mitternacht
Function getTimeStr : Hilfsfunktion, um den Wert der Time-Property in einen String umzuwandeln
Property UseSeconds(rw) : (Eigentlich selbsterklärend ...)
|
|
Tom.Schröder
      
Beiträge: 33
|
Verfasst: Mo 20.09.04 14:33
@Christian danke fürs umtaggen, kannte die delphi tags noch garnicht 
|
|
|