为啥 TDateTimePicker.Checked 在 Windows 7 上总是返回 True?

Posted

技术标签:

【中文标题】为啥 TDateTimePicker.Checked 在 Windows 7 上总是返回 True?【英文标题】:Why does TDateTimePicker.Checked return always True on Windows 7?为什么 TDateTimePicker.Checked 在 Windows 7 上总是返回 True? 【发布时间】:2012-10-06 14:18:26 【问题描述】:

我有一个应用程序,在 Delphi 2007 中构建,表单上有 TDateTimePicker。此日期时间选择器将ShowCheckbox 属性设置为True,它在日期或时间旁边显示一个复选框,每当用户选择日期或日期或时间由代码更改时,就会自动选中该复选框。该复选框的状态也可以由用户手动控制,其状态由Checked属性决定。

以下代码显示了如何在OnChange 事件中确定此复选框的状态:

procedure TForm1.FormCreate(Sender: TObject);
begin
  DateTimePicker1.ShowCheckbox := True;
end;

procedure TForm1.DateTimePicker1Change(Sender: TObject);
begin
  ShowMessage('Checked: ' + BoolToStr(DateTimePicker1.Checked, True));
end;

以上代码在 Windows XP 上按预期工作,但在 Windows 7 上,Checked 属性始终返回 True,无论该复选框的实际状态如何。

为什么Checked 属性总是返回 True,即使未选中复选框?有没有办法以某种方式解决或解决这个问题?

附:我的应用程序使用 Windows 主题

【问题讨论】:

【参考方案1】:

这是 Delphi 日期时间选择器控件实现中的 known issue(在 Delphi 2009 中修复,正如 @Remy 在他的评论中指出的那样)。要查询日期时间选择器的状态,应使用DTM_GETSYSTEMTIME 消息或DateTime_GetSystemtime 宏,它在内部发送此消息。如果消息(或宏)返回GDT_VALID 值,并且使用DTS_SHOWNONE 样式(在Delphi 中ShowCheckbox 属性为True 时),则表明控件的复选框已选中并且该控件包含有效日期时间。

以下是如何使用上述宏来确定复选框状态的示例:

uses
  CommCtrl;

procedure TForm1.DateTimePicker1Change(Sender: TObject);
var
  SysTime: SYSTEMTIME;
begin
  if DateTime_GetSystemTime(DateTimePicker1.Handle, @SysTime) = GDT_VALID then
    ShowMessage('Check box is checked!')
  else
    ShowMessage('Check box is not checked!');
end;

因此,您可以创建一个这样的辅助函数来解决错误的 Delphi 实现:

uses
  CommCtrl;

function IsDateTimePickerChecked(ADateTimePicker: TDateTimePicker): Boolean;
var
  SysTime: SYSTEMTIME;
begin
  Result := DateTime_GetSystemTime(ADateTimePicker.Handle, @SysTime) = GDT_VALID;
end;

procedure TMyForm.ButtonOneClick(Sender: TObject);
begin
  if IsDateTimePickerChecked(DateTimePicker1) then
    ShowMessage('Check box is checked!')
  else
    ShowMessage('Check box is not checked!');
end;

【讨论】:

“已知问题”已在 D2009 中修复。 此解决方法是否存在任何操作系统问题,或者对于 XP、VISTA 和 7 是否同样有效? @bullrider,我从 Windows 7 开始遇到的这个 Delphi 实现问题,但很可能是从 Windows Vista 开始的(但我不确定)。在 Windows XP 中它没有发生。在所有情况下,如果您针对此问题实施任何类型的修复并让您的应用程序在较新的 Windows 版本上正常工作,您会做得更好。 @bullrider,啊,我明白你的意思了。不,它不会导致任何错误。此类代码也适用于旧版本的 Windows。该消息(和宏)自 Windows 2000 起可用。 @TLama 非常感谢!

以上是关于为啥 TDateTimePicker.Checked 在 Windows 7 上总是返回 True?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?