FoxBase!
msgbartop
Блог Oracle разработчика
msgbarbottom
foxbase

22.10.2009 Редактирование даты и времени одновременно

В 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 сразу?

www.foxbase.ru




Смотрите также:



Оставьте свой комментарий

Вы должны быть авторизированны, чтобы оставить комментарий.