Delphirus - прграммирование на delphi
   Все о delphi Delphirus - прграммирование на delphi
blocks.gif
Навигация
 

Главная
Статьи
Базы данных
Графика
Защита
Интернет
Система
Тексты
Мультимедиа
Файлы
Формы и окна
Другое
Советы
Базы данных
Графика
Интернет
Мультимедиа
Система
Тексты
Файлы
Файлы
Исходники
Компоненты
Инфо
Поиск по сайту
Обратная связь
Самое популярное
Аккаунт
Карта сайта

 
story.gif
Календарь в DBGrid
 
Базы данных

Передо мной стояла задача в дбгрид запихать календарь и показывать его тогда когда курсор стоит на поле с типом дата.

Смысл был в том что если юзер нажал кнопку в право и фокус стоит на годе и нажата клавища в право то передать управление в грид .
и в другую сторону - если курсор на дне и клавиша в лево то тоже передать это в грид.



Пришлось усложнить жизнь пользователям (или облегчить) и делать так

Если нажат шифт то не под каким предлогом фокус в грид не возвращать .
Если не нажата клавиша шифт то отдаем фокус гриду.

Вот реализация.

Создадим сначала календарь ....

понадобятся глобальные переменные
Date_edit_base:TDateTimePicker;
data_chebged:boolean = true;
Date_edit_base_f_name:string;


Date_edit_base:=TDateTimePicker.Create(DBGrid1);
Date_edit_base.Parent:=DBGrid1;
Date_edit_base.Left:=0;
Date_edit_base.Top:=0;
Date_edit_base.Visible:=false;
Date_edit_base.ShowCheckbox:=false;
Date_edit_base.Checked:=true;
Date_edit_base.OnChange:=set_Date; // изменяем значение в гриде
Date_edit_base.OnKeyDown:=datta_KeyDown; // обработка нажатий клавиш


После смены даты в календаре меняем соответст значение поля

procedure TForm1.set_Date(Sender: TObject);
begin
if data_chebged then
if not(( DataSet.State = dsEdit) or (DataSet.State = dsInsert)) then
begin
DataSet.Edit;
DataSet.FieldByName(Date_edit_base_f_name).AsDateTime:=Date_edit_base.DateTime;
end;
data_chebged:=false;
end;


procedure TForm1.datta_KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
locc:boolean; // локально обрабатывать нажатую клавишу или отдать гриду фокус
begin
locc:=false;
if (VK_RETURN=Key) then locc:=true;
if (key in [48..57]) then locc:=true;
if (key in [96..105]) then locc:=true;

if key=109 then key:=189;
if (key = 189) then locc:=true;


if ((ssShift in Shift)
or (SsAlt in Shift)
or (SsCtrl in Shift)) then
begin
// самостоятельно обработать нажатую славишу
locc:=true;

end;


if not(locc) then
begin

//Фокус надо передать гриду
TDateTimePicker(Sender).Visible:=false;
DBGrid1.SetFocus;
PostMessage(DBGrid1.Handle,WM_KEYDOWN,Key,0);

Key:=0;
end;


if locc then
if (key = 13) then
push_down(Date_edit_base);
end;


Процедура push_down (заставляет выпать календарик ) реализована вот так

procedure push_down(contr:TDateTimePicker );
var
msg: tagEVENTMSG;
begin
msg.message:= WM_LBUTTONDOWN;
msg.paramL:=contr.Height div 2;
msg.paramH:= contr.Width - 5;
msg.hwnd:=contr.Handle;
contr.DefaultHandler(msg);
msg.message:=WM_LBUTTONUP;
contr.DefaultHandler(msg);
delay(1);

if contr.DroppedDown then
begin
contr.SetFocus;
msg.message:= WM_LBUTTONDOWN;
msg.paramL:= 5;
msg.paramH:= 5;
msg.hwnd:=contr.Handle;
contr.DefaultHandler(msg);
msg.message:=WM_LBUTTONUP;
contr.DefaultHandler(msg);
contr.SetFocus;
end;
end;


Также потребуется собственоо нарисовать (0тбразить = переместить ) календарик в грде
Для этого у грида есть всем извесное и любимое событие

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if (gdFocused in State) then
if(( AnsiUpperCase(Column.FieldName) = AnsiUpperCase('Din') )
// тут я перечислил все свои поля типа даты

or ( AnsiUpperCase(Column.FieldName) = AnsiUpperCase('UPD_DATE') ))

then
if not(Column.Field.DataSet.FieldByName(Column.FieldName).AsDateTime=0) then
begin

Date_edit_base_f_name:=Column.FieldName; // задали в глоб перем имя столбца
Date_edit_base.Left := Rect.Left ; // левая точка календаря в координ грида
Date_edit_base.Top := Rect.Top ; // верхняя точка
Date_edit_base.Width := Rect.Right - Rect.Left + 2; // длина :)
Date_edit_base.Visible := True;
data_chebged:=true; // флажок что мол данные сменидися

Date_edit_base.DateTime:= Column.Field.DataSet.FieldByName(Column.FieldName).AsDateTime;
// записали в календарь нужное время
Date_edit_base.SetFocus; // отдали фокус календ
// push_down(Date_edit_base); // по желанию можно заставить его сразу и выпасть

end
else
begin

DBGrid1.Canvas.TextOut(Rect.Left+1,Rect.Top+1,'Нет данных!');
// Дата не проставлена
end;
end;


также по мере отладки выяснилося что надо такой финт дописать
(поймете по чему если будете делать)
procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
IF Date_edit_base.DroppedDown THEN
PostMessage(DBGrid1.Handle,WM_KEYDOWN,VK_ESCAPE,0);
end;


procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
Date_edit_base.Visible := False;
end;



Спрашивается для чего все это нужно = смотрите скрин шот
 

Источник http://www.realcoding.net/

 
Разместил 31/01/2004 от rolcom ( Прочитано: )

  blocks.gif
Связанные ссылки
 

· Больше про Базы данных
· Новость от rolcom


Самая читаемая статья: Базы данных:
SQL-запросы в Delphi

 
blocks.gif
Рейтинг статьи
 

Средняя оценка: 5
Ответов: 3


Пожалуйста, проголосуйте за эту статью:

Отлично
Очень хорошо
Хорошо
Нормально
Плохо


 
blocks.gif
опции
 


 Напечатать текущую страницу  Напечатать текущую страницу

 Отправить статью другу  Отправить статью другу

 
 

Page generation 0.037 seconds