我发现,在将MaxDate的TDateTimePicker设置为非零值后,不可能将其恢复为零(禁用它)。我的意思是,MaxDate读取零,但最大范围仍然是活动的值设置之前。这可以通过放下日历和检查最后可见的日期来注意。
这是另一个bug,还是我不知道如何禁用MaxDate?
procedure TForm1.Button1Click(Sender: TObject);
begin
DateTimePicker1.MaxDate:= Date + 10;
DateTimePicker1.MaxDate:= 0;
Caption:= IntToStr(Trunc(Test.MaxDate));
end;P.S:我先把时间设置为零(这是另一个错误)。
发布于 2018-08-16 01:30:45
MSDN没有记录以下内容(并且是偶然发现的),但它似乎有效(至少在Windows 7上是这样)。您可以尝试调用以下宏(或发送相应的消息)以删除日期时间选择器控件的时间范围限制:
DateTime_SetRange(DateTimePicker1.Handle, 0, nil);我幸运的意外试验开始时,在发送指向任何时间范围的DTM消息时,没有使用GDTR_MIN或GDTR_MAX标志(因此,我向宏传递了和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;发布于 2018-08-16 07:46:38
维多利亚 发现无意中认为Win32 日期和时间选择器控制可以通过使用无文档的技巧来重新设置其范围。
然而,维多利亚的答案在Delphi10.2中行不通,因为VCL包装器的内部max和min字段没有正确地重置为0。它不会将MinDate和MaxDate属性更改为0 --由于属性设置器的实现,不会将FMinDate和FMaxDate字段设置为0。
这将使控制故障后,这一点。
解决方法是直接设置字段(我还稍微修改了Victoria的逻辑,使代码更简洁):
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;( with构造在这里是非常必要的,参见https://stackoverflow.com/a/42936824/282848。)
要尝试这一点:
procedure TForm1.FormClick(Sender: TObject);
begin
DateTimePicker1.MaxDate := IncDay(Now, 4);
// DateTimePicker1.ResetRange; // uncomment to see resetting in action
end;当然,这段代码既依赖于无文档的Win32特性,也依赖于VCL实现细节。不过,危险可能相当小。有关这一主题的更详细的讨论,请参见对维多利亚帖子的评论。如果您知道VCL版本,使用此代码可能是合理的。(您甚至可以让它在将来的VCL版本上不编译。)
https://stackoverflow.com/questions/51858235
复制相似问题