Usar la rueda del raton con un DBGrid  

Enviado Por: Radikal (Q3 Team)
Web : http://www.q3.nu
Email: radikal@q3.nu
Fecha: 06/02/04

Truco accedido 122 veces

 


A mi el uso que hace el DBGrid de la rueda del ratón no me gusta nada... ya que sólo permite moverse a través de la parte visible del DBGrid.
Si queremos ir para abajo o para arriba más registros... simplemente no podremos hacerlo con la rueda del ratón... y tendremos que usar o bien la barra de scroll vertical, o bien las teclas del cursor.
Pero no temas, que todo tiene solución...
Tendremos que hacer lo siguiente: capturar el mensaje WM_MOUSEWHEEL y substituir el comportamiento actual que tiene el DBGrid cuando recibe uno de estos mensajes por el que nosotros queremos.
Ahora bien... hay una pega (como no, siempre la hay) y es que... ¿como capturamos los mensajes dirijidos al DBGrid?... a simple vista, pareceria que sólo es posible hacerlo mediante una nueva versión del DBGrid en la que nosotros metamos nuevos manejadores de eventos ¿no?, con el coñazo que eso conlleva: hacer un nuevo control, instalarlo, cambiar nuestros DBGrids por ese nuevo componente... en fin, todo un coñazo.
Pues bien, aqui tienes un invento para hacerlo con un simple DBGrid.
Simplemente, cambiaremos la WndProc del DBGrid, colocando la que nos de la gana.
Para ello, usaremos una clase... llamemosla 'Comodin', descendiente de TControl (en este invento, la llamaremos TomaInvento) :


 type
   TomaInvento = class(TControl);



De tal forma que luego podremos substituir la WndProc del DbGrid1 con una instrucción tal que ésta:


   DBGrid1.WindowProc := DBGrid1PillaLaRueda;



por ejemplo, en el OnCreate de nuestra form...
Aqui tienes la Unit de una form en la que he puesto un DBgrid, un TTable y una TDatasource para probar todo el invento:

 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.


Basicamente: Cuando movemos la rueda hacia arriba (como alejando el dedo de nosotros), el mensaje nos da un valor positivo en el HiWord de wParam, y cuando movemos la rueda hacia abajo (acercando el dedo hacia nosotros) recibimos un valor negativo.
Dicho valor, aparte de mostrarnos la dirección de giro, nos dara un valor multiplo de 120, dependiendo de lo rápido que hayamos movido la rueda, por eso en el codigo, se desplaza el Dataset al registro anterior o porterior tantas veces como el valor dividido entre 120.
Para el que quiera saber más sobre el dichoso 120 que aparece el en código, que se lea la ayuda de WM_MOUSEWHEEL que teneis en el fichero win32.hlp que tendreis en vuestro disco duro.
Gracias a graendael the devil por la traducción al inglés


Actualizado el 06/02/2004 MoveBy en vez de Next y Prior