Scrolling 2 Richedit controls in sync

I have 2 richedit controls. I want to scroll one of them in sync with the other... so that if I cursor up/down or scroll using the scroll bar, the other richedit scrolls with it. Anyone have any ideas for the best way to do this?
davegreenAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

 
rwilson032697Commented:
Create a component derived from TRichEdit and override the WM_HSCROLL and WM_VSCROLL messages. In the handlers for these messages send a copy of them to the second memo which will then scroll in step with the first memo.

Cheers,

Raymond.
0
 
davegreenAuthor Commented:
Thanks for a quick response!

I am actually using two WPTools Richedits... have you got any example code to give me more of an idea what to do?
0
 
rwilson032697Commented:
You are too quick Dave!

After dashing off that quick answer I decided to give it a go. I am very embarassed to say the initial approach I outlined does not appear to work. I also tried overriding the WM_NCHITTEST message and passing that along but again this didn't work.

You should reject my answer and allow other experts to answer it. My apologies.

Cheers,

Raymond.

0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
davegreenAuthor Commented:
Thanks Raymond,
Well in theory it seems easy to do..but I have yet to come p with a solution. Still its not a thing you need to do everyday.

Dave
0
 
philipleighsCommented:
Have you tried sending an EM_SCROLL message?
0
 
rwilson032697Commented:
Dave, I wrote this (code below), which DOES work in terms of keeping them in sync when the user click on a scroll bar (I actually messed up the first attempt which is why it didn't work :-( )

Unfortunately this doesn't deal with the user arrowing down. Though I think this could be done with using EM_GETFIRSTVISIBLELINE and EM_SETFIRSTVISIBLELINE in the OnChange event (I havn't tried it out yet - I'll let you know how I go...)

I also tried EM_SCROLL (as Philipleighs suggested), but for some reason the control does not appear to be sent that message.

Cheers,

Raymond.

unit Unit1;

interface

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

type
  TMyRichEdit = class(TRichEdit)
    protected
      procedure OnWMHScroll(var Message : TMessage); message WM_HSCROLL;
      procedure OnWMVScroll(var Message : TMessage); message WM_VSCROLL;

    public
      SyncWithRichEdit : TRichEdit;
  end;

procedure Register;

implementation

{ TMyRichEdit }

procedure TMyRichEdit.OnWMHScroll(var Message: TMessage);
begin
  SendMessage(SyncWithRichEdit.Handle, WM_HSCROLL, Message.WParam, Message.LParam);
end;

procedure Register;

begin
  RegisterComponents('Samples', [TMyRichEdit]);
end;

procedure TMyRichEdit.OnWMVScroll(var Message: TMessage);
begin
 SendMessage(SyncWithRichEdit.Handle, WM_VSCROLL, Message.WParam, Message.LParam);
 inherited;
end;

end.

0
 
rwilson032697Commented:
Except there isn't a EM_SETFIRSTVISIBLELINE so you can't do

  RichEdit1.Perform(EM_SETFIRSTVISIBLELINE,
  Perform(EM_GETFIRSTVISIBLELINE, 0, 0));

sigh.

Raymond.
0
 
rwilson032697Commented:
I tried this in the on change but jut moving the cursor does not generate an onchange...

Cheers,

Raymond

  if Richedit1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0) >
     MyRichEdit1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0) then
    MyRichEdit1.perform(em_scroll, SB_LINEDOWN, 0)
  else
    MyRichEdit1.perform(em_scroll, SB_LINEUP, 0);
0
 
rwilson032697Commented:
OK here another attempt at the answer:

With the code I posted above for the WM_VSCROLL and WM_HSCROLL messages add this code (from above) to the KeyUp event like this:

procedure TForm1.MyRichEdit1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key = VK_UP) or (Key = VK_Down) or (key = vk_left) or (key = vk_right) then
  begin
     if MyRichedit1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0) > 
            MyRichEdit2.Perform(EM_GETFIRSTVISIBLELINE, 0, 0) then
           MyRichEdit2.perform(em_scroll, SB_LINEDOWN, 0)
         else
           MyRichEdit2.perform(em_scroll, SB_LINEUP, 0);
  end
end;

Cheers,

Raymond.
0

Experts Exchange Solution brought to you by ConnectWise

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
 
rwilson032697Commented:
Eureka! Here 'tis: A complete solution...

Cheers,

Raymond.

//************************* Source for the TMyRichEdit component...

unit Unit1;

interface

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

type
  TMyRichEdit = class(TRichEdit)
    protected
      procedure OnWMHScroll(var Message : TMessage); message WM_HSCROLL;
      procedure OnWMVScroll(var Message : TMessage); message WM_VSCROLL;
      procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
    public
      SyncWithRichEdit : TRichEdit;
  end;

procedure Register;

implementation

uses
  RichEdit;

{ TMyRichEdit }

procedure TMyRichEdit.OnWMHScroll(var Message: TMessage);
begin
  SendMessage(SyncWithRichEdit.Handle, WM_HSCROLL, Message.WParam, Message.LParam);
end;

procedure TMyRichEdit.OnWMVScroll(var Message: TMessage);
begin
 SendMessage(SyncWithRichEdit.Handle, WM_VSCROLL, Message.WParam, Message.LParam);
 inherited;
end;

procedure TMyRichEdit.CNNotify(var Message: TWMNotify);
var
  Diff : Integer;
  c : integer;
begin
  Inherited;
  with Message do
    case NMHdr^.code of
      EN_SELCHANGE:
      begin
        Diff := SyncWithRichEdit.Perform(EM_GETFIRSTVISIBLELINE, 0, 0) -
                 Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
        c := abs(diff);
        while c > 0 do
          begin
            if diff < 0 then
              SyncWithRichEdit.perform(em_scroll, SB_LINEDOWN, 0)
             else
              SyncWithRichEdit.perform(em_scroll, SB_LINEUP, 0);
            dec(c);
          end;
      end;
    end;
end;


procedure Register;

begin
  RegisterComponents('Samples', [TMyRichEdit]);
end;

end.

//************************* Form to test it with - just put a TRichEdit and a TMyRichEdit on it
unit RicheditForm;

interface

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

type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    MyRichEdit1: TMyRichEdit;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyRichEdit1.SyncWithRichEdit := RichEdit1;
end;


0
 
davegreenAuthor Commented:
BRILLIANT!
Thank you Raymond...this looks a great solution.
Just when I thought there was not solution you found one..

Thanks again.
Dave

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.