Recent

Author Topic: DateTimePicker in DBGrid query  (Read 1274 times)

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
DateTimePicker in DBGrid query
« on: December 04, 2018, 01:04:34 am »
Hi all,

I'm trying to put a DateTimePicker in a DBGrid so I can get the date into the grid.
I'm using DBGrid1DrawColumnCell to trap the cell where the date is needed using this code which positions the DateTimePicker control over the cell.

Code: Pascal  [Select]
  1. procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
  2. begin
  3.   if (gdFocused in State) then
  4.   begin
  5.     if (Column.Field.FieldName = 'FuelDate') then
  6.     with DateTimePicker1 do
  7.     begin
  8.       if SQLQuery1.State = dsInsert then
  9.         DBGrid1.SelectedField.Value := Now ;
  10.       Date := DBGrid1.SelectedField.AsDateTime;
  11.       Left := Rect.Left + DBGrid1.Left + 1;
  12.       Top := Rect.Top + DBGrid1.Top + 1;
  13.       Width := Rect.Right - Rect.Left + 1;
  14.       Height := Rect.Bottom - Rect.Top + 1;
  15.       Visible := True;
  16.       DateTimePicker1.SetFocus;
  17.       SendMessage(DateTimePicker1.Handle, WM_Char, Word(32), 0);
  18.       DBGrid1.DataSource.Edit;
  19.     end;
  20.   end
  21. end;

Then when the user hits tab I want it to return to the Grid and move to the next cell as if the DateTimePicker control wasn't there.So I use this code to trap the tab key, return focus to the grid and then send the DBgrid the tab key so that it moves to the next cell.

Code: Pascal  [Select]
  1. procedure TForm1.DateTimePicker1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  2. begin
  3.   if Key = 09 then then
  4.   begin
  5.     DBGrid1.SetFocus;
  6.     SendMessage(DBGrid1.Handle, WM_Char, Key, 0);
  7.   end ;
  8. end;

I also have an ColExit routine which updates the cell with the date from the DateTimePicker which works.

Code: Pascal  [Select]
  1. procedure TForm1.DBGrid1ColExit(Sender: TObject);
  2. begin
  3.   if DBGrid1.SelectedField.FieldName = 'FuelDate' then
  4.   begin
  5.     if DBGrid1.DataSource.State in [dsEdit, dsInsert] then
  6.       DBGrid1.SelectedField.value := DateTimePicker1.Date;
  7.     DateTimePicker1.Visible := False
  8.   end;
  9. end;

However, it doesn't work, the tab does set the DBGrid to focus, as the DateTimePicker loses it, althogh I suspect that it is just because the tab is moving to the next control anyway. But, the SendMessage doesn't seem to do anything, I still need to press tab again to move to the next cell. One thought I had was that you cannot do things like setfocus and sendmessage in an OnDo routine?

Can anyone give me some help or point me to an example or documentation around this?

Many thanks
ave
Version #:1.8.4 Date 2019-01-08 FPC Version: 3.0.4 and SVN Revision 57972 for x86_64-win64-win32/win64

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
Re: DateTimePicker in DBGrid query
« Reply #1 on: December 04, 2018, 01:27:13 am »
Hi,

Ok, so just after posting I found the documentaiton on SendMessage and realised that I should be using KeyDown rather than Char, and now it works, but if anyone can offer any neater code, please let me know.

Thanks
Version #:1.8.4 Date 2019-01-08 FPC Version: 3.0.4 and SVN Revision 57972 for x86_64-win64-win32/win64

eldonfsr

  • Full Member
  • ***
  • Posts: 131
Re: DateTimePicker in DBGrid query
« Reply #2 on: September 01, 2019, 06:08:09 pm »
Hi i tried to use your code but send me error SendMessage indentifier not found what unit i have use to get thats works.

wp

  • Hero Member
  • *****
  • Posts: 6235
Re: DateTimePicker in DBGrid query
« Reply #3 on: September 01, 2019, 11:21:58 pm »
I'm using DBGrid1DrawColumnCell to trap the cell where the date is needed using this code which positions the DateTimePicker control over the cell.
This is wrong. The OnDrawXXX events are for drawing, nothing else. You even call SetFocus which may trigger another drawing cycle and lead to an unfinite loop.

For introducing special editors there is the OnSelectEditor event. Did you try this one? And for ending the editing process you should use OnEditingDone where you can write the date to the database and the hide the DateTimePicker.

Look at the demo in the examples folder of the Lazarus installation (examples/gridexamples/gridcelleditor).
« Last Edit: September 01, 2019, 11:24:04 pm by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10