Ver Mensaje Individual
  #3  
Antiguo 28-08-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Reputación: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No hay un evento "OnScroll" en estos controles pero sí reciben el mensaje WM_VSCROLL cuando ocurre un desplazamiento (vertical en este caso).

Para intercepatr este mensaje tendríamos que crear derivados de TMemo y TRichEdit y redefinir sus manejadores de ventanas (método protegido WndProc).

O bien, hacerlo al vuelo como muestro en el siguiente ejemplo:

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    RichEdit1: TRichEdit;

    procedure FormCreate(Sender: TObject);
  private
    { Bandera para controlar el desplazamiento }
    Scrolling: Boolean;

    { Manejadores de mensajes originales }
    MemoOldWndProc: TWndMethod;
    RichEditOldWndProc: TWndMethod;

    { Manejadores de mensajes de reemplazo }
    procedure MemoWndProc(Var Msg: TMessage);
    procedure RichEditWndProc(Var Msg: TMessage);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Scrolling := false;

  { Guardar referencias a los manejadores de mensajes originales }
  MemoOldWndProc := Memo1.WindowProc;
  Memo1.WindowProc := MemoWndProc;

  { Reemplazar los manejadors de mensajes }
  RichEditOldWndProc := RichEdit1.WindowProc;
  RichEdit1.WindowProc := RichEditWndProc;
end;

{ Manejador de mensajes del memo }
procedure TForm1.MemoWndProc(var Msg: TMessage);
begin
  { Enviar mensaje al rich edit }
  if (Msg.Msg = WM_VSCROLL) and not Scrolling then
  begin
    Scrolling := true;
    RichEdit1.Perform(WM_VSCROLL, Msg.WParam, Msg.LParam);
    Scrolling := false;
  end;

  { Llamar al manejador original }
  MemoOldWndProc(Msg);
end;

{ Manejador de mensajes del rich edit }
procedure TForm1.RichEditWndProc(var Msg: TMessage);
begin
  { Enviar mensaje al memo }
  if (Msg.Msg = WM_VSCROLL) and not Scrolling then
  begin
    Scrolling := true;
    Memo1.Perform(WM_VSCROLL, Msg.WParam, Msg.LParam);
    Scrolling := false;
  end;

  { Llamar al manejador original }
  RichEditOldWndProc(Msg);
end;

end.

Pero hay que notar que no es perfecto, más que nada- supongo -porque los controles no dibujan exactamente igual su contenido. Por ejemplo, cargué un mismo texto en ambos controles con las mismas dimensiones, tipo de letra, etc, y tuve que aumentar unos pixeles a la altura del memo para que el contenido se viera igual. La sincronización funcionó bien si desplazaba dando click entre la flecha y el botón de la barra pero no sí se arrastraba el botón.

Pero bueno, creo que es un comienzo.

// Saludos

Última edición por roman fecha: 28-08-2006 a las 19:55:01.
Responder Con Cita