Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Gráficos (https://www.clubdelphi.com/foros/forumdisplay.php?f=8)
-   -   Scrollbar con un richedit y y un memo (https://www.clubdelphi.com/foros/showthread.php?t=34990)

lachuza 28-08-2006 13:57:44

Scrollbar con un richedit y y un memo
 
HOLA A TODOS:
me gustaria mover con un mismo scrollbar un memo y un richedit para visualizar las mismas lineas al mismo tiempo
desde ya muchas gracias

Bicho 28-08-2006 15:40:13

Hola lachuza, creo que en éste caso no se puede hacer, y digo creo, porque el scrollbar de un memo o un richedit no dispara ningún evento y no sé si se puede capturar cuando lo mueves.

Se me ocurre ahora mismo que se podría intentar trabajar con el componente ScrollBar de la pestaña Standard, tendrían que ser dos, coordinados totalmente entre ellos y cada uno con un memo o richedit según el caso.

A ver si podemos madurarlo un poco o alguien nos da una idea mejor.

Saludos

roman 28-08-2006 19:51:07

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

serrano 04-11-2007 08:52:34

La solución de roman, con una pequeña modificación, para que también funcione al arrastrar el botón central de la barra de desplazamiento:


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;
  RichEditOldWndProc := RichEdit1.WindowProc;

  { Reemplazar los manejadores de mensajes }
  Memo1.WindowProc := MemoWndProc;
  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;
    if Msg.WParam < 9 then
      RichEdit1.Perform(WM_VSCROLL, Msg.WParam, Msg.LParam)
    else
      RichEdit1.Perform(WM_VSCROLL, (Msg.WParam-5)*13+5, 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;
    if Msg.WParam < 9 then
      Memo1.Perform(WM_VSCROLL, Msg.WParam, Msg.LParam)
    else
      Memo1.Perform(WM_VSCROLL, Round((Msg.WParam-5)/13/65536)*65536+5, Msg.LParam);
    Scrolling := false;
  end;

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

end.


La franja horaria es GMT +2. Ahora son las 09:18:32.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi