Autor Beitrag
midan23
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 48

Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
BeitragVerfasst: 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 ... :oops:

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 48

Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 154



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 48

Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
BeitragVerfasst: Di 31.08.04 09:01 
Etwa so :
ausblenden 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 = 0and (key = '2'and (s[2in ['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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 48

Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
BeitragVerfasst: Do 16.09.04 15:52 
Hier erst mal der Code :
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:
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 = 0and (key = '2'and (s[2in ['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 60mod 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 48

Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Fr 17.09.04 13:03 
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:
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 = 0and (key = '2'and (s[2in ['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 user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.
midan23 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 48

Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: 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äß)

ausblenden Delphi-Quelltext
1:
2:
timeString := Form1.TimeEdit1.text;
time := StrToTime(timeString);


und da wird die leerzeichen null wohl rausgefiltert

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.
midan23 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 48

Win XP, Mac OS X, Linux
D6 Pers, XCode 2.1, Python
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33



BeitragVerfasst: Mo 20.09.04 14:33 
@Christian danke fürs umtaggen, kannte die delphi tags noch garnicht :roll: