![]() |
Eigene Komponente für unvollständige Datumsangaben
Hallo zusammen,
da ich immer wieder in die Situation komme, unvollständige Datumsangaben in eine Form eingeben zu müssen, habe ich mich nun am Wochenende mal hingesetzt und meine erste eigene Komponente geschrieben (siehe unten). Dafür, finde ich, ist sie nicht schlecht. :oops: Allerdings stieß ich dabei auf einige Probleme, bei denen Ihr mir bestimmt weiterhelfen könnt: 1. In der Entwurfsansicht erhält das Panel immer automatisch eine Caption, obwohl ich diese im Constructor leere. Wieso kann ich das nicht unterbinden? 2. In der Entwurfsansicht lassen sich die drei Edit-Felder auf dem Panel verschieben. Wie kann man sowas verhindern? 3. Wenn ich die Komponente auf eine leere Form ziehe und dann das Projekt starte, kommt eine Fehlermelung 'Klasse TEdit nicht gefunden', obwohl im uses-Sektor der Komponete doch StdCtrls steht. Weiß jemand warum? 4. Wie sorge ich dafür, dass es trotz mehrere Komponenten mit jeweils eigenem Hint nur einmal ein Hinweis erscheint? Viele Grüße e-gon
Delphi-Quellcode:
unit DateEdit;
interface uses ExtCtrls, StdCtrls, Classes, DateUtils, SysUtils; type TDateFormatStyle = (fsDDMMYYYY, fsYYYYMMDD, fsMMDDYYYY); TFormatStyle = fsDDMMYYYY..fsMMDDYYYY; TCustomDateEdit = class(TCustomPanel) private FDate: Integer; FMinDate: Integer; FMaxDate: Integer; FFormatStyle: TFormatStyle; FFourDigit: Boolean; FAutoExpansionYear: Boolean; FEnabled: Boolean; dIndex: Byte; mIndex: Byte; yIndex: Byte; FEdit: Array [0..2] of TEdit; function CheckDate(const y,m,d: Word): Boolean; procedure SetDate(Value: Integer); procedure SetMinDate(Value: Integer); procedure SetMaxDate(Value: Integer); procedure SetFormatStyle(Value: TFormatStyle); procedure SetFourDigit(Value: Boolean); procedure SetAutoExpansionYear(Value: Boolean); protected procedure SetEnabled(Value: Boolean); override; procedure PanelExit(Sender: TObject); procedure FEditKeyPress(Sender: TObject; var Key: Char); procedure FEditExit(Sender: TObject); property Date: Integer read FDate write SetDate default 0; property MinDate: Integer read FMinDate write SetMinDate default 0; property MaxDate: Integer read FMaxDate write SetMaxDate default 0; property FormatStyle: TFormatStyle read FFormatStyle write SetFormatStyle default fsDDMMYYYY; property FourDigit: Boolean read FFourDigit write SetFourDigit default True; property AutoExpansionYear: Boolean read FAutoExpansionYear write SetAutoExpansionYear default False; property Enabled: Boolean read FEnabled write SetEnabled default True; // property Hint: Integer read FHint write SetHint default 0; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; TDateEdit = class(TCustomDateEdit) published property AutoExpansionYear; property Caption; property Color; property Date; property Enabled; property FormatStyle; property FourDigit; property Hint; property MinDate; property MaxDate; property ShowHint; property Visible; end; procedure Register; implementation uses Dialogs, Graphics, Controls, UUtils; procedure Register; begin RegisterComponents('Beispiele', [TDateEdit]); end; function TCustomDateEdit.CheckDate(const y,m,d: Word): Boolean; var dAllow: Integer; begin Result:= True; if Result and (m>12) then begin MessageDLG('Ungültige Monatsangabe!',mtError,[mbOk],0); FEdit[mIndex].SetFocus; Result:= False; end; if Result then begin if m=0 then dAllow:= 31 else dAllow:= DaysInAMonth(y,m); if d>dAllow then begin MessageDLG('Ungültiger Tag im Monat!',mtError,[mbOk],0); FEdit[dIndex].SetFocus; Result:= False; end; end; if Result and (y>0) and FFourDigit and (y<1000) then begin MessageDLG('Ungültige Jahresangabe! Da FourDigit gesetzt wurde, muss die Jahreszahl 4 Zeichen lang sein.',mtError,[mbOk],0); FEdit[yIndex].SetFocus; Result:= False; end; if Result and (y>0) and (y*10000+m*100+d<FMinDate) then begin MessageDLG('Das Datum ist kleiner als das angegebene Mindestdatum!',mtError,[mbOk],0); FEdit[yIndex].SetFocus; Result:= False; end; if Result and (FMaxDate>0) and (y*10000+m*100+d>FMaxDate) then begin MessageDLG('Das Datum ist größer als das angegebene Höchstdatum!',mtError,[mbOk],0); FEdit[yIndex].SetFocus; Result:= False; end; end; constructor TCustomDateEdit.Create(AOwner: TComponent); var x: Integer; begin inherited Create(AOwner); Color:= clBtnFace; BevelOuter:= bvNone; Height:= 25; Constraints.MaxWidth:= Width; Constraints.MinWidth:= Width; Width:= 85; Constraints.MaxHeight:= Height; Constraints.MinHeight:= Height; UseDockManager:= True; OnExit:= PanelExit; for x:= 0 to Length(FEdit)-1 do begin FEdit[x]:= TEdit.Create(AOwner); FEdit[x].Parent:= Self; FEdit[x].Tag:= x; FEdit[x].Top:= 2; FEdit[x].Left:= 2+(x*24); FEdit[x].Width:= 21+(Trunc(x/2)*12); FEdit[x].MaxLength:= 2+(Trunc(x/2)*2); FEdit[x].OnKeyPress:= FEditKeyPress; FEdit[x].OnExit:= FEditExit; end; dIndex:= 0; mIndex:= 1; yIndex:= 2; Caption:= ''; end; destructor TCustomDateEdit.Destroy; var x: Integer; begin for x:= 0 to Length(FEdit)-1 do FEdit[x].Free; inherited Destroy; end; procedure TCustomDateEdit.FEditKeyPress(Sender: TObject; var Key: Char); var w: Word; begin w:= (Sender as TEdit).Tag; case Key of '0'..'9': begin if (Length(FEdit[w].Text)-FEdit[w].SelLength=FEdit[w].MaxLength-1) and (w<2) then FEdit[w+1].SetFocus; end; '.': begin if (FFormatStyle=fsDDMMYYYY) and (w<2) and (FEdit[w].Text<>'') then FEdit[w+1].SetFocus; Key:= #0; end; '-': begin if (FFormatStyle=fsYYYYMMDD) and (w<2) and (FEdit[w].Text<>'') then FEdit[w+1].SetFocus; Key:= #0; end; '/': begin if (FFormatStyle=fsMMDDYYYY) and (w<2) and (FEdit[w].Text<>'') then FEdit[w+1].SetFocus; Key:= #0; end; #8: begin if (FEdit[w].Text='') and (w>0) then begin FEdit[w-1].Text:= Copy(FEdit[w-1].Text,1,Length(FEdit[w-1].Text)-1); FEdit[w-1].SetFocus; FEdit[w-1].SelStart:= -1; Key:= #0; end; end; else Key:= #0; end; end; procedure TCustomDateEdit.FEditExit(Sender: TObject); var E: TEdit; i: Integer; begin E:= (Sender as TEdit); i:= StrToInt(E.Text); if FAutoExpansionYear and (E.Tag=yIndex) and (i>0) and (Length(E.Text)<3) then begin if i<50 then Inc(i,2000) else Inc(i,1900); E.Text:= IntToStr(i); end; end; procedure TCustomDateEdit.PanelExit(Sender: TObject); var d,m,y: Word; begin d:= StrToInt(FEdit[dIndex].Text); m:= StrToInt(FEdit[mIndex].Text); y:= StrToInt(FEdit[yIndex].Text); if CheckDate(y,m,d) then FDate:= d+m*100+y*10000; end; procedure TCustomDateEdit.SetDate(Value: Integer); var d,m,y: Word; i: Integer; begin y:= Value div 10000; i:= Value mod 10000; m:= i div 100; d:= i mod 100; FEdit[dIndex].Text:= FormatFloat('00',d); FEdit[mIndex].Text:= FormatFloat('00',m); FEdit[yIndex].Text:= IntToStr(y); if CheckDate(y,m,d) then FDate:= Value; end; procedure TCustomDateEdit.SetMinDate(Value: Integer); begin FMinDate:= Value; end; procedure TCustomDateEdit.SetMaxDate(Value: Integer); begin FMaxDate:= Value; end; procedure TCustomDateEdit.SetFormatStyle(Value: TFormatStyle); var y,m,d: string; i,Pix: Integer; IsYear: Boolean; begin if FFormatStyle<>Value then begin FFormatStyle:= Value; d:= FEdit[dIndex].Text; m:= FEdit[mIndex].Text; y:= FEdit[yIndex].Text; if FFormatStyle=fsDDMMYYYY then begin dIndex:= 0; mIndex:= 1; yIndex:= 2; end else if FFormatStyle=fsMMDDYYYY then begin dIndex:= 1; mIndex:= 0; yIndex:= 2; end else begin dIndex:= 2; mIndex:= 1; yIndex:= 0; end; Pix:= 2; for i:= 0 to 2 do begin IsYear:= i=yIndex; FEdit[i].Left:= Pix; FEdit[i].Width:= 21+(BoolToInt(IsYear)*12); FEdit[i].MaxLength:= 2+(BoolToInt(IsYear)*2); Inc(Pix,FEdit[i].Width+3); if i=dIndex then FEdit[i].Text:= d else if i=mIndex then FEdit[i].Text:= m else FEdit[i].Text:= y; end; end; end; procedure TCustomDateEdit.SetFourDigit(Value: Boolean); begin FFourDigit:= Value; end; procedure TCustomDateEdit.SetAutoExpansionYear(Value: Boolean); begin FAutoExpansionYear:= Value; end; procedure TCustomDateEdit.SetEnabled(Value: Boolean); var i: Integer; begin FEnabled:= Value; for i:= 0 to 2 do FEdit[i].Enabled:= Value; end; end. |
AW: Eigene Komponente für unvollständige Datumsangaben
Allgemein: Du solltest anstatt
Delphi-Quellcode:
FEdit[x]:= TEdit.Create(AOwner);
Delphi-Quellcode:
aufrufen und zusätzlich
FEdit[x]:= TEdit.Create(self);
Delphi-Quellcode:
aufrufen.
SetSubComponent(True)
Zu 1: Da wird wohl irgendwo beim setzen des Namens der Komponente die Caption (wenn zuvor leer oder gleich Name) gleich dem Namen gesetzt. Versuch mal
Delphi-Quellcode:
ShowCaption := False;
|
AW: Eigene Komponente für unvollständige Datumsangaben
Oder
Delphi-Quellcode:
Panel.ControlStyle := Panel.ControlStyle - [csSetCaption];
|
AW: Eigene Komponente für unvollständige Datumsangaben
Hallo,
danke für die schnellen Antworten! Mit
Delphi-Quellcode:
hat sich 3. erledigt. Dankeschön!
FEdit[x]:= TEdit.Create(Self);
Delphi-Quellcode:
bewirkt zwar dass die Edit-Felder in der Entwurfsansicht nicht mehr verzogen werden können, doch kann man die Felder auch zur Laufzeit nicht mehr beschreiben. Und auch nachdem ich die Zeile wieder auskommentiert habe komme ich nicht mehr in die Edit-Felder... :oops:
SetSubComponent(True)
Delphi-Quellcode:
lässt Caption nun leer. :thumb:
Panel.ControlStyle := Panel.ControlStyle - [csSetCaption];
Viele Grüße e-gon |
AW: Eigene Komponente für unvollständige Datumsangaben
Nachtrag:
Delphi-Quellcode:
bewirkt bei mir, dass ich nicht mehr in die Edit-Felder komme. Mit
FEdit[x]:= TEdit.Create(Self);
Delphi-Quellcode:
hingegen geht das... :gruebel:
FEdit[x]:= TEdit.Create(AOwner);
|
AW: Eigene Komponente für unvollständige Datumsangaben
Zitat:
Delphi-Quellcode:
oder
SetSubComponent(True)
Delphi-Quellcode:
aufgerufen?
FEdit[x].SetSubComponent(True)
Letzteres wäre richtig. |
AW: Eigene Komponente für unvollständige Datumsangaben
Habe mal deine Komponente dynamisch erstellt. Damit funktioniert folgender Code:
Delphi-Quellcode:
constructor TCustomDateEdit.Create(AOwner: TComponent);
var x: Integer; begin inherited Create(AOwner); Color:= clBtnFace; BevelOuter:= bvNone; Height:= 25; Constraints.MaxWidth:= Width; Constraints.MinWidth:= Width; Width:= 85; Constraints.MaxHeight:= Height; Constraints.MinHeight:= Height; UseDockManager:= True; OnExit:= PanelExit; for x:= 0 to Length(FEdit)-1 do begin FEdit[x]:= TEdit.Create(self); // <- self FEdit[x].Parent:= Self; FEdit[X].SetSubComponent(True); // <- SetSubComponent FEdit[x].Tag:= x; FEdit[x].Top:= 2; FEdit[x].Left:= 2+(x*24); FEdit[x].Width:= 21+(Trunc(x/2)*12); FEdit[x].MaxLength:= 2+(Trunc(x/2)*2); FEdit[x].OnKeyPress:= FEditKeyPress; FEdit[x].OnExit:= FEditExit; end; dIndex:= 0; mIndex:= 1; yIndex:= 2; Caption:= ''; end; |
AW: Eigene Komponente für unvollständige Datumsangaben
Hallo Olli73,
danke für Deine Bemühungen, aber irgendwie verhindert
Delphi-Quellcode:
dass ich zur Laufzeit dann noch auf die Edit-Felder zugreifen kann. Als wären die Felder disabled, was sie aber nicht sind... :gruebel:
FEdit[x]:= TEdit.Create(self);
Gruß e-gon |
AW: Eigene Komponente für unvollständige Datumsangaben
Funktioniert es bei dir auch, wenn du die Komponente dynamisch erstellst?
|
AW: Eigene Komponente für unvollständige Datumsangaben
Was ist unter 'dynamisch' zu verstehen? :oops:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz