AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Kalender

Ein Thema von Alter Mann · begonnen am 10. Jun 2007 · letzter Beitrag vom 28. Jun 2007
Antwort Antwort
Seite 1 von 2  1 2      
Alter Mann
Registriert seit: 15. Nov 2003
Hallo,

habe gerade einen kleinen Kalender fertig gestellt und stelle in hiermit zur Verfügung!

Ich habe bisher keinerlei Anpassungen bzg. anderer Delphiversionen vorgenommen, so wie es ist
läuft es unter D7 (wegen DateUtils), sollte aber mit ein paar Anpassungen auch unter andernen
Versionen laufen.

Der Kalender hat (leider) ein paar Bugs die sich leider nicht so einfach finden lassen und
weil das so ist, ist er auch Open-Source.

Die einzigste Bedingung die ich habe, ist das alle Änderungen hier veröffentlich werden.

Gruss

Alter Mann

[Edit]
Ups...

Jetzt sind alle Dateien bei. [Edit] Plus Beispiel inkl. aller Dateien für Delphi 7.[/Edit]
[/Edit]

PS Kleine Anmerkung sei noch gestattet:

Das Beispiel zeigt ungefähr wo es hingehen soll, vielleicht noch DB-Anbindung.

Was mich da ein wenig verwundert ist die Darstellung zur Desginzeit und zur Laufzeit bzw.
die unterschiedliche Darstellung zwischen Componenten auf Form plaziert und zur Laufzeit
erstellt(siehe Calendar.zip), genauso im Beispiel.
 
Benutzerbild von DeddyH
DeddyH

 
Delphi 11 Alexandria
 
#2
  Alt 10. Jun 2007, 17:17
Ööhhhmmm.... da fehlt aber die Unit uCalendar im Archiv
Detlef
  Mit Zitat antworten Zitat
BFI2007
 
#3
  Alt 15. Jun 2007, 11:17
echt ey
  Mit Zitat antworten Zitat
Alter Mann

 
Delphi 10.2 Tokyo Professional
 
#4
  Alt 19. Jun 2007, 17:56
Hallo


Ich habe mir nartürlich Gedanken gemacht und den ganzen Code neugeschrieben.
Es sind soweit alle 'irrsinnigen' Bugs rausgeflogen und 'andere?' dafür reingekommen.

Die jeniegen die sich den alten Code angetan haben, meine Bewunderung und Entschuldigung.

Für alle Intressierten:

Es fehlt noch die DB-Anbindung und Multiselect.

Aber vielleicht ist ja der/die Eine oder Andere so Hilfsbereit und stellt
die entsprechende Ableitung zur Verfügung.

Viele Grüsse

Alter Mann
  Mit Zitat antworten Zitat
Alter Mann

 
Delphi 10.2 Tokyo Professional
 
#5
  Alt 20. Jun 2007, 19:09
Hi,

auch wenn es scheinbar keiner Braucht, hier die DB-Anbindung.
Doch zuerst müssen wir die Kalender-Componente aktuallisieren:

Delphi-Quellcode:
  TCalendarControl = class(TCustomControl)
  private
  ...
    FDates : Array of TDateTime;
    FMaxRecords : Integer;
  ...
  protected
  ...
    procedure DataChange(Sender: TObject); virtual;
    function DateInArray(aDate : TDateTime) : Boolean;
  ...
  end;

...

constructor TCalendarControl.Create(aOwner : TComponent);
begin
  ...
  SetLength(FDates, 31);
  FMaxRecords := -1;
  ...
end;

...

procedure TCalendarControl.DataChange(Sender: TObject);
begin
end;

function TCalendarControl.DateInArray(aDate : TDateTime) : Boolean;
var
  I : Integer;
begin
  Result := False;
  for I := Low(FDates) to High(FDates) do
   if FDates[I] = aDate then
   begin
     Result := True;
     Break;
   end;
end;

...

procedure TCalendarControl.DoDateChange(aOldDate, aNewDate : TDateTime);
begin
  SetLength(FDates, 0);
  SetLength(FDates, 31);
  FMaxRecords := -1;
  DataChange(Self);
  if Assigned(FOnDateChange) then FOnDateChange(Self, aOldDate, aNewDate);
end;

...

procedure TCalendarControl.Paint;
   ...
          if DateInArray(CE.EntryDate) then Font.Style := Font.Style + [fsBold]
                                       else Font.Style := Font.Style - [fsBold];
          if FOptions.TrailingDays then
   ...
end;
Delphi-Quellcode:
  TDBCalendarControl = class(TCalendarControl)
  private
    FDataLink : TFieldDataLink;
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
  protected
    procedure DataChange(Sender: TObject); override;
    function IsDateTimeField : Boolean;
    procedure Loaded; override;
    procedure LoadDatesForMonth;
    procedure Notification(aComponent: TComponent;
                           Operation: TOperation); override;
  public
    constructor Create(aOwner: TComponent); override;
    destructor Destroy; override;
    property Field: TField read GetField;
    property DataField: string read GetDataField write SetDataField;
    property DataSource: TDataSource read GetDataSource write SetDataSource;
  end;

...

{
************  TDBCalendarControl
}


(* public *)

constructor TDBCalendarControl.Create(aOwner: TComponent);
begin
  inherited Create(aOwner);
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
end;

destructor TDBCalendarControl.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;


(* private *)


procedure TDBCalendarControl.DataChange(Sender: TObject);
begin
  if (FDataLink.Field <> nil) and not FDataLink.DataSourceFixed then
  begin
    if FMaxRecords <> FDataLink.DataSet.RecordCount - 1 then
    begin
      FMaxRecords := FDataLink.DataSet.RecordCount - 1;
      FDataLink.DataSourceFixed := True;
      LoadDatesForMonth;
    end;
  end;
end;

function TDBCalendarControl.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

function TDBCalendarControl.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

function TDBCalendarControl.GetField: TField;
begin
  Result := FDataLink.Field;
end;

procedure TDBCalendarControl.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

procedure TDBCalendarControl.SetDataSource(Value: TDataSource);
begin
  if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
    FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

procedure TDBCalendarControl.CMGetDataLink(var Message: TMessage);
begin
  Message.Result := Integer(FDataLink);
end;


(* protected *)

function TDBCalendarControl.IsDateTimeField : Boolean;
begin
  with FDataLink do
    Result := (Field <> nil) and (Field.DataType in [ftDateTime, ftTimeStamp]);
end;

procedure TDBCalendarControl.LoadDatesForMonth;
var
  I : Integer;
  DT : TDateTime;
  Y1, Y2, M1, M2, D1, D2 : Word;
begin
  FDataLink.DataSet.First;
  for I := 0 to FDataLink.DataSet.RecordCount - 1 do
  begin
    if IsDateTimeField then
      DT := Trunc(FDataLink.Field.AsDateTime)
    else
      DT := Trunc(FDataLink.Field.AsDateTime);

    DecodeDate(DT, Y1, M1, D1);
    DecodeDate(FDate, Y2, M2, D2);
    if (Y1 = Y2) and (M1 = M2) then FDates[D1] := DT;
    FDataLink.DataSet.Next;
  end;
  Invalidate;
  FDataLink.DataSourceFixed := False;
end;

procedure TDBCalendarControl.Loaded;
begin
  inherited Loaded;
  if (csDesigning in ComponentState) then DataChange(Self);
end;

procedure TDBCalendarControl.Notification(aComponent: TComponent;
                                            Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;
Um die Sache Rund zu machen fehlt noch dies:

Delphi-Quellcode:

  TExDBCalendar = class(TDBCalendarControl)
  published
    property CalendarDate;
    property Colors;
    property DataField;
    property DataSource;
    property Font;
    property Options;
    property OnDayClick;
    property OnDateChange;
  end;
Das war es.


Gruss
  Mit Zitat antworten Zitat
marabu
 
#6
  Alt 20. Jun 2007, 19:44
Hallo Alter Mann,

dass ein solches Control niemand braucht möchte ich nicht unterschreiben. Jedenfalls finde ich es nett von dir, dass du deine Komponente hier zur Verfügung stellst.

Beim Drüberschauen stellt sich mir die Frage, ob nicht ein Bookmark die Methode LoadDatesFromMonth() aufwerten würde. Immerhin verschiebst du den Datensatzzeiger. Dann sehe ich eine bedingte Zuweisung an DT, bei der beide Zweige gleich lauten, sodass die Bedingung eigentlich ungeprüft entfallen kann.

Für einen produktiven Einsatz würde ich eine lose Kopplung zwischen Control und Datenbank vorziehen. Hast du dir mal die Komponente TMonthCalendar und dort speziell das Ereignis OnGetMonthInfo() angeschaut?

Freundliche Grüße
  Mit Zitat antworten Zitat
Alter Mann

 
Delphi 10.2 Tokyo Professional
 
#7
  Alt 20. Jun 2007, 19:49
Hi marabu,

TMonthCalendar habe ich mir schon angeschaut, allerdings nicht OnGetMonthInfo, was ich nachholen werde.
Das mit DT ist mir auch klar, habe aber noch keine bessere Idee.

Mitarbeit erwünscht.

Bis bald und Danke.

Gruss

Alter Mann
  Mit Zitat antworten Zitat
Alter Mann

 
Delphi 10.2 Tokyo Professional
 
#8
  Alt 20. Jun 2007, 20:02
Hi marabu,

manchmal bin auch ich schnell(beim drüberlesen)

Klar PMonthDayState würde die Sache auch machen, aber die Compo auch 'aufblähen'.
Man muss auf OnGetMonthInfo reagieren und die Sache in Paint doch wieder umsetzen.
Es sei denn, es gibt Handfeste Argumente, die dagegen Sprechen.

MfG

Alter Mann
  Mit Zitat antworten Zitat
marabu
 
#9
  Alt 20. Jun 2007, 20:13
Mir gefällt die Entkopplung von Funktionalitäten, wie sie über OnGetMonthInfo() möglich wird.

Zu der Typprüfung: Ich würde einfach eine Exception werfen, wenn sich der Feldtyp beim ersten Zugriff als falsch herausstellt. Die Prüfung sollte auf keinen Fall innerhalb einer Schleife über potentiell Tausenden von Datensätzen statt finden.

Statt DataSet.First() bietet sich vielleicht DataSet.Locate() an. So könntest du in einer riesigen Tabelle Laufzeitvorteile gewinnen. Und nicht das Bookmarking vergessen.

Gute Nacht
  Mit Zitat antworten Zitat
Alter Mann

 
Delphi 10.2 Tokyo Professional
 
#10
  Alt 20. Jun 2007, 20:18
Hi marabu,

wie würde das Aussehen?
Zitat:
Statt DataSet.First() bietet sich vielleicht DataSet.Locate() an. So könntest du in einer riesigen Tabelle Laufzeitvorteile gewinnen. Und nicht das Bookmarking vergessen.
Gruss

Alter Mann

PS Entschuldigung wenn ich Dich von einer anderen 'wichtigeren' Sache abhalte.

Gute Nacht
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:03 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