年、月、日へのアクセス
日付の追跡 への移動
数値にエンコードされた日付はアプリケーションにはいいですが、人間が扱いたいのは年、月、日の方です。プロパティの作成により、エンコードされた日付のこれらの要素にアクセスできるようになります。
日付の各要素(年、月、日)は整数であり、また、それぞれを設定するには日付のエンコードが必要であるため、3 つのプロパティの実装メソッドを共通化することにより、いちいち同じコードを記述するのを避けることができます。つまり、要素を読み取るメソッドと要素を書き込むメソッドの 2 つのメソッドを記述し、それらのメソッドを使用して 3 つのプロパティの取得と設定を行うことができます。
設計時に年、月、日にアクセスできるようにするには:
- 3 つのプロパティを宣言し、それぞれに一意なインデックス番号を割り当てます。
Delphi:
type TSampleCalendar = class(TCustomGrid) public property Day: Integer index 3 read GetDateElement write SetDateElement; property Month: Integer index 2 read GetDateElement write SetDateElement; property Year: Integer index 1 read GetDateElement write SetDateElement; // …
C++:class PACKAGE TSampleCalendar : public TCustomGrid { // … public: __property int Day = {read=GetDateElement, write=SetDateElement, index=3, nodefault}; __property int Month = {read=GetDateElement, write=SetDateElement, index=2, nodefault}; __property int Year = {read=GetDateElement, write=SetDateElement, index=1, nodefault}; };
- 実装メソッドを宣言して記述し、インデックス値ごとに別の要素を設定します。
Delphi:
type TSampleCalendar = class(TCustomGrid) private function GetDateElement(Index: Integer): Integer; { note the Index parameter } procedure SetDateElement(Index: Integer; Value: Integer); // … function TSampleCalendar.GetDateElement(Index: Integer): Integer; var AYear, AMonth, ADay: Word; begin DecodeDate(FDate, AYear, AMonth, ADay); { break encoded date into elements } case Index of 1: Result := AYear; 2: Result := AMonth; 3: Result := ADay; else Result := -1; end; end; procedure TSampleCalendar.SetDateElement(Index: Integer; Value: Integer); var AYear, AMonth, ADay: Word; begin if Value > 0 then { all elements must be positive } begin DecodeDate(FDate, AYear, AMonth, ADay); { get current date elements } case Index of { set new element depending on Index } 1: AYear := Value; 2: AMonth := Value; 3: ADay := Value; else Exit; end; FDate := EncodeDate(AYear, AMonth, ADay); { encode the modified date } Refresh; { update the visible calendar } end; end;
C++:// header file class PACKAGE TSampleCalendar : public TCustomGrid { private: int __fastcall GetDateElement(int Index); // note the Index parameter void __fastcall SetDateElement(int Index, int Value); // … }; // implementation file int __fastcall TSampleCalendar::GetDateElement(int Index) { unsigned short AYear, AMonth, ADay; int result; FDate.DecodeDate(&AYear, &AMonth, &ADay); // break encoded date into elements switch (Index) { case 1: result = AYear; break; case 2: result = AMonth; break; case 3: result = ADay; break; default: result = -1; } return result; } void __fastcall TSampleCalendar::SetDateElement(int Index, int Value) { unsigned short AYear, AMonth, ADay; if (Value > 0) // all elements must be positive { FDate.DecodeDate(&AYear, &AMonth, &ADay); // get current date elements switch (Index) { case 1: AYear = Value; break; case 2: AMonth = Value; break; case 3: ADay = Value; break; default: return; } } FDate = TDateTime(AYear, AMonth, ADay); // encode the modified date Refresh(); // update the visible calendar }
これで、設計時に[オブジェクト インスペクタ]で、また、実行時にコードで、カレンダーの年、月、日を設定できるようになりました。もちろん、日付をセルに描画するコードはまだ追加していませんが、必要なデータは揃いました。