TGridPanelでカレンダー表示 ~Delphiソースコード集
TGridPanelを使うとコンポーネントをグリッド上に並べて配置することが出来ます。
これを利用してカレンダー表示を行ってみます。
TGridPanel.RowCollection.BeginUpdate(); ~ TGridPanel.RowCollection.EndUpdate();
TGridPanel.ColumnCollection.BeginUpdate(); ~ TGridPanel.ColumnCollection.EndUpdate();
が非常に重要となります。
プロジェクトの作成と画面設計
Delphiを起動し、メニューから「ファイル」⇒「新規作成」⇒
「Windows VCLアプリケーション -Delphi(W)」をクリックしてプロジェクトを作成します。
「TPanel」と「TGridPanel」をフォームにドラッグ&ドロップします。
Panel1の上に「TComboBox」を2個ドラッグ&ドロップします。

ソースコードの記述
「コード」モードに切り替えて(F12を押す)、以下ソースコードをドラッグ&ドロップして貼り付けます。
「デザイン」モードに切り替えて(F12を押す)、左下ペインの「オブジェクト インスペクタ」を「イベント」タブに切り替えて以下の設定を行います。
- Form1.OnCreate に FormCreate を設定します。
- ComboBox1.OnChange に ComboBox1Change を設定します。
- ComboBox2.OnChange に ComboBox1Change を設定します。
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, DateUtils, Vcl.Buttons; type TForm1 = class(TForm) GridPanel1: TGridPanel; Panel1: TPanel; ComboBox1: TComboBox; ComboBox2: TComboBox; procedure FormCreate(Sender: TObject); procedure ComboBox1Change(Sender: TObject); private { Private 宣言 } procedure CreateCalendar(GPanel:TGridPanel; y,m:Integer); procedure SpeedButtonClick(Sender:TObject); public { Public 宣言 } end; var Form1: TForm1; const Weeks:array[0..6] of String= ('日','月','火','水','木','金','土'); implementation {$R *.dfm} procedure TForm1.SpeedButtonClick(Sender: TObject); var d:TDateTime; begin if Sender is TSpeedButton then begin d:=TDateTime(TSpeedButton(Sender).Tag); ShowMessage(FormatDateTime('yyyy/mm/dd',d)); end; end; procedure TForm1.ComboBox1Change(Sender: TObject); begin CreateCalendar( GridPanel1, StrToInt(ComboBox1.Items[ComboBox1.ItemIndex]), StrToInt(ComboBox2.Items[ComboBox2.ItemIndex]) ); end; procedure TForm1.CreateCalendar(GPanel:TGridPanel; y,m:Integer); var StartDate, EndDate, PreviousDate, NextDate, GPDate:TDateTime; SButton:TSpeedButton; Lbl:TLabel; ColumnItem:TColumnItem; RowItem:TRowItem; DayCount, RowCount, Row,Col:Integer; begin //グリッドパネル上のコントロールを破棄 while GPanel.ControlCount>0 do GPanel.Controls[0].Free; //年月の最初の日 StartDate:=EncodeDate(y,m,1); //年月の最後の日 EndDate:=EndOfAMonth(y,m); //カレンダーには日曜日から表示するので前月日付 PreviousDate:=StartDate-(DayOfTheWeek(StartDate) Mod 7); //カレンダーには土曜日まで表示するので次月日付 NextDate:=EndOfAMonth(y,m)+(6-(DayOfTheWeek(EndDate) mod 7)); //グリッドパネル上に表示する総日数 DayCount:=trunc(NextDate-PreviousDate+1); //行数(上部に曜日を表示するので+1する) RowCount:=DayCount div 7 + 1; //グリッドパネルのグリッドをクリア GPanel.ColumnCollection.Clear; GPanel.RowCollection.Clear; //グリッドパネルに行を追加 GPanel.RowCollection.BeginUpdate(); for Row := 0 to RowCount-1 do begin RowItem:=GPanel.RowCollection.Add(); RowItem.SizeStyle:=TSizeStyle.ssPercent; RowItem.Value:=100/RowCount; end; GPanel.RowCollection.EndUpdate(); //グリッドパネルに列を追加 GPanel.ColumnCollection.BeginUpdate(); for Col := 0 to 6 do begin ColumnItem:=GPanel.ColumnCollection.Add(); ColumnItem.SizeStyle:=TSizeStyle.ssPercent; ColumnItem.Value:=100/7; end; GPanel.ColumnCollection.EndUpdate(); //TLabelで曜日をグリッドに配置 for Col := 0 to 6 do begin Lbl:=TLabel.Create(GPanel); Lbl.Parent:=GPanel; Lbl.Align:=alClient; Lbl.Layout:=tlCenter; Lbl.Caption:=Weeks[Col]; Lbl.Alignment:=taCenter; Lbl.Font.Size:=12; if Col=0 then Lbl.Font.Color:=clRed; if Col=6 then Lbl.Font.Color:=clBlue; GPanel.ControlCollection.AddControl(Lbl, Col, 0); end; //TButtonで日付のボタンを配置 GPDate:=PreviousDate; for Row:=1 to RowCount-1 do begin for Col := 0 to 6 do begin SButton:=TSpeedButton.Create(GPanel); SButton.Parent:=GPanel; SButton.Align:=alClient; SButton.Caption:=FormatDateTime('d', GPDate); SButton.Tag:=Trunc(GPDate);//年月日を入れておく SButton.StyleElements:=[seBorder]; SButton.Font.Size:=12; SButton.OnClick:=SpeedButtonClick; SButton.Font.Color:=clBlack; if MonthOf(GPDate)<>m then SButton.Font.Color:=clGray; if GPDate=Date() then begin SButton.Font.Color:=clRed; SButton.Font.Style:=[TFontStyle.fsBold]; end; GPanel.ControlCollection.AddControl(SButton, Col, Row); GPDate:=GPDate+1; end; end; end; procedure TForm1.FormCreate(Sender: TObject); var y, m, i:Integer; begin Panel1.Align:=alTop; Panel1.Caption:=''; GridPanel1.Align:=alCLient; GridPanel1.Caption:=''; //現在の年月を取得 y:=YearOf(Date()); m:=MonthOf(Date()); //前後10年分の値を設定 ComboBox1.Clear; ComboBox1.Style:=csDropDownList; for i := y-10 to y+10 do begin ComboBox1.Items.Add(IntToStr(i)); if i=y then ComboBox1.ItemIndex:=ComboBox1.Items.Count-1; end; //月の設定 ComboBox2.Clear; ComboBox2.Style:=csDropDownList; for i := 1 to 12 do begin ComboBox2.Items.Add(IntToStr(i)); if i=m then ComboBox2.ItemIndex:=ComboBox2.Items.Count-1; end; //カレンダーを表示する CreateCalendar( GridPanel1, StrToInt(ComboBox1.Items[ComboBox1.ItemIndex]), StrToInt(ComboBox2.Items[ComboBox2.ItemIndex]) ); end; end.
実行する
メニューから「実行」⇒「実行」をクリックするとコンパイルと実行が行われ、カレンダーが表示されます。
ComboBox1の年やComboBox2の月を変更すると、カレンダーが切り替わります。
日付のボタンを押すと年月日がモーダルウィンドウで表示されます。
