こんにちは。
いつもお世話になっております。
開発環境は、delphiXE3 enterprise(update2適用済)、win7(sp1)です。
MonthCalendarを使ってDateTimePickerを自作しようと思っています。
同系の質問をしているのですが、質問内容が違うので、投稿することにしました。
monthcalendarで日付が選択されたかどうかを確認する方法は無いでしょうか?
適当なイベントがなかったので、clickイベントに以下のコードを書いたのですが、カレンダーの年月(2014年11月)が表示されているタイトル部をクリックしても閉じてしまいます。
procedure TForm2.MonthCalendar1Click(Sender: TObject);
begin
form1.maskedit1.Text:=datetostr(MonthCalendar1.Date);
modalresult:=mrok;
end;
clickイベントなので当然と言えば当然なのですが。
日付がクリックされたときのみ、form2の画面を閉じたいです。
clickイベント以外のイベントがあれば、教えてほしいです。
どなたか教えてください。
よろしくお願いします。
TMonthCalendar の OnClick イベントで,
カレンダーのどの部分をクリックしたかを検出するサンプルです.
Form1 から Form2 を表示します.
Form2 には TMonthCalendar を配置しておきます.
動作確認は,Windows 7 U64(SP1) + Delphi XE5(UP2) Pro です.
--------------------- Form1 のコード ---------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Left := Self.Left + 100;
Form2.Top := Self.Top + 200;
Form2.ShowModal;
Panel1.Caption := DateToStr(Form2.FDataTime);
end;
--------------------- Form2 のコード ---------------------------------
type
TForm2 = class(TForm)
MonthCalendar1: TMonthCalendar;
procedure MonthCalendar1Click(Sender: TObject);
private
{ Private 宣言 }
public
public
{ Public 宣言 }
FDataTime : TDateTime; //この値をForm1で取得する
end;
var
Form2: TForm2;
implementation
uses CommCtrl;
{$R *.dfm}
{ TForm2 }
//-----------------------------------------------------------------------------
// TMonthCalendarのOnClickイベント処理
// クリックしたマウスの位置を取得し
// どんな通知メッセージでOnClickが発生したかを調べる
// WM_NOTIFYメッセージで調べる方法もある(WMNotifyメソッド使用)
//
// usesにCommCtrlが必要
// (コモンコントロールの定数値やレコード型の定義等が書かれているユニット)
//-----------------------------------------------------------------------------
procedure TForm2.MonthCalendar1Click(Sender: TObject);
var
MousePos : TPoint;
HitInfo : TMCHitTestInfo;
begin
GetCursorPos(MousePos);
MousePos := MonthCalendar1.ScreenToClient(MousePos);
HitInfo.cbSize := SizeOf(HitInfo);
HitInfo.pt := MousePos;
//MonthCal_HitTestマクロを使用
//Delphi XE以前では以下のメッセージを使用
//SendMessage(MonthCalendar1.Handle, MCM_HITTEST, 0, Longint(@HitInfo));
MonthCal_HitTest(MonthCalendar1.Handle, HitInfo);
//クリックした場所が日付関係だったらこのフォームを閉じる
if HitInfo.uHit and MCHT_CALENDARDAY <> 0 then begin
FDataTime := MonthCalendar1.Date;
ModalResult := mrOk;
end;
end;
--------------------- Form2 のコード 終り ---------------------------------
MCHT_CALENDARDAY については以下を参照.
こういうメッセージ関係は,日本語はほとんどないので,
[このページを訳す] をクリックしてみることになります.
https://www.google.co.jp/search?num=50&site=webhp&source=hp&q=MCHT_CALENDARDAY+site%3Ahttp%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2F&oq=MCHT_CALENDARDAY+site%3Ahttp%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2F&gs_l=hp.12...0.0.2.41.0.0.0.0.0.0.0.0..0.0....0...1c..58.hp..14.0.0.80xrR1ghXVg
コントロールの通知メッセージについては,以下を参照.
MonthCalendar, DateTimePicker は,Windows (マイクロソフト) が提供しているコントロールです.
こういうコントロールを一般的に「コモンコントロール」と言っています.
コモンコントロール類を Delphi から利用するためのコードが ComCtrls ユニットにあります.
ComCtrls, CommCtrl は,Common Control(s) の略でしょう.多分.
[2−4 WM_NOTIFY での通知メッセージ]
http://mrxray.on.coocan.jp/Halbow/VCL02.html#VChap2-4
通知メッセージを利用する方法
usesにComCtrls, CommCtrlを追加
MonthCalendarを使ってるformの定義の前に以下の定義を追加
TMonthCalendar = class(ComCtrls.TMonthCalendar)
private
FOnDaySelect: TNotifyEvent;
procedure SetOnDaySelect(const Value: TNotifyEvent);
protected
procedure CNNotify(var Message: TWMNotifyMC); message CN_NOTIFY;
public
property OnDaySelect: TNotifyEvent read FOnDaySelect write SetOnDaySelect;
end;
implementationの下に以下を追加
procedure TMonthCalendar.CNNotify(var Message: TWMNotifyMC);
begin
inherited;
with Message, NMHdr{$IFNDEF CLR}^{$ENDIF} do
begin
case code of
MCN_SELECT:
if Assigned(FOnDaySelect) then
FOnDaySelect(Self);
end;
end;
end;
使う場合はFormのOnCreateででも以下の感じでイベントをセットしたら良いかと。
MonthCalendar1.OnDaySelect := OnDaySelect;
これでユーザーが日付を選択した場合のみイベントが走ります。
蛇足ですが、JVCLのTJvMonthCalendar2では、日付が選択されるとOnSelectイベントが発生するようになっています。
ソースコードも参考になるかもしれません。