Mouse wheel in a DBGrid (improvement of)  

Send By: Radikal (Q3 Team)
Web : http://www.q3.nu
Email: radikal@q3.nu
Date: 06/02/04

Tip accessed 888 times

 


Speaking personally, I don't like the use that Dbgrid makes of the mousewheel because it only allows us to move through the visible part of the DBGrid.
If we want to move more records downwards or upwards, we simply can't do it by means of the mousewheel and we have to use the vertical scrollbar or the keys.
But, don't worry because everything has a solution
We have to do the following: To capture the WM_MOUSEWHEEL message and substitute the present behaviour of the DBGrid when it receives one of these messages for the behaviour we want it to have.
All in all, there is a little problem (of course, there is always one) and it is that ... How can we capture the messages directed to the DBGrid?.
At a first sight it would seem that it is only possible to do it through a new version of the DBGrid where we could introduce event handlers, wouldn't it?.
It is a tedious task to do it, to create a new control, install it, to substitute our DBGrids for that new component... as I said, a too tedious work.
Ok you have here something to do it with a simple DBGrid
We will simply change the WndProc of the DBGrid putting there what we want to.
For that task we will use a class, let's call it "Comodin" a descendant of Tcontrol (in this invention we will call it TomaInvento)


 type
   TomaInvento = class(TControl);



So we can, later on, substitute the WndProc of DBGrid1 with an instruction similar to:


   DBGrid1.WindowProc := DBGrid1PillaLaRueda;



for example in "Oncreate" of our Form
Here you have the Unit of a form in which I have placed a DBGrid a TTable and a TDataSource to check all the invention

 unit Unit1;

 interface

 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   Grids, DBGrids, Db, DBTables;

 type
   TForm1 = class(TForm)
     Table1: TTable;
     DataSource1: TDataSource;
     DBGrid1: TDBGrid;
     procedure FormCreate(Sender: TObject);
   private
     { Private declarations }
     procedure DBGrid1PillaLaRueda(var Message: TMessage);
   public
     { Public declarations }
   end;

 var
   Form1: TForm1;

 implementation

 {$R *.DFM}

 type
   TomaInvento = class(TControl);

 procedure TForm1.DBGrid1PillaLaRueda(var Message: TMessage);
 var
   Cuanto : short;
 begin

   if (Message.Msg = WM_MOUSEWHEEL) then begin
     Cuanto:=HIWORD(Message.WParam);
     Cuanto:=Cuanto div 120;
     DbGrid1.DataSource.DataSet.MoveBy(-Cuanto);

   end else TomaInvento(DBGrid1).WndProc(Message);
 end;

 procedure TForm1.FormCreate(Sender: TObject);
 begin
   DBGrid1.WindowProc := DBGrid1PillaLaRueda;
 end;

 end.


Basically when we move the wheel upwards (as if we moved our finger away) the message gives us a positive value in the HiWord of wParam, and when we move the wheel downwards (moving the finger towards us) we receive a negative value.
That value apart from showing the direction of the turning of the wheel it gives us a multiple of 120 depending on how fast we moved the wheel.
Those who want to know more about the 120 which appear in the code should read the help on WM_MOUSEWHEEL that you have in the win32.hlp that you should have in your hard disk.
Thanks to graendael the devil for the english traslation


Updated at 06/02/2004 MoveBy instead Next and Prior