我发现,在将TDateTimePicker的MaxDate设置为非零值之后,不可能将其恢复为零(禁用它)。我的意思是,MaxDate读取零,但最大范围仍对之前设置的值有效。可以通过下拉日历并检查最后一个可见日期来注意到这一点。
这是另一个错误,还是我不了解如何禁用MaxDate?
procedure TForm1.Button1Click(Sender: TObject);
begin
DateTimePicker1.MaxDate:= Date + 10;
DateTimePicker1.MaxDate:= 0;
Caption:= IntToStr(Trunc(Test.MaxDate));
end;
P.S:我会先将“时间”设置为零(这是另一个错误)。
答案 0 :(得分:2)
以下内容不是MSDN记录的(偶然发现的),但它似乎有效(至少在Windows 7上)。您可以尝试调用以下宏(或发送相应的消息)以消除日期时间选择器控件的时间范围限制:
DateTime_SetRange(DateTimePicker1.Handle, 0, nil);
我的幸运偶然试验是通过在没有时间范围的情况下发送DTM_SETRANGE消息时不使用 GDTR_MIN 或 GDTR_MAX 标志开始的,因此(我已经通过了< strong> 0 和 nil )。
如果您将此作为可能的解决方法,则VCL剩下的是重置内部字段值,例如做一个小帮手可能会变成:
uses
CommCtrl;
type
TDateTimePickerHelper = class helper for TDateTimePicker
public
procedure ResetRange;
end;
implementation
{ TDateTimePickerHelper }
procedure TDateTimePickerHelper.ResetRange;
var
DateRange: array[0..1] of TDate;
begin
DateRange[0] := MinDate; { ← store the current MinDate }
DateRange[1] := MaxDate; { ← store the current MaxDate }
MinDate := 0; { ← set the control's MinDate internal field to 0 }
MaxDate := 0; { ← set the control's MaxDate internal field to 0 }
if not DateTime_SetRange(Handle, 0, nil) then { ← if the macro fails, then... }
begin
MinDate := DateRange[0]; { ← restore the previous MinDate internal field value }
MaxDate := DateRange[1]; { ← restore the previous MaxDate internal field value }
end;
end;
然后使用它重置范围:
procedure TForm1.Button1Click(Sender: TObject);
begin
DateTimePicker1.ResetRange;
end;
答案 1 :(得分:2)
Victoria discovered意外地是Win32 Date and Time Picker control可以通过使用未记录的技巧来重置其范围。
但是,Victoria的答案在Delphi 10.2中不起作用,因为VCL包装器的内部max和min字段未正确重置为0
。不会将MinDate
和MaxDate
属性更改为0
-不会将FMinDate
和FMaxDate
字段设置为{{1} }归功于属性设置器的实现。
这将使控制失效。
一种解决方法是直接设置字段(我还对Victoria的逻辑进行了一些调整,以使代码更简洁):
0
(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;
结构在这里很有必要,请参阅https://stackoverflow.com/a/42936824/282848。)
要尝试此操作:
with
当然,此代码依赖于未记录的Win32功能和VCL实现细节。但是,危险可能很小。有关此主题的更详尽讨论,请参见Victoria的评论。如果您知道VCL版本,则使用此代码(仅)可能是合理的。 (您甚至可以使它不能在将来的VCL版本上编译。)