Recent

Author Topic: Intercept DBGrid OnColumnMove  (Read 2442 times)

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
Intercept DBGrid OnColumnMove
« on: January 11, 2019, 07:23:58 pm »
Hi,

I'd like to intercept the OnColumnMove event in a DBGrid, and have been reading up about Main Loop Hooks and AddEventHandler which is the way I think I need to do this. I've tried searching for some example, but can't find anything, does anyone have a pointer to some examples or a tutorial.

Just for background, I'm trying to write a set of routines that adds a dropdown filter button to the title columns in a DBGrid, so I don't just want to add my own routine to the OnColmnMoved or OnColumnSized, as the developer (me typical) may also want to use these events for other things.

Also on a similar note, does OnColumnMoved get fired after the columns have moved (as the name would suggest) or before - from what I can see it is before as everything in the grid appears the same.

Thanks in advance
Dave 
« Last Edit: January 18, 2019, 11:34:10 pm by daveinhull »
Version #:1.8.4 Date 2019-01-08 FPC Version: 3.0.4 and SVN Revision 57972 for x86_64-win64-win32/win64

lucamar

  • Hero Member
  • *****
  • Posts: 2120
Re: Intercept DBGrid OnColumnMove
« Reply #1 on: January 11, 2019, 09:58:30 pm »
The OnColumnMoved event is published: You can set it in the Object Inspector or assign it in code like any other event.
« Last Edit: January 11, 2019, 10:00:42 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
Re: Intercept DBGrid OnColumnMove
« Reply #2 on: January 11, 2019, 11:59:11 pm »
Thanks lucamar,

I realize that I can set a routine through the Object Inspector or through code , but I was interested in traping the event before it gets to that point. I wanted to do something in a general routine before passing the execution to that routine (if there is one).

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

lucamar

  • Hero Member
  • *****
  • Posts: 2120
Re: Intercept DBGrid OnColumnMove
« Reply #3 on: January 12, 2019, 12:22:04 am »
Oh, ok. Only thing that I can think at the moment is to dive into the source and see where and in response to what message (if any) or condition it's being called. Once you know that you can ascertain where and how intercept it. You may have to subclass it, though.

I'll give it a look a little later (or tomorrow!).
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
Re: Intercept DBGrid OnColumnMove
« Reply #4 on: January 12, 2019, 01:14:40 am »
Hey lucamar many thanks, but please don't spend too long on it, but any clues to help are most welcome  :)

I thought I could do it by using the AddEventHandler, but I'll see if I can navigate my way through the source code as well, although it may be a little tricky for a 1980's DEC VAR Pascal programmer  :o
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: Intercept DBGrid OnColumnMove
« Reply #5 on: January 14, 2019, 12:26:57 pm »
Any thoughts anyone?
Version #:1.8.4 Date 2019-01-08 FPC Version: 3.0.4 and SVN Revision 57972 for x86_64-win64-win32/win64

lucamar

  • Hero Member
  • *****
  • Posts: 2120
Re: Intercept DBGrid OnColumnMove
« Reply #6 on: January 14, 2019, 02:39:12 pm »

I have followed the source and I think you'll have to subclass TDBGrid and set your own handler for the method ColRowMoved. For example:
Code: Pascal  [Select]
  1. unit MyDBGrid;
  2.  
  3. interface
  4.  
  5. type
  6.   TMyDBGrid = (TDBGrid)
  7.   protected
  8.     procedure ColRowMoved(IsColumn: Boolean; FromIndex,ToIndex: Integer); override;
  9.   end;
  10.  
  11. implementation
  12.  
  13. procedure TMyDBGrid.ColRowMoved(IsColumn: Boolean; FromIndex,ToIndex: Integer);
  14. begin
  15.   {Do whatever you want before calling ...}
  16.   ShowMessage('I''m an interceptor !!!');
  17.   inherited ColRowMoved(IsColumn, FromIndex, ToIndex);
  18. end;
  19.  
  20. end.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
Re: Intercept DBGrid OnColumnMove
« Reply #7 on: January 14, 2019, 02:54:45 pm »
Hey lucamar many thanks for this, I'll take this further and see what I can do with it.

Just one quick (well I hope it is quick) question from your investigations; would it then be possible to continue to execute any user defined procedure.

The reason for me asking this which might sound strange as I'm the user of the routine in this case, is that I want to provide routine that adds dropdown filters to the DBGrid at design time, but leave the option for the programmer (me) to also add real app events on the same event.

So for example, my 'real'app code I'm trying to develop in the future uses a DBGrid and I need in that use to catch the ColRowMoved for some purpose in the app. But I also want to call this routine I'm working on to add dropdown filters to the DBGrid. So I have an app need for the event and I also have a Dropdown filter need for the event.

Hope thi smakes sence.
Dave
Version #:1.8.4 Date 2019-01-08 FPC Version: 3.0.4 and SVN Revision 57972 for x86_64-win64-win32/win64

lucamar

  • Hero Member
  • *****
  • Posts: 2120
Re: Intercept DBGrid OnColumnMove
« Reply #8 on: January 17, 2019, 03:15:34 am »
If what you mean is: can the new class work normally as if it were the parent class, adding an event handler for OnColumnMoved if so desired? Then the answer is: yes, of course; note that the new method calls the inherited method, so it does its thing and after that whatever the parent class  method is doing ... which in this case (as in most) is to call the user defined handler, if any.

If you didn't mean that than I'm misunderstanding what you want.

Oh, sorry for the delay; first month of the year is an hectic time around here.
« Last Edit: January 17, 2019, 03:17:39 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
Re: Intercept DBGrid OnColumnMove
« Reply #9 on: January 17, 2019, 07:51:37 am »
Hi lucamar,

Yes that is exactly what I mean, many thanks for the confirmation.

Dave
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: Intercept DBGrid OnColumnMove
« Reply #10 on: January 18, 2019, 11:38:58 pm »
Hi

I've followed through lucamar's example and added in the code, but I'm getting a runtime error that TDBGrids not found.

I've included my subclass of TDBGrids
Code: Pascal  [Select]
  1.   TMyDBGrid = class(TDBGrid)
  2.   protected
  3.     procedure DrawCell(aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState); override;
  4.   end;  

I've added a procedure
Code: Pascal  [Select]
  1. procedure TMyDBGrid.DrawCell(aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState);
  2. begin
  3.   {Do whatever you want before calling ...}
  4.   ShowMessage('I an interceptor !!!');
  5.   inherited DrawCell(aCol, aRow, aRect, aState);
  6. end;

and I've changed the type of my grids from TDBGrid to TMyDBGrid.
Everything compiles OK.

But when I run it I get Class "TDBGrid" not found.

I'm struggling a bit with the class structure as when I last did Pascal programming it was in the 80's using VAX VMS Pascal and I don't ever remember there being classes, so any help would be appreciated in my learning.

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

lucamar

  • Hero Member
  • *****
  • Posts: 2120
Re: Intercept DBGrid OnColumnMove
« Reply #11 on: January 19, 2019, 02:40:33 am »
and I've changed the type of my grids from TDBGrid to TMyDBGrid.
Everything compiles OK.

But when I run it I get Class "TDBGrid" not found.

That's probably because the form resource still has TDBGrid as the class for the grid but there's no corresponding object in the source. But it you change the class in the .lfm it will give you another error, because the class TMyDBGrid is not registered.

You could include it in a package and install the package in the IDE but I don't like having to do all that for such a simple change. I'll investigate a little more this weekend to see how it may be done more easily but if anyone else has any idea, please share!
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
Re: Intercept DBGrid OnColumnMove
« Reply #12 on: January 19, 2019, 10:55:30 am »
Hey lucamar,

Excellent, many thanks. Yes I did notice that the only reference to DBGrid was in the components part of the object inspector as you've said, but didn't know how to chnage it and clearly if I had found out I would have been asking about another problem.

Thank you so much for taking the time to help, as I said, this aspect of Pascal and probably all modern development, is a little foreign for my age, hahaha
Version #:1.8.4 Date 2019-01-08 FPC Version: 3.0.4 and SVN Revision 57972 for x86_64-win64-win32/win64

lucamar

  • Hero Member
  • *****
  • Posts: 2120
Re: Intercept DBGrid OnColumnMove
« Reply #13 on: January 19, 2019, 03:38:48 pm »
This is a "good news, bad news" situation.

The good news is that you can use the new class by creating it at run-time ... which leads to the bad news: it means that you can't use the designer to set properties, add event handlers , etc.

For myself that wouldn't worry me too much: it's pretty easy to copy all those from the .lfm, paste them into, say, the FormCreate handler and adding whatever it needs to make it apply to the TMyDBGrid object instead of the TDBGrid one.
I've attached an extremely simple (an utterly inutil) project as an example of this approach.

If you're not comfy with that, though, then I think your only solution is to make a package and install it on the IDE, which is quite another kettke of fish :)

ETA - Oh, BTW, regarding:
[ I ] didn't know how to change it [...]
to modify the lfm by hand in the IDE, right-click in the form and select "View source (.lfm)"; it'll open the LFM text in an editor window, where you can change whatever you want ... but you must know what you're doing!
« Last Edit: January 19, 2019, 03:46:21 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

daveinhull

  • Sr. Member
  • ****
  • Posts: 264
  • 1 divided by nothing must still be 1!
Re: Intercept DBGrid OnColumnMove
« Reply #14 on: January 19, 2019, 04:35:31 pm »
Hi Lucamar, really appreciate your help on this. I'll take a look at your example and I think I can work with doing things at design time. I'm not quite ready enough to go into creating my own packages, that's for the future  :D

Again, many thanks
Dave
Version #:1.8.4 Date 2019-01-08 FPC Version: 3.0.4 and SVN Revision 57972 for x86_64-win64-win32/win64