| 
unit ListForm;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Contnrs;
type
  TForm1 = class(TForm)
    ButtonAdd: TButton;
    ButtonList: TButton;
    ListBox1: TListBox;
    ButtonWrong: TButton;
    btnListStack: TButton;
    btnQueue: TButton;
    procedure ButtonAddClick(Sender: TObject);
    procedure ButtonListClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ButtonWrongClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnListStackClick(Sender: TObject);
    procedure btnQueueClick(Sender: TObject);
  private
    ListDate: TObjectList;
    Stack: TStack;
    Queue: TQueue;
  public
    
  end;
var
  Form1: TForm1;
implementation
uses
  Dates;
procedure TForm1.ButtonAddClick(Sender: TObject);
begin
  ListDate.Add (TDate.Create (
    1900 + Random (200), 1 + Random (12), 1 + Random (30)));
end;
procedure TForm1.ButtonListClick(Sender: TObject);
var
  I: Integer;
begin
  ListBox1.Clear;
  for I := 0 to ListDate.Count - 1 do
    Listbox1.Items.Add ((TObject(ListDate [I]) as TDate).Text);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  Randomize;
  ListDate := TObjectList.Create (True);
  Stack := TStack.Create;
  Queue := TQueue.Create;
  for I := 1 to 10 do
  begin
    Stack.Push (Pointer (I));
    Queue.Push (Pointer (I));
  end;
end;
procedure TForm1.ButtonWrongClick(Sender: TObject);
begin
  
  ListDate.Add (Sender);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
  ListDate.Free;
  Stack.Free;
  Queue.Free;
end;
procedure TForm1.btnListStackClick(Sender: TObject);
var
  Stack2: TStack;
begin
  Stack2 := TStack.Create;
  ListBox1.Clear;
  
  while Stack.Count > 0 do
  begin
    ListBox1.Items.Add (IntToStr (Integer (Stack.Peek)));
    Stack2.Push (Stack.Pop);
  end;
  
  while Stack2.Count > 0 do
    Stack.Push (Stack2.Pop);
  ShowMessage ('Removed: ' + IntToStr (Integer (Stack.Pop)));
end;
procedure TForm1.btnQueueClick(Sender: TObject);
var
  I: Integer;
begin
  ListBox1.Clear;
  for I := 0 to Queue.Count - 1 do
  begin
    ListBox1.Items.Add (IntToStr (Integer (Queue.Peek)));
    Queue.Push (Queue.Pop);
  end;
  ShowMessage ('Removed: ' + IntToStr (Integer (Queue.Pop)));
end;
end.
 | 
| 
unit Dates;
interface
uses
  Classes, SysUtils;
type
  TDate = class (TComponent)
  private
    fDate: TDateTime;
    FOnChange: TNotifyEvent;
    function GetYear: Integer;
    function GetDay: Integer;
    function GetMonth: Integer;
    procedure SetDay(const Value: Integer);
    procedure SetMonth(const Value: Integer);
    procedure SetYear(const Value: Integer);
  protected
    procedure DoChange; virtual;
  public
    constructor Create (AOwner: TComponent); overload; override;
    constructor Create (y, m, d: Integer); reintroduce; overload;
    procedure SetValue (y, m, d: Integer); overload;
    procedure SetValue (NewDate: TDateTime); overload;
    function LeapYear: Boolean;
    procedure Increase (NumberOfDays: Integer = 1);
    procedure Decrease (NumberOfDays: Integer = 1);
    function GetText: string; virtual;
    property Text: string read GetText;
  published
    property Day: Integer read GetDay write SetDay;
    property Month: Integer read GetMonth write SetMonth;
    property Year: Integer read GetYear write SetYear;
    property OnChange: TNotifyEvent
      read FonChange write FOnChange;
  end;
  
  EDateOutOfRange = class (Exception)
  end;
procedure Register;
implementation
procedure TDate.SetValue (y, m, d: Integer);
begin
  fDate := EncodeDate (y, m, d);
  
  DoChange;
end;
function TDate.LeapYear: Boolean;
begin
  
  if (GetYear mod 4 <> 0) then
    LeapYear := False
  else if (GetYear mod 100 <> 0) then
    LeapYear := True
  else if (GetYear mod 400 <> 0) then
    LeapYear := False
  else
    LeapYear := True;
end;
procedure TDate.Increase (NumberOfDays: Integer = 1);
begin
  fDate := fDate + NumberOfDays;
  
  DoChange;
end;
function TDate.GetText: string;
begin
  GetText := DateToStr (fDate);
end;
procedure TDate.Decrease (NumberOfDays: Integer = 1);
begin
  fDate := fDate - NumberOfDays;
  
  DoChange;
end;
constructor TDate.Create (y, m, d: Integer);
begin
  fDate := EncodeDate (y, m, d);
end;
constructor TDate.Create (AOwner: TComponent);
begin
  inherited Create (AOwner);
  
  fDate := Date;
end;
function TDate.GetYear: Integer;
var
  y, m, d: Word;
begin
  DecodeDate (fDate, y, m, d);
  Result := y;
end;
procedure TDate.SetValue(NewDate: TDateTime);
begin
  fDate := NewDate;
  
  DoChange;
end;
function TDate.GetDay: Integer;
var
  y, m, d: Word;
begin
  DecodeDate (fDate, y, m, d);
  Result := d;
end;
function TDate.GetMonth: Integer;
var
  y, m, d: Word;
begin
  DecodeDate (fDate, y, m, d);
  Result := m;
end;
procedure TDate.SetDay(const Value: Integer);
begin
  if (Value < 0) or (Value > 31) then
    raise EDateOutOfRange.Create ('Invalid month');
  SetValue (Year, Month, Value);
end;
procedure TDate.SetMonth(const Value: Integer);
begin
  if (Value < 0) or (Value > 12) then
    raise EDateOutOfRange.Create ('Invalid month');
  SetValue (Year, Value, Day);
end;
procedure TDate.SetYear(const Value: Integer);
begin
  SetValue (Value, Month, Day);
end;
procedure TDate.DoChange;
begin
  if Assigned (FOnChange) then
    FOnChange (Self);
end;
procedure Register;
begin
  RegisterComponents ('Md5', [TDate]);
end;
end.
 |