Victoria discovered accidentally that the Win32 Date and Time Picker control can have its range reset by employing an undocumented trick.
However, Victoria's answer doesn't work in Delphi 10.2 because the VCL wrapper's internal max and min fields aren't reset properly to 0
. It doesn't do to change the MinDate
and MaxDate
properties to 0
-- that will not set the FMinDate
and FMaxDate
fields to 0
due to the implementation of the property setters.
This will make the control malfunction after that point.
A workaround is to set the fields directly (I also tweaked Victoria's logic a bit to make the code briefer):
type
TCommonCalendarHelper = class helper for TCommonCalendar
procedure ResetRangeFields;
end;
TDateTimePickerHelper = class helper for TDateTimePicker
public
procedure ResetRange;
end;
{ TDateTimePickerHelper }
procedure TDateTimePickerHelper.ResetRange;
begin
if DateTime_SetRange(Handle, 0, nil) then
ResetRangeFields;
end;
{ TCommonCalendarHelper }
procedure TCommonCalendarHelper.ResetRangeFields;
begin
with Self do
begin
FMinDate := 0;
FMaxDate := 0;
end;
end;
(The with
construct is surprisingly necessary here, see https://stackoverflow.com/a/42936824/282848.)
To try this:
procedure TForm1.FormClick(Sender: TObject);
begin
DateTimePicker1.MaxDate := IncDay(Now, 4);
// DateTimePicker1.ResetRange; // uncomment to see resetting in action
end;
Of course, this code relies both on undocumented Win32 features and on VCL implementation details. The dangers are probably fairly small, though. See the comments on Victoria's post for a more thorough discussion on this topic. It might be reasonable to use this code (only) if you know the VCL version. (You could even make it not compile on future VCL versions.)