В Delphi есть такой компонент – TDateTimePicker. Позволяет редактировать дату, есть выпадающий календарик. Или время. Или так или эдак. Но одновременно – хоть об стенку. Интересно, что думали разработчики этого компонента и его клонов (например, TJvDateTimePicker)? Что никому никогда не потребуется редактировать дату и время одновременно в одном поле? Потрясающе, они даже свойство такое ввели – Kind, где можно выбрать или дату или время. В результате многим разработчикам приходится мучиться с этой идеологией. В компоненте даже свойство такое есть – Format, где можно вписать формат даты вместе со временем, но только время вместе с датой вы не отредактируете все равно.
Очень элегантное решение проблемы было предложено в Королевстве Делфи, Состоит оно в следующем. Создаем наследника
TDateTimePicker. Я думаю есть смысл расположить приведенный ниже код в отдельном модуле.
type
TMyDateTimePicker = class(TDateTimePicker)
private
procedure CNNotify(var Msg: TWMNotify); message CN_NOTIFY;
end;
implementation
procedure TMyDateTimePicker.CNNotify(var Msg: TWMNotify);
begin
with Msg, NMHdr^ do
begin
Result := 0;
if code = DTN_DATETIMECHANGE then
begin
with PNMDateTimeChange(NMHdr)^ do
if dwFlags = GDT_VALID then DateTime := SystemTimeToDateTime(st);
Change;
end;
end;
end;
В тех формах, где мы хотим использовать
TDateTimePicker, визуально добавляем нужные нам компоненты в требуемом количестве, вписываем в поле Format значение
dd.MM.yyyy HH:mm (регистр буковок не изменяем, а то поля даты начинают меняться вместе с полями времени и наоборот) и в коде перед объявлением класса формы вписываем строчку, где переобъявляется
TDateTimePicker:
TDateTimePicker = class(TMyDateTimePicker);
Это все, теперь время прекрасно редактируется в этих компонентах наряду с датой. Можно на базе этого быстро сделать свой компонентик, но это на любителя.
А как быть с одновременным редактированием даты и времени при работе с базой данных? В стандартной поставке Delphi нет компонента, аналогичного TDateTimePicker, предназначенного для работы с данными. Зато есть в JVCL, который есть у каждого уважающего себя разработчика. Называется этот компонент TJvDBDateTimePicker. Страдает теми же проблемами, что и обычный TDateTimePicker. Вылечить его описанным выше способом не получается. Исследование исходного кода (чем ценны компоненты JVCL) показало наличие метода под названием UpdateData, в котором необходимо кое-что подправить. Нет, конечно, по уму его надо переопределить. Но не получается – он расположен в секции protected. В итоге родилось вот такое простейшее решение.
Все делаем аналогично описанному выше, но в исходниках
TJvDBDateTimePicker объявление метода
UpdateData переносим в секцию
private. Теперь мы можем его аккуратно перекрыть в нашем коде. И если мы будем переставлять систему или обновлять версию JVCL, то у нас выскочит ошибка компиляции об отсутствии перекрываемого метода, что нам позволит не забыть, что мы что-то правили в исходном коде компонента. Перекрытый метод будет выглядеть следующим простейшим образом:
procedure TMyJvDBDateTimePicker.UpdateData(Sender: TObject);
begin
Field.AsDateTime := DateTime;
end;
И еще – для компонентов TJvDBDateTimePicker на формах необходимо выставить свойство TrimValue в false. В итоге все прекрасно будет работать. Опять же по желанию можно сделать нормальный компонент, взяв за основу исходник TJvDBDateTimePicker и добавив в свойство Kind наряду с dtkDate и dtkTime – dtkDateTime. Интересно, какие заумные соображения помешали сделать это разработчикам Delphi сразу?
Смотрите также:
Оставьте свой комментарий
Вы должны быть авторизированны, чтобы оставить комментарий.