Передо мной стояла задача в дбгрид запихать
календарь и показывать его тогда когда курсор стоит на поле с типом
дата.
Смысл был в том что если юзер нажал кнопку в право и фокус стоит на
годе и нажата клавища в право то передать управление в грид . и в другую
сторону - если курсор на дне и клавиша в лево то тоже передать это в
грид.
Пришлось усложнить жизнь пользователям (или облегчить) и делать
так
Если нажат шифт то не под каким предлогом фокус в грид не возвращать
. Если не нажата клавиша шифт то отдаем фокус гриду.
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;
---------------- Спрашивается для чего все это нужно =
смотрите скрин шот