Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Eigene Komponente für unvollständige Datumsangaben (https://www.delphipraxis.net/192729-eigene-komponente-fuer-unvollstaendige-datumsangaben.html)

e-gon 15. Mai 2017 08:54

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.

Olli73 15. Mai 2017 11:14

AW: Eigene Komponente für unvollständige Datumsangaben
 
Allgemein: Du solltest anstatt
Delphi-Quellcode:
FEdit[x]:= TEdit.Create(AOwner);
Delphi-Quellcode:
FEdit[x]:= TEdit.Create(self);
aufrufen und zusätzlich
Delphi-Quellcode:
SetSubComponent(True)
aufrufen.

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;

DeddyH 15. Mai 2017 12:05

AW: Eigene Komponente für unvollständige Datumsangaben
 
Oder
Delphi-Quellcode:
Panel.ControlStyle := Panel.ControlStyle - [csSetCaption];

e-gon 15. Mai 2017 12:18

AW: Eigene Komponente für unvollständige Datumsangaben
 
Hallo,

danke für die schnellen Antworten!

Mit
Delphi-Quellcode:
FEdit[x]:= TEdit.Create(Self);
hat sich 3. erledigt. Dankeschön!

Delphi-Quellcode:
SetSubComponent(True)
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:

Delphi-Quellcode:
Panel.ControlStyle := Panel.ControlStyle - [csSetCaption];
lässt Caption nun leer. :thumb:

Viele Grüße
e-gon

e-gon 15. Mai 2017 12:28

AW: Eigene Komponente für unvollständige Datumsangaben
 
Nachtrag:

Delphi-Quellcode:
FEdit[x]:= TEdit.Create(Self);
bewirkt bei mir, dass ich nicht mehr in die Edit-Felder komme. Mit
Delphi-Quellcode:
FEdit[x]:= TEdit.Create(AOwner);
hingegen geht das... :gruebel:

Olli73 15. Mai 2017 12:39

AW: Eigene Komponente für unvollständige Datumsangaben
 
Zitat:

Zitat von e-gon (Beitrag 1371466)
Delphi-Quellcode:
SetSubComponent(True)

Hast du nur
Delphi-Quellcode:
SetSubComponent(True)
oder
Delphi-Quellcode:
FEdit[x].SetSubComponent(True)
aufgerufen?

Letzteres wäre richtig.

Olli73 15. Mai 2017 12:55

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;

e-gon 15. Mai 2017 13:09

AW: Eigene Komponente für unvollständige Datumsangaben
 
Hallo Olli73,

danke für Deine Bemühungen, aber irgendwie verhindert
Delphi-Quellcode:
FEdit[x]:= TEdit.Create(self);
dass ich zur Laufzeit dann noch auf die Edit-Felder zugreifen kann. Als wären die Felder disabled, was sie aber nicht sind... :gruebel:

Gruß
e-gon

Olli73 15. Mai 2017 13:33

AW: Eigene Komponente für unvollständige Datumsangaben
 
Funktioniert es bei dir auch, wenn du die Komponente dynamisch erstellst?

e-gon 15. Mai 2017 14:22

AW: Eigene Komponente für unvollständige Datumsangaben
 
Was ist unter 'dynamisch' zu verstehen? :oops:

hoika 15. Mai 2017 14:32

AW: Eigene Komponente für unvollständige Datumsangaben
 
Hallo,

Zitat:

dass ich zur Laufzeit dann noch auf die Edit-Felder zugreifen kann
Wie versuchst du denn, darauf zuzugreifen (kleines Code-Stück)?

OK, erledigt: Wer lesen kann ...

Olli73 15. Mai 2017 14:49

AW: Eigene Komponente für unvollständige Datumsangaben
 
Ich habe deine Komponente einfach dynamisch/selbst erzeugt und es funktioniert bei mir:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  With TCustomDateEdit.Create(self) do begin
    Parent := Self;
  end;
end;
Ich habe aber keine echte Komponente draus gemacht.

hoika 15. Mai 2017 15:08

AW: Eigene Komponente für unvollständige Datumsangaben
 
Hallo,

Zitat:

auch nachdem ich die Zeile wieder auskommentiert habe komme ich nicht mehr in die Edit-Felder...
Deinstalliere/Installiere die Komponente nach der Änderung noch einmal.

e-gon 16. Mai 2017 07:41

AW: Eigene Komponente für unvollständige Datumsangaben
 
Moin!

Danke für die Antworten.

@Olli73: Dynamisch funktioniert es bei mir auch problemlos. Nur wenn ich die Komponente erstelle sind die Edit-Felder nicht mehr anklickbar.

@hoika: Deinstallieren und erneut installieren hat leider auch nicht geholfen.

Ich habe es auch mal mit InsertComponent versucht. Aber das wollte auch nicht so wie ich wollte.
Kann es vielleicht daran liegen, dass man ein Panel nicht anklicken kann und man deshalb die Edit-Felder darauf nicht erreicht?

Viele Grüße
e-gon

I3estii 16. Mai 2017 07:56

AW: Eigene Komponente für unvollständige Datumsangaben
 
Zu 2. schon mit Align left/right versucht?

Zu 3. die Uses auch in die Unit des Projektes einbinden

e-gon 16. Mai 2017 08:47

AW: Eigene Komponente für unvollständige Datumsangaben
 
Hallo I3estii,

danke für die Antwort.

Zu 2. Align würde die Sache tatsächlich verhindern, allerdings müsste ich dann auf das Panel als sichtbaren "Rahmen" verzichten und die Edit-Felder wären direkt nebeneinander angeordnet.

Zu 3. Natürlich könnte man einfach die Unit in Uses des Projekts einbinden. Aber ist das eher unschön. Bei anderen Komponenten muss man sowas ja auch nicht tun.

Durch
Delphi-Quellcode:
FEdit[x]:= TEdit.Create(self);
sind die beiden Probleme eigentlich auch schon gelöst. Nur das dadurch ein neues Problem auftrat...

Gruß
e-gon

nahpets 16. Mai 2017 09:44

AW: Eigene Komponente für unvollständige Datumsangaben
 
Anstelle eines TPanel ein TFrame nehmen?
Das ist doch eigentlich dazu da, um mehrere Komponenten "zu sammeln" und so in gekapselter Form zu verwenden.

Olli73 16. Mai 2017 11:28

AW: Eigene Komponente für unvollständige Datumsangaben
 
Schau mal ob deine Komponente auf Enabled := True steht!

e-gon 16. Mai 2017 11:56

AW: Eigene Komponente für unvollständige Datumsangaben
 
Ja, Enable steht bei allen Komponenten auf True.

Und ja, TFrame wäre eine Alternative...

Olli73 16. Mai 2017 12:04

AW: Eigene Komponente für unvollständige Datumsangaben
 
Zitat:

Zitat von e-gon (Beitrag 1371586)
Ja, Enable steht bei allen Komponenten auf True.

Also bei mir lag es am Enabled. Das hier funktioniert bei mir:

Delphi-Quellcode:
unit DateEdit;

interface

  uses
    VCL.ExtCtrls, VCL.StdCtrls, Classes, DateUtils, SysUtils, VCL.Controls, VCL.Forms;

  type
    TDateFormatStyle = (fsDDMMYYYY, fsYYYYMMDD, fsMMDDYYYY);
    TFormatStyle = fsDDMMYYYY..fsMMDDYYYY;

    TCustomDateEdit = class(TPanel)
    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);
      function BoolToInt(B: Boolean): Integer;
    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;
    published
    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
    VCL.Dialogs, VCL.Graphics;

  procedure Register;
  begin
    RegisterComponents('Test', [TDateEdit]);
  end;


  function TCustomDateEdit.BoolToInt(B: Boolean): Integer;
begin
  if B then
    result := 1
  else
    result := 0;
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;


    //Self.Enabled := True;

    ControlStyle := ControlStyle - [csSetCaption]; // <- kein Text

    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:= '';
    Enabled := True;  // <- Enabled
  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.

e-gon 16. Mai 2017 12:19

AW: Eigene Komponente für unvollständige Datumsangaben
 
Es TUT!!!!

Ich hatte nur die Edit-Felder auf Enabled geprüft, nicht das Panel selbst. Außerdem habe ich gesehen, dass Du TCustomPanel durch TPanel ersetzt hast. Jetzt geht es! Danke! :thumb:

Gruß
e-gon

Olli73 16. Mai 2017 12:21

AW: Eigene Komponente für unvollständige Datumsangaben
 
Zitat:

Zitat von e-gon (Beitrag 1371593)
Es TUT!!!!
Außerdem habe ich gesehen, dass Du TCustomPanel durch TPanel ersetzt hast. Jetzt geht es! Danke! :thumb:

Das war eigentlich nur ein Test. Sollte auch mit TCustomPanel gehen ?!


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:29 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz