Устранение ошибки в TDateTimePicker Delphi при использовании клавиш управления курсором
Вопрос, с которым вы столкнулись, является известной проблемой в компоненте TDateTimePicker в среде разработки Delphi. Эта ошибка связана с особенностями работы компонента при использовании клавиш управления курсором и возникает в определённых версиях Delphi, в частности, в Delphi 2009. Проблема заключается в том, что при настройке максимальной даты и текущей даты компонента, а также при определённых действиях с выпадающим списком, может возникать ошибка ECommonCalendarError, связанная с неудачной попыткой установки даты или времени календаря.
Пример кода, вызывающего ошибку:
procedure TForm1.FormShow(Sender: TObject);
begin
DateTimePicker1.MaxDate:= Now - 9;
DateTimePicker1.Date:= Now - 10;
end;
При попытке изменить дату с помощью клавиш управления курсором (например, стрелками вверх и вниз) возникает описанная ошибка. Однако, если изменить дату с помощью мыши, ошибка не появляется, и после этого управление курсором начинает работать корректно.
procedure TForm1.FormShow(Sender: TObject);
var
D: TDate;
begin
D:= Date;
DateTimePicker1.Date:= D;
DateTimePicker1.MaxDate:= D;
end;
В этом случае ошибка возникает, когда выпадающий список компонента TDateTimePicker открывается и закрывается без выбора даты.
Подробности проблемы:
Проблема заключается в ошибке VCL, которая была исправлена в более поздних релизах Delphi. В методе CNNotify при получении уведомления DTN_DATETIMECHANGE не устанавливается флаг FChanging. Подlying problem is that DTM_SETSYSTEMTIME fails to set date time because of existing time portion (which overlaps maximum datetime). Суть проблемы в том, что DTM_SETSYSTEMTIME не может установить дату и время из-за уже существующей части времени, которая перекрывает максимально допустимое значение даты и времени.
Решение проблемы:
Используйте один из предложенных способов:
- Сбросить свойство Time в 00:00:00.
- Присвоить дату, сохраняя часть времени нулевой, свойству DateTime.
Это связано с тем, что при установке только свойства Date, часть даты заменяется, но время остаётся, что приводит к тому, что дата и время, передаваемые в макрос DateTime_SetSystemTime, не укладываются в допустимый диапазон и вызывают исключение.
Оптимизация для исправления ошибок в компонентах VCL:
Изменение исходных текстов компонентов VCL.
Использование класса для перехвата событий, например, как в приведённом ссылке на Pastebin.
Подтвержденный ответ:
В версии Delphi 2009 обнаружена ошибка в VCL. Согласно описанию, установка свойства MaxDate не включает в себя время 23:59:59 в максимальный диапазон. Если свойство Time отличается от 00:00:00 и вы устанавливаете только свойство Date, то вызов макроса DateTime_SetSystemTime приведёт к ошибке, так как дата и время превысят допустимый диапазон.
Как избежать ошибки?
Сбросить свойство Time в 00:00:00.
Использовать свойство DateTime, устанавливая часть времени в 00:00:00.
Проблема с пропущенным временем 23:59:59 в установщике свойства MaxDate была исправлена в более поздних версиях Delphi. Это исправление означает, что если вы используете более свежую версию Delphi, вы не столкнётесь с этой проблемой.
Обратите внимание, что для устранения проблемы не всегда требуется вмешательство в код VCL, достаточно корректно обращаться с свойствами DateTimePicker, например, сбросить свойство Time перед установкой свойства Date. Это позволит избежать конфликта значений даты и времени, которые превышают допустимый диапазон.
Вопрос связан с устранением ошибки в компоненте `TDateTimePicker` в Delphi, возникающей при использовании клавиш управления курсором, особенно актуальной для Delphi 2009, и требующей корректного обращения со свойствами даты и времени
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.