davornik 4 Posted March 21 I am using DateTimePicker1.Format as ' ' to set the value to an empty string in TDateTimePicker (using it as dtkDate). procedure TForm1.FormCreate(Sender: TObject); begin DateTimePicker1.Format:=' '; end; procedure TForm1.DateTimePicker1Change(Sender: TObject); begin DateTimePicker1.Format:=''; end; procedure TForm1.btnResetClick(Sender: TObject); begin DateTimePicker1.Format:=' '; //set as Empty DateTimePicker1.Date:=Date; end; Change event does not fire if I select today's date. How can I detect a click on the calendar if today's date is selected or clicked somewhere in the calendar itself? Share this post Link to post
PeterBelow 238 Posted March 21 4 hours ago, davornik said: I am using DateTimePicker1.Format as ' ' to set the value to an empty string in TDateTimePicker (using it as dtkDate). procedure TForm1.FormCreate(Sender: TObject); begin DateTimePicker1.Format:=' '; end; procedure TForm1.DateTimePicker1Change(Sender: TObject); begin DateTimePicker1.Format:=''; end; procedure TForm1.btnResetClick(Sender: TObject); begin DateTimePicker1.Format:=' '; //set as Empty DateTimePicker1.Date:=Date; end; Change event does not fire if I select today's date. How can I detect a click on the calendar if today's date is selected or clicked somewhere in the calendar itself? The control (a Windows common control under the VCL surtace) has no real concept of an "empty" state. The usual way to use it is to set the shown date to Today (it does that by default if memory serves) and accept that if the user does not change it. If your requirements really need a way to detect that the user has entered a date you can use an additional TCheckbox that disables the picker unless it is checked. Share this post Link to post
Lajos Juhász 293 Posted March 21 You are setting the date to today thus after the user clicks to reset the value will remain. Change the code to: procedure TForm1.btnResetClick(Sender: TObject); begin DateTimePicker1.Format:=' '; DateTimePicker1.Date:=0; end; Now it will change when the user clicks on the today. Share this post Link to post
Remy Lebeau 1398 Posted March 21 4 hours ago, PeterBelow said: If your requirements really need a way to detect that the user has entered a date you can use an additional TCheckbox that disables the picker unless it is checked. Or, use the TDateTimePicker.ShowCheckBox and TDateTimePicker.Checked properties instead. Share this post Link to post
davornik 4 Posted March 21 4 hours ago, PeterBelow said: The control (a Windows common control under the VCL surtace) has no real concept of an "empty" state. The usual way to use it is to set the shown date to Today (it does that by default if memory serves) and accept that if the user does not change it. If your requirements really need a way to detect that the user has entered a date you can use an additional TCheckbox that disables the picker unless it is checked. I dont want to use checkbox, because it is not user frendly. Main problem is that OnChange event does not fire on every click on calendar but only if Date <> Today. Share this post Link to post
davornik 4 Posted March 21 4 hours ago, Lajos Juhász said: You are setting the date to today thus after the user clicks to reset the value will remain. Change the code to: procedure TForm1.btnResetClick(Sender: TObject); begin DateTimePicker1.Format:=' '; DateTimePicker1.Date:=0; end; Now it will change when the user clicks on the today. Yes, but it will then show something like 1899 year. DateTimePicker1.Date must be :=Date; is because it needs to be on today's date for user convinience, when calendar drops down - it is user frendly to have view of current month. Share this post Link to post
Remy Lebeau 1398 Posted March 21 (edited) 16 minutes ago, davornik said: I dont want to use checkbox, because it is not user frendly. And yet, that is the way Microsoft wants you to use it. 16 minutes ago, davornik said: Main problem is that OnChange event does not fire on every click on calendar but only if Date <> Today. If you really want to detect a mouse click, you will likely have to subclass the window for the TDateTimePicker's drop down calendar to handle WM_LBUTTON(DOWN|UP) messages directly. Edited March 21 by Remy Lebeau Share this post Link to post
Remy Lebeau 1398 Posted March 21 (edited) 4 minutes ago, davornik said: Yes, but it will then show something like 1899 year. DateTimePicker1.Date must be :=Date; is because it needs to be on today's date for user convinience, when calendar drops down - it is user frendly to have view of current month. Then you are just going to have to do what Peter suggested. Just assume today's Date is the default unless the user selects a different date, or else use another UI element to specify when the default Date should be ignored. Edited March 21 by Remy Lebeau Share this post Link to post
davornik 4 Posted March 21 2 minutes ago, Remy Lebeau said: And yet, that is the way Microsoft wants you to use it. If you really want to detect a mouse click, you will likely have to subclass the TDateTimePicker's window to handle WM_MOUSE(DOWN|UP) messages directly. How to subclass TDateTimePicker's window on WM_MOUSE(DOWN|UP) messages? Share this post Link to post
Remy Lebeau 1398 Posted March 21 (edited) 35 minutes ago, davornik said: How to subclass TDateTimePicker's window on WM_MOUSE(DOWN|UP) messages? See Subclassing Controls on MSDN, and Safer subclassing on Raymond Chen's blog. For example: uses Winapi.CommCtrl; function CalendarSubclassProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM; uIdSubclass: UINT_PTR; dwRefData: DWORD_PTR): LRESULT; stdcall; begin case uMsg of WM_LBUTTONDOWN: begin TDateTimePicker(dwRefData).Format := ''; end; WM_NCDESTROY: begin RemoveWindowSubclass(hWnd, @CalendarSubclassProc, uIdSubclass); end; end; Result := DefSubclassProc(hWnd, uMsg, wParam, lParam); end; procedure TForm1.DateTimePicker1DropDown(Sender: TObject); var cal: HWND; begin cal := DateTime_GetMonthCal(DateTimePicker1.Handle); SetWindowSubclass(cal, @CalendarSubclassProc, 1, DWORD_PTR(DateTimePicker1)); end; Edited March 21 by Remy Lebeau 1 Share this post Link to post
PeterBelow 238 Posted March 22 18 hours ago, Remy Lebeau said: Or, use the TDateTimePicker.ShowCheckBox and TDateTimePicker.Checked properties instead. Oh, I'm farther behind the times than I was aware of . Didn't know these properties exist now... Share this post Link to post
Rollo62 536 Posted March 22 1 hour ago, PeterBelow said: Oh, I'm farther behind the times than I was aware of . Well, you are so far behind, that you are already far far ahead .... in our cyclic universe Share this post Link to post
Remy Lebeau 1398 Posted March 22 7 hours ago, PeterBelow said: Oh, I'm farther behind the times than I was aware of . Didn't know these properties exist now... Those properties have existed in TDateTimePicker since at least Delphi 5. Share this post Link to post